Skip to content

Commit

Permalink
fixed customization.yml editor opening, added rtl support for transla…
Browse files Browse the repository at this point in the history
…te view, sorted model languages by display name for easier use
  • Loading branch information
TommiNieminen committed May 2, 2024
1 parent 2627695 commit 738118c
Show file tree
Hide file tree
Showing 12 changed files with 641 additions and 25 deletions.
14 changes: 12 additions & 2 deletions AvaloniaApplication1/AvaloniaApplication1.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
<AssemblyName>OpusCatMtEngineCore</AssemblyName>
<RootNamespace>OpusCatMtEngine</RootNamespace>
<PlatformTarget>AnyCPU</PlatformTarget>
<Configurations>Debug;Release;DebugWsl;DebugMacos</Configurations>
<Version>1.3.0.0</Version>
<Configurations>Debug;Release;DebugWsl;DebugMacos;ReleaseLinux;ReleaseMacos</Configurations>
<Version>1.0.0.0</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<WarningLevel>4</WarningLevel>
Expand All @@ -22,11 +22,20 @@
<PlatformTarget>anycpu</PlatformTarget>
<DefineConstants>$(DefineConstants);LINUX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLinux|AnyCPU'">
<WarningLevel>4</WarningLevel>
<PlatformTarget>anycpu</PlatformTarget>
<DefineConstants>$(DefineConstants);LINUX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMacos|AnyCPU'">
<DefineConstants>$(DefineConstants);MACOS</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMacos|AnyCPU'">
<DefineConstants>$(DefineConstants);MACOS</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Remove="Images\cross.png" />
<None Remove="iso-639-3-macrolanguages.tab" />
<None Remove="iso-639-3_20200515.tab" />
<None Remove="iso639-5.tsv" />
<None Remove="TatoebaTestsets\af-de\tatoeba.af.txt" />
Expand Down Expand Up @@ -2763,6 +2772,7 @@
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="iso-639-3-macrolanguages.tab" />
<EmbeddedResource Include="iso-639-3_20200515.tab" />
<EmbeddedResource Include="iso639-5.tsv" />
</ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions AvaloniaApplication1/AvaloniaApplication1.csproj.user
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugWsl|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLinux|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup>
<ActiveDebugProfile>AvaloniaApplication1</ActiveDebugProfile>
</PropertyGroup>
Expand Down
51 changes: 51 additions & 0 deletions AvaloniaApplication1/IsoLanguage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Serilog;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -60,6 +61,27 @@ private static void ParseIso639_3()
}
}

private static void ParseIso639_3MacroMappings()
{
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly(), "");
using (var isoTable = new StreamReader(embeddedProvider.GetFileInfo("OpusCatMtEngine.iso-639-3-macrolanguages.tab").CreateReadStream()))
{

//Skip header
isoTable.ReadLine();

string line;
while ((line = isoTable.ReadLine()) != null)
{
var split = line.Split('\t');
var iso639_3_macro = split[0];
var iso639_3_micro = split[1];
IsoLanguage.Iso639_3MacroMappings[iso639_3_micro] = iso639_3_macro;

}
}
}

private static void ParseIso639_5()
{
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly(), "");
Expand All @@ -85,12 +107,14 @@ static IsoLanguage()
{
IsoLanguage.ParseIso639_3();
IsoLanguage.ParseIso639_5();
IsoLanguage.ParseIso639_3MacroMappings();
}

private static Dictionary<string, string> Iso639_3To639_1 = new Dictionary<string, string>();
private static Dictionary<string, string> Iso639_1To639_3 = new Dictionary<string, string>();
private static Dictionary<string, string> Iso639_2BTo639_3 = new Dictionary<string, string>();
private static Dictionary<string, string> Iso639_3ToRefName = new Dictionary<string, string>();
private static Dictionary<string, string> Iso639_3MacroMappings = new Dictionary<string, string>();
private static Dictionary<string, string> Iso639_5ToRefName = new Dictionary<string, string>();

public string Iso639_5Code { get; set; }
Expand Down Expand Up @@ -130,6 +154,33 @@ public string ShortestIsoCode
public string Iso15924Script { get; set; }
public string IsoRefName { get; }
public string OriginalCode { get; }
public bool IsRightToLeft
{
get
{
List<CultureInfo> CultureInfos = CultureInfo
.GetCultures(CultureTypes.SpecificCultures)
.ToList();

foreach (CultureInfo cultureInfo in CultureInfos)
{
if (cultureInfo.TwoLetterISOLanguageName == this.Iso639_1Code ||
cultureInfo.ThreeLetterISOLanguageName == this.Iso639_3Code)
{
return cultureInfo.TextInfo.IsRightToLeft;
}
else if (IsoLanguage.Iso639_3MacroMappings.ContainsKey(this.Iso639_3Code))
{
if (cultureInfo.ThreeLetterISOLanguageName == IsoLanguage.Iso639_3MacroMappings[this.Iso639_3Code])
{
return cultureInfo.TextInfo.IsRightToLeft;
}
}
}

return false;
}
}

