mirror of
https://github.com/Cp0204/quark-auto-save.git
synced 2026-01-16 01:10:44 +08:00
优化新增文件时日志打印信息的方式,调整预览界面
This commit is contained in:
parent
be96a693ff
commit
50416ca514
143
app/run.py
143
app/run.py
@ -322,118 +322,49 @@ def get_share_detail():
|
|||||||
else:
|
else:
|
||||||
regex_pattern = re.escape(sequence_pattern).replace('\\{\\}', '(\\d+)')
|
regex_pattern = re.escape(sequence_pattern).replace('\\{\\}', '(\\d+)')
|
||||||
|
|
||||||
# 实现高级排序算法
|
# 实现与实际重命名相同的排序算法
|
||||||
def extract_sorting_value(file):
|
def extract_sort_value(file):
|
||||||
if file["dir"]: # 跳过文件夹
|
if file["dir"]: # 跳过文件夹
|
||||||
return float('inf')
|
return float('inf')
|
||||||
|
|
||||||
filename = file["file_name"]
|
file_name = file["file_name"]
|
||||||
|
|
||||||
# 提取文件名,不含扩展名
|
# 1. 首先尝试提取期数(第X期)
|
||||||
file_name_without_ext = os.path.splitext(filename)[0]
|
period_match = re.search(r'第(\d+)期[上中下]', file_name)
|
||||||
|
if period_match:
|
||||||
|
period_num = int(period_match.group(1))
|
||||||
|
# 根据上中下调整排序
|
||||||
|
if '上' in file_name:
|
||||||
|
return period_num * 3 - 2
|
||||||
|
elif '中' in file_name:
|
||||||
|
return period_num * 3 - 1
|
||||||
|
elif '下' in file_name:
|
||||||
|
return period_num * 3
|
||||||
|
return period_num * 3
|
||||||
|
|
||||||
# 1. "第X期/集/话" 格式
|
# 2. 尝试提取日期格式(YYYY-MM-DD)
|
||||||
match_chinese = re.search(r'第(\d+)[期集话]', filename)
|
date_match = re.search(r'(\d{4})-(\d{2})-(\d{2})', file_name)
|
||||||
episode_num = int(match_chinese.group(1)) if match_chinese else 0
|
if date_match:
|
||||||
|
year = int(date_match.group(1))
|
||||||
|
month = int(date_match.group(2))
|
||||||
|
day = int(date_match.group(3))
|
||||||
|
base_value = year * 10000 + month * 100 + day
|
||||||
|
# 如果同一天有多个文件,根据"上中下"或其他标识符进行排序
|
||||||
|
if '上' in file_name:
|
||||||
|
return base_value * 10 + 1
|
||||||
|
elif '中' in file_name:
|
||||||
|
return base_value * 10 + 2
|
||||||
|
elif '下' in file_name:
|
||||||
|
return base_value * 10 + 3
|
||||||
|
return base_value * 10
|
||||||
|
|
||||||
# 5. 文件名含"上中下"(优先处理,因为可能与其他格式同时存在)
|
# 3. 尝试提取任何数字
|
||||||
if match_chinese:
|
number_match = re.search(r'(\d+)', file_name)
|
||||||
# 如果同时存在集数和上中下,则按照集数*10+位置排序
|
if number_match:
|
||||||
if '上' in filename:
|
return int(number_match.group(1))
|
||||||
return episode_num * 10 + 1
|
|
||||||
elif '中' in filename:
|
|
||||||
return episode_num * 10 + 2
|
|
||||||
elif '下' in filename:
|
|
||||||
return episode_num * 10 + 3
|
|
||||||
elif '上' in filename:
|
|
||||||
return 1
|
|
||||||
elif '中' in filename:
|
|
||||||
return 2
|
|
||||||
elif '下' in filename:
|
|
||||||
return 3
|
|
||||||
|
|
||||||
# 如果已经匹配到"第X期/集/话"格式,直接返回
|
# 4. 默认使用原文件名
|
||||||
if episode_num > 0:
|
return float('inf')
|
||||||
return episode_num * 10
|
|
||||||
|
|
||||||
# 2.1 S01E01 格式,提取季数和集数
|
|
||||||
match_s_e = re.search(r'[Ss](\d+)[Ee](\d+)', filename)
|
|
||||||
if match_s_e:
|
|
||||||
season = int(match_s_e.group(1))
|
|
||||||
episode = int(match_s_e.group(2))
|
|
||||||
return season * 1000 + episode
|
|
||||||
|
|
||||||
# 2.2 E01 格式,仅提取集数
|
|
||||||
match_e = re.search(r'[Ee][Pp]?(\d+)', filename)
|
|
||||||
if match_e:
|
|
||||||
return int(match_e.group(1))
|
|
||||||
|
|
||||||
# 2.3 1x01 格式,提取季数和集数
|
|
||||||
match_x = re.search(r'(\d+)[Xx](\d+)', filename)
|
|
||||||
if match_x:
|
|
||||||
season = int(match_x.group(1))
|
|
||||||
episode = int(match_x.group(2))
|
|
||||||
return season * 1000 + episode
|
|
||||||
|
|
||||||
# 3. 日期格式识别(支持多种格式)
|
|
||||||
|
|
||||||
# 3.1 完整的YYYYMMDD格式
|
|
||||||
match_date_compact = re.search(r'(20\d{2})(\d{2})(\d{2})', filename)
|
|
||||||
if match_date_compact:
|
|
||||||
year = int(match_date_compact.group(1))
|
|
||||||
month = int(match_date_compact.group(2))
|
|
||||||
day = int(match_date_compact.group(3))
|
|
||||||
return year * 10000 + month * 100 + day
|
|
||||||
|
|
||||||
# 3.2 YYYY-MM-DD 或 YYYY.MM.DD 或 YYYY/MM/DD 格式
|
|
||||||
match_date_full = re.search(r'(20\d{2})[-./](\d{1,2})[-./](\d{1,2})', filename)
|
|
||||||
if match_date_full:
|
|
||||||
year = int(match_date_full.group(1))
|
|
||||||
month = int(match_date_full.group(2))
|
|
||||||
day = int(match_date_full.group(3))
|
|
||||||
return year * 10000 + month * 100 + day
|
|
||||||
|
|
||||||
# 3.3 MM/DD/YYYY 或 DD/MM/YYYY 格式
|
|
||||||
match_date_alt = re.search(r'(\d{1,2})[-./](\d{1,2})[-./](20\d{2})', filename)
|
|
||||||
if match_date_alt:
|
|
||||||
# 假设第一个是月,第二个是日(美式日期)
|
|
||||||
month = int(match_date_alt.group(1))
|
|
||||||
day = int(match_date_alt.group(2))
|
|
||||||
year = int(match_date_alt.group(3))
|
|
||||||
# 检查月份值,如果大于12可能是欧式日期格式(DD/MM/YYYY)
|
|
||||||
if month > 12:
|
|
||||||
month, day = day, month
|
|
||||||
return year * 10000 + month * 100 + day
|
|
||||||
|
|
||||||
# 3.4 MM/DD 格式(无年份),假设为当前年
|
|
||||||
match_date_short = re.search(r'(\d{1,2})[-./](\d{1,2})', filename)
|
|
||||||
if match_date_short:
|
|
||||||
# 假设第一个是月,第二个是日
|
|
||||||
month = int(match_date_short.group(1))
|
|
||||||
day = int(match_date_short.group(2))
|
|
||||||
# 检查月份值,如果大于12可能是欧式日期格式(DD/MM)
|
|
||||||
if month > 12:
|
|
||||||
month, day = day, month
|
|
||||||
# 由于没有年份,使用一个较低的基数,确保任何有年份的日期都排在后面
|
|
||||||
return month * 100 + day
|
|
||||||
|
|
||||||
# 3.5 年期格式,如"2025年14期"
|
|
||||||
match_year_issue = re.search(r'(20\d{2})[年].*?(\d+)[期]', filename)
|
|
||||||
if match_year_issue:
|
|
||||||
year = int(match_year_issue.group(1))
|
|
||||||
issue = int(match_year_issue.group(2))
|
|
||||||
return year * 1000 + issue
|
|
||||||
|
|
||||||
# 4. 纯数字格式(文件名开头是纯数字)
|
|
||||||
match_num = re.match(r'^(\d+)', file_name_without_ext)
|
|
||||||
if match_num:
|
|
||||||
return int(match_num.group(1))
|
|
||||||
|
|
||||||
# 6. 默认使用更新时间
|
|
||||||
try:
|
|
||||||
return file.get("last_update_at", 0)
|
|
||||||
except:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
# 过滤出非目录文件,并且排除已经符合命名规则的文件
|
# 过滤出非目录文件,并且排除已经符合命名规则的文件
|
||||||
files_to_process = []
|
files_to_process = []
|
||||||
@ -456,7 +387,7 @@ def get_share_detail():
|
|||||||
files_to_process.append(f)
|
files_to_process.append(f)
|
||||||
|
|
||||||
# 根据提取的排序值进行排序
|
# 根据提取的排序值进行排序
|
||||||
sorted_files = sorted(files_to_process, key=extract_sorting_value)
|
sorted_files = sorted(files_to_process, key=extract_sort_value)
|
||||||
|
|
||||||
# 应用过滤词过滤
|
# 应用过滤词过滤
|
||||||
filterwords = regex.get("filterwords", "")
|
filterwords = regex.get("filterwords", "")
|
||||||
|
|||||||
@ -485,8 +485,12 @@
|
|||||||
<b>剧集命名格式:</b><span class="badge badge-info" v-html="formData.tasklist[fileSelect.index].pattern"></span>
|
<b>剧集命名格式:</b><span class="badge badge-info" v-html="formData.tasklist[fileSelect.index].pattern"></span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<b>匹配表达式:</b><span class="badge badge-info" v-html="formData.tasklist[fileSelect.index].pattern"></span>
|
<div style="margin-bottom: 0;">
|
||||||
<b>替换表达式:</b><span class="badge badge-info" v-html="formData.tasklist[fileSelect.index].replace"></span>
|
<b>匹配表达式:</b><span class="badge badge-info" v-html="formData.tasklist[fileSelect.index].pattern"></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<b>替换表达式:</b><span class="badge badge-info" v-html="formData.tasklist[fileSelect.index].replace"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-hover table-sm">
|
<table class="table table-hover table-sm">
|
||||||
|
|||||||
@ -2527,183 +2527,106 @@ def do_save(account, tasklist=[]):
|
|||||||
|
|
||||||
# 按文件名排序
|
# 按文件名排序
|
||||||
if is_special_sequence:
|
if is_special_sequence:
|
||||||
if task.get("use_sequence_naming") and task.get("sequence_naming"):
|
# 对于顺序命名模式,使用重命名日志来获取新增的文件
|
||||||
# 如果是顺序命名模式,直接使用顺序命名模式的模板来显示
|
if rename_logs:
|
||||||
sequence_pattern = task["sequence_naming"]
|
# 从重命名日志提取新旧文件名
|
||||||
|
renamed_files = {}
|
||||||
|
for log in rename_logs:
|
||||||
|
# 格式:重命名: 旧名 → 新名
|
||||||
|
match = re.search(r'重命名: (.*?) → (.*?)($|\s|,)', log)
|
||||||
|
if match:
|
||||||
|
old_name = match.group(1)
|
||||||
|
new_name = match.group(2)
|
||||||
|
renamed_files[old_name] = new_name
|
||||||
|
|
||||||
# 对于每个文件,生成其重命名后的名称
|
# 只显示重命名的文件
|
||||||
for i, node in enumerate(file_nodes):
|
|
||||||
# 提取序号(从1开始)
|
|
||||||
file_num = i + 1
|
|
||||||
# 获取原始文件的扩展名
|
|
||||||
orig_filename = node.tag.lstrip("🎞️")
|
|
||||||
file_ext = os.path.splitext(orig_filename)[1]
|
|
||||||
# 生成新的文件名(使用顺序命名模式)
|
|
||||||
if sequence_pattern == "{}":
|
|
||||||
# 对于单独的{},直接使用数字序号作为文件名
|
|
||||||
new_filename = f"{file_num:02d}{file_ext}"
|
|
||||||
else:
|
|
||||||
new_filename = sequence_pattern.replace("{}", f"{file_num:02d}") + file_ext
|
|
||||||
# 获取适当的图标
|
|
||||||
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
|
||||||
# 添加到显示列表
|
|
||||||
display_files.append((f"{icon}{new_filename}", node))
|
|
||||||
|
|
||||||
# 按数字排序
|
|
||||||
display_files.sort(key=lambda x: int(os.path.splitext(x[0].lstrip("🎞️"))[0]) if os.path.splitext(x[0].lstrip("🎞️"))[0].isdigit() else float('inf'))
|
|
||||||
|
|
||||||
elif task.get("use_episode_naming") and task.get("episode_naming"):
|
|
||||||
# 剧集命名模式
|
|
||||||
episode_pattern = task["episode_naming"]
|
|
||||||
|
|
||||||
# 提取序号的函数
|
|
||||||
def extract_episode_number(filename):
|
|
||||||
# 优先匹配SxxExx格式
|
|
||||||
match_s_e = re.search(r'[Ss](\d+)[Ee](\d+)', filename)
|
|
||||||
if match_s_e:
|
|
||||||
return int(match_s_e.group(2))
|
|
||||||
|
|
||||||
# 其次匹配E01格式
|
|
||||||
match_e = re.search(r'[Ee][Pp]?(\d+)', filename)
|
|
||||||
if match_e:
|
|
||||||
return int(match_e.group(1))
|
|
||||||
|
|
||||||
# 尝试匹配更多格式
|
|
||||||
default_patterns = [
|
|
||||||
r'第(\d+)集',
|
|
||||||
r'第(\d+)期',
|
|
||||||
r'第(\d+)话',
|
|
||||||
r'(\d+)集',
|
|
||||||
r'(\d+)期',
|
|
||||||
r'(\d+)话',
|
|
||||||
r'[Ee][Pp]?(\d+)',
|
|
||||||
r'(\d+)[-_\s]*4[Kk]',
|
|
||||||
r'\[(\d+)\]',
|
|
||||||
r'【(\d+)】',
|
|
||||||
r'_?(\d+)_?'
|
|
||||||
]
|
|
||||||
|
|
||||||
# 如果配置了自定义规则,优先使用
|
|
||||||
if "config_data" in task and isinstance(task["config_data"].get("episode_patterns"), list) and task["config_data"]["episode_patterns"]:
|
|
||||||
patterns = [p.get("regex", "(\\d+)") for p in task["config_data"]["episode_patterns"]]
|
|
||||||
else:
|
|
||||||
# 尝试从全局配置获取
|
|
||||||
global CONFIG_DATA
|
|
||||||
if isinstance(CONFIG_DATA.get("episode_patterns"), list) and CONFIG_DATA["episode_patterns"]:
|
|
||||||
patterns = [p.get("regex", "(\\d+)") for p in CONFIG_DATA["episode_patterns"]]
|
|
||||||
else:
|
|
||||||
patterns = default_patterns
|
|
||||||
|
|
||||||
# 尝试使用每个正则表达式匹配文件名
|
|
||||||
for pattern_regex in patterns:
|
|
||||||
try:
|
|
||||||
match = re.search(pattern_regex, filename)
|
|
||||||
if match:
|
|
||||||
return int(match.group(1))
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 对于每个文件节点,生成预期的剧集命名格式
|
|
||||||
for node in file_nodes:
|
for node in file_nodes:
|
||||||
# 获取原始文件名
|
# 获取原始文件名(去除已有图标)
|
||||||
orig_filename = node.tag.lstrip("🎞️")
|
orig_filename = node.tag.lstrip("🎞️")
|
||||||
# 提取剧集号
|
# 检查此文件是否在重命名日志中
|
||||||
episode_num = extract_episode_number(orig_filename)
|
if orig_filename in renamed_files:
|
||||||
if episode_num is not None:
|
# 使用重命名后的文件名
|
||||||
# 获取扩展名
|
new_filename = renamed_files[orig_filename]
|
||||||
|
# 获取适当的图标
|
||||||
|
icon = get_file_icon(new_filename, is_dir=node.data.get("is_dir", False))
|
||||||
|
# 添加到显示列表
|
||||||
|
display_files.append((f"{icon}{new_filename}", node))
|
||||||
|
else:
|
||||||
|
# 如果没有重命名日志,使用原来的顺序命名逻辑
|
||||||
|
if task.get("use_sequence_naming") and task.get("sequence_naming"):
|
||||||
|
# 顺序命名模式预览
|
||||||
|
sequence_pattern = task["sequence_naming"]
|
||||||
|
|
||||||
|
# 对于每个文件,生成其重命名后的名称
|
||||||
|
for i, node in enumerate(file_nodes):
|
||||||
|
# 提取序号(从1开始)
|
||||||
|
file_num = i + 1
|
||||||
|
# 获取原始文件的扩展名
|
||||||
|
orig_filename = node.tag.lstrip("🎞️")
|
||||||
file_ext = os.path.splitext(orig_filename)[1]
|
file_ext = os.path.splitext(orig_filename)[1]
|
||||||
# 生成新的文件名(使用剧集命名模式)
|
# 生成新的文件名(使用顺序命名模式)
|
||||||
if episode_pattern == "[]":
|
if sequence_pattern == "{}":
|
||||||
# 对于单独的[],直接使用数字序号作为文件名
|
# 对于单独的{},直接使用数字序号作为文件名
|
||||||
new_filename = f"{episode_num:02d}{file_ext}"
|
new_filename = f"{file_num:02d}{file_ext}"
|
||||||
else:
|
else:
|
||||||
new_filename = episode_pattern.replace("[]", f"{episode_num:02d}") + file_ext
|
new_filename = sequence_pattern.replace("{}", f"{file_num:02d}") + file_ext
|
||||||
# 获取适当的图标
|
# 获取适当的图标
|
||||||
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
||||||
# 添加到显示列表
|
# 添加到显示列表
|
||||||
display_files.append((f"{icon}{new_filename}", node))
|
display_files.append((f"{icon}{new_filename}", node))
|
||||||
else:
|
|
||||||
# 如果无法提取剧集号,保留原始文件名
|
|
||||||
orig_filename = node.tag.lstrip("🎞️")
|
|
||||||
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
|
||||||
display_files.append((f"{icon}{orig_filename}", node))
|
|
||||||
|
|
||||||
# 按剧集号排序
|
# 按数字排序
|
||||||
display_files.sort(
|
display_files.sort(key=lambda x: int(os.path.splitext(x[0].lstrip("🎞️"))[0]) if os.path.splitext(x[0].lstrip("🎞️"))[0].isdigit() else float('inf'))
|
||||||
key=lambda x: extract_episode_number(x[0]) if extract_episode_number(x[0]) is not None else float('inf')
|
# 对于剧集命名模式
|
||||||
)
|
elif task.get("use_episode_naming") and task.get("episode_naming"):
|
||||||
|
# 从重命名日志提取新旧文件名 (备用)
|
||||||
|
renamed_files = {}
|
||||||
|
for log in rename_logs:
|
||||||
|
# 格式:重命名: 旧名 → 新名
|
||||||
|
match = re.search(r'重命名: (.*?) → (.*?)($|\s|,)', log)
|
||||||
|
if match:
|
||||||
|
old_name = match.group(1)
|
||||||
|
new_name = match.group(2)
|
||||||
|
renamed_files[old_name] = new_name
|
||||||
|
|
||||||
else:
|
# 使用已知的剧集命名模式来生成新文件名
|
||||||
# 正则模式或其他模式:尝试显示正则替换后的文件名
|
episode_pattern = task["episode_naming"]
|
||||||
if task.get("pattern") and task.get("replace") is not None:
|
|
||||||
# 获取正则模式
|
|
||||||
pattern, replace = account.magic_regex_func(
|
|
||||||
task.get("pattern", ""), task.get("replace", ""), task["taskname"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 对文件名应用正则替换
|
# 创建剧集号提取函数
|
||||||
|
def extract_episode_number(filename):
|
||||||
|
# 优先匹配SxxExx格式
|
||||||
|
match_s_e = re.search(r'[Ss](\d+)[Ee](\d+)', filename)
|
||||||
|
if match_s_e:
|
||||||
|
# 直接返回E后面的集数
|
||||||
|
return int(match_s_e.group(2))
|
||||||
|
|
||||||
|
# 尝试使用每个配置的正则表达式匹配文件名
|
||||||
|
if account.episode_patterns:
|
||||||
|
for pattern in account.episode_patterns:
|
||||||
|
try:
|
||||||
|
pattern_regex = pattern.get("regex", "(\\d+)")
|
||||||
|
match = re.search(pattern_regex, filename)
|
||||||
|
if match:
|
||||||
|
return int(match.group(1))
|
||||||
|
except Exception as e:
|
||||||
|
continue
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 只显示重命名的文件
|
||||||
for node in file_nodes:
|
for node in file_nodes:
|
||||||
orig_filename = node.tag.lstrip("🎞️")
|
|
||||||
try:
|
|
||||||
# 应用正则表达式
|
|
||||||
new_name = re.sub(pattern, replace, orig_filename)
|
|
||||||
|
|
||||||
# 检查新名称是否包含重复的前缀
|
|
||||||
if " - " in new_name:
|
|
||||||
parts = new_name.split(" - ")
|
|
||||||
if len(parts) >= 2 and parts[0] == parts[1]:
|
|
||||||
# 如果有重复前缀,使用原文件名
|
|
||||||
new_name = orig_filename
|
|
||||||
|
|
||||||
# 为文件添加图标
|
|
||||||
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
|
||||||
display_files.append((f"{icon}{new_name}", node))
|
|
||||||
except Exception as e:
|
|
||||||
# 如果正则替换失败,使用原文件名
|
|
||||||
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
|
||||||
display_files.append((f"{icon}{orig_filename}", node))
|
|
||||||
else:
|
|
||||||
# 使用字母顺序和原始文件名
|
|
||||||
display_files = []
|
|
||||||
for node in sorted(file_nodes, key=lambda node: node.tag):
|
|
||||||
# 获取原始文件名(去除已有图标)
|
# 获取原始文件名(去除已有图标)
|
||||||
orig_filename = node.tag.lstrip("🎞️")
|
orig_filename = node.tag.lstrip("🎞️")
|
||||||
# 添加适当的图标
|
# 检查此文件是否在重命名日志中
|
||||||
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
if orig_filename in renamed_files:
|
||||||
display_files.append((f"{icon}{orig_filename}", node))
|
# 使用重命名后的文件名
|
||||||
elif is_regex_mode:
|
new_filename = renamed_files[orig_filename]
|
||||||
# 正则模式:显示正则替换后的文件名
|
# 获取适当的图标
|
||||||
if task.get("pattern") is not None:
|
icon = get_file_icon(new_filename, is_dir=node.data.get("is_dir", False))
|
||||||
# 获取正则模式
|
# 添加到显示列表
|
||||||
pattern, replace = account.magic_regex_func(
|
display_files.append((f"{icon}{new_filename}", node))
|
||||||
task.get("pattern", ""), task.get("replace", ""), task["taskname"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 对文件名应用正则替换
|
# 如果没有找到任何文件要显示,使用原始文件名
|
||||||
for node in file_nodes:
|
if not display_files:
|
||||||
orig_filename = node.tag.lstrip("🎞️")
|
|
||||||
try:
|
|
||||||
# 应用正则表达式
|
|
||||||
new_name = re.sub(pattern, replace, orig_filename)
|
|
||||||
|
|
||||||
# 检查新名称是否包含重复的前缀
|
|
||||||
if " - " in new_name:
|
|
||||||
parts = new_name.split(" - ")
|
|
||||||
if len(parts) >= 2 and parts[0] == parts[1]:
|
|
||||||
# 如果有重复前缀,使用原文件名
|
|
||||||
new_name = orig_filename
|
|
||||||
|
|
||||||
# 为文件添加图标
|
|
||||||
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
|
||||||
display_files.append((f"{icon}{new_name}", node))
|
|
||||||
except Exception as e:
|
|
||||||
# 如果正则替换失败,使用原文件名
|
|
||||||
icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
|
|
||||||
display_files.append((f"{icon}{orig_filename}", node))
|
|
||||||
else:
|
|
||||||
# 使用字母顺序和原始文件名
|
|
||||||
display_files = []
|
|
||||||
for node in sorted(file_nodes, key=lambda node: node.tag):
|
for node in sorted(file_nodes, key=lambda node: node.tag):
|
||||||
# 获取原始文件名(去除已有图标)
|
# 获取原始文件名(去除已有图标)
|
||||||
orig_filename = node.tag.lstrip("🎞️")
|
orig_filename = node.tag.lstrip("🎞️")
|
||||||
@ -2770,79 +2693,140 @@ def do_save(account, tasklist=[]):
|
|||||||
# 过滤出非目录的文件
|
# 过滤出非目录的文件
|
||||||
file_nodes = [f for f in dir_file_list if not f["dir"]]
|
file_nodes = [f for f in dir_file_list if not f["dir"]]
|
||||||
|
|
||||||
# 计算文件数量
|
# 从重命名日志提取新旧文件名
|
||||||
file_count = len(file_nodes)
|
renamed_files = {}
|
||||||
|
for log in rename_logs:
|
||||||
|
# 格式:重命名: 旧名 → 新名
|
||||||
|
if "重命名:" in log and " → " in log:
|
||||||
|
# 先分割出"重命名:"后面的部分
|
||||||
|
parts = log.split("重命名:", 1)[1].strip()
|
||||||
|
# 再按箭头分割
|
||||||
|
if " → " in parts:
|
||||||
|
old_name, new_name = parts.split(" → ", 1)
|
||||||
|
# 如果新名称包含空格或其他分隔符,只取第一个换行符之前的内容
|
||||||
|
if "\n" in new_name:
|
||||||
|
new_name = new_name.split("\n")[0]
|
||||||
|
old_name = old_name.strip()
|
||||||
|
new_name = new_name.strip()
|
||||||
|
renamed_files[old_name] = new_name
|
||||||
|
|
||||||
# 提取序号的函数
|
# 确保至少显示重命名后的文件
|
||||||
|
display_files = []
|
||||||
|
|
||||||
|
# 添加所有重命名的目标文件
|
||||||
|
for old_name, new_name in renamed_files.items():
|
||||||
|
if new_name not in display_files:
|
||||||
|
display_files.append(new_name)
|
||||||
|
|
||||||
|
# 此外,检查是否有新的文件节点(比较节点时间)
|
||||||
|
if not display_files and is_new_tree and hasattr(is_new_tree, 'nodes'):
|
||||||
|
# 如果有转存文件树,从中提取文件
|
||||||
|
tree_nodes = is_new_tree.nodes.values()
|
||||||
|
for node in tree_nodes:
|
||||||
|
if hasattr(node, 'data') and not node.data.get('is_dir', False):
|
||||||
|
file_path = node.data.get('path', '')
|
||||||
|
if file_path:
|
||||||
|
file_name = os.path.basename(file_path)
|
||||||
|
if file_name not in display_files:
|
||||||
|
display_files.append(file_name)
|
||||||
|
|
||||||
|
# 还需要检查是否有打印到控制台的转存文件信息(情况:转存后立即重命名)
|
||||||
|
# 无论display_files是否为空都执行此代码,确保能提取到重命名的文件
|
||||||
|
for log in rename_logs:
|
||||||
|
if "重命名:" in log and " → " in log:
|
||||||
|
parts = log.split(" → ", 1)
|
||||||
|
if len(parts) > 1:
|
||||||
|
new_name = parts[1].strip()
|
||||||
|
# 过滤掉可能的结束标记,但要确保完整保留文件名
|
||||||
|
if "\n" in new_name:
|
||||||
|
new_name = new_name.split("\n")[0].strip()
|
||||||
|
|
||||||
|
# 只有当文件名包含明确的分隔符时才进行分割
|
||||||
|
# 例如"黑镜 - S07E02.mkv"不应该被分割
|
||||||
|
if "," in new_name:
|
||||||
|
new_name = new_name.split(",")[0].strip()
|
||||||
|
|
||||||
|
# 确保不要错误地只提取文件名的一部分(如"黑镜")
|
||||||
|
if " " in new_name and "." in new_name: # 如果包含空格和扩展名
|
||||||
|
# 检查这是不是一个完整文件名
|
||||||
|
if re.search(r'\.\w+$', new_name): # 检查是否以扩展名结尾
|
||||||
|
# 这是一个完整的文件名,不做进一步分割
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# 不是以扩展名结尾,可能需要进一步处理
|
||||||
|
new_name = new_name.split(" ")[0].strip()
|
||||||
|
|
||||||
|
if new_name and new_name not in display_files:
|
||||||
|
# 额外检查,确保提取的是完整文件名
|
||||||
|
if "." in new_name: # 通常文件名应包含扩展名
|
||||||
|
display_files.append(new_name)
|
||||||
|
|
||||||
|
# 如果通过重命名和文件树都没找到文件,使用最新时间排序的文件
|
||||||
|
if not display_files and file_nodes:
|
||||||
|
# 查找目录中修改时间最新的文件(可能是刚刚转存的)
|
||||||
|
today = datetime.now().strftime('%Y-%m-%d')
|
||||||
|
recent_files = []
|
||||||
|
|
||||||
|
# 首先尝试通过修改日期过滤当天的文件
|
||||||
|
for file in file_nodes:
|
||||||
|
# 如果有时间戳,转换为日期字符串
|
||||||
|
if 'updated_at' in file and file['updated_at']:
|
||||||
|
update_time = datetime.fromtimestamp(file['updated_at']).strftime('%Y-%m-%d')
|
||||||
|
if update_time == today:
|
||||||
|
recent_files.append(file)
|
||||||
|
|
||||||
|
# 如果没有找到当天的文件,至少显示一个最新的文件
|
||||||
|
if not recent_files and file_nodes:
|
||||||
|
# 按修改时间排序
|
||||||
|
recent_files = sorted(file_nodes, key=lambda x: x.get('updated_at', 0), reverse=True)
|
||||||
|
|
||||||
|
# 只取第一个作为显示
|
||||||
|
if recent_files:
|
||||||
|
display_files.append(recent_files[0]['file_name'])
|
||||||
|
|
||||||
|
# 添加成功通知
|
||||||
|
add_notify(f"✅《{task['taskname']}》 添加追更:")
|
||||||
|
add_notify(f"/{task['savepath']}")
|
||||||
|
|
||||||
|
# 创建episode_pattern函数用于排序
|
||||||
def extract_episode_number(filename):
|
def extract_episode_number(filename):
|
||||||
# 优先匹配SxxExx格式
|
# 优先匹配SxxExx格式
|
||||||
match_s_e = re.search(r'[Ss](\d+)[Ee](\d+)', filename)
|
match_s_e = re.search(r'[Ss](\d+)[Ee](\d+)', filename)
|
||||||
if match_s_e:
|
if match_s_e:
|
||||||
return int(match_s_e.group(2))
|
return int(match_s_e.group(2))
|
||||||
|
|
||||||
# 其次匹配E01格式
|
# 尝试从文件名中提取剧集号
|
||||||
match_e = re.search(r'[Ee][Pp]?(\d+)', filename)
|
episode_pattern = task["episode_naming"]
|
||||||
if match_e:
|
if "[]" in episode_pattern:
|
||||||
return int(match_e.group(1))
|
pattern_parts = episode_pattern.split("[]")
|
||||||
|
if len(pattern_parts) == 2:
|
||||||
|
prefix, suffix = pattern_parts
|
||||||
|
if prefix and filename.startswith(prefix):
|
||||||
|
number_part = filename[len(prefix):].split(suffix)[0] if suffix else filename[len(prefix):]
|
||||||
|
if number_part.isdigit():
|
||||||
|
return int(number_part)
|
||||||
|
|
||||||
# 尝试匹配更多格式
|
# 尝试其他通用提取方法
|
||||||
default_patterns = [
|
num_match = re.search(r'(\d+)', filename)
|
||||||
r'第(\d+)集',
|
if num_match:
|
||||||
r'第(\d+)期',
|
return int(num_match.group(1))
|
||||||
r'第(\d+)话',
|
|
||||||
r'(\d+)集',
|
|
||||||
r'(\d+)期',
|
|
||||||
r'(\d+)话',
|
|
||||||
r'[Ee][Pp]?(\d+)',
|
|
||||||
r'(\d+)[-_\s]*4[Kk]',
|
|
||||||
r'\[(\d+)\]',
|
|
||||||
r'【(\d+)】',
|
|
||||||
r'_?(\d+)_?'
|
|
||||||
]
|
|
||||||
|
|
||||||
# 如果配置了自定义规则,优先使用
|
return float('inf')
|
||||||
if "config_data" in task and isinstance(task["config_data"].get("episode_patterns"), list) and task["config_data"]["episode_patterns"]:
|
|
||||||
patterns = [p.get("regex", "(\\d+)") for p in task["config_data"]["episode_patterns"]]
|
|
||||||
else:
|
|
||||||
# 尝试从全局配置获取
|
|
||||||
global CONFIG_DATA
|
|
||||||
if isinstance(CONFIG_DATA.get("episode_patterns"), list) and CONFIG_DATA["episode_patterns"]:
|
|
||||||
patterns = [p.get("regex", "(\\d+)") for p in CONFIG_DATA["episode_patterns"]]
|
|
||||||
else:
|
|
||||||
patterns = default_patterns
|
|
||||||
|
|
||||||
# 尝试使用每个正则表达式匹配文件名
|
|
||||||
for pattern_regex in patterns:
|
|
||||||
try:
|
|
||||||
match = re.search(pattern_regex, filename)
|
|
||||||
if match:
|
|
||||||
return int(match.group(1))
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
return None
|
|
||||||
|
|
||||||
# 创建一个映射列表,包含排序后的文件
|
|
||||||
display_files = []
|
|
||||||
episode_pattern = task["episode_naming"]
|
|
||||||
regex_pattern = task.get("regex_pattern")
|
|
||||||
|
|
||||||
# 找出所有文件,无论是否符合命名格式
|
|
||||||
display_files = [file["file_name"] for file in file_nodes]
|
|
||||||
|
|
||||||
# 按剧集号排序
|
# 按剧集号排序
|
||||||
display_files.sort(
|
display_files.sort(key=extract_episode_number)
|
||||||
key=lambda x: extract_episode_number(x) if extract_episode_number(x) is not None else float('inf')
|
|
||||||
)
|
|
||||||
|
|
||||||
# 添加成功通知
|
|
||||||
add_notify(f"✅《{task['taskname']}》 添加追更:")
|
|
||||||
add_notify(f"/{task['savepath']}")
|
|
||||||
|
|
||||||
# 打印文件列表
|
# 打印文件列表
|
||||||
for idx, file_name in enumerate(display_files):
|
for idx, file_name in enumerate(display_files):
|
||||||
prefix = "├── " if idx < len(display_files) - 1 else "└── "
|
prefix = "├── " if idx < len(display_files) - 1 else "└── "
|
||||||
file_info = file_nodes[next((i for i, f in enumerate(file_nodes) if f["file_name"] == file_name), 0)]
|
# 查找文件信息用于获取图标
|
||||||
icon = get_file_icon(file_name, is_dir=file_info.get("dir", False))
|
file_info = next((f for f in file_nodes if f["file_name"] == file_name or
|
||||||
|
(f["file_name"] in renamed_files and renamed_files[f["file_name"]] == file_name)), None)
|
||||||
|
if file_info is None:
|
||||||
|
# 如果找不到对应信息,可能是已重命名文件,使用默认图标
|
||||||
|
icon = get_file_icon(file_name, is_dir=False)
|
||||||
|
else:
|
||||||
|
icon = get_file_icon(file_name, is_dir=file_info.get("dir", False))
|
||||||
add_notify(f"{prefix}{icon}{file_name}")
|
add_notify(f"{prefix}{icon}{file_name}")
|
||||||
add_notify("")
|
add_notify("")
|
||||||
# 添加正则命名模式的文件树显示逻辑
|
# 添加正则命名模式的文件树显示逻辑
|
||||||
@ -2854,37 +2838,26 @@ def do_save(account, tasklist=[]):
|
|||||||
# 过滤出非目录的文件
|
# 过滤出非目录的文件
|
||||||
file_nodes = [f for f in dir_file_list if not f["dir"]]
|
file_nodes = [f for f in dir_file_list if not f["dir"]]
|
||||||
|
|
||||||
# 创建一个映射列表,包含所有文件
|
# 从重命名日志提取新旧文件名
|
||||||
display_files = [file["file_name"] for file in file_nodes]
|
renamed_files = {}
|
||||||
|
for log in rename_logs:
|
||||||
|
# 格式:重命名: 旧名 → 新名
|
||||||
|
match = re.search(r'重命名: (.*?) → (.*?)($|\s|,)', log)
|
||||||
|
if match:
|
||||||
|
old_name = match.group(1)
|
||||||
|
new_name = match.group(2)
|
||||||
|
renamed_files[old_name] = new_name
|
||||||
|
|
||||||
# 按日期或任何数字排序 (复用local_sort_key函数逻辑)
|
# 只显示重命名的文件
|
||||||
def extract_sort_value(file_name):
|
display_files = []
|
||||||
# 尝试提取日期格式(优先YYYY-MM-DD格式)
|
for file in file_nodes:
|
||||||
date_match = re.search(r'(\d{4})[-./](\d{1,2})[-./](\d{1,2})', file_name)
|
if file["file_name"] in renamed_files:
|
||||||
if date_match:
|
display_files.append(renamed_files[file["file_name"]])
|
||||||
year = int(date_match.group(1))
|
|
||||||
month = int(date_match.group(2))
|
|
||||||
day = int(date_match.group(3))
|
|
||||||
return year * 10000 + month * 100 + day
|
|
||||||
|
|
||||||
# 尝试提取紧凑日期格式(YYYYMMDD)
|
# 如果没有找到任何文件要显示,使用原始逻辑
|
||||||
compact_date_match = re.search(r'(\d{4})(\d{2})(\d{2})', file_name)
|
if not display_files:
|
||||||
if compact_date_match:
|
# 创建一个映射列表,包含所有文件
|
||||||
year = int(compact_date_match.group(1))
|
display_files = [file["file_name"] for file in file_nodes]
|
||||||
month = int(compact_date_match.group(2))
|
|
||||||
day = int(compact_date_match.group(3))
|
|
||||||
return year * 10000 + month * 100 + day
|
|
||||||
|
|
||||||
# 尝试提取任何数字
|
|
||||||
number_match = re.search(r'(\d+)', file_name)
|
|
||||||
if number_match:
|
|
||||||
return int(number_match.group(1))
|
|
||||||
|
|
||||||
# 默认使用原文件名
|
|
||||||
return float('inf')
|
|
||||||
|
|
||||||
# 按提取的排序值进行排序
|
|
||||||
display_files.sort(key=extract_sort_value)
|
|
||||||
|
|
||||||
# 添加成功通知
|
# 添加成功通知
|
||||||
add_notify(f"✅《{task['taskname']}》 添加追更:")
|
add_notify(f"✅《{task['taskname']}》 添加追更:")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user