//翻译器-遍历文件 private static IEnumerable <string> TranslatorVisitFiles(TranslatorConfig config, string[] patterns) { DirectoryInfo dirInfo = new DirectoryInfo(config.WorkFolder); if (!dirInfo.Exists) { yield break; } if (config.ExceptTopFile) { foreach (DirectoryInfo subDir in dirInfo.EnumerateDirectories()) { if (subDir.Name.StartsWith(".")) { continue; } foreach (FileInfo subFileInfo in subDir.VisitFilesByRelativePattern(dirInfo, patterns)) { yield return(subFileInfo.FullName); } } } else { foreach (FileInfo fileInfo in dirInfo.VisitFilesByRelativePattern(dirInfo, patterns)) { yield return(fileInfo.FullName); } } }
//添加并提交,只限追踪文件 public static void GitCommit(TranslatorConfig config, string comment) { if (!config.AutoGitCommit) { return; } GitCommit(config.WorkFolder, comment); }
//添加所有文件,包含未追踪文件 public static void GitAdd(TranslatorConfig config) { if (!config.AutoGitCommit) { return; } GitAdd(config.WorkFolder); }
public async Task <TranslationResult> TranslateAsync(TranslatorConfig cfg) { var apiToken = cfg.YandexTranslateToken; if (apiToken == null && cfg.YandexTranslateOAuthToken != null) { var yandexIamTokensApi = ApiFactory.CreateIamApi(); apiToken = await yandexIamTokensApi.CreateToken(cfg.YandexTranslateOAuthToken); } if (string.IsNullOrEmpty(apiToken)) { return(TranslationResult.FromError("Error: Yandex Translate api token is not provided.")); } var api = ApiFactory.CreateTranslateApi(apiToken); var parser = new SubtitlesParser.Classes.Parsers.SrtParser(); await using var fileStream = File.OpenRead(cfg.SourceFile); var items = parser.ParseStream(fileStream, Encoding.Default); var allStrings = items.SelectMany(x => x.Lines).Distinct().ToList(); var translations = new Dictionary <string, string>(); foreach (var batch in allStrings.Batch(10)) { var src = batch.ToList(); try { var translateResponse = await api.Translate(new TranslateRequest { folder_id = cfg.YandexCloudFolderId, targetLanguageCode = cfg.TargetLanguageCode, texts = src }); for (var i = 0; i < src.Count; i++) { var dst = translateResponse.Translations[i].Text; dst = FixTags(dst); translations.Add(src[i], dst); } } catch (Exception exc) { return(TranslationResult.FromError(exc.ToString())); } } var translation = SubtitlesToString(items, translations); return(TranslationResult.Ok(translation)); }
public void GetConfigurationTest() { // arrage var httpClient = new HttpClient(); // act ITranslatorService translatorService = new TranslatorService(httpClient, EnvironmentName, ContentRootPath); TranslatorConfig config = translatorService.GetConfiguration(); // assert Assert.Equal(configuration.TranslatorTextAPIKey, config.TranslatorTextAPIKey); }
//翻译器-替换富友资源 public static StringBuilder TranslatorReplaceResourceWfy(TranslatorConfig config) { StringBuilder result = new StringBuilder(); if (config.WorkFolder.IsNullOrEmpty()) { return(result); } using (MemoryStream ms = new MemoryStream(Resources.resource)) { using (IArchive archive = ArchiveFactory.Open(ms)) { //创建临时目录 string tempDir = FilePathHelper.GetAbsolutePath(Guid.NewGuid().ToStringEx(), config.WorkFolder); Directory.CreateDirectory(tempDir); //解压到临时目录 foreach (var entry in archive.Entries) { if (!entry.IsDirectory) { entry.WriteToDirectory(tempDir, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite); } } //复制wfy 到工作目录 new DirectoryInfo(FilePathHelper.GetAbsolutePath(".\\wfy", tempDir)).Copy(new DirectoryInfo(config.WorkFolder)); //删除临时目录 try { Directory.Delete(tempDir, true); } catch { } } } //存在显式文件夹则复制 DirectoryInfo dirInfoWfy = new DirectoryInfo(FilePathHelper.GetAbsolutePath(".\\resources\\wfy")); if (dirInfoWfy.Exists) { dirInfoWfy.Copy(new DirectoryInfo(config.WorkFolder)); } //根据配置提交 GitHelper.GitAdd(config); GitHelper.GitCommit(config, "【富友资源】替换富友资源"); result.AppendLine("已替换富友资源"); return(result); }
public TranslatorService(HttpClient httpClient, string environmentName, string contentRootPath) { var builder = new ConfigurationBuilder() .SetBasePath(contentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{environmentName}.json", optional: true) .AddEnvironmentVariables(); var configuration = builder.Build(); config = new TranslatorConfig(); configuration.GetSection("TranslatorConfig").Bind(config); if (string.IsNullOrEmpty(config.TranslatorTextAPIKey)) { throw new ArgumentException("Missing value in TranslatorConfig -> TranslatorTextAPIKey"); } this.httpClient = httpClient ?? throw new ArgumentException("Missing value in HttpClient"); }
//翻译器断言 private static bool TranslatorAssert(TranslatorConfig config, StringBuilder result) { if (config == null) { result.AppendLine("配置为null."); return(false); } if (config.WorkFolder.IsNullOrEmpty()) { result.AppendLine("工作目录为空."); return(false); } if (!Directory.Exists(config.WorkFolder)) { result.AppendLine("工作目录不存在."); return(false); } return(true); }
//翻译器-替换 public static StringBuilder TranslatorReplace(IWin32Window owner, TranslatorConfig config, Translator translator, string comment) { StringBuilder result = new StringBuilder(1024); if (!TranslatorAssert(config, result)) { return(result); } IEnumerable <string> includefiles = TranslatorVisitFiles(config, translator.IncludeFile); IEnumerable <string> exceludefiles = (translator.ExcludeFile == null || translator.ExcludeFile.Length == 0) ? new string[] { } : TranslatorVisitFiles(config, translator.ExcludeFile); int count = 0; List <string> affects = new List <string>(); using (FrmBatch <string> dialog = new FrmBatch <string>(10, true)) { dialog.Work += delegate(object sender, EventArgs <string> e) { string fullName = e.Argument; string oldText = File.ReadAllText(fullName, UTF8_NO_BOM); string newText = oldText; StringComparison comparison = translator.CaseMatch ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; //大小写 bool isWindowsText = oldText.IndexOf("\r\n") >= 0; //windows换行 if (isWindowsText) { if (translator.WordMatch)//全字 { newText = newText.ReplaceWord(translator.Find.Replace("\r\n", "\n").Replace("\n", "\r\n"), translator.Replace.Replace("\r\n", "\n").Replace("\n", "\r\n"), translator.BanPrefix, translator.BanSuffix, comparison); } else { newText = newText.Replace(translator.Find.Replace("\r\n", "\n").Replace("\n", "\r\n"), translator.Replace.Replace("\r\n", "\n").Replace("\n", "\r\n"), translator.BanPrefix, translator.BanSuffix, comparison); } } else { if (translator.WordMatch)//全字 { newText = newText.ReplaceWord(translator.Find.Replace("\r\n", "\n"), translator.Replace.Replace("\r\n", "\n"), translator.BanPrefix, translator.BanSuffix, comparison); } else { newText = newText.Replace(translator.Find.Replace("\r\n", "\n"), translator.Replace.Replace("\r\n", "\n"), translator.BanPrefix, translator.BanSuffix, comparison); } } if (newText != oldText) { File.WriteAllText(fullName, newText, UTF8_NO_BOM); lock (affects) affects.Add(fullName); dialog.WriteLog("{0} 替换 {1}", translator.Find, fullName); } }; //全部完成,统计 dialog.AllWorkComplete += delegate(object sender, EventArgs e) { count = affects.Count; affects.OrderBy(fullName => fullName).ForEach(fullName => result.AppendLine(fullName)); GitHelper.GitCommit(config, comment); }; foreach (string fullname in includefiles.Except(exceludefiles)) { dialog.Enqueue(fullname); } dialog.ShowDialog(owner); } result.Insert(0, string.Format("{0} 替换以下文件,共 {1} 个\r\n", translator.Find, count)); return(result); }