This commit is contained in:
恍兮惚兮 2024-06-27 19:59:38 +08:00
parent 8286514f3d
commit 10d8eabf03
28 changed files with 858 additions and 228 deletions

View File

@ -2,7 +2,7 @@ from qtsymbols import *
import functools
from myutils.utils import checkencoding
from myutils.config import globalconfig, _TR, _TRL
from myutils.wrapper import Singleton
from myutils.wrapper import Singleton_close
from gui.usefulwidget import getspinbox, threebuttons, getlineedit, FocusCombo
nowsuppertcodes = _TRL(
@ -18,7 +18,7 @@ nowsuppertcodes = _TRL(
nowsuppertcodespy = ["SHIFT-JIS", "GBK", "BIG5", "EUC-KR", "ASCII"]
@Singleton
@Singleton_close
class codeacceptdialog(QDialog):
def _setcode_i(self, combox: QComboBox, itemsaver_, code="", idx=0):
itemsaver_.saveidx = idx
@ -76,7 +76,7 @@ class codeacceptdialog(QDialog):
)
row += 1
button = threebuttons()
button = threebuttons(texts=["添加行", "删除行", "立即应用"])
button.btn1clicked.connect(self.clicked1)
button.btn2clicked.connect(self.clicked2)
button.btn3clicked.connect(self.apply)
@ -122,8 +122,15 @@ class codeacceptdialog(QDialog):
self.table.setIndexWidget(index, codecombox)
def clicked2(self):
skip = []
for index in self.table.selectedIndexes():
if index.row() in skip:
continue
skip.append(index.row())
skip = reversed(sorted(skip))
self.model.removeRow(self.table.currentIndex().row())
for row in skip:
self.model.removeRow(row)
def apply(self):

View File

@ -16,12 +16,19 @@ from myutils.config import (
static_data,
)
from myutils.hwnd import getExeIcon
from myutils.wrapper import Singleton_close, Singleton, threader, tryprint
from myutils.wrapper import (
Singleton_close,
Singleton,
threader,
tryprint,
Singleton_close,
)
from myutils.utils import (
checkifnewgame,
str2rgba,
gamdidchangedtask,
titlechangedtask,
idtypecheck,
selectdebugfile,
targetmod,
)
@ -707,8 +714,9 @@ class dialog_setting_game_internal(QWidget):
if globalconfig["metadata"][key]["idtype"] == 0:
vndbid.setValidator(QIntValidator())
vndbid.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
vndbid.textEdited.connect(
functools.partial(savehook_new_data[gameuid].__setitem__, idname)
functools.partial(idtypecheck, key, idname, gameuid)
)
vndbid.returnPressed.connect(
functools.partial(gamdidchangedtask, key, idname, gameuid)
@ -729,7 +737,9 @@ class dialog_setting_game_internal(QWidget):
__settting = targetmod[key].querysettingwindow
_vbox_internal.insert(
1,
getIconButton(functools.partial(__settting, self), icon="fa.gear"),
getIconButton(
functools.partial(__settting, self, gameuid), icon="fa.gear"
),
)
except:
pass
@ -1149,9 +1159,16 @@ class dialog_setting_game_internal(QWidget):
): # 2
self.__checkaddnewmethod(row, k)
vbox.addWidget(table)
buttons = threebuttons(btns=2, texts=_TRL(["添加行", "删除行"]))
buttons = threebuttons(texts=["添加行", "删除行", "上移", "下移"])
buttons.btn1clicked.connect(self.__privatetextproc_btn1)
buttons.btn2clicked.connect(self.__privatetextproc_btn2)
buttons.btn2clicked.connect(self.removerows)
buttons.btn3clicked.connect(
functools.partial(self.__privatetextproc_moverank, -1)
)
buttons.btn4clicked.connect(
functools.partial(self.__privatetextproc_moverank, 1)
)
vbox.addWidget(buttons)
vbox.addWidget(buttons)
return _w
@ -1218,6 +1235,25 @@ class dialog_setting_game_internal(QWidget):
btn,
)
def removerows(self):
skip = []
for index in self.__textprocinternaltable.selectedIndexes():
if index.row() in skip:
continue
skip.append(index.row())
skip = reversed(sorted(skip))
for row in skip:
self.__textprocinternalmodel.removeRow(row)
_dict = savehook_new_data[self.__privatetextproc_gameuid][
"save_text_process_info"
]
post = _dict["rank"][row]
_dict["rank"].pop(row)
if post in _dict["postprocessconfig"]:
_dict["postprocessconfig"].pop(post)
def __privatetextproc_btn2(self):
row = self.__textprocinternaltable.currentIndex().row()
if row < 0:
@ -1475,7 +1511,7 @@ class dialog_setting_game(QDialog):
pass
@Singleton
@Singleton_close
class dialog_syssetting(QDialog):
def __init__(self, parent, type_=1) -> None:
@ -2491,6 +2527,50 @@ class pixwrapper(QWidget):
self.pixview.setPixmap(pix)
def getalistname(parent, callback, skipid=False, skipidid=None):
__d = {"k": 0}
__vis = []
__uid = []
for _ in savegametaged:
if _ is None:
__vis.append("GLOBAL")
__uid.append(None)
else:
__vis.append(_["title"])
__uid.append(_["uid"])
if skipid:
if skipidid == __uid[-1]:
__uid.pop(-1)
__vis.pop(-1)
def __wrap(callback, __d, __uid):
if len(__uid) == 0:
return
uid = __uid[__d["k"]]
callback(uid)
autoinitdialog(
parent,
_TR("目标"),
600,
[
{
"type": "combo",
"name": _TR("目标"),
"d": __d,
"k": "k",
"list": __vis,
},
{
"type": "okcancel",
"callback": functools.partial(__wrap, callback, __d, __uid),
},
],
)
class dialog_savedgame_v3(QWidget):
def viewitem(self, k):
try:
@ -2597,12 +2677,8 @@ class dialog_savedgame_v3(QWidget):
if curr and os.path.exists(curr):
savehook_new_data[self.currentfocusuid]["currentmainimage"] = curr
def addtolistcallback(self, __d, __uid, gameuid):
def addtolistcallback(self, uid, gameuid):
if len(__uid) == 0:
return
uid = __uid[__d["k"]]
__save = self.reftagid
self.reftagid = uid
@ -2616,39 +2692,11 @@ class dialog_savedgame_v3(QWidget):
self.reftagid = __save
def addtolist(self):
__d = {"k": 0}
__vis = []
__uid = []
for _ in savegametaged:
if _ is None:
__vis.append("GLOBAL")
__uid.append(None)
else:
__vis.append(_["title"])
__uid.append(_["uid"])
if self.reftagid == __uid[-1]:
__uid.pop(-1)
__vis.pop(-1)
autoinitdialog(
getalistname(
self,
_TR("目标"),
600,
[
{
"type": "combo",
"name": _TR("目标"),
"d": __d,
"k": "k",
"list": __vis,
},
{
"type": "okcancel",
"callback": functools.partial(
self.addtolistcallback, __d, __uid, self.currentfocusuid
),
},
],
lambda x: self.addtolistcallback(x, self.currentfocusuid),
True,
self.reftagid,
)
def directshow(self):

View File

@ -4,7 +4,7 @@ from traceback import print_exc
import qtawesome
from myutils.config import globalconfig, _TR, _TRL
from myutils.utils import makehtml
from myutils.wrapper import Singleton
from myutils.wrapper import Singleton_close
from gui.usefulwidget import (
MySwitch,
selectcolor,
@ -18,7 +18,7 @@ from gui.usefulwidget import (
)
@Singleton
@Singleton_close
class noundictconfigdialog1(QDialog):
def newline(self, row, item):
self.model.insertRow(
@ -29,6 +29,41 @@ class noundictconfigdialog1(QDialog):
self.model.index(row, 0), getsimpleswitch(item, "regex")
)
def showmenu(self, table: QTableView, _):
r = table.currentIndex().row()
if r < 0:
return
menu = QMenu(table)
up = QAction(_TR("上移"))
down = QAction(_TR("下移"))
menu.addAction(up)
menu.addAction(down)
action = menu.exec(table.cursor().pos())
if action == up:
self.moverank(table, -1)
elif action == down:
self.moverank(table, 1)
def moverank(self, table: QTableView, dy):
curr = table.currentIndex()
model = table.model()
target = (curr.row() + dy) % model.rowCount()
texts = [model.item(curr.row(), i).text() for i in range(model.columnCount())]
item = self.reflist.pop(curr.row())
self.reflist.insert(
target, {"key": texts[1], "value": [2], "regex": item["regex"]}
)
model.removeRow(curr.row())
model.insertRow(target, [QStandardItem(text) for text in texts])
table.setCurrentIndex(model.index(target, curr.column()))
table.setIndexWidget(
model.index(target, 0), getsimpleswitch(self.reflist[target], "regex")
)
def __init__(self, parent, reflist, title, label) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
@ -47,6 +82,10 @@ class noundictconfigdialog1(QDialog):
table.horizontalHeader().setSectionResizeMode(
0, QHeaderView.ResizeMode.ResizeToContents
)
table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
table.customContextMenuRequested.connect(
functools.partial(self.showmenu, table)
)
self.table = table
for row, item in enumerate(reflist):
@ -74,7 +113,7 @@ class noundictconfigdialog1(QDialog):
button4.clicked.connect(clicked4)
search.addWidget(button4)
button = threebuttons()
button = threebuttons(texts=["添加行", "删除行", "上移", "下移", "立即应用"])
def clicked1():
self.reflist.insert(0, {"key": "", "value": "", "regex": False})
@ -83,15 +122,26 @@ class noundictconfigdialog1(QDialog):
button.btn1clicked.connect(clicked1)
def clicked2():
self.model.removeRow(table.currentIndex().row())
self.reflist.pop(table.currentIndex().row())
skip = []
for index in self.table.selectedIndexes():
if index.row() in skip:
continue
skip.append(index.row())
skip = reversed(sorted(skip))
for row in skip:
self.model.removeRow(row)
self.reflist.pop(row)
button.btn2clicked.connect(clicked2)
button.btn3clicked.connect(self.apply)
button.btn5clicked.connect(self.apply)
button.btn3clicked.connect(functools.partial(self.moverank, table, -1))
button.btn4clicked.connect(functools.partial(self.moverank, table, 1))
self.button = button
formLayout.addWidget(table)
formLayout.addLayout(search)
formLayout.addWidget(button)
self.resize(QSize(600, 400))
self.show()
@ -115,7 +165,7 @@ class noundictconfigdialog1(QDialog):
self.apply()
@Singleton
@Singleton_close
class regexedit(QDialog):
def __init__(self, parent, regexlist) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
@ -135,7 +185,7 @@ class regexedit(QDialog):
for row, regex in enumerate(regexlist):
self.model.insertRow(row, [QStandardItem(regex)])
button = threebuttons()
button = threebuttons(texts=["添加行", "删除行", "立即应用"])
def clicked1():
regexlist.insert(0, "")
@ -144,9 +194,16 @@ class regexedit(QDialog):
button.btn1clicked.connect(clicked1)
def clicked2():
self.model.removeRow(table.currentIndex().row())
regexlist.pop(table.currentIndex().row())
skip = []
for index in self.table.selectedIndexes():
if index.row() in skip:
continue
skip.append(index.row())
skip = reversed(sorted(skip))
for row in skip:
self.model.removeRow(row)
regexlist.pop(row)
button.btn2clicked.connect(clicked2)
button.btn3clicked.connect(self.apply)
self.button = button
@ -157,17 +214,21 @@ class regexedit(QDialog):
def apply(self):
rows = self.model.rowCount()
rowoffset = 0
dedump = set()
needremoves = []
for row in range(rows):
regex = self.model.item(row, 0).text()
if regex == "" or regex in dedump:
self.regexlist.pop(row - rowoffset)
rowoffset += 1
needremoves.append(row)
continue
self.regexlist[row - rowoffset] = regex
self.regexlist[row] = regex
dedump.add(regex)
for row in reversed(needremoves):
self.model.removeRow(row)
self.regexlist.pop(row)
def closeEvent(self, _) -> None:
self.button.setFocus()
self.apply()
@ -185,7 +246,7 @@ def autoinitdialog_items(dic):
return items
@Singleton
@Singleton_close
class autoinitdialog(QDialog):
def __init__(self, parent, title, width, lines, _=None) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
@ -329,7 +390,7 @@ def getsomepath1(
)
@Singleton
@Singleton_close
class multicolorset(QDialog):
def __init__(self, parent) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
@ -382,7 +443,7 @@ class multicolorset(QDialog):
self.show()
@Singleton
@Singleton_close
class postconfigdialog_(QDialog):
def closeEvent(self, a0: QCloseEvent) -> None:
if self.closeevent:
@ -426,7 +487,7 @@ class postconfigdialog_(QDialog):
table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
# table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
# table.clicked.connect(self.show_info)
button = threebuttons()
button = threebuttons(texts=["添加行", "删除行", "立即应用"])
def clicked1():
model.insertRow(0, [QStandardItem(), QStandardItem()])
@ -434,8 +495,15 @@ class postconfigdialog_(QDialog):
button.btn1clicked.connect(clicked1)
def clicked2():
skip = []
for index in table.selectedIndexes():
if index.row() in skip:
continue
skip.append(index.row())
skip = reversed(sorted(skip))
model.removeRow(table.currentIndex().row())
for row in skip:
model.removeRow(row)
button.btn2clicked.connect(clicked2)
button.btn3clicked.connect(self.apply)

View File

@ -8,8 +8,8 @@ from webviewpy import (
declare_library_path,
)
from winsharedutils import HTMLBrowser
from myutils.config import _TR, globalconfig
from myutils.wrapper import Singleton, Singleton_close, tryprint
from myutils.config import _TR, globalconfig, _TRL
from myutils.wrapper import Singleton_close, tryprint
from myutils.utils import nowisdark, checkportavailable
@ -59,7 +59,7 @@ class FocusDoubleSpin(QDoubleSpinBox):
return super().wheelEvent(e)
@Singleton
@Singleton_close
class dialog_showinfo(QDialog):
def __init__(self, parent, title, info) -> None:
@ -1277,34 +1277,41 @@ class threebuttons(QWidget):
btn1clicked = pyqtSignal()
btn2clicked = pyqtSignal()
btn3clicked = pyqtSignal()
btn4clicked = pyqtSignal()
btn5clicked = pyqtSignal()
def __init__(self, btns=3, texts=None):
def __init__(self, texts=None):
super().__init__()
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(layout)
button = QPushButton(self)
if texts:
texts = _TRL(texts)
if len(texts) >= 1:
button = QPushButton(self)
button.setText(texts[0])
else:
button.setText(_TR("添加行"))
button.clicked.connect(self.btn1clicked)
button2 = QPushButton(self)
if texts:
button.clicked.connect(self.btn1clicked)
layout.addWidget(button)
if len(texts) >= 2:
button2 = QPushButton(self)
button2.setText(texts[1])
else:
button2.setText(_TR("删除行"))
button2.clicked.connect(self.btn2clicked)
layout.addWidget(button)
layout.addWidget(button2)
if btns == 3:
button2.clicked.connect(self.btn2clicked)
layout.addWidget(button2)
if len(texts) >= 3:
button3 = QPushButton(self)
if texts:
button3.setText(texts[2])
else:
button3.setText(_TR("立即应用"))
button3.setText(texts[2])
button3.clicked.connect(self.btn3clicked)
layout.addWidget(button3)
if len(texts) >= 4:
button4 = QPushButton(self)
button4.setText(texts[3])
button4.clicked.connect(self.btn4clicked)
layout.addWidget(button4)
if len(texts) >= 5:
button5 = QPushButton(self)
button5.setText(texts[4])
button5.clicked.connect(self.btn5clicked)
layout.addWidget(button5)
def tabadd_lazy(tab, title, getrealwidgetfunction):
@ -1534,7 +1541,8 @@ def makesubtab_lazy(
@Singleton_close
class listediter(QDialog):
def showmenu(self, p: QPoint):
r = self.hctable.currentIndex().row()
curr = self.hctable.currentIndex()
r = curr.row()
if r < 0:
return
menu = QMenu(self.hctable)
@ -1549,15 +1557,10 @@ class listediter(QDialog):
action = menu.exec(self.hctable.cursor().pos())
if action == remove:
self.hcmodel.removeRow(self.hctable.currentIndex().row())
self.hcmodel.removeRow(curr.row())
elif action == copy:
winsharedutils.clipboard_set(
self.hcmodel.item(
self.hctable.currentIndex().row(),
self.hctable.currentIndex().column(),
).text()
)
winsharedutils.clipboard_set(self.hcmodel.itemFromIndex(curr).text())
elif action == up:
@ -1567,12 +1570,12 @@ class listediter(QDialog):
self.moverank(1)
def moverank(self, dy):
target = (self.hctable.currentIndex().row() + dy) % self.hcmodel.rowCount()
text = self.hcmodel.item(
self.hctable.currentIndex().row(), self.hctable.currentIndex().column()
).text()
self.hcmodel.removeRow(self.hctable.currentIndex().row())
curr = self.hctable.currentIndex()
target = (curr.row() + dy) % self.hcmodel.rowCount()
text = self.hcmodel.itemFromIndex(curr).text()
self.hcmodel.removeRow(curr.row())
self.hcmodel.insertRow(target, [QStandardItem(text)])
self.hctable.setCurrentIndex(self.hcmodel.index(target, 0))
def __init__(
self, p, title, header, lst, closecallback=None, ispathsedit=None
@ -1607,9 +1610,11 @@ class listediter(QDialog):
self.hcmodel.insertRow(row, [QStandardItem(k)])
formLayout = QVBoxLayout()
formLayout.addWidget(self.hctable)
self.buttons = threebuttons(btns=2)
self.buttons = threebuttons(texts=["添加行", "删除行", "上移", "下移"])
self.buttons.btn1clicked.connect(self.click1)
self.buttons.btn2clicked.connect(self.clicked2)
self.buttons.btn3clicked.connect(functools.partial(self.moverank, -1))
self.buttons.btn4clicked.connect(functools.partial(self.moverank, 1))
formLayout.addWidget(self.buttons)
self.setLayout(formLayout)
@ -1619,7 +1624,15 @@ class listediter(QDialog):
print_exc()
def clicked2(self):
self.hcmodel.removeRow(self.hctable.currentIndex().row())
skip = []
for index in self.hctable.selectedIndexes():
if index.row() in skip:
continue
skip.append(index.row())
skip = reversed(sorted(skip))
for row in skip:
self.hcmodel.removeRow(row)
def closeEvent(self, a0: QCloseEvent) -> None:
self.buttons.setFocus()

View File

@ -29,8 +29,8 @@ class common:
return {}
@property
def name(self):
return self.config_all.get("name", self.typename)
def idname(self):
return self.config_all['target']
@property
def proxy(self):

View File

@ -1,11 +1,156 @@
import requests
from myutils.config import (
_TR,
savehook_new_data,
)
from myutils.utils import initanewitem, gamdidchangedtask
import functools
import time
from qtsymbols import *
from metadata.abstract import common
from gui.inputdialog import autoinitdialog, autoinitdialog_items
from gui.usefulwidget import getlineedit
from gui.dialog_savedgame import getreflist, getalistname
from myutils.wrapper import Singleton_close
@Singleton_close
class bgmsettings(QDialog):
@property
def headers(self):
return {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Authorization": "Bearer " + self._ref.config["access-token"].strip(),
}
@property
def username(self):
response = requests.get(
"https://api.bgm.tv/v0/me", headers=self.headers, proxies=self._ref.proxy
)
return response.json()["username"]
def querylist(self):
params = {
"subject_type": "4",
"limit": "30",
"offset": "0",
}
collectresults = []
response = requests.get(
f"https://api.bgm.tv/v0/users/{self.username}/collections",
params=params,
headers=self.headers,
proxies=self._ref.proxy,
)
for item in response.json()["data"]:
collectresults.append(
{"id": item["subject_id"], "name": item["subject"]["name"]}
)
return collectresults
def getalistname_download(self, uid):
reflist = getreflist(uid)
collectresults = self.querylist()
thislistvids = [
savehook_new_data[gameuid][self._ref.idname] for gameuid in reflist
]
collect = {}
for gameuid in savehook_new_data:
vid = savehook_new_data[gameuid][self._ref.idname]
collect[vid] = gameuid
for item in collectresults:
title = item["name"]
vid = item["id"]
if vid in thislistvids:
continue
if vid in collect:
gameuid = collect[vid]
else:
gameuid = initanewitem(f"bgm_{vid}_{time.time()}", title)
savehook_new_data[gameuid][self._ref.idname] = vid
gamdidchangedtask(self._ref.typename, self._ref.idname, gameuid)
reflist.insert(0, gameuid)
def getalistname_upload(self, uid):
reflist = getreflist(uid)
vids = [item["id"] for item in self.querylist()]
for gameuid in reflist:
vid = savehook_new_data[gameuid][self._ref.idname]
if vid == 0:
continue
if vid in vids:
continue
requests.post(
f"https://api.bgm.tv/v0/users/-/collections/{vid}",
headers=self.headers,
json={
"type": 4,
# "rate": 10,
"comment": "string",
"private": True,
"tags": ["string"],
},
proxies=self._ref.proxy,
)
def singleupload_existsoverride(self, gameuid):
vid = savehook_new_data[gameuid][self._ref.idname]
if not vid:
return
try:
requests.post(
f"https://api.bgm.tv/v0/users/-/collections/{vid}",
headers=self.headers,
json={
"type": 4,
# "rate": 10,
"comment": "string",
"private": True,
"tags": ["string"],
},
proxies=self._ref.proxy,
)
except:
pass
def __getalistname(self, callback, _):
getalistname(self, callback)
def __init__(self, parent, _ref: common, gameuid: str) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
self._ref = _ref
self.resize(QSize(800, 10))
self.setWindowTitle("vndb")
fl = QFormLayout(self)
fl.addRow("access-token", getlineedit(_ref.config, "access-token"))
btn = QPushButton(_TR("上传游戏"))
btn.clicked.connect(
functools.partial(self.singleupload_existsoverride, gameuid)
)
fl.addRow(btn)
btn = QPushButton(_TR("上传游戏列表"))
btn.clicked.connect(
functools.partial(self.__getalistname, self.getalistname_upload)
)
fl.addRow(btn)
btn = QPushButton(_TR("获取游戏列表"))
btn.clicked.connect(
functools.partial(self.__getalistname, self.getalistname_download)
)
fl.addRow(btn)
self.show()
class searcher(common):
def querysettingwindow(self, parent):
items = autoinitdialog_items(self.config_all)
autoinitdialog(parent, self.name, 800, items)
def querysettingwindow(self, parent, gameuid):
bgmsettings(parent, self, gameuid)
def getidbytitle(self, title):

View File

@ -1,103 +1,134 @@
import requests, re, os
from myutils.config import tryreadconfig, safesave
import gzip, json
import shutil, gobject
import requests, re
from myutils.config import (
tryreadconfig,
safesave,
savegametaged,
_TR,
savehook_new_data,
)
from myutils.utils import initanewitem, gamdidchangedtask
import gzip, json, functools
import shutil, gobject, time
from qtsymbols import *
from gui.inputdialog import autoinitdialog
from metadata.abstract import common
from gui.usefulwidget import getlineedit
from gui.dialog_savedgame import getreflist, getalistname
from myutils.wrapper import Singleton_close
def safegetvndbjson(proxy, url, json, getter):
def saferequestvndb(proxy, method, url, json=None, headers=None):
print(method, url, json)
try:
print(url, json)
_ = requests.post(
url,
resp = requests.request(
method,
"https://api.vndb.org/kana/" + url,
headers=headers,
json=json,
proxies=proxy,
)
print(_.text)
try:
return getter(_.json())
except:
# print_exc()
return None
except:
return None
time.sleep(3)
print("retry network error")
return saferequestvndb(proxy, method, url, json, headers)
if resp.status_code == 429:
time.sleep(3)
print("retry 429")
return saferequestvndb(proxy, method, url, json, headers)
elif resp.status_code == 400:
print(resp.text)
# 400 搜索失败
else:
if method.upper() in ["GET", "POST"]:
try:
return resp.json()
except:
print(resp.status_code)
print(resp.text)
return None
def safegetvndbjson(proxy, url, json):
return saferequestvndb(proxy, "POST", url, json)
def gettitlefromjs(js):
try:
for _ in js["titles"]:
main = _["main"]
title = _["title"]
if main:
return title
raise Exception()
except:
return js["title"]
def gettitlebyid(proxy, vid):
def _getter(js):
try:
for _ in js["results"][0]["titles"]:
main = _["main"]
title = _["title"]
if main:
return title
raise Exception()
except:
return js["results"][0]["title"]
return safegetvndbjson(
js = safegetvndbjson(
proxy,
"https://api.vndb.org/kana/vn",
"vn",
{"filters": ["id", "=", vid], "fields": "title,titles.title,titles.main"},
_getter,
)
if js:
return gettitlefromjs(js["results"][0])
def getscreenshotsbyid(proxy, vid):
def _getter(js):
js = safegetvndbjson(
proxy, "vn", {"filters": ["id", "=", vid], "fields": "screenshots.url"}
)
if js:
___ = []
for _ in js["results"][0]["screenshots"]:
url = _["url"]
___.append(url)
return ___
return safegetvndbjson(
proxy,
"https://api.vndb.org/kana/vn",
{"filters": ["id", "=", vid], "fields": "screenshots.url"},
_getter,
)
def getimgbyid(proxy, vid):
return safegetvndbjson(
proxy,
"https://api.vndb.org/kana/vn",
{"filters": ["id", "=", vid], "fields": "image.url"},
lambda js: js["results"][0]["image"]["url"],
js = safegetvndbjson(
proxy, "vn", {"filters": ["id", "=", vid], "fields": "image.url"}
)
if js:
return js["results"][0]["image"]["url"]
def getvidbytitle_vn(proxy, title):
return safegetvndbjson(
js = safegetvndbjson(
proxy,
"https://api.vndb.org/kana/vn",
"vn",
{"filters": ["search", "=", title], "fields": "id", "sort": "searchrank"},
lambda js: js["results"][0]["id"],
)
if js:
return js["results"][0]["id"]
def getvidbytitle_release(proxy, title):
return safegetvndbjson(
js = safegetvndbjson(
proxy,
"https://api.vndb.org/kana/release",
"release",
{
"filters": ["search", "=", title],
"fields": "id,vns.id",
"sort": "searchrank",
},
lambda js: js["results"][0]["vns"][0]["id"],
)
if js:
return js["results"][0]["vns"][0]["id"]
def getdevelopersbyid(proxy, vid):
def _js(js):
js = safegetvndbjson(
proxy,
"vn",
{"filters": ["id", "=", vid], "fields": "developers.name,developers.original"},
)
if js:
_ = []
for item in js["results"][0]["developers"]:
if item["original"]:
@ -105,14 +136,6 @@ def getdevelopersbyid(proxy, vid):
_.append(item["name"])
return _
name = safegetvndbjson(
proxy,
"https://api.vndb.org/kana/vn",
{"filters": ["id", "=", vid], "fields": "developers.name,developers.original"},
_js,
)
return name
def getidbytitle_(proxy, title):
vid = getvidbytitle_vn(proxy, title)
@ -122,9 +145,9 @@ def getidbytitle_(proxy, title):
def getcharnamemapbyid(proxy, vid):
res = safegetvndbjson(
js = safegetvndbjson(
proxy,
"https://api.vndb.org/kana/character",
"character",
{
"filters": [
"vn",
@ -133,8 +156,11 @@ def getcharnamemapbyid(proxy, vid):
],
"fields": "name,original",
},
lambda js: js["results"],
)
if js:
res = js["results"]
else:
return {}
namemap = {}
try:
for r in res:
@ -178,8 +204,8 @@ def safedownload(proxy):
def getvntagsbyid(proxy, vid):
res = safegetvndbjson(
"https://api.vndb.org/kana/vn",
js = safegetvndbjson(
"vn",
{
"filters": [
"id",
@ -188,8 +214,10 @@ def getvntagsbyid(proxy, vid):
],
"fields": "tags.rating",
},
lambda js: js["results"][0]["tags"],
)
if not js:
return
res = js["results"][0]["tags"]
if not res:
return
tags = []
@ -213,8 +241,171 @@ def getvntagsbyid(proxy, vid):
return tags
@Singleton_close
class vndbsettings(QDialog):
def getalistname(self, after):
__d = {"k": 0}
__vis = []
__uid = []
for _ in savegametaged:
if _ is None:
__vis.append("GLOBAL")
__uid.append(None)
else:
__vis.append(_["title"])
__uid.append(_["uid"])
autoinitdialog(
self,
_TR("目标"),
600,
[
{
"type": "combo",
"name": _TR("目标"),
"d": __d,
"k": "k",
"list": __vis,
},
{
"type": "okcancel",
"callback": functools.partial(after, __d, __uid),
},
],
)
@property
def headers(self):
return {
"Authorization": f"Token {self._ref.config['Token']}",
}
@property
def userid(self):
return saferequestvndb(
self._ref.proxy, "GET", "authinfo", headers=self.headers
)["id"]
def querylist(self, needtitle):
userid = self.userid
pagei = 1
collectresults = []
while True:
json_data = {
"user": userid,
"fields": (
"id, vn.title,vn.titles.title,vn.titles.main" if needtitle else "id"
),
"sort": "vote",
"results": 100,
"page": pagei,
}
pagei += 1
response = saferequestvndb(
self._ref.proxy, "POST", "ulist", json=json_data, headers=self.headers
)
collectresults += response["results"]
if not response["more"]:
break
return collectresults
def getalistname_download(self, uid):
reflist = getreflist(uid)
collectresults = self.querylist()
thislistvids = [
savehook_new_data[gameuid][self._ref.idname] for gameuid in reflist
]
collect = {}
for gameuid in savehook_new_data:
vid = savehook_new_data[gameuid][self._ref.idname]
collect[vid] = gameuid
for item in collectresults:
title = item["name"]
vid = int(item["id"][1:])
if vid in thislistvids:
continue
if vid in collect:
gameuid = collect[vid]
else:
gameuid = initanewitem(f"bgm_{vid}_{time.time()}", title)
savehook_new_data[gameuid][self._ref.idname] = vid
gamdidchangedtask(self._ref.typename, self._ref.idname, gameuid)
reflist.insert(0, gameuid)
def getalistname_upload(self, uid):
reflist = getreflist(uid)
vids = [int(item["id"][1:]) for item in self.querylist(False)]
for gameuid in reflist:
vid = savehook_new_data[gameuid][self._ref.idname]
if vid == 0:
continue
if vid in vids:
continue
saferequestvndb(
self._ref.proxy,
"PATCH",
f"ulist/v{vid}",
json={
"labels_set": [1],
},
headers=self.headers,
)
def singleupload_existsoverride(self, gameuid):
vid = savehook_new_data[gameuid][self._ref.idname]
if not vid:
return
saferequestvndb(
self._ref.proxy,
"PATCH",
f"ulist/v{vid}",
json={
"labels_set": [1],
# "labels_unset": [1],
# "vote" :100
},
headers=self.headers,
)
def __getalistname(self, callback, _):
getalistname(self, callback)
def __init__(self, parent, _ref: common, gameuid: str) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
self._ref = _ref
self.resize(QSize(800, 10))
self.setWindowTitle("vndb")
fl = QFormLayout(self)
fl.addRow("Token", getlineedit(_ref.config, "Token"))
btn = QPushButton(_TR("上传游戏"))
btn.clicked.connect(
functools.partial(self.singleupload_existsoverride, gameuid)
)
fl.addRow(btn)
btn = QPushButton(_TR("上传游戏列表"))
btn.clicked.connect(
functools.partial(self.__getalistname, self.getalistname_upload)
)
fl.addRow(btn)
btn = QPushButton(_TR("获取游戏列表"))
btn.clicked.connect(
functools.partial(self.__getalistname, self.getalistname_download)
)
fl.addRow(btn)
self.show()
class searcher(common):
def querysettingwindow(self, parent, gameuid):
vndbsettings(parent, self, gameuid)
def refmainpage(self, _id):
return f"https://vndb.org/v{_id}"

View File

@ -245,22 +245,25 @@ def everymethodsthread():
print_exc()
def gamdidchangedtask(key, idname, gameuid):
vid = savehook_new_data[gameuid][idname]
def idtypecheck(key, idname, gameuid, vid):
if vid == "":
return
else:
try:
if globalconfig["metadata"][key]["idtype"] == 0:
try:
vid = int(vid)
except:
print(vid)
return
savehook_new_data[gameuid][idname] = vid
searchvndbqueue.put((1, gameuid, (key, vid)), 1)
except:
print_exc()
try:
if globalconfig["metadata"][key]["idtype"] == 0:
try:
vid = int(vid)
except:
print(vid)
return
savehook_new_data[gameuid][idname] = vid
except:
print_exc()
def gamdidchangedtask(key, idname, gameuid):
vid = savehook_new_data[gameuid][idname]
searchvndbqueue.put((1, gameuid, (key, vid)), 1)
def titlechangedtask(gameuid, title):
@ -269,13 +272,17 @@ def titlechangedtask(gameuid, title):
searchvndbqueue.put((0, gameuid, [title]), 1)
def initanewitem(gamepath, title):
uid = f"{time.time()}_{uuid.uuid4()}"
gamepath2uid[gamepath] = uid
savehook_new_data[uid] = getdefaultsavehook(gamepath, title)
uid2gamepath[uid] = gamepath
return uid
def checkifnewgame(targetlist, gamepath, title=None):
if gamepath not in gamepath2uid:
uid = f"{time.time()}_{uuid.uuid4()}"
gamepath2uid[gamepath] = uid
savehook_new_data[uid] = getdefaultsavehook(gamepath, title)
uid2gamepath[uid] = gamepath
uid = initanewitem(gamepath, title)
searchvndbqueue.put((0, uid, [title] + guessmaybetitle(gamepath, title)))
else:
uid = gamepath2uid[gamepath]

View File

@ -19,13 +19,24 @@ def Singleton_impl(cls, behavior="activate"):
def _singleton(*args, **kwagrs):
if _lock.locked():
if cls not in _instance: # __init__很慢来不及放入_instance
pass
return
elif behavior == "activate":
_instance[cls].activateWindow()
_instance[cls].show()
try:
_instance[cls].activateWindow()
_instance[cls].show()
return
except:
# 父类被销毁
_lock.release()
pass
elif behavior == "close":
_instance[cls].close()
return
try:
_instance[cls].close()
return
except:
_lock.release()
pass
_lock.acquire()
class __(cls):
@ -43,6 +54,7 @@ def Singleton_impl(cls, behavior="activate"):
self.deleteLater()
_instance.pop(cls)
_lock.release()
try:
_inst = __(*args, **kwagrs)
except:

View File

@ -4,9 +4,11 @@ from collections import OrderedDict
from urllib.parse import urlencode, urlsplit
from functools import partial
class NetWorkException(Exception):
pass
class Timeout(NetWorkException):
pass
@ -352,6 +354,12 @@ class Sessionbase:
def options(self, url, **kwargs):
return self.request("OPTIONS", url, **kwargs)
def patch(self, url, **kwargs):
return self.request("PATCH", url, **kwargs)
def delete(self, url, **kwargs):
return self.request("DELETE", url, **kwargs)
Sessionimpl = [Sessionbase]
@ -369,3 +377,5 @@ def session():
get = partial(request, "GET")
post = partial(request, "POST")
options = partial(request, "OPTIONS")
patch = partial(request, "PATCH")
delete = partial(request, "DELETE")

View File

@ -1,5 +1,5 @@
from myutils.config import noundictconfig
import gobject, re
import gobject, re, functools
from qtsymbols import *
from traceback import print_exc
from myutils.config import (
@ -9,15 +9,45 @@ from myutils.config import (
)
import gobject
from gui.usefulwidget import getQMessageBox, threebuttons
from myutils.wrapper import Singleton
from myutils.wrapper import Singleton_close
@Singleton
@Singleton_close
class noundictconfigdialog(QDialog):
def closeEvent(self, a0: QCloseEvent) -> None:
self.button.setFocus()
self.apply()
def showmenu(self, table: QTableView, pos):
r = table.currentIndex().row()
if r < 0:
return
menu = QMenu(table)
up = QAction(_TR("上移"))
down = QAction(_TR("下移"))
menu.addAction(up)
menu.addAction(down)
action = menu.exec(table.cursor().pos())
if action == up:
self.moverank(table, -1)
elif action == down:
self.moverank(table, 1)
def moverank(self, table: QTableView, dy):
curr = table.currentIndex()
target = (curr.row() + dy) % table.model().rowCount()
texts = [
table.model().item(curr.row(), i).text()
for i in range(table.model().columnCount())
]
table.model().removeRow(curr.row())
table.model().insertRow(target, [QStandardItem(text) for text in texts])
table.setCurrentIndex(table.model().index(target, curr.column()))
def apply(self):
rows = self.model.rowCount()
newdict = {}
@ -64,9 +94,12 @@ class noundictconfigdialog(QDialog):
table = QTableView(self)
table.setModel(model)
table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
# table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
# table.clicked.connect(self.show_info)
button = threebuttons()
table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
table.customContextMenuRequested.connect(
functools.partial(self.showmenu, table)
)
button = threebuttons(texts=["添加行", "删除行", "上移", "下移", "立即应用"])
self.table = table
def clicked1():
try:
@ -84,19 +117,31 @@ class noundictconfigdialog(QDialog):
def clicked2():
model.removeRow(table.currentIndex().row())
skip = []
for index in self.table.selectedIndexes():
if index.row() in skip:
continue
skip.append(index.row())
skip = reversed(sorted(skip))
for row in skip:
model.removeRow(row)
button.btn2clicked.connect(clicked2)
button.btn3clicked.connect(self.apply)
button5 = QPushButton(self)
button5.setText(_TR("设置所有词条为全局词条"))
button.btn3clicked.connect(functools.partial(self.moverank, table, -1))
button.btn4clicked.connect(functools.partial(self.moverank, table, 1))
button.btn5clicked.connect(self.apply)
button2 = threebuttons(
texts=["设置所有词条为全局词条", "以当前md5复制选中行"]
)
def clicked5():
rows = model.rowCount()
for row in range(rows):
model.item(row, 0).setText("0")
button5.clicked.connect(
button2.btn1clicked.connect(
lambda: getQMessageBox(
self,
"警告",
@ -107,6 +152,8 @@ class noundictconfigdialog(QDialog):
)
)
button2.btn2clicked.connect(self.copysetmd5)
search = QHBoxLayout()
searchcontent = QLineEdit()
search.addWidget(searchcontent)
@ -132,7 +179,7 @@ class noundictconfigdialog(QDialog):
formLayout.addWidget(table)
formLayout.addLayout(search)
formLayout.addWidget(button)
formLayout.addWidget(button5)
formLayout.addWidget(button2)
setmd5layout = QHBoxLayout()
setmd5layout.addWidget(QLabel(_TR("当前MD5")))
md5content = QLineEdit(gobject.baseobject.currentmd5)
@ -150,6 +197,25 @@ class noundictconfigdialog(QDialog):
self.resize(QSize(600, 400))
self.show()
def copysetmd5(self):
if len(self.table.selectedIndexes()) == 0:
return
md5 = gobject.baseobject.currentmd5
row = self.table.selectedIndexes()[0].row()
skip = []
for index in self.table.selectedIndexes():
if index.row() in skip:
continue
skip.append(index.row())
self.model.insertRow(
row,
[
QStandardItem(md5),
QStandardItem(self.model.item(index.row(), 1).text()),
QStandardItem(self.model.item(index.row(), 2).text()),
],
)
class Process:
@staticmethod

View File

@ -235,7 +235,10 @@
"downloadtasks": [],
"useproxy": false,
"target": "vid",
"idtype": 0
"idtype": 0,
"args": {
"Token": ""
}
},
"dlsite": {
"name": "dlsite",

View File

@ -812,5 +812,9 @@
"论坛": "المنتديات",
"请选择": "الرجاء اختيار",
"安装成功": "تثبيت بنجاح",
"添加成功": "إضافة ناجحة"
"添加成功": "إضافة ناجحة",
"获取游戏列表": "الحصول على قائمة الألعاب",
"上传游戏列表": "تحميل قائمة الألعاب",
"上传游戏": "تحميل العاب",
"以当前md5复制选中行": "حدد صف مع نسخة MD5 الحالي"
}

View File

@ -812,5 +812,9 @@
"论坛": "論壇",
"请选择": "請選擇",
"安装成功": "安裝成功",
"添加成功": "添加成功"
"添加成功": "添加成功",
"获取游戏列表": "獲取遊戲清單",
"上传游戏列表": "上傳遊戲清單",
"上传游戏": "上傳遊戲",
"以当前md5复制选中行": "以當前md5複製選中行"
}

View File

@ -812,5 +812,9 @@
"论坛": "forum",
"请选择": "Please select",
"安装成功": "Installation successful",
"添加成功": "Successfully added"
"添加成功": "Successfully added",
"获取游戏列表": "Get game list",
"上传游戏列表": "Upload game list",
"上传游戏": "Upload game",
"以当前md5复制选中行": "Copy the selected row with the current MD5"
}

View File

@ -812,5 +812,9 @@
"论坛": "Foro",
"请选择": "Por favor, elija",
"安装成功": "Instalación exitosa",
"添加成功": "Se agregó con éxito"
"添加成功": "Se agregó con éxito",
"获取游戏列表": "Obtener la lista de juegos",
"上传游戏列表": "Subir la lista de juegos",
"上传游戏": "Sube el juego",
"以当前md5复制选中行": "Copiar la línea seleccionada con el MD5 actual"
}

View File

@ -812,5 +812,9 @@
"论坛": "Le Forum",
"请选择": "Veuillez sélectionner",
"安装成功": "Installation réussie",
"添加成功": "Ajouté avec succès"
"添加成功": "Ajouté avec succès",
"获取游戏列表": "Obtenir une liste de jeux",
"上传游戏列表": "Télécharger une liste de jeux",
"上传游戏": "Télécharger un jeu",
"以当前md5复制选中行": "Copier la ligne sélectionnée avec le MD5 actuel"
}

View File

@ -812,5 +812,9 @@
"论坛": "forum",
"请选择": "Seleziona",
"安装成功": "Installazione riuscita",
"添加成功": "Aggiunta con successo"
"添加成功": "Aggiunta con successo",
"获取游戏列表": "Ottieni la lista dei giochi",
"上传游戏列表": "Carica la lista dei giochi",
"上传游戏": "Carica gioco",
"以当前md5复制选中行": "Copia la riga selezionata con l'MD5 corrente"
}

View File

@ -812,5 +812,9 @@
"论坛": "フォーラム",
"请选择": "選択してください",
"安装成功": "インストールに成功しました",
"添加成功": "追加成功"
"添加成功": "追加成功",
"获取游戏列表": "ゲームリストの取得",
"上传游戏列表": "ゲームリストをアップロード",
"上传游戏": "ゲームをアップロード",
"以当前md5复制选中行": "選択した行を現在のmd 5でコピー"
}

View File

@ -812,5 +812,9 @@
"论坛": "포럼",
"请选择": "선택하십시오.",
"安装成功": "설치 성공",
"添加成功": "추가 성공"
"添加成功": "추가 성공",
"获取游戏列表": "게임 목록 가져오기",
"上传游戏列表": "게임 목록 업로드",
"上传游戏": "게임 업로드",
"以当前md5复制选中行": "선택된 행을 현재 md5로 복사"
}

View File

@ -812,5 +812,9 @@
"论坛": "forum",
"请选择": "Proszę wybrać",
"安装成功": "Instalacja pomyślna",
"添加成功": "Dodano pomyślnie"
"添加成功": "Dodano pomyślnie",
"获取游戏列表": "Pobierz listę gier",
"上传游戏列表": "Wyślij listę gier",
"上传游戏": "Przesyłaj grę",
"以当前md5复制选中行": "Kopiuj zaznaczony wiersz z bieżącym MD5"
}

View File

@ -812,5 +812,9 @@
"论坛": "Форум",
"请选择": "Выберите",
"安装成功": "Установка прошла успешно",
"添加成功": "Добавить успех"
"添加成功": "Добавить успех",
"获取游戏列表": "Получить список игр",
"上传游戏列表": "Загрузить список игр",
"上传游戏": "Загрузить игру",
"以当前md5复制选中行": "Копировать выделенную строку в текущем MD5"
}

View File

@ -812,5 +812,9 @@
"论坛": "ฟอรั่ม",
"请选择": "กรุณาเลือก",
"安装成功": "ติดตั้งสำเร็จ",
"添加成功": "เพิ่มความสำเร็จ"
"添加成功": "เพิ่มความสำเร็จ",
"获取游戏列表": "รับรายการเกม",
"上传游戏列表": "อัปโหลดรายการเกม",
"上传游戏": "อัปโหลดเกม",
"以当前md5复制选中行": "คัดลอกแถวที่เลือกด้วย md5 ปัจจุบัน"
}

View File

@ -812,5 +812,9 @@
"论坛": "forum",
"请选择": "Lütfen seçin",
"安装成功": "Yükleme başarılı",
"添加成功": "Başarılı eklendi"
"添加成功": "Başarılı eklendi",
"获取游戏列表": "Oyun listesini alın",
"上传游戏列表": "Oyun listesini yükle",
"上传游戏": "Oyunu yükle",
"以当前md5复制选中行": "Seçili satırı mevcut MD5 ile kopyalayın"
}

View File

@ -812,5 +812,9 @@
"论坛": "форум",
"请选择": "Будь ласка, виберіть",
"安装成功": "Встановлення успішно",
"添加成功": "Успішно додано"
"添加成功": "Успішно додано",
"获取游戏列表": "Отримати список гри",
"上传游戏列表": "Вивантажити список гр",
"上传游戏": "Вивантажити гру",
"以当前md5复制选中行": "Копіювати вибраний рядок поточним MD5"
}

View File

@ -812,5 +812,9 @@
"论坛": "Diễn đàn",
"请选择": "Vui lòng chọn",
"安装成功": "Cài đặt thành công",
"添加成功": "Thêm thành công"
"添加成功": "Thêm thành công",
"获取游戏列表": "Nhận danh sách trò chơi",
"上传游戏列表": "Tải lên danh sách trò chơi",
"上传游戏": "Tải lên trò chơi",
"以当前md5复制选中行": "Dòng đã chọn sao chép md5 hiện tại"
}

View File

@ -812,5 +812,9 @@
"论坛": "",
"请选择": "",
"安装成功": "",
"添加成功": ""
"添加成功": "",
"获取游戏列表": "",
"上传游戏列表": "",
"上传游戏": "",
"以当前md5复制选中行": ""
}

View File

@ -29,7 +29,7 @@ include(generate_product_version)
set(VERSION_MAJOR 5)
set(VERSION_MINOR 3)
set(VERSION_PATCH 1)
set(VERSION_PATCH 2)
add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h)