tsplay/install.sh
28allday b3bf49df05 Release v1.0.0: server switching, Walker launcher, curl install, user guide
- Switch servers from the browser (s) with auto-discovery; auto-fallback to
  discovery when a saved server is unreachable, so you're never locked to a
  rebuilt box. cliamp's Jellyfin provider is re-synced on every (re)login.
- Ignore late LAN-discovery results once off the login screen (footer/input
  clobber fix).
- install.sh: curl|bash one-liner that downloads the per-arch release binary,
  still builds from a clone when Go is present; adds a floating Walker entry
  (TUI.float app-id) + icon on Omarchy desktops.
- Docs: USER_GUIDE.md plain-English walkthrough; README install one-liner,
  accurate keybindings, features section.
- Bump version to 1.0.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:48:03 +01:00

146 lines
5.4 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# install.sh — install tsplay, a terminal Jellyfin player for Omarchy / Arch.
#
# Quick install (nothing to clone):
#
# curl -fsSL https://raw.githubusercontent.com/28allday/tsplay/main/install.sh | bash
#
# When run from a git clone it builds from source instead (if Go is present),
# otherwise it downloads the latest released binary for your architecture.
#
# ./install.sh
#
# Environment overrides:
# PREFIX=/somewhere install prefix (default ~/.local → ~/.local/bin)
# TSPLAY_VERSION=v1.0.0 pin a release (default: latest)
#
# tsplay needs mpv at run time; the installer fetches it via pacman on Arch if
# it's missing. On an Omarchy desktop it also adds a floating Walker entry.
set -euo pipefail
REPO="28allday/tsplay"
NAME="tsplay"
PREFIX="${PREFIX:-$HOME/.local}"
BIN_DIR="$PREFIX/bin"
BIN="$BIN_DIR/$NAME"
APP_DIR="$HOME/.local/share/applications"
VERSION="${TSPLAY_VERSION:-latest}"
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
warn() { printf '\033[33m%s\033[0m\n' "$1" >&2; }
err() { printf '\033[31m%s\033[0m\n' "$1" >&2; }
log() { printf '\033[1;36m==>\033[0m %s\n' "$*"; }
# ensure_dep makes sure a command exists, installing it via pacman on Arch if
# missing. mpv is tsplay's only run-time dependency.
ensure_dep() {
local cmd="$1" pkg="$2"
command -v "$cmd" >/dev/null 2>&1 && return 0
if command -v pacman >/dev/null 2>&1; then
bold "Installing missing dependency: ${pkg}"
sudo pacman -S --needed --noconfirm "$pkg"
else
err "Missing dependency '${cmd}'. Install the '${pkg}' package and re-run."
exit 1
fi
}
# mpv is required however we obtain the binary.
ensure_dep mpv mpv
mkdir -p "$BIN_DIR"
# If the script lives next to the source tree, we're in a clone.
SCRIPT_DIR=""
if [ -n "${BASH_SOURCE[0]:-}" ] && [ -f "${BASH_SOURCE[0]}" ]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
fi
# Detect OS/arch for prebuilt asset names.
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
case "$(uname -m)" in
x86_64 | amd64) arch=amd64 ;;
aarch64 | arm64) arch=arm64 ;;
*) arch="" ;;
esac
# ---- obtain the binary ----------------------------------------------------
TMPBIN=""
if [ -n "$SCRIPT_DIR" ] && [ -f "$SCRIPT_DIR/go.mod" ] && command -v go >/dev/null 2>&1; then
bold "Building $NAME from source…"
TMPBIN="$(mktemp)"
trap 'rm -f "$TMPBIN"' EXIT
( cd "$SCRIPT_DIR" && CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' \
-o "$TMPBIN" "./cmd/$NAME" )
elif [ -n "$SCRIPT_DIR" ] && [ -n "$arch" ] && [ -x "$SCRIPT_DIR/dist/${NAME}-${os}-${arch}" ]; then
log "Using prebuilt binary from dist/"
TMPBIN="$SCRIPT_DIR/dist/${NAME}-${os}-${arch}"
else
# Download the released binary for this OS/arch (curl-style install).
[ "$os" = "linux" ] || err "tsplay ships Linux binaries only (detected: $os). Clone the repo and build with Go."
[ "$os" = "linux" ] || exit 1
[ -n "$arch" ] || { err "unsupported architecture: $(uname -m)"; exit 1; }
asset="${NAME}-${os}-${arch}"
if [ "$VERSION" = "latest" ]; then
url="https://github.com/$REPO/releases/latest/download/$asset"
else
url="https://github.com/$REPO/releases/download/$VERSION/$asset"
fi
log "Downloading $asset ($VERSION)…"
TMPBIN="$(mktemp)"
trap 'rm -f "$TMPBIN"' EXIT
if command -v curl >/dev/null 2>&1; then
curl -fSL --proto '=https' --tlsv1.2 -o "$TMPBIN" "$url"
elif command -v wget >/dev/null 2>&1; then
wget -qO "$TMPBIN" "$url"
else
err "need curl or wget to download the binary."; exit 1
fi
fi
# ---- install --------------------------------------------------------------
install -Dm755 "$TMPBIN" "$BIN"
bold "Installed: $BIN"
# ---- Omarchy desktop integration -----------------------------------------
# Only on Omarchy: add a Walker entry that opens tsplay in a floating window.
# The TUI.float app-id is matched by Omarchy's stock floating-window rule, so
# no Hyprland configuration is required (same approach as omarchy-send).
if command -v omarchy-launch-tui >/dev/null 2>&1 || [ -d "$HOME/.local/share/omarchy" ]; then
mkdir -p "$APP_DIR"
# Install the bundled icon into the user's hicolor theme — a play triangle
# over a progress bar, in terminal-accent blue.
icon_dir="$HOME/.local/share/icons/hicolor/scalable/apps"
mkdir -p "$icon_dir"
cat > "$icon_dir/tsplay.svg" <<'SVG'
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256">
<rect width="256" height="256" rx="56" fill="#16161e"/>
<path d="M104 78 L104 158 L172 118 Z" fill="#7aa2f7"/>
<rect x="64" y="186" width="128" height="10" rx="5" fill="#2a2e42"/>
<rect x="64" y="186" width="80" height="10" rx="5" fill="#7aa2f7"/>
</svg>
SVG
gtk-update-icon-cache -q -t -f "$HOME/.local/share/icons/hicolor" 2>/dev/null || true
cat > "$APP_DIR/tsplay.desktop" <<EOF
[Desktop Entry]
Name=tsplay
Comment=Terminal Jellyfin player — browse your server and play in mpv
Exec=xdg-terminal-exec --app-id=TUI.float -e $BIN
Icon=tsplay
Terminal=false
Type=Application
Categories=AudioVideo;Player;Video;Network;
Keywords=jellyfin;media;player;stream;mpv;movies;tv;music;
EOF
bold "Omarchy detected — added floating Walker entry (with icon)."
echo " Launch it from Walker by searching 'tsplay'."
fi
case ":$PATH:" in
*":$BIN_DIR:"*) : ;;
*) warn "Note: $BIN_DIR is not on your PATH. Add it to use 'tsplay' directly." ;;
esac
echo "Run 'tsplay' to sign in to your Jellyfin server (it auto-detects LAN servers)."