最近看英文文档比较多,但英语水平不咋地,需要借助翻译工具。在ubuntu下,有startdict、goldendict等字典,但字典毕竟是字典,解释太多,用着不太爽。平时喜欢用谷歌翻译,最近谷歌翻译的水平也的确提升了不少,可惜没有客户端,平时看个PDF啥的也用不了,一顿google之后,发现Python有个翻译模块(translate),调用了google api 进行翻译(没有直接使用google api,而是封装了一下,接口为 http://mymemory.translated.net/api/get?q=%s&langpair=%s|%s ),目标只是能用谷歌翻译,还不用花钱就行。也不想管它用了啥API。
本来想写个接口封装一下,直接用goldendict显示的,无奈网络延迟太大,谷歌翻译都没出结果,字典的弹框就出来了,能找到goldendict的源码,但看到那一坨代码,实在没有修改的欲望。偶然的机会,发现了某道有ubuntu的客户端,解压出来,居然是python的代码,还是python大法好,这样就来优雅地改一下代码吧。
最后实现功能:
1.在弹框中显示调用translate模块显示的翻译信息
2.
3.点击保存,将所翻译的单词保存到指定目录的translate.csv文件中
4.调整弹框显示,解决翻译文本过长导致弹框显示不全的问题
实现代码:
提前安装translate模块
pip install translate
使用python3,先安装youdao的客户端,解决依赖关系,然后把youdao卸载。
下载.deb包,解压,参考文章:http://www.linuxdiyf.com/linux/20622.html
在dae/utils.py增加代码
def get_conf():
import json
import os
with open('configuration.json', 'r') as f:
conf = json.load(f)
return conf
修改translate.py文件
修改get_translate方法
def get_translate(self, text):
data = { "keyfrom" : "deskdict.linux", "q" : text.encode("utf-8"), "doctype" : "xml", "xmlVersion" : 8.2,
"client" : const.client, "id" : "cee84504d9984f1b2", "vendor": "deskdict.linux",
"in" : "YoudaoDict", "appVer" : "5.4.46.5554", "appZengqiang" : 0, "le" : "eng", "LTH" : 40}
# self.clear_translate()
# try:
ret = requests.get("http://dict.youdao.com/search", params=data).text
ret = ret.encode('utf-8')
pq = PyQuery(ret, parser="xml")
test_data = {"q": text, "type": 1, "pos": -1, "client": const.client}
test_ret = json.loads(requests.get("http://dict.youdao.com/jsonresult", params=test_data).text)
self.translate_info.text = text
text = str(text).replace('\n',' ')
from dae.utils import get_conf
conf = get_conf()
self.translate_info.webtrans = "谷歌翻译:\n"
if (str(conf['useTranslateModule']).upper() == 'TRUE' ):
self.translate_info.webtrans = self.translate_info.webtrans + useTranslateComponent(text) + "\n"
# if self.translate_info.webtrans:
self.translate_info.webtrans =self.translate_info.webtrans + "有道:\n"
self.translate_info.trans = '\n'.join([PyQuery(l)("i").text() for l in pq('trs l')])
#self.translate_info.phonetic = test_ret.get("ussm", "")
self.translate_info.webtrans = self.translate_info.webtrans + self.wrap_web_trans(pq)
# self.translate_info.lang = test_ret.get("lang", "")
#
# except:
# with open_offline_dict() as obj:
# ret = obj.query(text)
# if ret:
# self.translate_info.text = text
# self.translate_info.trans = ret[1].replace("\\n", "\n")
# self.translate_info.phonetic = ret[0][1:-1]
# self.translate_info.webtrans = "抱歉,从网络获取结果失败,请检测网络重试"
# self.translate_info.lang = "eng"
# self.translate_info.voices = get_voice_simple(text)
# if not text:
# return
#self.clear_translate()
#self.translate_info.text = text
if not self.translate_info.webtrans:
self.translate_info.webtrans = "查询失败"
if self.translate_info.webtrans:
self.translateFinished.emit()
在translate.py中添加代码(本来想直接使用translate模块的,但会出错,改用系统调用的方法):
def useTranslateComponent(text):
import translate
# import sys
# import locale
# from_lang = 'en'
# to_lang = 'zh'
# translator = translate.Translator(from_lang,to_lang)
# translation = translator.translate(text)
# if sys.version_info.major == 2:
# translation =translation.encode(locale.getpreferredencoding())
# return translation
import os
from dae.utils import get_conf
conf = get_conf()
cmd = conf['cmd']
translation = os.popen(cmd + " '" + text + "'").readlines()[0] #系统调用translate进行翻译
return translation
在windows.py添加类:
#@ 保存到文件
class saveToFile(QtCore.QObject):
@QtCore.pyqtSlot(str, str)
def saveToFile(self,fromText,toText):
import os
import csv
from dae.utils import get_conf
toText = str(toText).replace('谷歌翻译:','')
toText = toText.split('有道:')
firstText = ''
if toText[0]:
firstText = toText[0].strip('\n')
lastText = toText[1].replace('有道:','').strip('\n').lstrip('w. ')
if (firstText or lastText):
if not firstText:
firstText = ' '
if not lastText:
lastText = ' '
conf = get_conf()
savePath = str(conf['savePath']).rstrip('/') + '/translate.csv'
if not os.path.exists(savePath):
with open(savePath,'a+') as f:
writer = csv.writer(f)
writer.writerow(['翻译内容','谷歌翻译','有道词典'])
writeData = [
fromText, firstText, lastText
]
writer.writerow(writeData)
f.close()
return
with open(savePath,'a+') as f:
writer = csv.writer(f)
writeData = [
fromText, firstText, lastText
]
writer.writerow(writeData)
f.close()
return
return
在window.py 的__init__()方法中添加代码
#@ 单词保存到文件
self.saveToFile = saveToFile()
self.qml_context.setContextProperty("saveToFile", self.saveToFile) #把saveToFile类暴露给qml文件
在TranslateContent.qml 添加TextEdit,位置自己看着办就行
TextEdit{
color: "#ff0000"
anchors.verticalCenter: parent.verticalCenter
text: " 保存"
selectByMouse: true
readOnly: true
font.pixelSize: 15
MouseArea {
anchors.fill: parent
hoverEnabled: true
onExited: {
cursorShape = Qt.ArrowCursor
}
onClicked: {
saveToFile.saveToFile(translateInfo.text, translateInfo.webtrans)
if (parent.color == "#2699eb"){
parent.color = "#ff0000";
}
else{
if(parent.color == "#ff0000"){
parent.color = "#2699eb"
}
}
}
}
}
修改翻译内容显示方式
TextEdit{
id: keywordsText
width: parent.width
//anchors.verticalCenter: parent.verticalCenter
selectByMouse: true
readOnly: true
text: translateInfo.text
wrapMode: Text.WordWrap
font.pixelSize: 13
font.bold: true
}
在main.py所在文件夹下添加配置文件configuration.json,配置文件,可以选择是否启用translate模块,配置保存翻译信息文件位置,使用translate时系统调用的命令
{
"useTranslateModule": "true",
"savePath": "/home/ubuntu/Desktop",
"cmd": "translate -f en -t zh "
}
保存,直接运行main.py youdao-dict-backend.py就行
总结
直接利用youdao原有的事件处理,总体能用,但没有startdict或goldendict流畅,如果能直接修改startdict或goldendict的代码,利用它们的事件处理,估计会更稳定,但我好像没有看那堆代码的欲望,希望你们能给出更好的解决方案。
尊重版权,尊重有道,只为个人测试使用,不做商用。