mirror of
https://github.com/hect0x7/JMComic-Crawler-Python.git
synced 2025-09-26 22:31:30 +08:00
This commit is contained in:
parent
4f56f46cbc
commit
51c1db7057
80
.github/workflows/export_favorites.yml
vendored
Normal file
80
.github/workflows/export_favorites.yml
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
name: 导出收藏夹数据
|
||||
|
||||
on:
|
||||
# schedule:
|
||||
# - cron: "0 0 * * *"
|
||||
push:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IN_JM_USERNAME:
|
||||
type: string
|
||||
default: ''
|
||||
description: '禁漫帐号(不建议使用,会泄露在日志中。最好用secrets)'
|
||||
required: false
|
||||
|
||||
IN_JM_PASSWORD:
|
||||
type: string
|
||||
default: ''
|
||||
description: '禁漫密码(不建议使用,会泄露在日志中。最好用secrets)'
|
||||
required: false
|
||||
|
||||
IN_ZIP_PASSWORD:
|
||||
type: string
|
||||
default: ''
|
||||
description: '压缩文件密码(不建议使用,会泄露在日志中。最好用secrets)'
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
crawler:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# 工作流输入
|
||||
IN_JM_USERNAME: ${{ github.event.inputs.IN_JM_USERNAME }}
|
||||
IN_JM_PASSWORD: ${{ github.event.inputs.IN_JM_PASSWORD }}
|
||||
IN_ZIP_PASSWORD: ${{ github.event.inputs.IN_ZIP_PASSWORD }}
|
||||
|
||||
# 登录相关secrets
|
||||
JM_USERNAME: ${{ secrets.JM_USERNAME }}
|
||||
JM_PASSWORD: ${{ secrets.JM_PASSWORD }}
|
||||
ZIP_PASSWORD: ${{ secrets.ZIP_PASSWORD }}
|
||||
|
||||
# 邮件相关secrets
|
||||
EMAIL_FROM: ${{ secrets.EMAIL_FROM }}
|
||||
EMAIL_TO: ${{ secrets.EMAIL_TO }}
|
||||
EMAIL_PASS: ${{ secrets.EMAIL_PASS }}
|
||||
EMAIL_TITLE: ${{ secrets.EMAIL_TITLE }}
|
||||
EMAIL_CONTENT: ${{ secrets.EMAIL_CONTENT }}
|
||||
|
||||
# 固定值
|
||||
ZIP_FP: /home/runner/work/jmcomic/download/export.7z
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.11
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Install Dependency
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements-dev.txt
|
||||
sudo apt update
|
||||
sudo apt install p7zip-full
|
||||
|
||||
- name: 安装jmcomic(local)
|
||||
run: |
|
||||
pip install -e ./
|
||||
|
||||
- name: 执行代码
|
||||
run: |
|
||||
cd ./usage/
|
||||
python workflow_export_favorites.py
|
||||
|
||||
- name: 上传结果
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: '收藏夹导出zip'
|
||||
path: ${{ env.ZIP_FP }}
|
||||
if-no-files-found: error
|
||||
retention-days: 90
|
44
README.md
44
README.md
@ -4,6 +4,10 @@
|
||||
|
||||
你可以通过简单的几行Python代码,实现下载JM上的本子到本地,并且是处理好的图片。
|
||||
|
||||
[【指路】教程:使用GitHub Actions下载禁漫本子](./assets/docs/sources/tutorial/1_github_actions.md)
|
||||
|
||||
[【指路】教程:导出并下载你的禁漫收藏夹数据](./assets/docs/sources/tutorial/10_export_favorites.md)
|
||||
|
||||
**友情提示:珍爱JM,为了减轻JM的服务器压力,请不要一次性爬取太多本子,西门🙏🙏🙏**.
|
||||
|
||||
## 项目介绍
|
||||
@ -14,7 +18,6 @@
|
||||
|
||||
目前核心功能实现较为稳定,项目也处于维护阶段(因为禁漫接口经常变动,需要经常维护)。
|
||||
|
||||
|
||||
## 安装教程
|
||||
|
||||
* 通过pip官方源安装(推荐,并且更新也是这个命令)
|
||||
@ -50,24 +53,35 @@ $ jmcomic 422866
|
||||
- **实现禁漫APP接口最新的加解密算法 (1.6.3)**
|
||||
- 用法多样:
|
||||
|
||||
- GitHub Actions:网页上直接输入本子id就能下载([教程:使用GitHub Actions下载禁漫本子](./assets/docs/sources/tutorial/1_github_actions.md))
|
||||
- 命令行:无需写Python代码,简单易用([教程:使用命令行下载禁漫本子](./assets/docs/sources/tutorial/2_command_line.md))
|
||||
- Python代码:最本质、最强大的使用方式,需要你有一定的python编程基础
|
||||
- GitHub
|
||||
Actions:网页上直接输入本子id就能下载([教程:使用GitHub Actions下载禁漫本子](./assets/docs/sources/tutorial/1_github_actions.md))
|
||||
- 命令行:无需写Python代码,简单易用([教程:使用命令行下载禁漫本子](./assets/docs/sources/tutorial/2_command_line.md))
|
||||
- Python代码:最本质、最强大的使用方式,需要你有一定的python编程基础
|
||||
- 支持**网页端**和**移动端**两种客户端实现,可通过配置切换(**移动端不限ip兼容性好,网页端限制ip地区但效率高**)
|
||||
- 支持**自动重试和域名切换**机制
|
||||
- **多线程下载**(可细化到一图一线程,效率极高)
|
||||
- **可配置性强**
|
||||
|
||||
- 不配置也能使用,十分方便
|
||||
- 配置可以从配置文件生成,支持多种文件格式
|
||||
- 配置点有:`请求域名` `客户端实现` `是否使用磁盘缓存` `同时下载的章节/图片数量` `图片格式转换` `下载路径规则` `请求元信息(headers,cookies,proxies)`等
|
||||
- 不配置也能使用,十分方便
|
||||
- 配置可以从配置文件生成,支持多种文件格式
|
||||
- 配置点有:`请求域名` `客户端实现` `是否使用磁盘缓存` `同时下载的章节/图片数量` `图片格式转换` `下载路径规则` `请求元信息(headers,cookies,proxies)`
|
||||
等
|
||||
- **可扩展性强**
|
||||
|
||||
- **支持Plugin插件,可以方便地扩展功能,以及使用别人的插件**
|
||||
- 目前内置支持的插件有:`登录插件` `硬件占用监控插件` `只下载新章插件` `压缩文件插件` `下载特定后缀图片插件` `发送QQ邮件插件` `日志主题过滤插件` `自动使用浏览器cookies插件`
|
||||
- 支持自定义本子/章节/图片下载前后的回调函数
|
||||
- 支持自定义日志
|
||||
- 支持自定义类:`Downloader(负责调度)` `Option(负责配置)` `Client(负责请求)` `实体类`等
|
||||
- 支持自定义本子/章节/图片下载前后的回调函数
|
||||
- 支持自定义日志
|
||||
- 支持自定义类:`Downloader(负责调度)` `Option(负责配置)` `Client(负责请求)` `实体类`等
|
||||
- **支持Plugin插件,可以方便地扩展功能,以及使用别人的插件,目前内置插件有**:
|
||||
- `登录插件`
|
||||
- `硬件占用监控插件`
|
||||
- `只下载新章插件`
|
||||
- `压缩文件插件`
|
||||
- `下载特定后缀图片插件`
|
||||
- `发送QQ邮件插件`
|
||||
- `日志主题过滤插件`
|
||||
- `自动使用浏览器cookies插件`
|
||||
- `jpg图片合成为一个pdf插件`
|
||||
- `导出收藏夹为csv文件插件`
|
||||
|
||||
## 进阶使用
|
||||
|
||||
@ -91,12 +105,12 @@ $ jmcomic 422866
|
||||
|
||||
* assets:存放一些非代码的资源文件
|
||||
|
||||
* config:存放配置文件
|
||||
* docs:项目文档
|
||||
* config:存放配置文件
|
||||
* docs:项目文档
|
||||
|
||||
* src:存放源代码
|
||||
|
||||
* jmcomic:`jmcomic`模块
|
||||
* jmcomic:`jmcomic`模块
|
||||
|
||||
* tests:测试目录,存放测试代码,使用unittest
|
||||
* usage:用法目录,存放示例/使用代码
|
||||
|
BIN
assets/docs/sources/images/10.png
Normal file
BIN
assets/docs/sources/images/10.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
assets/docs/sources/images/7.png
Normal file
BIN
assets/docs/sources/images/7.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
BIN
assets/docs/sources/images/8.png
Normal file
BIN
assets/docs/sources/images/8.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
BIN
assets/docs/sources/images/9.png
Normal file
BIN
assets/docs/sources/images/9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 147 KiB |
@ -141,4 +141,19 @@ plugins:
|
||||
title: jmcomic # 标题
|
||||
content: jmcomic finished !!! # 内容
|
||||
|
||||
main:
|
||||
- plugin: favorite_folder_export # 导出收藏夹插件
|
||||
log: false
|
||||
kwargs:
|
||||
zip_enable: true # 对收藏夹进行压缩
|
||||
zip_filepath: ${JM_DOWNLOAD_DIR}/export.zip # 压缩文件路径
|
||||
zip_password: ${ZIP_PASSWORD} # 压缩密码
|
||||
|
||||
after_photo:
|
||||
- plugin: j2p # jpg图片合成为一个pdf插件
|
||||
kwargs:
|
||||
pdf_dir: D:/pdf # pdf存放文件夹
|
||||
filename_rule: Pid # pdf命名规则
|
||||
quality: 100 # pdf质量,0 - 100
|
||||
|
||||
```
|
75
assets/docs/sources/tutorial/10_export_favorites.md
Normal file
75
assets/docs/sources/tutorial/10_export_favorites.md
Normal file
@ -0,0 +1,75 @@
|
||||
# 导出并下载你的禁漫收藏夹数据
|
||||
|
||||
一共需要三步:
|
||||
|
||||
1. fork一份我的代码仓库。
|
||||
2. 配置你的禁漫帐号密码。
|
||||
3. 运行工作流,下载结果。
|
||||
|
||||
下面截图解析这三步的详细过程。
|
||||
|
||||
## 1. fork一份我的代码仓库
|
||||
|
||||
访问下面这个网址:
|
||||
|
||||
`https://github.com/hect0x7/JMComic-Crawler-Python/fork`
|
||||
|
||||
直接拉到页面最底部,如下所示:
|
||||
|
||||
(最新提示,下图的1可以不做,即直接点绿色的Create fork按钮)
|
||||
|
||||

