Skip to content

Commit

Permalink
Ajoutez des fichiers projet.
Browse files Browse the repository at this point in the history
  • Loading branch information
dchatel committed Jun 24, 2022
1 parent 28ae4eb commit 78ac311
Show file tree
Hide file tree
Showing 28 changed files with 2,350 additions and 0 deletions.
402 changes: 402 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions SwordAndFairy7Translator.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32328.378
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SwordAndFairy7Translator", "SwordAndFairy7Translator\SwordAndFairy7Translator.csproj", "{2481D2E1-9A7C-40DC-932B-7633252E7B09}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ethereality", "D:\code\Ethereality\Ethereality\Ethereality.csproj", "{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Éléments de solution", "Éléments de solution", "{2A2BCC1F-F43E-4C51-A0FE-7595AAA92526}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2481D2E1-9A7C-40DC-932B-7633252E7B09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2481D2E1-9A7C-40DC-932B-7633252E7B09}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2481D2E1-9A7C-40DC-932B-7633252E7B09}.Debug|x64.ActiveCfg = Debug|x64
{2481D2E1-9A7C-40DC-932B-7633252E7B09}.Debug|x64.Build.0 = Debug|x64
{2481D2E1-9A7C-40DC-932B-7633252E7B09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2481D2E1-9A7C-40DC-932B-7633252E7B09}.Release|Any CPU.Build.0 = Release|Any CPU
{2481D2E1-9A7C-40DC-932B-7633252E7B09}.Release|x64.ActiveCfg = Release|x64
{2481D2E1-9A7C-40DC-932B-7633252E7B09}.Release|x64.Build.0 = Release|x64
{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}.Debug|x64.ActiveCfg = Debug|x64
{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}.Debug|x64.Build.0 = Debug|x64
{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}.Release|Any CPU.Build.0 = Release|Any CPU
{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}.Release|x64.ActiveCfg = Release|x64
{21CEA71C-F222-4FF1-8FC5-C1C0B0180A6E}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {01FF3FD6-39EA-401F-8F25-36D349B2B195}
EndGlobalSection
EndGlobal
16 changes: 16 additions & 0 deletions SwordAndFairy7Translator/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Application x:Class="SwordAndFairy7Translator.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SwordAndFairy7Translator"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Ethereality;component/Ethereality.xaml" />
<ResourceDictionary Source="Views/TranslatorServiceConfigViews.xaml" />
</ResourceDictionary.MergedDictionaries>

</ResourceDictionary>
</Application.Resources>
</Application>
19 changes: 19 additions & 0 deletions SwordAndFairy7Translator/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using SwordAndFairy7Translator.Views.StartupDialog;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace SwordAndFairy7Translator
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
10 changes: 10 additions & 0 deletions SwordAndFairy7Translator/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows;

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
147 changes: 147 additions & 0 deletions SwordAndFairy7Translator/AzureTranslate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PostSharp.Patterns.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Windows;

namespace SwordAndFairy7Translator;

