mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-29 16:44:13 +08:00
many
1 Update websocket.py
This commit is contained in:
parent
1b6503bb70
commit
fd9049e714
@ -69,6 +69,7 @@ class MAINUI:
|
|||||||
self.currentsignature = None
|
self.currentsignature = None
|
||||||
self.isrunning = True
|
self.isrunning = True
|
||||||
self.solvegottextlock = threading.Lock()
|
self.solvegottextlock = threading.Lock()
|
||||||
|
self.outputers = {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def textsource(self):
|
def textsource(self):
|
||||||
@ -248,13 +249,8 @@ class MAINUI:
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if onlytrans == False:
|
if onlytrans == False:
|
||||||
|
self.dispatchoutputer(text)
|
||||||
self.currenttext = text
|
self.currenttext = text
|
||||||
if (
|
|
||||||
globalconfig["outputtopasteboard"]
|
|
||||||
and globalconfig["sourcestatus2"]["copy"]["use"] == False
|
|
||||||
):
|
|
||||||
winsharedutils.clipboard_set(text)
|
|
||||||
|
|
||||||
if globalconfig["read_raw"]:
|
if globalconfig["read_raw"]:
|
||||||
self.currentread = text
|
self.currentread = text
|
||||||
self.autoreadcheckname()
|
self.autoreadcheckname()
|
||||||
@ -556,16 +552,32 @@ class MAINUI:
|
|||||||
else:
|
else:
|
||||||
self.hira_ = None
|
self.hira_ = None
|
||||||
|
|
||||||
|
@threader
|
||||||
|
def startoutputer_re(self, klass):
|
||||||
|
self.outputers[klass].init()
|
||||||
|
|
||||||
|
@threader
|
||||||
|
def startoutputer(self):
|
||||||
|
for classname in globalconfig["textoutputer"]:
|
||||||
|
if not os.path.exists("./LunaTranslator/textoutput/" + classname + ".py"):
|
||||||
|
continue
|
||||||
|
aclass = importlib.import_module("textoutput." + classname).Outputer
|
||||||
|
self.outputers[classname] = aclass(classname)
|
||||||
|
|
||||||
|
def dispatchoutputer(self, text):
|
||||||
|
for _, kls in self.outputers.items():
|
||||||
|
if kls.config["use"]:
|
||||||
|
kls.puttask(text)
|
||||||
|
|
||||||
def fanyiinitmethod(self, classname):
|
def fanyiinitmethod(self, classname):
|
||||||
try:
|
try:
|
||||||
if classname == "selfbuild":
|
if classname == "selfbuild":
|
||||||
if os.path.exists("./userconfig/selfbuild.py") == False:
|
if not os.path.exists("./userconfig/selfbuild.py"):
|
||||||
return None
|
return None
|
||||||
aclass = importlib.import_module("selfbuild").TS
|
aclass = importlib.import_module("selfbuild").TS
|
||||||
else:
|
else:
|
||||||
if (
|
if not os.path.exists(
|
||||||
os.path.exists("./LunaTranslator/translator/" + classname + ".py")
|
"./LunaTranslator/translator/" + classname + ".py"
|
||||||
== False
|
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
aclass = importlib.import_module("translator." + classname).TS
|
aclass = importlib.import_module("translator." + classname).TS
|
||||||
@ -783,7 +795,7 @@ class MAINUI:
|
|||||||
self.prepare()
|
self.prepare()
|
||||||
self.startxiaoxueguan()
|
self.startxiaoxueguan()
|
||||||
self.starthira()
|
self.starthira()
|
||||||
|
self.startoutputer()
|
||||||
self.settin_ui = Settin(self.translation_ui)
|
self.settin_ui = Settin(self.translation_ui)
|
||||||
self.transhis = gui.transhist.transhist(self.settin_ui)
|
self.transhis = gui.transhist.transhist(self.settin_ui)
|
||||||
gobject.baseobject.Prompt = Prompt()
|
gobject.baseobject.Prompt = Prompt()
|
||||||
|
@ -54,7 +54,7 @@ import gobject
|
|||||||
from myutils.config import _TR, _TRL, globalconfig, static_data
|
from myutils.config import _TR, _TRL, globalconfig, static_data
|
||||||
import winsharedutils
|
import winsharedutils
|
||||||
from myutils.wrapper import Singleton_close, Singleton, threader
|
from myutils.wrapper import Singleton_close, Singleton, threader
|
||||||
from myutils.utils import checkifnewgame
|
from myutils.utils import checkifnewgame, vidchangedtask
|
||||||
from myutils.proxy import getproxy
|
from myutils.proxy import getproxy
|
||||||
from gui.usefulwidget import yuitsu_switch, saveposwindow, getboxlayout
|
from gui.usefulwidget import yuitsu_switch, saveposwindow, getboxlayout
|
||||||
from myutils.vndb import parsehtmlmethod
|
from myutils.vndb import parsehtmlmethod
|
||||||
@ -533,6 +533,7 @@ class dialog_setting_game(QDialog):
|
|||||||
|
|
||||||
def _titlechange(x):
|
def _titlechange(x):
|
||||||
savehook_new_data[exepath]["title"] = x
|
savehook_new_data[exepath]["title"] = x
|
||||||
|
savehook_new_data[exepath]["istitlesetted"] = True
|
||||||
savehook_new_data[exepath]["searchnoresulttime"] = 0
|
savehook_new_data[exepath]["searchnoresulttime"] = 0
|
||||||
self.setWindowTitle(x)
|
self.setWindowTitle(x)
|
||||||
gametitleitme.settitle(x)
|
gametitleitme.settitle(x)
|
||||||
@ -553,6 +554,7 @@ class dialog_setting_game(QDialog):
|
|||||||
_pixmap = QPixmap(res)
|
_pixmap = QPixmap(res)
|
||||||
if _pixmap.isNull() == False:
|
if _pixmap.isNull() == False:
|
||||||
savehook_new_data[exepath]["imagepath"] = res
|
savehook_new_data[exepath]["imagepath"] = res
|
||||||
|
savehook_new_data[exepath]["isimagepathusersetted"] = True
|
||||||
imgpath.setText(res)
|
imgpath.setText(res)
|
||||||
gametitleitme.setimg(_pixmap)
|
gametitleitme.setimg(_pixmap)
|
||||||
|
|
||||||
@ -572,13 +574,7 @@ class dialog_setting_game(QDialog):
|
|||||||
vndbid.setValidator(QIntValidator())
|
vndbid.setValidator(QIntValidator())
|
||||||
vndbid.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
|
vndbid.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
|
||||||
|
|
||||||
def changevid(exepath, text):
|
vndbid.textEdited.connect(functools.partial(vidchangedtask, exepath))
|
||||||
savehook_new_data[exepath]["vid"] = int(text)
|
|
||||||
savehook_new_data[exepath]["infopath"] = None
|
|
||||||
savehook_new_data[exepath]["searchnoresulttime"] = 0
|
|
||||||
# savehook_new_data[exepath]['imagepath']=None
|
|
||||||
|
|
||||||
vndbid.textEdited.connect(functools.partial(changevid, exepath))
|
|
||||||
|
|
||||||
statiswids = [
|
statiswids = [
|
||||||
QLabel(_TR("统计信息")),
|
QLabel(_TR("统计信息")),
|
||||||
@ -691,8 +687,8 @@ class dialog_setting_game(QDialog):
|
|||||||
|
|
||||||
methodtab = QTabWidget()
|
methodtab = QTabWidget()
|
||||||
methodtab.addTab(self.gethooktab(exepath), "HOOK")
|
methodtab.addTab(self.gethooktab(exepath), "HOOK")
|
||||||
methodtab.addTab(self.getpretranstab(exepath), "预翻译")
|
methodtab.addTab(self.getpretranstab(exepath), _TR("预翻译"))
|
||||||
methodtab.addTab(self.getttssetting(exepath), "语音")
|
methodtab.addTab(self.getttssetting(exepath), _TR("语音"))
|
||||||
formLayout.addWidget(methodtab)
|
formLayout.addWidget(methodtab)
|
||||||
|
|
||||||
self.show()
|
self.show()
|
||||||
|
@ -334,17 +334,55 @@ def gethookembedgrid(self):
|
|||||||
return grids
|
return grids
|
||||||
|
|
||||||
|
|
||||||
def setTabclip(self):
|
def getTabclip(self):
|
||||||
|
|
||||||
grids = [
|
grids = [
|
||||||
[
|
[
|
||||||
("提取的文本自动复制到剪贴板", 5),
|
("排除复制自翻译器的文本", 3),
|
||||||
(getsimpleswitch(globalconfig, "outputtopasteboard"), 1),
|
getsimpleswitch(globalconfig, "excule_from_self"),
|
||||||
("", 3),
|
("", 3),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
return grids
|
||||||
|
|
||||||
|
|
||||||
|
def outputgrid(self):
|
||||||
|
|
||||||
|
grids = [
|
||||||
|
[("自动输出提取的文本", 10)],
|
||||||
|
[],
|
||||||
|
[("剪贴板", 10)],
|
||||||
|
[
|
||||||
|
"",
|
||||||
|
("输出到剪贴板", 5),
|
||||||
|
(getsimpleswitch(globalconfig["textoutputer"]["clipboard"], "use"), 1),
|
||||||
|
],
|
||||||
|
[("WebSocket", 10)],
|
||||||
|
[
|
||||||
|
"",
|
||||||
|
("输出到WebSocket", 5),
|
||||||
|
(
|
||||||
|
getsimpleswitch(
|
||||||
|
globalconfig["textoutputer"]["websocket"],
|
||||||
|
"use",
|
||||||
|
callback=lambda _: gobject.baseobject.startoutputer_re("websocket"),
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
("排除复制自翻译器的文本", 5),
|
"",
|
||||||
(getsimpleswitch(globalconfig, "excule_from_self"), 1),
|
("端口号", 5),
|
||||||
|
(
|
||||||
|
getspinbox(
|
||||||
|
0,
|
||||||
|
65535,
|
||||||
|
globalconfig["textoutputer"]["websocket"],
|
||||||
|
"port",
|
||||||
|
callback=lambda _: gobject.baseobject.startoutputer_re("websocket"),
|
||||||
|
),
|
||||||
|
3,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
return grids
|
return grids
|
||||||
@ -462,12 +500,13 @@ def setTabOne(self):
|
|||||||
def setTabOne_lazy(self):
|
def setTabOne_lazy(self):
|
||||||
|
|
||||||
tab = self.makesubtab_lazy(
|
tab = self.makesubtab_lazy(
|
||||||
["HOOK设置", "OCR设置", "剪贴板", "内嵌翻译"],
|
["HOOK设置", "OCR设置", "剪贴板", "内嵌翻译", "文本输出"],
|
||||||
[
|
[
|
||||||
lambda: self.makescroll(self.makegrid(gethookgrid(self))),
|
lambda: self.makescroll(self.makegrid(gethookgrid(self))),
|
||||||
lambda: self.makescroll(self.makegrid(getocrgrid(self))),
|
lambda: self.makescroll(self.makegrid(getocrgrid(self))),
|
||||||
lambda: self.makescroll(self.makegrid(setTabclip(self))),
|
lambda: self.makescroll(self.makegrid(getTabclip(self))),
|
||||||
lambda: self.makescroll(self.makegrid(gethookembedgrid(self))),
|
lambda: self.makescroll(self.makegrid(gethookembedgrid(self))),
|
||||||
|
lambda: self.makescroll(self.makegrid(outputgrid(self))),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -280,6 +280,13 @@ def setTab7_lazy(self):
|
|||||||
"",
|
"",
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
if globalconfig["languageuse"] == 2: # en
|
||||||
|
grids2 += [
|
||||||
|
[
|
||||||
|
(("使用VNDB数据替换人名"), 6),
|
||||||
|
getsimpleswitch(globalconfig, "vndbmapname"),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
def __():
|
def __():
|
||||||
_w = self.makescroll(self.makegrid(grids, True, savelist, savelay))
|
_w = self.makescroll(self.makegrid(grids, True, savelist, savelay))
|
||||||
|
@ -93,6 +93,8 @@ def resourcegrid(self):
|
|||||||
else:
|
else:
|
||||||
if link[-8:] == "releases":
|
if link[-8:] == "releases":
|
||||||
__ = False
|
__ = False
|
||||||
|
elif link[-1] == "/":
|
||||||
|
__ = False
|
||||||
else:
|
else:
|
||||||
__ = True
|
__ = True
|
||||||
grid.append([(_TR(name), 1, ""), (makehtml(link, __), 2, "link")])
|
grid.append([(_TR(name), 1, ""), (makehtml(link, __), 2, "link")])
|
||||||
|
@ -60,8 +60,11 @@ def getdefaultsavehook(gamepath, title=None):
|
|||||||
"needinserthookcode": [],
|
"needinserthookcode": [],
|
||||||
"embedablehook": [],
|
"embedablehook": [],
|
||||||
"imagepath": None,
|
"imagepath": None,
|
||||||
|
"isimagepathusersetted": False,
|
||||||
|
"istitlesetted": False,
|
||||||
"infopath": None,
|
"infopath": None,
|
||||||
"vid": 0,
|
"vid": 0,
|
||||||
|
"namemap": {},
|
||||||
"statistic_playtime": 0,
|
"statistic_playtime": 0,
|
||||||
"statistic_wordcount": 0,
|
"statistic_wordcount": 0,
|
||||||
"statistic_wordcount_nodump": 0,
|
"statistic_wordcount_nodump": 0,
|
||||||
|
@ -311,6 +311,31 @@ _selfdefpost = None
|
|||||||
_selfdefpostmd5 = None
|
_selfdefpostmd5 = None
|
||||||
|
|
||||||
|
|
||||||
|
def trymapnameofvndb(s):
|
||||||
|
if not ((globalconfig["languageuse"] == 2) and globalconfig["vndbmapname"]):
|
||||||
|
return s
|
||||||
|
|
||||||
|
try:
|
||||||
|
exepath = gobject.baseobject.textsource.pname
|
||||||
|
namemap = savehook_new_data[exepath]["namemap"]
|
||||||
|
bettermap = {}
|
||||||
|
for k, v in namemap.items():
|
||||||
|
spja = k.split("・")
|
||||||
|
spen = v.split(" ")
|
||||||
|
if len(spja) == len(spen) and len(spen) > 1:
|
||||||
|
for i in range(len(spja)):
|
||||||
|
if len(spja[i]) >= 2:
|
||||||
|
bettermap[spja[i]] = spen[i]
|
||||||
|
|
||||||
|
for k, v in namemap.items():
|
||||||
|
s = s.replace(k, v)
|
||||||
|
for k, v in bettermap.items():
|
||||||
|
s = s.replace(k, v)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
def POSTSOLVE(line):
|
def POSTSOLVE(line):
|
||||||
global _selfdefpostmd5, _selfdefpost
|
global _selfdefpostmd5, _selfdefpost
|
||||||
if line == "":
|
if line == "":
|
||||||
@ -399,4 +424,5 @@ def POSTSOLVE(line):
|
|||||||
print_exc()
|
print_exc()
|
||||||
if postitem == "_11":
|
if postitem == "_11":
|
||||||
raise e
|
raise e
|
||||||
|
line = trymapnameofvndb(line)
|
||||||
return line
|
return line
|
||||||
|
@ -18,10 +18,29 @@ from myutils.config import (
|
|||||||
getdefaultsavehook,
|
getdefaultsavehook,
|
||||||
)
|
)
|
||||||
import threading, queue
|
import threading, queue
|
||||||
import re
|
import re, heapq
|
||||||
from myutils.vndb import searchforidimage
|
from myutils.vndb import searchforidimage
|
||||||
|
|
||||||
|
|
||||||
|
class PriorityQueue:
|
||||||
|
def __init__(self):
|
||||||
|
self._heap = []
|
||||||
|
self._sema = threading.Semaphore(0)
|
||||||
|
self._idx = 0
|
||||||
|
|
||||||
|
def put(self, item, priority=0):
|
||||||
|
heapq.heappush(self._heap, (-priority, self._idx, item))
|
||||||
|
self._idx += 1
|
||||||
|
self._sema.release()
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
self._sema.acquire()
|
||||||
|
return heapq.heappop(self._heap)[-1]
|
||||||
|
|
||||||
|
def empty(self):
|
||||||
|
return bool(len(self._heap) == 0)
|
||||||
|
|
||||||
|
|
||||||
def checkimage(gamepath):
|
def checkimage(gamepath):
|
||||||
return (savehook_new_data[gamepath]["imagepath"] is None) or (
|
return (savehook_new_data[gamepath]["imagepath"] is None) or (
|
||||||
os.path.exists(savehook_new_data[gamepath]["imagepath"]) == False
|
os.path.exists(savehook_new_data[gamepath]["imagepath"]) == False
|
||||||
@ -49,7 +68,7 @@ def checkneed(gamepath):
|
|||||||
return (gamepath in savehook_new_data) and (checkvid(gamepath))
|
return (gamepath in savehook_new_data) and (checkvid(gamepath))
|
||||||
|
|
||||||
|
|
||||||
searchvndbqueue = queue.Queue()
|
searchvndbqueue = PriorityQueue()
|
||||||
|
|
||||||
|
|
||||||
def dispatachtask(gamepath):
|
def dispatachtask(gamepath):
|
||||||
@ -57,7 +76,7 @@ def dispatachtask(gamepath):
|
|||||||
return
|
return
|
||||||
__t = []
|
__t = []
|
||||||
if savehook_new_data[gamepath]["vid"]:
|
if savehook_new_data[gamepath]["vid"]:
|
||||||
searchvndbqueue.put((gamepath, [savehook_new_data[gamepath]["vid"]]))
|
searchvndbqueue.put((gamepath, [savehook_new_data[gamepath]["vid"]]), 0)
|
||||||
else:
|
else:
|
||||||
for _ in [
|
for _ in [
|
||||||
savehook_new_data[gamepath]["title"],
|
savehook_new_data[gamepath]["title"],
|
||||||
@ -82,7 +101,7 @@ def dispatachtask(gamepath):
|
|||||||
if (len(t) < 10) and (all(ord(c) < 128 for c in t)):
|
if (len(t) < 10) and (all(ord(c) < 128 for c in t)):
|
||||||
continue
|
continue
|
||||||
lst.append(t)
|
lst.append(t)
|
||||||
searchvndbqueue.put((gamepath, lst))
|
searchvndbqueue.put((gamepath, lst), 0)
|
||||||
|
|
||||||
|
|
||||||
def everymethodsthread():
|
def everymethodsthread():
|
||||||
@ -102,13 +121,21 @@ def everymethodsthread():
|
|||||||
saveimg = data.get("imagepath", None)
|
saveimg = data.get("imagepath", None)
|
||||||
saveinfo = data.get("infopath", None)
|
saveinfo = data.get("infopath", None)
|
||||||
vid = data.get("vid", None)
|
vid = data.get("vid", None)
|
||||||
print(data)
|
title = data.get("title", None)
|
||||||
|
namemap = data.get("namemap", None)
|
||||||
|
|
||||||
if not vid:
|
if not vid:
|
||||||
continue
|
continue
|
||||||
savehook_new_data[gamepath]["vid"] = int(vid[1:])
|
savehook_new_data[gamepath]["vid"] = int(vid[1:])
|
||||||
if checkimage(gamepath):
|
if saveimg and (not savehook_new_data[gamepath]["isimagepathusersetted"]):
|
||||||
savehook_new_data[gamepath]["imagepath"] = saveimg
|
savehook_new_data[gamepath]["imagepath"] = saveimg
|
||||||
|
if title and (not savehook_new_data[gamepath]["istitlesetted"]):
|
||||||
|
savehook_new_data[gamepath]["title"] = title
|
||||||
|
if saveinfo:
|
||||||
savehook_new_data[gamepath]["infopath"] = saveinfo
|
savehook_new_data[gamepath]["infopath"] = saveinfo
|
||||||
|
if namemap:
|
||||||
|
savehook_new_data[gamepath]["namemap"] = namemap
|
||||||
|
print(namemap)
|
||||||
succ = True
|
succ = True
|
||||||
break
|
break
|
||||||
if succ == False:
|
if succ == False:
|
||||||
@ -118,6 +145,17 @@ def everymethodsthread():
|
|||||||
threading.Thread(target=everymethodsthread).start()
|
threading.Thread(target=everymethodsthread).start()
|
||||||
|
|
||||||
|
|
||||||
|
def vidchangedtask(gamepath, vid):
|
||||||
|
try:
|
||||||
|
vid = int(vid)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
savehook_new_data[gamepath]["vid"] = vid
|
||||||
|
savehook_new_data[gamepath]["infopath"] = None
|
||||||
|
savehook_new_data[gamepath]["searchnoresulttime"] = 0
|
||||||
|
searchvndbqueue.put((gamepath, [vid]), 1)
|
||||||
|
|
||||||
|
|
||||||
def checkifnewgame(gamepath, title=None):
|
def checkifnewgame(gamepath, title=None):
|
||||||
if gamepath not in savehook_new_list:
|
if gamepath not in savehook_new_list:
|
||||||
savehook_new_list.insert(0, gamepath)
|
savehook_new_list.insert(0, gamepath)
|
||||||
|
@ -72,69 +72,103 @@ def vndbdowloadinfo(vid):
|
|||||||
return savepath
|
return savepath
|
||||||
|
|
||||||
|
|
||||||
def searchforidimage(title):
|
def safegetvndbjson(url, json, getter):
|
||||||
if isinstance(title, str):
|
try:
|
||||||
|
_ = requests.post(
|
||||||
|
url,
|
||||||
|
json=json,
|
||||||
|
proxies=getproxy(),
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
return getter(_.json())
|
||||||
|
except:
|
||||||
|
print(_.text)
|
||||||
|
return None
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def gettitlebyid(vid):
|
||||||
|
def _getter(js):
|
||||||
|
try:
|
||||||
|
return js["results"][0]["titles"][0]["title"] # ja title
|
||||||
|
except:
|
||||||
|
return js["results"][0]["title"] # en title
|
||||||
|
|
||||||
|
return safegetvndbjson(
|
||||||
|
"https://api.vndb.org/kana/vn",
|
||||||
|
{"filters": ["id", "=", vid], "fields": "title,titles.title"},
|
||||||
|
_getter,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def getimgbyid(vid):
|
||||||
|
return safegetvndbjson(
|
||||||
|
"https://api.vndb.org/kana/vn",
|
||||||
|
{"filters": ["id", "=", vid], "fields": "image.url"},
|
||||||
|
lambda js: js["results"][0]["image"]["url"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def getvidbytitle_vn(title):
|
||||||
|
return safegetvndbjson(
|
||||||
|
"https://api.vndb.org/kana/vn",
|
||||||
|
{"filters": ["search", "=", title], "fields": "id", "sort": "searchrank"},
|
||||||
|
lambda js: js["results"][0]["id"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def getvidbytitle_release(title):
|
||||||
|
return safegetvndbjson(
|
||||||
|
"https://api.vndb.org/kana/release",
|
||||||
|
{"filters": ["search", "=", title], "fields": "id", "sort": "searchrank"},
|
||||||
|
lambda js: js["results"][0]["id"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def getvidbytitle(title):
|
||||||
|
vid = getvidbytitle_vn(title)
|
||||||
|
if vid:
|
||||||
|
return vid
|
||||||
|
return getvidbytitle_release(title)
|
||||||
|
|
||||||
|
|
||||||
|
def getcharnamemapbyid(vid):
|
||||||
|
res = safegetvndbjson(
|
||||||
|
"https://api.vndb.org/kana/character",
|
||||||
|
{
|
||||||
|
"filters": [
|
||||||
|
"vn",
|
||||||
|
"=",
|
||||||
|
["id", "=", vid],
|
||||||
|
],
|
||||||
|
"fields": "name,original",
|
||||||
|
},
|
||||||
|
lambda js: js["results"],
|
||||||
|
)
|
||||||
|
namemap = {}
|
||||||
|
try:
|
||||||
|
for r in res:
|
||||||
|
namemap[r["original"]] = r["name"]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return namemap
|
||||||
|
|
||||||
|
|
||||||
|
def searchforidimage(titleorid):
|
||||||
|
print(titleorid)
|
||||||
if os.path.exists("./cache/vndb") == False:
|
if os.path.exists("./cache/vndb") == False:
|
||||||
os.mkdir("./cache/vndb")
|
os.mkdir("./cache/vndb")
|
||||||
js = requests.post(
|
if isinstance(titleorid, str):
|
||||||
"https://api.vndb.org/kana/vn",
|
vid = getvidbytitle(titleorid)
|
||||||
json={
|
elif isinstance(titleorid, int):
|
||||||
"filters": ["search", "=", title],
|
vid = "v{}".format(titleorid)
|
||||||
"fields": "image.url",
|
img = getimgbyid(vid)
|
||||||
"sort": "searchrank",
|
title = gettitlebyid(vid)
|
||||||
},
|
namemap = getcharnamemapbyid(vid)
|
||||||
proxies=getproxy(),
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
results = js.json()["results"]
|
|
||||||
except:
|
|
||||||
print(js.text)
|
|
||||||
return {}
|
|
||||||
if len(results) == 0:
|
|
||||||
js = requests.post(
|
|
||||||
"https://api.vndb.org/kana/release",
|
|
||||||
json={
|
|
||||||
"filters": ["search", "=", title],
|
|
||||||
"fields": "vns.id",
|
|
||||||
"sort": "searchrank",
|
|
||||||
},
|
|
||||||
proxies=getproxy(),
|
|
||||||
)
|
|
||||||
results = js.json()["results"]
|
|
||||||
if len(results) == 0:
|
|
||||||
return {}
|
|
||||||
vns = results[0]["vns"]
|
|
||||||
if len(vns) == 0:
|
|
||||||
return {}
|
|
||||||
vid = vns[0]["id"]
|
|
||||||
js = requests.post(
|
|
||||||
"https://api.vndb.org/kana/vn",
|
|
||||||
json={"filters": ["id", "=", vid], "fields": "image.url"},
|
|
||||||
proxies=getproxy(),
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
results = js.json()["results"]
|
|
||||||
except:
|
|
||||||
print(js.text)
|
|
||||||
return {}
|
|
||||||
img = results[0]["image"]["url"]
|
|
||||||
else:
|
|
||||||
img = results[0]["image"]["url"]
|
|
||||||
vid = results[0]["id"]
|
|
||||||
elif isinstance(title, int):
|
|
||||||
vid = "v{}".format(title)
|
|
||||||
js = requests.post(
|
|
||||||
"https://api.vndb.org/kana/vn",
|
|
||||||
json={"filters": ["id", "=", vid], "fields": "image.url"},
|
|
||||||
proxies=getproxy(),
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
results = js.json()["results"]
|
|
||||||
except:
|
|
||||||
print(js.text)
|
|
||||||
return {}
|
|
||||||
img = results[0]["image"]["url"]
|
|
||||||
return {
|
return {
|
||||||
|
"namemap": namemap,
|
||||||
|
"title": title,
|
||||||
"vid": vid,
|
"vid": vid,
|
||||||
"infopath": vndbdowloadinfo(vid),
|
"infopath": vndbdowloadinfo(vid),
|
||||||
"imagepath": vndbdownloadimg(img),
|
"imagepath": vndbdownloadimg(img),
|
||||||
|
11
LunaTranslator/LunaTranslator/textoutput/clipboard.py
Normal file
11
LunaTranslator/LunaTranslator/textoutput/clipboard.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from textoutput.outputerbase import Base
|
||||||
|
from myutils.config import globalconfig
|
||||||
|
import winsharedutils
|
||||||
|
|
||||||
|
|
||||||
|
class Outputer(Base):
|
||||||
|
def dispatch(self, text):
|
||||||
|
if globalconfig["sourcestatus2"]["copy"]["use"]:
|
||||||
|
return
|
||||||
|
|
||||||
|
winsharedutils.clipboard_set(text)
|
29
LunaTranslator/LunaTranslator/textoutput/outputerbase.py
Normal file
29
LunaTranslator/LunaTranslator/textoutput/outputerbase.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
from myutils.config import globalconfig
|
||||||
|
from threading import Thread
|
||||||
|
from queue import Queue
|
||||||
|
|
||||||
|
|
||||||
|
class Base:
|
||||||
|
@property
|
||||||
|
def config(self):
|
||||||
|
return globalconfig["textoutputer"][self.classname]
|
||||||
|
|
||||||
|
def dispatch(self, text):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self, classname):
|
||||||
|
self.classname = classname
|
||||||
|
self.queue = Queue()
|
||||||
|
self.init()
|
||||||
|
Thread(target=self.dothread).start()
|
||||||
|
|
||||||
|
def dothread(self):
|
||||||
|
while True:
|
||||||
|
text = self.queue.get()
|
||||||
|
self.dispatch(text)
|
||||||
|
|
||||||
|
def puttask(self, text):
|
||||||
|
self.queue.put(text)
|
105
LunaTranslator/LunaTranslator/textoutput/websocket.py
Normal file
105
LunaTranslator/LunaTranslator/textoutput/websocket.py
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
from textoutput.outputerbase import Base
|
||||||
|
from traceback import print_exc
|
||||||
|
import socket
|
||||||
|
from base64 import encodebytes as base64encode
|
||||||
|
import hashlib
|
||||||
|
from myutils.wrapper import threader
|
||||||
|
|
||||||
|
|
||||||
|
class websocketserver:
|
||||||
|
def stop(self):
|
||||||
|
self.server_socket.close()
|
||||||
|
for sock in self.connectedsockets:
|
||||||
|
try:
|
||||||
|
sock.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self, port):
|
||||||
|
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.server_socket.bind(("localhost", port))
|
||||||
|
self.connectedsockets = []
|
||||||
|
self.errorsocks = []
|
||||||
|
self.listen()
|
||||||
|
|
||||||
|
@threader
|
||||||
|
def listen(self):
|
||||||
|
|
||||||
|
self.server_socket.listen(1)
|
||||||
|
while True:
|
||||||
|
client_socket, address = self.server_socket.accept()
|
||||||
|
print(f"Client connected: {address}")
|
||||||
|
|
||||||
|
self.handle_client(client_socket)
|
||||||
|
|
||||||
|
@threader
|
||||||
|
def handle_client(self, client_socket: socket.socket):
|
||||||
|
# 接收客户端的握手请求
|
||||||
|
request = client_socket.recv(1024).decode()
|
||||||
|
|
||||||
|
# 解析握手请求中的 WebSocket 关键信息
|
||||||
|
key = ""
|
||||||
|
for line in request.split("\r\n"):
|
||||||
|
if "Sec-WebSocket-Key:" in line:
|
||||||
|
key = line.split(":")[1].strip()
|
||||||
|
break
|
||||||
|
value = f"{key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11".encode("utf-8")
|
||||||
|
hashed = base64encode(hashlib.sha1(value).digest()).strip().lower().decode()
|
||||||
|
# 构造握手响应
|
||||||
|
response = "HTTP/1.1 101 Switching Protocols\r\n"
|
||||||
|
response += "Upgrade: websocket\r\n"
|
||||||
|
response += "Connection: Upgrade\r\n"
|
||||||
|
response += "sec-websocket-protocol: 111\r\n"
|
||||||
|
response += f"Sec-WebSocket-Accept: {hashed}\r\n\r\n"
|
||||||
|
|
||||||
|
# 发送握手响应给客户端
|
||||||
|
client_socket.send(response.encode())
|
||||||
|
self.connectedsockets.append(client_socket)
|
||||||
|
|
||||||
|
def maketextframe(self, message):
|
||||||
|
|
||||||
|
fin = 1
|
||||||
|
opcode = 0x1
|
||||||
|
payload = message.encode("utf-8")
|
||||||
|
length = len(payload)
|
||||||
|
|
||||||
|
frame = bytearray()
|
||||||
|
frame.append((fin << 7) | opcode)
|
||||||
|
|
||||||
|
if length <= 125:
|
||||||
|
frame.append(length)
|
||||||
|
elif length <= 65535:
|
||||||
|
frame.extend([126, (length >> 8) & 0xFF, length & 0xFF])
|
||||||
|
else:
|
||||||
|
frame.extend([127] + [(length >> (8 * i)) & 0xFF for i in range(7, -1, -1)])
|
||||||
|
|
||||||
|
frame.extend(payload)
|
||||||
|
return frame
|
||||||
|
|
||||||
|
def sendtext(self, text):
|
||||||
|
frame = self.maketextframe(text)
|
||||||
|
for i, sock in enumerate(self.connectedsockets):
|
||||||
|
if i in self.errorsocks:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
sock.send(frame)
|
||||||
|
except:
|
||||||
|
self.errorsocks.append(i)
|
||||||
|
|
||||||
|
|
||||||
|
class Outputer(Base):
|
||||||
|
def init(self):
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.server.stop()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if not self.config["use"]:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
self.server = websocketserver(self.config["port"])
|
||||||
|
except:
|
||||||
|
print_exc()
|
||||||
|
|
||||||
|
def dispatch(self, text):
|
||||||
|
self.server.sendtext(text)
|
@ -3,12 +3,12 @@ from queue import Queue
|
|||||||
|
|
||||||
from myutils.config import globalconfig, translatorsetting, static_data
|
from myutils.config import globalconfig, translatorsetting, static_data
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import threading, time, types, heapq
|
import time, types
|
||||||
import zhconv, gobject
|
import zhconv, gobject
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from myutils.commonbase import commonbase
|
from myutils.commonbase import commonbase
|
||||||
import functools
|
import functools
|
||||||
from myutils.utils import stringfyerror, autosql
|
from myutils.utils import stringfyerror, autosql, PriorityQueue
|
||||||
from myutils.commonbase import ArgsEmptyExc
|
from myutils.commonbase import ArgsEmptyExc
|
||||||
|
|
||||||
|
|
||||||
@ -57,25 +57,6 @@ def timeoutfunction(
|
|||||||
return t.get_result(timeout, checktutukufunction)
|
return t.get_result(timeout, checktutukufunction)
|
||||||
|
|
||||||
|
|
||||||
class PriorityQueue:
|
|
||||||
def __init__(self):
|
|
||||||
self._heap = []
|
|
||||||
self._sema = threading.Semaphore(0)
|
|
||||||
self._idx = 0
|
|
||||||
|
|
||||||
def put(self, item, priority=0):
|
|
||||||
heapq.heappush(self._heap, (-priority, self._idx, item))
|
|
||||||
self._idx += 1
|
|
||||||
self._sema.release()
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
self._sema.acquire()
|
|
||||||
return heapq.heappop(self._heap)[-1]
|
|
||||||
|
|
||||||
def empty(self):
|
|
||||||
return bool(len(self._heap) == 0)
|
|
||||||
|
|
||||||
|
|
||||||
class basetrans(commonbase):
|
class basetrans(commonbase):
|
||||||
def langmap(self):
|
def langmap(self):
|
||||||
return {}
|
return {}
|
||||||
|
@ -11,11 +11,21 @@
|
|||||||
"read_trans": false,
|
"read_trans": false,
|
||||||
"read_translator": 0,
|
"read_translator": 0,
|
||||||
"disappear_delay": 5,
|
"disappear_delay": 5,
|
||||||
|
"vndbmapname":false,
|
||||||
"network":1,
|
"network":1,
|
||||||
"hookmagpie":true,
|
"hookmagpie":true,
|
||||||
"hooklossless":true,
|
"hooklossless":true,
|
||||||
"direct_filterrepeat":false,
|
"direct_filterrepeat":false,
|
||||||
"allow_set_text_name":false,
|
"allow_set_text_name":false,
|
||||||
|
"textoutputer":{
|
||||||
|
"clipboard":{
|
||||||
|
"use":false
|
||||||
|
},
|
||||||
|
"websocket":{
|
||||||
|
"use":false,
|
||||||
|
"port":2333
|
||||||
|
}
|
||||||
|
},
|
||||||
"embedded": {
|
"embedded": {
|
||||||
"safecheck_use":true,
|
"safecheck_use":true,
|
||||||
"safecheckregexs": [
|
"safecheckregexs": [
|
||||||
@ -682,7 +692,6 @@
|
|||||||
"lighttheme":0,
|
"lighttheme":0,
|
||||||
"usesearchword": false,
|
"usesearchword": false,
|
||||||
"usecopyword":false,
|
"usecopyword":false,
|
||||||
"outputtopasteboard": false,
|
|
||||||
"ttscommon": {
|
"ttscommon": {
|
||||||
"rate": 1.0,
|
"rate": 1.0,
|
||||||
"volume": 100.0,
|
"volume": 100.0,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version":"v2.42.1",
|
"version":"v2.43.0",
|
||||||
"themes":{
|
"themes":{
|
||||||
"dark":[
|
"dark":[
|
||||||
{"file":"dark1.qss","name":"PyQtDarkTheme"},
|
{"file":"dark1.qss","name":"PyQtDarkTheme"},
|
||||||
@ -101,6 +101,10 @@
|
|||||||
"name": "MeCab",
|
"name": "MeCab",
|
||||||
"link": "https://github.com/HIllya51/RESOURCES/releases/download/dictionary/Mecab.zip"
|
"link": "https://github.com/HIllya51/RESOURCES/releases/download/dictionary/Mecab.zip"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "MeCab_unidic_latest",
|
||||||
|
"link": "https://clrd.ninjal.ac.jp/unidic/"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Unidic",
|
"name": "Unidic",
|
||||||
"link": "https://clrd.ninjal.ac.jp/unidic_archive/2302/unidic-cwj-202302.zip"
|
"link": "https://clrd.ninjal.ac.jp/unidic_archive/2302/unidic-cwj-202302.zip"
|
||||||
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "لا يقاطع",
|
"不被打断": "لا يقاطع",
|
||||||
"显示/隐藏历史翻译": "إظهار / إخفاء التاريخ",
|
"显示/隐藏历史翻译": "إظهار / إخفاء التاريخ",
|
||||||
"全屏/恢复游戏窗口": "كامل الشاشة / استعادة نافذة اللعبة",
|
"全屏/恢复游戏窗口": "كامل الشاشة / استعادة نافذة اللعبة",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "لا تحميل نموذج التعرف الضوئي على الحروف في هذه اللغة ، يرجى [ إعدادات أخرى ] - > [ تحميل الموارد ] - > [ التعرف الضوئي على الحروف حزمة اللغة ] تحميل نموذج استخراج الملفات / التعرف الضوئي على الحروف الطريق بعد استخدام"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "لا تحميل نموذج التعرف الضوئي على الحروف في هذه اللغة ، يرجى [ إعدادات أخرى ] - > [ تحميل الموارد ] - > [ التعرف الضوئي على الحروف حزمة اللغة ] تحميل نموذج استخراج الملفات / التعرف الضوئي على الحروف الطريق بعد استخدام",
|
||||||
|
"使用VNDB数据替换人名": "استبدال اسم الشخص مع بيانات فندب"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "不被打斷",
|
"不被打断": "不被打斷",
|
||||||
"显示/隐藏历史翻译": "顯示/隱藏歷史翻譯",
|
"显示/隐藏历史翻译": "顯示/隱藏歷史翻譯",
|
||||||
"全屏/恢复游戏窗口": "全屏/恢復遊戲視窗",
|
"全屏/恢复游戏窗口": "全屏/恢復遊戲視窗",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "未下載該語言的OCR模型,請在[其他設定]->[資源下載]->[OCR語言包]下載模型解壓到files/ocr路徑後使用"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "未下載該語言的OCR模型,請在[其他設定]->[資源下載]->[OCR語言包]下載模型解壓到files/ocr路徑後使用",
|
||||||
|
"使用VNDB数据替换人名": "使用VNDB數據替換人名"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "Not interrupted",
|
"不被打断": "Not interrupted",
|
||||||
"显示/隐藏历史翻译": "Show/hide historical translations",
|
"显示/隐藏历史翻译": "Show/hide historical translations",
|
||||||
"全屏/恢复游戏窗口": "Full screen/restore game window",
|
"全屏/恢复游戏窗口": "Full screen/restore game window",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "The OCR model for this language has not been downloaded. Please unzip the model to the files/ocr path in [Other Settings] ->[Resource Download] ->[OCR Language Pack] and use it"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "The OCR model for this language has not been downloaded. Please unzip the model to the files/ocr path in [Other Settings] ->[Resource Download] ->[OCR Language Pack] and use it",
|
||||||
|
"使用VNDB数据替换人名": "Replace person names with VNDB data"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "Sin ser interrumpido",
|
"不被打断": "Sin ser interrumpido",
|
||||||
"显示/隐藏历史翻译": "Mostrar / ocultar la traducción histórica",
|
"显示/隐藏历史翻译": "Mostrar / ocultar la traducción histórica",
|
||||||
"全屏/恢复游戏窗口": "Pantalla completa / restaurar la ventana del juego",
|
"全屏/恢复游戏窗口": "Pantalla completa / restaurar la ventana del juego",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "El modelo OCR del idioma no se ha descargado, por favor use después de descargar el modelo a la ruta files / OCR [configuración adicional] - > descarga de recursos] - > paquete de lenguaje ocr]"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "El modelo OCR del idioma no se ha descargado, por favor use después de descargar el modelo a la ruta files / OCR [configuración adicional] - > descarga de recursos] - > paquete de lenguaje ocr]",
|
||||||
|
"使用VNDB数据替换人名": "Reemplazar nombres con datos vndb"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "Ne pas être interrompu",
|
"不被打断": "Ne pas être interrompu",
|
||||||
"显示/隐藏历史翻译": "Afficher / masquer les traductions historiques",
|
"显示/隐藏历史翻译": "Afficher / masquer les traductions historiques",
|
||||||
"全屏/恢复游戏窗口": "Plein écran / restaurer la fenêtre de jeu",
|
"全屏/恢复游戏窗口": "Plein écran / restaurer la fenêtre de jeu",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Le modèle OCR pour cette langue n'a pas été téléchargé, utilisez - le après [autres paramètres] - > [ressources télécharger] - > [OCR Language Pack] télécharger le modèle Décompresser le chemin files / ocr"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Le modèle OCR pour cette langue n'a pas été téléchargé, utilisez - le après [autres paramètres] - > [ressources télécharger] - > [OCR Language Pack] télécharger le modèle Décompresser le chemin files / ocr",
|
||||||
|
"使用VNDB数据替换人名": "Remplacement des noms de personnes par des données vndb"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "Non interrotto",
|
"不被打断": "Non interrotto",
|
||||||
"显示/隐藏历史翻译": "Mostra/nasconde traduzioni storiche",
|
"显示/隐藏历史翻译": "Mostra/nasconde traduzioni storiche",
|
||||||
"全屏/恢复游戏窗口": "Finestra di gioco a schermo intero/ripristino",
|
"全屏/恢复游戏窗口": "Finestra di gioco a schermo intero/ripristino",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Il modello OCR per questa lingua non è stato scaricato. Si prega di decomprimere il modello nel percorso file/ocr in [Altre impostazioni] ->[Scaricare risorse] ->[OCR Language Pack] e utilizzarlo"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Il modello OCR per questa lingua non è stato scaricato. Si prega di decomprimere il modello nel percorso file/ocr in [Altre impostazioni] ->[Scaricare risorse] ->[OCR Language Pack] e utilizzarlo",
|
||||||
|
"使用VNDB数据替换人名": "Sostituisci i nomi delle persone con dati VNDB"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "中断されない",
|
"不被打断": "中断されない",
|
||||||
"显示/隐藏历史翻译": "履歴翻訳の表示/非表示",
|
"显示/隐藏历史翻译": "履歴翻訳の表示/非表示",
|
||||||
"全屏/恢复游戏窗口": "フルスクリーン/リカバリゲームウィンドウ",
|
"全屏/恢复游戏窗口": "フルスクリーン/リカバリゲームウィンドウ",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "この言語のOCRモデルはダウンロードされていません。[その他の設定]->[リソースダウンロード]->[OCR言語パック]ダウンロードモデルをfiles/ocrパスに解凍した後に使用してください"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "この言語のOCRモデルはダウンロードされていません。[その他の設定]->[リソースダウンロード]->[OCR言語パック]ダウンロードモデルをfiles/ocrパスに解凍した後に使用してください",
|
||||||
|
"使用VNDB数据替换人名": "VNDBデータを使用した人名の置換"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"离线": "오프라인",
|
"离线": "오프라인",
|
||||||
"显示/隐藏历史翻译": "히스토리 번역 표시 / 숨기기",
|
"显示/隐藏历史翻译": "히스토리 번역 표시 / 숨기기",
|
||||||
"全屏/恢复游戏窗口": "전체 화면 / 게임 창 복원",
|
"全屏/恢复游戏窗口": "전체 화면 / 게임 창 복원",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "이 언어의 OCR 모델을 다운로드하지 않았습니다. [기타 설정] -> [에셋 다운로드] -> [OCR 언어 팩] 모델을 다운로드하여 files/ocr 경로로 압축을 푼 후 사용하십시오."
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "이 언어의 OCR 모델을 다운로드하지 않았습니다. [기타 설정] -> [에셋 다운로드] -> [OCR 언어 팩] 모델을 다운로드하여 files/ocr 경로로 압축을 푼 후 사용하십시오.",
|
||||||
|
"使用VNDB数据替换人名": "VNDB 데이터로 사람 이름 바꾸기"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "Bez przerwy",
|
"不被打断": "Bez przerwy",
|
||||||
"显示/隐藏历史翻译": "Pokaż/ukryj tłumaczenia historyczne",
|
"显示/隐藏历史翻译": "Pokaż/ukryj tłumaczenia historyczne",
|
||||||
"全屏/恢复游戏窗口": "Pełny ekran/przywróć okno gry",
|
"全屏/恢复游戏窗口": "Pełny ekran/przywróć okno gry",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Model OCR dla tego języka nie został pobrany. Proszę rozpakować model do ścieżki plików/ocr w [Inne ustawienia] ->[Pobieranie zasobów] ->[OCR Language Pack] i użyć go"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Model OCR dla tego języka nie został pobrany. Proszę rozpakować model do ścieżki plików/ocr w [Inne ustawienia] ->[Pobieranie zasobów] ->[OCR Language Pack] i użyć go",
|
||||||
|
"使用VNDB数据替换人名": "Zastąp nazwiska osób na dane VNDB"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"非官方": "Неофициальные",
|
"非官方": "Неофициальные",
|
||||||
"显示/隐藏历史翻译": "Показать / скрыть исторический перевод",
|
"显示/隐藏历史翻译": "Показать / скрыть исторический перевод",
|
||||||
"全屏/恢复游戏窗口": "Полноэкранное / Восстановление игрового окна",
|
"全屏/恢复游戏窗口": "Полноэкранное / Восстановление игрового окна",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Модель OCR для этого языка не загружена, используйте ее после того, как [другие настройки] - > [загрузка ресурсов] - > [языковой пакет OCR] загрузит модель на путь files / ocr"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Модель OCR для этого языка не загружена, используйте ее после того, как [другие настройки] - > [загрузка ресурсов] - > [языковой пакет OCR] загрузит модель на путь files / ocr",
|
||||||
|
"使用VNDB数据替换人名": "Использование данных VNDB для замены имен"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "ไม่ถูกขัดจังหวะ",
|
"不被打断": "ไม่ถูกขัดจังหวะ",
|
||||||
"显示/隐藏历史翻译": "แสดง/ซ่อนการแปลประวัติ",
|
"显示/隐藏历史翻译": "แสดง/ซ่อนการแปลประวัติ",
|
||||||
"全屏/恢复游戏窗口": "เต็มหน้าจอ/กู้คืนหน้าต่างเกม",
|
"全屏/恢复游戏窗口": "เต็มหน้าจอ/กู้คืนหน้าต่างเกม",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "ไม่มีการดาวน์โหลดรุ่น OCR สำหรับภาษาโปรดใช้หลังจาก [การตั้งค่าอื่น ๆ] -> [ดาวน์โหลดทรัพยากร] -> [ชุดภาษา OCR] ดาวน์โหลดแบบจำลองเปิดเส้นทางไฟล์ / OCR"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "ไม่มีการดาวน์โหลดรุ่น OCR สำหรับภาษาโปรดใช้หลังจาก [การตั้งค่าอื่น ๆ] -> [ดาวน์โหลดทรัพยากร] -> [ชุดภาษา OCR] ดาวน์โหลดแบบจำลองเปิดเส้นทางไฟล์ / OCR",
|
||||||
|
"使用VNDB数据替换人名": "แทนที่ชื่อบุคคลด้วยข้อมูล VNDB"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "Bırakılmadı",
|
"不被打断": "Bırakılmadı",
|
||||||
"显示/隐藏历史翻译": "Tarihi çevirimleri göster/gizle",
|
"显示/隐藏历史翻译": "Tarihi çevirimleri göster/gizle",
|
||||||
"全屏/恢复游戏窗口": "Full screen/restore game window",
|
"全屏/恢复游戏窗口": "Full screen/restore game window",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Bu dilin OCR modeli indirilmedi. Lütfen modelini [Diğer Ayarlar] ->[Kaynak İndirme] ->[OCR Dil Paketi] içindeki dosyalara/ikiyüzlü yola bağlayın ve kullanın"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Bu dilin OCR modeli indirilmedi. Lütfen modelini [Diğer Ayarlar] ->[Kaynak İndirme] ->[OCR Dil Paketi] içindeki dosyalara/ikiyüzlü yola bağlayın ve kullanın",
|
||||||
|
"使用VNDB数据替换人名": "İnsan isimlerini VNDB veriyle değiştir"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"不被打断": "Не перервано",
|
"不被打断": "Не перервано",
|
||||||
"显示/隐藏历史翻译": "Показувати/сховати історичні переклади",
|
"显示/隐藏历史翻译": "Показувати/сховати історичні переклади",
|
||||||
"全屏/恢复游戏窗口": "Повний екран / відновити вікно гри",
|
"全屏/恢复游戏窗口": "Повний екран / відновити вікно гри",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Модель OCR для цієї мови не було звантажено. Будь ласка, відкрийте модель до шляху до файлів/ocr у [Інші параметри] ->[Звантаження ресурсів] ->[Пакет мови OCR] і скористайтеся ним"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Модель OCR для цієї мови не було звантажено. Будь ласка, відкрийте модель до шляху до файлів/ocr у [Інші параметри] ->[Звантаження ресурсів] ->[Пакет мови OCR] і скористайтеся ним",
|
||||||
|
"使用VNDB数据替换人名": "Замінити назви людей даними VNDB"
|
||||||
}
|
}
|
@ -743,5 +743,6 @@
|
|||||||
"非官方": "Không chính thức",
|
"非官方": "Không chính thức",
|
||||||
"显示/隐藏历史翻译": "Hiện/ẩn bản dịch lịch sử",
|
"显示/隐藏历史翻译": "Hiện/ẩn bản dịch lịch sử",
|
||||||
"全屏/恢复游戏窗口": "Toàn màn hình/Khôi phục cửa sổ trò chơi",
|
"全屏/恢复游戏窗口": "Toàn màn hình/Khôi phục cửa sổ trò chơi",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Mô hình OCR cho ngôn ngữ này chưa được tải xuống, vui lòng sử dụng sau khi [Cài đặt bổ sung] ->[Tải xuống tài nguyên] ->[Gói ngôn ngữ OCR] mô hình tải xuống đã được giải nén vào đường dẫn files/ocr"
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "Mô hình OCR cho ngôn ngữ này chưa được tải xuống, vui lòng sử dụng sau khi [Cài đặt bổ sung] ->[Tải xuống tài nguyên] ->[Gói ngôn ngữ OCR] mô hình tải xuống đã được giải nén vào đường dẫn files/ocr",
|
||||||
|
"使用VNDB数据替换人名": "Thay tên người bằng dữ liệu VNDB"
|
||||||
}
|
}
|
@ -129,7 +129,6 @@
|
|||||||
"其他": "",
|
"其他": "",
|
||||||
"设置所有词条为全局词条": "",
|
"设置所有词条为全局词条": "",
|
||||||
"过滤数字和英文字母": "",
|
"过滤数字和英文字母": "",
|
||||||
"提取的文本自动复制到剪贴板": "",
|
|
||||||
"Unicode范围": "",
|
"Unicode范围": "",
|
||||||
"原文颜色": "",
|
"原文颜色": "",
|
||||||
"未开始": "",
|
"未开始": "",
|
||||||
@ -743,5 +742,10 @@
|
|||||||
"不被打断": "",
|
"不被打断": "",
|
||||||
"显示/隐藏历史翻译": "",
|
"显示/隐藏历史翻译": "",
|
||||||
"全屏/恢复游戏窗口": "",
|
"全屏/恢复游戏窗口": "",
|
||||||
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": ""
|
"未下载该语言的OCR模型,请在[其他设置]->[资源下载]->[OCR语言包]下载模型解压到files/ocr路径后使用": "",
|
||||||
|
"使用VNDB数据替换人名": "",
|
||||||
|
"文本输出": "",
|
||||||
|
"自动输出提取的文本": "",
|
||||||
|
"输出到剪贴板": "",
|
||||||
|
"输出到WebSocket": ""
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user