Compare commits

...

6 Commits

Author SHA1 Message Date
xiaoQQya
060b8fac89
Merge 78581b15a7 into 2c2aa50a88 2025-09-09 00:06:53 +08:00
Cp0204
2c2aa50a88 🐛 修复一次性转存>100个时的报错
Some checks failed
Docker Publish / build-and-push (push) Has been cancelled
2025-09-06 22:17:11 +08:00
Cp0204
5cc955f590 适配官方新的分享子目录链接格式
Some checks failed
Docker Publish / build-and-push (push) Has been cancelled
2025-09-05 16:18:30 +08:00
Cp0204
33215957bf 📦 优化版本信息设置和获取方式 2025-09-05 12:18:06 +08:00
Cp0204
473ac0d468 优化 SmartStrm 插件初始化逻辑 2025-09-05 12:17:30 +08:00
xiaoQQya
78581b15a7 feat: 魔法变量 {E} 支持零填充格式化 2025-08-20 23:33:51 +08:00
5 changed files with 96 additions and 48 deletions

View File

@ -1,6 +1,12 @@
# 使用官方 Python 镜像作为基础镜像
FROM python:3.13-alpine
#构建版本
ARG BUILD_SHA
ARG BUILD_TAG
ENV BUILD_SHA=$BUILD_SHA
ENV BUILD_TAG=$BUILD_TAG
# 设置工作目录
WORKDIR /app
@ -8,17 +14,12 @@ WORKDIR /app
COPY . /app
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir -r requirements.txt && \
echo "{\"BUILD_SHA\":\"$BUILD_SHA\", \"BUILD_TAG\":\"$BUILD_TAG\"}" > build.json
# 时区
ENV TZ="Asia/Shanghai"
#构建版本
ARG BUILD_SHA
ARG BUILD_TAG
ENV BUILD_SHA=$BUILD_SHA
ENV BUILD_TAG=$BUILD_TAG
# 端口
EXPOSE 5005

View File

@ -34,8 +34,15 @@ from quark_auto_save import Quark, Config, MagicRename
def get_app_ver():
BUILD_SHA = os.environ.get("BUILD_SHA", "")
BUILD_TAG = os.environ.get("BUILD_TAG", "")
"""获取应用版本"""
try:
with open("build.json", "r") as f:
build_info = json.loads(f.read())
BUILD_SHA = build_info["BUILD_SHA"]
BUILD_TAG = build_info["BUILD_TAG"]
except Exception as e:
BUILD_SHA = os.getenv("BUILD_SHA", "")
BUILD_TAG = os.getenv("BUILD_TAG", "")
if BUILD_TAG[:1] == "v":
return BUILD_TAG
elif BUILD_SHA:
@ -316,7 +323,9 @@ def get_share_detail():
return jsonify(
{"success": False, "data": {"error": get_stoken.get("message")}}
)
share_detail = account.get_detail(pwd_id, stoken, pdir_fid, _fetch_share=1)
share_detail = account.get_detail(
pwd_id, stoken, pdir_fid, _fetch_share=1, fetch_share_full_path=1
)
if share_detail.get("code") != 0:
return jsonify(
@ -324,7 +333,10 @@ def get_share_detail():
)
data = share_detail["data"]
data["paths"] = paths
data["paths"] = [
{"fid": i["fid"], "name": i["file_name"]}
for i in share_detail["data"].get("full_path", [])
] or paths
data["stoken"] = stoken
# 正则处理预览

View File

@ -1220,9 +1220,9 @@
} else if (shareurl.includes(dir.fid)) {
shareurl = shareurl.match(`.*/${dir.fid}[^/]*`)[0]
} else if (shareurl.includes('#/list/share')) {
shareurl = `${shareurl}/${dir.fid}-${dir.name?.replace('-', '*101')}`
shareurl = `${shareurl.split('#')[0]}#/list/share/${dir.fid}`
} else {
shareurl = `${shareurl}#/list/share/${dir.fid}-${dir.name?.replace('-', '*101')}`
shareurl = `${shareurl.split('#')[0]}#/list/share/${dir.fid}`
}
return shareurl;
},

View File

