mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-29 16:44:13 +08:00
update
This commit is contained in:
parent
20e7106d60
commit
a001ba38c7
@ -415,7 +415,7 @@ class MAINUI:
|
|||||||
text, savehook_new_data[self.textsource.pname]
|
text, savehook_new_data[self.textsource.pname]
|
||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
print_exc()
|
pass
|
||||||
self.reader.read(text, force)
|
self.reader.read(text, force)
|
||||||
except:
|
except:
|
||||||
print_exc()
|
print_exc()
|
||||||
|
@ -5,16 +5,146 @@ from PyQt5.QtWidgets import (
|
|||||||
QVBoxLayout,
|
QVBoxLayout,
|
||||||
QTextBrowser,
|
QTextBrowser,
|
||||||
QLineEdit,
|
QLineEdit,
|
||||||
|
QMenu,
|
||||||
|
QAction,
|
||||||
QPushButton,
|
QPushButton,
|
||||||
|
QTextEdit,
|
||||||
QTabWidget,
|
QTabWidget,
|
||||||
|
QDialog,
|
||||||
|
QLabel,
|
||||||
)
|
)
|
||||||
|
from traceback import print_exc
|
||||||
|
import requests
|
||||||
from PyQt5.QtCore import Qt, pyqtSignal
|
from PyQt5.QtCore import Qt, pyqtSignal
|
||||||
import qtawesome, functools
|
from PyQt5.QtGui import QCursor
|
||||||
import threading, gobject
|
import qtawesome, functools, os
|
||||||
|
import threading, gobject, uuid
|
||||||
from myutils.config import globalconfig
|
from myutils.config import globalconfig
|
||||||
from myutils.config import globalconfig, _TR, _TRL
|
from myutils.config import globalconfig, _TR, _TRL
|
||||||
|
import myutils.ankiconnect as anki
|
||||||
|
from gui.usefulwidget import closeashidewindow, getQMessageBox, getboxlayout
|
||||||
|
|
||||||
from gui.usefulwidget import closeashidewindow
|
from myutils.ocrutil import imageCut
|
||||||
|
from gui.rangeselect import rangeselct_function
|
||||||
|
|
||||||
|
|
||||||
|
class AnkiWindow(QDialog):
|
||||||
|
setcurrenttext = pyqtSignal(str)
|
||||||
|
appenddictionary = pyqtSignal(str)
|
||||||
|
|
||||||
|
def langdu(self):
|
||||||
|
if gobject.baseobject.reader:
|
||||||
|
self.audiofile = gobject.baseobject.reader.syncttstofile(
|
||||||
|
self.wordedit.text()
|
||||||
|
)
|
||||||
|
|
||||||
|
def crop(self):
|
||||||
|
def ocroncefunction(rect):
|
||||||
|
img = imageCut(0, rect[0][0], rect[0][1], rect[1][0], rect[1][1])
|
||||||
|
fname = "./cache/ocr/cropforanki.png"
|
||||||
|
os.makedirs("./cache/ocr", exist_ok=True)
|
||||||
|
img.save(fname)
|
||||||
|
self.cropedimagepath = os.path.abspath(fname)
|
||||||
|
|
||||||
|
rangeselct_function(self, ocroncefunction, False, False)
|
||||||
|
|
||||||
|
def __init__(self, parent) -> None:
|
||||||
|
super().__init__(parent, Qt.WindowCloseButtonHint)
|
||||||
|
self.setWindowTitle("Anki Connect")
|
||||||
|
self.audiofile = None
|
||||||
|
self.cropedimagepath = None
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
self.setLayout(layout)
|
||||||
|
soundbutton = QPushButton(qtawesome.icon("fa.music"), "")
|
||||||
|
soundbutton.clicked.connect(self.langdu)
|
||||||
|
cropbutton = QPushButton(qtawesome.icon("fa.crop"), "")
|
||||||
|
cropbutton.clicked.connect(self.crop)
|
||||||
|
self.wordedit = QLineEdit()
|
||||||
|
layout.addLayout(
|
||||||
|
getboxlayout([QLabel(_TR("Word")), self.wordedit, soundbutton, cropbutton])
|
||||||
|
)
|
||||||
|
self.textedit = QTextEdit()
|
||||||
|
layout.addWidget(self.textedit)
|
||||||
|
|
||||||
|
btn = QPushButton(_TR("添加"))
|
||||||
|
btn.clicked.connect(self.errorwrap)
|
||||||
|
layout.addWidget(btn)
|
||||||
|
self.setcurrenttext.connect(self.reset)
|
||||||
|
self.appenddictionary.connect(self.textedit.append)
|
||||||
|
|
||||||
|
def reset(self, text):
|
||||||
|
self.wordedit.setText(text)
|
||||||
|
self.textedit.clear()
|
||||||
|
self.cropedimagepath = None
|
||||||
|
self.audiofile = None
|
||||||
|
|
||||||
|
def errorwrap(self):
|
||||||
|
try:
|
||||||
|
self.addanki()
|
||||||
|
getQMessageBox(self, _TR("成功"), _TR("成功"))
|
||||||
|
except requests.NetWorkException:
|
||||||
|
getQMessageBox(self, _TR("错误"), _TR("无法连接到anki"))
|
||||||
|
except anki.AnkiException as e:
|
||||||
|
getQMessageBox(self, _TR("错误"), str(e))
|
||||||
|
except:
|
||||||
|
print_exc()
|
||||||
|
|
||||||
|
def addanki(self):
|
||||||
|
word = self.wordedit.text()
|
||||||
|
explain = self.textedit.toHtml()
|
||||||
|
anki.Deck.create(anki.DeckName)
|
||||||
|
try:
|
||||||
|
model = anki.Model.create(
|
||||||
|
anki.ModelName,
|
||||||
|
anki.model_fileds,
|
||||||
|
anki.model_css,
|
||||||
|
False,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"Name": "LUNACARDTEMPLATE1",
|
||||||
|
"Front": anki.model_htmlfront,
|
||||||
|
"Back": anki.model_htmlback,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
except anki.AnkiModelExists:
|
||||||
|
model = anki.Model(anki.ModelName)
|
||||||
|
model.updateStyling(anki.model_css)
|
||||||
|
model.updateTemplates(
|
||||||
|
{
|
||||||
|
"LUNACARDTEMPLATE1": {
|
||||||
|
"Front": anki.model_htmlfront,
|
||||||
|
"Back": anki.model_htmlback,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
media = []
|
||||||
|
for k, _ in [("audio", self.audiofile), ("image", self.cropedimagepath)]:
|
||||||
|
if _:
|
||||||
|
media.append(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"path": _,
|
||||||
|
"filename": str(uuid.uuid4()) + os.path.basename(_),
|
||||||
|
"fields": [k],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
media.append([])
|
||||||
|
|
||||||
|
anki.Note.add(
|
||||||
|
anki.DeckName,
|
||||||
|
anki.ModelName,
|
||||||
|
{
|
||||||
|
"word": word,
|
||||||
|
"explain": explain,
|
||||||
|
},
|
||||||
|
False,
|
||||||
|
[],
|
||||||
|
media[0],
|
||||||
|
media[1],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class searchwordW(closeashidewindow):
|
class searchwordW(closeashidewindow):
|
||||||
@ -24,6 +154,7 @@ class searchwordW(closeashidewindow):
|
|||||||
|
|
||||||
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.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)
|
||||||
@ -55,16 +186,18 @@ class searchwordW(closeashidewindow):
|
|||||||
self.searchtext = QLineEdit()
|
self.searchtext = QLineEdit()
|
||||||
# self.searchtext.setFont(font)
|
# self.searchtext.setFont(font)
|
||||||
self.searchlayout.addWidget(self.searchtext)
|
self.searchlayout.addWidget(self.searchtext)
|
||||||
self.searchbutton = QPushButton(qtawesome.icon("fa.search"), "") # _TR("搜索"))
|
searchbutton = QPushButton(qtawesome.icon("fa.search"), "") # _TR("搜索"))
|
||||||
|
|
||||||
# self.searchbutton.setFont(font)
|
searchbutton.clicked.connect(lambda: self.search((self.searchtext.text())))
|
||||||
self.searchbutton.clicked.connect(lambda: self.search((self.searchtext.text())))
|
self.searchlayout.addWidget(searchbutton)
|
||||||
self.searchlayout.addWidget(self.searchbutton)
|
|
||||||
|
|
||||||
self.soundbutton = QPushButton(qtawesome.icon("fa.music"), "")
|
soundbutton = QPushButton(qtawesome.icon("fa.music"), "")
|
||||||
# self.searchbutton.setFont(font)
|
soundbutton.clicked.connect(self.langdu)
|
||||||
self.soundbutton.clicked.connect(self.langdu)
|
self.searchlayout.addWidget(soundbutton)
|
||||||
self.searchlayout.addWidget(self.soundbutton)
|
|
||||||
|
ankiconnect = QPushButton(qtawesome.icon("fa.adn"), "")
|
||||||
|
ankiconnect.clicked.connect(self.ankiwindow.show)
|
||||||
|
self.searchlayout.addWidget(ankiconnect)
|
||||||
|
|
||||||
self.tab = QTabWidget(self)
|
self.tab = QTabWidget(self)
|
||||||
|
|
||||||
@ -86,7 +219,6 @@ class searchwordW(closeashidewindow):
|
|||||||
|
|
||||||
textOutput = QTextBrowser(self)
|
textOutput = QTextBrowser(self)
|
||||||
# textOutput.setFont(font)
|
# textOutput.setFont(font)
|
||||||
textOutput.setContextMenuPolicy(Qt.CustomContextMenu)
|
|
||||||
textOutput.setUndoRedoEnabled(False)
|
textOutput.setUndoRedoEnabled(False)
|
||||||
textOutput.setReadOnly(True)
|
textOutput.setReadOnly(True)
|
||||||
textOutput.setOpenLinks(False)
|
textOutput.setOpenLinks(False)
|
||||||
@ -94,9 +226,10 @@ class searchwordW(closeashidewindow):
|
|||||||
self.tab.setTabVisible(i, False)
|
self.tab.setTabVisible(i, False)
|
||||||
|
|
||||||
self.textbs[self._k[i]] = textOutput
|
self.textbs[self._k[i]] = textOutput
|
||||||
|
|
||||||
textOutput.setContextMenuPolicy(Qt.CustomContextMenu)
|
textOutput.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||||
|
textOutput.customContextMenuRequested.connect(
|
||||||
|
functools.partial(self.showmenu, textOutput)
|
||||||
|
)
|
||||||
self.hiding = True
|
self.hiding = True
|
||||||
self.searchthreadsignal.connect(self.searchthread)
|
self.searchthreadsignal.connect(self.searchthread)
|
||||||
|
|
||||||
@ -104,6 +237,15 @@ class searchwordW(closeashidewindow):
|
|||||||
if gobject.baseobject.reader:
|
if gobject.baseobject.reader:
|
||||||
gobject.baseobject.reader.read(self.searchtext.text(), True)
|
gobject.baseobject.reader.read(self.searchtext.text(), True)
|
||||||
|
|
||||||
|
def showmenu(self, tb, point):
|
||||||
|
menu = QMenu(tb)
|
||||||
|
append = QAction(_TR("追加"))
|
||||||
|
menu.addAction(append)
|
||||||
|
print(point, (tb.pos()), self.mapToGlobal(tb.pos()))
|
||||||
|
action = menu.exec(QCursor.pos())
|
||||||
|
if action == append:
|
||||||
|
self.ankiwindow.appenddictionary.emit(tb.toHtml())
|
||||||
|
|
||||||
def getnewsentence(self, sentence, append):
|
def getnewsentence(self, sentence, append):
|
||||||
self.showNormal()
|
self.showNormal()
|
||||||
if append:
|
if append:
|
||||||
@ -120,7 +262,7 @@ class searchwordW(closeashidewindow):
|
|||||||
def search(self, sentence):
|
def search(self, sentence):
|
||||||
if sentence == "":
|
if sentence == "":
|
||||||
return
|
return
|
||||||
|
self.ankiwindow.setcurrenttext.emit(sentence)
|
||||||
_mp = {}
|
_mp = {}
|
||||||
_mp.update(gobject.baseobject.cishus)
|
_mp.update(gobject.baseobject.cishus)
|
||||||
|
|
||||||
|
230
LunaTranslator/LunaTranslator/myutils/ankiconnect.py
Normal file
230
LunaTranslator/LunaTranslator/myutils/ankiconnect.py
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
import requests
|
||||||
|
from .ankiconnect_config import *
|
||||||
|
|
||||||
|
|
||||||
|
class AnkiException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AnkiModelExists(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def invoke(action, **params):
|
||||||
|
response = requests.get(
|
||||||
|
f"http://127.0.0.1:{global_port}",
|
||||||
|
json={"action": action, "params": params, "version": 6},
|
||||||
|
).json()
|
||||||
|
if len(response) != 2:
|
||||||
|
raise AnkiException("response has an unexpected number of fields")
|
||||||
|
if "error" not in response:
|
||||||
|
raise AnkiException("response is missing required error field")
|
||||||
|
if "result" not in response:
|
||||||
|
raise AnkiException("response is missing required result field")
|
||||||
|
if response["error"] is not None:
|
||||||
|
if response["error"] == "Model name already exists":
|
||||||
|
raise AnkiModelExists()
|
||||||
|
else:
|
||||||
|
raise AnkiException(response["error"])
|
||||||
|
return response["result"]
|
||||||
|
|
||||||
|
|
||||||
|
class Deck:
|
||||||
|
@staticmethod
|
||||||
|
def create(name):
|
||||||
|
invoke("createDeck", deck=name)
|
||||||
|
return Deck(name)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def NamesAndIds():
|
||||||
|
return [Deck(k, v) for k, v in invoke("deckNamesAndIds").items()]
|
||||||
|
|
||||||
|
def __init__(self, name, did=None):
|
||||||
|
self.name = name
|
||||||
|
self.did = did
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"(Deck {self.name},{self.did})"
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
return invoke("deleteDecks", decks=[self.name], cardsToo=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def Config(self):
|
||||||
|
return invoke("getDeckConfig", deck=self.name)
|
||||||
|
|
||||||
|
@Config.setter
|
||||||
|
def Config(self, config):
|
||||||
|
return invoke("saveDeckConfig", config=config)
|
||||||
|
|
||||||
|
|
||||||
|
class Card:
|
||||||
|
def __repr__(self):
|
||||||
|
return f"(Card {self.cardId})"
|
||||||
|
|
||||||
|
def __init__(self, cardId):
|
||||||
|
self.cardId = cardId
|
||||||
|
|
||||||
|
def forget(self):
|
||||||
|
return invoke("forgetCards", cards=[self.cardId])
|
||||||
|
|
||||||
|
def relearn(self):
|
||||||
|
return invoke("relearnCards", cards=[self.cardId])
|
||||||
|
|
||||||
|
def answer(self):
|
||||||
|
return invoke("answerCards", cards=[self.cardId])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def Info(self):
|
||||||
|
return invoke("cardsInfo", cards=[self.cardId])[0]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def find(query="deck:current"):
|
||||||
|
return [Card(_) for _ in invoke("findCards", query=query)]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def Deck(self):
|
||||||
|
return Deck(list(invoke("getDecks", cards=[self.cardId]).keys())[0])
|
||||||
|
|
||||||
|
|
||||||
|
class Model:
|
||||||
|
@staticmethod
|
||||||
|
def create(modelName, inOrderFields: list, css, isCloze, cardTemplates):
|
||||||
|
try:
|
||||||
|
print(
|
||||||
|
invoke(
|
||||||
|
"createModel",
|
||||||
|
modelName=modelName,
|
||||||
|
inOrderFields=inOrderFields,
|
||||||
|
css=css,
|
||||||
|
isCloze=isCloze,
|
||||||
|
cardTemplates=cardTemplates,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except AnkiException as e:
|
||||||
|
if str(e) == "Model name already exists":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
return Model(modelName)
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def updateStyling(self, css):
|
||||||
|
return invoke("updateModelStyling", model={"name": self.name, "css": css})
|
||||||
|
|
||||||
|
def updateTemplates(self, templates):
|
||||||
|
return invoke(
|
||||||
|
"updateModelTemplates", model={"name": self.name, "templates": templates}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AnkiConnect:
|
||||||
|
@staticmethod
|
||||||
|
def version() -> int:
|
||||||
|
return invoke("version")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def createDeck(deck):
|
||||||
|
return invoke("createDeck", deck=deck)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def findCards(query="deck:current"):
|
||||||
|
return Card.find(query)
|
||||||
|
|
||||||
|
|
||||||
|
class Note:
|
||||||
|
@staticmethod
|
||||||
|
def add(
|
||||||
|
deckName,
|
||||||
|
modelName,
|
||||||
|
fields: dict,
|
||||||
|
allowDuplicate: bool,
|
||||||
|
tags: list,
|
||||||
|
audio: list,
|
||||||
|
picture: list,
|
||||||
|
):
|
||||||
|
invoke(
|
||||||
|
"addNote",
|
||||||
|
note={
|
||||||
|
"deckName": deckName,
|
||||||
|
"modelName": modelName,
|
||||||
|
"fields": fields,
|
||||||
|
"options": {
|
||||||
|
"allowDuplicate": allowDuplicate,
|
||||||
|
"duplicateScope": "deck",
|
||||||
|
"duplicateScopeOptions": {
|
||||||
|
"deckName": "Default",
|
||||||
|
"checkChildren": False,
|
||||||
|
"checkAllModels": False,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"tags": tags,
|
||||||
|
"audio": audio,
|
||||||
|
"picture": picture,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(AnkiConnect.version())
|
||||||
|
print(AnkiConnect.createDeck("shit2"))
|
||||||
|
# print(AnkiConnect.findCards()[0].Info['cardId'])
|
||||||
|
# print(Card(1504404537724).Info)
|
||||||
|
# print(AnkiConnect.findCards()[0].Deck)
|
||||||
|
print(Deck.NamesAndIds())
|
||||||
|
deck = Deck.NamesAndIds()[0]
|
||||||
|
print(deck)
|
||||||
|
Deck.create("test1111")
|
||||||
|
# print(deck.Config)
|
||||||
|
# deck.Config=deck.Config
|
||||||
|
# print(deck.delete())
|
||||||
|
# print(AnkiConnect.findCards()[0].Deck.delete())
|
||||||
|
|
||||||
|
model = Model.create(
|
||||||
|
"newModelName3111",
|
||||||
|
["expression", "sentence", "audio-text", "image"],
|
||||||
|
"Optional CSS with default to builtin css",
|
||||||
|
False,
|
||||||
|
[{"Name": "My Card 1", "Front": html, "Back": html}],
|
||||||
|
)
|
||||||
|
|
||||||
|
model.updateStyling("shitcss")
|
||||||
|
model.updateTemplates(
|
||||||
|
{
|
||||||
|
"My Card 1": {
|
||||||
|
"Front": html + "shit",
|
||||||
|
"Back": html + "shit",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Note.add(
|
||||||
|
"test1111",
|
||||||
|
"newModelName3111",
|
||||||
|
{
|
||||||
|
"expression": "shit122",
|
||||||
|
"sentence": "hahaa",
|
||||||
|
"meaning": "meaning",
|
||||||
|
"glossary-brief": "ss",
|
||||||
|
# "audio-text": Media(
|
||||||
|
# r"C:\dataH\LunaTranslator\cache\tts\1714228732.8068416.mp3"
|
||||||
|
# ).audio,
|
||||||
|
},
|
||||||
|
False,
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
# {
|
||||||
|
# "path": r"C:\dataH\LunaTranslator\cache\tts\1714228732.8068416.mp3",
|
||||||
|
# "filename": str(uuid.uuid4()) + "1714228732.8068416.mp3",
|
||||||
|
# "fields": ["audio-text"],
|
||||||
|
# }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
# {
|
||||||
|
# "path": r"C:\Users\11737\Documents\GitHub\LunaTranslator\LunaTranslator\cache\ocr\1709362617.9424458.png",
|
||||||
|
# "filename": str(uuid.uuid4()) + "1714228732.8068416.png",
|
||||||
|
# "fields": ["image"],
|
||||||
|
# }
|
||||||
|
],
|
||||||
|
)
|
25
LunaTranslator/LunaTranslator/myutils/ankiconnect_config.py
Normal file
25
LunaTranslator/LunaTranslator/myutils/ankiconnect_config.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
DeckName="LunaDeck"
|
||||||
|
|
||||||
|
ModelName="LunaModel"
|
||||||
|
|
||||||
|
global_port = 8765
|
||||||
|
|
||||||
|
model_fileds=["word","explain","image","audio"]
|
||||||
|
|
||||||
|
model_css=''
|
||||||
|
|
||||||
|
model_htmlfront = """
|
||||||
|
{{word}}
|
||||||
|
<br>
|
||||||
|
{{explain}}
|
||||||
|
<br>
|
||||||
|
{{image}}
|
||||||
|
"""
|
||||||
|
model_htmlback = """
|
||||||
|
{{word}}
|
||||||
|
<br>
|
||||||
|
{{explain}}
|
||||||
|
<br>
|
||||||
|
{{image}}
|
||||||
|
"""
|
@ -1,4 +1,5 @@
|
|||||||
import gobject, os
|
import gobject, os
|
||||||
|
from network.requests_common import NetWorkException
|
||||||
from ctypes import (
|
from ctypes import (
|
||||||
CDLL,
|
CDLL,
|
||||||
c_void_p,
|
c_void_p,
|
||||||
@ -316,7 +317,7 @@ class AutoCURLHandle(CURL):
|
|||||||
curl_easy_cleanup(self)
|
curl_easy_cleanup(self)
|
||||||
|
|
||||||
|
|
||||||
class CURLException(Exception):
|
class CURLException(NetWorkException):
|
||||||
def __init__(self, code) -> None:
|
def __init__(self, code) -> None:
|
||||||
if isinstance(code, CURLcode):
|
if isinstance(code, CURLcode):
|
||||||
self.errorcode = code.value
|
self.errorcode = code.value
|
||||||
|
@ -4,8 +4,10 @@ from collections import OrderedDict
|
|||||||
from urllib.parse import urlencode, urlsplit
|
from urllib.parse import urlencode, urlsplit
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
|
class NetWorkException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
class Timeout(Exception):
|
class Timeout(NetWorkException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
from ctypes import windll, POINTER, pointer, Structure, sizeof
|
from ctypes import windll, POINTER, pointer, Structure, sizeof
|
||||||
from ctypes.wintypes import LPCWSTR, DWORD, LPVOID, WORD, BOOL, LPCVOID, LPWSTR, USHORT
|
from ctypes.wintypes import LPCWSTR, DWORD, LPVOID, WORD, BOOL, LPCVOID, LPWSTR, USHORT
|
||||||
|
from network.requests_common import NetWorkException
|
||||||
|
|
||||||
|
class WinhttpException(NetWorkException):
|
||||||
class WinhttpException(Exception):
|
|
||||||
ERROR_INVALID_PARAMETER = 87
|
ERROR_INVALID_PARAMETER = 87
|
||||||
ERROR_INVALID_OPERATION = 4317
|
ERROR_INVALID_OPERATION = 4317
|
||||||
WINHTTP_ERROR_BASE = 12000
|
WINHTTP_ERROR_BASE = 12000
|
||||||
|
@ -51,7 +51,15 @@ class TTSbase:
|
|||||||
threading.Thread(target=_).start()
|
threading.Thread(target=_).start()
|
||||||
|
|
||||||
def read(self, content, force=False):
|
def read(self, content, force=False):
|
||||||
|
def _(content, force):
|
||||||
|
fname = self.syncttstofile(content)
|
||||||
|
volume = globalconfig["ttscommon"]["volume"]
|
||||||
|
if fname:
|
||||||
|
self.mp3playsignal.emit(fname, volume, force)
|
||||||
|
|
||||||
|
threading.Thread(target=_, args=(content, force)).start()
|
||||||
|
|
||||||
|
def syncttstofile(self, content):
|
||||||
if self.loadok == False:
|
if self.loadok == False:
|
||||||
return
|
return
|
||||||
if len(content) == 0:
|
if len(content) == 0:
|
||||||
@ -60,13 +68,7 @@ class TTSbase:
|
|||||||
return
|
return
|
||||||
|
|
||||||
rate = globalconfig["ttscommon"]["rate"]
|
rate = globalconfig["ttscommon"]["rate"]
|
||||||
volume = globalconfig["ttscommon"]["volume"]
|
|
||||||
voice = globalconfig["reader"][self.typename]["voice"]
|
voice = globalconfig["reader"][self.typename]["voice"]
|
||||||
voice_index = self.voicelist.index(voice)
|
voice_index = self.voicelist.index(voice)
|
||||||
|
fname = self.speak(content, rate, voice, voice_index)
|
||||||
def _():
|
return fname
|
||||||
fname = self.speak(content, rate, voice, voice_index)
|
|
||||||
if fname:
|
|
||||||
self.mp3playsignal.emit(fname, volume, force)
|
|
||||||
|
|
||||||
threading.Thread(target=_).start()
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import time
|
import time, os
|
||||||
import winsharedutils
|
import winsharedutils
|
||||||
|
|
||||||
from tts.basettsclass import TTSbase
|
from tts.basettsclass import TTSbase
|
||||||
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "نصف قطر",
|
"半径": "نصف قطر",
|
||||||
"圆角": "فيليه",
|
"圆角": "فيليه",
|
||||||
"合并": "دمج",
|
"合并": "دمج",
|
||||||
"立即应用": "التطبيق الفوري"
|
"立即应用": "التطبيق الفوري",
|
||||||
|
"无法连接到anki": "غير قادر على الاتصال انكي",
|
||||||
|
"追加": "إلحاق"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "半徑",
|
"半径": "半徑",
|
||||||
"圆角": "圓角",
|
"圆角": "圓角",
|
||||||
"合并": "合併",
|
"合并": "合併",
|
||||||
"立即应用": "立即應用"
|
"立即应用": "立即應用",
|
||||||
|
"无法连接到anki": "無法連接到anki",
|
||||||
|
"追加": "追加"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "radius",
|
"半径": "radius",
|
||||||
"圆角": "fillet",
|
"圆角": "fillet",
|
||||||
"合并": "merge",
|
"合并": "merge",
|
||||||
"立即应用": "apply now"
|
"立即应用": "apply now",
|
||||||
|
"无法连接到anki": "Unable to connect to Anki",
|
||||||
|
"追加": "Add"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "Radio",
|
"半径": "Radio",
|
||||||
"圆角": "Redondeado",
|
"圆角": "Redondeado",
|
||||||
"合并": "Fusión",
|
"合并": "Fusión",
|
||||||
"立即应用": "Aplicar de inmediato"
|
"立即应用": "Aplicar de inmediato",
|
||||||
|
"无法连接到anki": "No se puede conectar a Anki",
|
||||||
|
"追加": "Añadido"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "Rayon",
|
"半径": "Rayon",
|
||||||
"圆角": "Coins arrondis",
|
"圆角": "Coins arrondis",
|
||||||
"合并": "Consolidation",
|
"合并": "Consolidation",
|
||||||
"立即应用": "Appliquer maintenant"
|
"立即应用": "Appliquer maintenant",
|
||||||
|
"无法连接到anki": "Impossible de se connecter à Anki",
|
||||||
|
"追加": "Supplémentaire"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "raggio",
|
"半径": "raggio",
|
||||||
"圆角": "filetto",
|
"圆角": "filetto",
|
||||||
"合并": "fusione",
|
"合并": "fusione",
|
||||||
"立即应用": "Applica ora"
|
"立即应用": "Applica ora",
|
||||||
|
"无法连接到anki": "Impossibile connettersi ad Anki",
|
||||||
|
"追加": "Aggiungi"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "半径はんけい",
|
"半径": "半径はんけい",
|
||||||
"圆角": "フィレット",
|
"圆角": "フィレット",
|
||||||
"合并": "マージ",
|
"合并": "マージ",
|
||||||
"立即应用": "今すぐ適用"
|
"立即应用": "今すぐ適用",
|
||||||
|
"无法连接到anki": "ankiに接続できません",
|
||||||
|
"追加": "追加#ツイカ#"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "반지름",
|
"半径": "반지름",
|
||||||
"圆角": "필렛",
|
"圆角": "필렛",
|
||||||
"合并": "병합",
|
"合并": "병합",
|
||||||
"立即应用": "지금 적용"
|
"立即应用": "지금 적용",
|
||||||
|
"无法连接到anki": "anki에 연결할 수 없음",
|
||||||
|
"追加": "추가"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "promień",
|
"半径": "promień",
|
||||||
"圆角": "filet",
|
"圆角": "filet",
|
||||||
"合并": "połączenie",
|
"合并": "połączenie",
|
||||||
"立即应用": "aplikuj teraz"
|
"立即应用": "aplikuj teraz",
|
||||||
|
"无法连接到anki": "Nie można połączyć się z Anki",
|
||||||
|
"追加": "Dodaj"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "Радиус",
|
"半径": "Радиус",
|
||||||
"圆角": "Круглый угол",
|
"圆角": "Круглый угол",
|
||||||
"合并": "Объединение",
|
"合并": "Объединение",
|
||||||
"立即应用": "Немедленное применение"
|
"立即应用": "Немедленное применение",
|
||||||
|
"无法连接到anki": "Не удалось подключиться к ANKI",
|
||||||
|
"追加": "Добавить"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "รัศมี",
|
"半径": "รัศมี",
|
||||||
"圆角": "มุมกลม",
|
"圆角": "มุมกลม",
|
||||||
"合并": "การควบรวมกิจการ",
|
"合并": "การควบรวมกิจการ",
|
||||||
"立即应用": "สมัครตอนนี้"
|
"立即应用": "สมัครตอนนี้",
|
||||||
|
"无法连接到anki": "ไม่สามารถเชื่อมต่อกับ anki ได้",
|
||||||
|
"追加": "เพิ่ม"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "radius",
|
"半径": "radius",
|
||||||
"圆角": "fillet",
|
"圆角": "fillet",
|
||||||
"合并": "birleştir",
|
"合并": "birleştir",
|
||||||
"立即应用": "şimdi uygulayın"
|
"立即应用": "şimdi uygulayın",
|
||||||
|
"无法连接到anki": "Anki ile bağlanılamadı",
|
||||||
|
"追加": "Ekle"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "радіус",
|
"半径": "радіус",
|
||||||
"圆角": "філет",
|
"圆角": "філет",
|
||||||
"合并": "об’ єднати",
|
"合并": "об’ єднати",
|
||||||
"立即应用": "застосовувати зараз"
|
"立即应用": "застосовувати зараз",
|
||||||
|
"无法连接到anki": "Неможливо з' єднатися з Anki",
|
||||||
|
"追加": "Додати"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "Bán kính",
|
"半径": "Bán kính",
|
||||||
"圆角": "Góc tròn",
|
"圆角": "Góc tròn",
|
||||||
"合并": "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",
|
||||||
|
"追加": "Thêm"
|
||||||
}
|
}
|
@ -775,5 +775,7 @@
|
|||||||
"半径": "",
|
"半径": "",
|
||||||
"圆角": "",
|
"圆角": "",
|
||||||
"合并": "",
|
"合并": "",
|
||||||
"立即应用": ""
|
"立即应用": "",
|
||||||
|
"追加": "",
|
||||||
|
"无法连接到anki": ""
|
||||||
}
|
}
|
@ -29,7 +29,7 @@ include(generate_product_version)
|
|||||||
|
|
||||||
set(VERSION_MAJOR 2)
|
set(VERSION_MAJOR 2)
|
||||||
set(VERSION_MINOR 50)
|
set(VERSION_MINOR 50)
|
||||||
set(VERSION_PATCH 2)
|
set(VERSION_PATCH 3)
|
||||||
|
|
||||||
add_library(pch pch.cpp)
|
add_library(pch pch.cpp)
|
||||||
target_precompile_headers(pch PUBLIC pch.h)
|
target_precompile_headers(pch PUBLIC pch.h)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user