Skip to content

Commit e93964c

Browse files
authored
Merge-build: v2.7.0
2 parents 6a1d02f + 1668f6f commit e93964c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+13695
-8092
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ analyze/
174174
*.d
175175
*.zip
176176
*.psd
177+
*.clip
177178
*demo*.py
178179
__temp
179180
test/*

ComicSpider/middlewares.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,17 @@ def process_request(self, request, spider):
129129

130130

131131
class ComicDlProxyMiddleware(ComicspiderDownloaderMiddleware):
132-
"""使用情况是“通常页需要over wall访问”,“图源cn就能访问”... 因此domain的都使用代理"""
132+
"""使用情况是"通常页需要over wall访问","图源cn就能访问"... 因此domain的都使用代理
133+
Spider 可定义 proxy_domains 列表指定需要代理的域名,未定义则回退到 domain
134+
"""
133135
domain_regex: re.Pattern = None
134136

135137
@classmethod
136138
def from_crawler(cls, crawler):
137139
_ = super(ComicDlProxyMiddleware, cls).from_crawler(crawler)
138-
_.domain_regex = re.compile(crawler.spider.domain)
140+
spider = crawler.spider
141+
domains = getattr(spider, 'proxy_domains', None) or [spider.domain]
142+
_.domain_regex = re.compile('|'.join(re.escape(d) for d in domains))
139143
return _
140144

141145
def process_request(self, request, spider):

ComicSpider/pipelines.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,8 @@ def file_folder(self, basepath, section, spider, title, item):
7171

7272
os.makedirs(path, exist_ok=True)
7373
tasks_obj = spider.tasks.get(uuid_md5)
74-
if tasks_obj and getattr(tasks_obj, 'comic_info', None):
75-
comic_info_path = path.joinpath("ComicInfo.xml")
76-
if not comic_info_path.exists():
77-
with open(comic_info_path, 'w', encoding='utf-8') as f:
78-
f.write(tasks_obj.comic_info.out)
74+
if tasks_obj and getattr(tasks_obj, 'meta_info', None):
75+
tasks_obj.meta_info.sv_meta_in(path)
7976

8077
spider.tasks_path[uuid_md5] = path
8178
return path
@@ -98,6 +95,9 @@ def handle_task(spider, stats, task_obj):
9895
_tasks.downloaded.append(task_obj)
9996
curr_progress = int(len(_tasks.downloaded) / _tasks.tasks_count * 100)
10097
if conf.isDeduplicate and curr_progress >= 100:
98+
tasks_obj = spider.tasks[task_obj.taskid]
99+
if getattr(tasks_obj, 'meta_info', None):
100+
tasks_obj.meta_info.fin_callback(spider.tasks_path[tasks_obj.taskid])
101101
spider.sql_handler.add(task_obj.taskid)
102102
spider.Q('TasksQueue').send(task_obj, wait=True)
103103
stats.inc_value('image/downloaded')

ComicSpider/spiders/basecomicspider.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def parse_section(self, response):
233233
for ep in book.episodes:
234234
url_list = self.mk_page_tasks(url=ep.url)
235235
now_start_crawl_desc = self.res.parse_sec_now_start_crawl_desc % book.name
236-
self.say(font_color(f"📢 {now_start_crawl_desc}{ep}", cls='theme-tip', size=5))
236+
self.say(font_color(f"📢\t{now_start_crawl_desc}{ep}", cls='theme-tip', size=5))
237237
for url in url_list:
238238
yield scrapy.Request(url=url, callback=self.parse_fin_page, meta={'ep': ep})
239239

@@ -258,9 +258,8 @@ def mk_page_tasks(self, *arg, **kw) -> iter:
258258
return [kw['url']]
259259

260260
def set_task(self, task_info: t.Union[BookInfo, Episode]):
261-
comic_info_obj = self.mr.out(task_info)
262261
tasks_obj = task_info.to_tasks_obj()
263-
tasks_obj.comic_info = comic_info_obj
262+
tasks_obj.meta_info = self.mr.toMetaInfo(task_info)
264263
self.tasks[tasks_obj.taskid] = tasks_obj
265264
self.Q('TasksQueue').send(tasks_obj, wait=True)
266265

@@ -298,7 +297,7 @@ def from_crawler(cls, crawler, *args, **kwargs):
298297
spider.say = SayToGui(spider, q, spider.text_browser_state)
299298
spider.sql_handler = SqlUtils()
300299
spider.ut = spider_utils_map[spider.name]
301-
spider.mr = MetaRecorder()
300+
spider.mr = MetaRecorder(conf)
302301
return spider
303302

304303
def _remove_cache(self):
@@ -329,7 +328,7 @@ def close(self, reason):
329328

330329
def _handle_finished_status(self, stats):
331330
if 'init' in self.process_state.process:
332-
self.say(font_color('unknown init end,<br>if error occur, please contact maintainer with operation-process', cls='theme-err', size=6))
331+
self.say(font_color('unknown init end, if cgs not work, please contact maintainer with log', cls='theme-tip'))
333332
return
334333
downloaded_count = stats.get_value('image/downloaded', 0)
335334
exception_count = stats.get_value('process_exception/count', 0)

ComicSpider/spiders/kaobei.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class KaobeiSpider(BaseComicSpider):
5353
'Accept': '*/*',
5454
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
5555
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
56-
'dnts': '2',
56+
'dnts': '3',
5757
'Connection': 'keep-alive',
5858
'Sec-Fetch-Dest': 'empty',
5959
'Sec-Fetch-Mode': 'cors',
@@ -75,6 +75,7 @@ class KaobeiSpider(BaseComicSpider):
7575
}
7676
domain = domain
7777
pc_domain = pc_domain
78+
proxy_domains = [domain, pc_domain] # 需要代理的域名列表
7879
custom_settings = {
7980
"DOWNLOADER_MIDDLEWARES": {'ComicSpider.middlewares.UAKaobeiMiddleware': 5,
8081
'ComicSpider.middlewares.ComicDlProxyMiddleware': 6},

GUI/browser_window.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,15 @@ def setupUi(self, _window):
8484
self.set_btn()
8585
self.set_html()
8686
self.patch_tip()
87-
FluentMonkeyPatch.rbutton_menu_WebEngine(self)
87+
if self.is_publish_page():
88+
FluentMonkeyPatch.rbutton_menu_PulishPage(self)
89+
else:
90+
FluentMonkeyPatch.rbutton_menu_WebEngine(self)
91+
92+
def is_publish_page(self) -> bool:
93+
if hasattr(self.gui, 'tf') and self.gui.tf:
94+
return 'publish' in str(self.gui.tf).lower()
95+
return False
8896

8997
def patch_tip(self):
9098
for button in (self.topHintBox, self.homeBtn, self.backBtn, self.forwardBtn, self.refreshBtn, self.copyBtn, self.ensureBtn):
@@ -135,8 +143,9 @@ def second_init(self):
135143
self.home_url = QUrl.fromLocalFile(self.gui.tf)
136144
self.load_home()
137145

138-
def keep_top_hint(self):
139-
if self.topHintBox.isChecked():
146+
def keep_top_hint(self, _flag: bool = None):
147+
flag = _flag if _flag is not None else self.topHintBox.isChecked()
148+
if flag:
140149
self.setWindowFlags(Qt.WindowStaysOnTopHint)
141150
else:
142151
self.setWindowFlags(Qt.Widget)

GUI/conf_dialog.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from PyQt5.QtCore import QUrl, Qt
1414
from qfluentwidgets import (
1515
FluentIcon as FIF, PushButton, PrimaryPushButton, TransparentPushButton,
16-
PushSettingCard, InfoBarPosition, TransparentToggleToolButton, InfoBar
16+
PushSettingCard, InfoBarPosition, TransparentToggleToolButton, InfoBar, ComboBox
1717
)
1818
import uncurl
1919

@@ -69,12 +69,18 @@ def setupUi(self, Dialog):
6969
self._repaint_textEdit()
7070

7171
def retranslateUiAgain(self, Dialog):
72+
self.langBox = ComboBox(Dialog)
73+
self.langBox.setObjectName("langBox")
74+
self.langBox.setCurrentIndex(-1)
75+
self.pypiSourceBox = ComboBox(Dialog)
76+
self.pypiSourceBox.setObjectName("pypiSourceBox")
7277
_translate = QtCore.QCoreApplication.translate
7378
self.label_2.setText(_translate("Dialog", res.GUI.Uic.confDia_labelLogLevel))
7479
self.label_4.setText(_translate("Dialog", res.GUI.Uic.confDia_labelProxy))
7580
self.label_completer.setText(_translate("Dialog", res.GUI.Uic.confDia_labelPreset))
7681
self.label_6.setText(_translate("Dialog", res.GUI.Uic.confDia_labelClipDb))
7782
self.label_7.setText(_translate("Dialog", res.GUI.Uic.confDia_labelClipNum))
83+
self.metaTypeLabel.setText(_translate("Dialog", res.GUI.Uic.confDia_metaType))
7884
self.concurr_numLabel.setText(_translate("Dialog", res.GUI.Uic.confDia_labelConcurrNum))
7985
# 添加cookie类型选项
8086
support = list(COOKIES_PLACEHOLDER.keys())
@@ -88,6 +94,11 @@ def retranslateUiAgain(self, Dialog):
8894
self.pypiSourceBox.setItemText(1, _translate("Dialog", "清华源"))
8995
self.pypiSourceBox.setItemText(2, _translate("Dialog", "阿里源"))
9096
self.pypiSourceBox.setItemText(3, _translate("Dialog", "华为源"))
97+
self.metaTypeBox.addItem("")
98+
self.metaTypeBox.addItem("")
99+
self.metaTypeBox.setItemText(0, _translate("Dialog", "-"))
100+
self.metaTypeBox.setItemText(1, _translate("Dialog", "ComicInfo.xml"))
101+
self.metaTypeBox.setCurrentIndex(0)
91102
self.cookiesBox.setCurrentText(support[0])
92103

93104
for k, ui_key in LANG.items():
@@ -182,6 +193,19 @@ def _tip_lang_change(idx):
182193
duration=5000, parent=self
183194
)
184195
self.langBox.activated.connect(_tip_lang_change)
196+
def _tip_meta_change(idx):
197+
match self.metaTypeBox.itemText(idx):
198+
case "ComicInfo.xml":
199+
_meta_tip = "适配平台例如:ComicRack, Komga, kavita"
200+
case _:
201+
_meta_tip = ""
202+
if _meta_tip:
203+
InfoBar.success(
204+
title="", content=_meta_tip,
205+
orient=Qt.Horizontal, isClosable=True, position=InfoBarPosition.TOP,
206+
duration=5000, parent=self
207+
)
208+
self.metaTypeBox.activated.connect(_tip_meta_change)
185209
self.cookiesBox.currentTextChanged.connect(self._on_cookie_type_changed)
186210
def _tip_on(is_checked: bool, tip_content=None):
187211
if is_checked:
@@ -213,6 +237,7 @@ def show_self(self): # can't naming `show`. If done, just run code once
213237
self.logLevelComboBox.setCurrentIndex(self.logLevelComboBox.findText(getattr(conf, "log_level")))
214238
self.pypiSourceBox.setCurrentIndex(getattr(conf, "pypi_source"))
215239
self.langBox.setCurrentIndex(self.langBox.findData(getattr(conf, "lang")))
240+
self.metaTypeBox.setCurrentIndex(self.metaTypeBox.findText(getattr(conf, "meta_type")))
216241
# 仅当 初次confdia ui创建 & conf值设入ui后,才绑定槽函数
217242
if self._init_flag:
218243
self.bind_logic()
@@ -254,6 +279,7 @@ def save_conf(self):
254279
"sv_path": sv_path,
255280
"log_level": getattr(self, "logLevelComboBox").currentText(),
256281
"lang": getattr(self, "langBox").currentData(),
282+
"meta_type": getattr(self, "metaTypeBox").currentText(),
257283
"concurr_num": getattr(self, "concurr_numEdit").value(),
258284
"isDeduplicate": getattr(self, "isDeduplicate").isChecked(),
259285
"addUuid": getattr(self, "addUuid").isChecked(),