//This constructor parses the code.
//The language code may be from a MT model, Opus MT models generally have ISO-639-1 codes if possible,
Expand Down
7 changes: 5 additions & 2 deletions AvaloniaApplication1/MTModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,8 @@ public List<IsoLanguage> SourceLanguages
get => sourceLanguages;
set
{
sourceLanguages = value;
var sortedLangs = value.OrderBy(x => x.IsoRefName);
sourceLanguages = sortedLangs.ToList();
NotifyPropertyChanged("SourceLanguageString");
}
}
Expand All @@ -656,7 +657,9 @@ public List<IsoLanguage> TargetLanguages
get => targetLanguages;
set
{
targetLanguages = value;
var sortedLangs = value.OrderBy(x => x.IsoRefName);
targetLanguages = sortedLangs.ToList();

NotifyPropertyChanged("TargetLanguageString");
}
}
Expand Down
4 changes: 2 additions & 2 deletions AvaloniaApplication1/Marian/MarianProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ public MarianProcess(
{
this.preprocessor =
new MosesBpePreprocessor(
$"{this.modelDir}\\source.tcmodel",
$"{this.modelDir}\\source.bpe",
Path.Combine(this.modelDir,"source.tcmodel"),
Path.Combine(this.modelDir,"source.bpe"),
this.SourceCode, this.TargetCode);

this.segmentation = SegmentationMethod.Bpe;
Expand Down
43 changes: 31 additions & 12 deletions AvaloniaApplication1/OWIN/OwinMtService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using LiveChartsCore;

namespace OpusCatMtEngine
{
Expand All @@ -24,26 +25,31 @@ public OwinMtService(ModelManager modelManager)
if (OpusCatMtEngineSettings.Default.AllowRemoteUse)
{
baseAddress = $"http://+:{OpusCatMtEngineSettings.Default.HttpMtServicePort}";

//First try to open the external http listener, this requires admin (or a prior
//reservation of the port with netsh)
try
{
this.StartWebApp(baseAddress, modelManager);
Log.Information($"Started HTTP API at http://+:{OpusCatMtEngineSettings.Default.HttpMtServicePort}. This API can be accessed from remote computers, if the firewall has been configured to allow it.");
}
//If opening the external listener fails, open a localhost listener (works without admin).
catch (Exception ex)
{
this.StartWebApp($"http://localhost:{OpusCatMtEngineSettings.Default.HttpMtServicePort}", modelManager);
Log.Information($"Started HTTP API at http://localhost:{OpusCatMtEngineSettings.Default.HttpMtServicePort}. This API cannot be accessed from remote computers.");
}
}
else
{
baseAddress = $"http://localhost:{OpusCatMtEngineSettings.Default.HttpMtServicePort}";
}

//First try to open the external http listener, this requires admin (or a prior
//reservation of the port with netsh)
try
{
this.StartWebApp($"http://+:{OpusCatMtEngineSettings.Default.HttpMtServicePort}", modelManager);
Log.Information($"Started HTTP API at http://+:{OpusCatMtEngineSettings.Default.HttpMtServicePort}. This API can be accessed from remote computers, if the firewall has been configured to allow it.");
}
//If opening the external listener fails, open a localhost listener (works without admin).
catch (Exception ex)
{
this.StartWebApp($"http://localhost:{OpusCatMtEngineSettings.Default.HttpMtServicePort}", modelManager);
Log.Information($"Started HTTP API at http://localhost:{OpusCatMtEngineSettings.Default.HttpMtServicePort}. This API cannot be accessed from remote computers.");
}



}

private void StartWebApp(string baseAddress, ModelManager modelManager)
Expand All @@ -52,12 +58,25 @@ private void StartWebApp(string baseAddress, ModelManager modelManager)
builder.Services.AddControllers().AddJsonOptions(
options => { options.JsonSerializerOptions.PropertyNamingPolicy = null; options.JsonSerializerOptions.PropertyNameCaseInsensitive = false; });
builder.Services.AddSingleton<IMtProvider>(modelManager);
var app = builder.Build();

builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.AllowAnyOrigin();
builder.AllowAnyHeader();
builder.AllowAnyMethod();
});
});
;
var app = builder.Build();
app.UseCors();
app.UseRouting();
app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action}");

app.RunAsync(baseAddress);

}
Expand Down
2 changes: 2 additions & 0 deletions AvaloniaApplication1/OpusCatMtEngine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
LD_LIBRARY_PATH=$LD_LIBRARY_PATH./python3-linux-3.8.13-x86_64/lib/ PYTHONHOME=./python3-linux-3.8.13-x86_64/ ./OpusCatMtEngineCore
30 changes: 28 additions & 2 deletions AvaloniaApplication1/UI/OpusCatSettingsView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using Avalonia.Markup.Xaml;
using Avalonia.VisualTree;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using MsBox.Avalonia.Enums;
using MsBox.Avalonia;
using OpusCatMtEngine;
using OpusCatMtEngine.UI;
using System;
Expand All @@ -14,6 +16,7 @@
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using static System.Runtime.InteropServices.JavaScript.JSType;

