This commit is contained in:
恍兮惚兮 2024-05-16 01:36:03 +08:00
parent b43545bacb
commit 022e1553fb
46 changed files with 658 additions and 458 deletions

View File

@ -492,12 +492,13 @@ class MAINUI:
== False == False
): ):
continue continue
_hira = importlib.import_module("hiraparse." + name).hira _hira = importlib.import_module("hiraparse." + name)
_hira = getattr(_hira, name)
break break
try: try:
if _hira: if _hira:
self.hira_ = _hira() self.hira_ = _hira(name)
else: else:
self.hira_ = None self.hira_ = None
except: except:
@ -583,22 +584,7 @@ class MAINUI:
except: except:
return return
class cishuwrapper: return aclass(type_)
def __init__(self, _type) -> None:
self._ = _type()
@threader
def search(self, sentence):
try:
res = self._.search(sentence)
if res is None or res == "":
return
self.callback(res)
except:
pass
_ = cishuwrapper(aclass)
return _
def onwindowloadautohook(self): def onwindowloadautohook(self):
textsourceusing = globalconfig["sourcestatus2"]["texthook"]["use"] textsourceusing = globalconfig["sourcestatus2"]["texthook"]["use"]

View File

@ -0,0 +1,41 @@
from myutils.config import globalconfig
from myutils.wrapper import threader
class cishubase:
def init(self):
pass
def search(self, word):
return word
def __init__(self, typename) -> None:
self.typename = typename
self.callback = print
self.needinit = True
try:
self.init()
self.needinit = False
except:
pass
@threader
def safesearch(self, sentence):
try:
if self.needinit:
self.init()
self.needinit = False
try:
res = self.search(sentence)
except:
self.needinit = True
if res is None or res == "":
return
self.callback(res)
except:
pass
@property
def config(self):
return globalconfig["cishu"][self.typename]["args"]

View File

@ -1,14 +1,14 @@
from myutils.config import globalconfig
import sqlite3, os import sqlite3, os
import winsharedutils, re import winsharedutils, re
from myutils.utils import argsort, autosql from myutils.utils import argsort, autosql
from cishu.cishubase import cishubase
class edict: class edict(cishubase):
def __init__(self): def init(self):
self.sql = None self.sql = None
try: try:
path = globalconfig["cishu"]["edict"]["path"] path = self.config["path"]
if os.path.exists(path): if os.path.exists(path):
self.sql = autosql(sqlite3.connect(path, check_same_thread=False)) self.sql = autosql(sqlite3.connect(path, check_same_thread=False))
except: except:

View File

@ -1,15 +1,15 @@
from myutils.config import globalconfig
import winsharedutils, os import winsharedutils, os
import re import re
from myutils.utils import argsort from myutils.utils import argsort
from traceback import print_exc from traceback import print_exc
from cishu.cishubase import cishubase
class edict2: class edict2(cishubase):
def __init__(self): def init(self):
self.sql = None self.sql = None
try: try:
path = globalconfig["cishu"]["edict2"]["path"] path = self.config["path"]
if os.path.exists(path): if os.path.exists(path):
with open(path, "r", encoding="euc-jp") as ff: with open(path, "r", encoding="euc-jp") as ff:
_ = ff.read() _ = ff.read()

View File

@ -2,9 +2,10 @@ import requests
from urllib.parse import quote from urllib.parse import quote
import re import re
from myutils.proxy import getproxy from myutils.proxy import getproxy
from cishu.cishubase import cishubase
class goo: class goo(cishubase):
def search(self, word): def search(self, word):
url = "https://dictionary.goo.ne.jp/srch/all/{}/m1u/".format(quote(word)) url = "https://dictionary.goo.ne.jp/srch/all/{}/m1u/".format(quote(word))

View File

@ -1,35 +1,28 @@
from myutils.config import globalconfig
from myutils.utils import autosql from myutils.utils import autosql
import sqlite3 import sqlite3
import winsharedutils import winsharedutils
import os import os
from cishu.cishubase import cishubase
class linggesi: class linggesi(cishubase):
def __init__(self): def init(self):
self.sql = None self.sql = None
try: try:
if ( if (
os.path.exists( os.path.exists(os.path.join(self.config["path"], "ja-zh.db")) == False
os.path.join(globalconfig["cishu"]["linggesi"]["path"], "ja-zh.db") or os.path.exists(os.path.join(self.config["path"], "ja-zh-gbk.db"))
)
== False
or os.path.exists(
os.path.join(
globalconfig["cishu"]["linggesi"]["path"], "ja-zh-gbk.db"
)
)
== False == False
): ):
return return
self.sql = autosql( self.sql = autosql(
sqlite3.connect( sqlite3.connect(
os.path.join(globalconfig["cishu"]["linggesi"]["path"], "ja-zh.db"), os.path.join(self.config["path"], "ja-zh.db"),
check_same_thread=False, check_same_thread=False,
) )
) )
self.sql2 = sqlite3.connect( self.sql2 = sqlite3.connect(
os.path.join(globalconfig["cishu"]["linggesi"]["path"], "ja-zh-gbk.db"), os.path.join(self.config["path"], "ja-zh-gbk.db"),
check_same_thread=False, check_same_thread=False,
) )
except: except:

View File

@ -1,8 +1,10 @@
import requests import requests
from myutils.proxy import getproxy from myutils.proxy import getproxy
from cishu.cishubase import cishubase
class mojidict:
class mojidict(cishubase):
def search(self, word): def search(self, word):
try: try:
response = requests.post( response = requests.post(

View File

@ -1,11 +1,12 @@
import requests import requests
from urllib.parse import quote from urllib.parse import quote
from cishu.cishubase import cishubase
from myutils.proxy import getproxy from myutils.proxy import getproxy
import re import re
class weblio: class weblio(cishubase):
def search(self, word): def search(self, word):
url = "https://www.weblio.jp/content/" + quote(word) url = "https://www.weblio.jp/content/" + quote(word)

View File

@ -1,14 +1,15 @@
from myutils.config import globalconfig
import sqlite3, os import sqlite3, os
import winsharedutils import winsharedutils
from myutils.utils import argsort, autosql from myutils.utils import argsort, autosql
from cishu.cishubase import cishubase
class xiaoxueguan:
def __init__(self): class xiaoxueguan(cishubase):
def init(self):
self.sql = None self.sql = None
try: try:
path = globalconfig["cishu"]["xiaoxueguan"]["path"] path = self.config["path"]
if os.path.exists(path): if os.path.exists(path):
self.sql = autosql(sqlite3.connect(path, check_same_thread=False)) self.sql = autosql(sqlite3.connect(path, check_same_thread=False))
except: except:

View File

@ -3,9 +3,10 @@ import requests
from urllib.parse import quote from urllib.parse import quote
import re import re
from myutils.proxy import getproxy from myutils.proxy import getproxy
from cishu.cishubase import cishubase
class youdao: class youdao(cishubase):
@property @property
def srclang(self): def srclang(self):

View File

@ -310,6 +310,7 @@ class tagitem(QWidget):
super().__init__() super().__init__()
tagLayout = QHBoxLayout() tagLayout = QHBoxLayout()
tagLayout.setContentsMargins(0, 0, 0, 0) tagLayout.setContentsMargins(0, 0, 0, 0)
tagLayout.setSpacing(0)
self._type = _type self._type = _type
key = (tag, _type, refdata) key = (tag, _type, refdata)
self.setLayout(tagLayout) self.setLayout(tagLayout)

View File

@ -520,7 +520,7 @@ class hookselect(closeashidewindow):
savehook_new_data[gobject.baseobject.textsource.pname][ savehook_new_data[gobject.baseobject.textsource.pname][
"hooktypeasname" "hooktypeasname"
].__setitem__, ].__setitem__,
json.dumps(key), json.dumps(gobject.baseobject.textsource.serialkey(key)),
), ),
), ),
) )

View File