[NotifyPropertyChanged]
public class AzureTranslator : ITranslatorService
{
private static readonly string endpoint = "https://api.cognitive.microsofttranslator.com/";

private IEnumerable<Language>? languages;

[SafeForDependencyAnalysis]
public string? Key { get => Settings.Default.AzureAPIKey; set => Settings.Default.AzureAPIKey = value; }
[SafeForDependencyAnalysis]
public string? Region { get => Settings.Default.AzureRegion; set => Settings.Default.AzureRegion = value; }

public string Name => "Microsoft Azure";

[SafeForDependencyAnalysis]
public IEnumerable<Language>? Languages
{
get
{
if (languages is null)
{
Task.Run(async () =>
{
using var client = new HttpClient();
using var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://api.cognitive.microsofttranslator.com/languages?api-version=3.0"),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
var result = await response.Content.ReadAsStringAsync();

var json = JObject.Parse(result);
Dictionary<string, Language> langs = JsonConvert.DeserializeObject<Dictionary<string, Language>>(json["translation"]!.ToString())!;
foreach (var (k, v) in langs)
v.Code = k;
languages = langs.Values.AsEnumerable();
});
}
return languages;
}
}
public async Task<IEnumerable<string>> TranslateAsync(string from, params string[] textToTranslate)
{
if (string.IsNullOrEmpty(Key)) return Enumerable.Empty<string>();

// split strings in substrings with or without html tags
var allMStrings = textToTranslate
.Select(text => TranslatorServiceHelper.GetMStrings(text))
.ToArray();

// Filter strings with html tags and those who don't have text to translate
var toTranslateMStrings = allMStrings
.SelectMany(x => x)
.Where(x => !Regex.IsMatch(x.Text, @"<[^>]+>") && Regex.IsMatch(x.Text, @"\p{L}"))
.ToArray();

// Create Chunks of 40k characters max
var chunks = new List<List<TranslatorServiceHelper.MString>>
{
new()
};
foreach (var str in toTranslateMStrings)
{
if (chunks.Last().Count >= 1000 || chunks.Last().Sum(x => x.Text.Length) + str.Text.Length > 40000)
chunks.Add(new());
chunks.Last().Add(str);
}

// Translate using Azure
foreach (var body in chunks)
{
try
{
var requestBody = JsonConvert.SerializeObject(body);

using var client = new HttpClient();
using var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri($"{endpoint}translate?api-version=3.0&from={from}&to={Settings.Default.TargetLanguage}"),
Content = new StringContent(requestBody, Encoding.UTF8, "application/json"),
};
request.Headers.Add("Ocp-Apim-Subscription-Key", Key);
request.Headers.Add("Ocp-Apim-Subscription-Region", Region);

var response = await client.SendAsync(request).ConfigureAwait(false);
var result = await response.Content.ReadAsStringAsync();

var json = JToken.Parse(result);
if (json.Type == JTokenType.Object)
{

if (((JObject)json).ContainsKey("error"))
throw new ApplicationException((string)json["error"]!["message"]!);
}
else if (json.Type == JTokenType.Array)
{
var tr = json.Select(j => j["translations"]![0]!["text"]!.Value<string>()!);
foreach (var (t, ms) in tr.Zip(body))
{
ms.Text = t;
}
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}

// Rebuild strings
var translations = allMStrings
.Select(x => string.Join("", x.Select(t => t.Text)))
.ToArray();

return translations;
}

public async Task<bool> TestAsync()
{
try
{
_ = await TranslateAsync(from: "en", "Hello, World!");
return true;
}
catch (Exception)
{
return false;
}
}
}
138 changes: 138 additions & 0 deletions SwordAndFairy7Translator/DeepLTranslator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using DeepL;
using PostSharp.Patterns.Model;

namespace SwordAndFairy7Translator
{
[NotifyPropertyChanged]
public class DeepLTranslator : ITranslatorService, INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null!)
=> PropertyChanged?.Invoke(this, new(propertyName));

private IEnumerable<Language>? languages;

public string Name => "DeepL";

[SafeForDependencyAnalysis]
public string? Key
{
get => Settings.Default.DeepLAPIKey;
set
{
Settings.Default.DeepLAPIKey = value;
OnPropertyChanged(nameof(Languages));
}
}
[SafeForDependencyAnalysis]
public bool UseFreeApi {
get => Settings.Default.DeepLUseFreeApi;
set
{
Settings.Default.DeepLUseFreeApi = value;
OnPropertyChanged(nameof(Languages));
}
}

[SafeForDependencyAnalysis]
public IEnumerable<Language>? Languages
{
get
{
if (languages is null)
{
Task.Run(async () =>
{
if (!await TestAsync()) return;
using var deepl = new DeepLClient(Key, UseFreeApi);
var langs = await deepl.GetSupportedLanguagesAsync();
languages = langs
.Select(l => new Language
{
Code = l.LanguageCode.ToLower(),
Name = l.Name,
});
});
}
return languages;
}
}

public async Task<bool> TestAsync()
{
using var deepl = new DeepLClient(Key, UseFreeApi);
try
{
await deepl.TranslateAsync("Hello, World!", Settings.Default.TargetLanguage);
return true;
}
catch
{
return false;
}

}

public async Task<IEnumerable<string>> TranslateAsync(string from, params string[] texts)
{
if (string.IsNullOrEmpty(Key)) return Enumerable.Empty<string>();

// split strings in substrings with or without html tags
var allMStrings = texts
.Select(text => TranslatorServiceHelper.GetMStrings(text))
.ToArray();

// Filter strings with html tags and those who don't have text to translate
var toTranslateMStrings = allMStrings
.SelectMany(x => x)
.Where(x => !Regex.IsMatch(x.Text, @"<[^>]+>") && Regex.IsMatch(x.Text, @"\p{L}"))
.ToArray();

// Create Chunks of 40k characters max
var chunks = new List<List<TranslatorServiceHelper.MString>>
{
new()
};
foreach (var str in toTranslateMStrings)
{
if (chunks.Last().Count >= 50 || chunks.Last().Sum(x => x.Text.Length) + str.Text.Length > 5000)
chunks.Add(new());
chunks.Last().Add(str);
}

using var deepl = new DeepLClient(Key, UseFreeApi);
// Translate using Azure
foreach (var body in chunks)
{
try
{
var tr = await deepl.TranslateAsync(body.Select(b => b.Text), Settings.Default.TargetLanguage);
foreach (var (t, ms) in tr.Zip(body))
{
ms.Text = t.Text;
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}

// Rebuild strings
var translations = allMStrings
.Select(x => string.Join("", x.Select(t => t.Text)))
.ToArray();

return translations;
}
}
}
5 changes: 5 additions & 0 deletions SwordAndFairy7Translator/Engine/Config/BaseEngine.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[DerivedDataBackendGraph]
Root=(Type=KeyLength, Length=120, Inner=AsyncPut)
AsyncPut=(Type=AsyncPut, Inner=Hierarchy)
Hierarchy=(Type=Hierarchical, Inner=Boot, Inner=Pak, Inner=EnginePak, Inner=Local, Inner=Shared)
Local=(Type=FileSystem, ReadOnly=false, Clean=false, Flush=false, PurgeTransient=true, DeleteUnused=true, UnusedFileAge=34, FoldersToClean=-1, PromptIfMissing=true, Path=%ENGINEDIR%DerivedDataCache, EnvPathOverride=UE-LocalDataCachePath, EditorOverrideSetting=LocalDerivedDataCache)
3 changes: 3 additions & 0 deletions SwordAndFairy7Translator/GlobalAspects.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using PostSharp.Patterns.Model;

[assembly: NotifyPropertyChanged(AttributeTargetTypes = "*ViewModel")]
Loading

0 comments on commit 78ac311

Please sign in to comment.