Skip to content

Commit 47c5e76

Browse files
committed
fix: restore refresh_after_task function and fix scope issues in refreshService; bump to v0.1.2
1 parent 0314f49 commit 47c5e76

5 files changed

Lines changed: 61 additions & 39 deletions

File tree

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ services:
186186
# - DST_MOV_TARGETS=/shanct/电影 # 优先同步电影到此集合;支持 ,;: 分隔
187187
# - DST_REFRESH_TV=/media/电视剧,/videos/电视剧 # DST 同步时的刷新集合;支持 ,;: 分隔
188188
# - DST_REFRESH_MOV=/media/电影,/videos/电影 # DST 同步时的刷新集合;支持 ,;: 分隔
189-
- SYNC_TV_TARGETS=/115/videos/电视剧,/ODC/tv{max}/电视剧 # 回退电视剧同步集合;{odc_tv} → /ODC/tvX
190-
- SYNC_MOV_TARGETS=/115/videos/电影,/ODC/mov{max}/电影 # 回退电影同步集合;{odc_mov} → /ODC/movX
189+
- SYNC_TV_TARGETS=/115/videos/电视剧,/ODC/tv{max}/电视剧 # 回退电视剧同步集合;{max} → 自动匹配最大数字后缀目录
190+
- SYNC_MOV_TARGETS=/115/videos/电影,/ODC/mov{max}/电影 # 回退电影同步集合;{max} → 自动匹配最大数字后缀目录
191191
- SYNC_REFRESH_TV=/115/videos/电视剧,/ODC/tv{max}/电视剧,/videos/电视剧 # SYNC 同步时的刷新集合
192192
- SYNC_REFRESH_MOV=/115/videos/电影,/ODC/mov{max}/电影,/videos/电影 # SYNC 同步时的刷新集合
193193
volumes:
@@ -263,13 +263,13 @@ task_timeout=72
263263
| `TVsource` | 电视剧源根 | `/media/电视剧` |
264264
| `MOVsource` | 电影源根 | `/media/电影` |
265265
| `DST_TV_TARGETS` / `DST_MOV_TARGETS` | 优先同步根集合(原样使用),存在同名目录时仅同步到这里;仅在末尾追加“名称(年份)”;支持 `,;:` 分隔 | 例如 `/shanct/电视剧` 或 `/shanct/电影` |
266-
| `SYNC_TV_TARGETS` | 电视剧同步目标根集合,用 `,;:` 分隔,支持 `{odc_tv}`;仅在末尾追加“名称(年份)” | 例如 `/115/videos/电视剧,/ODC/{odc_tv}/电视剧` 或 `/115/videos/tv,/ODC/{odc_tv}/tv` |
267-
| `SYNC_MOV_TARGETS` | 电影同步目标根集合,支持 `{odc_mov}`;仅在末尾追加“名称(年份)” | 例如 `/115/videos/电影,/ODC/{odc_mov}/电影` 或 `/115/videos/mov,/ODC/{odc_mov}/mov` |
266+
| `SYNC_TV_TARGETS` | 电视剧同步目标根集合,用 `,;:` 分隔,支持 `{max}`;仅在末尾追加“名称(年份)” | 例如 `/115/videos/电视剧,/ODC/tv{max}/电视剧` 或 `/115/videos/tv,tv{max}/tv` |
267+
| `SYNC_MOV_TARGETS` | 电影同步目标根集合,支持 `{max}`;仅在末尾追加“名称(年份)” | 例如 `/115/videos/电影,/ODC/mov{max}/电影` 或 `/115/videos/mov,mov{max}/mov` |
268268
| `DST_REFRESH_TV` / `DST_REFRESH_MOV` | 当命中 `DST_*` 同步集合时使用的刷新集合;仅在末尾追加“名称(年份)”;支持 `,;:` 分隔 | 例如 `/media/电视剧,/videos/电视剧` 或 `/media/电影,/videos/电影` |
269-
| `SYNC_REFRESH_TV` | 当走 `SYNC_*` 同步集合时使用的刷新集合(仅在末尾追加“名称(年份)”) | 例如 `/115/videos/电视剧,/ODC/{odc_tv}/电视剧,/videos/电视剧` |
270-
| `SYNC_REFRESH_MOV` | 当走 `SYNC_*` 同步集合时使用的刷新集合(仅在末尾追加“名称(年份)”) | 例如 `/115/videos/电影,/ODC/{odc_mov}/电影,/videos/电影` |
269+
| `SYNC_REFRESH_TV` | 当走 `SYNC_*` 同步集合时使用的刷新集合(仅在末尾追加“名称(年份)”) | 例如 `/115/videos/电视剧,/ODC/tv{max}/电视剧,/videos/电视剧` |
270+
| `SYNC_REFRESH_MOV` | 当走 `SYNC_*` 同步集合时使用的刷新集合(仅在末尾追加“名称(年份)”) | 例如 `/115/videos/电影,/ODC/mov{max}/电影,/videos/电影` |
271271

