Skip to content

Commit f8e9d5d

Browse files
committed
docs: v0.1.7 changelog and README SECOND usage\nchore: bump version to v0.1.7
1 parent 5486c8c commit f8e9d5d

5 files changed

Lines changed: 72 additions & 7 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ services:
193193
- SYNC_MOV_TARGETS=/115/videos/电影,/ODC/mov{max}/电影 # 回退电影同步集合;{max} → 自动匹配最大数字后缀目录
194194
- SYNC_REFRESH_TV=/115/videos/电视剧,/ODC/tv{max}/电视剧,/videos/电视剧 # SYNC 同步时的刷新集合
195195
- SYNC_REFRESH_MOV=/115/videos/电影,/ODC/mov{max}/电影,/videos/电影 # SYNC 同步时的刷新集合
196+
- SECOND=true # 启用二级目录(从 webhook 文本“类别:xxx”解析为二级路径,电视剧与电影均支持)
196197
volumes:
197198
- ./data:/app/data
198199
```
@@ -274,6 +275,7 @@ task_timeout=72
274275
| `DST_REFRESH_TV` `DST_REFRESH_MOV` | 当命中 `DST_*` 同步集合时使用的刷新集合;仅在末尾追加“名称(年份)”;支持 `,;:` 分隔 | 例如 `/media/电视剧,/videos/电视剧` 或 `/media/电影,/videos/电影` |
275276
| `SYNC_REFRESH_TV` | 当走 `SYNC_*` 同步集合时使用的刷新集合(仅在末尾追加“名称(年份)”) | 例如 `/115/videos/电视剧,/ODC/tv{max}/电视剧,/videos/电视剧` |
276277
| `SYNC_REFRESH_MOV` | 当走 `SYNC_*` 同步集合时使用的刷新集合(仅在末尾追加“名称(年份)”) | 例如 `/115/videos/电影,/ODC/mov{max}/电影,/videos/电影` |
278+
| `SECOND` | 启用二级目录(从 webhook 文本“类别:xxx”解析为二级路径);开启后源与目标都将拼接该二级目录;电视剧与电影均支持 | `true` |
277279

278280
- 占位符说明:`{max}` 占位符(支持任意层级)。语法:`前缀{max}`(如 `tv{max}`、`disk{max}`)。系统会自动扫描父目录下(如果未指定父目录则默认为根目录 `/`)以该前缀开头的所有子目录,并选择数字后缀最大的那个。例如:`/ODC/tv{max}/电视剧` 会扫描 `/ODC` 下的 `tv*`,若有 `tv1`~`tv9`,则替换为 `/ODC/tv9/电视剧`。
279281
- 源存在判定:`TVsource` 或 `MOVsource` 下存在 `名称(年份)` 目录才会创建作业。
@@ -308,4 +310,4 @@ fd1/* 表示忽略/fd1/,/fd0/df1/等下所有文件
308310
309311
## Star随时间
310312
311-
[![Stargazers over time](https://starchart.cc/syscc/OpenlistSync.svg?variant=adaptive)](https://starchart.cc/syscc/OpenlistSync)
313+
[![Stargazers over time](https://starchart.cc/syscc/OpenlistSync.svg?variant=adaptive)](https://starchart.cc/syscc/OpenlistSync)

doc/changelog/v0.1.7.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# v0.1.7(2026-01-13)
2+
3+
变更概述
4+
5+
- 新增:引入二级目录开关变量 SECOND(1/true/yes 启用),从 webhook 文本中解析“类别:xxx”,将其作为二级路径用于源与目标目录的拼接(电视剧与电影均支持)。对应代码:service/webhook/webhookService.py
6+
- 修复:刷新集合(DST/SYNC)缺失路径的问题,现已在刷新路径拼接时纳入二级目录层;并保留对所有 Season 目录的逐个刷新。对应代码:service/webhook/refreshService.py
7+
- 统一:将此前仅电视剧支持的二级目录检测与命中逻辑扩展到电影,同步与刷新逻辑保持一致。
8+
9+
使用说明
10+
11+
- 在 data/config.ini 的 [OpenlistSync] 段添加 SECOND=true 即可启用;
12+
- webhook 文本需包含“类别:xxx”以确定二级目录(如“综艺”、“动作”等)。

service/webhook/refreshService.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,18 @@ def refresh_after_task(job, status):
136136
logger.info(f"Refresh context: is_tv={is_tv}, src={src}, dsts={dsts}")
137137
base_paths = []
138138
name = remark
139+
# 解析二级目录:从源路径中提取根之后到剧名之前的第一级目录
140+
second_level = None
141+
try:
142+
root_norm = tv_src_norm if is_tv else mov_src_norm
143+
if root_norm:
144+
tail = src_norm[len(root_norm):]
145+
tail = tail.lstrip('/')
146+
segs = [s for s in tail.split('/') if s]
147+
if segs and segs[0] != name:
148+
second_level = segs[0]
149+
except Exception:
150+
second_level = None
139151
dedup = []
140152
seen = set()
141153
tv_src = os.getenv('TVsource') or ''
@@ -169,6 +181,8 @@ def refresh_after_task(job, status):
169181
raw_refresh_paths = _expand_targets(env_refresh, client)
170182
for base in raw_refresh_paths:
171183
path = f"{base}/{name}"
184+
if second_level:
185+
path = f"{base}/{second_level}/{name}"
172186
if path not in seen:
173187
dedup.append(path)
174188
seen.add(path)
@@ -190,6 +204,8 @@ def refresh_after_task(job, status):
190204
if base:
191205
base = re.sub(r"/{2,}", "/", base).rstrip('/')
192206
path = f"{base}/{name}"
207+
if second_level:
208+
path = f"{base}/{second_level}/{name}"
193209
if path not in seen:
194210
dedup.append(path)
195211
seen.add(path)

service/webhook/webhookService.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ def parse_tv_title_to_remark(s):
6666
return None
6767
remark = parse_tv_title_to_remark(title) or parse_tv_title_to_remark(text)
6868

69+
def parse_second_level(s):
70+
if not s:
71+
return None
72+
m = re.search(r"类别[::]\s*([^\n\r,,;;]+)", s)
73+
if m:
74+
val = m.group(1).strip()
75+
# 清理可能的括号说明等
76+
val = re.sub(r"\s+", " ", val)
77+
return val if val else None
78+
return None
79+
6980
if remark:
7081
delay = req.get('delay', None)
7182
def _read_env_file(key):
@@ -168,13 +179,23 @@ def _is_tv(s):
168179
tv_src = os.getenv('TVsource') or ''
169180
mov_src = os.getenv('MOVsource') or ''
170181
media_root = tv_src if tv_flag else mov_src
182+
# 二级目录开关
183+
second_level_enable = (os.getenv('SECOND', 'false').lower() in ['1','true','yes'])
184+
second_level = parse_second_level(title or '') or parse_second_level(text or '')
171185
has_src = False
172186

173187
# 尝试查找源目录,支持半角冒号转全角冒号
174188
final_remark = remark
175189
if client is not None:
176190
try:
177-
dirs = client.filePathList(media_root)
191+
# 当启用二级目录且存在二级名称时,优先在二级目录下查找
192+
root_for_list = media_root
193+
if second_level_enable and second_level:
194+
try:
195+
root_for_list = re.sub(r"/{2,}", "/", f"{media_root.rstrip('/')}/{second_level}")
196+
except Exception:
197+
root_for_list = media_root
198+
dirs = client.filePathList(root_for_list)
178199
names = [d['path'] for d in dirs]
179200
if remark in names:
180201
has_src = True
@@ -268,7 +289,11 @@ def max_replacer(match):
268289

269290
return re.sub(r"(^|.*?/)([^/]*)\{max\}", max_replacer, path_str)
270291

271-
srcPath = f"{media_root.rstrip('/')}/{remark}/"
292+
# 组装源目录(支持二级目录)
293+
if second_level_enable and second_level:
294+
srcPath = f"{media_root.rstrip('/')}/{second_level}/{remark}/"
295+
else:
296+
srcPath = f"{media_root.rstrip('/')}/{remark}/"
272297
dst_env = os.getenv('DST_TV_TARGETS') if tv_flag else os.getenv('DST_MOV_TARGETS')
273298
dsts = []
274299
if dst_env and client is not None:
@@ -280,10 +305,17 @@ def max_replacer(match):
280305
if not base.startswith('/'):
281306
base = '/' + base
282307
base = re.sub(r"/{2,}", "/", base).rstrip('/')
283-
exists_dirs = client.filePathList(base)
308+
# 二级目录下的存在性检测
309+
base_for_list = base
310+
if second_level_enable and second_level:
311+
base_for_list = f"{base}/{second_level}"
312+
exists_dirs = client.filePathList(base_for_list)
284313
names = [d['path'] for d in exists_dirs]
285314
if remark in names:
286-
dsts = [f"{base}/{remark}/"]
315+
if second_level_enable and second_level:
316+
dsts = [f"{base}/{second_level}/{remark}/"]
317+
else:
318+
dsts = [f"{base}/{remark}/"]
287319
break
288320
except Exception:
289321
pass
@@ -297,7 +329,10 @@ def max_replacer(match):
297329
if not base.startswith('/'):
298330
base = '/' + base
299331
base = re.sub(r"/{2,}", "/", base).rstrip('/')
300-
dsts.append(f"{base}/{remark}/")
332+
if second_level_enable and second_level:
333+
dsts.append(f"{base}/{second_level}/{remark}/")
334+
else:
335+
dsts.append(f"{base}/{remark}/")
301336
else:
302337
try:
303338
notify_list = notifyService.getNotifyList(True)

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
v0.1.6,latest
1+
v0.1.7,latest
22

33
该文件仅第一行有效,表示打包的版本。
44
如果要打包多个,以英文,分隔,例如【v1.0.0,latest】;

0 commit comments

Comments
 (0)