129 lines
4.2 KiB
Bash
Executable File
129 lines
4.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# SVT Play Stream Launcher - Search and stream SVT Play content with zenity
|
|
|
|
set -euo pipefail
|
|
|
|
DEBUG="${DEBUG:-0}"
|
|
WAIT_FOR_MPV=0
|
|
LOG_FILE="${HOME}/.svtplay.log"
|
|
|
|
# Parse options
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--debug) DEBUG=1; shift ;;
|
|
--wait) WAIT_FOR_MPV=1; shift ;;
|
|
--log) tail -f "$LOG_FILE"; exit 0 ;;
|
|
--clear-log) rm -f "$LOG_FILE"; echo "Log cleared"; exit 0 ;;
|
|
--help|-h)
|
|
zenity --info --title="SVT Play" --text="Usage: ./svt.sh [--debug|--wait|--log|--help]"
|
|
exit 0 ;;
|
|
*) break ;;
|
|
esac
|
|
done
|
|
|
|
# Logging
|
|
log() { echo -e "\033[0;34m[$1]\033[0m $2" >&2; echo "[$(date '+%H:%M:%S')] [$1] $2" >> "$LOG_FILE"; }
|
|
log_err() { echo -e "\033[0;31m[ERROR]\033[0m $1" >&2; echo "[$(date '+%H:%M:%S')] [ERROR] $1" >> "$LOG_FILE"; }
|
|
|
|
# Force dark mode - works with GTK3 (GTK_THEME) and GTK4/libadwaita (ADW_DEBUG_COLOR_SCHEME)
|
|
zenity_dark() { GTK_THEME=Adwaita:dark ADW_DEBUG_COLOR_SCHEME=prefer-dark zenity "$@"; }
|
|
|
|
check_dependencies() {
|
|
local missing=()
|
|
for cmd in yt-dlp mpv zenity jq curl; do
|
|
command -v "$cmd" &>/dev/null || missing+=("$cmd")
|
|
done
|
|
if [[ ${#missing[@]} -gt 0 ]]; then
|
|
log_err "Missing: ${missing[*]}"
|
|
zenity_dark --error --title="Missing Dependencies" --text="Please install: ${missing[*]}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
search_programs() {
|
|
local query="$1"
|
|
log "API" "Searching: $query"
|
|
|
|
local response http_code
|
|
response=$(curl -s --connect-timeout 10 --max-time 30 -w "\n%{http_code}" -X POST \
|
|
"https://api.svt.se/contento/graphql" -H "Content-Type: application/json" \
|
|
-d "{\"query\": \"{ searchPage(query: \\\"${query}\\\", maxHits: 50) { flat { hits { teaser { heading item { urls { svtplay } } } } } } }\"}" 2>/dev/null) || return 1
|
|
|
|
http_code=$(echo "$response" | tail -1)
|
|
response=$(echo "$response" | sed '$d')
|
|
|
|
[[ "$http_code" != "200" ]] && { log_err "API HTTP $http_code"; return 1; }
|
|
|
|
local results
|
|
results=$(echo "$response" | jq -r '
|
|
.data.searchPage.flat.hits[].teaser |
|
|
select(.heading != null and .item.urls.svtplay != null) |
|
|
(.heading | gsub("<[^>]*>"; "")) + "|" + (.item.urls.svtplay | ltrimstr("/"))
|
|
' 2>/dev/null)
|
|
|
|
[[ -z "$results" ]] && return 1
|
|
log "API" "Found $(echo "$results" | wc -l) results"
|
|
echo "$results"
|
|
}
|
|
|
|
show_search_dialog() {
|
|
zenity_dark --entry --title="Search SVT Play" --text="Program name:" --width=400 2>/dev/null
|
|
}
|
|
|
|
show_results_list() {
|
|
local results="$1" temp_file="/tmp/svt_$$"
|
|
|
|
# Build zenity list and mapping file
|
|
local idx=0
|
|
while IFS='|' read -r title slug; do
|
|
[[ -z "$title" || -z "$slug" ]] && continue
|
|
((idx++))
|
|
title=$(echo "$title" | sed 's/&/\&/g; s/"/"/g; s/</</g; s/>/>/g')
|
|
echo "$title=$slug" >> "$temp_file.map"
|
|
[[ $idx -eq 1 ]] && echo "TRUE" >> "$temp_file" || echo "FALSE" >> "$temp_file"
|
|
echo "$title" >> "$temp_file"
|
|
done <<< "$results"
|
|
|
|
[[ $idx -eq 0 ]] && { rm -f "$temp_file"*; return 1; }
|
|
|
|
local selected
|
|
selected=$(zenity_dark --list --title="Results" --text="Select program:" \
|
|
--column="Select" --column="Program" --radiolist --width=700 --height=500 < "$temp_file" 2>/dev/null)
|
|
|
|
local slug=""
|
|
[[ -n "$selected" ]] && slug=$(grep "^${selected}=" "$temp_file.map" 2>/dev/null | cut -d= -f2)
|
|
rm -f "$temp_file"*
|
|
|
|
[[ -z "$slug" ]] && return 1
|
|
log "✓" "Selected: $selected"
|
|
echo "$slug"
|
|
}
|
|
|
|
play_program() {
|
|
local url="https://www.svtplay.se/$1"
|
|
log "▶" "Playing: $url"
|
|
mpv --force-window=immediate "$url" &
|
|
[[ "$WAIT_FOR_MPV" == "1" ]] && wait $! 2>/dev/null
|
|
}
|
|
|
|
main() {
|
|
check_dependencies
|
|
|
|
local search_term
|
|
search_term=$(show_search_dialog) || exit 0
|
|
[[ -z "$search_term" ]] && exit 0
|
|
|
|
local results
|
|
results=$(search_programs "$search_term") || {
|
|
zenity_dark --error --title="No Results" --text="No programs found for: $search_term"
|
|
exit 0
|
|
}
|
|
|
|
local slug
|
|
slug=$(show_results_list "$results") || exit 0
|
|
|
|
play_program "$slug"
|
|
}
|
|
|
|
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && main "$@"
|