272-
- 占位符说明:`{max}` 会替换为 `最大阿拉伯数值` 的最大值(如`/ODC/tv{max}` 有 `tv1-10` 扫描 `/ODC` 选择 `/tv10` 当前最大序号)
272+
- 占位符说明:`{max}` 占位符(支持任意层级)。语法:`前缀{max}`(如 `tv{max}`、`disk{max}`)。系统会自动扫描父目录下(如果未指定父目录则默认为根目录 `/`)以该前缀开头的所有子目录,并选择数字后缀最大的那个。例如:`/ODC/tv{max}/电视剧` 会扫描 `/ODC` 下的 `tv*`,若有 `tv1`~`tv9`,则替换为 `/ODC/tv9/电视剧`
273273
- 源存在判定:`TVsource` 或 `MOVsource` 下存在 `名称(年份)` 目录才会创建作业。
274274

275275

docker-compose.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ services:
1717
# - DST_MOV_TARGETS=/shanct/电影 # 优先同步电影到此集合;支持 ,;: 分隔
1818
# - DST_REFRESH_TV=/media/电视剧,/videos/电视剧 # DST 同步时的刷新集合;支持 ,;: 分隔
1919
# - DST_REFRESH_MOV=/media/电影,/videos/电影 # DST 同步时的刷新集合;支持 ,;: 分隔
20-
- SYNC_TV_TARGETS=/115/videos/电视剧,/ODC/{odc_tv}/电视剧 # 回退电视剧同步集合;{odc_tv} → /ODC/tvX
21-
- SYNC_MOV_TARGETS=/115/videos/电影,/ODC/{odc_mov}/电影 # 回退电影同步集合;{odc_mov} → /ODC/movX
22-
- SYNC_REFRESH_TV=/115/videos/电视剧,/ODC/{odc_tv}/电视剧,/videos/电视剧 # SYNC 同步时的刷新集合
23-
- SYNC_REFRESH_MOV=/115/videos/电影,/ODC/{odc_mov}/电影,/videos/电影 # SYNC 同步时的刷新集合
20+
- SYNC_TV_TARGETS=/115/videos/电视剧,/ODC/tv{max}/电视剧 # 回退电视剧同步集合;{max} → 自动匹配最大数字后缀目录
21+
- SYNC_MOV_TARGETS=/115/videos/电影,/ODC/mov{max}/电影 # 回退电影同步集合;{max} → 自动匹配最大数字后缀目录
22+
- SYNC_REFRESH_TV=/115/videos/电视剧,/ODC/tv{max}/电视剧,/videos/电视剧 # SYNC 同步时的刷新集合
23+
- SYNC_REFRESH_MOV=/115/videos/电影,/ODC/mov{max}/电影,/videos/电影 # SYNC 同步时的刷新集合
2424
volumes:
2525
- ./data:/app/data

