filemindr 0.1.0__tar.gz

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.
@@ -0,0 +1,46 @@
1
+ name: Publish Python Package
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ name: Test
14
+ runs-on: ubuntu-latest
15
+ container:
16
+ image: ghcr.io/astral-sh/uv:python3.12-bookworm
17
+
18
+ steps:
19
+ - name: Checkout
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Create venv
23
+ run: uv venv
24
+
25
+ - name: Install project + dev deps
26
+ run: uv sync --extra dev
27
+
28
+ - name: Run tests
29
+ run: uv run pytest -q
30
+
31
+ publish:
32
+ name: Build & Publish (PyPI)
33
+ needs: test
34
+ runs-on: ubuntu-latest
35
+ container:
36
+ image: ghcr.io/astral-sh/uv:python3.12-bookworm
37
+
38
+ steps:
39
+ - name: Checkout
40
+ uses: actions/checkout@v4
41
+
42
+ - name: Build package
43
+ run: uv build
44
+
45
+ - name: Publish to PyPI
46
+ run: uv publish --token ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,4 @@
1
+ .idea
2
+ __pycache__
3
+ .venv
4
+ fileflow.yaml
@@ -0,0 +1,22 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.6.9
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/pre-commit-hooks
10
+ rev: v4.6.0
11
+ hooks:
12
+ - id: check-merge-conflict
13
+ - id: end-of-file-fixer
14
+ - id: trailing-whitespace
15
+ - id: check-toml
16
+ - id: check-yaml
17
+
18
+ - repo: https://github.com/codespell-project/codespell
19
+ rev: v2.3.0
20
+ hooks:
21
+ - id: codespell
22
+ args: ["-L", "nd,teh"]
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: filemindr
3
+ Version: 0.1.0
4
+ Summary: Declarative local file pipelines in Python
5
+ Author: Jeferson Peter
6
+ Requires-Python: >=3.12
7
+ Requires-Dist: loguru
8
+ Requires-Dist: pydantic-settings
9
+ Requires-Dist: pyyaml
10
+ Requires-Dist: typer
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=8; extra == 'dev'
13
+ Requires-Dist: ruff>=0.5; extra == 'dev'
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Filemindr โ€” Rule-Driven Local File Automation
17
+
18
+ **Declarative local file pipelines for organizing your files.**
19
+
20
+ filemindr lets you describe *what should happen* to your files โ€” not *how*.
21
+ You define rules in YAML (extensions, regex, age, priority), and filemindr applies them safely with dryโ€‘run support, conflict handling, and a clean CLI.
22
+
23
+ This project was built as a learning + portfolio tool focused on clarity, safety, and developer experience.
24
+
25
+ ---
26
+
27
+ ## โœจ Features
28
+
29
+ - Declarative YAML configuration
30
+ - Rule engine with priority (highest wins)
31
+ - Match by:
32
+ - File extensions
33
+ - Regex on filename
34
+ - File age (`older_than_days`)
35
+ - Conflict policies:
36
+ - `rename`
37
+ - `skip`
38
+ - `overwrite`
39
+ - Dry-run mode (preview changes before touching files)
40
+ - Summary report after each run
41
+ - Proper logging levels (`INFO` / `DEBUG`)
42
+ - Cross-platform (Windows, macOS, Linux)
43
+
44
+ ---
45
+
46
+ ## ๐Ÿ“ฆ Installation
47
+
48
+ ### From PyPI (planned / when published)
49
+
50
+ ```bash
51
+ pip install Filemindr
52
+ ```
53
+
54
+ Or:
55
+
56
+ ```bash
57
+ python -m pip install Filemindr
58
+ ```
59
+
60
+ ### Local development
61
+
62
+ ```bash
63
+ pip install -e .
64
+ ```
65
+
66
+ With uv:
67
+
68
+ ```bash
69
+ uv sync
70
+ ```
71
+
72
+ ---
73
+
74
+ ## ๐Ÿš€ Quick Start
75
+
76
+ Create a `filemindr.yaml`:
77
+
78
+ ```yaml
79
+ source: ~/Downloads
80
+ default_target: ~/Downloads/others
81
+ conflict_policy: rename
82
+
83
+ rules:
84
+ - name: invoices
85
+ priority: 100
86
+ match:
87
+ extensions: ["pdf"]
88
+ regex: "(?i)invoice|nota|nf"
89
+ action:
90
+ move_to: ~/Downloads/finance/invoices
91
+
92
+ - name: documents
93
+ priority: 50
94
+ match:
95
+ extensions: ["pdf", "docx", "xlsx"]
96
+ action:
97
+ move_to: ~/Downloads/documents
98
+
99
+ - name: images
100
+ priority: 40
101
+ match:
102
+ extensions: ["jpg", "jpeg", "png", "webp"]
103
+ action:
104
+ move_to: ~/Downloads/images
105
+
106
+ - name: old_installers
107
+ priority: 80
108
+ match:
109
+ extensions: ["exe", "msi"]
110
+ older_than_days: 14
111
+ action:
112
+ move_to: ~/Downloads/installers/old
113
+ ```
114
+
115
+ Preview changes:
116
+
117
+ ```bash
118
+ filemindr run --dry-run
119
+ ```
120
+
121
+ Run for real:
122
+
123
+ ```bash
124
+ filemindr run
125
+ ```
126
+
127
+ Verbose mode (per-file logs):
128
+
129
+ ```bash
130
+ filemindr run --log-level DEBUG
131
+ ```
132
+
133
+ ---
134
+
135
+ ## ๐Ÿง  How it works
136
+
137
+ 1. Filemind scans the source directory
138
+ 2. Rules are evaluated by priority (highest first)
139
+ 3. The first matching rule wins
140
+ 4. Files are moved according to the selected conflict policy
141
+ 5. A summary is printed at the end
142
+
143
+ ---
144
+
145
+ ## โš” Conflict Policy
146
+
147
+ - `rename` (default): creates `file (1).ext`, `file (2).ext`, etc
148
+ - `skip`: ignores files that already exist
149
+ - `overwrite`: replaces existing files
150
+
151
+ ---
152
+
153
+ ## ๐Ÿงช Development
154
+
155
+ Run tests:
156
+
157
+ ```bash
158
+ uv run pytest
159
+ ```
160
+
161
+ Project layout:
162
+
163
+ ```
164
+ filemindr/
165
+ โ”œโ”€โ”€ src/filemindr/
166
+ โ”œโ”€โ”€ tests/
167
+ โ”œโ”€โ”€ pyproject.toml
168
+ โ””โ”€โ”€ README.md
169
+ ```
170
+
171
+ ---
172
+
173
+ ## ๐Ÿ›  Status
174
+
175
+ Early alpha / experimental.
176
+
177
+ APIs may change.
178
+
179
+ ---
180
+
181
+ ## ๐Ÿ“„ License
182
+
183
+ MIT
184
+
185
+ ---
186
+
187
+ ## Roadmap
188
+
189
+ - [ ] Watch mode (real-time folder monitoring)
190
+ - [ ] Per-rule conflict policies
191
+ - [ ] Copy instead of move
192
+ - [ ] Trash support
193
+ - [ ] Config validation
@@ -0,0 +1,178 @@
1
+ # Filemindr โ€” Rule-Driven Local File Automation
2
+
3
+ **Declarative local file pipelines for organizing your files.**
4
+
5
+ filemindr lets you describe *what should happen* to your files โ€” not *how*.
6
+ You define rules in YAML (extensions, regex, age, priority), and filemindr applies them safely with dryโ€‘run support, conflict handling, and a clean CLI.
7
+
8
+ This project was built as a learning + portfolio tool focused on clarity, safety, and developer experience.
9
+
10
+ ---
11
+
12
+ ## โœจ Features
13
+
14
+ - Declarative YAML configuration
15
+ - Rule engine with priority (highest wins)
16
+ - Match by:
17
+ - File extensions
18
+ - Regex on filename
19
+ - File age (`older_than_days`)
20
+ - Conflict policies:
21
+ - `rename`
22
+ - `skip`
23
+ - `overwrite`
24
+ - Dry-run mode (preview changes before touching files)
25
+ - Summary report after each run
26
+ - Proper logging levels (`INFO` / `DEBUG`)
27
+ - Cross-platform (Windows, macOS, Linux)
28
+
29
+ ---
30
+
31
+ ## ๐Ÿ“ฆ Installation
32
+
33
+ ### From PyPI (planned / when published)
34
+
35
+ ```bash
36
+ pip install Filemindr
37
+ ```
38
+
39
+ Or:
40
+
41
+ ```bash
42
+ python -m pip install Filemindr
43
+ ```
44
+
45
+ ### Local development
46
+
47
+ ```bash
48
+ pip install -e .
49
+ ```
50
+
51
+ With uv:
52
+
53
+ ```bash
54
+ uv sync
55
+ ```
56
+
57
+ ---
58
+
59
+ ## ๐Ÿš€ Quick Start
60
+
61
+ Create a `filemindr.yaml`:
62
+
63
+ ```yaml
64
+ source: ~/Downloads
65
+ default_target: ~/Downloads/others
66
+ conflict_policy: rename
67
+
68
+ rules:
69
+ - name: invoices
70
+ priority: 100
71
+ match:
72
+ extensions: ["pdf"]
73
+ regex: "(?i)invoice|nota|nf"
74
+ action:
75
+ move_to: ~/Downloads/finance/invoices
76
+
77
+ - name: documents
78
+ priority: 50
79
+ match:
80
+ extensions: ["pdf", "docx", "xlsx"]
81
+ action:
82
+ move_to: ~/Downloads/documents
83
+
84
+ - name: images
85
+ priority: 40
86
+ match:
87
+ extensions: ["jpg", "jpeg", "png", "webp"]
88
+ action:
89
+ move_to: ~/Downloads/images
90
+
91
+ - name: old_installers
92
+ priority: 80
93
+ match:
94
+ extensions: ["exe", "msi"]
95
+ older_than_days: 14
96
+ action:
97
+ move_to: ~/Downloads/installers/old
98
+ ```
99
+
100
+ Preview changes:
101
+
102
+ ```bash
103
+ filemindr run --dry-run
104
+ ```
105
+
106
+ Run for real:
107
+
108
+ ```bash
109
+ filemindr run
110
+ ```
111
+
112
+ Verbose mode (per-file logs):
113
+
114
+ ```bash
115
+ filemindr run --log-level DEBUG
116
+ ```
117
+
118
+ ---
119
+
120
+ ## ๐Ÿง  How it works
121
+
122
+ 1. Filemind scans the source directory
123
+ 2. Rules are evaluated by priority (highest first)
124
+ 3. The first matching rule wins
125
+ 4. Files are moved according to the selected conflict policy
126
+ 5. A summary is printed at the end
127
+
128
+ ---
129
+
130
+ ## โš” Conflict Policy
131
+
132
+ - `rename` (default): creates `file (1).ext`, `file (2).ext`, etc
133
+ - `skip`: ignores files that already exist
134
+ - `overwrite`: replaces existing files
135
+
136
+ ---
137
+
138
+ ## ๐Ÿงช Development
139
+
140
+ Run tests:
141
+
142
+ ```bash
143
+ uv run pytest
144
+ ```
145
+
146
+ Project layout:
147
+
148
+ ```
149
+ filemindr/
150
+ โ”œโ”€โ”€ src/filemindr/
151
+ โ”œโ”€โ”€ tests/
152
+ โ”œโ”€โ”€ pyproject.toml
153
+ โ””โ”€โ”€ README.md
154
+ ```
155
+
156
+ ---
157
+
158
+ ## ๐Ÿ›  Status
159
+
160
+ Early alpha / experimental.
161
+
162
+ APIs may change.
163
+
164
+ ---
165
+
166
+ ## ๐Ÿ“„ License
167
+
168
+ MIT
169
+
170
+ ---
171
+
172
+ ## Roadmap
173
+
174
+ - [ ] Watch mode (real-time folder monitoring)
175
+ - [ ] Per-rule conflict policies
176
+ - [ ] Copy instead of move
177
+ - [ ] Trash support
178
+ - [ ] Config validation
@@ -0,0 +1,6 @@
1
+ def main():
2
+ print("Hello from filemindr!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1,27 @@
1
+ [project]
2
+ name = "filemindr"
3
+ version = "0.1.0"
4
+ description = "Declarative local file pipelines in Python"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ authors = [{ name = "Jeferson Peter" }]
8
+
9
+ dependencies = [
10
+ "typer",
11
+ "pyyaml",
12
+ "loguru",
13
+ "pydantic-settings",
14
+ ]
15
+
16
+ [project.scripts]
17
+ filemindr = "filemindr.cli:app"
18
+
19
+ [project.optional-dependencies]
20
+ dev = [
21
+ "pytest>=8",
22
+ "ruff>=0.5",
23
+ ]
24
+
25
+ [build-system]
26
+ requires = ["hatchling"]
27
+ build-backend = "hatchling.build"
File without changes
@@ -0,0 +1,32 @@
1
+ import sys
2
+ import typer
3
+ from loguru import logger
4
+
5
+ from filemindr.core.config import resolve_config
6
+ from filemindr.core.runner import run_pipeline
7
+
8
+ app = typer.Typer(help="Declarative local file pipelines")
9
+
10
+
11
+ @app.command()
12
+ def run(
13
+ config: str = "filemindr.yaml",
14
+ dry_run: bool = False,
15
+ log_level: str = typer.Option("INFO", help="Log level: INFO or DEBUG"),
16
+ ):
17
+ """
18
+ Run filemindr pipeline.
19
+ """
20
+ # Configura logging
21
+ logger.remove()
22
+ logger.add(sys.stdout, level=log_level.upper())
23
+
24
+ config_path = resolve_config(config)
25
+
26
+ logger.info(f"Running pipeline with config={config_path} dry_run={dry_run}")
27
+
28
+ run_pipeline(str(config_path), dry_run)
29
+
30
+
31
+ if __name__ == "__main__":
32
+ app()
File without changes
@@ -0,0 +1,16 @@
1
+ from pathlib import Path
2
+
3
+
4
+ def resolve_config(cli_path: str | None = None) -> Path:
5
+ if cli_path:
6
+ return Path(cli_path).expanduser()
7
+
8
+ local = Path.cwd() / "filemindr.yaml"
9
+ if local.exists():
10
+ return local
11
+
12
+ home = Path.home() / ".filemindr" / "config.yaml"
13
+ if home.exists():
14
+ return home
15
+
16
+ raise FileNotFoundError("No filemindr config found.")