1+ using AutoResxTranslator . Definitions ;
2+ using Newtonsoft . Json ;
3+ using System ;
4+ using System . Collections . Generic ;
5+ using System . Net ;
6+ using System . Net . Http ;
7+ using System . Threading . Tasks ;
8+
9+ namespace AutoResxTranslator
10+ {
11+ /// <summary>
12+ /// Translation service using Microsoft Cogntive service.
13+ ///
14+ /// ref: https://azure.microsoft.com/en-in/services/cognitive-services/translator-text-api/
15+ /// </summary>
16+ public class DeepLTranslateService
17+ {
18+ private const string DeepLFreeCognitiveServicesApiUrl = "https://api-free.deepl.com" ;
19+ private const string DeepLProCognitiveServicesApiUrl = "https://api.deepl.com" ;
20+
21+ private readonly struct TextTranslateResult
22+ {
23+ /// <summary>Initializes a new instance of <see cref="TextTranslateResult" />, used for JSON deserialization.</summary>
24+ [ JsonConstructor ]
25+ public TextTranslateResult ( TextResult [ ] translations )
26+ {
27+ Translations = translations ;
28+ }
29+
30+ /// <summary>Array of <see cref="TextResult" /> objects holding text translation results.</summary>
31+ public TextResult [ ] Translations { get ; }
32+ public sealed class TextResult
33+ {
34+ /// <summary>Initializes a new instance of <see cref="TextResult" />.</summary>
35+ /// <param name="text">Translated text.</param>
36+ /// <param name="detectedSourceLanguageCode">The detected language code of the input text.</param>
37+ /// <remarks>
38+ /// The constructor for this class (and all other Model classes) should not be used by library users. Ideally it
39+ /// would be marked <see langword="internal" />, but needs to be <see langword="public" /> for JSON deserialization.
40+ /// In future this function may have backwards-incompatible changes.
41+ /// </remarks>
42+ [ JsonConstructor ]
43+ public TextResult ( string text , string detectedSourceLanguageCode )
44+ {
45+ Text = text ;
46+ DetectedSourceLanguageCode = detectedSourceLanguageCode ;
47+ }
48+
49+ /// <summary>The translated text.</summary>
50+ public string Text { get ; }
51+
52+ /// <summary>The language code of the source text detected by DeepL.</summary>
53+ [ JsonProperty ( "detected_source_language" ) ]
54+ public string DetectedSourceLanguageCode { get ; }
55+
56+ /// <summary>Returns the translated text.</summary>
57+ /// <returns>The translated text.</returns>
58+ public override string ToString ( ) => Text ;
59+ }
60+ }
61+
62+ public static async Task < ResultHolder < string > > TranslateAsync ( string text ,
63+ string fromLanguage ,
64+ string toLanguage ,
65+ string subscriptionKey ,
66+ string region )
67+ {
68+ if ( fromLanguage . Equals ( "auto" ) )
69+ {
70+ fromLanguage = "" ;
71+ }
72+
73+ var route = "/v2/translate" ;
74+
75+ try
76+ {
77+ using ( var client = new HttpClient ( ) )
78+ using ( var request = new HttpRequestMessage ( ) )
79+ {
80+ client . DefaultRequestHeaders . Accept . Add ( new System . Net . Http . Headers . MediaTypeWithQualityHeaderValue ( "application/json" ) ) ;
81+ client . DefaultRequestHeaders . TryAddWithoutValidation ( "Content-Type" , "application/x-www-form-urlencoded" ) ;
82+ // Build the request.
83+
84+ var data = new Dictionary < string , string >
85+ {
86+ { "auth_key" , subscriptionKey } ,
87+ { "text" , text } ,
88+ { "target_lang" , toLanguage . ToUpper ( ) }
89+ } ;
90+
91+ if ( ! string . IsNullOrEmpty ( fromLanguage ) )
92+ data . Add ( "source_lang" , fromLanguage . ToUpper ( ) ) ;
93+
94+ var response = await client . PostAsync (
95+ ( region == "0" ? DeepLFreeCognitiveServicesApiUrl : DeepLProCognitiveServicesApiUrl ) + route ,
96+ new FormUrlEncodedContent ( data ) ) ;
97+ response . EnsureSuccessStatusCode ( ) ;
98+
99+ if ( response . StatusCode == HttpStatusCode . OK )
100+ {
101+ // Read response as a string.
102+ var resultFromDeepL = await response . Content . ReadAsStringAsync ( ) ;
103+ var deserializedOutput = JsonConvert . DeserializeObject < TextTranslateResult > ( resultFromDeepL ) ;
104+
105+ // Iterate over the results, return the first result
106+ foreach ( var t in deserializedOutput . Translations )
107+ {
108+ return new ResultHolder < string > ( true , t . Text ) ;
109+ }
110+ }
111+ else
112+ {
113+ return new ResultHolder < string > ( false , "Translation failed! Reason: " + response . ReasonPhrase ) ;
114+ }
115+ }
116+ return new ResultHolder < string > ( false ) ;
117+ }
118+ catch ( Exception e )
119+ {
120+ return new ResultHolder < string > ( false , "Translation failed! Exception: " + e . Message ) ;
121+ }
122+ }
123+ }
124+ }
0 commit comments