forked from pengzhxyz/Wox.Plugin.Youdao
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Main.cs
267 lines (247 loc) · 9.03 KB
/
Main.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using Newtonsoft.Json;
using Wox.Infrastructure.Http;
using System.Security.Cryptography;
using System.Text;
namespace Wox.Plugin.Youdao
{
public class TranslateResult
{
public int errorCode { get; set; }
public List<string> translation { get; set; }
public BasicTranslation basic { get; set; }
public List<WebTranslation> web { get; set; }
}
// 有道词典-基本词典
public class BasicTranslation
{
public string phonetic { get; set; }
public List<string> explains { get; set; }
}
public class WebTranslation
{
public string key { get; set; }
public List<string> value { get; set; }
}
public class Main : IPlugin, ISettingProvider
{
private const string TranslateUrl = "https://fanyi.youdao.com/openapi.do?keyfrom=WoxLauncher&key=1247918016&type=data&doctype=json&version=1.1&q=";
private const string youdaoApiUrl = "https://openapi.youdao.com/api";
private PluginInitContext _context;
private readonly Settings _settings;
private readonly SettingsViewModel _viewModel;
public Main()
{
_viewModel = new SettingsViewModel();
_settings = _viewModel.Settings;
}
public List<Result> Query(Query query)
{
List<Result> results = new List<Result>();
const string ico = "Images\\youdao.ico";
if (string.IsNullOrWhiteSpace(_settings.AppKey) || string.IsNullOrWhiteSpace(_settings.SecretKey))
{
results.Add(new Result()
{
Title = "请设置有道翻译API Key",
SubTitle = "申请Key: https://ai.youdao.com/",
IcoPath = ico
});
return results;
}
if (query.Search.Length == 0)
{
results.Add(new Result
{
Title = "开始有道中英互译",
SubTitle = "基于有道智云 API",
IcoPath = ico
});
return results;
}
string q = query.Search;
string from = "auto";
string to = "auto";
string appKey = _settings.AppKey;
string salt = "6";
string sign = CalculateMD5Hash(appKey + q + salt + _settings.SecretKey);
string url = $"{youdaoApiUrl}?q={q}&from={from}&to={to}&appKey={appKey}&salt={salt}&sign={sign}";
var json = Http.Get(url).Result;
TranslateResult o = JsonConvert.DeserializeObject<TranslateResult>(json);
if (o.errorCode == 0)
{
if(o.translation != null)
{
var translation = string.Join(", ", o.translation.ToArray());
var title = translation;
if (o.basic?.phonetic != null)
{
title += " [" + o.basic.phonetic + "]";
}
results.Add(new Result
{
Title = title,
SubTitle = "翻译结果",
IcoPath = ico,
Action = this.copyToClipboardFunc(translation)
});
}
if(o.basic?.explains != null)
{
var explantion = string.Join(",", o.basic.explains.ToArray());
results.Add(new Result
{
Title = explantion,
SubTitle = "简明释义",
IcoPath = ico,
Action = this.copyToClipboardFunc(explantion)
});
}
if (o.web != null)
{
foreach (WebTranslation t in o.web)
{
var translation = string.Join(",", t.value.ToArray());
results.Add(new Result
{
Title = translation,
SubTitle = "网络释义:"+ t.key,
IcoPath = ico,
Action = this.copyToClipboardFunc(translation)
});
}
}
}
else
{
string error = string.Empty;
switch (o.errorCode)
{
//case 20:
// error = "要翻译的文本过长";
// break;
//case 30:
// error = "无法进行有效的翻译";
// break;
//case 40:
// error = "不支持的语言类型";
// break;
//case 50:
// error = "无效的key";
// break;
case 101:
error = "缺少必填的参数,出现这个情况还可能是et的值和实际加密方式不对应";
break;
case 102:
error = "不支持的语言类型";
break;
case 103:
error = "翻译文本过长";
break;
case 104:
error = "不支持的API类型";
break;
case 105:
error = "不支持的签名类型";
break;
case 106:
error = "不支持的响应类型";
break;
case 107:
error = "不支持的传输加密类型";
break;
case 108:
error = "appKey无效";
break;
case 109:
error = "batchLog格式不正确";
break;
case 110:
error = "无相关服务的有效实例";
break;
case 111:
error = "开发者账号无效,可能是账号为欠费状态";
break;
case 201:
error = "解密失败,可能为DES,BASE64,URLDecode的错误";
break;
case 202:
error = "签名检验失败";
break;
case 203:
error = "访问IP地址不在可访问IP列表";
break;
case 301:
error = "辞典查询失败";
break;
case 302:
error = "翻译查询失败";
break;
case 303:
error = "服务端的其它异常";
break;
case 401:
error = "账户已经欠费停";
break;
}
results.Add(new Result
{
Title = error,
IcoPath = ico
});
}
return results;
}
public void Init(PluginInitContext context)
{
_context = context;
}
private System.Func<ActionContext, bool> copyToClipboardFunc(string text)
{
return c =>
{
if (this.copyToClipboard(text))
{
_context.API.ShowMsg("翻译已被存入剪贴板");
}
else
{
_context.API.ShowMsg("剪贴板打开失败,请稍后再试");
}
return false;
};
}
private string CalculateMD5Hash(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
private bool copyToClipboard(string text)
{
try
{
Clipboard.SetText(text);
}catch(System.Exception e)
{
return false;
}
return true;
}
public Control CreateSettingPanel()
{
return new SettingsControl(_viewModel);
}
}
}