locals-filesystem 1.0.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.
- locals_filesystem-1.0.0/LICENSE +21 -0
- locals_filesystem-1.0.0/PKG-INFO +309 -0
- locals_filesystem-1.0.0/README.md +276 -0
- locals_filesystem-1.0.0/fileforge/__init__.py +24 -0
- locals_filesystem-1.0.0/fileforge/__main__.py +9 -0
- locals_filesystem-1.0.0/fileforge/analytics.py +185 -0
- locals_filesystem-1.0.0/fileforge/archive.py +311 -0
- locals_filesystem-1.0.0/fileforge/cli.py +897 -0
- locals_filesystem-1.0.0/fileforge/core.py +467 -0
- locals_filesystem-1.0.0/fileforge/gui.py +1883 -0
- locals_filesystem-1.0.0/fileforge/hashutil.py +235 -0
- locals_filesystem-1.0.0/fileforge/repl.py +177 -0
- locals_filesystem-1.0.0/fileforge/search.py +242 -0
- locals_filesystem-1.0.0/fileforge/security.py +264 -0
- locals_filesystem-1.0.0/fileforge/utils.py +416 -0
- locals_filesystem-1.0.0/locals_filesystem.egg-info/PKG-INFO +309 -0
- locals_filesystem-1.0.0/locals_filesystem.egg-info/SOURCES.txt +20 -0
- locals_filesystem-1.0.0/locals_filesystem.egg-info/dependency_links.txt +1 -0
- locals_filesystem-1.0.0/locals_filesystem.egg-info/entry_points.txt +5 -0
- locals_filesystem-1.0.0/locals_filesystem.egg-info/top_level.txt +1 -0
- locals_filesystem-1.0.0/pyproject.toml +48 -0
- locals_filesystem-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Windows Monitor
|
|
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,309 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: locals_filesystem
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Portable local file-system toolkit (CLI + interactive shell + Tkinter GUI) for Linux, Windows and macOS. Pure standard library, zero dependencies.
|
|
5
|
+
Author: goldensakurazero
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: filesystem,file-manager,file-search,duplicate-finder,checksum,archive,cross-platform,cli,gui,tkinter
|
|
8
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Environment :: X11 Applications
|
|
11
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
12
|
+
Classifier: Environment :: MacOS X
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Topic :: Desktop Environment :: File Managers
|
|
27
|
+
Classifier: Topic :: System :: Filesystems
|
|
28
|
+
Classifier: Topic :: Utilities
|
|
29
|
+
Requires-Python: >=3.8
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# fileforge
|
|
35
|
+
|
|
36
|
+
A portable, **dependency-free** local file-system toolkit written in pure Python.
|
|
37
|
+
Runs unchanged on **Linux**, **Windows** and **macOS** — command line, interactive
|
|
38
|
+
shell **and a full graphical interface**.
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
_____.__.__ _____
|
|
42
|
+
_|__| | | | ____ / ____/___ ________ ____ ______ ____
|
|
43
|
+
| | | | | _/ __ \ / /_ / __ \/ ___/ _ \/ __ `/ ___/ _ \_/ __ \
|
|
44
|
+
| | |_| |_|\ ___// __/ / /_/ / / / __/ /_/ / / / __/ ___/
|
|
45
|
+
|__|____/____/ \___/ /_/ \____/_/ \___/\__, /_/ \___/\___/
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Requirements
|
|
51
|
+
|
|
52
|
+
* Python **3.8+** (tested on 3.12 / 3.13)
|
|
53
|
+
* No third-party packages — only the standard library
|
|
54
|
+
* The GUI needs `tkinter` (bundled with Windows/macOS Python and
|
|
55
|
+
`python3-tk` on Linux)
|
|
56
|
+
* Works on Linux, Windows 10/11 and macOS
|
|
57
|
+
|
|
58
|
+
## Quick start
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# from the repository
|
|
62
|
+
python fileforge.py --help # list all commands
|
|
63
|
+
python fileforge.py gui # graphical interface
|
|
64
|
+
python fileforge.py shell # interactive shell
|
|
65
|
+
python -m fileforge ls -l . # run as a module
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Install as a pip package
|
|
69
|
+
|
|
70
|
+
The project ships as a wheel (`dist/fileforge_toolkit-1.0.0-py3-none-any.whl`):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install dist/fileforge_toolkit-1.0.0-py3-none-any.whl
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
After installation two commands are available everywhere:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
fileforge --version # CLI (all 40+ commands)
|
|
80
|
+
fileforge shell # interactive shell
|
|
81
|
+
fileforge-gui # graphical interface (no console window)
|
|
82
|
+
fileforge gui # GUI via the CLI entry point
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
To publish to PyPI (once you own the name):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
python -m build # rebuild dist/
|
|
89
|
+
twine upload dist/*
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
To build from source: `pip install build && python -m build`.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Command reference
|
|
97
|
+
|
|
98
|
+
### Navigation & listing
|
|
99
|
+
|
|
100
|
+
| Command | Description |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `ls [path] [-l] [-a] [--sort name\|size\|time\|ext]` | List directory contents |
|
|
103
|
+
| `tree [path] [-L depth] [-a] [--no-size]` | ASCII directory tree with sizes |
|
|
104
|
+
| `stat <path> [--json]` | Detailed metadata (mode, times, inode, counts, MIME) |
|
|
105
|
+
| `filetype <path>` | Content-based MIME detection |
|
|
106
|
+
| `free [path]` | Free / used / total space on a volume |
|
|
107
|
+
|
|
108
|
+
### File content
|
|
109
|
+
|
|
110
|
+
| Command | Description |
|
|
111
|
+
|---|---|
|
|
112
|
+
| `cat <path> [-n] [--head N] [--tail N] [--encoding ENC]` | Print a text file |
|
|
113
|
+
| `write <path> (-c TEXT \| -f FILE \| --stdin) [-a] [--newline]` | Write or append |
|
|
114
|
+
| `touch <path>` | Create an empty file / bump mtime |
|
|
115
|
+
| `wc <path>` | Count lines, words, chars, bytes |
|
|
116
|
+
| `replace <path> OLD NEW [--regex] [-i] [--dry-run]` | In-place text replace |
|
|
117
|
+
| `convert-encoding <path> --to ENC [--from ENC] [-o OUT]` | Transcode a text file |
|
|
118
|
+
|
|
119
|
+
### File & directory management
|
|
120
|
+
|
|
121
|
+
| Command | Description |
|
|
122
|
+
|---|---|
|
|
123
|
+
| `cp <src> <dest> [--overwrite] [--no-recursive] [--no-preserve]` | Copy file/dir |
|
|
124
|
+
| `mv <src> <dest> [--overwrite]` | Move or rename |
|
|
125
|
+
| `rm <path> [-r] [-f] [--secure] [--passes N]` | Remove (optionally shred) |
|
|
126
|
+
| `mkdir <path> [--no-parents] [--exist-ok]` | Create directories |
|
|
127
|
+
| `rename <path> <new_name>` | Rename one path |
|
|
128
|
+
| `rename-batch <paths...> --pattern P --replacement R [--regex] [-i] [--dry-run]` | Batch rename |
|
|
129
|
+
| `symlink <target> <link>` / `readlink <path>` | Symbolic links |
|
|
130
|
+
|
|
131
|
+
### Search
|
|
132
|
+
|
|
133
|
+
| Command | Description |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `find [root] [-name GLOB] [--regex RE] [--ext .py] [--min-size 1k] [--max-size 10M] [--newer 7d] [--older 30d] [--content TEXT] [--files-only] [--dirs-only] [--empty] [--depth N] [-a] [-l] [--limit N]` | Multi-criteria search |
|
|
136
|
+
| `grep <pattern> [paths...] [--regex] [-s] [--include GLOB] [--exclude GLOB] [--no-recursive] [--max N]` | Search text inside files |
|
|
137
|
+
|
|
138
|
+
Size accepts `B, K/KB, M/MB, G/GB, T/TB`. Duration accepts `s, m, h, d, w`
|
|
139
|
+
(e.g. `7d`, `12h`, `3d12h`).
|
|
140
|
+
|
|
141
|
+
### Integrity
|
|
142
|
+
|
|
143
|
+
| Command | Description |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `hash <paths...> [-a ALGO] [-r]` | Checksums (md5, sha1/224/256/384/512, blake2b/s) |
|
|
146
|
+
| `manifest <root> [-a ALGO] [-o OUT]` | Create a JSON checksum manifest |
|
|
147
|
+
| `verify <manifest> [--extra]` | Verify files against a manifest |
|
|
148
|
+
| `compare <a> <b> [-a ALGO]` | Compare two files, report first differing byte |
|
|
149
|
+
| `dupes <root> [-a ALGO] [--min-size SIZE] [--hidden]` | Find duplicate files |
|
|
150
|
+
|
|
151
|
+
### Analytics
|
|
152
|
+
|
|
153
|
+
| Command | Description |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `du [root] [--top N] [--no-hidden]` | Disk-usage breakdown by extension / top-level |
|
|
156
|
+
| `largest [root] [--limit N]` | Largest files |
|
|
157
|
+
| `newest [root] [--limit N]` / `oldest [root] [--limit N]` | By modification time |
|
|
158
|
+
| `empty [root]` | Empty files and directories |
|
|
159
|
+
| `broken-links [root]` | Broken symbolic links |
|
|
160
|
+
| `ext-summary [root]` | Per-extension file count and size |
|
|
161
|
+
| `summary [root]` | One-shot full report |
|
|
162
|
+
|
|
163
|
+
### Archives, split & sync
|
|
164
|
+
|
|
165
|
+
| Command | Description |
|
|
166
|
+
|---|---|
|
|
167
|
+
| `archive-create <output> <sources...> [--format zip\|tar] [--base-dir DIR]` | Create zip / tar / tar.gz / tar.bz2 / tar.xz |
|
|
168
|
+
| `archive-extract <archive> [-d DEST] [--member NAME]` | Extract (zip-slip protected) |
|
|
169
|
+
| `archive-list <archive>` | List entries |
|
|
170
|
+
| `gzip <path> [-d] [-k]` | Single-file gzip / gunzip |
|
|
171
|
+
| `split <path> --size 10M [--out-dir D]` | Split a file into parts |
|
|
172
|
+
| `merge <output> <parts...>` | Merge parts back |
|
|
173
|
+
| `sync <src> <dest> [--delete] [--dry-run]` | Incremental directory mirror |
|
|
174
|
+
|
|
175
|
+
### Permissions & security
|
|
176
|
+
|
|
177
|
+
| Command | Description |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `chmod <path> <mode> [-r]` | Octal (`644`) or symbolic (`+x`, `u+rw`, `go-w`) |
|
|
180
|
+
| `perms [path] [-r]` | Show permission strings |
|
|
181
|
+
| `world-writable [root]` | Audit world-writable entries |
|
|
182
|
+
| `shred <path> [--passes N]` | Overwrite then delete a file |
|
|
183
|
+
| `encrypt <path> [-p PWD] [-o OUT] [--remove-source]` | Encrypt to `.ffenc` |
|
|
184
|
+
| `decrypt <path> [-p PWD] [-o OUT] [--remove-source]` | Decrypt `.ffenc` |
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Graphical interface
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
python fileforge.py gui # or: fileforge-gui after pip install
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
A single window with a directory tree on the left and eight tool tabs:
|
|
195
|
+
|
|
196
|
+
| Tab | What you can do |
|
|
197
|
+
|---|---|
|
|
198
|
+
| **Browser** | Navigate, sort, copy/move/rename/delete/shred, properties, hash, archive, encrypt, open terminal or file manager, context menu |
|
|
199
|
+
| **Search** | All find criteria (glob, regex, ext, size, age, content, empty, depth) with a results table and right-click actions |
|
|
200
|
+
| **Grep** | Recursive text search with include/exclude filters; double-click jumps to the line in the built-in viewer |
|
|
201
|
+
| **Integrity** | Hash any file, compare two files, create/verify manifests, find duplicates and delete the extra copies |
|
|
202
|
+
| **Archive** | Create/extract/inspect zip & tar archives, gzip, split files into parts, merge parts back, incremental folder sync |
|
|
203
|
+
| **Analytics** | Summary report, extension breakdown with a bar chart, largest/newest/oldest files, empty items, broken links |
|
|
204
|
+
| **Security** | Encrypt/decrypt with password, shred, chmod (octal + symbolic), permission listing, world-writable audit |
|
|
205
|
+
| **Text Tools** | View and edit files, save, word count, regex replace with dry-run, encoding conversion |
|
|
206
|
+
|
|
207
|
+
Extras: light/dark minimal theme toggle, hidden-files toggle, `F5` refresh,
|
|
208
|
+
status bar with live free space, all long jobs run on background threads.
|
|
209
|
+
|
|
210
|
+
## Interactive shell
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
python fileforge.py shell
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
ff:D:\projects> ls
|
|
218
|
+
ff:D:\projects> cd src
|
|
219
|
+
ff:D:\projects\src> find . --ext .py -l
|
|
220
|
+
ff:D:\projects\src> summary .
|
|
221
|
+
ff:D:\projects\src> !dir # run any native shell command
|
|
222
|
+
ff:D:\projects\src> exit
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Builtins: `cd`, `pwd`, `help`, `history`, `clear`, `exit` / `quit`,
|
|
226
|
+
and `!<command>` to pass through to the system shell. **Every CLI command is
|
|
227
|
+
available inside the shell with identical options.**
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Example workflows
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Find Python files changed in the last 3 days and check their hashes
|
|
235
|
+
python fileforge.py find . --ext .py --newer 3d -l
|
|
236
|
+
python fileforge.py hash ./src -a sha256 -r
|
|
237
|
+
|
|
238
|
+
# Reclaim disk space: find duplicates and large files
|
|
239
|
+
python fileforge.py dupes ~/Downloads
|
|
240
|
+
python fileforge.py largest ~/Videos --limit 10
|
|
241
|
+
|
|
242
|
+
# Back up a project as a tar.gz and record a checksum manifest
|
|
243
|
+
python fileforge.py archive-create backup.tar.gz ./project
|
|
244
|
+
python fileforge.py manifest ./project -o ./project/manifest.json
|
|
245
|
+
python fileforge.py verify ./project/manifest.json --extra
|
|
246
|
+
|
|
247
|
+
# Batch-rename screenshots IMG_1234.png -> photo_1234.png
|
|
248
|
+
python fileforge.py rename-batch ~/Pictures/*.png --pattern IMG_ --replacement photo_ --dry-run
|
|
249
|
+
|
|
250
|
+
# Split a large file for transfer, then merge it back
|
|
251
|
+
python fileforge.py split big.iso --size 100M --out-dir ./parts
|
|
252
|
+
python fileforge.py merge big.iso ./parts/*
|
|
253
|
+
|
|
254
|
+
# Mirror a folder, removing files deleted at the source
|
|
255
|
+
python fileforge.py sync ./site ./backup/site --delete
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Design notes
|
|
261
|
+
|
|
262
|
+
* **Pure stdlib** — no `pip install` required; copies of this folder run anywhere.
|
|
263
|
+
* **Safety first** — extraction guards against path traversal; `--dry-run`
|
|
264
|
+
is available for rename, replace and sync.
|
|
265
|
+
* **Structured core** — `fileforge/*.py` modules (`core`, `search`, `hashutil`,
|
|
266
|
+
`archive`, `analytics`, `security`, `utils`) can be imported and reused as a
|
|
267
|
+
library:
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
from fileforge import core, search, hashutil
|
|
271
|
+
|
|
272
|
+
core.write_text("notes.txt", "hello\n")
|
|
273
|
+
print(hashutil.hash_file("notes.txt", "sha256"))
|
|
274
|
+
for e in search.find(search.FindCriteria(root=".", extensions=[".py"])):
|
|
275
|
+
print(e.rel, e.size)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
* **Custom encryption caveat** — `encrypt` / `decrypt` use a self-contained
|
|
279
|
+
PBKDF2 + SHA-256 stream cipher with an HMAC tag. It is dependency-free and
|
|
280
|
+
fine for personal obfuscation, but it is **not audited cryptography**. For
|
|
281
|
+
sensitive data prefer `age`, `gpg` or `openssl`.
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Project layout
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
localfilessystem/
|
|
289
|
+
├── fileforge.py # single-file launcher
|
|
290
|
+
├── README.md
|
|
291
|
+
└── fileforge/
|
|
292
|
+
├── __init__.py
|
|
293
|
+
├── __main__.py # enables `python -m fileforge`
|
|
294
|
+
├── cli.py # argparse dispatcher + all command impls
|
|
295
|
+
├── gui.py # Tkinter graphical interface
|
|
296
|
+
├── repl.py # interactive shell
|
|
297
|
+
├── core.py # file/dir operations, tree, stat, text tools
|
|
298
|
+
├── search.py # find + grep + size/duration parsing
|
|
299
|
+
├── hashutil.py # hashes, manifest, verify, duplicates, compare
|
|
300
|
+
├── archive.py # zip/tar/gzip, split/merge, sync
|
|
301
|
+
├── analytics.py # du, largest/newest, empty, broken links
|
|
302
|
+
├── security.py # chmod, shred, encryption
|
|
303
|
+
└── utils.py # shared helpers, platform detection, output
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
## License
|
|
308
|
+
|
|
309
|
+
MIT
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# fileforge
|
|
2
|
+
|
|
3
|
+
A portable, **dependency-free** local file-system toolkit written in pure Python.
|
|
4
|
+
Runs unchanged on **Linux**, **Windows** and **macOS** — command line, interactive
|
|
5
|
+
shell **and a full graphical interface**.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
_____.__.__ _____
|
|
9
|
+
_|__| | | | ____ / ____/___ ________ ____ ______ ____
|
|
10
|
+
| | | | | _/ __ \ / /_ / __ \/ ___/ _ \/ __ `/ ___/ _ \_/ __ \
|
|
11
|
+
| | |_| |_|\ ___// __/ / /_/ / / / __/ /_/ / / / __/ ___/
|
|
12
|
+
|__|____/____/ \___/ /_/ \____/_/ \___/\__, /_/ \___/\___/
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
* Python **3.8+** (tested on 3.12 / 3.13)
|
|
20
|
+
* No third-party packages — only the standard library
|
|
21
|
+
* The GUI needs `tkinter` (bundled with Windows/macOS Python and
|
|
22
|
+
`python3-tk` on Linux)
|
|
23
|
+
* Works on Linux, Windows 10/11 and macOS
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# from the repository
|
|
29
|
+
python fileforge.py --help # list all commands
|
|
30
|
+
python fileforge.py gui # graphical interface
|
|
31
|
+
python fileforge.py shell # interactive shell
|
|
32
|
+
python -m fileforge ls -l . # run as a module
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Install as a pip package
|
|
36
|
+
|
|
37
|
+
The project ships as a wheel (`dist/fileforge_toolkit-1.0.0-py3-none-any.whl`):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install dist/fileforge_toolkit-1.0.0-py3-none-any.whl
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
After installation two commands are available everywhere:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
fileforge --version # CLI (all 40+ commands)
|
|
47
|
+
fileforge shell # interactive shell
|
|
48
|
+
fileforge-gui # graphical interface (no console window)
|
|
49
|
+
fileforge gui # GUI via the CLI entry point
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To publish to PyPI (once you own the name):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python -m build # rebuild dist/
|
|
56
|
+
twine upload dist/*
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
To build from source: `pip install build && python -m build`.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Command reference
|
|
64
|
+
|
|
65
|
+
### Navigation & listing
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `ls [path] [-l] [-a] [--sort name\|size\|time\|ext]` | List directory contents |
|
|
70
|
+
| `tree [path] [-L depth] [-a] [--no-size]` | ASCII directory tree with sizes |
|
|
71
|
+
| `stat <path> [--json]` | Detailed metadata (mode, times, inode, counts, MIME) |
|
|
72
|
+
| `filetype <path>` | Content-based MIME detection |
|
|
73
|
+
| `free [path]` | Free / used / total space on a volume |
|
|
74
|
+
|
|
75
|
+
### File content
|
|
76
|
+
|
|
77
|
+
| Command | Description |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `cat <path> [-n] [--head N] [--tail N] [--encoding ENC]` | Print a text file |
|
|
80
|
+
| `write <path> (-c TEXT \| -f FILE \| --stdin) [-a] [--newline]` | Write or append |
|
|
81
|
+
| `touch <path>` | Create an empty file / bump mtime |
|
|
82
|
+
| `wc <path>` | Count lines, words, chars, bytes |
|
|
83
|
+
| `replace <path> OLD NEW [--regex] [-i] [--dry-run]` | In-place text replace |
|
|
84
|
+
| `convert-encoding <path> --to ENC [--from ENC] [-o OUT]` | Transcode a text file |
|
|
85
|
+
|
|
86
|
+
### File & directory management
|
|
87
|
+
|
|
88
|
+
| Command | Description |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `cp <src> <dest> [--overwrite] [--no-recursive] [--no-preserve]` | Copy file/dir |
|
|
91
|
+
| `mv <src> <dest> [--overwrite]` | Move or rename |
|
|
92
|
+
| `rm <path> [-r] [-f] [--secure] [--passes N]` | Remove (optionally shred) |
|
|
93
|
+
| `mkdir <path> [--no-parents] [--exist-ok]` | Create directories |
|
|
94
|
+
| `rename <path> <new_name>` | Rename one path |
|
|
95
|
+
| `rename-batch <paths...> --pattern P --replacement R [--regex] [-i] [--dry-run]` | Batch rename |
|
|
96
|
+
| `symlink <target> <link>` / `readlink <path>` | Symbolic links |
|
|
97
|
+
|
|
98
|
+
### Search
|
|
99
|
+
|
|
100
|
+
| Command | Description |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `find [root] [-name GLOB] [--regex RE] [--ext .py] [--min-size 1k] [--max-size 10M] [--newer 7d] [--older 30d] [--content TEXT] [--files-only] [--dirs-only] [--empty] [--depth N] [-a] [-l] [--limit N]` | Multi-criteria search |
|
|
103
|
+
| `grep <pattern> [paths...] [--regex] [-s] [--include GLOB] [--exclude GLOB] [--no-recursive] [--max N]` | Search text inside files |
|
|
104
|
+
|
|
105
|
+
Size accepts `B, K/KB, M/MB, G/GB, T/TB`. Duration accepts `s, m, h, d, w`
|
|
106
|
+
(e.g. `7d`, `12h`, `3d12h`).
|
|
107
|
+
|
|
108
|
+
### Integrity
|
|
109
|
+
|
|
110
|
+
| Command | Description |
|
|
111
|
+
|---|---|
|
|
112
|
+
| `hash <paths...> [-a ALGO] [-r]` | Checksums (md5, sha1/224/256/384/512, blake2b/s) |
|
|
113
|
+
| `manifest <root> [-a ALGO] [-o OUT]` | Create a JSON checksum manifest |
|
|
114
|
+
| `verify <manifest> [--extra]` | Verify files against a manifest |
|
|
115
|
+
| `compare <a> <b> [-a ALGO]` | Compare two files, report first differing byte |
|
|
116
|
+
| `dupes <root> [-a ALGO] [--min-size SIZE] [--hidden]` | Find duplicate files |
|
|
117
|
+
|
|
118
|
+
### Analytics
|
|
119
|
+
|
|
120
|
+
| Command | Description |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `du [root] [--top N] [--no-hidden]` | Disk-usage breakdown by extension / top-level |
|
|
123
|
+
| `largest [root] [--limit N]` | Largest files |
|
|
124
|
+
| `newest [root] [--limit N]` / `oldest [root] [--limit N]` | By modification time |
|
|
125
|
+
| `empty [root]` | Empty files and directories |
|
|
126
|
+
| `broken-links [root]` | Broken symbolic links |
|
|
127
|
+
| `ext-summary [root]` | Per-extension file count and size |
|
|
128
|
+
| `summary [root]` | One-shot full report |
|
|
129
|
+
|
|
130
|
+
### Archives, split & sync
|
|
131
|
+
|
|
132
|
+
| Command | Description |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `archive-create <output> <sources...> [--format zip\|tar] [--base-dir DIR]` | Create zip / tar / tar.gz / tar.bz2 / tar.xz |
|
|
135
|
+
| `archive-extract <archive> [-d DEST] [--member NAME]` | Extract (zip-slip protected) |
|
|
136
|
+
| `archive-list <archive>` | List entries |
|
|
137
|
+
| `gzip <path> [-d] [-k]` | Single-file gzip / gunzip |
|
|
138
|
+
| `split <path> --size 10M [--out-dir D]` | Split a file into parts |
|
|
139
|
+
| `merge <output> <parts...>` | Merge parts back |
|
|
140
|
+
| `sync <src> <dest> [--delete] [--dry-run]` | Incremental directory mirror |
|
|
141
|
+
|
|
142
|
+
### Permissions & security
|
|
143
|
+
|
|
144
|
+
| Command | Description |
|
|
145
|
+
|---|---|
|
|
146
|
+
| `chmod <path> <mode> [-r]` | Octal (`644`) or symbolic (`+x`, `u+rw`, `go-w`) |
|
|
147
|
+
| `perms [path] [-r]` | Show permission strings |
|
|
148
|
+
| `world-writable [root]` | Audit world-writable entries |
|
|
149
|
+
| `shred <path> [--passes N]` | Overwrite then delete a file |
|
|
150
|
+
| `encrypt <path> [-p PWD] [-o OUT] [--remove-source]` | Encrypt to `.ffenc` |
|
|
151
|
+
| `decrypt <path> [-p PWD] [-o OUT] [--remove-source]` | Decrypt `.ffenc` |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Graphical interface
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
python fileforge.py gui # or: fileforge-gui after pip install
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
A single window with a directory tree on the left and eight tool tabs:
|
|
162
|
+
|
|
163
|
+
| Tab | What you can do |
|
|
164
|
+
|---|---|
|
|
165
|
+
| **Browser** | Navigate, sort, copy/move/rename/delete/shred, properties, hash, archive, encrypt, open terminal or file manager, context menu |
|
|
166
|
+
| **Search** | All find criteria (glob, regex, ext, size, age, content, empty, depth) with a results table and right-click actions |
|
|
167
|
+
| **Grep** | Recursive text search with include/exclude filters; double-click jumps to the line in the built-in viewer |
|
|
168
|
+
| **Integrity** | Hash any file, compare two files, create/verify manifests, find duplicates and delete the extra copies |
|
|
169
|
+
| **Archive** | Create/extract/inspect zip & tar archives, gzip, split files into parts, merge parts back, incremental folder sync |
|
|
170
|
+
| **Analytics** | Summary report, extension breakdown with a bar chart, largest/newest/oldest files, empty items, broken links |
|
|
171
|
+
| **Security** | Encrypt/decrypt with password, shred, chmod (octal + symbolic), permission listing, world-writable audit |
|
|
172
|
+
| **Text Tools** | View and edit files, save, word count, regex replace with dry-run, encoding conversion |
|
|
173
|
+
|
|
174
|
+
Extras: light/dark minimal theme toggle, hidden-files toggle, `F5` refresh,
|
|
175
|
+
status bar with live free space, all long jobs run on background threads.
|
|
176
|
+
|
|
177
|
+
## Interactive shell
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
python fileforge.py shell
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
ff:D:\projects> ls
|
|
185
|
+
ff:D:\projects> cd src
|
|
186
|
+
ff:D:\projects\src> find . --ext .py -l
|
|
187
|
+
ff:D:\projects\src> summary .
|
|
188
|
+
ff:D:\projects\src> !dir # run any native shell command
|
|
189
|
+
ff:D:\projects\src> exit
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Builtins: `cd`, `pwd`, `help`, `history`, `clear`, `exit` / `quit`,
|
|
193
|
+
and `!<command>` to pass through to the system shell. **Every CLI command is
|
|
194
|
+
available inside the shell with identical options.**
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Example workflows
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Find Python files changed in the last 3 days and check their hashes
|
|
202
|
+
python fileforge.py find . --ext .py --newer 3d -l
|
|
203
|
+
python fileforge.py hash ./src -a sha256 -r
|
|
204
|
+
|
|
205
|
+
# Reclaim disk space: find duplicates and large files
|
|
206
|
+
python fileforge.py dupes ~/Downloads
|
|
207
|
+
python fileforge.py largest ~/Videos --limit 10
|
|
208
|
+
|
|
209
|
+
# Back up a project as a tar.gz and record a checksum manifest
|
|
210
|
+
python fileforge.py archive-create backup.tar.gz ./project
|
|
211
|
+
python fileforge.py manifest ./project -o ./project/manifest.json
|
|
212
|
+
python fileforge.py verify ./project/manifest.json --extra
|
|
213
|
+
|
|
214
|
+
# Batch-rename screenshots IMG_1234.png -> photo_1234.png
|
|
215
|
+
python fileforge.py rename-batch ~/Pictures/*.png --pattern IMG_ --replacement photo_ --dry-run
|
|
216
|
+
|
|
217
|
+
# Split a large file for transfer, then merge it back
|
|
218
|
+
python fileforge.py split big.iso --size 100M --out-dir ./parts
|
|
219
|
+
python fileforge.py merge big.iso ./parts/*
|
|
220
|
+
|
|
221
|
+
# Mirror a folder, removing files deleted at the source
|
|
222
|
+
python fileforge.py sync ./site ./backup/site --delete
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Design notes
|
|
228
|
+
|
|
229
|
+
* **Pure stdlib** — no `pip install` required; copies of this folder run anywhere.
|
|
230
|
+
* **Safety first** — extraction guards against path traversal; `--dry-run`
|
|
231
|
+
is available for rename, replace and sync.
|
|
232
|
+
* **Structured core** — `fileforge/*.py` modules (`core`, `search`, `hashutil`,
|
|
233
|
+
`archive`, `analytics`, `security`, `utils`) can be imported and reused as a
|
|
234
|
+
library:
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from fileforge import core, search, hashutil
|
|
238
|
+
|
|
239
|
+
core.write_text("notes.txt", "hello\n")
|
|
240
|
+
print(hashutil.hash_file("notes.txt", "sha256"))
|
|
241
|
+
for e in search.find(search.FindCriteria(root=".", extensions=[".py"])):
|
|
242
|
+
print(e.rel, e.size)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
* **Custom encryption caveat** — `encrypt` / `decrypt` use a self-contained
|
|
246
|
+
PBKDF2 + SHA-256 stream cipher with an HMAC tag. It is dependency-free and
|
|
247
|
+
fine for personal obfuscation, but it is **not audited cryptography**. For
|
|
248
|
+
sensitive data prefer `age`, `gpg` or `openssl`.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Project layout
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
localfilessystem/
|
|
256
|
+
├── fileforge.py # single-file launcher
|
|
257
|
+
├── README.md
|
|
258
|
+
└── fileforge/
|
|
259
|
+
├── __init__.py
|
|
260
|
+
├── __main__.py # enables `python -m fileforge`
|
|
261
|
+
├── cli.py # argparse dispatcher + all command impls
|
|
262
|
+
├── gui.py # Tkinter graphical interface
|
|
263
|
+
├── repl.py # interactive shell
|
|
264
|
+
├── core.py # file/dir operations, tree, stat, text tools
|
|
265
|
+
├── search.py # find + grep + size/duration parsing
|
|
266
|
+
├── hashutil.py # hashes, manifest, verify, duplicates, compare
|
|
267
|
+
├── archive.py # zip/tar/gzip, split/merge, sync
|
|
268
|
+
├── analytics.py # du, largest/newest, empty, broken links
|
|
269
|
+
├── security.py # chmod, shred, encryption
|
|
270
|
+
└── utils.py # shared helpers, platform detection, output
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
MIT
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
fileforge
|
|
3
|
+
=========
|
|
4
|
+
|
|
5
|
+
A portable, dependency-free local file-system toolkit for Linux, Windows
|
|
6
|
+
and macOS. It bundles file / directory management, search, integrity
|
|
7
|
+
checking, archives, permissions, security helpers and tree analytics
|
|
8
|
+
behind a single command line (and an interactive shell).
|
|
9
|
+
|
|
10
|
+
Quick start
|
|
11
|
+
-----------
|
|
12
|
+
python fileforge.py --help
|
|
13
|
+
python fileforge.py ls -l .
|
|
14
|
+
python fileforge.py find . --ext .py --newer 7d
|
|
15
|
+
python fileforge.py summary .
|
|
16
|
+
python fileforge.py shell
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from .utils import FileForgeError
|
|
22
|
+
|
|
23
|
+
__version__ = "1.0.0"
|
|
24
|
+
__all__ = ["FileForgeError", "__version__"]
|