Skip to content

Commit

Permalink
feat(AzureTranslator): add AzureTranslator service (#2519)
Browse files Browse the repository at this point in the history
* feat: 增加 Translator 服务

* chore: 增加翻译服务

* doc: 增加翻译源码映射

* doc: 增加翻译服务示例

* chore: 更新内置服务菜单

* doc: 增加本地化资源
  • Loading branch information
ArgoZhang authored Dec 9, 2023
1 parent 5f56486 commit 6c521a5
Show file tree
Hide file tree
Showing 15 changed files with 375 additions and 2 deletions.
7 changes: 7 additions & 0 deletions BootstrapBlazor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "configuration", "configurat
exclusion.dic = exclusion.dic
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapBlazor.AzureTranslator", "src\Extensions\Components\BootstrapBlazor.AzureTranslator\BootstrapBlazor.AzureTranslator.csproj", "{D63E50CB-EF78-47BF-9809-003D4574ABF4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -258,6 +260,10 @@ Global
{49D9E679-6824-43DF-9DAA-70E24ACCAA62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49D9E679-6824-43DF-9DAA-70E24ACCAA62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49D9E679-6824-43DF-9DAA-70E24ACCAA62}.Release|Any CPU.Build.0 = Release|Any CPU
{D63E50CB-EF78-47BF-9809-003D4574ABF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D63E50CB-EF78-47BF-9809-003D4574ABF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D63E50CB-EF78-47BF-9809-003D4574ABF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D63E50CB-EF78-47BF-9809-003D4574ABF4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -303,6 +309,7 @@ Global
{568237B9-209E-49B1-9BCF-E853F2D61442} = {CD062AB6-244D-402A-8F33-C37DAC5856CC}
{25B67FF0-3D70-47D8-AC70-1934442A8881} = {CD062AB6-244D-402A-8F33-C37DAC5856CC}
{49D9E679-6824-43DF-9DAA-70E24ACCAA62} = {CD062AB6-244D-402A-8F33-C37DAC5856CC}
{D63E50CB-EF78-47BF-9809-003D4574ABF4} = {CD062AB6-244D-402A-8F33-C37DAC5856CC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0DCB0756-34FA-4FD0-AE1D-D3F08B5B3A6B}
Expand Down
1 change: 1 addition & 0 deletions src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<PackageReference Include="Longbow.Logging" Version="7.0.0" />
<PackageReference Include="Longbow.Tasks" Version="7.0.0" />
<PackageReference Include="BootstrapBlazor.AzureOpenAI" Version="8.0.1" />
<PackageReference Include="BootstrapBlazor.AzureTranslator" Version="8.0.0" />
<PackageReference Include="BootstrapBlazor.BaiduSpeech" Version="8.0.0" />
<PackageReference Include="BootstrapBlazor.BaiduOcr" Version="8.0.0" />
<PackageReference Include="BootstrapBlazor.BarCode" Version="8.0.0" />
Expand Down
30 changes: 30 additions & 0 deletions src/BootstrapBlazor.Server/Components/Samples/Translators.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@page "/translator"
@inject IStringLocalizer<Translators> Localizer

<h3>@Localizer["TranslatorsTitle"]</h3>
<h4>@Localizer["TranslatorsDescription"]</h4>

<PackageTips Name="BootstrapBlazor.AzureTranslator" />

<div class="mt-3">@Localizer["TranslatorsInjectService"]</div>
<Pre class="no-highlight mt-3">services.AddBootstrapBlazorAzureTranslator();</Pre>

<DemoBlock Title="@Localizer["TranslatorsNormalTitle"]"
Introduction="@Localizer["TranslatorsNormalIntro"]"
Name="Normal">
<CheckboxList Items="_languages" @bind-Value="_selectedLanguages" class="mb-3"></CheckboxList>
<BootstrapInputGroup>
<BootstrapInput @bind-Value="@_input"></BootstrapInput>
<Button Icon="fa-solid fa-language" Text="翻译" OnClick="OnClickTranslate"></Button>
</BootstrapInputGroup>

@if (_results.Any())
{
@foreach (var translation in _results.First().Translations)
{
<div class="mt-3">@FormatResult(translation)</div>
}
}
</DemoBlock>

<MethodTable Items="@GetMethods()" />
65 changes: 65 additions & 0 deletions src/BootstrapBlazor.Server/Components/Samples/Translators.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using Azure.AI.Translation.Text;
using System.Globalization;

namespace BootstrapBlazor.Server.Components.Samples;

/// <summary>
/// 翻译示例
/// </summary>
public partial class Translators
{
private readonly List<SelectedItem> _languages = [];

private List<string> _selectedLanguages = [];

private static readonly string[] sourceArray = ["zh-CN", "en-US", "ru-RU"];

private string _input = "";

private IReadOnlyList<TranslatedTextItem> _results = new List<TranslatedTextItem>();

[Inject]
[NotNull]
private IAzureTranslatorService? TranslatorService { get; set; }

/// <summary>
/// <inheritdoc/>
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();

_languages.AddRange(sourceArray.Select(i => new SelectedItem(i, new CultureInfo(i).NativeName)));
_selectedLanguages.AddRange(sourceArray);
}

private async Task OnClickTranslate()
{
_results = await TranslatorService.TranslateAsync(_selectedLanguages, [_input], "en-US");
}

private static string FormatResult(Translation translation)
{
var culture = new CultureInfo(translation.To);
return $"{culture.NativeName}: {translation.Text}";
}

/// <summary>
/// 获得属性方法
/// </summary>
/// <returns></returns>
protected IEnumerable<MethodItem> GetMethods() => new MethodItem[]
{
new()
{
Name = nameof(IAzureTranslatorService.TranslateAsync),
Description = Localizer[nameof(IAzureTranslatorService.TranslateAsync)],
Parameters = " - ",
ReturnValue = "IReadOnlyList<TranslatedTextItem>"
},
};
}
21 changes: 21 additions & 0 deletions src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ public static List<MenuItem> GenerateMenus(this IStringLocalizer<NavMenu> Locali
};
AddSpeech(item);

item = new DemoMenuItem()
{
Text = Localizer["Services"],
Icon = "fa-fw fa-solid fa-screwdriver-wrench",
};
AddServices(item);

item = new DemoMenuItem()
{
Text = Localizer["OtherComponents"],
Expand Down Expand Up @@ -1291,6 +1298,20 @@ void AddLayout(DemoMenuItem item)
AddBadge(item);
}

void AddServices(DemoMenuItem item)
{
item.Items = new List<DemoMenuItem>
{
new()
{
IsNew = true,
Text = Localizer["AzureTranslator"],
Url = "translator"
}
};
AddBadge(item);
}

void AddSummary(DemoMenuItem item)
{
// 计算组件总数
Expand Down
3 changes: 3 additions & 0 deletions src/BootstrapBlazor.Server/Extensions/ServicesExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ void Invoke(BootstrapBlazorOptions option)
// 增加 AzureOpenAI 服务
services.AddBootstrapBlazorAzureOpenAIService();

// 增加 AzureTranslator 服务
services.AddBootstrapBlazorAzureTranslator();

// 增加 Pdf 导出服务
services.AddBootstrapBlazorHtml2PdfService();

Expand Down
11 changes: 10 additions & 1 deletion src/BootstrapBlazor.Server/Locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4528,7 +4528,9 @@
"Clipboard": "Clipboard Service",
"CodeEditor": "CodeEditor",
"Gantt": "Gantt",
"ImageCropper": "ImageCropper"
"ImageCropper": "ImageCropper",
"Services": "Services",
"AzureTranslator": "AzureTranslator"
},
"BootstrapBlazor.Server.Components.Samples.Table.TablesHeader": {
"TablesHeaderTitle": "Header grouping function",
Expand Down Expand Up @@ -6039,5 +6041,12 @@
"AttributesImageCropperOnBase64Result": "Crop result base64 callback method",
"AttributesImageCropperCrop": "Crop, return base64, and execute OnResult/OnBase64Result callback",
"AttributesImageCropperCropToStream": "Crop, return Stream"
},
"BootstrapBlazor.Server.Components.Samples.Translators": {
"TranslatorsTitle": "Azure Translator",
"TranslatorsDescription": "Converts characters or letters of a source language to the corresponding characters or letters of a target language.",
"TranslatorsNormalTitle": "Basic usage",
"TranslatorsNormalIntro": "Call <code>TranslateAsync</code> method for convert target language",
"TranslatorsInjectService": "Inject Service"
}
}
11 changes: 10 additions & 1 deletion src/BootstrapBlazor.Server/Locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -4528,7 +4528,9 @@
"Clipboard": "剪切板服务",
"CodeEditor": "代码编辑器 CodeEditor",
"Gantt": "甘特图 Gantt",
"ImageCropper": "图像裁剪 ImageCropper"
"ImageCropper": "图像裁剪 ImageCropper",
"Services": "内置服务",
"AzureTranslator": "翻译服务 AzureTranslator"
},
"BootstrapBlazor.Server.Components.Samples.Table.TablesHeader": {
"TablesHeaderTitle": "表头分组功能",
Expand Down Expand Up @@ -6039,5 +6041,12 @@
"AttributesImageCropperOnBase64Result": "剪裁结果 base64 回调方法",
"AttributesImageCropperCrop": "剪裁,返回 base64, 并执行 OnResult/OnBase64Result 回调",
"AttributesImageCropperCropToStream": "剪裁,返回 Stream"
},
"BootstrapBlazor.Server.Components.Samples.Translators": {
"TranslatorsTitle": "AzureTranslator 翻译服务",
"TranslatorsDescription": "将源语言的字符或字母转换为目标语言的对应字符或字母",
"TranslatorsNormalTitle": "基础用法",
"TranslatorsNormalIntro": "通过调用 <code>TranslateAsync</code> 进行文本翻译",
"TranslatorsInjectService": "注入服务"
}
}
1 change: 1 addition & 0 deletions src/BootstrapBlazor.Server/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
"table/tree": "Table\\TablesTree",
"table/virtualization": "Table\\TablesVirtualization",
"table/wrap": "Table\\TablesWrap",
"translator": "Translators",
"js-extensions": "JSRuntimeExtensions",
"clipboard-service": "Clipboards",
"image-cropper": "ImageCroppers"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.Components;