service/webhook/refreshService.py

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,16 @@ def _find_max_dir(client, parent_dir, prefix):
7373
except Exception:
7474
return f"{prefix}1"
7575

76-
def _expand_targets(env_s):
76+
77+
def _expand_targets(env_s, client):
7778
arr = []
7879
if not env_s:
7980
return arr
8081
raw = [p.strip() for p in re.split(r"[,;:]", env_s) if p and p.strip() != '']
8182

82-
# 兼容旧逻辑:先计算出默认的 /ODC 下的 tv/mov 前缀
83-
tv_prefix_default = _find_max_dir(client, '/ODC', 'tv')
84-
mov_prefix_default = _find_max_dir(client, '/ODC', 'mov')
83+
# 兼容旧逻辑:默认搜索根目录 / 下的 tv/mov 前缀
84+
tv_prefix_default = _find_max_dir(client, '/', 'tv')
85+
mov_prefix_default = _find_max_dir(client, '/', 'mov')
8586

8687
for base in raw:
8788
# 1. 处理通用 {max} 语法
@@ -93,14 +94,14 @@ def max_replacer(match):
9394
parent = match.group(1) # e.g. "/a/b/" or ""
9495
prefix = match.group(2) # e.g. "disk"
9596

96-
# 如果没有父路径,默认使用 /ODC
97-
search_dir = parent if parent else '/ODC'
97+
# 如果没有父路径,默认使用根目录 /
98+
search_dir = parent if parent else '/'
9899

99100
best_name = _find_max_dir(client, search_dir, prefix)
100101

101-
# 如果父路径为空(隐含 /ODC),则返回完整路径 /ODC/best_name
102+
# 如果父路径为空(隐含 /),则返回完整路径 /best_name
102103
if not parent:
103-
return f"/ODC/{best_name}"
104+
return f"/{best_name}"
104105
# 否则返回 原父路径 + best_name
105106
return f"{parent}{best_name}"
106107

@@ -114,10 +115,42 @@ def max_replacer(match):
114115
base = re.sub(r"/{2,}", "/", base).rstrip('/')
115116
arr.append(base)
116117
return arr
118+
119+
120+
_recent_refresh = {}
121+
122+
123+
def refresh_after_task(job, status):
124+
logger = logging.getLogger()
125+
if status not in [2, 3]:
126+
logger.info(f"Refresh skipped: status {status} not in [2, 3]")
127+
return
128+
logger.info(f"Refresh start: job={job.get('remark')}, status={status}")
129+
130+
openlistId = int(job['openlistId'])
131+
client = openlistService.getClientById(openlistId)
132+
remark = job.get('remark') or ''
133+
src = job.get('srcPath') or ''
134+
dsts = (job.get('dstPath') or '').split(':') if job.get('dstPath') else []
135+
src_norm = re.sub(r"/{2,}", "/", src).rstrip('/') + '/'
136+
tv_src_env = (os.getenv('TVsource') or '').strip()
137+
mov_src_env = (os.getenv('MOVsource') or '').strip()
138+
tv_src_norm = re.sub(r"/{2,}", "/", tv_src_env).rstrip('/') + '/' if tv_src_env else ''
139+
mov_src_norm = re.sub(r"/{2,}", "/", mov_src_env).rstrip('/') + '/' if mov_src_env else ''
140+
is_tv = bool(tv_src_norm and src_norm.startswith(tv_src_norm))
141+
logger.info(f"Refresh context: is_tv={is_tv}, src={src}, dsts={dsts}")
142+
odc_prefix = None
143+
base_paths = []
144+
name = remark
145+
dedup = []
146+
seen = set()
147+
tv_src = os.getenv('TVsource') or ''
148+
mov_src = os.getenv('MOVsource') or ''
149+
117150
dst_target_env = os.getenv('DST_TV_TARGETS') if is_tv else os.getenv('DST_MOV_TARGETS')
118151
sync_target_env = os.getenv('SYNC_TV_TARGETS') if is_tv else os.getenv('SYNC_MOV_TARGETS')
119-
dst_bases = _expand_targets(dst_target_env)
120-
sync_bases = _expand_targets(sync_target_env)
152+
dst_bases = _expand_targets(dst_target_env, client)
153+
sync_bases = _expand_targets(sync_target_env, client)
121154
dst_used = False
122155
for d in dsts:
123156
for b in dst_bases:
@@ -137,12 +170,10 @@ def max_replacer(match):
137170
env_refresh = os.getenv('SYNC_REFRESH_MOV') or os.getenv('REFRESH_MOV_TARGETS')
138171

