初めまして、アキちゃんです。
備忘録をかねてブログを書くことにしました。
今回は初の試みで、Qiita Advent Calender 2022に記事を書いてみることにしました。
内容は「Blazor+Radzen & みんなの自動翻訳@TexTraでLine風翻訳あぷりつくってみたよ」です。
それでは早速・・・
Blazor+Radzen & みんなの自動翻訳@TexTraでLine風翻訳あぷり !
(ピクチャインピクチャじゃないと潰れてほぼみえませんね・・・)
Lesson.0 事前準備
ある程度の準備はしておきたいと思います。
1.Blazor Serverのプロジェクトの作成し、Radzen導入だけ済ませたものを用意します。本記事では、プロジェクトの名前は"Honya-kun"として作成します。
akr9915.hatenablog.com
2.みんなの自動翻訳@TexTraのAPI を使いたいため、以下サイトでユーザー登録を行います。
mt-auto-minhon-mlt.ucri.jgn-x.jp
3.2で登録したユーザー情報で、みんなの自動翻訳@TexTraにログインしユーザーの設定からWeb API のAPI keyとAPI secretを確認します。(併せてユーザーIDも後で使うので覚えておきます)
Lesson.1 みんなの自動翻訳API
まずみんなの自動翻訳のAPI を使えるようにしたいため、サイトから公開されているソースコード を取得したいとおもいます。
Dataフォルダを右クリックし"追加"→"クラス"Textra.csを追加し、作成されたファイルのソースコード をすべて消します。
みんなの自動翻訳のページに行きログイン→Web API のページに行きます。
Web API 一覧から自動翻訳リクエス ト-一覧をクリック
汎用NT 【 英語 - 日本語 】のAPI のインフォメーションアイコンをクリックします。
自動翻訳 WebAPIという画面が表示されるので、下の方にスクロールしていくとアクセス例がでてきます。OAuth→C# を選択し少し下にスクロールしusing System;・・以下をまるまるコピーして先ほど追加したTextra.csにまるまるペーストします。
貼り付けたソースコード の13行目、724行目、764行目を削除します。
13行目 不要な参照のため削除 using System.Windows .Forms; 724行目 設定は明示的にしたいため削除 private static TexTraPlugin.Properties.Settings MySettings = TexTraPlugin.Properties.Settings.Default; 764行目 ASP.Net では使えない関数のため削除 if (show_message) MessageBox.Show("XML の読込に失敗しました。\n\n" + e.Message);
724行目を削除した段階でおびただしい数のエラーが発生します、代わりの構造体を用意してあげるために22行目APIAccessor_jaの宣言の直下に以下のコードを追加します。
public static class APIAccessor_ja { private static TexTraPlugin MySettings = new TexTraPlugin() { API _URL = "", API _KEY = "", API _SECRET = "", API _USER = "" }; public class TexTraPlugin { public string API _自動翻訳 { get; set; } public string API _URL { get; set; } public string API _KEY { get; set; } public string API _SECRET { get; set; } public string API _USER { get; set; } public string proxy { get; set; } public string proxy_id { get; set; } public string proxy_password { get; set; } public int proxy_port { get; set; } } #region "API "
371行目辺りにinit_settings()という関数がありますが、この中に定義されているUrlが若干違うのでgeneral→generalNTに修正します。
"https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/ generalNT _zh-CN_ja/" "https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/ generalNT _zh-TW_ja/" "https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/ generalNT _ja_zh-CN/" "https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/ generalNT _ja_zh-TW/" "https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/ generalNT _ja_en/" "https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/ generalNT _ja_ko/" "https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/ generalNT _en_ja/" "https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/ generalNT _ko_ja/"
実際のところは"https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/generalNT_ja_en/ "だけ変えればいいんですが、今後使う機会があるかもしれないので全部変えておきましょう。
24行目に追加したMySettingsに設定を入れようと思います。
API _URLは今回日本語→英語の想定なので"https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/generalNT_ja_en/ "を入力します。それ以外の項目はLesson.0で確認した値を入力します。
private static TexTraPlugin MySettings = new TexTraPlugin() { API _URL = "https://mt-auto-minhon-mlt.ucri.jgn-x.jp/api/mt/generalNT_ja_en/ ", API _KEY = "ここは自分のAPI Keyを入れます ", API _SECRET = "ここは自分のAPI Secretを入れます ", API _USER = "ここは自分のUser Nameを入れます " };
API Keyはユニークであり、第三者 に知られると悪用されることもあるため絶対に自分以外の人間にはばれないようにしましょう。(というか知られたら120%悪用されると思ってください)
ここまできたら動くか確認しましょう、Pages/Counter.razorを以下のように修正します。
@page "/counter" @using static TexTra.APIAccessor_ja <PageTitle>Counter</PageTitle> <h1>Counter</h1> <p role="status">Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button><RadzenTextBox @bind-Value =@orgValue></RadzenTextBox> <RadzenTextBox @bind-Value =@newValue></RadzenTextBox> @code { private int currentCount = 0; string orgValue = string.Empty; string newValue = string.Empty; private void IncrementCount() { currentCount++; var get = TexTra.APIAccessor_ja.get_auto_trans(orgValue, Language.ja, Language.en, out APIResponseBean aPIResponseBean); if (get.Any()) { newValue = ((TexTra.APIAccessor_ja.AutoTransInfo)get[0].value ).text_translated; } } }
アプリケーションを起動しCounterに遷移します。
左側のテキストボックスに”野球”と入力し、Click meを押下後右側のテキストボックスにBaseball と表示されたらここまでは完了です。
Lesson.2 Line風導入
あとはLine風の送信画面を追加しようと思います。
RadzenにはHtmlEditorがあるので、これにCss を反映させてそれっぽい画面を作っていこうと思います。
Line風のCss は以下サイトを参考にさせてもらおうと思います。
jisuijisan.com
Pagesフォルダを右クリック後、追加→Radzenコンポーネント からChat.razorを追加し、Chat.razorに作成時書かれているコードを削除します。
取り敢えず上記のサイトように表示できることを確認したいため、HtmlとCss を拝借して以下のコードをChar.razorにコピペします。
Char.razor(クリックで展開) Char.razor(クリックで圧縮)
@page "/chat" <RadzenHtmlEditor @bind-Value =@value ></RadzenHtmlEditor> @code { string value = string.Empty; string chatCss { get => "<style>" + "/*==============" + "LINE風フキダシ" + "===============*/" + "/*フレームとフォント*/" + ".kaiwa.line {" + " width: 100%;" + " max-width: 500px;" + " margin: 0 auto;" + " padding: 10px 0;" + " background: #769ece;" + " font-family: \"ヒラギノ 角ゴ Pro W3\",\"Hiragino Kaku Gothic Pro\",\"Helvetica Neue\", \"Lucida Sans Unicode \", \"Arial\";" + " font-size: 16px;" + " color: #333;" + " line-height: 1.4;" + " overflow: hidden;" + "}" + "/*フキダシ共通*/" + ".kaiwa.line .fukidasi {" + " position: relative;" + " display: inline-block;" + " max-width: 192px;" + " margin: 8px 0 0;" + " padding: 9px 14px;" + " border-radius : 19px;" + " overflow-wrap: break-word;" + " clear: both;" + " box-sizing: content-box;/*はてな 用*/" + "}" + "/*フキダシ左*/" + ".kaiwa.line .fukidasi.left {" + " float: left;" + " margin-left: 62px;" + " background: white;" + "}" + "/*グループのときのフキダシ*/" + ".kaiwa.line .name + .fukidasi.left {" + " margin-top: 5px;" + "}" + "/*フキダシ右*/" + ".kaiwa.line .fukidasi.right {" + " float: right;" + " margin-right: 12px;" + " background: #7adc40;" + "}" + "/*相手の名前*/" + ".kaiwa.line .name {" + " clear: right;" + " margin-left: 62px;" + " color: white;" + "}" + "/*ユーザアイコン*/" + ".kaiwa.line .icon {" + " position: absolute;" + " width: 40px;" + " height: 40px;" + " left: -54px;" + " top: -2px;" + " border-radius : 20px;" + "}" + "/*グループのときのユーザアイコン*/" + ".kaiwa.line .name + .left .icon {" + " top: -1.8em;" + "}" + "/*しっぽ共通*/" + ".kaiwa.line .fukidasi::after {" + " position: absolute;" + " content: \"\";" + " width: 24px;" + " height: 36px;" + " top: -21px;" + "}" + "/*しっぽ左*/" + ".kaiwa.line .fukidasi.left:after {" + " left: -10px;" + " border-radius : 18px 0 6px 18px/18px 0 1px 18px;" + " box-shadow: -3px -15px 0 -5px white inset;" + "}" + "/*しっぽ右*/" + ".kaiwa.line .fukidasi.right::after {" + " right: -10px;" + " border-radius : 0 18px 18px 6px/0 18px 18px 1px;" + " box-shadow: inset 3px -15px 0 -5px #7adc40;" + "}" + "/*フキダシが続いてしっぽがないとき*/" + ".kaiwa.line .left + .left::after," + ".kaiwa.line .right + .right::after {" + " content: none;" + "}"+ "</style>" ; } protected override void OnParametersSet() { value = chatCss; value += "<div class=\"kaiwa line\">"+ " <div class=\"name\">"+ " おなまえ"+ " </div>"+ " <div class=\"fukidasi left\">"+ " <img class=\"icon\" src=\"img/icon.png \" alt=\"\">LINE風です。"+ " </div>"+ " <div class=\"fukidasi left\">"+ " 続けて喋るとフキダシのしっぽはつきません。"+ " </div>"+ " <div class=\"fukidasi right\">"+ " HTMLとCSS でできます。"+ " </div>"+ " <br><!-- 次のフキダシにしっぽをつけたいときはbrを挿入 -->"+ " <div class=\"fukidasi right\">"+ " 続けても、しっぽをつけたいときは間にbrを入れます。"+ " </div>"+ " <div class=\"fukidasi left\">"+ " <img class=\"icon\" src=\"img/icon.png \" alt=\"\">グループじゃないとき。" + " </div>" + "</div>"; } }
Shared/NavMenu.razorのNavLinkに以下のコードを追加します。
<div class="nav-item px-3"> <NavLink class="nav-link" href="chat"> <span class="oi oi-chat" aria -hidden="true"></span>Chat </NavLink> </div>
ここまできたら動くか確認しましょう、アプリを実行し左のタブからChatに移動し、以下画面が表示されたらここまでは完了です。
Lesson.3 Line風画面Component化
上記までである程度できてきましたが、もう少しそれっぽい画面にしたいと思います。
プロジェクトにComponentsフォルダを作成し、そのフォルダにLineChat.razorを作成します。
作成したLineChat.razorに以下のコードを貼り付けます。
<RadzenHtmlEditor @bind-Value =@Value class="w-100" style="font-family:Source Han Code JP;height:100%;" UploadUrl="upload/image" Disabled=@false> <RadzenHtmlEditorSeparator /> </RadzenHtmlEditor> @code { string _Value = string.Empty; [Parameter] public string Value { get => _Value ; set { if (_Value == value ) return; _Value = value ; ValueChanged.InvokeAsync(value ); } } [Parameter] public EventCallback<string> ValueChanged { get; set; } }
Pages/Chat.razorを以下のように修正します。
@page "/chat" @using Radzen<RadzenSplitter Orientation="Orientation.Vertical" Style="height:850px;"> <RadzenSplitterPane Size="90%"> <div class="h-100" style="overflow-y: scroll;"> <Honya_kun.Components.LineChat @bind-Value =@value ></Honya_kun.Components.LineChat> </div> </RadzenSplitterPane> <RadzenSplitterPane Size="10%"> <RadzenSplitter Orientation="Orientation.Horizontal"> <RadzenSplitterPane Size="70%"> <RadzenTextArea class="w-100 h-100" @bind-Value =@sendStr></RadzenTextArea> </RadzenSplitterPane> <RadzenSplitterPane Size="30%"> <RadzenButton class="w-100 h-100" Text="送信" Click=@SendClick></RadzenButton> </RadzenSplitterPane> </RadzenSplitter> </RadzenSplitterPane> </RadzenSplitter> @code { string value = string.Empty; string sendStr = string.Empty; string chatCss・・・(省略) protected override void OnParametersSet() { value = chatCss; value += "<div class=\"kaiwa line\">" + " <div class=\"name\">" + " ほんやくん" + " </div>" + " <div class=\"fukidasi left\">" + " <img class=\"icon\" src=\"img/icon.png \" alt=\"\">LINE風です。" + " </div>" + " <div class=\"fukidasi left\">" + " 続けて喋るとフキダシのしっぽはつきません。" + " </div>" + " <div class=\"fukidasi right\">" + " HTMLとCSS でできます。" + " </div>" + " <br><!-- 次のフキダシにしっぽをつけたいときはbrを挿入 -->" + " <div class=\"fukidasi right\">" + " 続けても、しっぽをつけたいときは間にbrを入れます。" + " </div>" + " <div class=\"fukidasi left\">" + " <img class=\"icon\" src=\"img/icon.png \" alt=\"\">グループじゃないとき。" + " </div>" + "</div>"; } async Task SendClick() { await Task.Delay(100); } }
chatCss { get => を以下のように修正します。
get => "<style>" + "/*==============" + "LINE風フキダシ" + "===============*/" + "/*フレームとフォント*/" + ".kaiwa.line {" + " width: 100%;" + " height:100%;" + //" max-width: 500px;" + " margin: 0 auto;" + " padding: 10px 0;" + " background: #769ece;" + Console.WriteLine("Hello, World!");
ここまできたら実行してみて以下画面が表示されたらここまでは完成です。
Lesson.4 送信ボタン実装
任意のテキストを送り変換する送信ボタンを実装しようと思います。
まず、通信している間のBusyフラグを追加します。
@using static TexTra.APIAccessor_ja <RadzenSplitter Orientation="Orientation.Vertical" Style="height:850px;"> <RadzenSplitterPane Size="90%"> <div class="h-100" style="overflow-y: scroll;"> <Honya_kun.Components.LineChat @bind-Value =@value ></Honya_kun.Components.LineChat> </div> </RadzenSplitterPane> <RadzenSplitterPane Size="10%"> <RadzenSplitter Orientation="Orientation.Horizontal"> <RadzenSplitterPane Size="70%"> <RadzenTextArea class="w-100 h-100" @bind-Value =@sendStr></RadzenTextArea> </RadzenSplitterPane> <RadzenSplitterPane Size="30%"> <RadzenButton class="w-100 h-100" Text="送信" Click=@SendClick IsBusy=@IsBusy BusyText="通信中" ></RadzenButton> </RadzenSplitterPane> </RadzenSplitter> </RadzenSplitterPane> </RadzenSplitter> @code { string value = string.Empty; string sendStr = string.Empty; bool IsBusy = false;
OnParameterSet()の中を以下のように修正します。
protected override void OnParametersSet() { value = chatCss; value += "<div class=\"kaiwa line\">" + " <div class=\"name\">" + " ほんやくん" + " </div>" + " <div class=\"fukidasi left\">" + " <img class=\"icon\" src=\"img/icon.png \" alt=\"\">こんにちは!" + " </div>" + " <div class=\"fukidasi left\">" + " 日本語→英語の翻訳ができるほんや君です!" + " </div>" + " </div>"; }
SendClickの中を以下のように修正します。
async Task SendClick() { if (string.IsNullOrEmpty(sendStr)) { // Nothing } else { IsBusy = true; List<APIResponseBean> get = new List<APIResponseBean>(); value = value .TrimEnd(new char[6] { '<', '/', 'd', 'i', 'v', '>' }); value += "<div class=\"fukidasi right\">" + sendStr + "</div>"; await Task.WhenAll(new Task[] { Task.Factory.StartNew(() => { get = TexTra.APIAccessor_ja.get_auto_trans(sendStr, Language.ja, Language.en, out APIResponseBean aPIResponseBean); }) }); if (get.Any()) { var newValue = ((TexTra.APIAccessor_ja.AutoTransInfo)get[0].value ).text_translated; value += "<div class=\"fukidasi left\">><img class=\"icon\" src=\"img/icon.png \" alt=\"\">" + newValue + "</div>"; } else { value += "<div class=\"fukidasi left\">" + "翻訳できませんでした・・・" + "</div>"; } value += " </div>"; IsBusy = false; } }
chatCssのフキダシ共通を以下のように修正します
"/*フキダシ共通*/" + ".kaiwa.line .fukidasi {" + " position: relative;" + " display: inline-block;" + " max-width: 500px; " + " margin: 8px 0 0;" + " padding: 9px 14px;" + " border-radius : 19px;" + " overflow-wrap: break-word;" + " clear: both;" + " box-sizing: content-box;/*はてな 用*/" + "}" +
ほんやくんのアイコンを追加したいのでwwwrootの直下にiconフォルダを作り、おなじみのイラストやさんの力をかりicon..png をiconフォルダに入れます。
www.irasutoya.com
ここまできたら実行して任意の文字を入力し、送信ボタンを押すとほんやくんが返事してくれると思います!
↓
Lesson.5 あとがき
おもったよりも長い記事になってしまいました、何かの役に立てれば幸いです。
以上!
github.com