Metadata-Version: 2.4
Name: pheser
Version: 1.0.0
Summary: Photo Metadata Privacy Toolkit -- scan, clean, redact, and export EXIF data
Author-email: AzzTE <azztecheco@gmail.com>
Maintainer-email: AzzTE <azztecheco@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/azztche/pheser
Project-URL: Repository, https://github.com/azztche/pheser
Project-URL: Bug Tracker, https://github.com/azztche/pheser/issues
Keywords: exif,metadata,privacy,photo,image,gps,strip,clean,redact,piexif,ate,azzte
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Security
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: Pillow>=10.0
Requires-Dist: piexif>=1.1.3
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"

# Pheser

**Photo Metadata Privacy Toolkit** -- scan, clean, redact, compare, and export EXIF metadata from images.

```
pip install pheser
```

---

## Features

| Feature | Description |
|---|---|
| **Scan** | Full EXIF dump with privacy risk score (0-100) and Google Maps link for GPS |
| **Clean** | Remove GPS only, all EXIF, specific tags, or keep-only-safe-tags mode |
| **Remake** | Recreate metadata with custom Make/Model/DateTime/GPS values |
| **Redact** | Spoof GPS coordinates, randomize timestamps, replace device info |
| **Compare** | Diff EXIF between two images (before/after verification) |
| **Batch** | Process entire directories recursively with any operation |
| **Export** | Save scan results as JSON, CSV, or plain-text report |

Orientation and display geometry tags are always preserved -- your image will never be rotated by Pheser.

---

## Installation

```bash
pip install pheser
```

**Requirements:** Python 3.11+, Pillow >= 10.0, piexif >= 1.1.3

---

## CLI

### Scan
```bash
pheser scan photo.jpg
pheser scan photo.jpg --export report.json --fmt json
pheser scan photo.jpg --export report.csv  --fmt csv
pheser scan photo.jpg --no-hash --no-risk
```

### Clean
```bash
# Remove GPS only (default)
pheser clean photo.jpg

# Strip ALL EXIF
pheser clean photo.jpg --mode all

# Remove specific tags
pheser clean photo.jpg --mode tags --tags Make Model Software

# Keep only safe tags (removes GPS + device serials + owner info)
pheser clean photo.jpg --mode keep_basic -o safe_photo.jpg
```

### Remake
```bash
pheser remake photo.jpg --make Sony --model "Alpha 7" --artist "Jane Doe"
pheser remake photo.jpg --inject-gps 48.8584 2.2945
```

### Redact (Spoof)
```bash
# Replace GPS with random coordinates
pheser redact photo.jpg --random-gps

# Spoof exact location
pheser redact photo.jpg --spoof-gps 51.5074 -0.1278

# Randomize everything
pheser redact photo.jpg --random-gps --random-datetime --spoof-device Apple "iPhone 15"
```

### Compare
```bash
pheser compare original.jpg cleaned.jpg
```

### Batch
```bash
pheser batch ./photos --op clean-gps --out-dir ./photos_clean
pheser batch ./photos --op redact-random --recursive
pheser batch ./photos --op clean-all --dry-run
```

---

## Python API

```python
from pheser import scan, clean, redact, remake, batch_process
from pheser.compare import compare
from pheser.exporter import export_report

# Scan
results = scan("photo.jpg", raw=True)
print(results["risk_score"])   # 0-100
print(results["gps"])          # {"latitude": ..., "maps_url": ...}

# Clean GPS
clean("photo.jpg", mode="gps")

# Strip all EXIF
clean("photo.jpg", mode="all", output_file="stripped.jpg")

# Remove specific tags
clean("photo.jpg", mode="tags", remove_tags=["Make", "Model", "Software"])

# Keep only safe metadata
clean("photo.jpg", mode="keep_basic")

# Spoof GPS + randomize datetime
redact("photo.jpg", randomize_gps=True, randomize_datetime=True)

# Inject fake GPS
redact("photo.jpg", spoof_gps=(35.6762, 139.6503))  # Tokyo

# Recreate with custom values
remake("photo.jpg", make="Fujifilm", model="X100V", artist="John")

# Compare two files
diff = compare("before.jpg", "after.jpg")

# Export scan report
results = scan("photo.jpg", raw=True)
export_report(results, "report.json", fmt="json")
export_report(results, "report.csv",  fmt="csv")
export_report(results, "report.txt",  fmt="txt")

# Batch process a folder
batch_process(
    "photos/",
    lambda src, dst: clean(src, dst, mode="gps", verbose=False),
    out_dir="photos_clean/",
    recursive=True,
)
```

---

## Privacy Risk Score

| Score | Label | Meaning |
|---|---|---|
| 0 | Safe | No sensitive metadata |
| 1-19 | Low | Minor device info only |
| 20-49 | Medium | Device + timestamps present |
| 50-100 | High | GPS location data found |

---

## Supported Formats

`.jpg` / `.jpeg` -- `.tiff` / `.tif` -- `.webp`

---

## License

MIT -- Copyright (c) 2025 AzzTE
