From bd92e53b7d99d23b27d2dfe41e444a225c693e55 Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 06:55:45 -0500 Subject: [PATCH 01/10] Create retroiptv_rpi.sh Install / Uninstall for Raspberry Pi --- retroiptv_rpi.sh | 269 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 retroiptv_rpi.sh diff --git a/retroiptv_rpi.sh b/retroiptv_rpi.sh new file mode 100644 index 0000000..1a4f4dd --- /dev/null +++ b/retroiptv_rpi.sh @@ -0,0 +1,269 @@ +#!/bin/bash +# RetroIPTVGuide Raspberry Pi Manager +# Combined Installer / Uninstaller for Pi 3 & 4 +# License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International + +# --- Banner --- +cat <<'EOF' +░█████████ ░██ ░██████░█████████ ░██████████░██ ░██ ░██████ ░██ ░██ +░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ +░██ ░██ ░███████ ░████████ ░██░████ ░███████ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░████████ ░███████ +░█████████ ░██ ░██ ░██ ░███ ░██ ░██ ░██ ░█████████ ░██ ░██ ░██ ░██ █████ ░██ ░██ ░██░██ ░██ ░██ ░██ +░██ ░██ ░█████████ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ██ ░██ ░██ ░██░██ ░██ ░█████████ +░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██░██ ░██ ░███ ░██ ░███ ░██░██ ░███ ░██ +░██ ░██ ░███████ ░████ ░██ ░███████ ░██████░██ ░██ ░███ ░█████░█ ░█████░██ ░██ ░█████░██ ░███████ + + + +EOF +echo "===========================================================================" +echo " RetroIPTVGuide | Raspberry Pi Edition" +echo "===========================================================================" +echo "" + +set -e + +APP_DIR="/opt/RetroIPTVGuide" +SERVICE_FILE="/etc/systemd/system/retroiptvguide.service" +CONFIG_FILE="/boot/config.txt" +USER_NAME="${SUDO_USER:-$(whoami)}" + +ACTION="$1" +AUTO_YES=false +if [[ "$2" == "--yes" || "$2" == "-y" ]]; then + AUTO_YES=true +fi + +#====================== FUNCTIONS ======================# + +show_usage() { + echo "" + echo "Usage:" + echo " sudo ./retroiptv_rpi.sh install" + echo " sudo ./retroiptv_rpi.sh uninstall [--yes|-y]" + echo "" + echo "Examples:" + echo " sudo ./retroiptv_rpi.sh install" + echo " sudo ./retroiptv_rpi.sh uninstall --yes" + echo "" + exit 1 +} + +#---------------------------------------------------------- +install_app() { + echo "" + echo "============================================================" + echo " RetroIPTVGuide Raspberry Pi Installer Agreement " + echo "============================================================" + echo "" + echo "This installer will perform the following actions:" + echo " - Detect Raspberry Pi model (3 or 4)" + echo " - Install dependencies (Python3, ffmpeg, etc.)" + echo " - Clone or update RetroIPTVGuide into /opt/RetroIPTVGuide" + echo " - Configure Python virtual environment and systemd service" + echo " - Auto-configure GPU acceleration (KMS/Fake KMS)" + echo " - Optionally reboot when done" + echo "" + echo "By continuing, you agree that:" + echo " - This software should ONLY be run on internal networks." + echo " - It must NOT be exposed to the public Internet." + echo " - You accept all risks; no warranty is provided." + echo "" + + read -p "Do you agree to these terms? (yes/no): " agreement + if [ "$agreement" != "yes" ]; then + echo "Installation aborted by user." + exit 1 + fi + echo "Agreement accepted. Continuing..." + echo "" + + # Detect model + PI_MODEL=$(tr -d '\0' < /proc/device-tree/model) + if echo "$PI_MODEL" | grep -q "Raspberry Pi 4"; then + PI_TYPE="pi4" + elif echo "$PI_MODEL" | grep -q "Raspberry Pi 3"; then + PI_TYPE="pi3" + else + PI_TYPE="unknown" + fi + echo "Detected board: $PI_MODEL ($PI_TYPE)" + echo "" + + # Update + deps + sudo apt update -y && sudo apt full-upgrade -y + sudo apt install -y git python3 python3-venv python3-pip ffmpeg mesa-utils v4l-utils raspi-config + + # Clone repo + if [ ! -d "$APP_DIR" ]; then + echo "Cloning RetroIPTVGuide..." + sudo git clone https://github.com/thehack904/RetroIPTVGuide.git "$APP_DIR" + else + echo "Existing repo found, updating..." + cd "$APP_DIR" && sudo git pull + fi + + # Python venv + cd "$APP_DIR" + sudo python3 -m venv venv + source venv/bin/activate + pip install --upgrade pip + if [ -f requirements.txt ]; then + pip install -r requirements.txt + else + pip install Flask + fi + deactivate + + # Systemd service + sudo tee "$SERVICE_FILE" > /dev/null </dev/null || true + sudo systemctl disable retroiptvguide 2>/dev/null || true + echo "Service stopped and disabled." + fi + + # Remove service + [ -f "$SERVICE_FILE" ] && sudo rm -f "$SERVICE_FILE" && sudo systemctl daemon-reload + + # Remove app directory + if [ -d "$APP_DIR" ]; then + if [ "$AUTO_YES" = true ]; then + sudo rm -rf "$APP_DIR" + echo "Application directory deleted automatically." + else + read -p "Delete all files under $APP_DIR? (yes/no): " del + [[ "$del" == "yes" ]] && sudo rm -rf "$APP_DIR" && echo "Deleted." || echo "Retained." + fi + fi + + # Optional logs + LOG_DIRS=("/var/log/retroiptvguide" "/tmp/retroiptvguide" "$HOME/.cache/retroiptvguide") + for dir in "${LOG_DIRS[@]}"; do + if [ -d "$dir" ]; then + if [ "$AUTO_YES" = true ]; then + sudo rm -rf "$dir" + echo "Removed logs: $dir" + else + read -p "Delete logs in $dir? (yes/no): " ans + [[ "$ans" == "yes" ]] && sudo rm -rf "$dir" && echo "Deleted $dir." + fi + fi + done + + echo "" + echo "============================================================" + echo " Uninstallation Complete " + echo "============================================================" + echo "All RetroIPTVGuide components removed." + echo "System packages remain installed." + echo "End time: $(date)" + echo "" +} + +#====================== MAIN ======================# + +if [[ -z "$ACTION" ]]; then + show_usage +fi + +case "$ACTION" in + install) + install_app + ;; + uninstall) + uninstall_app + ;; + *) + show_usage + ;; +esac From f77791ab01bc7c22799346a69b051cdaf04e0801 Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 07:01:07 -0500 Subject: [PATCH 02/10] Update retroiptv_rpi.sh --- retroiptv_rpi.sh | 352 +++++++++++++++++++---------------------------- 1 file changed, 141 insertions(+), 211 deletions(-) diff --git a/retroiptv_rpi.sh b/retroiptv_rpi.sh index 1a4f4dd..2920098 100644 --- a/retroiptv_rpi.sh +++ b/retroiptv_rpi.sh @@ -1,7 +1,7 @@ #!/bin/bash -# RetroIPTVGuide Raspberry Pi Manager -# Combined Installer / Uninstaller for Pi 3 & 4 -# License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International +# RetroIPTVGuide Raspberry Pi Manager (Installer + Uninstaller) +# Logs all output to /var/log/retroiptvguide/YYYYMMDD-HHMMSS.log +# License: CC BY-NC-SA 4.0 # --- Banner --- cat <<'EOF' @@ -23,6 +23,21 @@ echo "" set -e +# --- Logging Setup --- +LOG_DIR="/var/log/retroiptvguide" +TIMESTAMP=$(date +"%Y%m%d-%H%M%S") +LOG_FILE="$LOG_DIR/install-$TIMESTAMP.log" + +# Make sure log directory exists and is writable +sudo mkdir -p "$LOG_DIR" +sudo chmod 755 "$LOG_DIR" + +# Redirect all stdout/stderr to tee so user sees it and it’s saved +exec > >(tee -a "$LOG_FILE") 2>&1 + +echo "Log file: $LOG_FILE" +echo "" + APP_DIR="/opt/RetroIPTVGuide" SERVICE_FILE="/etc/systemd/system/retroiptvguide.service" CONFIG_FILE="/boot/config.txt" @@ -30,97 +45,63 @@ USER_NAME="${SUDO_USER:-$(whoami)}" ACTION="$1" AUTO_YES=false -if [[ "$2" == "--yes" || "$2" == "-y" ]]; then - AUTO_YES=true -fi +if [[ "$2" == "--yes" || "$2" == "-y" ]]; then AUTO_YES=true; fi #====================== FUNCTIONS ======================# - show_usage() { - echo "" - echo "Usage:" - echo " sudo ./retroiptv_rpi.sh install" - echo " sudo ./retroiptv_rpi.sh uninstall [--yes|-y]" - echo "" - echo "Examples:" - echo " sudo ./retroiptv_rpi.sh install" - echo " sudo ./retroiptv_rpi.sh uninstall --yes" - echo "" - exit 1 + echo "" + echo "Usage:" + echo " sudo ./retroiptv_rpi.sh install" + echo " sudo ./retroiptv_rpi.sh uninstall [--yes|-y]" + echo "" + exit 1 } #---------------------------------------------------------- install_app() { - echo "" - echo "============================================================" - echo " RetroIPTVGuide Raspberry Pi Installer Agreement " - echo "============================================================" - echo "" - echo "This installer will perform the following actions:" - echo " - Detect Raspberry Pi model (3 or 4)" - echo " - Install dependencies (Python3, ffmpeg, etc.)" - echo " - Clone or update RetroIPTVGuide into /opt/RetroIPTVGuide" - echo " - Configure Python virtual environment and systemd service" - echo " - Auto-configure GPU acceleration (KMS/Fake KMS)" - echo " - Optionally reboot when done" - echo "" - echo "By continuing, you agree that:" - echo " - This software should ONLY be run on internal networks." - echo " - It must NOT be exposed to the public Internet." - echo " - You accept all risks; no warranty is provided." - echo "" - - read -p "Do you agree to these terms? (yes/no): " agreement - if [ "$agreement" != "yes" ]; then - echo "Installation aborted by user." - exit 1 - fi - echo "Agreement accepted. Continuing..." - echo "" - - # Detect model - PI_MODEL=$(tr -d '\0' < /proc/device-tree/model) - if echo "$PI_MODEL" | grep -q "Raspberry Pi 4"; then - PI_TYPE="pi4" - elif echo "$PI_MODEL" | grep -q "Raspberry Pi 3"; then - PI_TYPE="pi3" - else - PI_TYPE="unknown" - fi - echo "Detected board: $PI_MODEL ($PI_TYPE)" - echo "" - - # Update + deps - sudo apt update -y && sudo apt full-upgrade -y - sudo apt install -y git python3 python3-venv python3-pip ffmpeg mesa-utils v4l-utils raspi-config - - # Clone repo - if [ ! -d "$APP_DIR" ]; then - echo "Cloning RetroIPTVGuide..." - sudo git clone https://github.com/thehack904/RetroIPTVGuide.git "$APP_DIR" - else - echo "Existing repo found, updating..." - cd "$APP_DIR" && sudo git pull - fi - - # Python venv - cd "$APP_DIR" - sudo python3 -m venv venv - source venv/bin/activate - pip install --upgrade pip - if [ -f requirements.txt ]; then - pip install -r requirements.txt - else - pip install Flask - fi - deactivate - - # Systemd service - sudo tee "$SERVICE_FILE" > /dev/null < /dev/null </dev/null || true - sudo systemctl disable retroiptvguide 2>/dev/null || true - echo "Service stopped and disabled." - fi - - # Remove service - [ -f "$SERVICE_FILE" ] && sudo rm -f "$SERVICE_FILE" && sudo systemctl daemon-reload - - # Remove app directory - if [ -d "$APP_DIR" ]; then - if [ "$AUTO_YES" = true ]; then - sudo rm -rf "$APP_DIR" - echo "Application directory deleted automatically." - else - read -p "Delete all files under $APP_DIR? (yes/no): " del - [[ "$del" == "yes" ]] && sudo rm -rf "$APP_DIR" && echo "Deleted." || echo "Retained." - fi - fi - - # Optional logs - LOG_DIRS=("/var/log/retroiptvguide" "/tmp/retroiptvguide" "$HOME/.cache/retroiptvguide") - for dir in "${LOG_DIRS[@]}"; do - if [ -d "$dir" ]; then - if [ "$AUTO_YES" = true ]; then - sudo rm -rf "$dir" - echo "Removed logs: $dir" - else - read -p "Delete logs in $dir? (yes/no): " ans - [[ "$ans" == "yes" ]] && sudo rm -rf "$dir" && echo "Deleted $dir." - fi - fi - done - - echo "" - echo "============================================================" - echo " Uninstallation Complete " - echo "============================================================" - echo "All RetroIPTVGuide components removed." - echo "System packages remain installed." - echo "End time: $(date)" - echo "" + echo "" + echo "============================================================" + echo " RetroIPTVGuide Uninstaller for Raspberry Pi " + echo "============================================================" + echo "" + + if [ "$AUTO_YES" = false ]; then + read -p "Proceed with uninstallation? (yes/no): " c + [[ "$c" != "yes" ]] && echo "Aborted." && exit 1 + fi + + systemctl stop retroiptvguide 2>/dev/null || true + systemctl disable retroiptvguide 2>/dev/null || true + [ -f "$SERVICE_FILE" ] && sudo rm -f "$SERVICE_FILE" && sudo systemctl daemon-reload + + if [ -d "$APP_DIR" ]; then + if [ "$AUTO_YES" = true ]; then sudo rm -rf "$APP_DIR" + else read -p "Delete $APP_DIR? (yes/no): " d && [[ "$d" == "yes" ]] && sudo rm -rf "$APP_DIR"; fi + fi + + LOG_DIRS=("/var/log/retroiptvguide" "/tmp/retroiptvguide" "$HOME/.cache/retroiptvguide") + for dir in "${LOG_DIRS[@]}"; do + [ -d "$dir" ] || continue + if [ "$AUTO_YES" = true ]; then sudo rm -rf "$dir" + else read -p "Delete logs in $dir? (yes/no): " a && [[ "$a" == "yes" ]] && sudo rm -rf "$dir"; fi + done + + echo "" + echo "============================================================" + echo " Uninstallation Complete " + echo "============================================================" + echo "All RetroIPTVGuide components removed." + echo "End time: $(date)" + echo "Log file: $LOG_FILE" + echo "" } #====================== MAIN ======================# - -if [[ -z "$ACTION" ]]; then - show_usage -fi - +if [[ -z "$ACTION" ]]; then show_usage; fi case "$ACTION" in - install) - install_app - ;; - uninstall) - uninstall_app - ;; - *) - show_usage - ;; + install) install_app ;; + uninstall) uninstall_app ;; + *) show_usage ;; esac From 76be2a428db32be9d4ed123c6dba108f78fca699 Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 07:18:35 -0500 Subject: [PATCH 03/10] Update retroiptv_rpi.sh --- retroiptv_rpi.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/retroiptv_rpi.sh b/retroiptv_rpi.sh index 2920098..dafce25 100644 --- a/retroiptv_rpi.sh +++ b/retroiptv_rpi.sh @@ -122,15 +122,15 @@ EOF case "$PI_TYPE" in pi3) sudo raspi-config nonint do_gldriver G1 - sudo raspi-config nonint do_memory_split 128 + sudo raspi-config nonint set_config_var gpu_mem 128 /boot/config.txt grep -q "dtoverlay=vc4-fkms-v3d" "$CONFIG_FILE" || echo "dtoverlay=vc4-fkms-v3d" | sudo tee -a "$CONFIG_FILE" ;; pi4) sudo raspi-config nonint do_gldriver G2 - sudo raspi-config nonint do_memory_split 256 + sudo raspi-config nonint set_config_var gpu_mem 256 /boot/config.txt grep -q "dtoverlay=vc4-kms-v3d" "$CONFIG_FILE" || echo "dtoverlay=vc4-kms-v3d" | sudo tee -a "$CONFIG_FILE" ;; - *) sudo raspi-config nonint do_memory_split 128 ;; + *) sudo raspi-config nonint set_config_var gpu_mem 128 /boot/config.txt ;; esac echo "" From 4e6f600cd095530c19566e0fdf5be91ad3f88ff8 Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 08:36:58 -0500 Subject: [PATCH 04/10] Update ROADMAP.md --- ROADMAP.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ROADMAP.md b/ROADMAP.md index 7704779..59f07f7 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -100,3 +100,15 @@ These are **not yet implemented**, but provide a development path for future rel ## ✅ Completed (v3.0.0) - [x] Full Windows installer/uninstaller support with NSSM service, firewall rule, and Chocolatey integration (v3.0.0). - [x] Documentation updates (README.md, INSTALL.md) to reflect Windows support (v3.0.0). + +### Installer Enhancement: Kiosk vs Headless Mode (Planned) +**Target Version:** v3.2.0 +**Status:** Planned +**Effort:** Medium + +- Add an interactive mode selector to the Raspberry Pi installer. +- Headless mode → install to `/home/iptv/iptv-server` with service user `iptv`. +- Kiosk mode → install to `/opt/RetroIPTVGuide` and auto-launch Chromium in fullscreen displaying RetroIPTVGuide. +- Support command-line flags: `--mode kiosk` or `--mode headless` for non-interactive installs. +- Ensure logs and services are properly separated between modes. + From 8ff431a2988f26dffb55e00646db219334715a0f Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 08:38:34 -0500 Subject: [PATCH 05/10] Update ROADMAP.md --- ROADMAP.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 59f07f7..a659ab9 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -80,6 +80,17 @@ These are **not yet implemented**, but provide a development path for future rel - Medium term: Test and harden installer/uninstaller on mixed Windows environments (v3.0.0 complete, further refinements planned). - Long term: .m3u8 support, DB logs, recording functionality. +## 💻🥧 Installer Enhancement: Kiosk vs Headless Mode (Planned) +**Target Version:** v3.2.0 +**Status:** Planned +**Effort:** Medium + +- Add an interactive mode selector to the Raspberry Pi installer. +- Headless mode → install to `/home/iptv/iptv-server` with service user `iptv`. +- Kiosk mode → install to `/opt/RetroIPTVGuide` and auto-launch Chromium in fullscreen displaying RetroIPTVGuide. +- Support command-line flags: `--mode kiosk` or `--mode headless` for non-interactive installs. +- Ensure logs and services are properly separated between modes. + --- ## ✅ Completed @@ -96,19 +107,6 @@ These are **not yet implemented**, but provide a development path for future rel - [x] Basic Windows installer support (Git Bash + PowerShell bootstrap) (v2.3.0). - ## ✅ Completed (v3.0.0) - [x] Full Windows installer/uninstaller support with NSSM service, firewall rule, and Chocolatey integration (v3.0.0). - [x] Documentation updates (README.md, INSTALL.md) to reflect Windows support (v3.0.0). - -### Installer Enhancement: Kiosk vs Headless Mode (Planned) -**Target Version:** v3.2.0 -**Status:** Planned -**Effort:** Medium - -- Add an interactive mode selector to the Raspberry Pi installer. -- Headless mode → install to `/home/iptv/iptv-server` with service user `iptv`. -- Kiosk mode → install to `/opt/RetroIPTVGuide` and auto-launch Chromium in fullscreen displaying RetroIPTVGuide. -- Support command-line flags: `--mode kiosk` or `--mode headless` for non-interactive installs. -- Ensure logs and services are properly separated between modes. - From e9e040002770839e2b5b8685d39a0349f047eefb Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:06:49 -0500 Subject: [PATCH 06/10] Update retroiptv_rpi.sh --- retroiptv_rpi.sh | 238 ++++++++++++++++++++++++++++++----------------- 1 file changed, 152 insertions(+), 86 deletions(-) diff --git a/retroiptv_rpi.sh b/retroiptv_rpi.sh index dafce25..ccbe44f 100644 --- a/retroiptv_rpi.sh +++ b/retroiptv_rpi.sh @@ -1,6 +1,7 @@ #!/bin/bash -# RetroIPTVGuide Raspberry Pi Manager (Installer + Uninstaller) -# Logs all output to /var/log/retroiptvguide/YYYYMMDD-HHMMSS.log +# RetroIPTVGuide Raspberry Pi Installer (Headless, Pi3/4/5) +# Installs to /home/iptv/iptv-server for consistency with Debian/Windows +# Logs to /var/log/retroiptvguide/install-YYYYMMDD-HHMMSS.log # License: CC BY-NC-SA 4.0 # --- Banner --- @@ -13,102 +14,173 @@ cat <<'EOF' ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██░██ ░██ ░███ ░██ ░███ ░██░██ ░███ ░██ ░██ ░██ ░███████ ░████ ░██ ░███████ ░██████░██ ░██ ░███ ░█████░█ ░█████░██ ░██ ░█████░██ ░███████ - - EOF echo "===========================================================================" -echo " RetroIPTVGuide | Raspberry Pi Edition" +echo " RetroIPTVGuide | Raspberry Pi Edition (Headless)" echo "===========================================================================" echo "" set -e -# --- Logging Setup --- +# --- Logging --- LOG_DIR="/var/log/retroiptvguide" TIMESTAMP=$(date +"%Y%m%d-%H%M%S") LOG_FILE="$LOG_DIR/install-$TIMESTAMP.log" - -# Make sure log directory exists and is writable sudo mkdir -p "$LOG_DIR" sudo chmod 755 "$LOG_DIR" - -# Redirect all stdout/stderr to tee so user sees it and it’s saved exec > >(tee -a "$LOG_FILE") 2>&1 - echo "Log file: $LOG_FILE" echo "" -APP_DIR="/opt/RetroIPTVGuide" +# --- Vars --- +APP_USER="iptv" +APP_DIR="/home/$APP_USER/iptv-server" SERVICE_FILE="/etc/systemd/system/retroiptvguide.service" CONFIG_FILE="/boot/config.txt" -USER_NAME="${SUDO_USER:-$(whoami)}" ACTION="$1" AUTO_YES=false -if [[ "$2" == "--yes" || "$2" == "-y" ]]; then AUTO_YES=true; fi +AUTO_AGREE=false +for arg in "$@"; do + case "$arg" in + --yes|-y) AUTO_YES=true ;; + --agree|-a) AUTO_AGREE=true ;; + esac +done -#====================== FUNCTIONS ======================# -show_usage() { - echo "" - echo "Usage:" - echo " sudo ./retroiptv_rpi.sh install" - echo " sudo ./retroiptv_rpi.sh uninstall [--yes|-y]" - echo "" - exit 1 +# --- Helpers --- +set_gpu_mem() { + local val="$1" + if command -v raspi-config >/dev/null 2>&1; then + sudo raspi-config nonint set_config_var gpu_mem "$val" "$CONFIG_FILE" + else + # Fallback: edit/append gpu_mem in /boot/config.txt + sudo sed -i -E 's/^\s*gpu_mem\s*=.*/gpu_mem='"$val"'/g' "$CONFIG_FILE" 2>/dev/null || true + if ! grep -qE '^\s*gpu_mem\s*=' "$CONFIG_FILE" 2>/dev/null; then + echo "gpu_mem=$val" | sudo tee -a "$CONFIG_FILE" >/dev/null + fi + fi +} + +ensure_owned_by_iptv() { + sudo chown -R "$APP_USER:$APP_USER" "$APP_DIR" } -#---------------------------------------------------------- +pip_install_as_iptv() { + local cmd="$1" + sudo -u "$APP_USER" bash -lc "$cmd" +} + +#====================== INSTALL ======================# install_app() { echo "" echo "============================================================" - echo " RetroIPTVGuide Raspberry Pi Installer Agreement " + echo " RetroIPTVGuide Raspberry Pi Headless Installer " echo "============================================================" echo "" echo "This installer will perform the following actions:" - echo " - Detect Raspberry Pi model (3 or 4)" + echo " - Detect Raspberry Pi model (3, 4, or newer)" echo " - Install dependencies (Python3, ffmpeg, etc.)" - echo " - Clone or update RetroIPTVGuide into /opt/RetroIPTVGuide" + echo " - Create system user 'iptv' (if not present)" + echo " - Clone RetroIPTVGuide into /home/iptv/iptv-server" echo " - Configure Python virtual environment and systemd service" - echo " - Auto-configure GPU acceleration (KMS/Fake KMS)" + echo " - Auto-configure GPU memory for headless operation" + echo " - Enable the retroiptvguide service on boot" echo " - Optionally reboot when done" echo "" - read -p "Do you agree to these terms? (yes/no): " agreement - [[ "$agreement" != "yes" ]] && echo "Installation aborted." && exit 1 - - # Detect model - PI_MODEL=$(tr -d '\0' < /proc/device-tree/model) - if echo "$PI_MODEL" | grep -q "Raspberry Pi 4"; then PI_TYPE="pi4" - elif echo "$PI_MODEL" | grep -q "Raspberry Pi 3"; then PI_TYPE="pi3" - else PI_TYPE="unknown"; fi + echo "By continuing, you agree that:" + echo " - This software should only be run on internal networks." + echo " - It must not be exposed to the public Internet." + echo " - You accept all risks; no warranty is provided." + echo "" + + if [ "$AUTO_AGREE" = true ]; then + echo "[Auto-agree] Terms accepted via --agree flag." + else + read -p "Do you agree to these terms? (yes/no): " agreement + if [ "$agreement" != "yes" ]; then + echo "Installation aborted by user." + exit 1 + fi + echo "Agreement accepted. Continuing..." + fi + echo "" + + # Detect Pi model + PI_MODEL=$(tr -d '\0' < /proc/device-tree/model 2>/dev/null || echo "Unknown Model") + if echo "$PI_MODEL" | grep -q "Raspberry Pi 5"; then + PI_TYPE="pi5" + elif echo "$PI_MODEL" | grep -q "Raspberry Pi 4"; then + PI_TYPE="pi4" + elif echo "$PI_MODEL" | grep -q "Raspberry Pi 3"; then + PI_TYPE="pi3" + else + PI_TYPE="unknown" + fi echo "Detected board: $PI_MODEL ($PI_TYPE)" + echo "" - sudo apt update -y && sudo apt full-upgrade -y - sudo apt install -y git python3 python3-venv python3-pip ffmpeg mesa-utils v4l-utils raspi-config + # Create system user + if ! id "$APP_USER" &>/dev/null; then + echo "Creating user '$APP_USER'..." + sudo useradd -m -r -s /usr/sbin/nologin "$APP_USER" + fi + + # Prepare app dir + sudo mkdir -p "$APP_DIR" + ensure_owned_by_iptv + + # Update & deps (apt-get, script-safe) + echo "Installing dependencies..." + sudo apt-get update -y + sudo apt-get dist-upgrade -y + sudo apt-get install -y git python3 python3-venv python3-pip ffmpeg mesa-utils v4l-utils + # raspi-config is standard on Raspberry Pi OS; on Ubuntu it may be missing (we handle fallback in set_gpu_mem) + sudo apt-get install -y raspi-config || true - if [ ! -d "$APP_DIR" ]; then - sudo git clone https://github.com/thehack904/RetroIPTVGuide.git "$APP_DIR" + # Clone / update repo + if [ ! -d "$APP_DIR/.git" ]; then + sudo -u "$APP_USER" git clone https://github.com/thehack904/RetroIPTVGuide.git "$APP_DIR" else - cd "$APP_DIR" && sudo git pull + ( cd "$APP_DIR" && sudo -u "$APP_USER" git pull ) fi - cd "$APP_DIR" - sudo python3 -m venv venv - source venv/bin/activate - pip install --upgrade pip - [ -f requirements.txt ] && pip install -r requirements.txt || pip install Flask - deactivate + # Python venv & deps (as iptv user) + if [ ! -d "$APP_DIR/venv" ]; then + sudo -u "$APP_USER" python3 -m venv "$APP_DIR/venv" + fi + pip_install_as_iptv "source '$APP_DIR/venv/bin/activate' && pip install --upgrade pip" + if [ -f "$APP_DIR/requirements.txt" ]; then + pip_install_as_iptv "source '$APP_DIR/venv/bin/activate' && pip install -r '$APP_DIR/requirements.txt'" + else + pip_install_as_iptv "source '$APP_DIR/venv/bin/activate' && pip install Flask" + fi - sudo tee "$SERVICE_FILE" > /dev/null </dev/null < Date: Thu, 9 Oct 2025 11:09:28 -0500 Subject: [PATCH 07/10] Update retroiptv_rpi.sh --- retroiptv_rpi.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/retroiptv_rpi.sh b/retroiptv_rpi.sh index ccbe44f..0fdff3d 100644 --- a/retroiptv_rpi.sh +++ b/retroiptv_rpi.sh @@ -205,6 +205,21 @@ EOF echo "Full log saved to: $LOG_FILE" echo "" + # --- Post-install verification --- + echo "Verifying service status..." + sleep 3 + if systemctl is-active --quiet retroiptvguide; then + echo "✅ Service is active." + if curl -fs http://localhost:5000 >/dev/null 2>&1; then + echo "✅ Web interface responding on port 5000." + else + echo "⚠️ Service active, but no HTTP response. Check logs in $LOG_FILE." + fi + else + echo "❌ Service not active. Run: sudo systemctl status retroiptvguide" + fi + echo "" + # Optional reboot prompt if [ "$AUTO_YES" = true ]; then # For unattended runs, perform a quick service check and skip reboot by default From 26d4dac371464dba8c4811d74c4a602b0c54d6b5 Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:29:36 -0500 Subject: [PATCH 08/10] Update retroiptv_rpi.sh --- retroiptv_rpi.sh | 85 +++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/retroiptv_rpi.sh b/retroiptv_rpi.sh index 0fdff3d..7fda9bb 100644 --- a/retroiptv_rpi.sh +++ b/retroiptv_rpi.sh @@ -48,28 +48,20 @@ for arg in "$@"; do esac done -# --- Helpers --- +# --- Helper functions --- set_gpu_mem() { local val="$1" if command -v raspi-config >/dev/null 2>&1; then sudo raspi-config nonint set_config_var gpu_mem "$val" "$CONFIG_FILE" else - # Fallback: edit/append gpu_mem in /boot/config.txt sudo sed -i -E 's/^\s*gpu_mem\s*=.*/gpu_mem='"$val"'/g' "$CONFIG_FILE" 2>/dev/null || true if ! grep -qE '^\s*gpu_mem\s*=' "$CONFIG_FILE" 2>/dev/null; then echo "gpu_mem=$val" | sudo tee -a "$CONFIG_FILE" >/dev/null fi fi } - -ensure_owned_by_iptv() { - sudo chown -R "$APP_USER:$APP_USER" "$APP_DIR" -} - -pip_install_as_iptv() { - local cmd="$1" - sudo -u "$APP_USER" bash -lc "$cmd" -} +ensure_owned_by_iptv() { sudo chown -R "$APP_USER:$APP_USER" "$APP_DIR"; } +pip_install_as_iptv() { sudo -u "$APP_USER" bash -lc "$1"; } #====================== INSTALL ======================# install_app() { @@ -80,6 +72,7 @@ install_app() { echo "" echo "This installer will perform the following actions:" echo " - Detect Raspberry Pi model (3, 4, or newer)" + echo " - Check storage, RAM, and swap configuration" echo " - Install dependencies (Python3, ffmpeg, etc.)" echo " - Create system user 'iptv' (if not present)" echo " - Clone RetroIPTVGuide into /home/iptv/iptv-server" @@ -98,54 +91,62 @@ install_app() { echo "[Auto-agree] Terms accepted via --agree flag." else read -p "Do you agree to these terms? (yes/no): " agreement - if [ "$agreement" != "yes" ]; then - echo "Installation aborted by user." - exit 1 - fi + [[ "$agreement" != "yes" ]] && echo "Installation aborted." && exit 1 echo "Agreement accepted. Continuing..." fi echo "" # Detect Pi model PI_MODEL=$(tr -d '\0' < /proc/device-tree/model 2>/dev/null || echo "Unknown Model") - if echo "$PI_MODEL" | grep -q "Raspberry Pi 5"; then - PI_TYPE="pi5" - elif echo "$PI_MODEL" | grep -q "Raspberry Pi 4"; then - PI_TYPE="pi4" - elif echo "$PI_MODEL" | grep -q "Raspberry Pi 3"; then - PI_TYPE="pi3" - else - PI_TYPE="unknown" - fi + case "$PI_MODEL" in + *"Raspberry Pi 5"*) PI_TYPE="pi5" ;; + *"Raspberry Pi 4"*) PI_TYPE="pi4" ;; + *"Raspberry Pi 3"*) PI_TYPE="pi3" ;; + *) PI_TYPE="unknown" ;; + esac echo "Detected board: $PI_MODEL ($PI_TYPE)" echo "" - # Create system user + # Check SD card and swap + echo "Checking storage and memory..." + ROOT_DEV=$(df / | tail -1 | awk '{print $1}') + SD_SIZE=$(df -h / | awk 'NR==2 {print $2}') + MEM_TOTAL=$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo) + SWAP_TOTAL=$(awk '/SwapTotal/ {print int($2/1024)}' /proc/meminfo) + echo "Root device: $ROOT_DEV" + echo "Storage size: $SD_SIZE" + echo "RAM: ${MEM_TOTAL}MB | Swap: ${SWAP_TOTAL}MB" + if [ "$MEM_TOTAL" -lt 1000 ] && [ "$SWAP_TOTAL" -lt 400 ]; then + echo "⚠️ Warning: <1GB RAM and <400MB swap — increase swap to 1GB for stability:" + echo " sudo dphys-swapfile swapoff && sudo sed -i 's/^CONF_SWAPSIZE=.*/CONF_SWAPSIZE=1024/' /etc/dphys-swapfile && sudo dphys-swapfile setup && sudo dphys-swapfile swapon" + fi + if df -BG / | awk 'NR==2 {exit ($2<8)}'; then + echo "⚠️ Warning: Root filesystem smaller than 8GB — limited space for logs/updates." + fi + echo "" + + # Create user if needed if ! id "$APP_USER" &>/dev/null; then echo "Creating user '$APP_USER'..." sudo useradd -m -r -s /usr/sbin/nologin "$APP_USER" fi - - # Prepare app dir sudo mkdir -p "$APP_DIR" ensure_owned_by_iptv - # Update & deps (apt-get, script-safe) + # Update & deps echo "Installing dependencies..." sudo apt-get update -y sudo apt-get dist-upgrade -y - sudo apt-get install -y git python3 python3-venv python3-pip ffmpeg mesa-utils v4l-utils - # raspi-config is standard on Raspberry Pi OS; on Ubuntu it may be missing (we handle fallback in set_gpu_mem) - sudo apt-get install -y raspi-config || true + sudo apt-get install -y git python3 python3-venv python3-pip ffmpeg mesa-utils v4l-utils raspi-config || true - # Clone / update repo + # Clone or update repo if [ ! -d "$APP_DIR/.git" ]; then sudo -u "$APP_USER" git clone https://github.com/thehack904/RetroIPTVGuide.git "$APP_DIR" else ( cd "$APP_DIR" && sudo -u "$APP_USER" git pull ) fi - # Python venv & deps (as iptv user) + # Python venv setup if [ ! -d "$APP_DIR/venv" ]; then sudo -u "$APP_USER" python3 -m venv "$APP_DIR/venv" fi @@ -155,15 +156,13 @@ install_app() { else pip_install_as_iptv "source '$APP_DIR/venv/bin/activate' && pip install Flask" fi - - # Ensure DB/data dirs if app expects them sudo -u "$APP_USER" mkdir -p "$APP_DIR/data" || true - # GPU memory per model (headless safe) + # GPU memory by model echo "Configuring GPU memory..." case "$PI_TYPE" in pi4|pi5) set_gpu_mem 256 ;; - pi3|unknown|*) set_gpu_mem 128 ;; + pi3|*) set_gpu_mem 128 ;; esac # systemd service @@ -184,7 +183,6 @@ Environment=FLASK_RUN_HOST=0.0.0.0 [Install] WantedBy=multi-user.target EOF - sudo systemctl daemon-reload sudo systemctl enable retroiptvguide sudo systemctl restart retroiptvguide @@ -220,19 +218,16 @@ EOF fi echo "" - # Optional reboot prompt - if [ "$AUTO_YES" = true ]; then - # For unattended runs, perform a quick service check and skip reboot by default - systemctl is-active --quiet retroiptvguide && echo "Service is active." || echo "Warning: service not active." - else - read -t 10 -p "Reboot now to ensure GPU memory takes effect? (Y/n, default Y in 10s): " R || R="Y" + # Optional reboot + if [ "$AUTO_YES" = false ]; then + read -t 10 -p "Reboot now to apply GPU memory? (Y/n, default Y in 10s): " R || R="Y" R=${R:-Y} if [[ "$R" =~ ^[Yy]$ ]]; then echo "Rebooting..." sleep 2 sudo reboot else - echo "Reboot skipped. Run 'sudo reboot' later to apply GPU memory if changed." + echo "Reboot skipped. Run 'sudo reboot' later if GPU memory changed." fi fi } From 999c8efd77194052991ae8029a6710b58afd7058 Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 12:13:09 -0500 Subject: [PATCH 09/10] Update retroiptv_rpi.sh --- retroiptv_rpi.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/retroiptv_rpi.sh b/retroiptv_rpi.sh index 7fda9bb..cac9547 100644 --- a/retroiptv_rpi.sh +++ b/retroiptv_rpi.sh @@ -52,12 +52,24 @@ done set_gpu_mem() { local val="$1" if command -v raspi-config >/dev/null 2>&1; then - sudo raspi-config nonint set_config_var gpu_mem "$val" "$CONFIG_FILE" + # Quietly apply GPU memory change and suppress unrelated warnings + sudo raspi-config nonint set_config_var gpu_mem "$val" "$CONFIG_FILE" 2>/dev/null || true + + # Verify it was written correctly + local current_val + current_val=$(grep -E "^gpu_mem=" "$CONFIG_FILE" 2>/dev/null | tail -n1 | cut -d'=' -f2) + if [ "$current_val" = "$val" ]; then + echo "✅ Verified: GPU memory successfully set to ${val}MB" | tee -a "$LOG_FILE" + else + echo "⚠️ Warning: Could not confirm gpu_mem=$val in $CONFIG_FILE" | tee -a "$LOG_FILE" + fi else + # Manual fallback if raspi-config missing sudo sed -i -E 's/^\s*gpu_mem\s*=.*/gpu_mem='"$val"'/g' "$CONFIG_FILE" 2>/dev/null || true if ! grep -qE '^\s*gpu_mem\s*=' "$CONFIG_FILE" 2>/dev/null; then echo "gpu_mem=$val" | sudo tee -a "$CONFIG_FILE" >/dev/null fi + echo "✅ Fallback: gpu_mem set manually to ${val}MB" | tee -a "$LOG_FILE" fi } ensure_owned_by_iptv() { sudo chown -R "$APP_USER:$APP_USER" "$APP_DIR"; } From b1718b3f52c5510a4ac5569e511353ee1ef91ba8 Mon Sep 17 00:00:00 2001 From: thehack904 <35552907+thehack904@users.noreply.github.com> Date: Thu, 9 Oct 2025 21:43:01 -0500 Subject: [PATCH 10/10] Update retroiptv_rpi.sh --- retroiptv_rpi.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/retroiptv_rpi.sh b/retroiptv_rpi.sh index cac9547..81a4fdd 100644 --- a/retroiptv_rpi.sh +++ b/retroiptv_rpi.sh @@ -220,16 +220,28 @@ EOF sleep 3 if systemctl is-active --quiet retroiptvguide; then echo "✅ Service is active." - if curl -fs http://localhost:5000 >/dev/null 2>&1; then - echo "✅ Web interface responding on port 5000." - else - echo "⚠️ Service active, but no HTTP response. Check logs in $LOG_FILE." + echo "Waiting for web interface to start..." + local wait_time=0 + local max_wait=15 + while [ $wait_time -lt $max_wait ]; do + if curl -fs http://localhost:5000 >/dev/null 2>&1; then + echo "✅ Web interface responding on port 5000 (after ${wait_time}s)." + echo "✅ Verified: HTTP response received." | tee -a "$LOG_FILE" + break + fi + sleep 2 + wait_time=$((wait_time+2)) + done + if [ $wait_time -ge $max_wait ]; then + echo "⚠️ Service active, but no HTTP response after ${max_wait}s. Check logs in $LOG_FILE." + echo "⚠️ Possible slow startup on first run (SQLite or dependencies still initializing)." | tee -a "$LOG_FILE" fi else echo "❌ Service not active. Run: sudo systemctl status retroiptvguide" fi echo "" + # Optional reboot if [ "$AUTO_YES" = false ]; then read -t 10 -p "Reboot now to apply GPU memory? (Y/n, default Y in 10s): " R || R="Y"