# ━━━━━ MEDIA ━━━━━

Foundation-level media library management — permissions, junk removal, and play state
sync. These three scripts run before and independently of arr stack operations.

For arr stack scripts (orphan cleanup, release fixer, sync, discovery, webhooks) see
`Arrs_Stack/README-Arrs_Stack.md`.

---

## ━━━ THE PROBLEMS THAT BUILT THIS ━━━

**Files Owned by Root That Arrs Can't Touch**
Download clients without explicit PUID/PGID write files owned by root. Arrs running as
`nobody:users` cannot rename, move, or delete them. Import fails. Upgrade attempts fail.
The failure is subtle — arr shows the file as managed but can't touch it. You only
discover this when an upgrade is requested and the old version refuses to delete.
The fix: `media_shares_permissions.sh` applies correct ownership daily. Even if a
container is misconfigured, the window is at most 24 hours.

**Scene Junk Confusing Orphan Detection**
Scene releases include `.sfv`, `.nfo`, `.rar`, `.sample` files alongside the actual media.
After extraction and import these are worthless — but they're not tracked by any arr.
They look like orphans. Processing them as orphans means the cleanup output is full of
noise, making it hard to spot actual orphaned media.
The fix: `media_cleaner.sh` runs before any arr cleanup and removes all known junk
patterns first. By the time arr cleanup runs, every untracked file is actual media.

**Watch State Diverging Across Servers**
With two Emby servers, played status and resume positions diverge — a film marked watched
on HOST1 shows as unwatched on HOST2. Two users on different servers get different
continue-watching rows.
The fix: `play_state_sync.sh` syncs watched/played state and resume positions every 30
minutes. Newest timestamp wins. Both servers always reflect the same play history.

---

## ━━━ WHAT THIS FOLDER DOES ━━━

**Library Foundation**
`media_shares_permissions.sh` — normalize ownership and permissions daily. Runs first in
every maintenance window because arr cleanup depends on correct ownership to delete files.

**Junk Removal**
`media_cleaner.sh` — remove scene debris and tool artifacts before orphan scan. Runs
before any arr cleanup so orphan detection only encounters actual media files.

**Play State Sync**
`play_state_sync.sh` — syncs watched/played state and resume positions across all
configured Emby and Jellyfin servers. Newest timestamp wins. Runs every 30 minutes
via critical_sync_maintenance.sh.

---

## ━━━ EXECUTION ORDER ━━━

**Daily via `daily_sync_maintenance.sh` (DAILY_MAINTENANCE_SCRIPTS — runs first):**

```
1. media_shares_permissions.sh   — permissions first — arr cleanup depends on this
2. media_cleaner.sh anime        — junk before orphan scan
3. media_cleaner.sh media
```

These complete before any Arrs_Stack/ scripts run.

**Every 30 min via `critical_sync_maintenance.sh` (CRITICAL_MAINTENANCE_SCRIPTS):**

```
play_state_sync.sh   — sync watched/resume state across Emby + Jellyfin
```

**Why permissions before everything else:** arr cleanup needs `nobody:users` ownership to
delete files. If a file is `root:root`, deletion fails silently — the file looks processed
but stays on disk.

**Why junk before arr cleanup:** junk files are not tracked by any arr — they look like
orphans. Removing them first means orphan detection only finds actual media. Cleaner
output, more accurate detection.

---

## ━━━ HOST AWARENESS ━━━

Scripts run on both servers via `detect_hosts()`, which aliases all `HOST*_` prefixed vars
to their unprefixed names at runtime.

Permissions and cleaner scripts run locally against each server's own shares, defined
in `HOST*_MEDIA_PERMISSION_SHARES` and `HOST*_MEDIA_CLEAN_FOLDERS` in host*.conf.

`play_state_sync.sh` reads both servers' Emby/Jellyfin endpoints from host*.conf and
syncs between them.

---

## ━━━ SCRIPTS IN THIS FOLDER ━━━

| Script | Role | When It Runs |
|--------|------|--------------|
| `media_shares_permissions.sh` | Apply `nobody:users` ownership + correct permissions to all media shares | Daily — runs first |
| `media_cleaner.sh` | Remove junk files (two profiles: `anime` + `media`) | Daily — runs before arr cleanup |
| `play_state_sync.sh` | Sync watched/played state + resume positions across Emby + Jellyfin | Every 30 min |
