feat: 校验根据映射表添加作者链接

This commit is contained in:
起个名字好难的喵
2025-07-26 19:41:11 +08:00
parent 1351e9dc09
commit f0201f39e5
30 changed files with 379 additions and 137 deletions

View File

@@ -1,6 +1,7 @@
{ {
"rename": { "rename": {
"起个名字好难": "起个名字好难的喵" "起个名字好难": "起个名字好难的喵",
"this-Fish": "蜜柑魚"
}, },
"links": { "links": {
"秋云": "https://github.com/physligl", "秋云": "https://github.com/physligl",

View File

@@ -1,136 +1,169 @@
import os import os
import sys
import json import json
# 获取配置文件路径(和脚本在同一目录) def process_json_authors(input_path, config_path="author_config.json", verbose=True):
script_dir = os.path.dirname(os.path.abspath(__file__)) """
config_path = os.path.join(script_dir, "author_config.json") 处理 JSON 文件中的作者信息(支持 author → authors 结构化迁移、作者名重命名和链接统一)
参数:
input_path (str): 要处理的文件路径或目录路径
config_path (str): 配置文件路径(默认在脚本同级)
verbose (bool): 是否打印详细日志信息
返回:
dict: 包含处理总数和修改数量的统计信息
"""
result = {
"total_files": 0,
"modified_files": 0,
"errors": []
}
# 获取要处理的文件夹路径 if not os.path.exists(input_path):
if len(sys.argv) < 2: raise FileNotFoundError(f"路径不存在:{input_path}")
print("❌ 用法python pathing_authors.py <JSON目录路径>") if not os.path.exists(config_path):
sys.exit(1) raise FileNotFoundError(f"配置文件不存在:{config_path}")
folder_path = sys.argv[1] # 加载配置
try:
with open(config_path, "r", encoding="utf-8") as f:
config = json.load(f)
except Exception as e:
raise RuntimeError(f"配置文件加载失败:{e}")
if not os.path.exists(folder_path): author_rename = config.get("rename", {})
print(f"❌ JSON目录不存在{folder_path}") author_links = config.get("links", {})
sys.exit(1)
if not os.path.exists(config_path):
print(f"❌ 配置文件不存在:{config_path}")
sys.exit(1)
# 加载配置 # 构建待处理文件列表
try: file_list = []
with open(config_path, "r", encoding="utf-8") as f: if os.path.isfile(input_path) and input_path.endswith(".json"):
config = json.load(f) file_list.append(input_path)
except Exception as e: elif os.path.isdir(input_path):
print(f"❌ 配置文件加载失败:{e}") for root, dirs, files in os.walk(input_path):
sys.exit(1) for filename in files:
if filename.endswith(".json"):
file_list.append(os.path.join(root, filename))
else:
raise ValueError("输入路径必须是 .json 文件或目录")
author_rename = config.get("rename", {}) for file_path in file_list:
author_links = config.get("links", {}) result["total_files"] += 1
if verbose:
print(f"🚀 启动,处理目录:{folder_path}")
count_total = 0
count_modified = 0
for root, dirs, files in os.walk(folder_path):
for filename in files:
if filename.endswith(".json"):
count_total += 1
file_path = os.path.join(root, filename)
print(f"\n🔍 处理文件:{file_path}") print(f"\n🔍 处理文件:{file_path}")
try: try:
with open(file_path, "r", encoding="utf-8") as f: with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f) data = json.load(f)
except Exception as e: except Exception as e:
print(f"❌ 解析失败:{e}") msg = f"❌ 解析失败:{e}"
continue if verbose:
print(msg)
result["errors"].append((file_path, str(e)))
continue
info = data.get("info") info = data.get("info")
if not isinstance(info, dict): if not isinstance(info, dict):
if verbose:
print("⚠️ 缺少 info 字段") print("⚠️ 缺少 info 字段")
continue continue
modified = False modified = False
author_field = info.get("author") author_field = info.get("author")
if author_field is not None: if author_field is not None:
# 旧格式字符串处理 if isinstance(author_field, str):
if isinstance(author_field, str): names = [name.strip() for name in author_field.split("&")]
names = [name.strip() for name in author_field.split("&")] new_authors = []
new_authors = [] for name in names:
for name in names: new_name = author_rename.get(name, name)
new_name = author_rename.get(name, name) author_obj = {"name": new_name}
author_obj = {"name": new_name} if new_name in author_links:
if new_name in author_links: author_obj["links"] = author_links[new_name]
author_obj["links"] = author_links[new_name] new_authors.append(author_obj)
new_authors.append(author_obj) data["info"]["authors"] = new_authors
data["info"]["authors"] = new_authors modified = True
modified = True if verbose:
print("✅ 替换为结构化 authors") print("✅ 替换为结构化 authors")
elif isinstance(author_field, list): elif isinstance(author_field, list):
for author_obj in author_field: for author_obj in author_field:
if not isinstance(author_obj, dict): if not isinstance(author_obj, dict):
continue continue
name = author_obj.get("name") name = author_obj.get("name")
if not name: if not name:
continue continue
new_name = author_rename.get(name, name) new_name = author_rename.get(name, name)
if name != new_name: if name != new_name:
author_obj["name"] = new_name author_obj["name"] = new_name
modified = True modified = True
if verbose:
print(f"📝 重命名:{name}{new_name}") print(f"📝 重命名:{name}{new_name}")
existing_link = author_obj.pop("link", None) or author_obj.pop("url", None) or author_obj.get("links") existing_link = author_obj.pop("link", None) or author_obj.pop("url", None) or author_obj.get("links")
if new_name in author_links: if new_name in author_links:
if author_obj.get("links") != author_links[new_name]: if author_obj.get("links") != author_links[new_name]:
author_obj["links"] = author_links[new_name] author_obj["links"] = author_links[new_name]
modified = True
print(f"🔧 更新链接:{new_name}{author_links[new_name]}")
elif "links" not in author_obj and existing_link:
author_obj["links"] = existing_link
modified = True modified = True
if verbose:
print(f"🔧 更新链接:{new_name}{author_links[new_name]}")
elif "links" not in author_obj and existing_link:
author_obj["links"] = existing_link
modified = True
if verbose:
print(f"🔄 标准化已有链接字段为 links → {existing_link}") print(f"🔄 标准化已有链接字段为 links → {existing_link}")
else: else:
# 🔧 处理已有结构化 authors 字段,补充 links authors_field = info.get("authors")
authors_field = info.get("authors") if isinstance(authors_field, list):
if isinstance(authors_field, list): for author_obj in authors_field:
for author_obj in authors_field: if not isinstance(author_obj, dict):
if not isinstance(author_obj, dict): continue
continue name = author_obj.get("name")
name = author_obj.get("name") if not name:
if not name: continue
continue new_name = author_rename.get(name, name)
new_name = author_rename.get(name, name) if name != new_name:
if name != new_name: author_obj["name"] = new_name
author_obj["name"] = new_name modified = True
modified = True if verbose:
print(f"📝 重命名authors{name}{new_name}") print(f"📝 重命名authors{name}{new_name}")
existing_link = author_obj.pop("link", None) or author_obj.pop("url", None) or author_obj.get("links") existing_link = author_obj.pop("link", None) or author_obj.pop("url", None) or author_obj.get("links")
if new_name in author_links: if new_name in author_links:
if author_obj.get("links") != author_links[new_name]: if author_obj.get("links") != author_links[new_name]:
author_obj["links"] = author_links[new_name] author_obj["links"] = author_links[new_name]
modified = True
print(f"🔧 更新链接authors{new_name}{author_links[new_name]}")
elif "links" not in author_obj and existing_link:
author_obj["links"] = existing_link
modified = True modified = True
if verbose:
print(f"🔧 更新链接authors{new_name}{author_links[new_name]}")
elif "links" not in author_obj and existing_link:
author_obj["links"] = existing_link
modified = True
if verbose:
print(f"🔄 标准化已有链接字段为 links → {existing_link}") print(f"🔄 标准化已有链接字段为 links → {existing_link}")
else: else:
if verbose:
print("⚠️ 缺少 author 字段,且 authors 非标准格式") print("⚠️ 缺少 author 字段,且 authors 非标准格式")
if modified: if modified:
with open(file_path, "w", encoding="utf-8") as f: with open(file_path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2) json.dump(data, f, ensure_ascii=False, indent=2)
count_modified += 1 result["modified_files"] += 1
if verbose:
print("✅ 写入完成") print("✅ 写入完成")
else: else:
if verbose:
print("⏭️ 无需修改") print("⏭️ 无需修改")
print(f"\n🎉 处理完成:共 {count_total} 个 JSON 文件,修改了 {count_modified}") if verbose:
print(f"\n🎉 处理完成:共 {result['total_files']} 个 JSON 文件,修改了 {result['modified_files']}")
return result
# 如果作为独立脚本运行
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("❌ 用法python pathing_authors.py <JSON文件或目录路径>")
else:
process_json_authors(sys.argv[1])

View File

@@ -415,7 +415,7 @@ def check_position_ids(positions):
return validation_issues, corrections return validation_issues, corrections
# ==================== 验证修复编码 ==================== # ==================== 验证修复文件编码 ====================
def detect_encoding(file_path, read_size=2048): def detect_encoding(file_path, read_size=2048):
try: try:
@@ -477,6 +477,164 @@ def scan_and_convert(path, target_extensions=None):
else: else:
print(f"❌ Path not found: {path}") print(f"❌ Path not found: {path}")
# ==================== 验证修复作者信息 ====================
def process_json_authors(input_path, config_path="author_config.json", verbose=False):
"""
处理 JSON 文件中的作者信息(支持 author → authors 结构化迁移、作者名重命名和链接统一)
参数:
input_path (str): 要处理的文件路径或目录路径
config_path (str): 配置文件路径(默认在脚本同级)
verbose (bool): 是否打印详细日志信息
返回:
dict: 包含处理总数和修改数量的统计信息
"""
result = {
"total_files": 0,
"modified_files": 0,
"errors": []
}
if not os.path.exists(input_path):
raise FileNotFoundError(f"路径不存在:{input_path}")
if not os.path.exists(config_path):
raise FileNotFoundError(f"配置文件不存在:{config_path}")
# 加载配置
try:
with open(config_path, "r", encoding="utf-8") as f:
config = json.load(f)
except Exception as e:
raise RuntimeError(f"配置文件加载失败:{e}")
author_rename = config.get("rename", {})
author_links = config.get("links", {})
# 构建待处理文件列表
file_list = []
if os.path.isfile(input_path) and input_path.endswith(".json"):
file_list.append(input_path)
elif os.path.isdir(input_path):
for root, dirs, files in os.walk(input_path):
for filename in files:
if filename.endswith(".json"):
file_list.append(os.path.join(root, filename))
else:
raise ValueError("输入路径必须是 .json 文件或目录")
for file_path in file_list:
result["total_files"] += 1
if verbose:
print(f"\n🔍 处理文件:{file_path}")
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
except Exception as e:
msg = f"❌ 解析失败:{e}"
if verbose:
print(msg)
result["errors"].append((file_path, str(e)))
continue
info = data.get("info")
if not isinstance(info, dict):
if verbose:
print("⚠️ 缺少 info 字段")
continue
modified = False
author_field = info.get("author")
if author_field is not None:
if isinstance(author_field, str):
names = [name.strip() for name in author_field.split("&")]
new_authors = []
for name in names:
new_name = author_rename.get(name, name)
author_obj = {"name": new_name}
if new_name in author_links:
author_obj["links"] = author_links[new_name]
new_authors.append(author_obj)
data["info"]["authors"] = new_authors
modified = True
if verbose:
print("✅ 替换为结构化 authors")
elif isinstance(author_field, list):
for author_obj in author_field:
if not isinstance(author_obj, dict):
continue
name = author_obj.get("name")
if not name:
continue
new_name = author_rename.get(name, name)
if name != new_name:
author_obj["name"] = new_name
modified = True
if verbose:
print(f"📝 重命名:{name}{new_name}")
existing_link = author_obj.pop("link", None) or author_obj.pop("url", None) or author_obj.get("links")
if new_name in author_links:
if author_obj.get("links") != author_links[new_name]:
author_obj["links"] = author_links[new_name]
modified = True
if verbose:
print(f"🔧 更新链接:{new_name}{author_links[new_name]}")
elif "links" not in author_obj and existing_link:
author_obj["links"] = existing_link
modified = True
if verbose:
print(f"🔄 标准化已有链接字段为 links → {existing_link}")
else:
authors_field = info.get("authors")
if isinstance(authors_field, list):
for author_obj in authors_field:
if not isinstance(author_obj, dict):
continue
name = author_obj.get("name")
if not name:
continue
new_name = author_rename.get(name, name)
if name != new_name:
author_obj["name"] = new_name
modified = True
if verbose:
print(f"📝 重命名authors{name}{new_name}")
existing_link = author_obj.pop("link", None) or author_obj.pop("url", None) or author_obj.get("links")
if new_name in author_links:
if author_obj.get("links") != author_links[new_name]:
author_obj["links"] = author_links[new_name]
modified = True
if verbose:
print(f"🔧 更新链接authors{new_name}{author_links[new_name]}")
elif "links" not in author_obj and existing_link:
author_obj["links"] = existing_link
modified = True
if verbose:
print(f"🔄 标准化已有链接字段为 links → {existing_link}")
else:
# if verbose:
print("⚠️ 缺少 author 字段,且 authors 非标准格式")
if modified:
with open(file_path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
result["modified_files"] += 1
if verbose:
print("✅ 写入完成")
else:
if verbose:
print("⏭️ 无需修改")
if verbose:
print(f"\n🎉 处理完成:共 {result['total_files']} 个 JSON 文件,修改了 {result['modified_files']}")
# ==================== 主验证逻辑 ==================== # ==================== 主验证逻辑 ====================
def initialize_data(data, file_path): def initialize_data(data, file_path):
@@ -678,6 +836,7 @@ def main():
if os.path.isfile(path) and path.endswith('.json'): if os.path.isfile(path) and path.endswith('.json'):
scan_and_convert(path) scan_and_convert(path)
process_json_authors(path)
# print(f"\n🔍 校验文件: {path}") # print(f"\n🔍 校验文件: {path}")
notices = validate_file(path, auto_fix) notices = validate_file(path, auto_fix)
if notices: if notices:
@@ -694,6 +853,7 @@ def main():
file_path = os.path.join(root, file) file_path = os.path.join(root, file)
print(f"\n🔍 校验文件: {file_path}") print(f"\n🔍 校验文件: {file_path}")
scan_and_convert(file_path) scan_and_convert(file_path)
process_json_authors(file_path)
notices = validate_file(file_path, auto_fix) notices = validate_file(file_path, auto_fix)
if notices: if notices:
all_notices.extend([f"{file_path}: {n}" for n in notices]) all_notices.extend([f"{file_path}: {n}" for n in notices])

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750469776906 "last_modified_time": 1750469776906,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750488231659 "last_modified_time": 1750488231659,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750489051636 "last_modified_time": 1750489051636,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750493202651 "last_modified_time": 1750493202651,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750493402601 "last_modified_time": 1750493402601,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750490619726 "last_modified_time": 1750490619726,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750490831463 "last_modified_time": 1750490831463,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750493845402 "last_modified_time": 1750493845402,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750491808549 "last_modified_time": 1750491808549,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -10,7 +10,12 @@
"tags": [ "tags": [
"芭芭拉" "芭芭拉"
], ],
"last_modified_time": 1750492515991 "last_modified_time": 1750492515991,
"authors": [
{
"name": "寥寥轻舟"
}
]
}, },
"positions": [ "positions": [
{ {

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -12,8 +12,7 @@
"enable_monster_loot_split": false, "enable_monster_loot_split": false,
"authors": [ "authors": [
{ {
"name": "未知作者", "name": "白白喵"
"links": "https://github.com/babalae/bettergi-scripts-list"
} }
] ]
}, },

View File

@@ -12,8 +12,7 @@
"enable_monster_loot_split": false, "enable_monster_loot_split": false,
"authors": [ "authors": [
{ {
"name": "未知作者", "name": "白白喵"
"links": "https://github.com/babalae/bettergi-scripts-list"
} }
] ]
}, },

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -5,7 +5,7 @@
"authors": [ "authors": [
{ {
"name": "Tool_tingsu", "name": "Tool_tingsu",
"links": "" "links": "https://github.com/Tooltingsu"
} }
], ],
"version": "1.0", "version": "1.0",

View File

@@ -4,7 +4,7 @@
"type": "collect", "type": "collect",
"authors": [ "authors": [
{ {
"name": "this-Fish", "name": "蜜柑魚",
"links": "https://github.com/this-Fish" "links": "https://github.com/this-Fish"
} }
], ],

View File

@@ -4,7 +4,7 @@
"type": "collect", "type": "collect",
"authors": [ "authors": [
{ {
"name": "this-Fish", "name": "蜜柑魚",
"links": "https://github.com/this-Fish" "links": "https://github.com/this-Fish"
} }
], ],

View File

@@ -4,7 +4,7 @@
"type": "collect", "type": "collect",
"authors": [ "authors": [
{ {
"name": "this-Fish", "name": "蜜柑魚",
"links": "https://github.com/this-Fish" "links": "https://github.com/this-Fish"
} }
], ],

View File

@@ -4,7 +4,7 @@
"type": "collect", "type": "collect",
"authors": [ "authors": [
{ {
"name": "this-Fish", "name": "蜜柑魚",
"links": "https://github.com/this-Fish" "links": "https://github.com/this-Fish"
} }
], ],