Bash common.sh: consolidate docker_cmd/retry_docker/verify_running/emby_api, fix tailscale dups

common.sh gains:
- docker_cmd() + verify_running() + retry_docker() — removed from all 3 Docker_Essentials
  scripts where they were byte-for-byte duplicates
- emby_api(endpoint, [timeout=30]) — removed from 6 Media/Tools scripts that each defined
  their own _emby_api() with the same curl/parse/error pattern; call sites renamed emby_api
- format_duration() extended with days/hours branch (was capped at minutes+seconds)
- notify() comment: scripts do not need to preflight the notify script via validate_unraid_cmd

Tailscale deduplication:
- arr_sync.sh: _resolve_node_ip() and inline block in _delete_remote_item() both replaced
  with resolve_tailscale_ip() from common.sh
- git_pull_execute.sh: inline tailscale ip -4 replaced with resolve_tailscale_ip() (adds
  the tailscale status fallback that was missing)
This commit is contained in:
Gmer4Lfe
2026-06-04 17:00:50 -04:00
parent 0bcb773332
commit b5d33cd6a5
12 changed files with 98 additions and 238 deletions
+4 -15
View File
@@ -216,17 +216,6 @@ fi
# ── API HELPERS ───────────────────────────────────────────────────────────────────────────────
# ==============================================================================================
_emby_api() {
local response http_code body
response=$(curl -sf --max-time 30 \
-H "X-Emby-Token: $EMBY_API_KEY" \
-w "\n%{http_code}" \
"${EMBY_URL}/${1}" 2>/dev/null)
http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | head -n -1)
[[ "$http_code" != "200" ]] && { error "Emby API HTTP $http_code: $1"; return 1; }
echo "$body"
}
_sonarr_get() {
curl -sf --max-time 30 \
@@ -348,7 +337,7 @@ echo "$ICON_HOST $MY_ID ($LOCAL_SERVER_NAME) | lookback: ${LOOKBACK_DAYS}d | thr
echo ""
echo "━━━ $ICON_SYNC Emby Series Library ━━━"
LIBRARIES_JSON=$(_emby_api "Library/VirtualFolders") || { error "Could not fetch Emby libraries"; exit 1; }
LIBRARIES_JSON=$(emby_api "Library/VirtualFolders") || { error "Could not fetch Emby libraries"; exit 1; }
CUTOFF_ISO=$(date -d "${LOOKBACK_DAYS} days ago" '+%Y-%m-%dT%H:%M:%SZ')
TODAY_EPOCH=$(date +%s)
TODAY=$(date +%Y-%m-%d)
@@ -369,7 +358,7 @@ for lib_name in "${SONARR_EMBY_LIBRARIES[@]}"; do
continue
fi
log "Scanning library: $lib_name (ItemId: $lib_id)"
LIB_JSON=$(_emby_api "Items?ParentId=${lib_id}&IncludeItemTypes=Series&Recursive=true&Fields=ProviderIds&Limit=5000") || {
LIB_JSON=$(emby_api "Items?ParentId=${lib_id}&IncludeItemTypes=Series&Recursive=true&Fields=ProviderIds&Limit=5000") || {
warn "Could not fetch series from library: $lib_name"
continue
}
@@ -404,7 +393,7 @@ echo "━━━ $ICON_SYNC Emby Watch History ━━━"
declare -A ITEM_USER_PLAYS # "episode_item_id|user_id" → play count
declare -A ITEM_LAST_PLAY # episode_item_id → ISO date of most recent play
ACTIVITY_JSON=$(_emby_api "System/ActivityLog/Entries?MinDate=${CUTOFF_ISO}&Limit=5000") || {
ACTIVITY_JSON=$(emby_api "System/ActivityLog/Entries?MinDate=${CUTOFF_ISO}&Limit=5000") || {
error "Could not fetch Emby activity log"
exit 1
}
@@ -448,7 +437,7 @@ if [[ "${#ALL_EPISODE_IDS[@]}" -gt 0 ]]; then
for (( _b=0; _b<${#ALL_EPISODE_IDS[@]}; _b+=BATCH_SIZE )); do
BATCH=("${ALL_EPISODE_IDS[@]:_b:BATCH_SIZE}")
IDS_CSV=$(printf '%s,' "${BATCH[@]}"); IDS_CSV="${IDS_CSV%,}"
ITEMS_DETAIL=$(_emby_api "Items?Ids=${IDS_CSV}&Fields=SeriesId,Type&Limit=200") || {
ITEMS_DETAIL=$(emby_api "Items?Ids=${IDS_CSV}&Fields=SeriesId,Type&Limit=200") || {
warn "Could not fetch episode batch starting at $_b"
continue
}