Skip to content

Commit

Permalink
Gzip decompress supported, Yandex change response.
Browse files Browse the repository at this point in the history
  • Loading branch information
alekssamos committed Nov 11, 2020
1 parent 6267d3b commit e34bc76
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 34 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Дополнение Яндекс.Переводчик для NVDA

[Скачать версию 2020.11.11](https://github.com/alekssamos/YandexTranslate/releases/latest/download/YandexTranslate-2020.11.11.nvda-addon)
[Скачать версию 2020.11.12](https://github.com/alekssamos/YandexTranslate/releases/latest/download/YandexTranslate-2020.11.12.nvda-addon)

После установки зайдите в NVDA меню, Параметры, Жесты ввода, назначте удобные вам сочетания клавиш для YandexTranslate. Или используйте уже предустановленные.

Expand Down
75 changes: 43 additions & 32 deletions addon/globalPlugins/yandexTranslate/yandexfreetranslate.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
try: from utils import smartsplit
except: from .utils import smartsplit
import ssl
import gzip
import json
import os
import os.path
Expand All @@ -11,9 +11,11 @@
try:
import urllib.parse as urllibparse
import urllib.request as urllibrequest
import urllib.error as urlliberror
except ImportError:
import urllib as urllibrequest
import urllib as urllibparse
import urllib as urlliberror
sys.path.insert(0, os.path.dirname(__file__))
import socks
try: from sockshandler import SocksiPyHandler
Expand All @@ -23,20 +25,29 @@
class YandexFreeTranslateError(Exception): pass

class YandexFreeTranslate():
error_count = 0
siteurl = "https://translate.yandex.ru/"
apibaseurl = "https://translate.yandex.net/api/v1/tr.json/"
ua = r"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0"
key = ""
keysuffix = "-0-0"
keyfilename = os.path.join(os.path.expanduser("~"), ".YandexFreeTranslate.key")
expiretime = 60*60*24*4
backfilename = keyfilename+".back"
useProxy = False
proxy_protocol = ""
proxy_host = ""
proxy_port = 0
proxy_username = ""
proxy_password = ""
def setProxy(self, protocol, host, port, username, password):
def decode_response(self, response):
try:
res = response.decode("UTF8")
except UnicodeDecodeError:
res = gzip.decompress(response).decode("UTF8")
return res

def setProxy(self, protocol, host, port, username="", password=""):
self.useProxy = True
self.proxy_protocol = protocol
self.proxy_host = host
Expand Down Expand Up @@ -73,7 +84,6 @@ def _sid_to_key(self, sid):
l = []
for item in sid.split(splitter): l.append(item[::-1])
return splitter.join(l)+self.keysuffix

def _parse_sid(self):
try:
if self.useProxy:
Expand All @@ -84,13 +94,15 @@ def _parse_sid(self):
req.add_header("Accept", r"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 ")
req.add_header("Accept-Language", r"ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3")
req.add_header("DNT", "1")
req.add_header("Accept-Encoding", "gzip, deflate, br")
page = self._create_opener().open(req).read().decode("UTF8")
req.add_header("Accept-Encoding", "gzip")
response = self._create_opener().open(req).read()
page = self.decode_response(response)
#open("page.html", "w", encoding="utf8").write(page)
try:
return re.search(r'''SID[\s]?[:][\s]?['"]([^'"]+)['"]''', page).group(1)
except AttributeError:
raise YandexFreeTranslateError("blocked or not found \n"+str(page))
raise YandexFreeTranslateError("blocked or not found")
except: raise
finally:
if self.useProxy:
ssl._create_default_https_context = old_context
Expand All @@ -111,19 +123,23 @@ def _get_key(self):
return key
def get_key(self): return self._get_key()
def regenerate_key(self):
try:
if os.path.isfile(self.keyfilename): os.rename(self.keyfilename, self.keyfilename+".back")
except FileExistsError: pass
return self._get_key()
if os.path.isfile(self.backfilename): os.remove(self.backfilename)
if os.path.isfile(self.keyfilename):
os.rename(self.keyfilename, self.backfilename)
self.key = self._get_key()
return self.key
def __init__(self):
if not os.path.isfile(self.keyfilename) and os.path.isfile(self.keyfilename+".back"):
os.rename(self.keyfilename+".back", self.keyfilename)
if not os.path.isfile(self.keyfilename) and os.path.isfile(self.backfilename):
os.rename(self.backfilename, self.keyfilename)
def translate(self, lang, text=""):
resp = {}
content = None
try:
if self.useProxy:
old_context = ssl._create_default_https_context
ssl._create_default_https_context = ssl.create_default_context
if self.key == "": self.key = self._get_key()
if text == "": raise ValueError("text")
p=[]
for part in smartsplit(text, 500, 550):
req = self._create_request(self.apibaseurl+"translate?"+urllibparse.urlencode({
Expand All @@ -135,34 +151,29 @@ def translate(self, lang, text=""):
req.add_header("DNT", "1")
req.add_header("Accept-Encoding", "gzip, deflate, br")
try:
content = self._create_opener().open(req, data = urllibparse.urlencode({
response = self._create_opener().open(req, data = urllibparse.urlencode({
"options": 4, "text":part
}).encode("UTF8")).read().decode("UTF8")
}).encode("UTF8")).read()
content = self.decode_response(response)
resp = json.loads(content)
except json.JSONDecodeError:
raise YandexFreeTranslateError(content)
except (urlliberror.HTTPError, json.JSONDecodeError):
if self.error_count >= 2:
self.error_count = 0
if sys.exc_info()[0] == json.JSONDecodeError:
raise YandexFreeTranslateError(content)
else:
raise
else:
self.error_count = self.error_count + 1
self.regenerate_key()
return self.translate(lang, text)
if "text" not in resp:
raise YandexFreeTranslateError(content)
p.append(resp["text"][0])
resp["text"] = p
return resp
except: raise
finally:
if self.useProxy:
ssl._create_default_https_context = old_context


if __name__ == "__main__":
if len(sys.argv) < 4:
print("usage: "+sys.argv[0]+" \t sourcelang \t targetlang \t text or file.txt \t [output_file_name.txt]")
print('example: {0} "{1}" "{2}" "{3}"'.format(sys.argv[0], "en", "ru", "hello, world!"))
print('example: {0} "{1}" "{2}" "{3}"'.format(sys.argv[0], "en", "ru", "in.txt"))
sys.exit(0)
yt = YandexFreeTranslate()
text = sys.argv[3]
if len(text) < 150 and os.path.isfile(text): text = open(text, "r", encoding="utf8").read()
tr_text = yt.translate(sys.argv[1], sys.argv[2], text)
if len(sys.argv) == 5:
with open(sys.argv[4], "w") as f: f.write(tr_text)
print("text saved in file: "+sys.argv[4])
else:
print(tr_text)
2 changes: 1 addition & 1 deletion buildVars.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# Translators: Long description to be shown for this add-on on add-on information from add-ons manager
"addon_description": _("""Translates text using service Yandex Translate."""),
# version
"addon_version": "2020.11.11",
"addon_version": "2020.11.12",
# Author(s)
"addon_author": u"alekssamos <[email protected]>",
# URL for the add-on documentation support
Expand Down

0 comments on commit e34bc76

Please sign in to comment.