diff --git a/AvaloniaApplication1/AvaloniaApplication1.csproj b/AvaloniaApplication1/AvaloniaApplication1.csproj
index 6820ad7..0ece434 100644
--- a/AvaloniaApplication1/AvaloniaApplication1.csproj
+++ b/AvaloniaApplication1/AvaloniaApplication1.csproj
@@ -9,8 +9,8 @@
OpusCatMtEngineCoreOpusCatMtEngineAnyCPU
- Debug;Release;DebugWsl;DebugMacos
- 1.3.0.0
+ Debug;Release;DebugWsl;DebugMacos;ReleaseLinux;ReleaseMacos
+ 1.0.0.04
@@ -22,11 +22,20 @@
anycpu$(DefineConstants);LINUX
+
+ 4
+ anycpu
+ $(DefineConstants);LINUX
+ $(DefineConstants);MACOS
+
+ $(DefineConstants);MACOS
+
+
@@ -2763,6 +2772,7 @@
+
diff --git a/AvaloniaApplication1/AvaloniaApplication1.csproj.user b/AvaloniaApplication1/AvaloniaApplication1.csproj.user
index 75a8667..4f1b814 100644
--- a/AvaloniaApplication1/AvaloniaApplication1.csproj.user
+++ b/AvaloniaApplication1/AvaloniaApplication1.csproj.user
@@ -6,6 +6,9 @@
ProjectDebugger
+
+ ProjectDebugger
+ AvaloniaApplication1
diff --git a/AvaloniaApplication1/IsoLanguage.cs b/AvaloniaApplication1/IsoLanguage.cs
index e0cbc74..01a4bba 100644
--- a/AvaloniaApplication1/IsoLanguage.cs
+++ b/AvaloniaApplication1/IsoLanguage.cs
@@ -2,6 +2,7 @@
using Serilog;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -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(), "");
@@ -85,12 +107,14 @@ static IsoLanguage()
{
IsoLanguage.ParseIso639_3();
IsoLanguage.ParseIso639_5();
+ IsoLanguage.ParseIso639_3MacroMappings();
}
private static Dictionary Iso639_3To639_1 = new Dictionary();
private static Dictionary Iso639_1To639_3 = new Dictionary();
private static Dictionary Iso639_2BTo639_3 = new Dictionary();
private static Dictionary Iso639_3ToRefName = new Dictionary();
+ private static Dictionary Iso639_3MacroMappings = new Dictionary();
private static Dictionary Iso639_5ToRefName = new Dictionary();
public string Iso639_5Code { get; set; }
@@ -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 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,
diff --git a/AvaloniaApplication1/MTModel.cs b/AvaloniaApplication1/MTModel.cs
index 10eb3e7..39954f2 100644
--- a/AvaloniaApplication1/MTModel.cs
+++ b/AvaloniaApplication1/MTModel.cs
@@ -646,7 +646,8 @@ public List SourceLanguages
get => sourceLanguages;
set
{
- sourceLanguages = value;
+ var sortedLangs = value.OrderBy(x => x.IsoRefName);
+ sourceLanguages = sortedLangs.ToList();
NotifyPropertyChanged("SourceLanguageString");
}
}
@@ -656,7 +657,9 @@ public List TargetLanguages
get => targetLanguages;
set
{
- targetLanguages = value;
+ var sortedLangs = value.OrderBy(x => x.IsoRefName);
+ targetLanguages = sortedLangs.ToList();
+
NotifyPropertyChanged("TargetLanguageString");
}
}
diff --git a/AvaloniaApplication1/Marian/MarianProcess.cs b/AvaloniaApplication1/Marian/MarianProcess.cs
index c0f5042..92e267f 100644
--- a/AvaloniaApplication1/Marian/MarianProcess.cs
+++ b/AvaloniaApplication1/Marian/MarianProcess.cs
@@ -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;
diff --git a/AvaloniaApplication1/OWIN/OwinMtService.cs b/AvaloniaApplication1/OWIN/OwinMtService.cs
index 35d5306..8406a49 100644
--- a/AvaloniaApplication1/OWIN/OwinMtService.cs
+++ b/AvaloniaApplication1/OWIN/OwinMtService.cs
@@ -12,6 +12,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
+using LiveChartsCore;
namespace OpusCatMtEngine
{
@@ -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)
@@ -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(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);
}
diff --git a/AvaloniaApplication1/OpusCatMtEngine.sh b/AvaloniaApplication1/OpusCatMtEngine.sh
new file mode 100644
index 0000000..10ab9b4
--- /dev/null
+++ b/AvaloniaApplication1/OpusCatMtEngine.sh
@@ -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
\ No newline at end of file
diff --git a/AvaloniaApplication1/UI/OpusCatSettingsView.axaml.cs b/AvaloniaApplication1/UI/OpusCatSettingsView.axaml.cs
index 94f1398..e6f1f37 100644
--- a/AvaloniaApplication1/UI/OpusCatSettingsView.axaml.cs
+++ b/AvaloniaApplication1/UI/OpusCatSettingsView.axaml.cs
@@ -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;
@@ -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;
@@ -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();
+ }
}
diff --git a/AvaloniaApplication1/UI/RightToLeftConverter.cs b/AvaloniaApplication1/UI/RightToLeftConverter.cs
new file mode 100644
index 0000000..50b3a80
--- /dev/null
+++ b/AvaloniaApplication1/UI/RightToLeftConverter.cs
@@ -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();
+ }
+ }
+}
diff --git a/AvaloniaApplication1/UI/TranslateView.axaml b/AvaloniaApplication1/UI/TranslateView.axaml
index b82615e..a002161 100644
--- a/AvaloniaApplication1/UI/TranslateView.axaml
+++ b/AvaloniaApplication1/UI/TranslateView.axaml
@@ -8,6 +8,9 @@
xmlns:resx="clr-namespace:OpusCatMtEngine.Properties"
x:Name="_this"
x:CompileBindings="False">
+
+
+
@@ -39,9 +42,9 @@
-
+
-
+
@@ -64,7 +67,7 @@
-
+
diff --git a/AvaloniaApplication1/UI/TranslateView.axaml.cs b/AvaloniaApplication1/UI/TranslateView.axaml.cs
index fa34aac..e9ff906 100644
--- a/AvaloniaApplication1/UI/TranslateView.axaml.cs
+++ b/AvaloniaApplication1/UI/TranslateView.axaml.cs
@@ -66,8 +66,8 @@ public IsoLanguage SourceLanguage
get => sourceLanguage;
set
{
- NotifyPropertyChanged();
sourceLanguage = value;
+ NotifyPropertyChanged();
}
}
@@ -76,8 +76,8 @@ public IsoLanguage TargetLanguage
get => targetLanguage;
set
{
- NotifyPropertyChanged();
targetLanguage = value;
+ NotifyPropertyChanged();
}
}
diff --git a/AvaloniaApplication1/iso-639-3-macrolanguages.tab b/AvaloniaApplication1/iso-639-3-macrolanguages.tab
new file mode 100644
index 0000000..dbf2285
--- /dev/null
+++ b/AvaloniaApplication1/iso-639-3-macrolanguages.tab
@@ -0,0 +1,457 @@
+M_Id I_Id I_Status
+aka fat A
+aka twi A
+ara aao A
+ara abh A
+ara abv A
+ara acm A
+ara acq A
+ara acw A
+ara acx A
+ara acy A
+ara adf A
+ara aeb A
+ara aec A
+ara afb A
+ara ajp R
+ara apc A
+ara apd A
+ara arb A
+ara arq A
+ara ars A
+ara ary A
+ara arz A
+ara auz A
+ara avl A
+ara ayh A
+ara ayl A
+ara ayn A
+ara ayp A
+ara bbz R
+ara pga A
+ara shu A
+ara ssh A
+aym ayc A
+aym ayr A
+aze azb A
+aze azj A
+bal bcc A
+bal bgn A
+bal bgp A
+bik bcl A
+bik bhk R
+bik bln A
+bik bto A
+bik cts A
+bik fbl A
+bik lbl A
+bik rbl A
+bik ubl A
+bnc ebk A
+bnc lbk A
+bnc obk A
+bnc rbk A
+bnc vbk A
+bua bxm A
+bua bxr A
+bua bxu A
+chm mhr A
+chm mrj A
+cre crj A
+cre crk A
+cre crl A
+cre crm A
+cre csw A
+cre cwd A
+del umu A
+del unm A
+den scs A
+den xsl A
+din dib A
+din dik A
+din dip A
+din diw A
+din dks A
+doi dgo A
+doi xnr A
+est ekk A
+est vro A
+fas pes A
+fas prs A
+ful ffm A
+ful fub A
+ful fuc A
+ful fue A
+ful fuf A
+ful fuh A
+ful fui A
+ful fuq A
+ful fuv A
+gba bdt A
+gba gbp A
+gba gbq A
+gba gmm A
+gba gso A
+gba gya A
+gba mdo R
+gon esg A
+gon ggo R
+gon gno A
+gon wsg A
+grb gbo A
+grb gec A
+grb grj A
+grb grv A
+grb gry A
+grn gnw A
+grn gug A
+grn gui A
+grn gun A
+grn nhd A
+hai hax A
+hai hdn A
+hbs bos A
+hbs cnr A
+hbs hrv A
+hbs srp A
+hmn blu R
+hmn cqd A
+hmn hea A
+hmn hma A
+hmn hmc A
+hmn hmd A
+hmn hme A
+hmn hmg A
+hmn hmh A
+hmn hmi A
+hmn hmj A
+hmn hml A
+hmn hmm A
+hmn hmp A
+hmn hmq A
+hmn hms A
+hmn hmw A
+hmn hmy A
+hmn hmz A
+hmn hnj A
+hmn hrm A
+hmn huj A
+hmn mmr A
+hmn muq A
+hmn mww A
+hmn sfm A
+iku ike A
+iku ikt A
+ipk esi A
+ipk esk A
+jrb ajt R
+jrb aju A
+jrb jye A
+jrb yhd A
+jrb yud A
+kau kby A
+kau knc A
+kau krt A
+kln enb A
+kln eyo A
+kln niq A
+kln oki A
+kln pko A
+kln sgc A
+kln spy A
+kln tec A
+kln tuy A
+kok gom A
+kok knn A
+kom koi A
+kom kpv A
+kon kng A
+kon kwy A
+kon ldi A
+kpe gkp A
+kpe xpe A
+kur ckb A
+kur kmr A
+kur sdh A
+lah hnd A
+lah hno A
+lah jat A
+lah phr A
+lah pmu R
+lah pnb A
+lah skr A
+lah xhe A
+lav ltg A
+lav lvs A
+luy bxk A
+luy ida A
+luy lkb A
+luy lko A
+luy lks A
+luy lri A
+luy lrm A
+luy lsm A
+luy lto A
+luy lts A
+luy lwg A
+luy nle A
+luy nyd A
+luy rag A
+man emk A
+man mku A
+man mlq A
+man mnk A
+man msc A
+man mwk A
+man myq R
+mlg bhr A
+mlg bjq R
+mlg bmm A
+mlg bzc A
+mlg msh A
+mlg plt A
+mlg skg A
+mlg tdx A
+mlg tkg A
+mlg txy A
+mlg xmv A
+mlg xmw A
+mon khk A
+mon mvf A
+msa bjn A
+msa btj A
+msa bve A
+msa bvu A
+msa coa A
+msa dup A
+msa hji A
+msa ind A
+msa jak A
+msa jax A
+msa kvb A
+msa kvr A
+msa kxd A
+msa lce A
+msa lcf A
+msa liw A
+msa max A
+msa meo A
+msa mfa A
+msa mfb A
+msa min A
+msa mly R
+msa mqg A
+msa msi A
+msa mui A
+msa orn A
+msa ors A
+msa pel A
+msa pse A
+msa tmw A
+msa urk A
+msa vkk A
+msa vkt A
+msa xmm A
+msa zlm A
+msa zmi A
+msa zsm A
+mwr dhd A
+mwr mtr A
+mwr mve A
+mwr rwr A
+mwr swv A
+mwr wry A
+nep dty A
+nep npi A
+nor nno A
+nor nob A
+oji ciw A
+oji ojb A
+oji ojc A
+oji ojg A
+oji ojs A
+oji ojw A
+oji otw A
+ori ory A
+ori spv A
+orm gax A
+orm gaz A
+orm hae A
+orm orc A
+pus pbt A
+pus pbu A
+pus pst A
+que cqu R
+que qub A
+que qud A
+que quf A
+que qug A
+que quh A
+que quk A
+que qul A
+que qup A
+que qur A
+que qus A
+que quw A
+que qux A
+que quy A
+que quz A
+que qva A
+que qvc A
+que qve A
+que qvh A
+que qvi A
+que qvj A
+que qvl A
+que qvm A
+que qvn A
+que qvo A
+que qvp A
+que qvs A
+que qvw A
+que qvz A
+que qwa A
+que qwc A
+que qwh A
+que qws A
+que qxa A
+que qxc A
+que qxh A
+que qxl A
+que qxn A
+que qxo A
+que qxp A
+que qxr A
+que qxt A
+que qxu A
+que qxw A
+raj bgq A
+raj gda A
+raj gju A
+raj hoj A
+raj mup A
+raj wbr A
+rom rmc A
+rom rmf A
+rom rml A
+rom rmn A
+rom rmo A
+rom rmw A
+rom rmy A
+san cls A
+san vsn A
+sqi aae A
+sqi aat A
+sqi aln A
+sqi als A
+srd sdc A
+srd sdn A
+srd src A
+srd sro A
+swa swc A
+swa swh A
+syr aii A
+syr cld A
+tmh taq A
+tmh thv A
+tmh thz A
+tmh ttq A
+uzb uzn A
+uzb uzs A
+yid ydd A
+yid yih A
+zap zaa A
+zap zab A
+zap zac A
+zap zad A
+zap zae A
+zap zaf A
+zap zai A
+zap zam A
+zap zao A
+zap zaq A
+zap zar A
+zap zas A
+zap zat A
+zap zav A
+zap zaw A
+zap zax A
+zap zca A
+zap zcd A
+zap zoo A
+zap zpa A
+zap zpb A
+zap zpc A
+zap zpd A
+zap zpe A
+zap zpf A
+zap zpg A
+zap zph A
+zap zpi A
+zap zpj A
+zap zpk A
+zap zpl A
+zap zpm A
+zap zpn A
+zap zpo A
+zap zpp A
+zap zpq A
+zap zpr A
+zap zps A
+zap zpt A
+zap zpu A
+zap zpv A
+zap zpw A
+zap zpx A
+zap zpy A
+zap zpz A
+zap zsr A
+zap ztc R
+zap zte A
+zap ztg A
+zap ztl A
+zap ztm A
+zap ztn A
+zap ztp A
+zap ztq A
+zap zts A
+zap ztt A
+zap ztu A
+zap ztx A
+zap zty A
+zha ccx R
+zha ccy R
+zha zch A
+zha zeh A
+zha zgb A
+zha zgm A
+zha zgn A
+zha zhd A
+zha zhn A
+zha zlj A
+zha zln A
+zha zlq A
+zha zqe A
+zha zyb A
+zha zyg A
+zha zyj A
+zha zyn A
+zha zzj A
+zho cdo A
+zho cjy A
+zho cmn A
+zho cnp A
+zho cpx A
+zho csp A
+zho czh A
+zho czo A
+zho gan A
+zho hak A
+zho hsn A
+zho lzh A
+zho mnp A
+zho nan A
+zho wuu A
+zho yue A
+zza diq A
+zza kiu A