Skip to content

Commit f6f2d27

Browse files
authored
v2.2.9: 实现基于命令行的调用方式,更加简单易用,更新文档 (#133)
1 parent 05dcb7e commit f6f2d27

File tree

8 files changed

+166
-9
lines changed

8 files changed

+166
-9
lines changed

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,22 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
3737
# 如果你想要配置,请参考文件 assets/config/常用配置介绍.yml
3838
```
3939

40+
* v2.2.9: 新增命令行调用方式,上述的代码可以转为一行命令
41+
42+
```bash
43+
# 下载album_id为422866的本子
44+
$ jmcomic 422866
45+
# 更多用法请参考文件 usage/usage_cl.py (命令行使用介绍)
46+
```
47+
4048

4149

4250
## 进阶使用
4351

4452
进阶使用可以参考本repo下usage文件夹内的示例代码文件,下面是各个文件的作用,你可以挑感兴趣的阅读:
4553

4654
- API上手介绍: `getting_started.py`
55+
- 命令行使用介绍: `usage_cl.py`
4756
- 使用API实现简单功能: `usage_simple.py`
4857
- 演示jmcomic模块的可自定义功能点: `usage_custom.py`
4958
- 使用API的Filter过滤功能: `usage_feature_filter.py`
@@ -52,7 +61,6 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
5261
- 包括6个功能需求的介绍、实现方案和完整运行日志
5362
- 实现方案非常简洁,充分jmcomic的便利性,以及强大的插件扩展机制
5463

55-
5664
以及一些趣味用法:
5765

5866
- 测试你的ip可以访问哪些禁漫域名: `pick_domain.py`
@@ -63,10 +71,11 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
6371
## 项目特点
6472

6573
- **绕过Cloudflare的反爬虫**
74+
- 支持使用**命令行**下载本子,无需写Python代码,简单易用
6675
- 支持使用**GitHub Actions**下载本子,网页上直接输入本子id就能下载([教程:使用GitHub Actions下载禁漫本子](./assets/docs/教程:使用GitHub%20Actions下载禁漫本子.md)
6776
- **可配置性强**
6877
- 不配置也能使用,十分方便
69-
- 配置可以从**配置文件**生成,支持多种文件格式,无需写Python代码
78+
- 配置可以从**配置文件**生成,支持多种文件格式
7079
- 配置点有:`是否使用磁盘缓存` `并发下载图片数` `图片类型转换` `下载路径` `请求元信息(headers,cookies,proxies)`
7180
- **可扩展性强**
7281
- **支持Plugin插件,可以方便地扩展功能,以及使用别人的插件**
@@ -81,13 +90,15 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
8190

8291

8392

93+
8494
## 使用小说明
8595

8696
* Python >= 3.7
8797
* 个人项目,文档和示例会有不及时之处,可以Issue提问
8898

8999

90100

101+
91102
## 项目文件夹介绍
92103

93104
* assets:存放一些非代码的资源文件

setup.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,9 @@
4545
"Operating System :: POSIX :: Linux",
4646
"Operating System :: Microsoft :: Windows",
4747
],
48+
entry_points={
49+
'console_scripts': [
50+
'jmcomic = jmcomic:main'
51+
]
52+
}
4853
)

src/jmcomic/__init__.py

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

5-
__version__ = '2.2.8'
5+
__version__ = '2.2.9'
66

77
from .api import *
88
from .jm_plugin import *
9+
from .cl import main

src/jmcomic/cl.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
"""
2+
command-line usage
3+
4+
for example, download album 123 456, photo 333:
5+
6+
$ jmcomic 123 456 p333 --option="D:/option.yml"
7+
8+
9+
"""
10+
import os.path
11+
from typing import List
12+
13+
14+
def get_env(name, default):
15+
import os
16+
value = os.getenv(name, None)
17+
if value is None or value == '':
18+
return default
19+
20+
return value
21+
22+
23+
class JmcomicUI:
24+
25+
def __init__(self) -> None:
26+
self.option_path = None
27+
self.raw_id_list: List[str] = []
28+
self.album_id_list: List[str] = []
29+
self.photo_id_list: List[str] = []
30+
31+
def parse_arg(self):
32+
import argparse
33+
parser = argparse.ArgumentParser(prog='python -m jmcomic', description='JMComic Command Line Downloader')
34+
parser.add_argument(
35+
'id_list',
36+
nargs='*',
37+
help='input all album/photo ids that you want to download, separating them by spaces. '
38+
'Need add a "p" prefix to indicate a photo id, such as `123 456 p333`.',
39+
default=[],
40+
)
41+
42+
parser.add_argument(
43+
'--option',
44+
help='path to the option file, you can also specify it by env `JM_OPTION_PATH`',
45+
default=get_env('JM_OPTION_PATH', './option.yml'),
46+
)
47+
48+
args = parser.parse_args()
49+
self.option_path = os.path.abspath(args.option)
50+
self.raw_id_list = args.id_list
51+
52+
self.parse_raw_id()
53+
54+
def parse_raw_id(self):
55+
56+
def parse(text):
57+
from .jm_toolkit import JmcomicText
58+
59+
try:
60+
return JmcomicText.parse_to_album_id(text)
61+
except Exception as e:
62+
print(e.args[0])
63+
exit(1)
64+
65+
for raw_id in self.raw_id_list:
66+
if raw_id.startswith('p'):
67+
self.photo_id_list.append(parse(raw_id[1:]))
68+
elif raw_id.startswith('a'):
69+
self.album_id_list.append(parse(raw_id[1:]))
70+
else:
71+
self.album_id_list.append(parse(raw_id))
72+
73+
def main(self):
74+
self.parse_arg()
75+
from .api import jm_debug
76+
jm_debug('command_line',
77+
f'start downloading...\n'
78+
f'- using option: [{self.option_path}]\n'
79+
f'to be downloaded: \n'
80+
f'- album: {self.album_id_list}\n'
81+
f'- photo: {self.photo_id_list}')
82+
self.run()
83+
84+
def run(self):
85+
from .api import download_album, download_photo, create_option
86+
from common import MultiTaskLauncher
87+
88+
option = create_option(self.option_path)
89+
90+
if len(self.album_id_list) == 0:
91+
download_photo(self.photo_id_list, option)
92+
elif len(self.photo_id_list) == 0:
93+
download_album(self.album_id_list, option)
94+
else:
95+
# 同时下载album和photo
96+
launcher = MultiTaskLauncher()
97+
98+
launcher.create_task(
99+
target=download_album,
100+
args=(self.album_id_list, option)
101+
)
102+
launcher.create_task(
103+
target=download_photo,
104+
args=(self.photo_id_list, option)
105+
)
106+
107+
launcher.wait_finish()
108+
109+
110+
def main():
111+
JmcomicUI().main()

src/jmcomic/jm_config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ def option_default_dict(cls) -> dict:
271271
返回JmOption.default()的默认配置字典。
272272
这样做是为了支持外界自行覆盖option默认配置字典
273273
"""
274-
option_dict = cls.default_option_dict.copy()
274+
from copy import deepcopy
275+
276+
option_dict = deepcopy(cls.default_option_dict)
275277

276278
# debug
277279
if option_dict['debug'] is None:

src/jmcomic/jm_entity.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,14 +452,14 @@ def single_album(self) -> JmAlbumDetail:
452452

453453
@classmethod
454454
def wrap_single_album(cls, album: JmAlbumDetail) -> 'JmSearchPage':
455-
obj = JmSearchPage([(
455+
page = JmSearchPage([(
456456
album.album_id, {
457457
'name': album.title,
458458
'tag_list': album.tag_list,
459459
}
460460
)])
461-
setattr(obj, 'album', album)
462-
return obj
461+
setattr(page, 'album', album)
462+
return page
463463

464464
# 下面的方法实现方便的元素访问
465465

src/jmcomic/jm_toolkit.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
class JmcomicText:
77
pattern_jm_domain = compile('https://([\w.-]+)')
8-
pattern_jm_pa_id = compile('/(photos?|album)/(\d+)')
8+
pattern_jm_pa_id = compile('(photos?|album)/(\d+)')
99
pattern_html_jm_pub_domain = compile('[\w-]+\.\w+/?\w+')
1010

1111
pattern_html_photo_photo_id = compile('<meta property="og:url" content=".*?/photo/(\d+)/?.*?">')
@@ -264,7 +264,7 @@ def parse_html_to_page(cls, html: str) -> JmSearchPage:
264264
html = match[0]
265265

266266
# 提取结果
267-
content = [] # content这个名字来源于是api版搜索返回值
267+
content = [] # content这个名字来源于api版搜索返回值
268268
album_info_list = cls.pattern_html_search_album_info_list.findall(html)
269269

270270
for (album_id, title, _, label_category, label_sub, tag_text) in album_info_list:

usage/usage_cl.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
3+
使用命令行下载禁漫本子
4+
5+
1. 基本用法
6+
# 下载album 123 456,下载photo 333。彼此之间使用空格间隔
7+
```
8+
jmcomic 123 456 p333
9+
```
10+
11+
2. 自定义option
12+
13+
2.1. 通过命令行
14+
```
15+
jmcomic 123 --option="D:/a.yml"
16+
```
17+
18+
2.2. 通过环境变量
19+
设置环境: JM_OPTION_PATH = D:/a.yml
20+
命令行的命令不变
21+
```
22+
jmcomic 123
23+
```
24+
25+
26+
27+
"""

0 commit comments

Comments
 (0)