前些日子需要阅读某个使用日文注释的项目的代码,就想给vim装个翻译插件。网上简单找了下都是基于Google Translator API的,而Google的该服务已经可耻地不免费了。
本着“不断重新发明轮子”和练练Python的想法,就用Python写了这么个小插件。一共也就几十行代码,功能很少,但够我用的了。由于我初学Python,代码大概是不堪入目的,希望你给予指点或直接改进这个插件。
全部代码如下:
if !has('python')
echo "Sorry, Microsoft Translator requires python support"
finish
endif
python << EOF
import json
import string
import time
import urllib
import urllib2
import xml.dom.minidom
import vim
class MicrosoftTranslator:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.from_lang = None
self.access_token = None
self.token_expires_at = 0.0
self.to_lang = 'zh-CHS'
self.__renew_access_token()
def __generate_auth_params(self):
auth_params = {
'grant_type': 'client_credentials',
'scope': 'http://api.microsofttranslator.com',
'client_id' : self.client_id,
'client_secret' : self.client_secret
}
return urllib.urlencode(auth_params)
def __renew_access_token(self):
auth_url = 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13'
try:
resp = urllib2.urlopen(auth_url, self.__generate_auth_params())
resp_json = json.loads(resp.read())
self.access_token = resp_json['access_token']
self.token_expires_at = time.time() + string.atof(resp_json['expires_in'])
except urllib2.URLError, e:
print "Error: %s" % (e.reason)
def __current_access_token(self):
if time.time() > self.token_expires_at:
self.__renew_access_token()
return self.access_token
def set_lang(self, to_lang, from_lang=None):
self.from_lang = from_lang
self.to_lang = to_lang
def translate(self, text):
url = 'http://api.microsofttranslator.com/v2/Http.svc/Translate?'
data = {
'text': text,
'to': self.to_lang,
}
if self.from_lang != None:
data['from'] = self.from_lang
try:
request = urllib2.Request(url + urllib.urlencode(data))
request.add_header('Authorization', 'Bearer ' + self.__current_access_token())
response = urllib2.urlopen(request)
dom = xml.dom.minidom.parseString(response.read())
result = dom.documentElement.childNodes[0].nodeValue
return result
except urllib2.URLError, e:
errinfo = "Error: %s" % (e.reason)
return errinfo
EOF
if exists('g:MSTranslator_ID') && exists('g:MSTranslator_SECRET')
python << EOF
tr = MicrosoftTranslator(vim.eval('g:MSTranslator_ID'), vim.eval('g:MSTranslator_SECRET'))
EOF
function! s:Translate(text)
python << EOF
print tr.translate(vim.eval("a:text"))
EOF
endfunction
function! TranslateCWORD()
call s:Translate(expand("<cword>"))
endfunction
function! TranslateVISUAL()
call s:Translate(getline("'<")[getpos("'<")[2]-1:getpos("'>")[2]-1])
endfunction
function! TranslateEOL()
call s:Translate(strpart(getline("."), col(".")-1))
endfunction
endif
当然你也可以在github上查看源码和使用说明。
Microsoft Translator API的文档在这里。