OSDN Git Service

Microsoft Translator Text API v3 に対応
authorKimura Youichi <kim.upsilon@bucyou.net>
Sat, 23 Mar 2019 10:10:58 +0000 (19:10 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Sat, 23 Mar 2019 10:10:58 +0000 (19:10 +0900)
OpenTween.Tests/Api/MicrosoftTranslatorApiTest.cs
OpenTween/Api/MicrosoftTranslatorApi.cs
OpenTween/Resources/ChangeLog.txt

index ea77c51..d02e97d 100644 (file)
 // Boston, MA 02110-1301, USA.
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Net;
 using System.Net.Http;
-using System.Text;
+using System.Runtime.Serialization.Json;
 using System.Threading.Tasks;
 using System.Web;
+using System.Xml;
+using System.Xml.Linq;
+using System.Xml.XPath;
 using Moq;
 using Xunit;
 
@@ -46,21 +48,41 @@ namespace OpenTween.Api
 
                 var translateApi = mock.Object;
 
-                mockHandler.Enqueue(x =>
+                mockHandler.Enqueue(async x =>
                 {
-                    Assert.Equal(HttpMethod.Get, x.Method);
+                    Assert.Equal(HttpMethod.Post, x.Method);
                     Assert.Equal(MicrosoftTranslatorApi.TranslateEndpoint.AbsoluteUri,
                         x.RequestUri.GetLeftPart(UriPartial.Path));
 
                     var query = HttpUtility.ParseQueryString(x.RequestUri.Query);
 
-                    Assert.Equal("hogehoge", query["text"]);
+                    Assert.Equal("3.0", query["api-version"]);
                     Assert.Equal("ja", query["to"]);
                     Assert.Equal("en", query["from"]);
 
+                    var requestBody = await x.Content.ReadAsByteArrayAsync()
+                        .ConfigureAwait(false);
+
+                    using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(requestBody, XmlDictionaryReaderQuotas.Max))
+                    {
+                        var xElm = XElement.Load(jsonReader);
+
+                        var textElm = xElm.XPathSelectElement("/item/Text");
+                        Assert.Equal("hogehoge", textElm.Value);
+                    }
+
                     return new HttpResponseMessage(HttpStatusCode.OK)
                     {
-                        Content = new StringContent("ほげほげ"),
+                        Content = new StringContent(@"[
+    {
+        ""translations"": [
+            {
+                ""text"": ""ほげほげ"",
+                ""to"": ""ja""
+            }
+        ]
+    }
+]"),
                     };
                 });
 
index e07433f..5d035bf 100644 (file)
@@ -29,6 +29,7 @@ using System.Text;
 using System.Threading.Tasks;
 using System.Xml;
 using System.Xml.Linq;
+using System.Xml.XPath;
 using OpenTween.Connection;
 
 namespace OpenTween.Api
@@ -36,7 +37,7 @@ namespace OpenTween.Api
     public class MicrosoftTranslatorApi
     {
         public static readonly Uri IssueTokenEndpoint = new Uri("https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
-        public static readonly Uri TranslateEndpoint = new Uri("https://api.microsofttranslator.com/v2/Http.svc/Translate");
+        public static readonly Uri TranslateEndpoint = new Uri("https://api.cognitive.microsofttranslator.com/translate");
 
         public string AccessToken { get; internal set; }
         public DateTimeUtc RefreshAccessTokenAt { get; internal set; }
@@ -59,7 +60,7 @@ namespace OpenTween.Api
 
             var param = new Dictionary<string, string>
             {
-                ["text"] = text,
+                ["api-version"] = "3.0",
                 ["to"] = langTo,
             };
 
@@ -68,14 +69,32 @@ namespace OpenTween.Api
 
             var requestUri = new Uri(TranslateEndpoint, "?" + MyCommon.BuildQueryString(param));
 
-            using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
+            using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
             {
                 request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", this.AccessToken);
 
-                using (var response = await this.Http.SendAsync(request).ConfigureAwait(false))
+                var escapedText = JsonUtils.EscapeJsonString(text);
+                var json = $@"[{{""Text"": ""{escapedText}""}}]";
+
+                using (var body = new StringContent(json, Encoding.UTF8, "application/json"))
                 {
-                    return await response.Content.ReadAsStringAsync()
-                        .ConfigureAwait(false);
+                    request.Content = body;
+
+                    using (var response = await this.Http.SendAsync(request).ConfigureAwait(false))
+                    {
+                        response.EnsureSuccessStatusCode();
+
+                        var responseJson = await response.Content.ReadAsByteArrayAsync()
+                            .ConfigureAwait(false);
+
+                        using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(responseJson, XmlDictionaryReaderQuotas.Max))
+                        {
+                            var xElm = XElement.Load(jsonReader);
+                            var transtlationTextElm = xElm.XPathSelectElement("/item/translations/item/text[1]");
+
+                            return transtlationTextElm?.Value ?? "";
+                        }
+                    }
                 }
             }
         }
index c2fa477..c7bdb29 100644 (file)
@@ -3,6 +3,8 @@
 ==== Ver 2.2.1-dev(20xx/xx/xx)
  * CHG: 投稿欄にフォーカスしている間は、AltGrキーを使う言語のキーボートと重複する一部のショートカットを無効にします (thx @pitermach, @lukaszgo1!)
   - 対象となるショートカットは Ctrl+Alt+S (Fav+RT), Ctrl+Alt+R (Fav+非公式RT), Ctrl+Alt+H (ユーザー指定のURLを開く) の3つです
+ * CHG: Microsoft Translator Text API v3 に対応
+  - OpenTweenの古いバージョンの翻訳機能は 2019/4/30 以降に使用できなくなります
 
 ==== Ver 2.2.0(2018/11/03)
  * NEW: 絵文字に関する文字数カウントの新仕様に対応しました