Skip to content

Commit

Permalink
feat: Add Local Service Translation
Browse files Browse the repository at this point in the history
  • Loading branch information
ZGGSONG committed Feb 1, 2024
1 parent b3b637e commit 0c82e66
Show file tree
Hide file tree
Showing 15 changed files with 274 additions and 9 deletions.
1 change: 1 addition & 0 deletions STranslate.Model/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public enum ServiceType
NiutransService,
CaiyunService,
VolcengineService,
STranslateService,
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions STranslate.Style/Styles/Themes/ColorDark.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,5 @@

<!-- // Other // -->
<SolidColorBrush x:Key="OfficialServiceColor">#e6c619</SolidColorBrush>
<SolidColorBrush x:Key="UnOfficialServiceColor">#7CCD7C</SolidColorBrush>
</ResourceDictionary>
1 change: 1 addition & 0 deletions STranslate.Style/Styles/Themes/ColorLight.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,5 @@

<!-- // Other // -->
<SolidColorBrush x:Key="OfficialServiceColor">#e6c619</SolidColorBrush>
<SolidColorBrush x:Key="UnOfficialServiceColor">#7CCD7C</SolidColorBrush>
</ResourceDictionary>
9 changes: 5 additions & 4 deletions STranslate.Util/Volcengine.cs → STranslate.Util/GoUtil.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace STranslate.Util
{
public class Volcengine
public class GoUtil
{
[DllImport("volcengine.dll", EntryPoint = "Execute", CallingConvention = CallingConvention.Cdecl)]
public static extern GoTuple Execute(byte[] appid, byte[] appkey, byte[] source, byte[] target, byte[] content);

[DllImport("zstranslator.dll", EntryPoint = "Execute", CallingConvention = CallingConvention.Cdecl)]
public static extern GoString Execute(byte[] source, byte[] target, byte[] content);


public struct GoTuple
{
public int intValue;
Expand Down
4 changes: 4 additions & 0 deletions STranslate.Util/STranslate.Util.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<ItemGroup>
<None Remove="volcengine.dll" />
<None Remove="zstranslator.dll" />
</ItemGroup>

<ItemGroup>
Expand All @@ -31,6 +32,9 @@
<Content Include="volcengine.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="zstranslator.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
Expand Down
Binary file added STranslate.Util/zstranslator.dll
Binary file not shown.
6 changes: 4 additions & 2 deletions STranslate/Helper/ConfigHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,9 @@ private ConfigModel InitialConfig()
TargetLanguage = LanguageEnum.AUTO.GetDescription(),
Services =
[
new TranslatorApi(Guid.NewGuid(), "https://deeplx.deno.dev/translate", "DeepL"),
new TranslatorApi(Guid.NewGuid(), "https://googlet.deno.dev/translate", "Google", IconType.Google, isEnabled: true),
new TranslatorSTranslate(Guid.NewGuid(), "", "STranslate", IconType.STranslate),
new TranslatorApi(Guid.NewGuid(), "https://googlet.deno.dev/translate", "Google", IconType.Google),
new TranslatorApi(Guid.NewGuid(), "https://deeplx.deno.dev/translate", "DeepL", IconType.DeepL),
new TranslatorApi(Guid.NewGuid(), "https://iciba.deno.dev/translate", "爱词霸", IconType.Iciba, isEnabled: false)
]
};
Expand Down Expand Up @@ -320,6 +321,7 @@ JsonSerializer serializer

ITranslator translator = type switch
{
(int)ServiceType.STranslateService => new TranslatorSTranslate(),
(int)ServiceType.ApiService => new TranslatorApi(),
(int)ServiceType.BaiduService => new TranslatorBaidu(),
(int)ServiceType.MicrosoftService => new TranslatorMicrosoft(),
Expand Down
1 change: 1 addition & 0 deletions STranslate/ViewModels/InputViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ public override ITranslator ReadJson(JsonReader reader, Type objectType, ITransl
translators.FirstOrDefault(x => x.Identify.ToString() == identify)
?? type switch
{
(int)ServiceType.STranslateService => new TranslatorSTranslate(),
(int)ServiceType.BaiduService => new TranslatorBaidu(),
(int)ServiceType.MicrosoftService => new TranslatorMicrosoft(),
(int)ServiceType.OpenAIService => new TranslatorOpenAI(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public override ITranslator ReadJson(JsonReader reader, Type objectType, ITransl

ITranslator translator = type switch
{
(int)ServiceType.STranslateService => new TranslatorSTranslate(),
(int)ServiceType.ApiService => new TranslatorApi(),
(int)ServiceType.BaiduService => new TranslatorBaidu(),
(int)ServiceType.MicrosoftService => new TranslatorMicrosoft(),
Expand Down
3 changes: 3 additions & 0 deletions STranslate/ViewModels/Preference/ServiceViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public ServiceViewModel()
{
//添加默认支持服务
//TODO: 新接口需要适配
TransServices.Add(new TranslatorSTranslate());
TransServices.Add(new TranslatorApi());
TransServices.Add(new TranslatorOpenAI());
TransServices.Add(new TranslatorGemini());
Expand Down Expand Up @@ -90,6 +91,7 @@ private void TogglePage(ITranslator service)
//TODO: 新接口需要适配
var name = service.Type switch
{
ServiceType.STranslateService => string.Format("{0}TextSTranslateServicesPage", head),
ServiceType.ApiService => string.Format("{0}TextApiServicePage", head),
ServiceType.BaiduService => string.Format("{0}TextBaiduServicesPage", head),
ServiceType.MicrosoftService => string.Format("{0}TextMicrosoftServicesPage", head),
Expand Down Expand Up @@ -121,6 +123,7 @@ private void Add(List<object> list)
//TODO: 新接口需要适配
CurTransServiceList.Add(service switch
{
TranslatorSTranslate stranslate => stranslate.DeepClone(),
TranslatorApi api => api.DeepClone(),
TranslatorBaidu baidu => baidu.DeepClone(),
TranslatorMicrosoft bing => bing.DeepClone(),
Expand Down
148 changes: 148 additions & 0 deletions STranslate/ViewModels/Preference/Services/TranslatorSTranslate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using STranslate.Model;
using STranslate.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace STranslate.ViewModels.Preference.Services
{
public partial class TranslatorSTranslate : ObservableObject, ITranslator
{
public TranslatorSTranslate()
: this(Guid.NewGuid(), "", "STranslate") { }

public TranslatorSTranslate(
Guid guid,
string url,
string name = "",
IconType icon = IconType.STranslate,
string appID = "",
string appKey = "",
bool isEnabled = true,
ServiceType type = ServiceType.STranslateService
)
{
Identify = guid;
Url = url;
Name = name;
Icon = icon;
AppID = appID;
AppKey = appKey;
IsEnabled = isEnabled;
Type = type;
}

[ObservableProperty]
private Guid _identify = Guid.Empty;

[JsonIgnore]
[ObservableProperty]
private ServiceType _type = 0;

[JsonIgnore]
[ObservableProperty]
public bool _isEnabled = true;

[JsonIgnore]
[ObservableProperty]
private string _name = string.Empty;

[JsonIgnore]
[ObservableProperty]
private IconType _icon = IconType.STranslate;

[JsonIgnore]
[ObservableProperty]
public string _url = string.Empty;

[JsonIgnore]
[ObservableProperty]
public string _AppID = string.Empty;

[JsonIgnore]
[ObservableProperty]
public string _appKey = string.Empty;

[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
public TranslationResult _data = TranslationResult.Reset;

[JsonIgnore]
public List<IconType> Icons { get; private set; } = Enum.GetValues(typeof(IconType)).OfType<IconType>().ToList();

[JsonIgnore]
public string Tips { get; set; } = "本地服务,无需配置";

#region Show/Hide Encrypt Info

[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
private bool _idHide = true;

[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
private bool _keyHide = true;

private void ShowEncryptInfo(string? obj)
{
if (obj == null)
return;

if (obj.Equals(nameof(AppID)))
{
IdHide = !IdHide;
}
else if (obj.Equals(nameof(AppKey)))
{
KeyHide = !KeyHide;
}
}

private RelayCommand<string>? showEncryptInfoCommand;

[JsonIgnore]
public IRelayCommand<string> ShowEncryptInfoCommand => showEncryptInfoCommand ??= new RelayCommand<string>(new Action<string?>(ShowEncryptInfo));

#endregion Show/Hide Encrypt Info

public async Task<TranslationResult> TranslateAsync(object request, CancellationToken token)
{
if (request is RequestModel req)
{
//https://github.com/Baozisoftware/go-dll/wiki/C%23%E8%B0%83%E7%94%A8Go%E7%89%88DLL#%E5%85%B3%E4%BA%8Ego%E7%9A%84%E6%95%B0%E7%BB%84%E5%88%87%E7%89%87%E8%BF%94%E5%9B%9E%E9%97%AE%E9%A2%98
//加入这个就不崩溃了
Environment.SetEnvironmentVariable("GODEBUG", "cgocheck=0");
var sourceBytes = Encoding.UTF8.GetBytes(req.SourceLang);
var targetBytes = Encoding.UTF8.GetBytes(req.TargetLang);
var contentBytes = Encoding.UTF8.GetBytes(req.Text);
var result = await Task.Run(() => GoUtil.Execute(sourceBytes, targetBytes, contentBytes));
var resp = GoUtil.GoStringToCSharpString(result);

// 解析JSON数据
var parsedData = JsonConvert.DeserializeObject<JObject>(resp ?? throw new Exception("请求结果为空")) ?? throw new Exception($"反序列化失败: {resp}");

// 提取content的值
var data = parsedData["data"]?.ToString() ?? throw new Exception("未获取到结果");

return string.IsNullOrEmpty(data) ? TranslationResult.Fail("获取结果为空") : TranslationResult.Success(data);
}

throw new Exception($"请求数据出错: {request}");
}

public Task TranslateAsync(object request, Action<string> OnDataReceived, CancellationToken token)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ public async Task<TranslationResult> TranslateAsync(object request, Cancellation
var sourceBytes = Encoding.UTF8.GetBytes(req.SourceLang.ToLower());
var targetBytes = Encoding.UTF8.GetBytes(req.TargetLang.ToLower());
var contentBytes = Encoding.UTF8.GetBytes(req.Text);
var result = await Task.Run(() => Volcengine.Execute(accessKeyBytes, secretKeyBytes, sourceBytes, targetBytes, contentBytes));
var tuple = Volcengine.GoTupleToCSharpTuple(result);
var result = await Task.Run(() => GoUtil.Execute(accessKeyBytes, secretKeyBytes, sourceBytes, targetBytes, contentBytes));
var tuple = GoUtil.GoTupleToCSharpTuple(result);
var resp = tuple.Item2;
if (tuple.Item1 != 200) throw new Exception(resp);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<Border Grid.Column="1"
Width="88"
HorizontalAlignment="Left"
BorderBrush="{DynamicResource ThemeAccentColor}"
BorderBrush="{DynamicResource UnOfficialServiceColor}"
BorderThickness="2"
CornerRadius="5">
<TextBlock Padding="5,2" FontWeight="Black" Text="自建服务" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<UserControl x:Class="STranslate.Views.Preference.Service.TextSTranslateServicesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="clr-namespace:STranslate.Style.Commons;assembly=STranslate.Style"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:STranslate.ViewModels.Preference.Services"
d:DataContext="{d:DesignInstance Type=vm:TranslatorSTranslate}"
d:DesignHeight="450"
d:DesignWidth="800"
Background="Transparent"
FontSize="{DynamicResource FontSize_Content}"
mc:Ignorable="d">
<Border Padding="10,20"
BorderBrush="{DynamicResource BorderBrushColor}"
BorderThickness="1"
CornerRadius="4">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="类型: " />

<Border Grid.Column="1"
Width="88"
HorizontalAlignment="Left"
BorderBrush="{DynamicResource ThemeAccentColor}"
BorderThickness="2"
CornerRadius="5">
<TextBlock Padding="5,2" FontWeight="Black" Text="本地服务" />
</Border>
</Grid>

<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="名称: " />

<common:PlaceholderTextBox Grid.Column="1"
MinWidth="160"
HorizontalAlignment="Left"
Placeholder="STranslate"
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</Grid>

<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="图标: " />

<ComboBox Grid.Column="1"
Width="120"
HorizontalAlignment="Left"
BorderThickness="1"
ItemsSource="{Binding Icons}"
SelectedValue="{Binding Icon}" />
</Grid>

<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="说明: " />
<TextBlock Grid.Column="1" Text="本地服务" />
<TextBlock Grid.Column="1" Margin="80,0,0,0" Style="{DynamicResource InfoTextBlock}" ToolTip="{Binding Tips}" />
</Grid>
</StackPanel>
</Border>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using STranslate.Model;

namespace STranslate.Views.Preference.Service
{
public partial class TextSTranslateServicesPage : UserControl
{
public TextSTranslateServicesPage(ITranslator vm)
{
InitializeComponent();

DataContext = vm;
}

/// <summary>
/// 通过缓存加载View时刷新ViewModel
/// </summary>
/// <param name="vm"></param>
public void UpdateVM(ITranslator vm)
{
DataContext = vm;
}
}
}

0 comments on commit 0c82e66

Please sign in to comment.