GUI/gui.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import traceback
66
from multiprocessing import Process
77
import multiprocessing.managers as m
8-
from PyQt5.QtGui import QKeySequence
8+
from PyQt5.QtGui import QKeySequence, QGuiApplication
99
from PyQt5.QtCore import QThread, Qt, QCoreApplication, QRect, QTimer
1010
from PyQt5.QtWidgets import QMainWindow, QCompleter, QShortcut
1111

@@ -18,16 +18,17 @@
1818
from GUI.conf_dialog import ConfDialog
1919
from GUI.browser_window import BrowserWindow as BrowserWindowCls
2020
from GUI.thread import WorkThread, QueueInitThread
21-
from GUI.tools import ToolWindow, TextUtils
21+
from GUI.tools import ToolWindow, TextUtils, DomainToolView
2222
from GUI.manager import TaskProgressManager, ClipGUIManager, AggrSearchManager
2323
from GUI.manager.preprocess import PreprocessManager
24+
from GUI.uic.qfluent import CustomFlyout
2425
from variables import *
2526
from assets import res
26-
from utils import Queues, QueuesManager, conf, p, curr_os, select
27+
from utils import Queues, QueuesManager, conf, p, curr_os, select, ori_path, bs_theme
2728
from utils.processed_class import (
2829
InputFieldState, TextBrowserState, ProcessState,
2930
GuiQueuesManger, refresh_state, crawl_what,
30-
PreviewHtml
31+
PreviewHtml, TmpFormatHtml
3132
)
3233
from utils.website import spider_utils_map, InfoMinix
3334
from utils.sql import SqlUtils
@@ -584,3 +585,24 @@ def hook_exception(self, exc_type, exc_value, exc_traceback):
584585
self.log.error(exception)
585586
self.say(font_color(rf"{type(exc_value)}{exc_value}", cls='theme-err', size=4), ignore_http=True)
586587
self.say(font_color(rf"<br>{self.res.global_err_hook} <br>[{conf.log_path}\GUI.log]<br>", cls='theme-err', size=5))
588+
589+
def do_publish(self):
590+
with open(ori_path.joinpath('assets/pubilsh_helper.html')) as f:
591+
format_text = f.read()
592+
html = format_text.replace("{bs_theme}", bs_theme()) \
593+
.replace("{publish_url}", self.spiderUtils.publish_url)
594+
self.tf = TmpFormatHtml.created_temp_html(html, flag="publish")
595+
self.set_preview()
596+
screen_width = QGuiApplication.primaryScreen().availableGeometry().width()
597+
o_w, o_h = self.BrowserWindow.width(), self.BrowserWindow.height()
598+
if o_w < screen_width * 0.75:
599+
o_w = int(screen_width * 0.75)
600+
self.BrowserWindow.resize(o_w, o_h+150)
601+
self.BrowserWindow.show()
602+
603+
def tpd(self, texts):
604+
self.BrowserWindow.domain_v = DomainToolView(self)
605+
CustomFlyout.make(
606+
view=self.BrowserWindow.domain_v, target=self.BrowserWindow, parent=self.BrowserWindow
607+
)
608+
self.BrowserWindow.domain_v.handle(texts)

GUI/manager/preprocess.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ def handle_choosebox_changed(self, index: int):
3939
self._preprocess_jm()
4040
else:
4141
self.gui.say("🔔 已设置代理,跳过域名缓存处理")
42-
self.gui.toolWin.addDomainTool()
4342
self.gui.toolWin.addAggrSearchView()
4443
case 4:
4544
self._preprocess_ehentai()
@@ -88,14 +87,14 @@ def on_success(_):
8887

8988
def on_error(_):
9089
self.gui.disable_start()
91-
self.gui.say("<br>❌ 域名获取/测试失效,点击 rV按钮 > domainTool, 按指示操作")
90+
self.gui.say("<br>❌ 域名获取/测试失效,按内置浏览器引导操作")
91+
self.gui.do_publish()
9292

9393
self.task_manager.execute_simple_task(
9494
task_func=task,
9595
success_callback=on_success, show_error_info=self.show_err, error_callback=on_error,
9696
tooltip_title="更新域名缓存", task_id="domain_preprocess"
9797
)
98-
self.gui.toolWin.addDomainTool()
9998
self.gui.toolWin.addAggrSearchView()
10099

101100
def _preprocess_ehentai(self):

0 commit comments

Comments
 (0)