Metadata-Version: 2.1
Name: valscanner
Version: 0.1.0
Summary: Recursive file scanner with metadata, tagging, and duplicate detection
Author-email: Abdalrahman Valabji <valabji@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Abdalrahman Valabji
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Keywords: scanner,files,metadata,duplicates,sqlite,gui
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Utilities
Classifier: Topic :: System :: Filesystems
Classifier: Environment :: X11 Applications :: Qt
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PySide6
Provides-Extra: rich
Requires-Dist: Pillow; extra == "rich"
Requires-Dist: mutagen; extra == "rich"
Requires-Dist: PyPDF2; extra == "rich"

# 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

```bash
# 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)

```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)

```bash
# Minimal — GUI only, no image/audio/PDF metadata
pip install -e .

# Full — all optional metadata extractors
pip install -e ".[rich]"
```

---

## Usage

### GUI

```bash
valscanner-gui
# or
python -m valscanner.gui.window
```

### CLI

```bash
# 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

```bash
# 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
