我的自动化番剧工作流

啊B最近番剧越来越不能看了,加上鼓捣影音库已经上了Plex Pass,是时候鼓捣自动下番了!

Plex Bangumi

Transmission

使用 Transmission 进行 BT下载

无脑 Docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
---
version: "2.1"
services:
transmission:
image: lscr.io/linuxserver/transmission:latest
container_name: transmission
environment:
- PUID=1001
- PGID=1001
- TZ=Asia/Shanghai
- TRANSMISSION_WEB_HOME= #optional
- USER= #optional
- PASS= #optional
- WHITELIST= #optional
- PEERPORT= #optional
- HOST_WHITELIST= #optional
volumes:
- /path/to/config/folder:/config
- /path/to/downloads/folder:/downloads
- /path/to/watch/folder:/watch
ports:
- 9091:9091
- 51413:51413
- 51413:51413/udp
# network_mode: host
restart: unless-stopped

自动化下载

通过 FlexGet 定期向 acg.rip 爬取rss,解析想要的字幕组,推送到 Transmission 自动下载。

无脑安装命令

1
pip install flexget

config.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
templates:
tr:
transmission:
host: localhost
port: your_port
username: your_username
password: your_password
# add_paused: yes # 添加后不自动下载
variables:
save_root: /mnt/Media/WEB-DL # 保存的位置
# 最终会保存到 /mnt/Media/WEB-DL/字幕组名称/番剧名称/S??/ 下

tasks:
acg.rip:
rss: https://acg.rip/.xml?term=
seen:
fields:
- url
manipulate:
- full:
from: title # 保存一份拷贝
- full:
from: full
replace:
regexp: '\[(Lilith-Raws)] (.* / )?(.*?)( S?(\d+))? - (\d+) \[([^]]+)].*?(1080|720)[pP].+'
format: '\1#0#\3#1#\5#2#\6#3#\7#4#\8'
- full:
from: full
replace:
regexp: '【(喵萌.*?)】★.*?★\[.*? ?/ ?([^]]+)]\[(\d+)]\[(1080|720)[pP]?].*?(简).+'
format: '\1#0#\2#1##2#\3#3#\4#4#'
- full:
from: full
replace:
regexp: '\[(ANi)] (.+?)( S(\d+))? - .+ - (\d+) \[(1080|720)[Pp]?]\[([^]]+)].+'
format: '\1#0#\2#1#\4#2#\5#3#\7#4#\6'
- full:
from: full
replace:
regexp: '\[.*(LoliHouse).*] .+ / (.+?)( S(\d+))? - (\d+)(?:v\d+)? \[.*?(1080|720)[pP].*(简).+'
format: '\1#0#\2#1#\4#2#\5#3##4#\6'
- full:
from: full
replace:
regexp: '\[(桜都字幕组|MingY|Oborozuki)] .*? / (.*?)( [Ss](\d+))? \[(\d+)]\[(1080|720)[pP]?].*简繁.*内封.+'
format: '\1#0#\2#1#\4#2#\5#3##4#\6'
- full:
from: full
replace:
regexp: '\[(SweetSub)[^]]*]\[.+?]\[(.+?)([Ss](\d+))?]\[(\d+)].+?(1080|720)[pP].+?简.+'
format: '\1#0#\2#1#\4#2#\5#3##4#\6'
- group: # 提取字幕组名称
from: full
replace:
regexp: '^(.+?)#0#(.+?)#1#(\d*)#2#(\d+)#3#(\S*)#4#(\S*)$'
format: '\1'
- name: # 提取番剧名
from: full
replace:
regexp: '^(.+?)#0#(.+?)#1#(\d*)#2#(\d+)#3#(\S*)#4#(\S*)$'
format: '\2'
- session: # 提取第几季
from: full
replace:
regexp: '^(.+?)#0#(.+?)#1#(\d*)#2#(\d+)#3#(\S*)#4#(\S*)$'
format: 'S\3'
- session: # 格式化 S1 改成 S01
from: session
replace:
regexp: '^S(\d)$'
format: 'S0\1'
- session: # 如果为空,默认S01
from: session
replace:
regexp: '^S$'
format: 'S01'
- episode: # 提取第几集
from: full
replace:
regexp: '^(.+?)#0#(.+?)#1#(\d*)#2#(\d+)#3#(\S*)#4#(\S*)$'
format: 'E\4'
- episode: # E1 改成 S01
from: episode
replace:
regexp: '^E(\d)$'
format: 'E0\1'
- source: # 来源,Baha 之类的
from: full
replace:
regexp: '^(.+?)#0#(.+?)#1#(\d*)#2#(\d+)#3#(\S*)#4#(\S*)$'
format: '\5'
- resolution: # 分辨率
from: full
replace:
regexp: '^(.+?)#0#(.+?)#1#(\d*)#2#(\d+)#3#(\S*)#4#(\S*)$'
format: '\6'