|
||||
|
||||
## 2. 配置你的禁漫帐号密码
|
||||
|
||||
在开始下面的步骤之前,你需要先启用你的repo的Actions,开启方式如下:
|
||||

|
||||
|
||||
|
||||
**注意事项:
|
||||
最好使用secrets保证不会泄漏信息。
|
||||
虽然也支持通过工作流dispatch输入帐号密码,但是那种方式会让账号密码明文显示在Actions日志中。
|
||||
如果你打算采用后者,最好下载完就及时删除工作流。**
|
||||
|
||||
然后访问下面这个网址:
|
||||
|
||||
`https://github.com/你的用户名/JMComic-Crawler-Python/settings/secrets/actions`
|
||||
|
||||
|
||||
按下图步骤进行操作:
|
||||
|
||||

|
||||
|
||||
然后来到填写页面
|
||||
|
||||

|
||||
|
||||
你需要填入下面的内容,并点【Add secret】保存:
|
||||
|
||||
`JM_USERNAME`: 你的禁漫帐号用户名
|
||||
|
||||
同样的方式再配置如下内容:
|
||||
|
||||
`JM_PASSWORD`: 你的禁漫帐号密码
|
||||
|
||||
`ZIP_PASSWORD`: 压缩文件密码,防止别人下载使用你的文件
|
||||
|
||||
|
||||
|
||||
## 3. 运行工作流,下载结果。
|
||||
|
||||
访问如下网址:
|
||||
|
||||
`https://github.com/你的用户名/JMComic-Crawler-Python/actions/workflows/export_favorites.yml`
|
||||
|
||||
按照下图步骤点击,即可运行工作流。
|
||||
|
||||
* 如果你在步骤2已经配置了secrets,无需在意输入框。
|
||||
|
||||
* 如果你没有配置secrets,你可以在输入框中输入账号 密码 压缩密码,但要记得及时删除工作流来避免信息泄漏。
|
||||
|
||||

