Skip to content

Commit ee23037

Browse files
authored
v2.5.8: 新增插件【订阅本子更新插件】,可以自动订阅本子的章节更新,并下载和发送邮件通知; 优化代码。 (#216)
1 parent 147c796 commit ee23037

File tree

7 files changed

+92
-14
lines changed

7 files changed

+92
-14
lines changed

assets/docs/sources/option_file_syntax.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
因此,在配置option时,不需要配置全部的值,只需要配置特定部分即可。
88
* 你可以使用下面的代码来得到option的默认值,你可以删除其中的大部分配置项,只保留你要覆盖的配置项
99

10+
* **下面的插件配置,kwargs参数支持引用环境变量,语法为 ${环境变量名}**
11+
1012
```python
1113
from jmcomic import JmOption
1214
JmOption.default().to_file('./option.yml') # 创建默认option,导出为option.yml文件
@@ -84,6 +86,8 @@ download:
8486
# 文件夹规则配置,决定图片文件存放在你的电脑上的哪个文件夹
8587
dir_rule:
8688
# base_dir: 根目录。
89+
# 此配置也支持引用环境变量,例如
90+
# base_dir: ${JM_DIR}/下载文件夹/
8791
base_dir: D:/a/b/c/
8892

8993
# rule: 规则dsl。
@@ -106,7 +110,6 @@ dir_rule:
106110
107111
```yml
108112
# 插件的配置示例
109-
# 当kwargs的值为字符串类型时,支持使用环境变量,语法为 ${环境变量名}
110113
plugins:
111114
after_init:
112115
- plugin: usage_log # 实时打印硬件占用率的插件
@@ -160,6 +163,18 @@ plugins:
160163
bg.jpg: D:/浏览器的背景图
161164
m_bg.jpeg: D:/移动设备浏览器的背景图
162165

166+
- plugin: subscribe_album_update # 自动订阅本子并下载、发送邮件通知的插件
167+
kwargs:
168+
download_if_has_update: true
169+
email_notify: # 见下【发送qq邮件插件】
170+
msg_from: x
171+
msg_to: x
172+
password: x
173+
title: album update !!!
174+
content: album update !!!
175+
album_photo_dict:
176+
324930: 424507
177+
163178
after_album:
164179
- plugin: zip # 压缩文件插件
165180
kwargs:

src/jmcomic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# 被依赖方 <--- 使用方
33
# config <--- entity <--- toolkit <--- client <--- option <--- downloader
44

5-
__version__ = '2.5.7'
5+
__version__ = '2.5.8'
66

77
from .api import *
88
from .jm_plugin import *

src/jmcomic/jm_client_interface.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ def json(self) -> Dict:
8888
except Exception as e:
8989
ExceptionTool.raises_resp(f'json解析失败: {e}', self, JsonResolveFailException)
9090

91-
def model(self) -> AdvancedEasyAccessDict:
92-
return AdvancedEasyAccessDict(self.json())
91+
def model(self) -> AdvancedDict:
92+
return AdvancedDict(self.json())
9393

9494

9595
class JmApiResp(JmJsonResp):
@@ -118,9 +118,9 @@ def res_data(self) -> Any:
118118
return loads(self.decoded_data)
119119

120120
@property
121-
def model_data(self) -> AdvancedEasyAccessDict:
121+
def model_data(self) -> AdvancedDict:
122122
self.require_success()
123-
return AdvancedEasyAccessDict(self.res_data)
123+
return AdvancedDict(self.res_data)
124124

125125

126126
# album-comment

src/jmcomic/jm_exception.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ def __init__(self, msg: str, context: dict):
1212
def from_context(self, key):
1313
return self.context[key]
1414

15+
def __str__(self):
16+
return self.msg
1517

1618
class ResponseUnexpectedException(JmcomicException):
1719
description = '响应不符合预期异常'

src/jmcomic/jm_option.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,11 @@ def __init__(self,
197197
# 路径规则配置
198198
self.dir_rule = DirRule(**dir_rule)
199199
# 客户端配置
200-
self.client = AdvancedEasyAccessDict(client)
200+
self.client = AdvancedDict(client)
201201
# 下载配置
202-
self.download = AdvancedEasyAccessDict(download)
202+
self.download = AdvancedDict(download)
203203
# 插件配置
204-
self.plugins = AdvancedEasyAccessDict(plugins)
204+
self.plugins = AdvancedDict(plugins)
205205
# 其他配置
206206
self.filepath = filepath
207207

@@ -376,6 +376,7 @@ def deconstruct(self) -> Dict:
376376
@classmethod
377377
def from_file(cls, filepath: str) -> 'JmOption':
378378
dic: dict = PackerUtil.unpack(filepath)[0]
379+
dic.setdefault('filepath', filepath)
379380
return cls.construct(dic)
380381

381382
def to_file(self, filepath=None):

src/jmcomic/jm_plugin.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,3 +903,63 @@ def build(cls, option: JmOption) -> 'JmOptionPlugin':
903903
instance = JmServerPlugin(option)
904904
setattr(cls, field_name, instance)
905905
return instance
906+
907+
908+
class SubscribeAlbumUpdatePlugin(JmOptionPlugin):
909+
plugin_key = 'subscribe_album_update'
910+
911+
def invoke(self,
912+
album_photo_dict=None,
913+
email_notify=None,
914+
download_if_has_update=True,
915+
auto_update_after_download=True,
916+
) -> None:
917+
if album_photo_dict is None:
918+
return
919+
920+
album_photo_dict: Dict
921+
for album_id, photo_id in album_photo_dict.copy().items():
922+
# check update
923+
try:
924+
has_update, photo_new_list = self.check_photo_update(album_id, photo_id)
925+
except JmcomicException as e:
926+
self.log('Exception happened: ' + str(e), 'check_update.error')
927+
continue
928+
929+
if has_update is False:
930+
continue
931+
932+
self.log(f'album={album_id},发现新章节: {photo_new_list},准备开始下载')
933+
934+
# send email
935+
try:
936+
if email_notify:
937+
SendQQEmailPlugin.build(self.option).invoke(**email_notify)
938+
except PluginValidationException:
939+
# ignore
940+
pass
941+
942+
# download new photo
943+
if has_update and download_if_has_update:
944+
self.option.download_photo(photo_new_list)
945+
946+
if auto_update_after_download:
947+
album_photo_dict[album_id] = photo_new_list[-1]
948+
self.option.to_file()
949+
950+
def check_photo_update(self, album_id: str, photo_id: str):
951+
client = self.option.new_jm_client()
952+
album = client.get_album_detail(album_id)
953+
954+
photo_new_list = []
955+
is_new_photo = False
956+
sentinel = int(photo_id)
957+
958+
for photo in album:
959+
if is_new_photo:
960+
photo_new_list.append(photo.photo_id)
961+
962+
if int(photo.photo_id) == sentinel:
963+
is_new_photo = True
964+
965+
return len(photo_new_list) != 0, photo_new_list

src/jmcomic/jm_toolkit.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ def parse_html_to_favorite_page(cls, html: str) -> JmFavoritePage:
472472
return JmFavoritePage(content, folder_list, total)
473473

474474
@classmethod
475-
def parse_api_to_search_page(cls, data: AdvancedEasyAccessDict) -> JmSearchPage:
475+
def parse_api_to_search_page(cls, data: AdvancedDict) -> JmSearchPage:
476476
"""
477477
model_data: {
478478
"search_query": "MANA",
@@ -501,7 +501,7 @@ def parse_api_to_search_page(cls, data: AdvancedEasyAccessDict) -> JmSearchPage:
501501
return JmSearchPage(content, total)
502502

503503
@classmethod
504-
def parse_api_to_favorite_page(cls, data: AdvancedEasyAccessDict) -> JmFavoritePage:
504+
def parse_api_to_favorite_page(cls, data: AdvancedDict) -> JmFavoritePage:
505505
"""
506506
{
507507
"list": [
@@ -546,7 +546,7 @@ def parse_api_to_favorite_page(cls, data: AdvancedEasyAccessDict) -> JmFavoriteP
546546

547547
@classmethod
548548
def adapt_content(cls, content):
549-
def adapt_item(item: AdvancedEasyAccessDict):
549+
def adapt_item(item: AdvancedDict):
550550
item: dict = item.src_dict
551551
item.setdefault('tags', [])
552552
return item
@@ -673,7 +673,7 @@ def post_adapt_album(cls, data: dict, _clazz: type, fields: dict):
673673
series = data['series']
674674
episode_list = []
675675
for chapter in series:
676-
chapter = AdvancedEasyAccessDict(chapter)
676+
chapter = AdvancedDict(chapter)
677677
# photo_id, photo_index, photo_title, photo_pub_date
678678
episode_list.append(
679679
(chapter.id, chapter.sort, chapter.name, None)
@@ -688,7 +688,7 @@ def post_adapt_photo(cls, data: dict, _clazz: type, fields: dict):
688688
sort = 1
689689
series: list = data['series'] # series中的sort从1开始
690690
for chapter in series:
691-
chapter = AdvancedEasyAccessDict(chapter)
691+
chapter = AdvancedDict(chapter)
692692
if int(chapter.id) == int(data['id']):
693693
sort = chapter.sort
694694
break

0 commit comments

Comments
 (0)