# ━━━━━ 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.