@ -18,8 +18,26 @@ class Smartstrm:
else:
print(f"{self.plugin_name} 模块缺少必要参数: {key}")
if self.webhook and self.strmtask:
print(f"SmartStrm 触发任务: {self.strmtask} ")
self.is_active = True
if self.get_info():
self.is_active = True
def get_info(self):
"""获取 SmartStrm 信息"""
try:
response = requests.request(
"GET",
self.webhook,
timeout=5,
)
response = response.json()
if response.get("success"):
print(f"SmartStrm 触发任务: 连接成功 {response.get('version','')}")
return response
print(f"SmartStrm 触发任务:连接失败 {response.get('message','')}")
return None
except Exception as e:
print(f"SmartStrm 触发任务:连接出错 {str(e)}")
return None
def run(self, task, **kwargs):
"""

View File

@ -1,6 +1,6 @@
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
# Modify: 2024-11-13
# Modify: 2025-09-05
# Repo: https://github.com/Cp0204/quark_auto_save
# ConfigFile: quark_config.json
"""
@ -164,7 +164,7 @@ class MagicRename:
"{YEAR}": [r"(?<!\d)(18|19|20)\d{2}(?!\d)"],
"{S}": [r"(?<=[Ss])\d{1,2}(?=[EeXx])", r"(?<=[Ss])\d{1,2}"],
"{SXX}": [r"[Ss]\d{1,2}(?=[EeXx])", r"[Ss]\d{1,2}"],
"{E}": [
"{E+}": [
r"(?<=[Ss]\d\d[Ee])\d{1,3}",
r"(?<=[Ee])\d{1,3}",
r"(?<=[Ee][Pp])\d{1,3}",
@ -224,7 +224,7 @@ class MagicRename:
return file_name
# 预处理替换变量
for key, p_list in self.magic_variable.items():
if key in replace:
if match_key := re.search(key, replace):
# 正则类替换变量
if p_list and isinstance(p_list, list):
for p in p_list:
@ -240,7 +240,10 @@ class MagicRename:
value = (
str(datetime.now().year)[: (8 - len(value))] + value
)
replace = replace.replace(key, value)
# 集数零填充处理
elif key == "{E+}":
value = value.lstrip("0").zfill(match_key.group().count("E"))
replace = re.sub(key, value, replace)
break
# 非正则类替换变量
if key == "{TASKNAME}":
@ -251,7 +254,7 @@ class MagicRename:
continue
else:
# 清理未匹配的 magic_variable key
replace = replace.replace(key, "")
replace = re.sub(key, "", replace)
if pattern and replace:
file_name = re.sub(pattern, replace, file_name)
else:
@ -497,7 +500,9 @@ class Quark:
).json()
return response
def get_detail(self, pwd_id, stoken, pdir_fid, _fetch_share=0):
def get_detail(
self, pwd_id, stoken, pdir_fid, _fetch_share=0, fetch_share_full_path=0
):
list_merge = []
page = 1
while True:
@ -515,6 +520,8 @@ class Quark:
"_fetch_share": _fetch_share,
"_fetch_total": "1",
"_sort": "file_type:asc,updated_at:desc",
"ver": "2",
"fetch_share_full_path": fetch_share_full_path,
}
response = self._send_request("GET", url, params=querystring).json()
if response["code"] != 0:
@ -709,6 +716,7 @@ class Quark:
match_pwd = re.search(r"pwd=(\w+)", url)
passcode = match_pwd.group(1) if match_pwd else ""
# path: fid-name
# Legacy 20250905
paths = []
matches = re.findall(r"/(\w{32})-?([^/]+)?", url)
for match in matches:
@ -967,36 +975,45 @@ class Quark:
fid_list = [item["fid"] for item in need_save_list]
fid_token_list = [item["share_fid_token"] for item in need_save_list]
if fid_list:
save_file_return = self.save_file(
fid_list, fid_token_list, to_pdir_fid, pwd_id, stoken
)
err_msg = None
if save_file_return["code"] == 0:
task_id = save_file_return["data"]["task_id"]
query_task_return = self.query_task(task_id)
if query_task_return["code"] == 0:
# 建立目录树
for index, item in enumerate(need_save_list):
icon = self._get_file_icon(item)
tree.create_node(
f"{icon}{item['file_name_re']}",
item["fid"],
parent=pdir_fid,
data={
"file_name": item["file_name"],
"file_name_re": item["file_name_re"],
"fid": f"{query_task_return['data']['save_as']['save_as_top_fids'][index]}",
"path": f"{savepath}/{item['file_name_re']}",
"is_dir": item["dir"],
"obj_category": item.get("obj_category", ""),
},
save_as_top_fids = []
while fid_list:
# 分次转存100个/次因query_task返回save_as_top_fids最多100
save_file_return = self.save_file(
fid_list[:100], fid_token_list[:100], to_pdir_fid, pwd_id, stoken
)
fid_list = fid_list[100:]
fid_token_list = fid_token_list[100:]
if save_file_return["code"] == 0:
# 转存成功,查询转存结果
task_id = save_file_return["data"]["task_id"]
query_task_return = self.query_task(task_id)
if query_task_return["code"] == 0:
save_as_top_fids.extend(
query_task_return["data"]["save_as"]["save_as_top_fids"]
)
else:
err_msg = query_task_return["message"]
else:
err_msg = query_task_return["message"]
else:
err_msg = save_file_return["message"]
if err_msg:
add_notify(f"❌《{task['taskname']}》转存失败:{err_msg}\n")
err_msg = save_file_return["message"]
if err_msg:
add_notify(f"❌《{task['taskname']}》转存失败:{err_msg}\n")
# 建立目录树
for index, item in enumerate(need_save_list):
icon = self._get_file_icon(item)
tree.create_node(
f"{icon}{item['file_name_re']}",
item["fid"],
parent=pdir_fid,
data={
"file_name": item["file_name"],
"file_name_re": item["file_name_re"],
"fid": f"{save_as_top_fids[index]}",
"path": f"{savepath}/{item['file_name_re']}",
"is_dir": item["dir"],
"obj_category": item.get("obj_category", ""),
},
)
return tree
def do_rename(self, tree, node_id=None):