Recursive file scanner with metadata, tagging, and duplicate detection
Project description
ValScanner
A recursive file scanner with rich metadata extraction, full-text search, tagging, thumbnail generation, and duplicate/similar-folder detection — available as both a CLI tool and a PySide6 GUI.
Features
- Recursive scan — indexes every file under a root directory into SQLite
- Rich metadata — image EXIF, audio tags, PDF page count (optional deps)
- Thumbnails — JPEG blobs stored in the database; displayed in the GUI grid view
- Tagging — rule-based tags derived from path, filename, size, and extension
- Full-text search — FTS5 virtual table over filenames and paths
- Similar-folder detection — pairwise comparison using filename Jaccard + extension cosine + size ratio + SHA-256 Jaccard
- Export — CSV and JSON export from the CLI
- Multiple scan sessions — each scan stored with a label; list or delete past scans
Requirements
| Requirement | Version |
|---|---|
| Python | 3.8+ |
| PySide6 | any recent release |
| Pillow (optional) | image EXIF + thumbnails |
| mutagen (optional) | audio metadata |
| PyPDF2 (optional) | PDF page count |
Installation
macOS / Linux
# Clone the repo
git clone <repo-url> myscanner
cd myscanner
# Run the installer (creates .venv, installs all deps, links launchers)
bash install.sh
# Or skip optional rich-metadata deps
bash install.sh --no-rich
# Or install into your active Python environment (no venv)
bash install.sh --no-venv
# Or specify where launcher scripts go
bash install.sh --prefix ~/.local
The installer places valscanner and valscanner-gui symlinks in ~/.local/bin (Linux) or /usr/local/bin (macOS, if writable).
Windows (PowerShell)
# Clone the repo
git clone <repo-url> myscanner
cd myscanner
# Run the installer (creates .venv, installs all deps, writes .cmd launchers)
.\install.ps1
# Skip optional rich-metadata deps
.\install.ps1 -NoRich
# Install into your active Python environment (no venv)
.\install.ps1 -NoVenv
# Specify launcher directory
.\install.ps1 -Prefix "C:\Tools\ValScanner"
Launchers are written as .cmd files to %LOCALAPPDATA%\Programs\ValScanner\bin by default. The script offers to add that directory to your user PATH.
Manual (pip)
# Minimal — GUI only, no image/audio/PDF metadata
pip install -e .
# Full — all optional metadata extractors
pip install -e ".[rich]"
Usage
GUI
valscanner-gui
# or
python -m valscanner.gui.window
CLI
# Scan a directory
valscanner /path/to/scan
# With options
valscanner /path/to/scan --db my.db --no-hash --export-csv --export-json --verbose
# List past scans
valscanner --list-scans --db my.db
# Delete a scan by ID
valscanner --delete-scan 3 --db my.db
Full flag reference:
| Flag | Default | Description |
|---|---|---|
--db PATH |
scanner.db |
SQLite database file |
--no-hash |
off | Skip SHA-256 (faster) |
--export-csv |
off | Write <label>.csv after scan |
--export-json |
off | Write <label>.json after scan |
--verbose / -v |
off | Per-file progress |
--list-scans |
— | Print all stored scans and exit |
--delete-scan ID |
— | Delete scan by ID and exit |
Project layout
myscanner/
├── pyproject.toml ← packaging & entry points
├── install.sh ← macOS/Linux installer
├── install.ps1 ← Windows PowerShell installer
├── file_scanner.py ← backward-compat shim
├── file_scanner_gui.py ← backward-compat shim
│
└── valscanner/
├── cli.py ← CLI entry point
├── core/ ← zero Qt dependencies
│ ├── schema.py
│ ├── categories.py
│ ├── metadata.py
│ ├── tagging.py
│ ├── scanner.py
│ ├── similarity.py
│ ├── export.py
│ └── db.py
└── gui/ ← PySide6 front-end
├── constants.py
├── workers.py
├── models.py
├── delegates.py
├── dialogs.py
├── window.py
└── panels/
├── detail.py
├── folders.py
├── similar.py
├── scans.py
└── console.py
Database schema
Every .db file contains five tables:
| Table | Contents |
|---|---|
scans |
One row per scan session (label, root, file count, total size) |
files |
One row per file; extra_meta is a JSON blob of rich metadata |
folders |
Cumulative byte/file counts for every ancestor directory |
thumbnails |
JPEG blobs keyed by file_id |
media_samples |
Low-quality audio/video clips keyed by file_id |
files_fts |
FTS5 virtual table over files; populated by triggers |
Development
# Editable install with all extras
pip install -e ".[rich]"
# Run directly without installing
python -m valscanner.gui.window # GUI
python -m valscanner.cli # CLI (add args after --)
Output files (*.db, *.csv, *.json) are gitignored.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file valscanner-0.1.0.tar.gz.
File metadata
- Download URL: valscanner-0.1.0.tar.gz
- Upload date:
- Size: 57.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d37a79aa6b1e1b10503a8fe1ba75a8b606bfb84978f7ede246e45fdf67dfd69a
|
|
| MD5 |
28489aa0120be56e01b215e05976047d
|
|
| BLAKE2b-256 |
40d3da33506399453e9a730ed6c9a5b8faec7f45f07beff0e63d34458a57ead5
|
File details
Details for the file valscanner-0.1.0-py3-none-any.whl.
File metadata
- Download URL: valscanner-0.1.0-py3-none-any.whl
- Upload date:
- Size: 66.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd9cb78abfc02330af77d44ba9ad0191ba095cf3d45f56f61f5f7e2f76d9aa9a
|
|
| MD5 |
68e8a99ba2b866ebf256000dee4d2882
|
|
| BLAKE2b-256 |
3e89991aee2c6b451c21a1980c3a3358464bfc32d51b7e5c27e0e65255f18810
|