- subpath: # 可以用黑名单来拦截
from: full
replace:
regexp: '^(.+?)#0#(.+?)#1#(\d*)#2#(\d+)#3#(\S*)#4#(\S*)$'
format: 'Group: \1; Name: \2; Session: S\3'
- subpath:
from: subpath
replace:
regexp: '^Group: (.+); Name: (.*); Session: S$'
format: 'Group: \1; Name: \2; Session: S1'
- subpath:
from: subpath
replace:
regexp: '^Group: (.+); Name: (.*); Session: S(\d)$'
format: 'Group: \1; Name: \2; Session: S0\3'
- subpath:
from: subpath
replace:
regexp: '^Group: (.+); Name: (.*); Session: (.*)$'
format: '\1/\2/\3'
regexp:
reject:
- ANi/Mononogatari/S01 # 黑名单,这样不会下载这个番,支持正则
accept:
- .+\/.+\/S\d+
from: subpath
template: tr
transmission:
path: '{? save_root ?}/{{ subpath }}/'

Plex 识别优化 和 自动清空旧种

Plex 有一个bug,如果文件名为 [Nekomoe kissaten][Undead Girl Murder Farce][02][1080p][JPTC].mp4 是无法识别的,
需要替换为 [Nekomoe kissaten] Undead Girl Murder Farce - 02 [1080p][JPTC].mp4,把名称和集数给分开。
所以写一个简单的脚本来修改名称,也顺便清理旧种子。

flexget-auto.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import transmission_rpc
import sys
import time
import re

TRANS_CLIENT_CONF = {
"host": "localhost",
"port": "9091",
"username": "username",
"password": "password",
}

def Airota(client: transmission_rpc.Client, torrent: transmission_rpc.Torrent):
r = re.compile(r'^(\[Airota\])\[([^]]+)\]\[(\d+)\]')
new_file_name = r.sub(r"\1 \2 - \3 ", torrent.name, 1)
if new_file_name == torrent.name:
return
ret = client.rename_torrent_path(torrent.id, torrent.name, new_file_name)
print(f'Airota Rename: {torrent.name} -> {new_file_name}: {ret}')

def NekomoeKissaten(client: transmission_rpc.Client, torrent: transmission_rpc.Torrent):
r = re.compile(r'^(\[Nekomoe kissaten\])\[([^]]+)\]\[(\d+)\]')
new_file_name = r.sub(r"\1 \2 - \3 ", torrent.name, 1)
if new_file_name == torrent.name:
return
ret = client.rename_torrent_path(torrent.id, torrent.name, new_file_name)
print(f'NekomoeKissaten Rename: {torrent.name} -> {new_file_name}: {ret}')

def DeleteOldTorrent(client: transmission_rpc.Client, torrent: transmission_rpc.Torrent) -> bool:
if torrent.is_finished is False:
return False
if torrent.done_date.timestamp() + 3600 * 24 * 7 > time.time():
return False
ret = client.remove_torrent(torrent.id, delete_data=False)
print(f'Delete: {torrent.name}: {ret}')
return True

def main():
try:
trans_client = transmission_rpc.Client(**TRANS_CLIENT_CONF)
except transmission_rpc.error.TransmissionAuthError as e:
print(e)
sys.exit()

