# ━━━━━ MEDIA — Manual ━━━━━

Config reference, procedures, operational workflows for Media/ scripts.
For overview see README-Media.md. For per-script detail see script headers.

For arr stack config and procedures (cleanup, release fixer, sync, discovery) see
`Arrs_Stack/Manual-Arrs_Stack.md`.

---

## ━━━ PERMISSIONS MODEL ━━━

```
Directories: 755 nobody:users
  Owner (nobody) — rwx   enter, list, create files
  Group (users)  — r-x   enter and list
  Others         — r-x   Samba guests can browse
  No world-write — prevents accidental deletion by unauthenticated access

Files: 664 nobody:users
  Owner (nobody) — rw    read + write
  Group (users)  — rw    arrs can import, rename, delete
  Others         — r     Samba guests can read
  No execute bit — media files are never executable
```

**Two separate passes — not a single recursive chmod.** Directories need the execute bit
to enter. Files must never have the execute bit. A single `chmod -R 664` would break
directory entry. The script runs `find -type d` and `find -type f` separately.

**If this script corrects many files on every run**, a container has wrong PUID/PGID.
Correct values on unRAID: `PUID=99 (nobody)` `PGID=100 (users)`. Add to each container's
environment in its Docker template. Common culprits: SABnzbd, qBittorrent, slskd.
Once fixed, this script corrects 0 files per run — it becomes a pure daily failsafe.

---

## ━━━ CONFIGURATION — master.conf ━━━

### Permissions

```bash
PERMISSIONS_DIR_MODE="755"
PERMISSIONS_FILE_MODE="664"
PERMISSIONS_OWNER="nobody:users"
```

---

### Media Cleaner — File Patterns

```bash
ANIME_FILE_PATTERNS=(
    "*.sfv"             # checksum verification — useless after download verified
    "*.md5" "*.sha1"    # other checksum formats
    "*.nfo"             # scene info file — not library metadata
    "*.url" "*.lnk"     # website shortcuts
    "*.rar" "*.zip"     # source archives kept by some clients after extraction
    "*.info"            # tool output files
    "*.torrent"         # torrent descriptor left by some clients
    "*.sample*"         # scene preview clip
    "*.proof*"          # screenshot proving encode quality
    "*sync-conflict*"   # Syncthing conflict copies
    "*.scr" "*.exe"     # executables — should never be in a media folder
    "*.srr"             # scene recovery record
    "*.log"             # tool/client logs
    "*.json"            # metadata or tool output
)

MEDIA_FILE_PATTERNS=(
    "${ANIME_FILE_PATTERNS[@]}"   # all anime patterns plus:
    "*.iso"                       # disc images after ripping
    "*.lrc"                       # lyric files in media folders
)
```

> **DO NOT add patterns that match media you want to keep:**
> `*.mkv *.mp4 *.avi *.m4v` — video files
> `*.flac *.mp3 *.m4a` — audio files
> `*.srt *.sub *.ass` — subtitle files (Bazarr managed)
> `*.jpg *.png` — artwork
> Always use `--dry-run` when adding new patterns.

---

### Play State Sync

```bash
PLAY_STATE_SYNC_ENABLED=true          # toggle entire sync
PLAY_STATE_SYNC_LOOKBACK_DAYS=30      # history window for played items
```

Emby and Jellyfin servers configured per-host:

```bash
# host*.conf
HOST1_EMBY_URL="http://192.168.50.2:8096"
HOST1_EMBY_API_KEY="..."
HOST1_JELLYFIN_URL=""   # empty = skip Jellyfin on this host
HOST1_JELLYFIN_API_KEY=""
```

---

## ━━━ CONFIGURATION — host*.conf ━━━

```bash
# Shares this server applies permissions to
HOST1_MEDIA_PERMISSION_SHARES=(
    "/mnt/user/Movies"
    "/mnt/user/Tv_Shows"
    "/mnt/user/Music"
    "/mnt/user/Kids_Movies"
    "/mnt/user/Kids_Tv_Shows"
    "/mnt/user/Sports"
    "/mnt/user/stand-up_comedy"
)

# Folders cleaned by each profile
HOST1_ANIME_CLEAN_FOLDERS=(
    "/mnt/user/Anime_Movies"
    "/mnt/user/Anime_Movies-Old"
    "/mnt/user/Anime_Shows"
    "/mnt/user/Anime_Shows-Old"
)
HOST1_MEDIA_CLEAN_FOLDERS=(
    "/mnt/user/Kids_Movies"
    "/mnt/user/Kids_Tv_Shows"
    "/mnt/user/Movies"
    "/mnt/user/Music"
    "/mnt/user/Sports"
    "/mnt/user/stand-up_comedy"
    "/mnt/user/Tv_Shows"
)
```

---

## ━━━ OUTPUT TIERS ━━━

All scripts have two output levels controlled by `--log`.

Without `--log`, each script processes silently and concludes with a summary block.
Warnings and errors are always visible.

With `--log`, per-item detail appears — individual shares being processed, file counts,
per-server sync results.

---

## ━━━ FLAG REFERENCE ━━━

### media_shares_permissions.sh

`media_shares_permissions.sh`
Apply correct ownership and permissions to all configured media shares. Safe to run
manually at any time — idempotent, only changes what's wrong.

`media_shares_permissions.sh --dry-run`
Show how many files and directories would be corrected per share. If unexpectedly large,
check container PUID/PGID settings first (PUID=99 PGID=100).

`media_shares_permissions.sh --status`
Show configured share list and ownership of the share roots.

`media_shares_permissions.sh --log`
Show ownership correction count per share and per file (verbose).

> On large libraries this runs 20-30 minutes. This is expected — millions of files with
> recursive walk takes time. Designed to run overnight in the maintenance window.

---

### media_cleaner.sh

`media_cleaner.sh anime`
Remove junk files from anime share folders using ANIME_FILE_PATTERNS.

`media_cleaner.sh media`
Remove junk files from media share folders using MEDIA_FILE_PATTERNS.

`media_cleaner.sh [profile] --dry-run`
Show what would be deleted without removing anything. Always run first when adding new
patterns or folders.

`media_cleaner.sh [profile] --status`
Show folder list and file patterns for the profile.

`media_cleaner.sh [profile] --log`
Show every file examined, not just those removed.

---

### play_state_sync.sh

`play_state_sync.sh`
Sync played/unplayed state and resume positions from local Emby to the remote Emby.
Only items played within PLAY_STATE_SYNC_LOOKBACK_DAYS are synced.

`play_state_sync.sh --full`
Ignore PLAY_STATE_SYNC_LOOKBACK_DAYS — sync all played items regardless of age. May be
slow on large libraries. Use after a new Emby install or database restore to rebuild
full play history.

`play_state_sync.sh --dry-run`
Show what would be synced without writing any state.

`play_state_sync.sh --status`
Show configured servers, reachability, and user counts.

`play_state_sync.sh --log`
Verbose output — show each item comparison.
