Skip to main content

Renomate

先给方案、你点头、才动手、随时一键后悔 的安全批量重命名工具(TUI + CLI)。

首个场景是音乐库:把 01 稻香.mp3、周杰伦 - 稻香 [320K].mp3 这类乱七八糟的名字, 统一成 稻香 - 周杰伦 - 魔杰座 - CN.mp3。

CI Python License


1. 安全承诺(不可妥协的四条)

# 承诺 落地方式
1 默认 dry-run:任何写操作都要显式 --yes apply 默认只打印计划,不动文件
2 路径黑名单:系统目录、挂载根目录一律拒绝 safety.is_blocked_path,进入目录时立即生效
3 执行前确认:必须看见并点头 TUI 确认屏要求输入 APPLY;CLI 需要 --token APPLY
4 一键回退:改完随时后悔 事务日志 $XDG_DATA_HOME/renomate/journals/*.jsonl + renomate undo

另外:符号链接、隐藏文件、非白名单类型、只读文件默认全部跳过; 单个文件失败绝不中断整批,且会尽力回滚。

2. 效果预览

┌─ renomate v0.1.0 ── profile: audio ── /mnt/d/Music ────────────────────┐
│ 模板:{title} - {artist} - {album} - {country}                          │
│ [x] 01 稻香.mp3      → 稻香 - 周杰伦 - 魔杰座 - CN.mp3                  │
│ [x] 晴天[320K].mp3   → 晴天 - 周杰伦 - 叶惠美 - CN.mp3                  │
│ [ ] unknown.mp3      → 未知标题 - 未知歌手 - 未知专辑 - CN.mp3   ▲缺失   │
│ [!!] CON.mp3         → (Windows 保留名,已拦截)                       │
│ [??] 重名.mp3        → (冲突未消解,需手工指定)                       │
│ OK 2 / -- 1 / !! 1 / ?? 1        Space 勾选  Enter 执行  u 回退  q 退出 │
└────────────────────────────────────────────────────────────────────────┘

3. 安装

推荐从 PyPI 安装;想追最新源码或参与开发可从 GitHub 安装(见下方)。

从 PyPI 安装(推荐)

pip install "renomate[audio]"     # 含 mutagen 音频标签读取;不要 [audio] 也能跑(仅文件名推断)

从源码安装(开发 / 追最新)

git clone https://github.com/tochikoma777/renomate.git
cd renomate

# 方式 A:用 conda(Python 3.11+)
conda create -n renomate python=3.12 -y
conda activate renomate
pip install -e ".[audio]"          # 含 mutagen 音频标签读取;不要 [audio] 也能跑(仅文件名推断)

# 方式 B:用系统/已有的 Python 3.11+(虚拟环境)
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[audio]"

装完验证:

renomate --version     # 应输出版本号,如 renomate 0.1.0
renomate --help        # 应列出所有子命令

开发 / 跑测试

pip install -e ".[dev,audio]"
pytest -q

conda 一键复现

仓库也提供 environment.yml:

conda env create -f environment.yml && conda activate renomate

mutagen 是可选依赖且运行时动态 import:没装也能跑,只是读不出内嵌标签 (自动降级为文件名/目录推断)。音乐库场景建议带 [audio]。

4. 30 秒上手

renomate scan    ~/Music                       # 看看扫到了什么
renomate preview ~/Music --preset sorted       # 只看方案,绝不改文件
renomate apply   ~/Music --yes --token APPLY   # 真正执行(默认 dry-run)
renomate undo --last                           # 后悔了,一键还原

TUI:

renomate tui

不想用预设模板,可换成自定义模板(语法见第 5 节):

renomate preview ~/Music --template "{track|pad:2}. {title} - {artist}"

5. 模板语法速查

写法 含义
{title} 取字段值
{field|filter} 应用过滤器
{field|filter:arg} 带参过滤器
{album|default:未知专辑} 字段为空时的缺省值
{track|pad:2} 数字补零 → 01
{title|upper} / {lower} / {title_case} 大小写转换
{artist|strip_feat} 去掉 feat. / ft.
{country_zh} 国别代码转中文(CN → 中国)
{album}/{track|pad:2} - {title} / 表示创建子目录

渲染流程(顺序固定):取值 → 过滤器 → 逐字段 sanitize → 拼接 → 空折叠 → 长度截断 → 补扩展名。

内置预设:simple / sorted / by_album / with_year([presets] 可自行添加)。

6. 安全机制详解(五道闸门)

闸门 时机 行为
1 路径黑名单 进入目录时 /etc、/mnt/c/Windows、C:\Program Files、挂载根目录 → 拒绝
2 类型/属性白名单 扫描时 符号链接、隐藏文件、非白名单扩展名、只读文件 → 跳过并记原因
3 计划体检 生成计划时 no_op / empty_name / missing:* / path_too_long / name_too_long / cross_device / 冲突 → 跳过或拦截
4 执行前确认 执行前 TUI 确认屏输入 APPLY;CLI --token APPLY
5 执行期防御 执行时 两阶段 rename、大小写安全 rename、逐条 try/except

文件名合规化(Windows/WSL 重点):非法字符替换、控制字符删除、保留设备名 (CON.txt → _CON.txt)、末尾空格与点删除、NFC 归一化、MAX_PATH=260 与 255 字符上限校验。

7. 回退怎么用

renomate journals                       # 列出所有 session
renomate undo --last                    # 回退最近一次
renomate undo --session 20261007-153012-8f3a
renomate undo --last --dry-run          # 只看会做什么
renomate undo --last --only "稻香*"      # 只回退匹配的文件
renomate recover ~/Music                # 清理崩溃残留的 .renomate_tmp_*

回退前会校验 size + mtime_ns:与日志不一致就标 needs_manual 并跳过, 绝不基于猜测乱改名。

8. 配置

配置文件:$XDG_CONFIG_HOME/renomate/config.toml(默认 ~/.config/renomate/config.toml)。

renomate config --init      # 生成带注释的默认配置
renomate config --show
renomate config --set general.max_batch=8000
renomate profiles           # 列出 Profile 与字段定义

要点:

  • [profiles.audio]:扩展名白名单、字段列表、required_fields、默认模板、Provider 顺序;
  • [presets]:命名预设;
  • [sanitize]:平台(windows/posix)、策略(replace/drop/underscore)、长度上限、替换表;
  • [safety]:额外黑名单、allow_missing_fields、require_confirm、confirm_token;
  • [musicbrainz]:默认关闭(enabled = false),开启后限流 1 req/s 且本地缓存 30 天;
  • [defaults]:字段兜底值(未知标题 / 未知歌手 / CN …)。

目录推断(path Provider)只对嵌套文件生效:躺在扫描根目录里的文件不会把 ~/Downloads 这种目录名当成艺术家。

9. 扩展新领域(以 PDF 为例)

  1. 写 Provider(实现 name / supports / fill):
from renomate.models import FieldSource, FieldValue
from renomate.providers import register_provider


class PdfTagProvider:
    name = "pdftag"

    def supports(self, profile: str, path) -> bool:
        return path.suffix.casefold() == ".pdf"

    def fill(self, bundle, cfg) -> None:
        bundle.set("title", FieldValue("论文标题", FieldSource.AUDIOTAG, 0.9))


register_provider(PdfTagProvider())
  1. 注册 Profile(零代码,只改配置):
[profiles.pdf]
extensions = ["pdf"]
fields = ["title", "author", "year"]
required_fields = ["title"]
default_template = "{title} - {author} ({year})"
providers = ["pdftag", "filename", "default"]
  1. 加测试:pytest tests/test_providers_pdf.py。核心层(models / template / plan / executor / journal)零改动。

10. WSL / Windows 注意事项

  • /mnt/c、/mnt/d 继承 Windows 的大小写不敏感语义:A.mp3 → a.mp3 必须先改到临时名, 本工具已实现(rename_case_safe)。
  • 盘符/挂载根目录本身(C:\、/mnt/c)拒绝批量重命名。
  • Windows 保留设备名带扩展名同样非法(CON.txt)。
  • 跨设备(EXDEV)不做 move,直接 BLOCKED: cross_device。
  • 完整路径按 Windows 传统 MAX_PATH = 260 校验。

11. License

本项目 MIT,见 LICENSE。

关于 mutagen:它是 GPL-2.0-or-later,仅作为可选依赖 + 运行时动态 import 使用, 本项目本身不链接、不分发它的代码,仍为 MIT;不安装 [audio] 额外依赖时完全不会加载它。

12. Roadmap

  • 已发布到 PyPI:pip install "renomate[audio]" 即可(见第 3 节)。TestPyPI 同步有预发布验证版。
  • PDF / 照片 / 视频 Profile(架构已预留,见第 9 节)
  • undo 支持跨目录移动(当前仅同目录重命名)
  • 重名智能合并策略(保留更高音质版本)
  • 模板条件段 {album?[...]}
  • TUI 单元格就地编辑

Metadata

Release files for renomate 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for renomate 0.1.0
File Size Uploaded Provenance Actions
renomate-0.1.0.tar.gz 92.7 kB With provenance Details for renomate-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for renomate 0.1.0
File Interpreter ABI Platform Actions
renomate-0.1.0-py3-none-any.whl Python 3 none any Details for renomate-0.1.0-py3-none-any.whl

Total release size: 165.2 kB

Release files / renomate-0.1.0.tar.gz

Download URL renomate-0.1.0.tar.gz
Size 92.7 kB
Tags Source
SHA-256 checksum
How to use checksums
760ee12e7a22ab167f7f14c4025706d62b99b21cf5a9e3f9279f1612a101014b
BLAKE2b-256 checksum
How to use checksums
e9220969afd342ce7c6063fed70c8e3a02c38572d75e5b93672c3c151796a7bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / renomate-0.1.0-py3-none-any.whl

Download URL renomate-0.1.0-py3-none-any.whl
Size 72.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
809719a2e4fec71c0e049f67fc17e034b1d56e390bc54436a152cd1213f8d5f1
BLAKE2b-256 checksum
How to use checksums
46bb9828aa72da85f21b6b8c610f7568577278a1f2f84e3b2d5e7f9eede6419d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Security for renomate 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for renomate-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page