优化 项目文档&测试代码 (#252)

This commit is contained in:
hect0x7 2024-06-26 00:14:30 +08:00 committed by GitHub
parent 826be95865
commit 99acab28d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 81 additions and 63 deletions

View File

@ -1,4 +1,5 @@
repo_url: https://github.com/hect0x7/JMComic-Crawler-Python repo_url: https://github.com/hect0x7/JMComic-Crawler-Python
repo_name: hect0x7/JMComic-Crawler-Python
site_name: jmcomic site_name: jmcomic
theme: theme:

View File

@ -20,9 +20,10 @@
## 特殊用法教程 ## 特殊用法教程
- [GitHub Actions使用教程](./tutorial/1_github_actions.md) - [使用GitHub Actions下载本子](./tutorial/1_github_actions.md)
- [命令行使用教程](tutorial/2_command_line.md) - [使用GitHub Actions导出收藏夹](tutorial/10_export_favorites.md)
- [导出收藏夹教程](tutorial/10_export_favorites.md) - [命令行用法教程](tutorial/2_command_line.md)
- [测试你的ip能访问哪些禁漫域名](tutorial/8_pick_domain.md)

View File

@ -1,4 +1,4 @@
# 日志自定义 - 如果你不想看到那么多的日志 # 日志自定义
本文档缘起于 GitHub Discussions: [discussions/195](https://github.com/hect0x7/JMComic-Crawler-Python/discussions/195) 本文档缘起于 GitHub Discussions: [discussions/195](https://github.com/hect0x7/JMComic-Crawler-Python/discussions/195)

View File

@ -2,45 +2,77 @@
plugin(扩展/插件)是v2.2.0新引入的机制,使用插件可以实现灵活无感知的功能增强。 plugin(扩展/插件)是v2.2.0新引入的机制,使用插件可以实现灵活无感知的功能增强。
plugin的机制为可在`特定时间` 回调 `特定插件` 目前jmcomic已经内置了一些插件源码位于 src/jmcomic/jm_plugin.py
目前jmcomic已经内置了一些强大的插件源码位于 src/jmcomic/jm_plugin.py。 你可以在这里查看这些插件的配置→ [option_file_syntax](../option_file_syntax.md#3-option插件配置项)
配置插件的方式请查看 [option_file_syntax](../option_file_syntax.md#3-option插件配置项) ## 1. 插件机制介绍
你可以在option配置文件中配置插件插件会特定的<u>`事件`</u>发生时自动执行。
jmcomic里的内置事件如下
- `after_init`: option对象创建后
- `before_image`: 下载图片前
- `before_album`: 下载本子前
- `before_photo`: 下载章节前
## 示例1. 使用login插件自动登录禁漫
特定时间after_initoption对象实例化完毕后 - `after_image`: 下载图片后
- `after_album`: 下载本子后
- `after_photo`: 下载章节后
特定插件login 举例你可以配置一个login插件在option对象创建后`after_init`)时,调用`login`插件,执行登录禁漫的功能。
插件功能登录JM获取并保存cookies所有的Client都会使用这个cookies 这样你后续使用option下载本子时都会处于已登录状态。已登录状态可以让你访问所有禁漫本子
首先你需要在option配置文件当中配置如下内容来实现在after_init时调用login插件。 ## 2. 示例在after_init时调用login插件
`login`插件功能登录JM获取并保存cookies到option内。后续option创建的Client都会携带cookies即都是登录状态。
配置方式将以下配置写入option文件
```yaml ```yaml
plugins: plugins: # 插件配置项
after_init: # 时机 after_init: # 在after_init事件时自动执行插件
- plugin: login # 插件的key - plugin: login # 插件的key
kwargs: kwargs: # 下面是给插件的参数 (kwargs),由插件类自定义
# 下面是给插件的参数 (kwargs),由插件类自定义 username: un # 禁漫帐号
username: un # 禁漫帐号 password: pw # 密码
password: pw # 密码
``` ```
有了上述option配置当你调用下面的代码时login插件就会执行。 有了上述option配置当你调用下面的代码时login插件就会执行。
```python ```python
import jmcomic import jmcomic
option = jmcomic.create_option('xxx.yml')
# 程序走到这里login插件已经调用完毕了。 option = jmcomic.create_option_by_file('xxx.yml') # 创建option对象
# 程序走到这里login插件已经调用完毕了
# 后续下载本子就都是已登录状态里了
option.download_album(123)
``` ```
## 3. 怎么手动调用插件
你可以使用下面的代码触发某个事件
## 示例2. 自定义插件 ```python
# 假设你已经创建了option对象
from jmcomic import JmOption
option: JmOption
# 手动调用after_init事件下的插件
option.call_all_plugin('after_init')
# 手动调用一个特定事件的插件(如果你没有配置这个事件的插件,那么无事发生。)
option.call_all_plugin('my_event')
```
## 4. 示例:自定义插件
* 如果你有好的plugin想法也欢迎向我提PR将你的plugin内置到jmcomic模块中
下面演示自定义插件分为3步: 下面演示自定义插件分为3步:
@ -48,20 +80,21 @@ option = jmcomic.create_option('xxx.yml')
2. 让plugin类生效 2. 让plugin类生效
3. 使用plugin的key 3. 使用plugin的key
* 如果你有好的plugin想法也欢迎向我提PR将你的plugin内置到jmcomic模块中
```python ```python
# 1. 自定义plugin类 # 1. 自定义plugin类
from jmcomic import JmOptionPlugin, JmModuleConfig, create_option from jmcomic import JmOptionPlugin, JmModuleConfig
# 自定义一个类继承JmOptionPlugin
class MyPlugin(JmOptionPlugin): class MyPlugin(JmOptionPlugin):
# 指定你的插件的key # 指定你的插件的key
plugin_key = 'myplugin' plugin_key = 'myplugin'
# 覆盖invoke方法设定方法只有一个参数名为`hello_plugin` # 实现invoke方法
def invoke(self, hello_plugin) -> None: # 方法的参数可以自定义,这里假设方法只有一个参数 word
print(hello_plugin) def invoke(self, word) -> None:
print(word)
# 2. 让plugin类生效 # 2. 让plugin类生效
JmModuleConfig.register_plugin(MyPlugin) JmModuleConfig.register_plugin(MyPlugin)
@ -72,20 +105,17 @@ JmModuleConfig.register_plugin(MyPlugin)
```yaml ```yaml
# 3. 在配置文件中使用plugin # 3. 在配置文件中使用plugin
plugins: plugins:
after_init: # 时机 after_init: # 事件
- plugin: myplugin # 插件key - plugin: myplugin # 你自定义的插件key
kwargs: kwargs:
hello_plugin: this is my plugin invoke method's parameter # 你自定义的插件的参数 word: hello jmcomic # 你自定义的插件的参数
``` ```
完成上述步骤后每当你使用下面的代码你的plugin会被调用控制台就会打印出 `this is my plugin invoke method's parameter` 完成上述步骤后每当你使用下面的代码你的plugin会被调用控制台就会打印出 `hello jmcomic`
```python ```python
from jmcomic import create_option from jmcomic import create_option
option = create_option('xxx') option = create_option('xxx')
``` ```

View File

@ -1,4 +1,4 @@
# jmcomic 综合使用实例 # 综合使用实例
* 基于v2.2.2+内置插件 * 基于v2.2.2+内置插件

View File

@ -16,7 +16,7 @@ meta_data = {
disable_jm_log() disable_jm_log()
def get_domain_ls(): def get_all_domain():
template = 'https://jmcmomic.github.io/go/{}.html' template = 'https://jmcmomic.github.io/go/{}.html'
url_ls = [ url_ls = [
template.format(i) template.format(i)
@ -39,9 +39,9 @@ def get_domain_ls():
return domain_set return domain_set
domain_set = get_domain_ls() domain_set = get_all_domain()
domain_status_dict = {}
print(f'获取到{len(domain_set)}个域名,开始测试') print(f'获取到{len(domain_set)}个域名,开始测试')
domain_status_dict = {}
def test_domain(domain: str): def test_domain(domain: str):

View File

@ -251,7 +251,7 @@ class Test_Client(JmTestConfigurable):
return cl.get_album_detail('123') return cl.get_album_detail('123')
def assertEqual(first_cl, second_cl, msg): def assertEqual(first_cl, second_cl, msg):
return self.assertEqual( self.assertEqual(
get(first_cl), get(first_cl),
get(second_cl), get(second_cl),
msg, msg,
@ -265,12 +265,6 @@ class Test_Client(JmTestConfigurable):
) )
cases = [ cases = [
(
CacheRegistry.level_option,
CacheRegistry.level_option,
CacheRegistry.level_client,
CacheRegistry.level_client,
),
( (
True, True,
'level_option', 'level_option',
@ -291,25 +285,17 @@ class Test_Client(JmTestConfigurable):
# c1 == c2 # c1 == c2
# c3 == c4 # c3 == c4
# c1 != c3 # c1 != c3
assertEqual(c1, c2, 'equals in same option level')
assertNotEqual(c3, c4, 'not equals in client level')
assertNotEqual(c1, c3, 'not equals in different level')
# c5 != c1, c2, c3, c4 # c5 != c1, c2, c3, c4
invoke_all( obj = get(c5)
args_func_list=[ self.assertNotEqual(obj, get(c1))
(None, func) for func in [ self.assertNotEqual(obj, get(c3))
lambda: assertEqual(c1, c2, 'equals in same option level'),
lambda: assertNotEqual(c3, c4, 'not equals in client level'),
lambda: assertNotEqual(c1, c3, 'not equals in different level'),
lambda: assertNotEqual(c1, c5, 'not equals for None level'),
lambda: assertNotEqual(c3, c5, 'not equals for None level'),
]
]
)
future_ls = thread_pool_executor( for case in cases:
iter_objs=cases, run(*case)
apply_each_obj_func=run,
)
return [f.result() for f in future_ls] # 等待执行完毕
def test_search_advanced(self): def test_search_advanced(self):
if not self.client.is_given_type(JmHtmlClient): if not self.client.is_given_type(JmHtmlClient):