|
||||
|
||||
待工作流变绿,表示已完成,点击去拉到页面底部,即可下载文件。
|
||||
|
||||

|
27
assets/option/option_workflow_export_favorites.yml
Normal file
27
assets/option/option_workflow_export_favorites.yml
Normal file
@ -0,0 +1,27 @@
|
||||
client:
|
||||
impl: api
|
||||
domain:
|
||||
html: [ jmcomic1.me, jmcomic.me ]
|
||||
|
||||
# 插件配置
|
||||
plugins:
|
||||
main:
|
||||
- plugin: login # 登录插件
|
||||
kwargs:
|
||||
username: ${JM_USERNAME}
|
||||
password: ${JM_PASSWORD}
|
||||
|
||||
- plugin: favorite_folder_export
|
||||
log: false
|
||||
kwargs:
|
||||
zip_enable: true
|
||||
zip_filepath: ${ZIP_FP}
|
||||
zip_password: ${ZIP_PASSWORD}
|
||||
|
||||
- plugin: send_qq_email # 发送邮件,如果未配置下面的前3个环境变量则不会发送。
|
||||
kwargs:
|
||||
msg_from: ${EMAIL_FROM}
|
||||
msg_to: ${EMAIL_TO}
|
||||
password: ${EMAIL_PASS}
|
||||
title: ${EMAIL_TITLE}
|
||||
content: ${EMAIL_CONTENT}
|
@ -2,7 +2,7 @@
|
||||
# 被依赖方 <--- 使用方
|
||||
# config <--- entity <--- toolkit <--- client <--- option <--- downloader
|
||||
|
||||
__version__ = '2.4.10'
|
||||
__version__ = '2.4.11'
|
||||
|
||||
from .api import *
|
||||
from .jm_plugin import *
|
||||
|
@ -181,6 +181,14 @@ class JmDownloader(DownloadCallback):
|
||||
downloader=self,
|
||||
)
|
||||
|
||||
def after_photo(self, photo: JmPhotoDetail):
|
||||
super().after_photo(photo)
|
||||
self.option.call_all_plugin(
|
||||
'after_photo',
|
||||
photo=photo,
|
||||
downloader=self,
|
||||
)
|
||||
|
||||
def after_image(self, image: JmImageDetail, img_save_path):
|
||||
super().after_image(image, img_save_path)
|
||||
photo = image.from_photo
|
||||
|
@ -528,6 +528,10 @@ class JmOption:
|
||||
# 构建插件对象
|
||||
plugin: JmOptionPlugin = plugin_class.build(self)
|
||||
|
||||
# 设置日志开关
|
||||
if pinfo.get('log', True) is not True:
|
||||
plugin.log_enable = False
|
||||
|
||||
jm_log('plugin.invoke', f'调用插件: [{plugin_class.plugin_key}]')
|
||||
# 调用插件功能
|
||||
plugin.invoke(**kwargs)
|
||||
|
@ -17,6 +17,7 @@ class JmOptionPlugin:
|
||||
|
||||
def __init__(self, option: JmOption):
|
||||
self.option = option
|
||||
self.log_enable = True
|
||||
|
||||
def invoke(self, **kwargs) -> None:
|
||||
"""
|
||||
@ -33,10 +34,12 @@ class JmOptionPlugin:
|
||||
"""
|
||||
return cls(option)
|
||||
|
||||
@classmethod
|
||||
def log(cls, msg, topic=None):
|
||||
def log(self, msg, topic=None):
|
||||
if self.log_enable is not True:
|
||||
return
|
||||
|
||||
jm_log(
|
||||
topic=f'plugin.{cls.plugin_key}' + (f'.{topic}' if topic is not None else ''),
|
||||
topic=f'plugin.{self.plugin_key}' + (f'.{topic}' if topic is not None else ''),
|
||||
msg=msg
|
||||
)
|
||||
|
||||
@ -65,11 +68,12 @@ class JmLoginPlugin(JmOptionPlugin):
|
||||
def invoke(self,
|
||||
username: str,
|
||||
password: str,
|
||||
impl=None,
|
||||
) -> None:
|
||||
self.require_true(username, '用户名不能为空')
|
||||
self.require_true(password, '密码不能为空')
|
||||
|
||||
client = self.option.new_jm_client()
|
||||
client = self.option.new_jm_client(impl=impl)
|
||||
client.login(username, password)
|
||||
|
||||
cookies = dict(client['cookies'])
|
||||
@ -515,3 +519,165 @@ class AutoSetBrowserCookiesPlugin(JmOptionPlugin):
|
||||
{k: v for k, v in cookies.items() if k in self.accepted_cookies_keys}
|
||||
)
|
||||
self.log('获取浏览器cookies成功')
|
||||
|
||||
|
||||
# noinspection PyMethodMayBeStatic
|
||||
class FavoriteFolderExportPlugin(JmOptionPlugin):
|
||||
plugin_key = 'favorite_folder_export'
|
||||
|
||||
# noinspection PyAttributeOutsideInit
|
||||
def invoke(self,
|
||||
save_dir=None,
|
||||
zip_enable=False,
|
||||
zip_filepath=None,
|
||||
zip_password=None,
|
||||
delete_original_file=False,
|
||||
):
|
||||
self.save_dir = os.path.abspath(save_dir if save_dir is not None else os.getcwd() + '/export/')
|
||||
self.zip_enable = zip_enable
|
||||
self.zip_filepath = os.path.abspath(zip_filepath)
|
||||
self.zip_password = zip_password
|
||||
self.delete_original_file = delete_original_file
|
||||
self.files = []
|
||||
|
||||
mkdir_if_not_exists(self.save_dir)
|
||||
mkdir_if_not_exists(of_dir_path(self.zip_filepath))
|
||||
|
||||
self.main()
|
||||
|
||||
def main(self):
|
||||
cl = self.option.new_jm_client(impl=JmApiClient)
|
||||
# noinspection PyAttributeOutsideInit
|
||||
self.cl = cl
|
||||
page = cl.favorite_folder()
|
||||
|
||||
# 获取所有的收藏夹
|
||||
folders = {fid: fname for fid, fname in page.iter_folder_id_name()}
|
||||
# 加上特殊收藏栏【全部】
|
||||
folders.setdefault('0', '全部')
|
||||
|
||||
# 一个收藏夹一个线程,导出收藏夹数据到文件
|
||||
multi_thread_launcher(
|
||||
iter_objs=folders.items(),
|
||||
apply_each_obj_func=self.handle_folder,
|
||||
)
|
||||
|
||||
if not self.zip_enable:
|
||||
return
|
||||
|
||||
# 压缩导出的文件
|
||||
self.require_true(self.zip_filepath, '如果开启zip,请指定zip_filepath参数(压缩文件保存路径)')
|
||||
|
||||
if self.zip_password is None:
|
||||
self.zip_folder_without_password(self.files, self.zip_filepath)
|
||||
else:
|
||||
self.zip_with_password()
|
||||
|
||||
# 删除导出的原文件
|
||||
if self.delete_original_file is True:
|
||||
for f in self.files:
|
||||
os.remove(f)
|
||||
|
||||
def handle_folder(self, fid: str, fname: str):
|
||||
self.log(f'【收藏夹: {fname}, fid: {fid}】开始获取数据')
|
||||
|
||||
# 获取收藏夹数据
|
||||
page_data = self.fetch_folder_page_data(fid)
|
||||
|
||||
# 序列化到文件
|
||||
filepath = self.save_folder_page_data_to_file(page_data, fid, fname)
|
||||
|
||||
if filepath is None:
|
||||
self.log(f'【收藏夹: {fname}, fid: {fid}】收藏夹无数据')
|
||||
return
|
||||
|
||||
self.log(f'【收藏夹: {fname}, fid: {fid}】保存文件成功 → [{filepath}]')
|
||||
self.files.append(filepath)
|
||||
|
||||
def fetch_folder_page_data(self, fid):
|
||||
# 一页一页获取,不使用并行
|
||||
page_data = list(self.cl.favorite_folder_gen(folder_id=fid))
|
||||
return page_data
|
||||
|
||||
def save_folder_page_data_to_file(self, page_data: List[JmFavoritePage], fid: str, fname: str):
|
||||
from os import path
|
||||
filepath = path.abspath(path.join(self.save_dir, fix_windir_name(f'【{fid}】{fname}.csv')))
|
||||
|
||||
data = []
|
||||
for page in page_data:
|
||||
for aid, extra in page.content:
|
||||
data.append(
|
||||
(aid, extra.get('author', '') or JmMagicConstants.DEFAULT_AUTHOR, extra['name'])
|
||||
)
|
||||
|
||||
if len(data) == 0:
|
||||
return
|
||||
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write('id,author,name\n')
|
||||
for item in data:
|
||||
f.write(','.join(item) + '\n')
|
||||
|
||||
return filepath
|
||||
|
||||
def zip_folder_without_password(self, files, zip_path):
|
||||
"""
|
||||
压缩文件夹中的文件并设置密码
|
||||
|
||||
:param files: 要压缩的文件的绝对路径的列表
|
||||
:param zip_path: 压缩文件的保存路径
|
||||
"""
|
||||
import zipfile
|
||||
|
||||
with zipfile.ZipFile(zip_path, 'w') as zipf:
|
||||
# 获取文件夹中的文件列表并将其添加到 ZIP 文件中
|
||||
for file in files:
|
||||
zipf.write(file, arcname=of_file_name(file))
|
||||
|
||||
def zip_with_password(self):
|
||||
os.chdir(self.save_dir)
|
||||
cmd = f'7z a "{self.zip_filepath}" "{self.save_dir}" -p{self.zip_password} -mhe=on'
|
||||
self.require_true(
|
||||
0 == os.system(cmd),
|
||||
'加密压缩文件失败'
|
||||
)
|
||||
|
||||
|
||||
class ConvertJpgToPdfPlugin(JmOptionPlugin):
|
||||
plugin_key = 'j2p'
|
||||
|
||||
def invoke(self,
|
||||
photo: JmPhotoDetail,
|
||||
pdf_dir=None,
|
||||
filename_rule='Pid',
|
||||
quality=100,
|
||||
**kwargs,
|
||||
):
|
||||
filename = DirRule.apply_rule_directly(None, photo, filename_rule)
|
||||
photo_dir = self.option.decide_image_save_dir(photo)
|
||||
if pdf_dir is None:
|
||||
pdf_dir = photo_dir
|
||||
else:
|
||||
pdf_dir = fix_windir_name(pdf_dir)
|
||||
mkdir_if_not_exists(pdf_dir)
|
||||
|
||||
pdf_filepath = f'{pdf_dir}{filename}.pdf'
|
||||
|
||||
def get_cmd(suffix='.jpg'):
|
||||
return f'magick convert -quality {quality} "{photo_dir}*{suffix}" "{pdf_filepath}"'
|
||||
|
||||
cmd = get_cmd()
|
||||
self.log(f'execute command: {cmd}')
|
||||
code = self.execute_cmd(cmd)
|
||||
|
||||
self.require_true(
|
||||
code == 0,
|
||||
'jpg图片合并为pdf失败!'
|
||||
'请确认你是否安装了magick,安装网站: [http://www.imagemagick.org/]'
|
||||
)
|
||||
|
||||
self.log(f'Convert Successfully: JM{photo.id} → {pdf_filepath}')
|
||||
|
||||
# noinspection PyMethodMayBeStatic
|
||||
def execute_cmd(self, cmd):
|
||||
return os.system(cmd)
|
||||
|
35
usage/workflow_export_favorites.py
Normal file
35
usage/workflow_export_favorites.py
Normal file
@ -0,0 +1,35 @@
|
||||
from jmcomic import *
|
||||
|
||||
|
||||
def prepare_actions_input_and_secrets():
|
||||
def env(match: Match) -> str:
|
||||
name = match[1]
|
||||
value = os.getenv(name, '')
|
||||
|
||||
# 配置了有效的值,放行
|
||||
if value != '':
|
||||
return value
|
||||
|
||||
# 未配置,或者值为空(值为空是GitHub Actions的未配置默认值)
|
||||
# 是EMAIL相关,也放行
|
||||
if name.startswith('EMAIL'):
|
||||
return value
|
||||
|
||||
# 尝试从工作流中取
|
||||
value = os.getenv(f'IN_{name}', '')
|
||||
# 工作流也没有传值
|
||||
ExceptionTool.require_true(value != '', f'未配置secrets或工作流,字段为: {name}')
|
||||
|
||||
return value
|
||||
|
||||
JmcomicText.dsl_replacer.add_dsl_and_replacer(r'\$\{(.*?)\}', env)
|
||||
|
||||
|
||||
def main():
|
||||
prepare_actions_input_and_secrets()
|
||||
option = create_option('../assets/option/option_workflow_export_favorites.yml')
|
||||
option.call_all_plugin('main')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user