fileflow-cli 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fileflow/templates.py ADDED
@@ -0,0 +1,124 @@
1
+ """模板路径变量解析引擎.
2
+
3
+ 支持以下变量(在 target 路径中使用):
4
+ {name} — 文件名(不含扩展名)
5
+ {ext} — 扩展名,例如 .jpg, .pdf(含点)
6
+ {ext_no_dot} — 扩展名不带点
7
+ {filename} — 完整文件名
8
+ {year} — 4 位年份
9
+ {month} — 2 位月份(01-12)
10
+ {month:02d} — 同上,始终 2 位
11
+ {day} — 2 位日期(01-31)
12
+ {day:02d} — 同上,始终 2 位
13
+ {hour} — 2 位小时
14
+ {minute} — 2 位分钟
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import string
20
+ from dataclasses import dataclass
21
+ from datetime import datetime
22
+ from pathlib import Path
23
+ from typing import Any
24
+
25
+
26
+ class TemplateError(Exception):
27
+ """模板解析错误."""
28
+
29
+
30
+ @dataclass
31
+ class TemplateContext:
32
+ """模板变量上下文."""
33
+
34
+ filename: str
35
+ name: str
36
+ ext: str
37
+ ext_no_dot: str
38
+ year: str
39
+ month: str
40
+ day: str
41
+ hour: str
42
+ minute: str
43
+
44
+ @classmethod
45
+ def from_path(cls, path: Path) -> TemplateContext:
46
+ """根据文件路径和当前时间构建上下文."""
47
+ now = datetime.now()
48
+ return cls(
49
+ filename=path.name,
50
+ name=path.stem,
51
+ ext=path.suffix,
52
+ ext_no_dot=path.suffix.lstrip("."),
53
+ year=str(now.year),
54
+ month=f"{now.month:02d}",
55
+ day=f"{now.day:02d}",
56
+ hour=f"{now.hour:02d}",
57
+ minute=f"{now.minute:02d}",
58
+ )
59
+
60
+
61
+ class TemplateFormatter(string.Formatter):
62
+ """自定义格式化器,支持 {month:02d} 等格式."""
63
+
64
+ def get_field(self, field_name: str, args: Any, kwargs: Any) -> Any:
65
+ return super().get_field(field_name, args, kwargs)
66
+
67
+
68
+ _formatter = TemplateFormatter()
69
+ _ALLOWED_VARS = {
70
+ "filename", "name", "ext", "ext_no_dot",
71
+ "year", "month", "day", "hour", "minute",
72
+ }
73
+
74
+
75
+ def render(template: str, path: Path) -> str:
76
+ """渲染目标路径模板.
77
+
78
+ Args:
79
+ template: 模板字符串,如 "Pictures/{ext}/{filename}"
80
+ path: 源文件路径.
81
+
82
+ Returns:
83
+ 渲染后的路径字符串(相对路径,不含源文件根目录).
84
+
85
+ Raises:
86
+ TemplateError: 模板包含未知变量.
87
+ """
88
+ ctx = TemplateContext.from_path(path)
89
+ try:
90
+ result = _formatter.vformat(template, (), ctx.__dict__)
91
+ except KeyError as e:
92
+ raise TemplateError(f"未知的模板变量: {e}") from e
93
+
94
+ # 检查是否有未识别的变量
95
+ for unresolved in _find_unresolved_braces(result):
96
+ raise TemplateError(f"未解析的模板变量: {{{unresolved}}}")
97
+
98
+ return result
99
+
100
+
101
+ def _find_unresolved_braces(text: str) -> list[str]:
102
+ """查找未解析的 {var} 模式."""
103
+ import re
104
+
105
+ return re.findall(r"\{(\w+)\}", text)
106
+
107
+
108
+ def resolve_path(target_template: str, source_path: Path, base_dir: Path) -> Path:
109
+ """将目标模板解析为绝对路径.
110
+
111
+ 如果 target_template 是绝对路径,直接使用;
112
+ 否则拼接在 base_dir 下。
113
+
114
+ Returns:
115
+ 目标绝对路径.
116
+
117
+ Raises:
118
+ TemplateError: 模板变量错误.
119
+ """
120
+ rendered = render(target_template, source_path)
121
+ dest = Path(rendered)
122
+ if dest.is_absolute():
123
+ return dest
124
+ return (base_dir / dest).resolve()
@@ -0,0 +1,204 @@
1
+ Metadata-Version: 2.4
2
+ Name: fileflow-cli
3
+ Version: 0.1.0
4
+ Summary: 🧹 智能文件整理器 — YAML 规则引擎驱动的 CLI 文件分类/移动/清理工具
5
+ Author-email: Yuluo <lingeryuluo@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Linger668/fileflow
8
+ Project-URL: Repository, https://github.com/Linger668/fileflow
9
+ Project-URL: Issues, https://github.com/Linger668/fileflow/issues
10
+ Keywords: file-organization,file-management,cli,productivity
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Desktop Environment :: File Managers
22
+ Classifier: Topic :: Utilities
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: typer>=0.12.0
27
+ Requires-Dist: rich>=13.7.0
28
+ Requires-Dist: pyyaml>=6.0
29
+ Provides-Extra: watch
30
+ Requires-Dist: watchdog>=4.0.0; extra == "watch"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=8.0; extra == "dev"
33
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
34
+ Requires-Dist: ruff>=0.5.0; extra == "dev"
35
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
36
+ Requires-Dist: build>=1.0.0; extra == "dev"
37
+ Requires-Dist: twine>=5.0.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # 🧹 FileFlow
41
+
42
+ > 智能文件整理器 — 基于 YAML 规则引擎的 CLI 文件分类/移动/清理工具
43
+
44
+ [![PyPI version](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/fileflow/)
45
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
46
+ [![Ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
47
+
48
+ ---
49
+
50
+ ## ✨ 功能
51
+
52
+ - 📝 **YAML 规则引擎** — 声明式配置,一目了然
53
+ - 🔍 **预览模式** — 先看效果再执行,安全无副作用
54
+ - 📂 **多种匹配方式** — 扩展名/通配符/正则/文件名/大小
55
+ - 🎯 **智能文件移动** — 自动创建目录,冲突策略可选
56
+ - ⏪ **支持撤销** — 操作历史可追溯(即将推出)
57
+ - 🎨 **Rich 终端美化** — 彩色表格,清晰直观
58
+ - 🔌 **可扩展架构** — 匹配器和操作都支持注册表模式
59
+
60
+ ## 🚀 快速开始
61
+
62
+ ### 安装
63
+
64
+ ```bash
65
+ pip install fileflow
66
+ ```
67
+
68
+ ### 1. 初始化配置
69
+
70
+ 在要整理的目录下生成配置文件:
71
+
72
+ ```bash
73
+ cd ~/Downloads
74
+ fileflow init
75
+ ```
76
+
77
+ 这会生成 `.fileflow.yaml`,内置了图片/文档/视频/代码等常用规则。
78
+
79
+ ### 2. 预览效果
80
+
81
+ ```bash
82
+ fileflow run .
83
+ ```
84
+
85
+ 以预览模式运行,会展示每个文件将被如何整理,**不会真正移动文件**。
86
+
87
+ ### 3. 执行整理
88
+
89
+ ```bash
90
+ fileflow run . --force
91
+ ```
92
+
93
+ 确认无误后,使用 `--force` 真正执行。
94
+
95
+ ### 一键完成(跳过确认)
96
+
97
+ ```bash
98
+ fileflow run . --force --yes
99
+ ```
100
+
101
+ ## 📖 使用指南
102
+
103
+ ### 命令概览
104
+
105
+ ```bash
106
+ fileflow init # 生成默认配置文件
107
+ fileflow run # 运行整理(默认预览)
108
+ fileflow validate # 验证配置文件
109
+ fileflow list-rules # 查看规则列表
110
+ fileflow --help # 查看全部命令
111
+ ```
112
+
113
+ ### 选项
114
+
115
+ | 选项 | 说明 |
116
+ |------|------|
117
+ | `--config, -c` | 指定配置文件路径 |
118
+ | `--dry-run, -n` | 仅预览模式 |
119
+ | `--force, -f` | 跳过预览直接执行 |
120
+ | `--yes, -y` | 自动确认,跳过交互提示 |
121
+ | `--no-recursive` | 不递归扫描子目录 |
122
+ | `--verbose, -v` | 详细输出 |
123
+ | `--version, -V` | 显示版本 |
124
+
125
+ ### 配置示例
126
+
127
+ ```yaml
128
+ # .fileflow.yaml
129
+ version: "1.0"
130
+
131
+ settings:
132
+ dry_run_by_default: true # 默认预览模式
133
+ on_conflict: "skip" # skip | rename | overwrite | ask
134
+ create_target_dirs: true
135
+
136
+ rules:
137
+ - name: "整理图片"
138
+ match:
139
+ extensions: [".jpg", ".jpeg", ".png", ".gif", ".svg"]
140
+ action: move
141
+ target: "Pictures/{ext}/{filename}"
142
+
143
+ - name: "清理旧日志"
144
+ match:
145
+ extensions: [".log"]
146
+ modified_before_days: 30
147
+ action: delete
148
+ enabled: false # 默认禁用
149
+ ```
150
+
151
+ ### 📂 模板变量
152
+
153
+ 目标路径 `target` 支持以下变量:
154
+
155
+ | 变量 | 说明 | 示例 |
156
+ |------|------|------|
157
+ | `{filename}` | 完整文件名 | `report.pdf` |
158
+ | `{name}` | 文件名(不含扩展名) | `report` |
159
+ | `{ext}` | 扩展名(含点,推荐用于文件名) | `.pdf` |
160
+ | `{ext_no_dot}` | 扩展名(不含点,推荐用于目录名) | `pdf` |
161
+ | `{year}` | 4 位年份 | `2026` |
162
+ | `{month}` | 2 位月份 | `07` |
163
+ | `{day}` | 2 位日期 | `13` |
164
+ | `{hour}` | 2 位小时 | `14` |
165
+ | `{minute}` | 2 位分钟 | `30` |
166
+
167
+ ## 🏗 项目架构
168
+
169
+ ```
170
+ fileflow/
171
+ ├── src/fileflow/
172
+ │ ├── cli.py # CLI 命令定义 (Typer)
173
+ │ ├── config.py # YAML 配置加载 & 验证
174
+ │ ├── engine.py # 核心编排引擎
175
+ │ ├── rules.py # 规则数据模型
176
+ │ ├── matchers.py # 匹配器注册表 & 内置匹配器
177
+ │ ├── actions.py # 文件操作 (move/copy/delete)
178
+ │ ├── templates.py # 路径模板变量解析
179
+ │ ├── report.py # Rich 终端输出
180
+ │ └── watcher.py # 实时监控(可选)
181
+ ├── tests/ # 全模块测试覆盖
182
+ └── pyproject.toml # 项目配置
183
+ ```
184
+
185
+ ## 🧪 运行测试
186
+
187
+ ```bash
188
+ pip install -e ".[dev]"
189
+ pytest
190
+ ```
191
+
192
+ 查看测试覆盖率:
193
+
194
+ ```bash
195
+ pytest --cov --cov-report=html
196
+ ```
197
+
198
+ ## 🤝 贡献
199
+
200
+ 欢迎提交 Issue 和 PR!详情见 [CONTRIBUTING.md](CONTRIBUTING.md)。
201
+
202
+ ## 📄 许可证
203
+
204
+ [MIT](LICENSE) © 2026 Yuluo
@@ -0,0 +1,16 @@
1
+ fileflow/__init__.py,sha256=p9sKzFor4MSLHEJGL4Y_LHG2ReYWPgoGMJB1r2slbW8,65
2
+ fileflow/__main__.py,sha256=0j6YkleysZiA9zUxOdSOB0VLE4RJAOVa2e8xwsHJIYg,100
3
+ fileflow/actions.py,sha256=xVKdnwCOU7EU6QAgKX82cUQx-yoEcWDI_f9qsgRuR38,4710
4
+ fileflow/cli.py,sha256=kXW9zeaA93metNp6cI1cc0p4X8XgIU-YPBqwJJJxzh8,5357
5
+ fileflow/config.py,sha256=xo2ukKyAxGC5ruNl6cCWXObDtrAaxUBFOP8bxdMIrOk,5226
6
+ fileflow/engine.py,sha256=Tb37W0JbpMSJ3QP2k570DUduMKGBJC0idlgveGkPc6I,5096
7
+ fileflow/matchers.py,sha256=q4v_jSAhR80MCfXLaaSP-u6XwXyoDZa6k5XezuHmRxQ,6352
8
+ fileflow/report.py,sha256=BK44CWfamyqpZT_Vzoahmi4ihbBnUS_-ppimGJlmf0c,5310
9
+ fileflow/rules.py,sha256=K_u9MOtCFzgDPbcfh62CC322tv1hgLwfmYVC8XvSuHE,2669
10
+ fileflow/templates.py,sha256=VH-UGQqKNr6nQotKlSTtT0RlXYCUhzne_v4i63lMfsc,3267
11
+ fileflow_cli-0.1.0.dist-info/licenses/LICENSE,sha256=hNx-ECYdfwssDGwJr1LV-rFwAjyYoTc8XQs4HEWkx4c,1062
12
+ fileflow_cli-0.1.0.dist-info/METADATA,sha256=TFFmMsMm45f_qYuY6xOC9B6LxIPSl3aLEmjb6BGQFEI,5963
13
+ fileflow_cli-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
14
+ fileflow_cli-0.1.0.dist-info/entry_points.txt,sha256=G7wG0F-rGKahrDqANcAvvPyYeanLMlPkr-ruyazH5WA,46
15
+ fileflow_cli-0.1.0.dist-info/top_level.txt,sha256=dqhg2RJdWiHT_o-4y5CgIhJV2vsJQHr3GS4Uo3zVENY,9
16
+ fileflow_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ fileflow = fileflow.cli:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yuluo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ fileflow