139172
logger.info(f"Refresh env config: dst_used={dst_used}, env_refresh={env_refresh}")
140-
173+
141174
if env_refresh:
142175
# 使用通用展开逻辑处理刷新路径中的 {max}
143-
# 注意:这里我们递归调用 _expand_targets 来处理 env_refresh 字符串
144-
# 但 _expand_targets 内部会返回列表,我们需要处理这个列表
145-
raw_refresh_paths = _expand_targets(env_refresh)
176+
raw_refresh_paths = _expand_targets(env_refresh, client)
146177
for base in raw_refresh_paths:
147178
path = f"{base}/{name}"
148179
if path not in seen:
@@ -207,4 +238,4 @@ def max_replacer(match):
207238
last = _recent_refresh.get(key)
208239
if last and now - last < 60:
209240
return
210-
_recent_refresh[key] = now
241+
_recent_refresh[key] = now

service/webhook/webhookService.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def _pick(prefix):
147147
if not parent_dir.startswith('/'):
148148
parent_dir = '/' + parent_dir
149149
else:
150-
parent_dir = '/ODC'
150+
parent_dir = '/'
151151
search_prefix = prefix
152152

153153
dirs = client.filePathList(parent_dir)
@@ -161,12 +161,6 @@ def _pick(prefix):
161161
if n > best_n:
162162
best_n = n
163163
best = name
164-
# 如果是全路径模式,返回完整路径;否则仅返回文件名(旧逻辑兼容)
165-
# 但这里的 _pick 原本只返回文件名(如 tv14)
166-
# 调用方 re.sub(..., lambda m: _pick(m.group(1)))
167-
# 如果 regex 是 ([^/]*)\{max\},它只捕获了文件名部分
168-
# 这意味着它不支持路径?
169-
# 确实,webhookService.py 的 regex 需要同步更新!
170164
return best or f"{search_prefix}1"
171165
except Exception:
172166
if '/' in prefix:
@@ -179,10 +173,7 @@ def max_replacer(match):
179173
parent = match.group(1) # e.g. "/a/b/" or ""
180174
prefix = match.group(2) # e.g. "disk"
181175

182-
# 构造 _pick 需要的参数:如果是 /ODC 下的,传文件名;否则传完整路径前缀
183-
# 但 _pick 上面我改写成了支持路径的
184-
# 如果 parent 为空,传 prefix (tv) -> _pick 内部用 /ODC
185-
# 如果 parent 不为空,传 parent + prefix (/a/b/disk) -> _pick 内部解析
176+
# 构造 _pick 需要的参数:如果是 / 下的,传文件名;否则传完整路径前缀
186177

187178
arg = prefix
188179
if parent:
@@ -193,7 +184,7 @@ def max_replacer(match):
193184
# _pick 返回的是纯文件名 (best_name)
194185
# 我们需要重新组装
195186
if not parent:
196-
return f"/ODC/{best_name}"
187+
return f"/{best_name}"
197188
return f"{parent}{best_name}"
198189

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

version.txt

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

33

44
该文件仅第一行有效,表示打包的版本。

0 commit comments

Comments
 (0)