@ -1,6 +1,6 @@
import functools, os import functools, os
from myutils.config import globalconfig, _TRL from myutils.config import globalconfig, _TRL
from gui.inputdialog import getsomepath1, autoinitdialog from gui.inputdialog import autoinitdialog, autoinitdialog_items
from gui.usefulwidget import ( from gui.usefulwidget import (
getcolorbutton, getcolorbutton,
yuitsu_switch, yuitsu_switch,
@ -18,83 +18,54 @@ def gethiragrid(self):
grids = [] grids = []
i = 0 i = 0
self.ocrswitchs = {} self.hiraswitchs = {}
line = [] line = []
for name in globalconfig["hirasetting"]: for name in globalconfig["hirasetting"]:
_f = "./LunaTranslator/hiraparse/{}.py".format(name) _f = "./LunaTranslator/hiraparse/{}.py".format(name)
if os.path.exists(_f) == False: if os.path.exists(_f) == False:
continue continue
if "args" in globalconfig["hirasetting"][name]:
line += [ items = autoinitdialog_items(globalconfig["hirasetting"][name])
((globalconfig["hirasetting"][name]["name"]), 5), _3 = getcolorbutton(
getsimpleswitch( globalconfig,
globalconfig["hirasetting"][name], "",
"use",
parent=self,
name=name,
callback=functools.partial( callback=functools.partial(
yuitsu_switch, autoinitdialog,
self, self,
globalconfig["hirasetting"], globalconfig["hirasetting"][name]["name"],
"hiraswitchs", 800,
name, items,
gobject.baseobject.starthira,
), ),
pair="hiraswitchs", icon="fa.gear",
), constcolor="#FF69B4",
] )
items = []
for key in globalconfig["hirasetting"][name]:
if key == "path":
items.append(
{
"t": "file",
"l": globalconfig["hirasetting"][name]["name"],
"d": globalconfig["hirasetting"][name],
"k": "path",
"dir": True,
}
)
elif key == "token":
items.append(
{
"t": "lineedit",
"l": globalconfig["hirasetting"][name]["token_name"],
"d": globalconfig["hirasetting"][name],
"k": "token",
}
)
elif key == "codec":
items.append(
{
"t": "combo",
"l": "codec",
"d": globalconfig["hirasetting"][name],
"k": "codec",
"list": ["utf8", "shiftjis"],
}
)
if len(items):
items.append({"t": "okcancel", "callback": gobject.baseobject.starthira})
line += [
getcolorbutton(
globalconfig,
"",
callback=functools.partial(
autoinitdialog,
self,
globalconfig["hirasetting"][name]["name"],
800,
items,
),
icon="fa.gear",
constcolor="#FF69B4",
)
]
else: else:
line += [""] _3 = ""
line += [
((globalconfig["hirasetting"][name]["name"]), 6),
(
getsimpleswitch(
globalconfig["hirasetting"][name],
"use",
name=name,
parent=self,
callback=functools.partial(
yuitsu_switch,
self,
globalconfig["hirasetting"],
"hiraswitchs",
name,
gobject.baseobject.starthira,
),
pair="hiraswitchs",
),
1,
),
_3,
]
if i % 3 == 2: if i % 3 == 2:
grids.append(line) grids.append(line)
line = [] line = []
@ -112,7 +83,7 @@ def setTabcishu_l(self):
[ [
[("分词&假名分析器", 10)], [("分词&假名分析器", 10)],
[ [
("日语注音方案", 5), ("日语注音方案", 6),
( (
getsimplecombobox( getsimplecombobox(
_TRL(["平假名", "片假名", "罗马音"]), _TRL(["平假名", "片假名", "罗马音"]),
@ -128,7 +99,7 @@ def setTabcishu_l(self):
[], [],
[], [],
[ [
("点击单词查词", 5), ("点击单词查词", 6),
(getsimpleswitch(globalconfig, "usesearchword"), 1), (getsimpleswitch(globalconfig, "usesearchword"), 1),
getcolorbutton( getcolorbutton(
globalconfig, globalconfig,
@ -138,11 +109,11 @@ def setTabcishu_l(self):
constcolor="#FF69B4", constcolor="#FF69B4",
), ),
"", "",
("点击单词复制", 5), ("点击单词复制", 6),
(getsimpleswitch(globalconfig, "usecopyword"), 1), (getsimpleswitch(globalconfig, "usecopyword"), 1),
], ],
[ [
("使用原型查询", 5), ("使用原型查询", 6),
(getsimpleswitch(globalconfig, "usewordorigin"), 1), (getsimpleswitch(globalconfig, "usewordorigin"), 1),
], ],
[], [],
@ -156,33 +127,28 @@ def setTabcishu_l(self):
_f = "./LunaTranslator/cishu/{}.py".format(cishu) _f = "./LunaTranslator/cishu/{}.py".format(cishu)
if os.path.exists(_f) == False: if os.path.exists(_f) == False:
continue continue
items = autoinitdialog_items(globalconfig["cishu"][cishu])
line += [ line += [
(globalconfig["cishu"][cishu]["name"], 5), (globalconfig["cishu"][cishu]["name"], 6),
getsimpleswitch( getsimpleswitch(
globalconfig["cishu"][cishu], globalconfig["cishu"][cishu],
"use", "use",
callback=functools.partial(gobject.baseobject.startxiaoxueguan, cishu), callback=functools.partial(gobject.baseobject.startxiaoxueguan, cishu),
), ),
( getcolorbutton(
getcolorbutton( globalconfig,
globalconfig, "",
"", callback=functools.partial(
callback=functools.partial( autoinitdialog,
getsomepath1, self,
self, globalconfig["cishu"][cishu]["name"],
globalconfig["cishu"][cishu]["name"], 800,
globalconfig["cishu"][cishu], items,
"path", ),
globalconfig["cishu"][cishu]["name"], icon="fa.gear",
functools.partial(gobject.baseobject.startxiaoxueguan, cishu), constcolor="#FF69B4",
globalconfig["cishu"][cishu]["isdir"],
globalconfig["cishu"][cishu]["filter"],
),
icon="fa.gear",
constcolor="#FF69B4",
)
if "path" in globalconfig["cishu"][cishu]
else ""
), ),
] ]

View File

@ -16,7 +16,6 @@ def getocrgrid(self):
grids = [] grids = []
i = 0 i = 0
lendict = len(list(globalconfig["ocr"].keys()))
self.ocrswitchs = {} self.ocrswitchs = {}
line = [] line = []

View File

@ -65,4 +65,6 @@ class showocrimage(closeashidewindow):
self.originimage = originimage self.originimage = originimage
self.img1 = QPixmap.fromImage(originimage) self.img1 = QPixmap.fromImage(originimage)
self.img2 = QPixmap.fromImage(solved) self.img2 = QPixmap.fromImage(solved)
self.img1.setDevicePixelRatio(self.devicePixelRatioF())
self.img2.setDevicePixelRatio(self.devicePixelRatioF())
self.showimg() self.showimg()

View File

@ -1,4 +1,3 @@
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QWidget, QWidget,
QHBoxLayout, QHBoxLayout,
@ -7,24 +6,21 @@ from PyQt5.QtWidgets import (
QLineEdit, QLineEdit,
QPlainTextEdit, QPlainTextEdit,
QFormLayout, QFormLayout,
QAction,
QSizePolicy, QSizePolicy,
QStylePainter,
QStyleOptionTab,
QStyle,
QPushButton, QPushButton,
QTextEdit, QTextEdit,
QTabWidget,QFileDialog, QTabWidget,
QFileDialog,
QTabBar, QTabBar,
QLabel, QLabel,
) )
from PyQt5.QtGui import QPixmap, QImage
from traceback import print_exc from traceback import print_exc
import requests, json import requests, json
from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QCursor import qtawesome, functools, os, base64
import qtawesome, functools, os, re, base64 import gobject, uuid
import threading, gobject, uuid from myutils.config import globalconfig, _TR, static_data
from myutils.config import globalconfig, _TR, _TRL, static_data
import myutils.ankiconnect as anki import myutils.ankiconnect as anki
from gui.usefulwidget import ( from gui.usefulwidget import (
closeashidewindow, closeashidewindow,
@ -33,8 +29,8 @@ from gui.usefulwidget import (
getboxlayout, getboxlayout,
getspinbox, getspinbox,
getlineedit, getlineedit,
saveposwindow, getsimpleswitch,
getsimpleswitch,getcolorbutton, getcolorbutton,
tabadd_lazy, tabadd_lazy,
) )
from myutils.wrapper import threader from myutils.wrapper import threader
@ -42,16 +38,22 @@ from myutils.ocrutil import imageCut, ocr_run
from gui.rangeselect import rangeselct_function from gui.rangeselect import rangeselct_function
class AnkiWindow(closeashidewindow): class AnkiWindow(QWidget):
setcurrenttext = pyqtSignal(str) setcurrenttext = pyqtSignal(str)
__ocrsettext = pyqtSignal(str) __ocrsettext = pyqtSignal(str)
refreshhtml = pyqtSignal() refreshhtml = pyqtSignal()
def langdu(self): def langdu(self):
if gobject.baseobject.reader: if gobject.baseobject.reader:
self.audiopath.setText(gobject.baseobject.reader.syncttstofile( self.audiopath.setText(
self.wordedit.text() gobject.baseobject.reader.syncttstofile(self.currentword)
)) )
def langdu2(self):
if gobject.baseobject.reader:
self.audiopath_sentence.setText(
gobject.baseobject.reader.syncttstofile(self.example.toPlainText())
)
@threader @threader
def asyncocr(self, fname): def asyncocr(self, fname):
@ -63,20 +65,26 @@ class AnkiWindow(closeashidewindow):
fname = "./cache/ocr/cropforanki.png" fname = "./cache/ocr/cropforanki.png"
os.makedirs("./cache/ocr", exist_ok=True) os.makedirs("./cache/ocr", exist_ok=True)
img.save(fname) img.save(fname)
self.editpath.setText("")
self.editpath.setText(os.path.abspath(fname)) self.editpath.setText(os.path.abspath(fname))
self.asyncocr(fname) self.asyncocr(fname)
rangeselct_function(self, ocroncefunction, False, False) rangeselct_function(self, ocroncefunction, False, False)
def __init__(self, parent) -> None: def __init__(self) -> None:
super().__init__(parent, globalconfig, "ankiwindow") super().__init__()
self.setWindowTitle("Anki Connect") self.setWindowTitle("Anki Connect")
self.currentword = ""
self.tabs = QTabWidget() self.tabs = QTabWidget()
self.tabs.addTab(self.createaddtab(), _TR("添加")) self.tabs.addTab(self.createaddtab(), _TR("添加"))
tabadd_lazy(self.tabs, "设置", self.creatsetdtab) tabadd_lazy(self.tabs, "设置", self.creatsetdtab)
tabadd_lazy(self.tabs, "模板", self.creattemplatetab) tabadd_lazy(self.tabs, "模板", self.creattemplatetab)
self.setCentralWidget(self.tabs)
l = QHBoxLayout()
l.setContentsMargins(0, 0, 0, 0)
l.setSpacing(0)
l.addWidget(self.tabs)
self.setLayout(l)
self.refreshhtml.connect(self.refreshhtmlfunction) self.refreshhtml.connect(self.refreshhtmlfunction)
self.tabs.currentChanged.connect(self.ifshowrefresh) self.tabs.currentChanged.connect(self.ifshowrefresh)
@ -127,6 +135,7 @@ class AnkiWindow(closeashidewindow):
layout = QHBoxLayout() layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
wid = QWidget() wid = QWidget()
wid.setLayout(layout) wid.setLayout(layout)
@ -139,7 +148,6 @@ class AnkiWindow(closeashidewindow):
layout.addLayout( layout.addLayout(
getboxlayout( getboxlayout(
[ [
QLabel(_TR("编辑")),
edittemptab, edittemptab,
getboxlayout([revertbtn, savebtn], makewidget=True), getboxlayout([revertbtn, savebtn], makewidget=True),
], ],
@ -152,7 +160,7 @@ class AnkiWindow(closeashidewindow):
self.htmlbrowser.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.htmlbrowser.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
layout.addLayout( layout.addLayout(
getboxlayout( getboxlayout(
[QLabel(_TR("预览")), self.previewtab, self.htmlbrowser], [self.previewtab, self.htmlbrowser],
lc=QVBoxLayout, lc=QVBoxLayout,
margin0=True, margin0=True,
) )
@ -179,7 +187,7 @@ class AnkiWindow(closeashidewindow):
object.setPlainText(text) object.setPlainText(text)
def loadfileds(self): def loadfileds(self):
word = self.wordedit.text() word = self.currentword
explain = json.dumps(gobject.baseobject.searchwordW.generate_explains()) explain = json.dumps(gobject.baseobject.searchwordW.generate_explains())
remarks = self.remarks.toHtml() remarks = self.remarks.toHtml()
example = self.example.toPlainText() example = self.example.toPlainText()
@ -205,12 +213,24 @@ class AnkiWindow(closeashidewindow):
if len(self.audiopath.text()): if len(self.audiopath.text()):
with open(self.audiopath.text(), "rb") as image_file: with open(self.audiopath.text(), "rb") as image_file:
encoded_string2 = base64.b64encode(image_file.read()).decode("utf-8") encoded_string2 = base64.b64encode(image_file.read()).decode("utf-8")
encoded_string2 = '<audio controls><source src="data:audio/mpeg;base64,{}"></audio>'.format( encoded_string2 = """<button onclick='document.getElementById("audio1111").play()'>play audio<audio controls id="audio1111" style="display: none"><source src="data:audio/mpeg;base64,{}"></audio></button>""".format(
encoded_string2 encoded_string2
) )
else: else:
encoded_string2 = "" encoded_string2 = ""
fields = {"audio": encoded_string2, "image": encoded_string} if len(self.audiopath_sentence.text()):
with open(self.audiopath_sentence.text(), "rb") as image_file:
encoded_string3 = base64.b64encode(image_file.read()).decode("utf-8")
encoded_string3 = """<button onclick='document.getElementById("audio2222").play()'>play audio_sentence<audio controls id="audio2222" style="display: none"><source src="data:audio/mpeg;base64,{}"></audio></button>""".format(
encoded_string3
)
else:
encoded_string3 = ""
fields = {
"audio": encoded_string2,
"audio_sentence": encoded_string3,
"image": encoded_string,
}
return fields return fields
def saveedits(self): def saveedits(self):
@ -236,13 +256,17 @@ class AnkiWindow(closeashidewindow):
_TR("DeckName"), getlineedit(globalconfig["ankiconnect"], "DeckName") _TR("DeckName"), getlineedit(globalconfig["ankiconnect"], "DeckName")
) )
layout.addRow( layout.addRow(
_TR("ModelName"), getlineedit(globalconfig["ankiconnect"], "ModelName") _TR("ModelName"), getlineedit(globalconfig["ankiconnect"], "ModelName2")
) )
layout.addRow( layout.addRow(
_TR("allowDuplicate"), _TR("allowDuplicate"),
getsimpleswitch(globalconfig["ankiconnect"], "allowDuplicate"), getsimpleswitch(globalconfig["ankiconnect"], "allowDuplicate"),
) )
layout.addRow(
_TR("autoUpdateModel"),
getsimpleswitch(globalconfig["ankiconnect"], "autoUpdateModel"),
)
return wid return wid
@ -252,42 +276,94 @@ class AnkiWindow(closeashidewindow):
wid.setLayout(layout) wid.setLayout(layout)
soundbutton = QPushButton(qtawesome.icon("fa.music"), "") soundbutton = QPushButton(qtawesome.icon("fa.music"), "")
soundbutton.clicked.connect(self.langdu) soundbutton.clicked.connect(self.langdu)
soundbutton2 = QPushButton(qtawesome.icon("fa.music"), "")
soundbutton2.clicked.connect(self.langdu2)
cropbutton = QPushButton(qtawesome.icon("fa.crop"), "") cropbutton = QPushButton(qtawesome.icon("fa.crop"), "")
cropbutton.clicked.connect(self.crop) cropbutton.clicked.connect(self.crop)
self.wordedit = QLineEdit()
self.wordedit.textEdited.connect(self.reset) self.audiopath = QLineEdit()
layout.addLayout( self.audiopath.setReadOnly(True)
getboxlayout([QLabel(_TR("Word")), self.wordedit]) self.audiopath_sentence = QLineEdit()
) self.audiopath_sentence.setReadOnly(True)
self.editpath = QLineEdit()
self.editpath.setReadOnly(True)
self.viewimagelabel = QLabel()
self.editpath.textChanged.connect(self.wrappedpixmap)
self.example = QPlainTextEdit() self.example = QPlainTextEdit()
layout.addWidget(QLabel(_TR("例句")))
layout.addWidget(self.example)
self.remarks = QTextEdit() self.remarks = QTextEdit()
layout.addWidget(QLabel(_TR("备注"))) layout.addLayout(
layout.addWidget(self.remarks) getboxlayout(
[
getboxlayout(
[
getboxlayout(
[QLabel(_TR("例句")), self.example],
QVBoxLayout,
margin0=True,
),
getboxlayout(
[QLabel(_TR("备注")), self.remarks],
QVBoxLayout,
margin0=True,
),
],
QVBoxLayout,
),
getboxlayout(
[
getboxlayout(
[
QLabel(_TR("语音")),
self.audiopath,
soundbutton,
getcolorbutton(
"",
"",
functools.partial(self.selectaudio),
icon="fa.gear",
constcolor="#FF69B4",
),
]
),
getboxlayout(
[
QLabel(_TR("语音_例句")),
self.audiopath_sentence,
soundbutton2,
getcolorbutton(
"",
"",
functools.partial(self.selectaudio2),
icon="fa.gear",
constcolor="#FF69B4",
),
]
),
getboxlayout(
[
QLabel(_TR("截图")),
self.editpath,
cropbutton,
getcolorbutton(
"",
"",
functools.partial(self.selectimage),
icon="fa.gear",
constcolor="#FF69B4",
),
]
),
self.viewimagelabel,
],
QVBoxLayout,
),
]
)
)
self.tagsedit = QLineEdit() self.tagsedit = QLineEdit()
layout.addLayout(getboxlayout([QLabel(_TR("Tags(split by |)")), self.tagsedit])) layout.addLayout(getboxlayout([QLabel(_TR("Tags(split by |)")), self.tagsedit]))
self.audiopath = QLineEdit()
self.audiopath.setReadOnly(True)
layout.addLayout(getboxlayout([QLabel(_TR("语音")),self.audiopath,soundbutton,getcolorbutton(
"",
"",
functools.partial(self.selectaudio),
icon="fa.gear",
constcolor="#FF69B4",
)]))
self.editpath = QLineEdit()
self.editpath.setReadOnly(True)
layout.addLayout(getboxlayout([QLabel(_TR("截图")),self.editpath,cropbutton,getcolorbutton(
"",
"",
functools.partial(self.selectimage),
icon="fa.gear",
constcolor="#FF69B4",
)]))
btn = QPushButton(_TR("添加")) btn = QPushButton(_TR("添加"))
btn.clicked.connect(self.errorwrap) btn.clicked.connect(self.errorwrap)
layout.addWidget(btn) layout.addWidget(btn)
@ -298,24 +374,46 @@ class AnkiWindow(closeashidewindow):
self.reset("") self.reset("")
return wid return wid
def wrappedpixmap(self, src):
pix = QPixmap.fromImage(QImage(src))
rate = self.devicePixelRatioF()
pix.setDevicePixelRatio(rate)
if (
pix.width() > self.viewimagelabel.width()
or pix.height() > self.viewimagelabel.height()
):
pix = pix.scaled(self.viewimagelabel.size() * rate, Qt.KeepAspectRatio)
self.viewimagelabel.setPixmap(pix)
def selectimage(self): def selectimage(self):
f = QFileDialog.getOpenFileName() f = QFileDialog.getOpenFileName()
res = f[0] res = f[0]
if res != "": if res != "":
self.editpath.setText(res) self.editpath.setText(res)
def selectaudio(self): def selectaudio(self):
f = QFileDialog.getOpenFileName() f = QFileDialog.getOpenFileName()
res = f[0] res = f[0]
if res != "": if res != "":
self.audiopath.setText(res) self.audiopath.setText(res)
def selectaudio2(self):
f = QFileDialog.getOpenFileName()
res = f[0]
if res != "":
self.audiopath_sentence.setText(res)
def reset(self, text): def reset(self, text):
self.wordedit.setText(text) self.currentword = text
if text and len(text): if text and len(text):
self.ruby = json.dumps(gobject.baseobject.translation_ui.parsehira(text)) self.ruby = json.dumps(gobject.baseobject.translation_ui.parsehira(text))
else: else:
self.ruby = "" self.ruby = ""
self.editpath.clear() self.editpath.clear()
self.audiopath.clear() self.audiopath.clear()
self.audiopath_sentence.clear()
def errorwrap(self): def errorwrap(self):
try: try:
self.addanki() self.addanki()
@ -345,9 +443,10 @@ class AnkiWindow(closeashidewindow):
return model_htmlfront, model_htmlback, model_css return model_htmlfront, model_htmlback, model_css
def addanki(self): def addanki(self):
autoUpdateModel = globalconfig["ankiconnect"]["autoUpdateModel"]
allowDuplicate = globalconfig["ankiconnect"]["allowDuplicate"] allowDuplicate = globalconfig["ankiconnect"]["allowDuplicate"]
anki.global_port = globalconfig["ankiconnect"]["port"] anki.global_port = globalconfig["ankiconnect"]["port"]
ModelName = globalconfig["ankiconnect"]["ModelName"] ModelName = globalconfig["ankiconnect"]["ModelName2"]
DeckName = globalconfig["ankiconnect"]["DeckName"] DeckName = globalconfig["ankiconnect"]["DeckName"]
model_htmlfront, model_htmlback, model_css = self.tryloadankitemplates() model_htmlfront, model_htmlback, model_css = self.tryloadankitemplates()
try: try:
@ -370,19 +469,24 @@ class AnkiWindow(closeashidewindow):
], ],
) )
except anki.AnkiModelExists: except anki.AnkiModelExists:
model = anki.Model(ModelName) if autoUpdateModel:
model.updateStyling(model_css) model = anki.Model(ModelName)
model.updateTemplates( model.updateStyling(model_css)
{ model.updateTemplates(
"LUNACARDTEMPLATE1": { {
"Front": model_htmlfront, "LUNACARDTEMPLATE1": {
"Back": model_htmlback, "Front": model_htmlfront,
"Back": model_htmlback,
}
} }
} )
)
media = [] media = []
tempfiles = [] tempfiles = []
for k, _ in [("audio", self.audiopath.text()), ("image", self.editpath.text())]: for k, _ in [
("audio", self.audiopath.text()),
("audio_sentence", self.audiopath_sentence.text()),
("image", self.editpath.text()),
]:
if len(_): if len(_):
media.append( media.append(
[ [
@ -403,49 +507,47 @@ class AnkiWindow(closeashidewindow):
self.loadfileds(), self.loadfileds(),
allowDuplicate, allowDuplicate,
tags, tags,
media[0], media[0] + media[1],
media[1], media[2],
) )
class searchwordW(closeashidewindow): class searchwordW(closeashidewindow):
getnewsentencesignal = pyqtSignal(str, bool) getnewsentencesignal = pyqtSignal(str, bool)
searchthreadsignal = pyqtSignal(str, dict, str)
showtabsignal = pyqtSignal(str, str) showtabsignal = pyqtSignal(str, str)
def __init__(self, parent): def __init__(self, parent):
super(searchwordW, self).__init__(parent, globalconfig, "sw_geo") super(searchwordW, self).__init__(parent, globalconfig, "sw_geo")
self.ankiwindow = AnkiWindow(self) self.ankiwindow = AnkiWindow()
self.setupUi() self.setupUi()
# self.setWindowFlags(self.windowFlags()&~Qt.WindowMinimizeButtonHint) # self.setWindowFlags(self.windowFlags()&~Qt.WindowMinimizeButtonHint)
self.getnewsentencesignal.connect(self.getnewsentence) self.getnewsentencesignal.connect(self.getnewsentence)
self.setWindowTitle(_TR("查词")) self.setWindowTitle(_TR("查词"))
def showresfun(self, k, res): def showresfun(self, k, res):
first = res.split("<hr>")[0] self.cache_results[k] = res
self.textbs[k].insertHtml(first) thisp = globalconfig["cishu"][k]["args"]["priority"]
self.textbs[k].firsttext = self.textbs[k].toPlainText() idx = 0
self.textbs[k].insertHtml(res[len(first) :]) for kk in self.tabks:
if globalconfig["cishu"][kk]["args"]["priority"] >= thisp:
scrollbar = self.textbs[k].verticalScrollBar() idx += 1
scrollbar.setValue(0) self.tabks.insert(idx, k)
self.tab.setTabVisible(self._k.index(k), True) self.tab.insertTab(idx, _TR(globalconfig["cishu"][k]["name"]))
def setupUi(self): def setupUi(self):
self.setWindowIcon(qtawesome.icon("fa.search")) self.setWindowIcon(qtawesome.icon("fa.search"))
self.showtabsignal.connect(self.showresfun) self.showtabsignal.connect(self.showresfun)
self.centralWidget = QWidget(self) ww = QWidget(self)
self.setWindowIcon(qtawesome.icon("fa.gear")) self.setWindowIcon(qtawesome.icon("fa.gear"))
self.hboxlayout = QHBoxLayout(self.centralWidget)
self.vboxlayout = QVBoxLayout() self.vboxlayout = QVBoxLayout()
ww.setLayout(self.vboxlayout)
self.searchlayout = QHBoxLayout() self.searchlayout = QHBoxLayout()
self.vboxlayout.addLayout(self.searchlayout) self.vboxlayout.addLayout(self.searchlayout)
self.searchtext = QLineEdit() self.searchtext = QLineEdit()
# self.searchtext.setFont(font) self.searchtext.textChanged.connect(self.ankiwindow.reset)
self.searchlayout.addWidget(self.searchtext) self.searchlayout.addWidget(self.searchtext)
searchbutton = QPushButton(qtawesome.icon("fa.search"), "") # _TR("搜索")) searchbutton = QPushButton(qtawesome.icon("fa.search"), "") # _TR("搜索"))
@ -457,38 +559,41 @@ class searchwordW(closeashidewindow):
self.searchlayout.addWidget(soundbutton) self.searchlayout.addWidget(soundbutton)
ankiconnect = QPushButton(qtawesome.icon("fa.adn"), "") ankiconnect = QPushButton(qtawesome.icon("fa.adn"), "")
ankiconnect.clicked.connect(self.ankiwindow.show) ankiconnect.clicked.connect(self.onceaddankiwindow)
self.searchlayout.addWidget(ankiconnect) self.searchlayout.addWidget(ankiconnect)
self.tab = QTabWidget(self) self.tab = QTabBar(self)
self.tab.currentChanged.connect(
lambda idx: self.textOutput.setHtml(self.cache_results[self.tabks[idx]])
)
self.tabks = []
self.setCentralWidget(ww)
self.vboxlayout.addWidget(self.tab) textOutput = QTextBrowser(self)
self.hboxlayout.addLayout(self.vboxlayout) textOutput.setUndoRedoEnabled(False)
self.setCentralWidget(self.centralWidget) textOutput.setReadOnly(True)
textOutput.setOpenLinks(False)
self.textbs = {} self.textOutput = textOutput
self.cache_results = {}
_k = []
_name = []
for cishu in globalconfig["cishu"]:
_name.append(globalconfig["cishu"][cishu]["name"])
_k.append(cishu)
self._k = _k
_name = _TRL(_name)
for i in range(len(_name)):
textOutput = QTextBrowser(self)
# textOutput.setFont(font)
textOutput.setUndoRedoEnabled(False)
textOutput.setReadOnly(True)
textOutput.setOpenLinks(False)
self.tab.addTab(textOutput, _name[i])
self.tab.setTabVisible(i, False)
self.textbs[self._k[i]] = textOutput
self.hiding = True self.hiding = True
self.searchthreadsignal.connect(self.searchthread) self.addankiwindowidx = 0
tablayout = QVBoxLayout()
tablayout.addWidget(self.tab)
tablayout.addWidget(textOutput)
tablayout.setContentsMargins(0, 0, 0, 0)
tablayout.setSpacing(0)
self.vboxlayout.addLayout(tablayout)
def onceaddankiwindow(self):
if self.addankiwindowidx == 0:
self.vboxlayout.addWidget(self.ankiwindow)
else:
if self.addankiwindowidx % 2 == 0:
self.ankiwindow.show()
else:
self.ankiwindow.hide()
self.addankiwindowidx += 1
def langdu(self): def langdu(self):
if gobject.baseobject.reader: if gobject.baseobject.reader:
@ -496,13 +601,18 @@ class searchwordW(closeashidewindow):
def generate_explains(self): def generate_explains(self):
res = [] res = []
for i in range(len(self._k)): tabks = []
if len(self.textbs[self._k[i]].toPlainText()) == 0: for k, v in self.cache_results.items():
if len(v) == 0:
continue continue
thisp = globalconfig["cishu"][k]["args"]["priority"]
res.append( idx = 0
{"source": self._k[i], "content": self.textbs[self._k[i]].toHtml()} for i in tabks:
) if i >= thisp:
idx += 1
k = _TR(globalconfig["cishu"][k]["name"])
tabks.append(thisp)
res.insert(idx, {"source": k, "content": v})
return res return res
def getnewsentence(self, sentence, append): def getnewsentence(self, sentence, append):
@ -513,22 +623,14 @@ class searchwordW(closeashidewindow):
self.search(sentence) self.search(sentence)
def searchthread(self, k, _mp, sentence):
_mp[k].callback = functools.partial(self.showtabsignal.emit, k)
_mp[k].search(sentence)
def search(self, sentence): def search(self, sentence):
if sentence == "": if sentence == "":
return return
self.ankiwindow.setcurrenttext.emit(sentence) self.ankiwindow.setcurrenttext.emit(sentence)
_mp = {} for i in range(self.tab.count()):
_mp.update(gobject.baseobject.cishus) self.tab.removeTab(0)
self.tabks.clear()
for k in self._k: self.cache_results.clear()
self.tab.setTabVisible(self._k.index(k), False) for k, cishu in gobject.baseobject.cishus.items():
self.textbs[k].clear() cishu.callback = functools.partial(self.showtabsignal.emit, k)
if k in _mp: cishu.safesearch(sentence)
threading.Thread(
target=self.searchthreadsignal.emit, args=(k, _mp, sentence)
).start()

View File

@ -2,13 +2,12 @@ import time
import functools import functools
import threading import threading
import os, sys import os, sys
from PyQt5.QtCore import QT_VERSION_STR
import windows, importlib import windows, importlib
from traceback import print_exc from traceback import print_exc
from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtCore import Qt, pyqtSignal
import qtawesome import qtawesome
from PyQt5.QtCore import pyqtSignal, Qt, QSize from PyQt5.QtCore import pyqtSignal, Qt, QSize
from PyQt5.QtGui import QCursor, QColor from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QLabel, QPushButton, QSystemTrayIcon from PyQt5.QtWidgets import QLabel, QPushButton, QSystemTrayIcon
import gobject import gobject
from myutils.wrapper import threader, trypass from myutils.wrapper import threader, trypass
@ -152,25 +151,8 @@ class QUnFrameWindow(resizableframeless):
hira = [] hira = []
try: try:
if gobject.baseobject.hira_: if gobject.baseobject.hira_:
hira = gobject.baseobject.hira_.fy(text) hira = gobject.baseobject.hira_.parseparse(text)
for _1 in range(len(hira)):
_ = len(hira) - 1 - _1
if globalconfig["hira_vis_type"] == 0:
hira[_]["hira"] = hira[_]["hira"].translate(self.castkata2hira)
elif globalconfig["hira_vis_type"] == 1:
hira[_]["hira"] = hira[_]["hira"].translate(self.casthira2kata)
elif globalconfig["hira_vis_type"] == 2:
__kanas = [
static_data["hira"] + [""],
static_data["kata"] + [""],
]
target = static_data["roma"] + ["-"]
for _ka in __kanas:
for __idx in range(len(_ka)):
_reverse_idx = len(_ka) - 1 - __idx
hira[_]["hira"] = hira[_]["hira"].replace(
_ka[_reverse_idx], target[_reverse_idx]
)
except: except:
print_exc() print_exc()
return hira return hira
@ -624,8 +606,7 @@ class QUnFrameWindow(resizableframeless):
self.tray.setIcon(icon) self.tray.setIcon(icon)
showintab(int(self.winId()), globalconfig["showintab"]) showintab(int(self.winId()), globalconfig["showintab"])
self.isfirstshow = True self.isfirstshow = True
if QT_VERSION_STR != "5.5.1": self.setAttribute(Qt.WA_TranslucentBackground)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setAttribute(Qt.WA_ShowWithoutActivating, True) self.setAttribute(Qt.WA_ShowWithoutActivating, True)
self.showintab = globalconfig["showintab"] self.showintab = globalconfig["showintab"]
self.setWindowTitle("LunaTranslator") self.setWindowTitle("LunaTranslator")
@ -655,12 +636,6 @@ class QUnFrameWindow(resizableframeless):
self.quitf_signal.connect(self.close) self.quitf_signal.connect(self.close)
self.fullsgame_signal.connect(self._fullsgame) self.fullsgame_signal.connect(self._fullsgame)
self.castkata2hira = str.maketrans(
static_data["allkata"], static_data["allhira"]
)
self.casthira2kata = str.maketrans(
static_data["allhira"], static_data["allkata"]
)
self.fullscreenmanager_busy = False self.fullscreenmanager_busy = False
self.isletgamefullscreened = False self.isletgamefullscreened = False
self.fullscreenmanager = None self.fullscreenmanager = None

View File

@ -9,6 +9,7 @@ from PyQt5.QtWidgets import (
QSizePolicy, QSizePolicy,
QHBoxLayout, QHBoxLayout,
QWidget, QWidget,
QLayout,
) )
from webviewpy import ( from webviewpy import (
@ -507,7 +508,10 @@ def selectcolor(
def getboxlayout(widgets, lc=QHBoxLayout, margin0=False, makewidget=False): def getboxlayout(widgets, lc=QHBoxLayout, margin0=False, makewidget=False):
cp_layout = lc() cp_layout = lc()
for w in widgets: for w in widgets:
cp_layout.addWidget(w) if isinstance(w, QWidget):
cp_layout.addWidget(w)
elif isinstance(w, QLayout):
cp_layout.addLayout(w)
if margin0: if margin0:
cp_layout.setContentsMargins(0, 0, 0, 0) cp_layout.setContentsMargins(0, 0, 0, 0)
if makewidget: if makewidget:

View File

@ -0,0 +1,59 @@
from myutils.config import globalconfig, static_data
from traceback import print_exc
class basehira:
def init(self):
pass
def parse(self, text):
return []
def __init__(self, typename) -> None:
self.typename = typename
self.castkata2hira = str.maketrans(
static_data["allkata"], static_data["allhira"]
)
self.casthira2kata = str.maketrans(
static_data["allhira"], static_data["allkata"]
)
self.needinit = True
self.init()
self.needinit = False
@property
def config(self):
return globalconfig["hirasetting"][self.typename]["args"]
def parseparse(self, text):
hira = []
try:
if self.needinit:
self.init()
self.needinit = False
try:
hira = self.parse(text)
except Exception as e:
self.needinit = True
raise e
for _1 in range(len(hira)):
_ = len(hira) - 1 - _1
if globalconfig["hira_vis_type"] == 0:
hira[_]["hira"] = hira[_]["hira"].translate(self.castkata2hira)
elif globalconfig["hira_vis_type"] == 1:
hira[_]["hira"] = hira[_]["hira"].translate(self.casthira2kata)
elif globalconfig["hira_vis_type"] == 2:
__kanas = [
static_data["hira"] + [""],
static_data["kata"] + [""],
]
target = static_data["roma"] + ["-"]
for _ka in __kanas:
for __idx in range(len(_ka)):
_reverse_idx = len(_ka) - 1 - __idx
hira[_]["hira"] = hira[_]["hira"].replace(
_ka[_reverse_idx], target[_reverse_idx]
)
except:
print_exc()
return hira

View File

@ -1,8 +1,9 @@
class hira: from hiraparse.basehira import basehira
def __init__(self) -> None:
pass
def fy(self, text):
class latin(basehira):
def parse(self, text):
_x = [] _x = []
i = 0 i = 0
for _ in text.split(" "): for _ in text.split(" "):

View File

@ -1,22 +1,21 @@
from myutils.config import globalconfig
import winsharedutils import winsharedutils
import os import os
from hiraparse.basehira import basehira
class hira:
def __init__(self) -> None:
hirasettingbase = globalconfig["hirasetting"]
mecabpath = hirasettingbase["mecab"]["path"] class mecab(basehira):
def init(self) -> None:
mecabpath = self.config["path"]
if os.path.exists(mecabpath): if os.path.exists(mecabpath):
self.kks = winsharedutils.mecabwrap( self.kks = winsharedutils.mecabwrap(
mecabpath mecabpath
) # fugashi.Tagger('-r nul -d "{}" -Owakati'.format(mecabpath)) ) # fugashi.Tagger('-r nul -d "{}" -Owakati'.format(mecabpath))
def fy(self, text): def parse(self, text):
start = 0 start = 0
result = [] result = []
codec = ["utf8", "shiftjis"][globalconfig["hirasetting"]["mecab"]["codec"]] codec = ["utf8", "shiftjis"][self.config["codec"]]
for node, fields in self.kks.parse( for node, fields in self.kks.parse(
text, codec text, codec
): # self.kks.parseToNodeList(text): ): # self.kks.parseToNodeList(text):
@ -49,7 +48,6 @@ class hira:
if origorig is None: if origorig is None:
origorig = orig origorig = orig
start += l start += l
hira = kana # .translate(self.h2k) hira = kana # .translate(self.h2k)

View File

@ -1,14 +1,10 @@
from myutils.config import globalconfig
from myutils.proxy import getproxy from myutils.proxy import getproxy
import requests import requests
from hiraparse.basehira import basehira
class hira: class mojinlt(basehira):
def __init__(self) -> None: def parse(self, text):
pass
def fy(self, text):
def nlt(text, token): def nlt(text, token):
try: try:
@ -37,4 +33,4 @@ class hira:
except: except:
return [] return []
return nlt(text, globalconfig["hirasetting"]["mojinlt"]["token"]) return nlt(text, self.config["Moji NLT Token"])

View File

@ -460,10 +460,14 @@ class texthook(basetext):
return True return True
def serialkey(self, key):
hc, hn, tp = key
return (tp.processId, tp.addr, tp.ctx, tp.ctx2, hn, hc)
def serialselectedhook(self): def serialselectedhook(self):
xx = [] xx = []
for hc, hn, tp in self.selectedhook: for key in self.selectedhook:
xx.append((tp.processId, tp.addr, tp.ctx, tp.ctx2, hn, hc)) xx.append(self.serialkey(key))
return xx return xx
def checkisusingembed(self, address, ctx1, ctx2): def checkisusingembed(self, address, ctx1, ctx2):

View File

@ -1,5 +1,4 @@
from translator.basetranslator_dev import basetransdev from translator.basetranslator_dev import basetransdev
from urllib.parse import quote
class TS(basetransdev): class TS(basetransdev):
@ -18,15 +17,12 @@ class TS(basetransdev):
def translate(self, content): def translate(self, content):
self.Runtime_evaluate( self.Runtime_evaluate(
"document.getElementsByClassName('textarea-clear-btn')[0].click()" """document.querySelector("#editor-text > div.AZLVLJHb > div.Ssl84aLh > span").click()"""
) )
self.Runtime_evaluate(
self.Page_navigate( """document.querySelector("#editor-text > div.AZLVLJHb > div.Ssl84aLh > div > div > div").click()"""
"https://fanyi.baidu.com/#{}/{}/{}".format( )
self.srclang, self.tgtlang, quote(content) self.send_keys(content)
) return self.wait_for_result(
"""document.querySelector("#trans-selection").innerText"""
) )
res = self.wait_for_result(
"document.querySelector('div.output-bd')===null?'':document.querySelector('div.output-bd').innerText"
).replace("\n\n", "\n")
return res

View File

@ -40,28 +40,21 @@ class basetransdev(basetrans):
if self.using == False: if self.using == False:
return return
self._id += 1 self._id += 1
try:
if ws is None: if ws is None:
ws = self.ws ws = self.ws
ws.send(json.dumps({"id": self._id, "method": method, "params": params})) ws.send(json.dumps({"id": self._id, "method": method, "params": params}))
res = ws.recv() res = ws.recv()
except:
print_exc()
self._createtarget()
time.sleep(1)
return self._SendRequest(method, params, ws)
res = json.loads(res) res = json.loads(res)
try: try:
return res["result"] return res["result"]
except: except:
print(res) if res['error']['code']==-32600:
if ( self._id+=1
res["method"] == "Inspector.detached" self._SendRequest(method,params,ws)
and res["params"]["reason"] == "target_closed" else:
): raise
self._createtarget()
return self._SendRequest(method, params, ws)
def _createtarget(self): def _createtarget(self):
if self.using == False: if self.using == False:
return return

View File

@ -1,28 +0,0 @@
from translator.basetranslator_dev import basetransdev
class TS(basetransdev):
target_url = "https://fanyi.baidu.com/mtpe-individual/multimodal#/"
def langmap(self):
return {
"es": "spa",
"ko": "kor",
"fr": "fra",
"ja": "jp",
"cht": "cht",
"vi": "vie",
"uk": "ukr",
}
def translate(self, content):
self.Runtime_evaluate(
"""document.querySelector("#editor-text > div.AZLVLJHb > div.Ssl84aLh > span").click()"""
)
self.Runtime_evaluate(
"""document.querySelector("#editor-text > div.AZLVLJHb > div.Ssl84aLh > div > div > div").click()"""
)
self.send_keys(content)
return self.wait_for_result(
"""document.querySelector("#trans-selection").innerText"""
)

View File

@ -1,6 +1,9 @@
<div class="hide-style">{{audio}}</div> <div class="hide-style">
<div id="audio">{{audio}}</div>
<div id="audio_sentence">{{audio_sentence}}</div>
</div>
<div class="centerdiv"> <div class="centerdiv">
<div id="rubyword" class="ruby-div"></div> <div id="rubyword" class="ruby-div" onclick='playAudio("audio")'></div>
</div> </div>
<script> <script>
@ -13,17 +16,13 @@
</script> </script>
<div id="example_sentence" class="centerdiv example-div"> <div id="example_sentence" class="centerdiv example-div" onclick='playAudio("audio_sentence")'>
{{example_sentence}} {{example_sentence}}
</div> </div>
<div id="image" class="centerdiv"> <div id="image" class="centerdiv">
{{image}} {{image}}
</div> </div>
<div id="remarks" class="centerdiv remark-div">
{{remarks}}
</div>
<div class="tab-widget"> <div class="tab-widget">
<div class="centerdiv"> <div class="centerdiv">
<div class="tab-buttons" id="tab_buttons"> <div class="tab-buttons" id="tab_buttons">
@ -46,11 +45,22 @@
<script> <script>
explains = {{ explain }} explains = {{ explain }}
function safehtml(html) {
var tempParent = document.createElement('div');
tempParent.innerHTML = html;
var fragment = document.createElement('div');
while (tempParent.firstChild) {
fragment.appendChild(tempParent.firstChild);
}
return fragment.innerHTML
}
htmltabbuttons = '' htmltabbuttons = ''
htmlcontents = '' htmlcontents = ''
for (i = 0; i < explains.length; i++) { for (i = 0; i < explains.length; i++) {
htmltabbuttons += '<button type="button" class="tab-button" data-tab="tab' + (i + 0).toString() + '">' + explains[i]['source'] + '</button>' htmltabbuttons += '<button type="button" class="tab-button" data-tab="tab' + (i + 0).toString() + '">' + explains[i]['source'] + '</button>'
htmlcontents += '<div id="tab' + (i + 0).toString() + '" class="tab-pane">' + explains[i]['content'] + '</div>' htmlcontents += '<div id="tab' + (i + 0).toString() + '" class="tab-pane">' + safehtml(explains[i]['content']) + '</div>'
} }
document.getElementById('tab_buttons').innerHTML = htmltabbuttons document.getElementById('tab_buttons').innerHTML = htmltabbuttons
document.getElementById('tab_contents').innerHTML = htmlcontents document.getElementById('tab_contents').innerHTML = htmlcontents
@ -78,6 +88,13 @@
</script> </script>
<script> <script>
function playAudio(audioId) {
var audioDiv = document.getElementById(audioId);
var audio = audioDiv.getElementsByTagName('*');
if (audio.length > 0) {
audio[0].click();
}
}
function checkhide(eid) { function checkhide(eid) {
var emptyDiv = document.getElementById(eid); var emptyDiv = document.getElementById(eid);
if (emptyDiv && emptyDiv.innerText.trim() === "") { if (emptyDiv && emptyDiv.innerText.trim() === "") {

View File

@ -1,6 +1,9 @@
<div class="hide-style">{{audio}}</div> <div class="hide-style">
<div id="audio">{{audio}}</div>
<div id="audio_sentence">{{audio_sentence}}</div>
</div>
<div class="centerdiv"> <div class="centerdiv">
<div id="rubyword" class="ruby-div"></div> <div id="rubyword" class="ruby-div" onclick='playAudio("audio")'></div>
</div> </div>
<script> <script>
@ -13,7 +16,7 @@
</script> </script>
<div id="example_sentence" class="centerdiv example-div"> <div id="example_sentence" class="centerdiv example-div" onclick='playAudio("audio_sentence")'>
{{example_sentence}} {{example_sentence}}
</div> </div>
<div id="image" class="centerdiv"> <div id="image" class="centerdiv">
@ -22,6 +25,13 @@
<script> <script>
function playAudio(audioId) {
var audioDiv = document.getElementById(audioId);
var audio = audioDiv.getElementsByTagName('*');
if (audio.length > 0) {
audio[0].click();
}
}
function checkhide(eid) { function checkhide(eid) {
var emptyDiv = document.getElementById(eid); var emptyDiv = document.getElementById(eid);
if (emptyDiv && emptyDiv.innerText.trim() === "") { if (emptyDiv && emptyDiv.innerText.trim() === "") {

View File

@ -179,9 +179,9 @@
"ankiconnect": { "ankiconnect": {
"port": 8765, "port": 8765,
"DeckName": "lunadeck", "DeckName": "lunadeck",
"ModelName": "lunamodel", "ModelName2": "lunamodel2",
"allowDuplicate":true "allowDuplicate": true,
"autoUpdateModel": true
}, },
"ankiwindow": [ "ankiwindow": [
100, 100,
@ -678,15 +678,31 @@
"hirasetting": { "hirasetting": {
"mecab": { "mecab": {
"use": false, "use": false,
"path": "",
"name": "MeCab", "name": "MeCab",
"codec": 0 "args": {
"path": "",
"codec": 0
},
"argstype": {
"path": {
"type": "file",
"dir": true
},
"codec": {
"type": "combo",
"list": [
"utf8",
"shiftjis"
]
}
}
}, },
"mojinlt": { "mojinlt": {
"use": false, "use": false,
"token": "", "name": "mojinlt",
"token_name": "Moji NLT Token", "args": {
"name": "mojinlt" "Moji NLT Token": ""
}
}, },
"latin": { "latin": {
"use": false, "use": false,
@ -695,48 +711,146 @@
}, },
"cishu": { "cishu": {
"xiaoxueguan": { "xiaoxueguan": {
"args": {
"path": "",
"priority": 100
},
"argstype": {
"path": {
"type": "file",
"dir": false,
"filter": "*.db"
},
"priority": {
"type": "intspin",
"min": 0,
"max": 10000,
"step": 1
}
},
"use": false, "use": false,
"path": "", "name": "小学馆"
"name": "小学馆",
"filter": "*.db",
"isdir": false
}, },
"edict": { "edict": {
"use": false, "use": false,
"path": "",
"name": "EDICT", "name": "EDICT",
"filter": "*.db", "args": {
"isdir": false "path": "",
"priority": 100
},
"argstype": {
"path": {
"type": "file",
"dir": false,
"filter": "*.db"
},
"priority": {
"type": "intspin",
"min": 0,
"max": 10000,
"step": 1
}
}
}, },
"edict2": { "edict2": {
"use": false, "use": false,
"path": "",
"name": "EDICT2", "name": "EDICT2",
"filter": "", "args": {
"isdir": false "path": "",
"priority": 100
},
"argstype": {
"path": {
"type": "file",
"dir": false
},
"priority": {
"type": "intspin",
"min": 0,
"max": 10000,
"step": 1
}
}
}, },
"linggesi": { "linggesi": {
"use": false, "use": false,
"path": "",
"name": "灵格斯词典", "name": "灵格斯词典",
"filter": "", "args": {
"isdir": true "path": "",
"priority": 100
},
"argstype": {
"path": {
"type": "file",
"dir": true
},
"priority": {
"type": "intspin",
"min": 0,
"max": 10000,
"step": 1
}
}
}, },
"mojidict": { "mojidict": {
"use": false, "use": false,
"name": "Moji辞书" "name": "Moji辞书",
"args": {
"priority": 100
},
"argstype": {
"priority": {
"type": "intspin",
"min": 0,
"max": 10000,
"step": 1
}
}
}, },
"youdao": { "youdao": {
"use": false, "use": false,
"name": "youdao" "name": "有道",
"args": {
"priority": 100
},
"argstype": {
"priority": {
"type": "intspin",
"min": 0,
"max": 10000,
"step": 1
}
}
}, },
"weblio": { "weblio": {
"use": false, "use": false,
"name": "weblio" "name": "weblio",
"args": {
"priority": 100
},
"argstype": {
"priority": {
"type": "intspin",
"min": 0,
"max": 10000,
"step": 1
}
}
}, },
"goo": { "goo": {
"use": false, "use": false,
"name": "goo" "name": "goo",
"args": {
"priority": 100
},
"argstype": {
"priority": {
"type": "intspin",
"min": 0,
"max": 10000,
"step": 1
}
}
} }
}, },
"darklight": 0, "darklight": 0,
@ -951,12 +1065,6 @@
"type": "dev", "type": "dev",
"name": "百度" "name": "百度"
}, },
"dev_baidu_ai": {
"use": false,
"color": "blue",
"type": "dev",
"name": "百度_ai"
},
"google_dev": { "google_dev": {
"use": false, "use": false,
"color": "blue", "color": "blue",

View File

@ -1625,6 +1625,7 @@
"explain", "explain",
"image", "image",
"audio", "audio",
"audio_sentence",
"example_sentence", "example_sentence",
"rubytext", "rubytext",
"remarks" "remarks"

View File

@ -777,12 +777,10 @@
"合并": "دمج", "合并": "دمج",
"立即应用": "التطبيق الفوري", "立即应用": "التطبيق الفوري",
"无法连接到anki": "غير قادر على الاتصال انكي", "无法连接到anki": "غير قادر على الاتصال انكي",
"追加": "إلحاق",
"例句": "على سبيل المثال", "例句": "على سبيل المثال",
"正面": "أمامي", "正面": "أمامي",
"背面": "ظهر", "背面": "ظهر",
"样式": "نمط", "样式": "نمط",
"预览": "معاينة",
"恢复": "استعاد", "恢复": "استعاد",
"模板": "قالب .", "模板": "قالب .",
"截图": "لقطة" "截图": "لقطة"

View File

@ -777,12 +777,10 @@
"合并": "合併", "合并": "合併",
"立即应用": "立即應用", "立即应用": "立即應用",
"无法连接到anki": "無法連接到anki", "无法连接到anki": "無法連接到anki",
"追加": "追加",
"例句": "例句", "例句": "例句",
"正面": "正面", "正面": "正面",
"背面": "背面", "背面": "背面",
"样式": "樣式", "样式": "樣式",
"预览": "預覽",
"恢复": "恢復", "恢复": "恢復",
"模板": "範本", "模板": "範本",
"截图": "截圖" "截图": "截圖"

View File

@ -777,12 +777,10 @@
"合并": "merge", "合并": "merge",
"立即应用": "apply now", "立即应用": "apply now",
"无法连接到anki": "Unable to connect to Anki", "无法连接到anki": "Unable to connect to Anki",
"追加": "Add",
"例句": "Example sentence", "例句": "Example sentence",
"正面": "front", "正面": "front",
"背面": "Back", "背面": "Back",
"样式": "style", "样式": "style",
"预览": "preview",
"恢复": "recovery", "恢复": "recovery",
"模板": "Template", "模板": "Template",
"截图": "screenshot" "截图": "screenshot"

View File

@ -777,12 +777,10 @@
"合并": "Fusión", "合并": "Fusión",
"立即应用": "Aplicar de inmediato", "立即应用": "Aplicar de inmediato",
"无法连接到anki": "No se puede conectar a Anki", "无法连接到anki": "No se puede conectar a Anki",
"追加": "Añadido",
"例句": "Ejemplo", "例句": "Ejemplo",
"正面": "Frontal", "正面": "Frontal",
"背面": "Parte posterior", "背面": "Parte posterior",
"样式": "Estilo", "样式": "Estilo",
"预览": "Vista previa",
"恢复": "Recuperación", "恢复": "Recuperación",
"模板": "Plantilla", "模板": "Plantilla",
"截图": "Captura de pantalla" "截图": "Captura de pantalla"

View File

@ -777,12 +777,10 @@
"合并": "Consolidation", "合并": "Consolidation",
"立即应用": "Appliquer maintenant", "立即应用": "Appliquer maintenant",
"无法连接到anki": "Impossible de se connecter à Anki", "无法连接到anki": "Impossible de se connecter à Anki",
"追加": "Supplémentaire",
"例句": "Phrases d'exemple", "例句": "Phrases d'exemple",
"正面": "Le Front", "正面": "Le Front",
"背面": "Arrière", "背面": "Arrière",
"样式": "Style", "样式": "Style",
"预览": "Preview",
"恢复": "Récupération", "恢复": "Récupération",
"模板": "Modèle", "模板": "Modèle",
"截图": "Capture d'écran" "截图": "Capture d'écran"

View File

@ -777,12 +777,10 @@
"合并": "fusione", "合并": "fusione",
"立即应用": "Applica ora", "立即应用": "Applica ora",
"无法连接到anki": "Impossibile connettersi ad Anki", "无法连接到anki": "Impossibile connettersi ad Anki",
"追加": "Aggiungi",
"例句": "Esempio di frase", "例句": "Esempio di frase",
"正面": "anteriore", "正面": "anteriore",
"背面": "Indietro", "背面": "Indietro",
"样式": "stile", "样式": "stile",
"预览": "anteprima",
"恢复": "recupero", "恢复": "recupero",
"模板": "Modello", "模板": "Modello",
"截图": "screenshot" "截图": "screenshot"

View File

@ -777,12 +777,10 @@
"合并": "マージ", "合并": "マージ",
"立即应用": "今すぐ適用", "立即应用": "今すぐ適用",
"无法连接到anki": "ankiに接続できません", "无法连接到anki": "ankiに接続できません",
"追加": "追加#ツイカ#",
"例句": "例文", "例句": "例文",
"正面": "前面", "正面": "前面",
"背面": "背面", "背面": "背面",
"样式": "スタイル", "样式": "スタイル",
"预览": "プレビュー",
"恢复": "リカバリ", "恢复": "リカバリ",
"模板": "テンプレート", "模板": "テンプレート",
"截图": "スクリーンショット" "截图": "スクリーンショット"

View File

@ -777,12 +777,10 @@
"合并": "병합", "合并": "병합",
"立即应用": "지금 적용", "立即应用": "지금 적용",
"无法连接到anki": "anki에 연결할 수 없음", "无法连接到anki": "anki에 연결할 수 없음",
"追加": "추가",
"例句": "예문", "例句": "예문",
"正面": "정면", "正面": "정면",
"背面": "뒷면", "背面": "뒷면",
"样式": "스타일", "样式": "스타일",
"预览": "미리 보기",
"恢复": "복구", "恢复": "복구",
"模板": "템플릿", "模板": "템플릿",
"截图": "캡처" "截图": "캡처"

View File

@ -777,12 +777,10 @@
"合并": "połączenie", "合并": "połączenie",
"立即应用": "aplikuj teraz", "立即应用": "aplikuj teraz",
"无法连接到anki": "Nie można połączyć się z Anki", "无法连接到anki": "Nie można połączyć się z Anki",
"追加": "Dodaj",
"例句": "Zdanie przykładowe", "例句": "Zdanie przykładowe",
"正面": "z przodu", "正面": "z przodu",
"背面": "Z powrotem", "背面": "Z powrotem",
"样式": "styl", "样式": "styl",
"预览": "podgląd",
"恢复": "odzyskiwanie", "恢复": "odzyskiwanie",
"模板": "Szablon", "模板": "Szablon",
"截图": "zrzut ekranu" "截图": "zrzut ekranu"

View File

@ -777,12 +777,10 @@
"合并": "Объединение", "合并": "Объединение",
"立即应用": "Немедленное применение", "立即应用": "Немедленное применение",
"无法连接到anki": "Не удалось подключиться к ANKI", "无法连接到anki": "Не удалось подключиться к ANKI",
"追加": "Добавить",
"例句": "Примеры", "例句": "Примеры",
"正面": "Положительный", "正面": "Положительный",
"背面": "Задняя сторона", "背面": "Задняя сторона",
"样式": "Стиль", "样式": "Стиль",
"预览": "Предварительный просмотр",
"恢复": "Восстановление", "恢复": "Восстановление",
"模板": "Шаблоны:", "模板": "Шаблоны:",
"截图": "Снимок экрана" "截图": "Снимок экрана"

View File

@ -777,12 +777,10 @@
"合并": "การควบรวมกิจการ", "合并": "การควบรวมกิจการ",
"立即应用": "สมัครตอนนี้", "立即应用": "สมัครตอนนี้",
"无法连接到anki": "ไม่สามารถเชื่อมต่อกับ anki ได้", "无法连接到anki": "ไม่สามารถเชื่อมต่อกับ anki ได้",
"追加": "เพิ่ม",
"例句": "ตัวอย่างประโยค", "例句": "ตัวอย่างประโยค",
"正面": "ด้านหน้า", "正面": "ด้านหน้า",
"背面": "ด้านหลัง", "背面": "ด้านหลัง",
"样式": "สไตล์", "样式": "สไตล์",
"预览": "แสดงตัวอย่าง",
"恢复": "การกู้คืน", "恢复": "การกู้คืน",
"模板": "เทมเพลต", "模板": "เทมเพลต",
"截图": "ภาพหน้าจอ" "截图": "ภาพหน้าจอ"

View File

@ -777,12 +777,10 @@
"合并": "birleştir", "合并": "birleştir",
"立即应用": "şimdi uygulayın", "立即应用": "şimdi uygulayın",
"无法连接到anki": "Anki ile bağlanılamadı", "无法连接到anki": "Anki ile bağlanılamadı",
"追加": "Ekle",
"例句": "Örnek cümle", "例句": "Örnek cümle",
"正面": "ön", "正面": "ön",
"背面": "Geri", "背面": "Geri",
"样式": "stil", "样式": "stil",
"预览": "önizleme",
"恢复": "iyileştirme", "恢复": "iyileştirme",
"模板": "Şablon", "模板": "Şablon",
"截图": "ekran fotoğrafı" "截图": "ekran fotoğrafı"

View File

@ -777,12 +777,10 @@
"合并": "об єднати", "合并": "об єднати",
"立即应用": "застосовувати зараз", "立即应用": "застосовувати зараз",
"无法连接到anki": "Неможливо з' єднатися з Anki", "无法连接到anki": "Неможливо з' єднатися з Anki",
"追加": "Додати",
"例句": "Приклад речення", "例句": "Приклад речення",
"正面": "передній", "正面": "передній",
"背面": "Назад", "背面": "Назад",
"样式": "стиль", "样式": "стиль",
"预览": "перегляд",
"恢复": "відновлення", "恢复": "відновлення",
"模板": "Шаблон", "模板": "Шаблон",
"截图": "знімок екрана" "截图": "знімок екрана"

View File

@ -777,12 +777,10 @@
"合并": "Hợp nhất", "合并": "Hợp nhất",
"立即应用": "Áp dụng ngay", "立即应用": "Áp dụng ngay",
"无法连接到anki": "Không thể kết nối với Anki", "无法连接到anki": "Không thể kết nối với Anki",
"追加": "Thêm",
"例句": "Câu ví dụ", "例句": "Câu ví dụ",
"正面": "Mặt trước", "正面": "Mặt trước",
"背面": "Mặt sau", "背面": "Mặt sau",
"样式": "Kiểu dáng", "样式": "Kiểu dáng",
"预览": "Xem thử",
"恢复": "Phục hồi", "恢复": "Phục hồi",
"模板": "Mẫu", "模板": "Mẫu",
"截图": "Ảnh chụp màn hình" "截图": "Ảnh chụp màn hình"

View File

@ -776,13 +776,11 @@
"圆角": "", "圆角": "",
"合并": "", "合并": "",
"立即应用": "", "立即应用": "",
"追加": "",
"无法连接到anki": "", "无法连接到anki": "",
"例句": "", "例句": "",
"正面": "", "正面": "",
"背面": "", "背面": "",
"样式": "", "样式": "",
"预览": "",
"恢复": "", "恢复": "",
"模板": "", "模板": "",
"截图": "" "截图": ""

View File

@ -28,8 +28,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
include(generate_product_version) include(generate_product_version)
set(VERSION_MAJOR 2) set(VERSION_MAJOR 2)
set(VERSION_MINOR 50) set(VERSION_MINOR 51)
set(VERSION_PATCH 4) set(VERSION_PATCH 0)
add_library(pch pch.cpp) add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h) target_precompile_headers(pch PUBLIC pch.h)