/// <summary>
/// AzureTranslatorOption 配置类
/// </summary>
public class AzureTranslatorOption
{
/// <summary>
/// 获得/设置 订阅 Key 由 Azure 提供
/// </summary>
[NotNull]
public string? Key { get; set; }

/// <summary>
/// 获得/设置 Location/Region 描述 由 Azure 提供
/// </summary>
[NotNull]
public string? Region { get; set; }

/// <summary>
/// 获得/设置 超时时长 默认 0 未设置
/// </summary>
public int Timeout { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Version>8.0.0</Version>
</PropertyGroup>

<PropertyGroup>
<PackageTags>Bootstrap Blazor Azure WebAssembly wasm Translator Components</PackageTags>
<Description>Bootstrap UI components extensions of Azure Translator</Description>
<RootNamespace>BootstrapBlazor.Components</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.AI.Translation.Text" Version="1.0.0-beta.1" />
<PackageReference Include="BootstrapBlazor" Version="8.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using BootstrapBlazor.Components;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// BootstrapBlazor 服务扩展类
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// 增加 语音识别服务
/// </summary>
/// <param name="services"></param>
/// <param name="configOptions"></param>
/// <returns></returns>
public static IServiceCollection AddBootstrapBlazorAzureTranslator(this IServiceCollection services, Action<
AzureTranslatorOption>? configOptions = null)
{
services.AddHttpClient();

services.AddSingleton<IAzureTranslatorService, AzureTranslatorService>();
services.AddOptionsMonitor<AzureTranslatorOption>();

services.Configure<AzureTranslatorOption>(option =>
{
configOptions?.Invoke(option);
});
return services;
}
}
Loading

0 comments on commit 6c521a5

Please sign in to comment.