Compare commits

..

No commits in common. "f9730f2994a43a71e61859dccbeef18515fa572f" and "efc2be761f8798e60add5921f4412e667882e874" have entirely different histories.

3 changed files with 12 additions and 42 deletions

View File

@ -38,7 +38,7 @@
- [x] 支持分享链接的子目录
- [x] 记录失效分享并跳过任务
- [x] 支持需提取码的分享链接 <sup>[?](https://github.com/x1ao4/quark-auto-save-x/wiki/使用技巧集锦#支持需提取码的分享链接)</sup>
- [x] 智能搜索资源并自动填充(**支持自动过滤失效链接** <sup>[?](https://github.com/x1ao4/quark-auto-save-x/wiki/资源搜索)</sup>
- [x] 智能搜索资源并自动填充(**支持自动过滤失效链接** <sup>[?](https://github.com/x1ao4/quark-auto-save-x/wiki/CloudSaver搜索源)</sup>
- 文件管理
- [x] 目标目录不存在时自动新建
@ -63,9 +63,9 @@
- 其它
- [x] 每日签到领空间 <sup>[?](https://github.com/x1ao4/quark-auto-save-x/wiki/使用技巧集锦#每日签到领空间)</sup>
- [x] 支持多个通知推送渠道 <sup>[?](https://github.com/x1ao4/quark-auto-save-x/wiki/通知置)</sup>
- [x] 支持多个通知推送渠道 <sup>[?](https://github.com/x1ao4/quark-auto-save-x/wiki/通知推送服务配置)</sup>
- [x] 支持多账号(多账号签到、**文件管理**,仅首账号转存)
- [x] 支持网盘文件下载、strm 文件生成等功能 <sup>[?](https://github.com/x1ao4/quark-auto-save-x/wiki/插件置)</sup>
- [x] 支持网盘文件下载、strm 文件生成等功能 <sup>[?](https://github.com/x1ao4/quark-auto-save-x/wiki/插件置)</sup>
- [x] **支持通过追剧日历功能了解订阅内容的播出情况**
## 部署
@ -86,6 +86,7 @@ docker run -d \
Docker Compose推荐
```yaml
version: "3.3"
services:
quark-auto-save-x:
image: x1ao4/quark-auto-save-x:latest
@ -129,10 +130,10 @@ services:
| `乘风2025 - S06E{}` | | 按照文件顺序命名,`{}` 会被代入序号,新增项目序号在已存在的最大序号的基础上递增 |
| `黑镜 - S07E[]` | | 自动识别文件名中的集编号,`[]` 会被代入从文件名中自动提取的集编号 |
更多正则使用说明:[命名规则](https://github.com/x1ao4/quark-auto-save-x/wiki/命名规则)
更多正则使用说明:[正则处理教程](https://github.com/x1ao4/quark-auto-save-x/wiki/正则处理教程)
### 刷新媒体库
在有新转存时,可触发完成相应功能,如自动刷新媒体库、生成 .strm 文件等。配置指南:[插件设置](https://github.com/x1ao4/quark-auto-save-x/wiki/插件设置)
在有新转存时,可触发完成相应功能,如自动刷新媒体库、生成 .strm 文件等。配置指南:[插件配置](https://github.com/x1ao4/quark-auto-save-x/wiki/插件配置)
媒体库模块以插件的方式的集成,如果你有兴趣请参考[插件开发指南](https://github.com/x1ao4/quark-auto-save-x/tree/x/plugins)。

View File

@ -699,13 +699,10 @@ def favicon():
def serve_cache_images(filename):
resp = send_from_directory(CACHE_IMAGES_DIR, filename)
try:
# 启用长期缓存:依赖前端通过 `?t=` 穿透参数在变更时刷新
# 说明:图片文件名稳定且内容稳定,正常情况应命中浏览器缓存;
# 当用户主动更换海报时,前端会为该节目生成新的时间戳参数,形成新的 URL从而触发重新下载。
resp.headers['Cache-Control'] = 'public, max-age=31536000, immutable'
# 清理可能的历史字段(部分代理可能保留)
resp.headers.pop('Pragma', None)
resp.headers.pop('Expires', None)
# 禁用强缓存,允许协商缓存
resp.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate, max-age=0'
resp.headers['Pragma'] = 'no-cache'
resp.headers['Expires'] = '0'
except Exception:
pass
return resp
@ -4356,11 +4353,6 @@ def redownload_all_posters():
# 更新数据库中的海报路径
cal_db.update_show_poster(int(tmdb_id), poster_local_path)
success_count += 1
# 通知前端该节目海报已更新
try:
notify_calendar_changed(f'poster_updated:{int(tmdb_id)}')
except Exception:
pass
except Exception as e:
logging.error(f"重新下载海报失败 (TMDB ID: {show.get('tmdb_id')}): {e}")
@ -4513,7 +4505,7 @@ def download_custom_poster(poster_url: str, tmdb_id: int, target_safe_name: str
with open(file_path, 'wb') as f:
f.write(r.content)
# 自定义海报保存成功(静默)
logging.info(f"成功保存自定义海报: {poster_url} -> {file_path}")
return f"/cache/images/{safe_name}"
except Exception as e:
@ -4828,12 +4820,6 @@ def calendar_refresh_show():
try:
notify_calendar_changed('refresh_show')
# 通知前端指定节目海报可能已更新,用于触发按节目维度的缓存穿透
try:
if tmdb_id:
notify_calendar_changed(f'poster_updated:{int(tmdb_id)}')
except Exception:
pass
except Exception:
pass
@ -5169,13 +5155,8 @@ def calendar_edit_metadata():
# 即使对比失败也不影响功能
pass
# 成功更新自定义海报(静默)
logging.info(f"成功更新自定义海报: TMDB ID {current_tmdb_id}, 路径: {saved_path}")
changed = True
# 仅当自定义海报保存成功时,通知前端该节目海报已更新
try:
notify_calendar_changed(f'poster_updated:{int(current_tmdb_id)}')
except Exception:
pass
else:
logging.warning(f"自定义海报保存失败: {custom_poster_url}")
except Exception as e:

View File

@ -5531,18 +5531,6 @@
let changeReason = '';
try { changeReason = JSON.parse(ev && ev.data || '{}').reason || ''; } catch (e) {}
// 如果是海报更新通知poster_updated:<tmdb_id>),为该节目设置缓存穿透,避免使用旧缓存
try {
if (typeof changeReason === 'string' && changeReason.startsWith('poster_updated:')) {
const idStr = changeReason.split(':')[1] || '';
const eid = parseInt(idStr, 10);
if (!isNaN(eid)) {
const nowTick = Date.now();
this.$set(this.imageCacheBustById, eid, nowTick);
}
}
} catch (e) {}
// 先拉取最新转存信息并重建映射(用于管理视图与进度判定)
try {
const latestRes = await axios.get('/task_latest_info');