Skip to main content

fileforge

A portable, dependency-free local file-system toolkit written in pure Python. Runs unchanged on Linux, Windows and macOS — command line, interactive shell and a full graphical interface.

 _____.__.__             _____
_|__|  |  |  |   ____   / ____/___  ________  ____ ______   ____
|  |  |  |  | _/ __ \ / /_  / __ \/ ___/ _ \/ __ `/ ___/ _ \_/ __ \
|  |  |_|  |_|\  ___// __/ / /_/ / /  /  __/ /_/ / /  /  __/  ___/
|__|____/____/ \___/ /_/    \____/_/   \___/\__, /_/   \___/\___/

Requirements

  • Python 3.8+ (tested on 3.12 / 3.13)
  • No third-party packages — only the standard library
  • The GUI needs tkinter (bundled with Windows/macOS Python and python3-tk on Linux)
  • Works on Linux, Windows 10/11 and macOS

Quick start

# from the repository
python fileforge.py --help                 # list all commands
python fileforge.py gui                    # graphical interface (8 tabs)
python fileforge.py shell                  # interactive shell
python -m fileforge ls -l .                # run as a module

# see your whole computer immediately
python fileforge.py computerui             # "This PC" window: every drive, all files
python fileforge.py computer -L 2          # the same as a text tree
python fileforge.py tree . -L 3 --du       # live directory tree, no cache
python fileforge.py drives                 # volumes + free space
python fileforge.py treemap . --top 25     # terminal disk-usage chart

Install as a pip package

The project ships as a wheel (dist/locals_filesystem-2.1.0-py3-none-any.whl, published on PyPI as locals-filesystem):

pip install locals-filesystem                              # from PyPI
pip install dist/locals_filesystem-2.1.0-py3-none-any.whl  # from this folder

After installation the fileforge command is available everywhere and accepts every command in this README:

fileforge --version        # 2.1.0
fileforge help             # full command list
fileforge computerui       # "This PC" window - all drives, all files
fileforge computer -L 2    # the same machine as a text tree
fileforge tree . -L 3 --du # live directory tree, no cache
fileforge shell            # interactive shell
fileforge gui              # full GUI (8 tabs)
fileforge-gui              # GUI without a console window

Aliases and typos are understood, so all of these open the same window:

fileforge computerui   fileforge pcgui   fileforge thispcui
fileforge computrui     # <- typo, auto-corrected

To publish a new version:

python -m build            # rebuild dist/
twine upload dist/*

To build from source: pip install build && python -m build.

Every entry point understands every command

fileforge.dispatch is the single registry that knows all 57 commands (classic CLI + live tree + This PC). It is wired into all entry points, so they behave identically:

Entry point Routes through
fileforge <cmd> (console script) fileforge.dispatch:main
python -m fileforge <cmd> fileforge/__main__.py → dispatch
python fileforge.py <cmd> the launcher's own copy of the registry
fileforge.cli:main (old entry point) re-exported to dispatch

Rebuild the wheel whenever you want the installed command to pick up the newest modules (treeview, treeui, treemap, computer, computerview, dispatch) — the dist/ artifacts are a snapshot, not a live copy.

If pip install fails while replacing Scripts\fileforge.exe (some sandboxes intercept pip's rename-to-.deleteme write), regenerate the launcher with the bundled helper instead:

python make_launchers.py                      # current environment
python make_launchers.py <path-to-Scripts>    # another environment

Command reference

Navigation & listing

Command Description
ls [path] [-l] [-a] [--sort name|size|time|ext] List directory contents
tree [path] [-L depth] [-a] [--no-size] ASCII directory tree with sizes
stat <path> [--json] Detailed metadata (mode, times, inode, counts, MIME)
filetype <path> Content-based MIME detection
free [path] Free / used / total space on a volume

Live file tree (no cache)

Command Description
tree [path] [-L N] [-a] [-d] [-f] [--du] [--stats] [--ext .py] [--include G] [--exclude G] [--min-size 10M] [--max-size 1G] [--newer 7d] [--older 30d] [--sort name|size|mtime|none] [--reverse] [-n N] [--time] [--ascii] [--no-color] [--json F] [--out F] [--top-dirs N] [--max-children N] Stream a live tree straight from disk
treeui [path] [-L N] Tkinter live tree explorer for one directory
treemap [path] [-L N] [--top N] [--mode blocks|bars|both] [--width N] Terminal block map + ranked bar chart of disk usage
drives / roots Every mount point / drive with free space

Whole computer ("This PC")

Command Description
computer [-L N] [--volumes] [--files] [--full-path] [-n N] [--stats] [--max-children N] The entire machine as one tree, or a flat file list
computerui [-L N] Window that opens straight onto every drive
pc / thispc / pcgui Aliases for the two commands above

File content

Command Description
cat <path> [-n] [--head N] [--tail N] [--encoding ENC] Print a text file
write <path> (-c TEXT | -f FILE | --stdin) [-a] [--newline] Write or append
touch <path> Create an empty file / bump mtime
wc <path> Count lines, words, chars, bytes
replace <path> OLD NEW [--regex] [-i] [--dry-run] In-place text replace
convert-encoding <path> --to ENC [--from ENC] [-o OUT] Transcode a text file

File & directory management

Command Description
cp <src> <dest> [--overwrite] [--no-recursive] [--no-preserve] Copy file/dir
mv <src> <dest> [--overwrite] Move or rename
rm <path> [-r] [-f] [--secure] [--passes N] Remove (optionally shred)
mkdir <path> [--no-parents] [--exist-ok] Create directories
rename <path> <new_name> Rename one path
rename-batch <paths...> --pattern P --replacement R [--regex] [-i] [--dry-run] Batch rename
symlink <target> <link> / readlink <path> Symbolic links
Command Description
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
grep <pattern> [paths...] [--regex] [-s] [--include GLOB] [--exclude GLOB] [--no-recursive] [--max N] Search text inside files

Size accepts B, K/KB, M/MB, G/GB, T/TB. Duration accepts s, m, h, d, w (e.g. 7d, 12h, 3d12h).

Integrity

Command Description
hash <paths...> [-a ALGO] [-r] Checksums (md5, sha1/224/256/384/512, blake2b/s)
manifest <root> [-a ALGO] [-o OUT] Create a JSON checksum manifest
verify <manifest> [--extra] Verify files against a manifest
compare <a> <b> [-a ALGO] Compare two files, report first differing byte
dupes <root> [-a ALGO] [--min-size SIZE] [--hidden] Find duplicate files

Analytics

Command Description
du [root] [--top N] [--no-hidden] Disk-usage breakdown by extension / top-level
largest [root] [--limit N] Largest files
newest [root] [--limit N] / oldest [root] [--limit N] By modification time
empty [root] Empty files and directories
broken-links [root] Broken symbolic links
ext-summary [root] Per-extension file count and size
summary [root] One-shot full report

Archives, split & sync

Command Description
archive-create <output> <sources...> [--format zip|tar] [--base-dir DIR] Create zip / tar / tar.gz / tar.bz2 / tar.xz
archive-extract <archive> [-d DEST] [--member NAME] Extract (zip-slip protected)
archive-list <archive> List entries
gzip <path> [-d] [-k] Single-file gzip / gunzip
split <path> --size 10M [--out-dir D] Split a file into parts
merge <output> <parts...> Merge parts back
sync <src> <dest> [--delete] [--dry-run] Incremental directory mirror

Permissions & security

Command Description
chmod <path> <mode> [-r] Octal (644) or symbolic (+x, u+rw, go-w)
perms [path] [-r] Show permission strings
world-writable [root] Audit world-writable entries
shred <path> [--passes N] Overwrite then delete a file
encrypt <path> [-p PWD] [-o OUT] [--remove-source] Encrypt to .ffenc
decrypt <path> [-p PWD] [-o OUT] [--remove-source] Decrypt .ffenc

Live file tree & "This PC"

Everything in this section is read straight from the disk on every run. There is no cache, no index file, no background crawler: what you see is the volume as it is right now.

tree — one directory, streamed

python fileforge.py tree                    # current directory, 3 levels
python fileforge.py tree C:\ -L 2           # drive structure
python fileforge.py tree . --du --stats     # aggregated folder sizes + totals
python fileforge.py tree ~/src --ext .py --sort size --stats
python fileforge.py tree . -L 4 --json tree.json
python fileforge.py tree C:\ -L 2 --ascii --out C:\Temp\ctree.txt
python fileforge.py tree . -L 3 --top-dirs 10

iter_tree() is a generator: it emits each line the moment it is read, so memory stays proportional to the tree depth, not its size. Only --du, --json and treemap materialise the subtree (aggregation needs it).

treemap — disk usage in the terminal

python fileforge.py treemap . -L 3 --top 15 --mode both

Renders a proportional block map of the top level plus a ranked bar chart of the largest directories.

computerui — the whole machine, visible at once

python fileforge.py computerui          # opens on every drive
python fileforge.py computerui -L 3
Tab What it shows
This PC (tree) Root is the computer itself; every volume is a child and is expanded automatically in a background thread, rows appearing as they are read
All files Flat table of every file on every volume — full path, size, type, modified — streamed live, cancellable with Stop

Toolbar: Depth (auto-expand levels), Max/folder, Hidden, Dirs only, Filter, Expand tree, Scan files, Stop, Export. Right-click on either tab: open, reveal in file manager, terminal here, copy path/name, properties, SHA-256. F5 refreshes, Ctrl+Q quits.

This PC
├── C:\                     free 82.37 GB of 392.13 GB
│   ├── AMD\
│   ├── cos_build\
│   │   ├── string.c
│   │   ├── test.c
│   │   └── test.o
│   └── cygwin64\
├── D:\                     free 1.21 TB of 1.82 TB
└── E:\                     free 74.70 GB of 83.70 GB

Why Max/folder matters

A single folder can hold hundreds of thousands of entries. On the machine this was developed on, D:\documents contains 303,676 entries and needs 185 s merely to enumerate — one folder would stall the entire view. Max/folder (default 500 in the window) reads only the first N entries of each folder and shows a + N more entries (not listed) marker. Set it to 0 for unlimited, or raise it when you really need everything.

With the cap in place a whole-machine depth-2 scan finishes in 3 seconds:

WHOLE MACHINE depth=2: 8258 entries, 2674 dirs, 5585 files  3.0s

Symlinks, junctions and Windows reparse points are skipped by default — os.scandir resolves their target, and if that target is an offline network share the call blocks for minutes. The check is done before the directory is opened. Use --follow-links (or the option flag) only when you know the tree. Unreadable folders are reported inline instead of aborting the scan.

Library use

from fileforge.treeview import Options, iter_tree, build_tree, dir_sizes, to_json

for prefix, node, stats in iter_tree("D:/", Options(max_depth=2)):
    print(prefix + node.name)
print(stats.as_dict())

tree = build_tree("D:/Projects", Options(max_depth=4))
print(tree.node.agg_size, tree.node.n_files)

from fileforge.computer import iter_computer_tree, iter_all_files, volumes
for prefix, node, stats in iter_computer_tree(Options(max_depth=2, max_children=500)):
    print(prefix + node.name)
for node in iter_all_files(Options(max_depth=3), max_items=1000):
    print(node.path)

Graphical interface

python fileforge.py gui      # or: fileforge-gui after pip install

A single window with a directory tree on the left and eight tool tabs:

Tab What you can do
Browser Navigate, sort, copy/move/rename/delete/shred, properties, hash, archive, encrypt, open terminal or file manager, context menu
Search All find criteria (glob, regex, ext, size, age, content, empty, depth) with a results table and right-click actions
Grep Recursive text search with include/exclude filters; double-click jumps to the line in the built-in viewer
Integrity Hash any file, compare two files, create/verify manifests, find duplicates and delete the extra copies
Archive Create/extract/inspect zip & tar archives, gzip, split files into parts, merge parts back, incremental folder sync
Analytics Summary report, extension breakdown with a bar chart, largest/newest/oldest files, empty items, broken links
Security Encrypt/decrypt with password, shred, chmod (octal + symbolic), permission listing, world-writable audit
Text Tools View and edit files, save, word count, regex replace with dry-run, encoding conversion

Extras: light/dark minimal theme toggle, hidden-files toggle, F5 refresh, status bar with live free space, all long jobs run on background threads.

The two tree windows

Besides the 8-tab interface above there are two dedicated viewers:

python fileforge.py treeui D:\ -L 4   # single-directory live tree
python fileforge.py computerui        # the whole computer ("This PC")
python fileforge.py treeui            # no path -> opens "This PC"

Both expand lazily (only the branch you open is ever read), offer sortable columns, a live filter, an export to .txt/.json, a light/dark theme and the same right-click actions as the main interface. computerui adds the whole-machine auto-expansion and the streaming "All files" table described above.

Interactive shell

python fileforge.py shell
ff:D:\projects> ls
ff:D:\projects> cd src
ff:D:\projects\src> find . --ext .py -l
ff:D:\projects\src> summary .
ff:D:\projects\src> !dir                 # run any native shell command
ff:D:\projects\src> exit

Builtins: cd, pwd, help, history, clear, exit / quit, and !<command> to pass through to the system shell. Every CLI command is available inside the shell with identical options.


Example workflows

# Find Python files changed in the last 3 days and check their hashes
python fileforge.py find . --ext .py --newer 3d -l
python fileforge.py hash ./src -a sha256 -r

# Reclaim disk space: find duplicates and large files
python fileforge.py dupes ~/Downloads
python fileforge.py largest ~/Videos --limit 10

# Back up a project as a tar.gz and record a checksum manifest
python fileforge.py archive-create backup.tar.gz ./project
python fileforge.py manifest ./project -o ./project/manifest.json
python fileforge.py verify ./project/manifest.json --extra

# Batch-rename screenshots IMG_1234.png -> photo_1234.png
python fileforge.py rename-batch ~/Pictures/*.png --pattern IMG_ --replacement photo_ --dry-run

# Split a large file for transfer, then merge it back
python fileforge.py split big.iso --size 100M --out-dir ./parts
python fileforge.py merge big.iso ./parts/*

# Mirror a folder, removing files deleted at the source
python fileforge.py sync ./site ./backup/site --delete

# Explore an unfamiliar machine: every drive, two levels deep
python fileforge.py computer -L 2 --stats
python fileforge.py computerui

# Where is my disk space going?
python fileforge.py treemap . -L 3 --top 20 --mode bars
python fileforge.py tree ~/Downloads -L 2 --du --sort size

# Every log file on the machine, newest first
python fileforge.py computer --files --limit 2000 --full-path

Design notes

  • Pure stdlib — no pip install required; copies of this folder run anywhere.
  • Safety first — extraction guards against path traversal; --dry-run is available for rename, replace and sync.
  • Structured core — src/fileforge/*.py modules (core, search, hashutil, archive, analytics, security, utils, treeview, treeui, treemap, computer, computerview) can be imported and reused as a library:
from fileforge import core, search, hashutil

core.write_text("notes.txt", "hello\n")
print(hashutil.hash_file("notes.txt", "sha256"))
for e in search.find(search.FindCriteria(root=".", extensions=[".py"])):
    print(e.rel, e.size)
  • Never hangs on a bad link — the tree scanners detect symlinks, junctions and Windows reparse points before opening a directory, because os.scandir resolves their target and an offline network share would block for minutes. Huge folders are bounded by max_children (500 per folder in the GUI), and unreadable folders are reported inline instead of aborting the scan.
  • Custom encryption caveat — encrypt / decrypt use a self-contained PBKDF2 + SHA-256 stream cipher with an HMAC tag. It is dependency-free and fine for personal obfuscation, but it is not audited cryptography. For sensitive data prefer age, gpg or openssl.

Project layout

localfilessystem/
├── fileforge.py            # single-file launcher - full command registry
├── pyproject.toml          # pip package definition (locals-filesystem 2.1.0)
├── README.md
├── dist/                   # built wheel + sdist (pip installable)
└── src/
    └── fileforge/
        ├── __init__.py
        ├── __main__.py         # `python -m fileforge` -> dispatch
        ├── dispatch.py         # unified registry: every command, aliases,
        │                       # typo correction.  Console-script entry point
        ├── cli.py              # classic argparse CLI; `main` -> dispatch,
        │                       # original kept as `main_classic`
        ├── gui.py              # Tkinter graphical interface (8 tabs)
        ├── repl.py             # interactive shell
        ├── core.py             # file/dir operations, tree, stat, text tools
        ├── search.py           # find + grep + size/duration parsing
        ├── hashutil.py         # hashes, manifest, verify, duplicates, compare
        ├── archive.py          # zip/tar/gzip, split/merge, sync
        ├── analytics.py        # du, largest/newest, empty, broken links
        ├── security.py         # chmod, shred, encryption
        ├── utils.py            # shared helpers, platform detection, output
        ├── treeview.py         # live cache-free tree scanner + renderer
        ├── treeui.py           # single-directory Tkinter tree explorer
        ├── treemap.py          # terminal block map / bar chart
        ├── computer.py         # whole-machine ("This PC") scanning engine
        └── computerview.py     # whole-machine Tkinter explorer (2 tabs)

Testing

python tree_smoke.py        # live tree:    TOTAL 54 passed, 0 failed
python computer_smoke.py    # This PC:      TOTAL 33 passed, 0 failed
python dispatch_smoke.py    # dispatcher:   TOTAL 25 passed, 0 failed

dispatch_smoke.py checks that every catalogue entry is reachable, that all aliases resolve, that computrui auto-corrects to computerui, that an unknown command exits with code 2, and that the launcher's registry and the package's registry are identical.

Both suites drive the real CLI as a subprocess, call the library API directly and construct the Tkinter windows for real (without a blocking main loop). They need tkinter for the GUI section, which is skipped automatically when it is missing:

# Linux
sudo apt install python3-tk

The original CLI/GUI suites (smoke_test.py, gui_smoke.py) were written against the pre-src layout and are no longer part of the tree; the CLI and GUI themselves are covered by the two suites above plus python fileforge.py --help.

License

MIT

Metadata

Release files for locals-filesystem 3.0.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 locals-filesystem 3.0.0
File Size Uploaded
locals_filesystem-3.0.0.tar.gz 61.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for locals-filesystem 3.0.0
File Interpreter ABI Platform
locals_filesystem-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 119.1 kB

Release files / locals_filesystem-3.0.0.tar.gz

Download URL locals_filesystem-3.0.0.tar.gz
Size 61.3 kB
Tags Source
SHA-256 checksum
How to use checksums
907470ada734b87193011401deee39471d984e6c895ad040ae18e2bfadb8ff5c
BLAKE2b-256 checksum
How to use checksums
732746502c62d182643cf956655cc73a94f9c29af3ef84d1420624772f734fc3
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 9, 2026.

Transparency log

Release files / locals_filesystem-3.0.0-py3-none-any.whl

Download URL locals_filesystem-3.0.0-py3-none-any.whl
Size 57.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5ccaa0d349f3f3604cd9eb7efdd8f3696c43a4c814d5c5a8bd1442d9d1d59e51
BLAKE2b-256 checksum
How to use checksums
1ebd293ec77444e240dff0b0f20cb688b51013d74ff1bf15393d615a6dcb639e
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 9, 2026.

Transparency log

Release history Release notifications | RSS feed

6.0.0

2 release files

5.0.0

2 release files

4.0.0

1 release file

This release

3.0.0 This release

2 release files

2.0.0

2 release files

1.0.0

2 release files

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