新增字幕命名规则功能,支持在全局设置字幕文件的语言代码后缀

- 添加字幕文件语言代码后缀自动添加功能
- 支持 .srt/.ass/.ssa/.vtt/.sup 等常见字幕格式
- 在系统配置中提供语言代码设置和启用开关
- 覆盖所有重命名场景:预览界面、任务执行、文件整理
- 支持顺序命名、剧集命名、正则表达式命名模式
- 避免重复添加语言代码后缀
- 默认语言代码为 "zh",默认禁用状态

功能说明:
- 用户可在系统配置中设置字幕文件的语言代码(如 "zh")
- 启用后,所有字幕文件重命名时自动添加语言代码后缀
- 例如:`movie.srt` → `movie.zh.srt`
- 支持所有命名模式和预览功能
- 向后兼容,不影响现有功能
This commit is contained in:
x1ao4 2025-09-29 15:19:11 +08:00
parent be5773fb84
commit 1f99f66ce5
3 changed files with 110 additions and 3 deletions

View File

@ -44,7 +44,7 @@ from quark_auto_save import Config, format_bytes
# 添加导入全局extract_episode_number和sort_file_by_name函数
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from quark_auto_save import extract_episode_number, sort_file_by_name, chinese_to_arabic, is_date_format
from quark_auto_save import extract_episode_number, sort_file_by_name, chinese_to_arabic, is_date_format, apply_subtitle_naming_rule
# 导入豆瓣服务
from sdk.douban_service import douban_service
@ -2105,6 +2105,9 @@ def get_share_detail():
else:
# 替换所有的{}为当前序号
file["file_name_re"] = sequence_pattern.replace("{}", f"{current_sequence:02d}") + file_ext
# 应用字幕命名规则
file["file_name_re"] = apply_subtitle_naming_rule(file["file_name_re"], config_data["task_settings"])
current_sequence += 1
return share_detail
@ -2143,6 +2146,8 @@ def get_share_detail():
if episode_num is not None:
file["file_name_re"] = episode_pattern.replace("[]", f"{episode_num:02d}") + extension
# 应用字幕命名规则
file["file_name_re"] = apply_subtitle_naming_rule(file["file_name_re"], config_data["task_settings"])
# 添加episode_number字段用于前端排序
file["episode_number"] = episode_num
else:
@ -2177,6 +2182,8 @@ def get_share_detail():
item["file_name_re"] = (
re.sub(pattern, replace, file_name) if replace != "" else file_name
)
# 应用字幕命名规则
item["file_name_re"] = apply_subtitle_naming_rule(item["file_name_re"], config_data["task_settings"])
return share_detail
share_detail = preview_regex(share_detail)
@ -3383,6 +3390,8 @@ def preview_rename():
for file in filtered_files:
extension = os.path.splitext(file["file_name"])[1] if not file["dir"] else ""
new_name = pattern.replace("{}", f"{sequence:02d}") + extension
# 应用字幕命名规则
new_name = apply_subtitle_naming_rule(new_name, config_data["task_settings"])
preview_results.append({
"original_name": file["file_name"],
"new_name": new_name,
@ -3420,6 +3429,8 @@ def preview_rename():
if episode_num is not None:
new_name = pattern.replace("[]", f"{episode_num:02d}") + extension
# 应用字幕命名规则
new_name = apply_subtitle_naming_rule(new_name, config_data["task_settings"])
preview_results.append({
"original_name": file["file_name"],
"new_name": new_name,
@ -3439,10 +3450,14 @@ def preview_rename():
# 应用正则表达式
if replace:
new_name = re.sub(pattern, replace, file["file_name"])
# 应用字幕命名规则
new_name = apply_subtitle_naming_rule(new_name, config_data["task_settings"])
else:
# 如果没有提供替换表达式,则检查是否匹配
if re.search(pattern, file["file_name"]):
new_name = file["file_name"] # 匹配但不替换
# 应用字幕命名规则
new_name = apply_subtitle_naming_rule(new_name, config_data["task_settings"])
else:
new_name = "" # 表示不匹配

View File

@ -788,6 +788,20 @@
</div>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">字幕命名规则</span>
</div>
<input type="text" class="form-control" v-model="formData.task_settings.subtitle_naming_rule" placeholder="zh" title="设置字幕文件的语言代码,在重命名字幕文件时会在文件名末尾添加此代码">
<div class="input-group-append" title="启用后,重命名字幕文件时会在文件名末尾添加语言代码后缀">
<div class="input-group-text">
<input type="checkbox" v-model="formData.task_settings.subtitle_add_language_code">&nbsp;添加语言代码
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
@ -2831,7 +2845,9 @@
movie_naming_pattern: "^(.*)\\.([^.]+)",
movie_naming_replace: "片名 (年份).\\2",
tv_naming_rule: "剧名 - S季数E[]",
tv_ignore_extension: true
tv_ignore_extension: true,
subtitle_naming_rule: "zh",
subtitle_add_language_code: false
},
source: {
cloudsaver: {
@ -6935,6 +6951,8 @@
movie_naming_replace: "片名 (年份).\\2",
tv_naming_rule: "剧名 - S季数E[]",
tv_ignore_extension: true,
subtitle_naming_rule: "zh",
subtitle_add_language_code: false,
auto_search_resources: "enabled"
};
}

View File

@ -1083,7 +1083,7 @@ def get_file_icon(file_name, is_dir=False):
return "📝"
# 字幕文件
if any(lower_name.endswith(ext) for ext in ['.srt', '.ass', '.ssa', '.vtt']):
if any(lower_name.endswith(ext) for ext in ['.srt', '.ass', '.ssa', '.vtt', '.sup']):
return "💬"
# 歌词文件
@ -1108,6 +1108,54 @@ def remove_file_icons(filename):
return clean_name
# 定义一个函数来检测字幕文件并应用语言代码后缀
def apply_subtitle_naming_rule(filename, task_settings):
"""
检测字幕文件并应用语言代码后缀
Args:
filename: 原始文件名
task_settings: 任务设置包含字幕命名规则配置
Returns:
处理后的文件名
"""
# 从任务设置中获取字幕命名规则配置
subtitle_add_language_code = task_settings.get("subtitle_add_language_code", False)
subtitle_naming_rule = task_settings.get("subtitle_naming_rule", "zh")
# 如果任务设置中没有配置,尝试从全局配置中获取
if not subtitle_add_language_code:
try:
if 'CONFIG_DATA' in globals() and CONFIG_DATA:
global_task_settings = CONFIG_DATA.get("task_settings", {})
subtitle_add_language_code = global_task_settings.get("subtitle_add_language_code", False)
subtitle_naming_rule = global_task_settings.get("subtitle_naming_rule", "zh")
except (KeyError, AttributeError, TypeError):
# 配置获取失败,使用默认值
pass
# 检查是否启用了字幕命名规则
if not subtitle_add_language_code or not subtitle_naming_rule:
return filename
# 检测是否为字幕文件
lower_name = filename.lower()
subtitle_extensions = ['.srt', '.ass', '.ssa', '.vtt', '.sup']
if not any(lower_name.endswith(ext) for ext in subtitle_extensions):
return filename
# 分离文件名和扩展名
name_without_ext, ext = os.path.splitext(filename)
# 检查是否已经包含语言代码后缀,避免重复添加
if f".{subtitle_naming_rule}" in name_without_ext:
return filename
# 添加语言代码后缀
return f"{name_without_ext}.{subtitle_naming_rule}{ext}"
class Config:
# 下载配置
@ -2561,6 +2609,9 @@ class Quark:
# 生成新文件名
save_name = sequence_pattern.replace("{}", f"{current_sequence:02d}") + file_ext
# 应用字幕命名规则
save_name = apply_subtitle_naming_rule(save_name, task)
# 检查目标目录是否已存在此文件,支持忽略后缀选项
if task.get("ignore_extension", False):
# 忽略后缀模式:只比较文件名部分,不比较扩展名
@ -2763,6 +2814,9 @@ class Quark:
target_name = f"{episode_num:02d}{file_ext}"
else:
target_name = episode_pattern.replace("[]", f"{episode_num:02d}") + file_ext
# 应用字幕命名规则
target_name = apply_subtitle_naming_rule(target_name, task)
# 检查目标文件名是否已存在,支持忽略后缀选项
if task.get("ignore_extension", False):
@ -2904,6 +2958,8 @@ class Quark:
# 尝试应用正则替换
if re.search(pattern, original_file_name):
renamed_file = re.sub(pattern, replace, original_file_name)
# 应用字幕命名规则
renamed_file = apply_subtitle_naming_rule(renamed_file, task)
renamed_base = os.path.splitext(renamed_file)[0]
else:
renamed_file = None
@ -3058,6 +3114,9 @@ class Quark:
else share_file["file_name"]
)
# 应用字幕命名规则
save_name = apply_subtitle_naming_rule(save_name, task)
# 检查新名称是否存在重复的前缀
if replace and " - " in save_name:
parts = save_name.split(" - ")
@ -3509,6 +3568,9 @@ class Quark:
else:
save_name = sequence_pattern.replace("{}", f"{current_sequence:02d}") + file_ext
# 应用字幕命名规则
save_name = apply_subtitle_naming_rule(save_name, task)
# 检查是否需要重命名,支持忽略后缀选项
name_conflict = False
if task.get("ignore_extension", False):
@ -3701,6 +3763,8 @@ class Quark:
new_name = f"{episode_num:02d}{file_ext}"
else:
new_name = episode_pattern.replace("[]", f"{episode_num:02d}") + file_ext
# 应用字幕命名规则
new_name = apply_subtitle_naming_rule(new_name, task)
else:
new_name = None
@ -3775,6 +3839,9 @@ class Quark:
else:
save_name = episode_pattern.replace("[]", f"{episode_num:02d}") + file_ext
# 应用字幕命名规则
save_name = apply_subtitle_naming_rule(save_name, task)
# 检查过滤词
should_filter = False
if task.get("filterwords"):
@ -3987,12 +4054,16 @@ class Quark:
# 使用完整的剧集号识别逻辑,而不是简单的纯数字判断
# 生成新文件名
new_name = f"{episode_num:02d}{file_ext}"
# 应用字幕命名规则
new_name = apply_subtitle_naming_rule(new_name, task)
# 只有当当前文件名与目标文件名不同时才重命名
if dir_file["file_name"] != new_name:
rename_operations.append((dir_file, new_name, episode_num))
else:
# 生成目标文件名
new_name = episode_pattern.replace("[]", f"{episode_num:02d}") + file_ext
# 应用字幕命名规则
new_name = apply_subtitle_naming_rule(new_name, task)
# 检查文件名是否已经符合目标格式
if dir_file["file_name"] != new_name:
rename_operations.append((dir_file, new_name, episode_num))
@ -4140,6 +4211,9 @@ class Quark:
# 应用正则表达式获取目标文件名
new_name = re.sub(pattern, replace, orig_name)
# 应用字幕命名规则
new_name = apply_subtitle_naming_rule(new_name, task)
# 如果替换后的文件名没有变化,跳过
if new_name == orig_name:
continue