Expand Down Expand Up @@ -59,10 +62,33 @@ private void SettingsControl_Loaded(object? sender, RoutedEventArgs e)
NotifyPropertyChanged("SaveButtonEnabled");
}

public void OpenCustomSettingsInEditor_Click(object sender, RoutedEventArgs e)
public async void OpenCustomSettingsInEditor_Click(object sender, RoutedEventArgs e)
{
var customizeYml = HelperFunctions.GetOpusCatDataPath(OpusCatMtEngineSettings.Default.CustomizationBaseConfig);
Process.Start("notepad.exe", customizeYml);
try
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Process.Start(new ProcessStartInfo("cmd", $"/c start {customizeYml}"));
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Process.Start("xdg-open", customizeYml);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
Process.Start("open", customizeYml);
}
}
catch (Exception ex)
{
string messageBoxText = "Could not open customize.yml in a text editor.";
var box = MessageBoxManager.GetMessageBoxStandard(
"Cannot open editor",
messageBoxText,
ButtonEnum.Ok);
var result = await box.ShowAsync();
}
}


Expand Down
42 changes: 42 additions & 0 deletions AvaloniaApplication1/UI/RightToLeftConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Avalonia.Data.Converters;
using Avalonia.Data;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Media;

namespace OpusCatMtEngine
{
public class RightToLeftConverter : IValueConverter
{
public static readonly RightToLeftConverter Instance = new();

public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Boolean isRtl
&& targetType.IsAssignableTo(typeof(FlowDirection)))
{
if (isRtl)
{
return FlowDirection.RightToLeft;
}
else
{
return FlowDirection.LeftToRight;
}

}

// converter used for the wrong type
return new BindingNotification(new InvalidCastException(), BindingErrorType.Error);
}

public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}
9 changes: 6 additions & 3 deletions AvaloniaApplication1/UI/TranslateView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
xmlns:resx="clr-namespace:OpusCatMtEngine.Properties"
x:Name="_this"
x:CompileBindings="False">
<UserControl.Resources>
<local:RightToLeftConverter x:Key="rtlConverter"/>
</UserControl.Resources>
<Grid>
<StackPanel Margin="10">
<Label>Note: This translation functionality is intended mainly for testing models. Sentences of the source text should be on separate lines.</Label>
Expand Down Expand Up @@ -39,9 +42,9 @@
</DockPanel>
<Border BorderThickness="1" BorderBrush="Black">
<Grid>
<TextBox TextWrapping="Wrap" IsVisible="{Binding !TranslationActive, Mode=TwoWay}" AcceptsReturn="True" Name="SourceInputBox" Height="120"></TextBox>
<TextBox FlowDirection="{Binding ElementName=_this, Path=SourceLanguage.IsRightToLeft, Converter={StaticResource rtlConverter}}" TextWrapping="Wrap" IsVisible="{Binding !TranslationActive, Mode=TwoWay}" AcceptsReturn="True" Name="SourceInputBox" Height="120"></TextBox>
<ScrollViewer Height="120" IsVisible="{Binding TranslationActive, Mode=TwoWay}" >
<SelectableTextBlock TextWrapping="Wrap" Name="SourceBoxDisplay"></SelectableTextBlock>
<SelectableTextBlock FlowDirection="{Binding ElementName=_this, Path=SourceLanguage.IsRightToLeft, Converter={StaticResource rtlConverter}}" TextWrapping="Wrap" Name="SourceBoxDisplay"></SelectableTextBlock>
</ScrollViewer>
</Grid>
</Border>
Expand All @@ -64,7 +67,7 @@
<Label Content="{x:Static resx:Resources.Translate_TranslationLabel}"/>
<Border BorderThickness="1" BorderBrush="Black">
<ScrollViewer Height="120" >
<TextBlock Name="TargetBox" TextWrapping="Wrap" />
<TextBlock FlowDirection="{Binding ElementName=_this, Path=TargetLanguage.IsRightToLeft, Converter={StaticResource rtlConverter}}" Name="TargetBox" TextWrapping="Wrap" />
</ScrollViewer>
</Border>
</StackPanel>
Expand Down
4 changes: 2 additions & 2 deletions AvaloniaApplication1/UI/TranslateView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public IsoLanguage SourceLanguage
get => sourceLanguage;
set
{
NotifyPropertyChanged();
sourceLanguage = value;
NotifyPropertyChanged();
}
}

Expand All @@ -76,8 +76,8 @@ public IsoLanguage TargetLanguage
get => targetLanguage;
set
{
NotifyPropertyChanged();
targetLanguage = value;
NotifyPropertyChanged();
}
}

Expand Down
Loading

0 comments on commit 738118c

Please sign in to comment.