torrents = trans_client.get_torrents()
for torrent in torrents:
print(f'{torrent.hashString[-8:]}: {torrent.name} ({torrent.status})', 'in transmission.')
if DeleteOldTorrent(trans_client, torrent): # 删除老种子
continue
NekomoeKissaten(trans_client, torrent)
Airota(trans_client, torrent)
main()

Plex 去重

之后,会有部分剧集多次重复下载,这里使用 plex dupefinder 来去重。
它是通过 文件名,音频编码格式,视频编码格式,分辨率来给资源算分,自动算出最高的进行保留。

Plex DupeFinder

无脑安装命令

1
2
3
4
5
git clone https://github.com/l3uddz/plex_dupefinder.git
cd plex_dupefinder
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

再创建 plex_dupefinder.sh 作为启动入口

1
2
3
4
#! /bin/bash
BASE_PATH=`dirname $0`
source $BASE_PATH/venv/bin/activate
python $BASE_PATH/plex_dupefinder.py

由于我的播放器支持 hevc 编码和我喜欢mkv格式,所以微调了下config。一般用默认即可。
FILENAME_SCORES 也能主动给一些喜欢的字幕组加分。
config.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
{
"AUDIO_CODEC_SCORES": {
"Unknown": 0,
"aac": 1000,
"ac3": 1000,
"dca": 2000,
"dca-ma": 4000,
"eac3": 1250,
"flac": 2500,
"mp2": 500,
"mp3": 1000,
"pcm": 2500,
"truehd": 4500,
"wmapro": 200
},
"AUTO_DELETE": true,
"FIND_DUPLICATE_FILEPATHS_ONLY": false,
"FILENAME_SCORES": {
"*.avi": -1000,
"*.ts": -1000,
"*.vob": -5000,
"*.mp4": -500,
"*.mkv": 500,
"*1080p*BluRay*": 15000,
"*720p*BluRay*": 10000,
"*HDTV*": -1000,
"*PROPER*": 1500,
"*REPACK*": 1500,
"*Remux*": 20000,
"*WEB*CasStudio*": 5000,
"*WEB*KINGS*": 5000,
"*WEB*NTB*": 5000,
"*WEB*QOQ*": 5000,
"*WEB*SiGMA*": 5000,
"*WEB*TBS*": -1000,
"*WEB*TROLLHD*": 2500,
"*WEB*VISUM*": 5000,
"*dvd*": -1000
},
"PLEX_LIBRARIES": [
"Bangumi"
],
"PLEX_SERVER": "https://your.plex/",
"PLEX_TOKEN": "",
"SCORE_FILESIZE": true,
"SKIP_LIST": [],
"VIDEO_CODEC_SCORES": {
"Unknown": 0,
"h264": 8000,
"h265": 10000,
"hevc": 10000,
"mpeg1video": 250,
"mpeg2video": 250,
"mpeg4": 500,
"msmpeg4": 100,
"msmpeg4v2": 100,
"msmpeg4v3": 100,
"vc1": 3000,
"vp9": 1000,
"wmv2": 250,
"wmv3": 250
},
"VIDEO_RESOLUTION_SCORES": {
"1080": 10000,
"480": 3000,
"4k": 20000,
"720": 5000,
"Unknown": 0,
"sd": 1000
}
}

统一启动 + 定时任务

这里需要再 flexget 执行后,需要跑一些脚本,不用 flexgetschedule,用 crontab 触发

run.sh

1
2
3
4
5
6
7
# ! /bin/bash
find /mnt/WEB-DL/ -type d -empty # 自动清空目录为空的文件夹
source /flexget/bin/activate
cd /config/flexget # 配置在这里
flexget --cron execute
python flexget-auto.py > flexget-auto.log
/plex_dupefinder/plex_dupefinder.sh > plex_dupefinder.log

再加入 crontab 就搞定啦~

1
*/10 * * * * "/flexget/run.sh"
作者

Kur4ge

发布于

2023-07-16

更新于

2023-07-15

许可协议

评论