Skip to content

Commit

Permalink
refactor option handling, configure now deparate in and output dir an…
Browse files Browse the repository at this point in the history
…d files
  • Loading branch information
penCsharpener committed Mar 8, 2020
1 parent ebe81b6 commit 9ceff4c
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ public interface IAppInformation
PropertyInfo[] GetConfigFilePropertyInfos();
string GetWorkingDirectory();

FileInfo[] GetExcelFiles();
FileInfo[] GetExcelFiles(DirectoryInfo inputPath);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using NetDeepL.TranslationWorker.Models.Config;

namespace NetDeepL.TranslationWorker.Abstractions
{
public interface IConfigFileProvider
public interface IConfigFileProvider : IOptions<ConfigFile>
{
Task<bool> CreateTemplate(bool overwrite = false);
Task<ConfigFileRaw> GetConfig();
Expand Down
14 changes: 11 additions & 3 deletions tools/NetDeepL.TranslationWorker/Implementations/AppInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,23 @@ namespace NetDeepL.TranslationWorker.Implementations
{
public class AppInformation : IAppInformation
{
private static string _workingDir = Directory.GetCurrentDirectory();
private static PropertyInfo[] _configFileProperties = typeof(ConfigFileRaw).GetProperties();
private readonly string _workingDir;

public AppInformation()
{
_workingDir = Directory.GetCurrentDirectory();
}

public PropertyInfo[] GetConfigFilePropertyInfos() => _configFileProperties;

public FileInfo[] GetExcelFiles()
public FileInfo[] GetExcelFiles(DirectoryInfo inputPath)
{
return new DirectoryInfo(_workingDir).GetFiles("*.xlsx", SearchOption.TopDirectoryOnly);
if (!inputPath.Exists)
{
Directory.CreateDirectory(inputPath.FullName);
}
return new DirectoryInfo(inputPath.FullName).GetFiles("*.xlsx", SearchOption.TopDirectoryOnly);
}

public string GetWorkingDirectory() => _workingDir;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@ public class ConfigFileProvider : IConfigFileProvider
{
private readonly IAppInformation _appInformation;
private const string CONFIG_FILENAME = "config.ini";
private string ConfigFullFilePath;
private string _configFullFilePath;

public ConfigFile Value => GetOptionValues();

public ConfigFileProvider(IAppInformation appInformation)
{
_appInformation = appInformation;
ConfigFullFilePath = Path.Combine(_appInformation.GetWorkingDirectory(), CONFIG_FILENAME);
_configFullFilePath = Path.Combine(_appInformation.GetWorkingDirectory(), CONFIG_FILENAME);
}

public async Task<bool> CreateTemplate(bool overwrite = false)
{
if (File.Exists(ConfigFullFilePath) && overwrite)
if (File.Exists(_configFullFilePath) && overwrite)
{
File.Delete(ConfigFullFilePath);
File.Delete(_configFullFilePath);
}

if (!File.Exists(ConfigFullFilePath) || overwrite)
if (!File.Exists(_configFullFilePath) || overwrite)
{
var conf = new ConfigFileRaw();
var lines = new List<string>();
Expand All @@ -38,7 +40,7 @@ public async Task<bool> CreateTemplate(bool overwrite = false)
lines.Add($"{name}={value}");
}

await File.WriteAllLinesAsync(ConfigFullFilePath, lines);
await File.WriteAllLinesAsync(_configFullFilePath, lines);
return true;
}
return false;
Expand All @@ -47,9 +49,9 @@ public async Task<bool> CreateTemplate(bool overwrite = false)
public async Task<ConfigFileRaw> GetConfig()
{
var conf = new ConfigFileRaw();
if (File.Exists(ConfigFullFilePath))
if (File.Exists(_configFullFilePath))
{
var lines = await File.ReadAllLinesAsync(ConfigFullFilePath);
var lines = await File.ReadAllLinesAsync(_configFullFilePath);
var props = _appInformation.GetConfigFilePropertyInfos();
foreach (var line in lines)
{
Expand Down Expand Up @@ -93,5 +95,10 @@ public async Task ValidateConfigFile()
Environment.Exit(0);
}
}

public ConfigFile GetOptionValues()
{
return new ConfigFile(GetConfig().Result);
}
}
}
108 changes: 60 additions & 48 deletions tools/NetDeepL.TranslationWorker/Implementations/WorkbookTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
using System.Threading.Tasks;
using ClosedXML.Excel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NetDeepL.Abstractions;
using NetDeepL.Models;
using NetDeepL.TranslationWorker.Abstractions;
using NetDeepL.TranslationWorker.Models;
using NetDeepL.TranslationWorker.Models.Config;
using Polly;

namespace NetDeepL.TranslationWorker.Implementations
Expand All @@ -18,50 +20,61 @@ public class WorkbookTranslator : IWorkbookTranslator
private const string DEEPL_PLACEHOLDER = "_DeepL_";
private readonly IAppInformation _appInformation;
private INetDeepL _deepL;
private readonly IConfigFileProvider _configFileProvider;
private readonly IOptions<ConfigFile> _options;
private readonly IServiceProvider _serviceProvider;
private Languages _sourceLanguage;

public WorkbookTranslator(IAppInformation appInformation, INetDeepL deepL, IConfigFileProvider configFileProvider, IServiceProvider serviceProvider)
public WorkbookTranslator(IAppInformation appInformation, INetDeepL deepL, IOptions<ConfigFile> options, IServiceProvider serviceProvider)
{
_appInformation = appInformation;
_deepL = deepL;
_configFileProvider = configFileProvider;
_options = options;
_serviceProvider = serviceProvider;

}

public async Task TranslateAsync()
{
var conf = await _configFileProvider.GetConfig();
_sourceLanguage = Enum.Parse<Languages>(conf.SourceLanguage);
var delay = int.Parse(conf.DelayMilliseconds);

var usageBefore = await _deepL.GetUsage();
Console.WriteLine();
Console.WriteLine("Translation starting");
Console.WriteLine($"Api usage: {usageBefore.CharacterCount}/{usageBefore.CharacterLimit}");
Console.WriteLine();

foreach (var xlsx in _appInformation.GetExcelFiles())
foreach (var xlsx in _appInformation.GetExcelFiles(_options.Value.InputPath))
{
Console.WriteLine();
Console.WriteLine($"processing file '{xlsx.Name}'");

using (var wb = new XLWorkbook(xlsx.FullName))
{
try
if (!_options.Value.OutputPath.Exists)
{
CheckForAlreadyTranslatedWorksheets(wb);
Directory.CreateDirectory(_options.Value.OutputPath.FullName);
}

await ProcessSheets(wb, conf.LanguagesToTranslate, delay);
Console.WriteLine();
var xlsxCopy = Path.Combine(_options.Value.OutputPath.FullName, xlsx.Name.Replace(".xlsx", "_NetDeepL.xlsx"));
File.Copy(xlsx.FullName, xlsxCopy);

wb.Save();
}
catch (Exception ex)
using (var wbCopy = new XLWorkbook(xlsxCopy))
{
Console.WriteLine(ex.ToString());
try
{
CheckForAlreadyTranslatedWorksheets(wbCopy);

await ProcessSheets(wbCopy, _options.Value.LanguagesToTranslate, _options.Value.DelayMilliseconds);
Console.WriteLine();

// delete original sheets in copied workbook
for (int i = wbCopy.Worksheets.Where(x => x.Name.IndexOf(DEEPL_PLACEHOLDER) == -1).ToList().Count - 1; i >= 0; i--)
{
wbCopy.Worksheets.Where(x => x.Name.IndexOf(DEEPL_PLACEHOLDER) == -1).ToList()[i].Delete();
}

wbCopy.Save();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
Expand All @@ -73,40 +86,14 @@ public async Task TranslateAsync()
Console.WriteLine();
}

private void CheckForAlreadyTranslatedWorksheets(IXLWorkbook wb)
{
var alreadyTranslated = wb.Worksheets.Where(x => x.Name.IndexOf(DEEPL_PLACEHOLDER) >= 0).ToList();

if (alreadyTranslated.Count > 0)
{
Console.WriteLine("This file was already translated. " +
"Delete all the sheets with _DeepL_ in it to retranslate it.");
Console.WriteLine("Do you want to delete translated sheet now? y/n");
if (Console.ReadLine() == "y")
{
for (int i = alreadyTranslated.Count - 1; i >= 0; i--)
{
Console.WriteLine($"Deleting sheet '{alreadyTranslated[i].Name}'");
alreadyTranslated[i].Delete();
}
Console.WriteLine();
}
else
{
Environment.Exit(0);
}
}
}

private async Task ProcessSheets(IXLWorkbook workbook, string languagesToTranslate, int delay)
private async Task ProcessSheets(IXLWorkbook workbook, Languages[] languagesToTranslate, int delay)
{
foreach (IXLWorksheet ws in workbook.Worksheets.Where(x => x.Name.IndexOf(DEEPL_PLACEHOLDER) == -1).ToList())
{
Console.WriteLine($"Beginning worksheet '{ws.Name}'");

foreach (var language in languagesToTranslate.Split(","))
foreach (var language in languagesToTranslate)
{
var langEnum = Enum.Parse<Languages>(language);
Console.WriteLine($"Language '{language}'");

var usedCells = ws.CellsUsed().Cast<IXLCell>()
Expand All @@ -121,7 +108,7 @@ private async Task ProcessSheets(IXLWorkbook workbook, string languagesToTransla

foreach (var cell in usedCells)
{
await TranslateCell(cell, translatedSheet, delay, langEnum);
await TranslateCell(cell, translatedSheet, delay, language);
}

Console.WriteLine();
Expand All @@ -148,7 +135,7 @@ private async Task TranslateCell(ExcelCell cell, IXLWorksheet translatedSheet, i
})
.ExecuteAsync(async () =>
{
var response = await _deepL.TranslateAsync(cell.Text, language, _sourceLanguage);
var response = await _deepL.TranslateAsync(cell.Text, language, _options.Value.SourceLanguage);
return response.Text;
});
}
Expand All @@ -170,5 +157,30 @@ private async Task TranslateCell(ExcelCell cell, IXLWorksheet translatedSheet, i

translatedSheet.Cell(cell.Address).Value = translation;
}

private void CheckForAlreadyTranslatedWorksheets(IXLWorkbook wb)
{
var alreadyTranslated = wb.Worksheets.Where(x => x.Name.IndexOf(DEEPL_PLACEHOLDER) >= 0).ToList();

if (alreadyTranslated.Count > 0)
{
Console.WriteLine("This file was already translated. " +
"Delete all the sheets with _DeepL_ in it to retranslate it.");
Console.WriteLine("Do you want to delete translated sheet now? y/n");
if (Console.ReadLine() == "y")
{
for (int i = alreadyTranslated.Count - 1; i >= 0; i--)
{
Console.WriteLine($"Deleting sheet '{alreadyTranslated[i].Name}'");
alreadyTranslated[i].Delete();
}
Console.WriteLine();
}
else
{
Environment.Exit(0);
}
}
}
}
}
34 changes: 34 additions & 0 deletions tools/NetDeepL.TranslationWorker/Models/Config/ConfigFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.IO;
using System.Linq;
using NetDeepL.Models;

namespace NetDeepL.TranslationWorker.Models.Config
{
public class ConfigFile
{
public ConfigFile()
{

}

public ConfigFile(ConfigFileRaw raw)
{
DeepLApiKey = raw.DeepLApiKey;
LanguagesToTranslate = raw.LanguagesToTranslate.Split(',', System.StringSplitOptions.RemoveEmptyEntries)
.Select(x => Enum.Parse<Languages>(x)).ToArray();
SourceLanguage = Enum.Parse<Languages>(raw.SourceLanguage);
DelayMilliseconds = int.Parse(raw.DelayMilliseconds);
var currentDir = new DirectoryInfo(Directory.GetCurrentDirectory());
InputPath = string.IsNullOrWhiteSpace(raw.InputPath) ? currentDir : new DirectoryInfo(raw.InputPath);
OutputPath = string.IsNullOrWhiteSpace(raw.OutputPath) ? currentDir : new DirectoryInfo(raw.OutputPath);
}

public string DeepLApiKey { get; }
public Languages[] LanguagesToTranslate { get; }
public Languages SourceLanguage { get; }
public int DelayMilliseconds { get; }
public DirectoryInfo InputPath { get; }
public DirectoryInfo OutputPath { get; }
}
}
10 changes: 10 additions & 0 deletions tools/NetDeepL.TranslationWorker/Models/Config/ConfigFileRaw.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
using System;
using System.IO;

namespace NetDeepL.TranslationWorker.Models.Config
{
public class ConfigFileRaw
{
public ConfigFileRaw()
{
var currentDir = Directory.GetCurrentDirectory();
OutputPath = $"{currentDir}\\output";
InputPath = $"{currentDir}\\input";
}

public string DeepLApiKey { get; set; } = Guid.Empty.ToString();
public string LanguagesToTranslate { get; set; } = "EN,DE,FR,ES,PT,IT,NL,PL,RU # multiple possible";
public string SourceLanguage { get; set; } = "EN,DE,FR,ES,PT,IT,NL,PL,RU # only select one language";
public string DelayMilliseconds { get; set; } = "500 # 1 second = 1000 millisecond, if this value is too low DeepL could response with code 429";
public string InputPath { get; set; }
public string OutputPath { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyVersion>0.3.0.0</AssemblyVersion>
<FileVersion>0.3.0.0</FileVersion>
<AssemblyVersion>0.4.0.0</AssemblyVersion>
<FileVersion>0.4.0.0</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions tools/NetDeepL.TranslationWorker/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NetDeepL.TranslationWorker.Abstractions;
using NetDeepL.TranslationWorker.Implementations;
using NetDeepL.TranslationWorker.Models.Config;

namespace NetDeepL.TranslationWorker
{
Expand All @@ -12,6 +14,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddSingleton<IConfigFileProvider, ConfigFileProvider>();
services.AddSingleton<IAppInformation, AppInformation>();
services.AddSingleton<IWorkbookTranslator, WorkbookTranslator>();
services.AddTransient<IOptions<ConfigFile>, ConfigFileProvider>();
services.AddSingleton(sp =>
{
var configProvider = sp.GetService<IConfigFileProvider>();
Expand Down

0 comments on commit 9ceff4c

Please sign in to comment.