Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# 🤝 参与贡献 (Contributing)

首先,非常感谢每一位愿意为 `jmcomic` 贡献代码和力量的机长!将 `jmcomic` 驶向更广阔的天空,离不开各位的添砖加瓦。

如果把每一次启动爬虫看作是一次狂热的航班起飞,那么这份文档就是塔台(仓库维护者)下发的**飞行手册与航权指南**。在改造战机、请求起飞之前,请务必花两分钟阅读这套协同规则。

## 💡 航前申报 (Before Writing Code)

如果你的航线规划(代码改动)涉及核心组件或者需要编写超过几行代码,**强烈建议你先通过提交一个 Issue 向塔台申请**,详细讨论你想要拓展的功能或重构的想法。

在投入大量燃油(精力)之前,我们应该先在技术路线和实现方式上达成一致,避免你的心血被白白浪费或航线规划不被塔台接受。

## 💻 登机准备与试飞 (Build and Test)

### 1. 组装战机 (Build)

参与贡献的第一步,是将本项目 **[Fork](https://github.com/hect0x7/JMComic-Crawler-Python/fork)** 到你个人的机库(GitHub 账号)下,然后克隆到控制台,并独立切出你的任务分支:

```bash
git clone https://github.com/<your_user_name>/JMComic-Crawler-Python.git
cd JMComic-Crawler-Python
git checkout dev
git checkout -b <your_feature_branch>
```

强烈建议使用现代化的包管理器(如 [uv](https://github.com/astral-sh/uv))进行极速的沙盒隔离开发,避免污染你本地的系统空域:

```bash
# 自动打通虚拟环境并注满燃油(安装源码及开发依赖)
uv venv
uv pip install -r requirements-dev.txt -e ./
```

### 2. 空中改造 (Coding)

在战机组装完毕并建立好安全的沙盒后,你就可以开始编写代码进行你的改装了。

在动工之前,请务必仔细阅读本文档末尾的《[🛠️ 引擎改装规范(Coding Guidelines)](#%EF%B8%8F-引擎改装规范-coding-guidelines)》 部分。那里记载了你必须要遵守的架构底线(如统一日志与异常拆解机制)。这能确保你的航线设计不偏离塔台的预设轨迹,避免在安检时因为违规操作被打回。

### 3. 试飞运行 (Test)

向原仓库 `dev` 航道发起 PR 之前,你需要作为机长执行跑道级自检,**请务必保证你新编撰的代码能够顺利通过试飞用例**

你可以任选以下两种自检方式之一:

**选项 A:本地试飞 (终端测试)**
本项目使用 Python 标准库 `unittest` 作为本地质检验证,跑通所有测试:
```bash
cd ./tests/
uv run python -m unittest
```

**选项 B:云端试飞 (GitHub Actions)**
如果你的本地环境不便配置,也可以直接将代码推送至你个人 Fork 仓库的 `dev` 分支。云端塔台会在后台自动触发 `test_api.yml` 动作。
> 💡 请前往你个人仓库的 **Actions** 面板,确保最新地推流全部亮起绿灯。
## 📥 申请接入航线 (Pull Request)

`jmcomic` 的代码管线有着极其明确的空域隔离,发起 PR 时请务必挂对你的目标分支:

- 🟢 **`dev` 航道 (代码开发)**:所有的**功能特性 (feat)****功能重构 (refactor)****Bug 修复 (fix)** 的 PR,均需指向原仓库的 `dev` 航道。由塔台(维护者)合并试飞后集中推向主发版链路。

- 📘 **`docs` 航道 (文档维护)**:本航道直通项目专属的 **[在线文档 (Read the Docs)](https://jmcomic.readthedocs.io/zh-cn/latest/)**。所有不涉及功能性代码修改的**纯粹文档更新**,请直接提交至此分支。入线后它将即刻触发并全网同步部署,绕过复杂的流水安检。需要注意的是,`docs` 航道的进度通常会超前于主系统 (`master`),塔台会在新版发布或定期检修时统一将二者对齐同步。

- 🚫 **禁飞区 (禁止直飞 master)**:为防止外部航班意外触发 `release_auto.yml` 这个威力巨大的自动发版工作流,**本项目不接受任何直接指向 `master` 分支的 PR**。所有的新功能与代码改造必须经由 `dev` 航道降落并完成试飞,新版本号的最终敲定与发布由塔台统一操控。

PR 申请后,我会尽快 review 各位机长的代码并反馈通讯。再次感谢你的付出!🎉

---

## 🚀 发版巡航 (Release Process)

项目使用自动化流水线进行发版,此流程仅由塔台(维护者)在合并至 `master` 分支时触发。

### 1. 触发条件
当代码被推送(或 PR 合并)至 `master` 分支,且 **Commit Message 以 `v` 开头**时,GitHub Actions 会自动启动 `release_auto.yml` 工作流,执行以下操作:
1. 自动根据 Commit Message 创建 GitHub Release 标签。
2. 自动构建项目并发布至 [PyPI](https://pypi.org/project/jmcomic/)

### 2. Commit 格式指令 (仅针对维护者)
当塔台(维护者)准备好发布新版本并合入 `master` 时,需要根据 `.github/release.py` 的解析要求使用特定格式的 Commit Message:

**格式:** `v<版本号>: <更新项1>; <更新项2>; ...`

* **示例:** `v2.1.0: 修复搜索解析异常; 优化多线程下载效率; 新增插件系统`
* **黑匣子解析逻辑:**
* **Tag**:冒号 `:` 前的内容(如 `v2.1.0`)。
* **Body**:冒号 `:` 后的内容,程序会将分号 `;` 分割的每一项转化为有序列表。

---

## 🛠️ 引擎改装规范 (Coding Guidelines)

> 📌 **塔台公告**:本《引擎改装规范》将伴随舰队的探索进度**持续迭代更新**。当前的强制适航指令主要聚焦于 **黑匣子 (日志记录)****空难溯源 (异常处理)** 两大核心电传模块。
### 📝 测试与操作手册 (Tests & Docs)

在完成代码改造后,机长请务必补全以下配套设施,这是确保新战机安全入库的必要纲领:

- **补充伴飞测试 (Tests)**:如果你打造了新型挂载(新功能)或排查掉了深层故障(Bug),你必须在 `tests/` 目录下为其编写对应的试飞用例。每一行核心代码都应当能通过稳定飞行测试。
- **更新操作手册 (Docs)**:如果你实现了向其他机长开放的新仪表盘能力(功能入口),你还需要同步更新操作手册。文档应安放在 `assets/docs/` 下的对应位置。如果不知道该放哪,欢迎在 PR 中呼叫塔台。

---

### 💻 核心架构指令 (Architecture Rules)

在为 `jmcomic` 编写或改造代码时,请尽量增加类型注解 (Type hints) 并遵守合理地命名。除此之外,为确保全机队的统一性,请尽量遵循以下架构规范:

#### 1. 统一使用黑匣子网关 (统一日志)
所有的业务代码请统一使用 `from jmcomic import jm_log` 进行留痕。**避免**直接 `import logging` 或手动去拼接带有 `【】` 的日志头:
```python
from jmcomic import jm_log, jm_logger

# ❌ 避免直接调用底层 logger(jm_logger 是 jmcomic 内部原始的 logging.Logger 实例)
jm_logger.info("【api】请求成功")

# ✅ 推荐做法,统一走网关,系统会自动套用格式化主题
jm_log('api', '请求成功')
```

#### 2. 优雅记录坠机日志 (异常处理)
在飞行途中捕获到不可预料的 Exception 时,**无需**使用 `traceback.format_exc()` 费力拼装栈残骸。直接将异常对象作为入参传入 `jm_log` 即可,底层引擎会自动完整解析现场:
```python
try:
do_something()
except Exception as e:
# ❌ 避免手动拼装残骸,否则日志过滤系统会把它当成纯文本
import traceback
jm_log('req.error', f'{e}\n{traceback.format_exc()}')

# ✅ 推荐做法:直接上交异常对象本体,清爽且精准
jm_log('req.error', e)
```

#### 3. 触发系统级警报 (统一抛错)
当发生预期的业务级阻断时,请尽量避免直接抛出内置的裸 Exception。通过内置的 `ExceptionTool` 抛出,能确保异常准确传达给用户外部装配的监听器 (`ExceptionListener`):
```python
from jmcomic import ExceptionTool

# ❌ 避免直接 raise 底层异常,这会导致外部监听器失效
raise Exception("解析 json 数据失败")

# ✅ 推荐做法:通过工具类附带上下文信息抛出
ExceptionTool.raises_resp(msg="解析 json 数据失败", resp=response)
```
2 changes: 1 addition & 1 deletion .github/workflows/test_api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
test: # This code is based on https://github.com/gaogaotiantian/viztracer/blob/master/.github/workflows/python-package.yml
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.13']
python-version: ['3.9', '3.10', '3.13', '3.14'] # 3.9 is kept as the minimum supported version test (EOL)
os: [ ubuntu-latest ]
runs-on: ${{ matrix.os }}
timeout-minutes: 5
Expand Down
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@
</div>




> 本项目封装了一套可用于爬取JM的Python API.
>
> 你可以通过简单的几行Python代码,实现下载JM上的本子到本地,并且是处理好的图片。
>
> **🧭 快速指路**
> - [教程:使用 GitHub Actions 下载禁漫本子](./assets/docs/sources/tutorial/1_github_actions.md)
> - [教程:导出并下载你的禁漫收藏夹数据](./assets/docs/sources/tutorial/10_export_favorites.md)
> - [塔台广播:欢迎各位机长加入并贡献代码](./.github/CONTRIBUTING.md)
>
> **友情提示:珍爱JM,为了减轻JM的服务器压力,请不要一次性爬取太多本子,西门🙏🙏🙏**.
[【指路】教程:使用GitHub Actions下载禁漫本子](./assets/docs/sources/tutorial/1_github_actions.md)

[【指路】教程:导出并下载你的禁漫收藏夹数据](./assets/docs/sources/tutorial/10_export_favorites.md)
>

![introduction.jpg](./assets/docs/sources/images/introduction.jpg)
Expand All @@ -59,7 +59,8 @@

## 安装教程

> ⚠如果你没有安装过Python,需要先安装Python再执行下面的步骤,且版本需要>=3.7([点我去python官网下载](https://www.python.org/downloads/)
> ⚠如果你没有安装过 Python,需要先前往 [Python 官网下载](https://www.python.org/downloads/) 再执行以下步骤。
>**推荐使用 Python 3.12及以上版本**
* 通过pip官方源安装(推荐,并且更新也是这个命令)

Expand Down Expand Up @@ -201,8 +202,10 @@ jmcomic 123

## 使用小说明

* Python >= 3.7,建议3.9以上,因为jmcomic的依赖库可能会不支持3.9以下的版本。
* 个人项目,文档和示例会有不及时之处,可以Issue提问
* 推荐使用 **Python 3.12+**,目前最低兼容版本为3.9。
> 注意:Python 3.9 及更早版本皆已于 2025 年彻底结束官方生命周期 (EOL),使用3.9及以下随时有可能遇到第三方库不兼容的问题。
* 个人项目,文档和示例会有不及时之处,可以Issue提问。

## 项目文件夹介绍

Expand Down
30 changes: 21 additions & 9 deletions assets/docs/sources/tutorial/11_log_custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@

## 1. 日志完全开启/关闭

使用代码:

```
from jmcomic import disable_jm_log
disable_jm_log()
```

使用配置:

```yaml
log: false
```


或者使用代码:

```python
from jmcomic import disable_jm_log
disable_jm_log()
```

## 2. 日志过滤,只保留特定topic

使用插件配置
Expand All @@ -43,13 +45,23 @@ plugins:
```yaml
plugins:
after_init:
- plugin: client_proxy # 提高移动端的请求效率的插件
- plugin: client_proxy
log: false # 插件自身不打印日志
kwargs:
proxy_client_key: photo_concurrent_fetcher_proxy
whitelist: [ api, ]
```

## 4. 完全自定义 jmcomic 日志
## 4. 深度自定义:两类不同的拦截手段

根据你的需求复杂度,你可以选择以下方式:

- **方式 A:操作 jm_logger (推荐 / 标准)**

适用于:改变日志输出位置(如文件、监控、后端服务)、调整显示格式、自定义过滤。

- **方式 B:接管 EXECUTOR_LOG (高级 / 深度定制)**

适用于:需要完全重塑日志的分发逻辑,或者将日志直接桥接到不符合标准 logging 协议的第三方系统。

你可以自定义jmcomic的模块日志打印函数,参考文档:[模块自定义](./4_module_custom.md#自定义log)
详细参考文档:[模块自定义](./4_module_custom.md#自定义log)
28 changes: 18 additions & 10 deletions assets/docs/sources/tutorial/4_module_custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,24 +137,32 @@ def custom_album_photo_image_detail_class():
```python
def custom_jm_log():
"""
该函数演示自定义log
该函数演示如何接管和自定义日志输出
"""

# jmcomic模块在运行过程中会使用 jm_log() 这个函数进行打印信息
# jm_log() 这个函数 最后会调用 JmModuleConfig.EXECUTOR_LOG 函数
# 你可以写一个自己的函数,替换 JmModuleConfig.EXECUTOR_LOG,实现自定义log
# jmcomic 项目默认使用内置的 Python logging 模块
# 其日志记录器的名字固定为 "jmcomic"

# 1. 自定义log函数
def my_log(topic: str, msg: str):
# 【推荐方式】直接配置原生的 logging logger
import logging
jm_logger = logging.getLogger("jmcomic")

# 例如,取消默认往下游控制台打印的 Handler,转存到文件中
jm_logger.handlers.clear()
jm_logger.addHandler(logging.FileHandler("jm_download.log", encoding="utf-8"))

# 【向后兼容方式/遗留用法】
# 你依然可以通过替换全局配置类的 EXECUTOR_LOG 函数暴力接管日志
def my_custom_log(topic: str, msg, e: Exception = None):
"""
这个log函数的参数列表必须包含两个参数,topic和msg
@param topic: log主题,例如 'album.before', 'req.error', 'plugin.error'
@param msg: 具体log的信息
@param msg: 具体log的信息,也可以直接传入 Exception 对象(底层会自动适配)
@param e: 可选,异常对象(当 msg 本身就是 Exception 时无需传)
"""
pass

# 2. 让my_log生效
JmModuleConfig.EXECUTOR_LOG = my_log
# 生效自定义的 log 打印函数
JmModuleConfig.EXECUTOR_LOG = my_custom_log
```


Expand Down
16 changes: 10 additions & 6 deletions assets/readme/README-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
>
> With a few simple lines of Python code, you can download albums from JM to your local machine, with properly processed images.
>
> **🧭 Quick Guide**
> - [Tutorial: Downloading JM Albums using GitHub Actions](../docs/sources/tutorial/1_github_actions.md)
> - [Tutorial: Exporting and downloading your JM favorites data](../docs/sources/tutorial/10_export_favorites.md)
> - [Tower Broadcast: Welcome captains to join and contribute code](../../.github/CONTRIBUTING.md)
>
> **Friendly Prompt: Cherish JM. In order to reduce the pressure on JM servers, please do not download too many albums at once 🙏🙏🙏.**
[【Guide】Tutorial: Downloading JM Albums using GitHub Actions](../docs/sources/tutorial/1_github_actions.md)

[【Guide】Tutorial: Exporting and downloading your JM favorites data](../docs/sources/tutorial/10_export_favorites.md)


![introduction.jpg](../docs/sources/images/introduction.jpg)

Expand All @@ -59,7 +60,8 @@ In addition to downloading, other JM interfaces are also implemented on demand.

## Installation Guide

> ⚠ If you have not installed Python, you must install Python before executing the following steps. Version >= 3.7 is required ([Download from Python Official Site](https://www.python.org/downloads/)).
> ⚠ If you have not installed Python, you must install Python before executing the following steps. [Download from Python Official Site](https://www.python.org/downloads/)
> **Version 3.12+ is recommended.**
* Install via official pip source (recommended, the update command is identical)

Expand Down Expand Up @@ -200,7 +202,9 @@ Please check the documentation homepage → [jmcomic.readthedocs.io (Chinese lan

## Prerequisites

* Python >= 3.7. Version 3.9+ is highly recommended because `jmcomic`'s dependencies may not perfectly support prior versions.
* Version **3.12+** is recommended, with a minimum compatible version of 3.9.
> Note: Python 3.9 and earlier versions reached their End Of Life (EOL) in 2025. You may encounter third-party library incompatibilities at any time if you use version 3.9 or below.
* Since this is a personal project, the documentation/examples may occasionally be out of sync. Please feel free to open an Issue for any clarifications.

## Directory Structure
Expand Down
16 changes: 10 additions & 6 deletions assets/readme/README-jp.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
>
> 数行のPythonコードだけで、JM上のアルバムをローカルへダウンロードすることができます。ダウンロードされた画像は完全に処理済みです。
>
> **🧭 クイックガイド**
> - [チュートリアル: GitHub Actionsを使ってダウンロードする](../docs/sources/tutorial/1_github_actions.md)
> - [チュートリアル: お気に入りのデータをエクスポートしてダウンロードする](../docs/sources/tutorial/10_export_favorites.md)
> - [タワーブロードキャスト: 機長のみなさん、参加とコード提供を歓迎します](../../.github/CONTRIBUTING.md)
>
> **ご案内:JMのサーバー負荷を軽減するため、一度に大量のダウンロードは控えてください 🙏🙏🙏**
[【ガイド】チュートリアル:GitHub Actionsを使ってダウンロードする](../docs/sources/tutorial/1_github_actions.md)

[【ガイド】チュートリアル:お気に入りのデータをエクスポートしてダウンロードする](../docs/sources/tutorial/10_export_favorites.md)


![introduction.jpg](../docs/sources/images/introduction.jpg)

Expand All @@ -59,7 +60,8 @@

## インストール手順

> ⚠ まだPythonをインストールしていない場合は、先にPythonのインストールをお願いします。要件: Python >= 3.7 ([公式のPythonページからダウンロード](https://www.python.org/downloads/))。
> ⚠ まだPythonをインストールしていない場合は、先に [公式のPythonページからダウンロード](https://www.python.org/downloads/) してインストールをお願いします。
> **Python 3.12以上の使用を推奨します**
* 公式 pip ソースからインストール(推奨。アップデートもこのコマンドを使用します)

Expand Down Expand Up @@ -199,7 +201,9 @@ jmcomic 123

## ご利用上の注意点

* Python >= 3.7 ですが、jmcomicの依存ライブラリが古いバージョンをサポートしない可能性があるため、3.9以上をお勧めします。
* **Python 3.12以上**を推奨します。現在の最小互換バージョンは3.9です。
> 注意: Python 3.9 およびそれ以前のバージョンは2025年に完全にサポート終了 (EOL) となっており、3.9以下のバージョンを使用すると、サードパーティ製ライブラリの非互換性の問題がいつでも発生する可能性があります。
* 個人のプロジェクトであるため、ドキュメントやサンプルコードの更新が遅れることがあります。ご不明な点はIssueにてご質問ください。

## ディレクトリ構造のご紹介
Expand Down
Loading