mirror of
https://github.com/mrworf/plexupdate.git
synced 2025-07-14 17:22:57 -07:00
Automatically detects 32 or 64 bit systems and the new -l option will allow you to easily see what options you have when defining BUILD and DISTRO. Also improved error messages.
431 lines
12 KiB
Bash
Executable file
431 lines
12 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# Plex Linux Server download tool
|
|
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
# This tool will download the latest version of Plex Media
|
|
# Server for Linux. It supports both the public versions
|
|
# as well as the PlexPass versions.
|
|
#
|
|
# PlexPass users:
|
|
# Either modify this file to add email and password OR create
|
|
# a separate .plexupdate file in your home directory with these
|
|
# values.
|
|
#
|
|
# Returns 0 on success
|
|
# 1 on error
|
|
# 2 if file already downloaded
|
|
# 3 if page layout has changed.
|
|
# 4 if download fails
|
|
# 5 if version already installed
|
|
#
|
|
# All other return values not documented.
|
|
#
|
|
# Call program with -h for available options
|
|
#
|
|
# Enjoy!
|
|
#
|
|
# Check out https://github.com/mrworf/plexupdate for latest version
|
|
# and also what's new.
|
|
#
|
|
####################################################################
|
|
# Quick-check before we allow bad things to happen
|
|
if [ -z "${BASH_VERSINFO}" ]; then
|
|
echo "ERROR: You must execute this script with BASH"
|
|
exit 255
|
|
fi
|
|
####################################################################
|
|
# Set these three settings to what you need, or create a .plexupdate file
|
|
# in your home directory with this section (avoids changing this).
|
|
# DOWNLOADDIR is the full directory path you would like the download to go.
|
|
#
|
|
EMAIL=
|
|
PASS=
|
|
DOWNLOADDIR="."
|
|
|
|
#################################################################
|
|
# Don't change anything below this point
|
|
#
|
|
|
|
# Defaults
|
|
# (aka "Advanced" settings, can be overriden with config file)
|
|
KEEP=no
|
|
FORCE=no
|
|
PUBLIC=no
|
|
AUTOINSTALL=no
|
|
AUTODELETE=no
|
|
AUTOUPDATE=no
|
|
AUTOSTART=no
|
|
CRON=no
|
|
QUIET=no
|
|
SILENT=no
|
|
ARCH=$(uname -m)
|
|
|
|
# Default options for package managers, override if needed
|
|
REDHAT_INSTALL="yum -y install"
|
|
DEBIAN_INSTALL="dpkg -i"
|
|
DISTRO_INSTALL=""
|
|
|
|
# Sanity, make sure wget is in our path...
|
|
wget >/dev/null 2>/dev/null
|
|
if [ $? -eq 127 ]; then
|
|
echo "Error: This script requires wget in the path. It could also signify that you don't have the tool installed." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Load settings from config file if it exists
|
|
if [ -f ~/.plexupdate ]; then
|
|
source ~/.plexupdate
|
|
fi
|
|
|
|
if [ ! "${RELEASE}" = "" ]; then
|
|
echo "ERROR: RELEASE keyword is deprecated, use DISTRO and BUILD"
|
|
exit 255
|
|
fi
|
|
|
|
# Current pages we need - Do not change unless Plex.tv changes again
|
|
URL_LOGIN=https://plex.tv/users/sign_in
|
|
URL_DOWNLOAD=https://plex.tv/api/downloads/1.json?channel=plexpass
|
|
URL_DOWNLOAD_PUBLIC=https://plex.tv/api/downloads/1.json
|
|
|
|
usage() {
|
|
echo "Usage: $(basename $0) [-aCfhkopqsSuU]"
|
|
echo " -a Auto install if download was successful (requires root)"
|
|
echo " -C Cron mode. Only output to stdout on an actionable operation"
|
|
echo " -d Auto delete after auto install"
|
|
echo " -f Force download even if it's the same version or file"
|
|
echo " already exists (WILL NOT OVERWRITE)"
|
|
echo " -h This help"
|
|
echo " -k Reuse last authentication"
|
|
echo " -l List available builds and distros"
|
|
echo " -p Public Plex Media Server version"
|
|
echo " -q Quiet mode. No stdout, only stderr and exit codes"
|
|
echo " -r Print download URL and exit"
|
|
echo " -s Auto start (needed for some distros)"
|
|
echo " -S Silent mode. No text output, only exit codes"
|
|
echo " -u Auto update plexupdate.sh before running it (experimental)"
|
|
echo " -U Do not autoupdate plexupdate.sh (experimental, default)"
|
|
echo
|
|
exit 0
|
|
}
|
|
|
|
# Parse commandline
|
|
ALLARGS="$@"
|
|
set -- $(getopt aCdfhkopqruU: -- "$@")
|
|
while true;
|
|
do
|
|
case "$1" in
|
|
(-h) usage;;
|
|
(-a) AUTOINSTALL=yes;;
|
|
(-C) CRON=yes;;
|
|
(-d) AUTODELETE=yes;;
|
|
(-f) FORCE=yes;;
|
|
(-k) KEEP=yes;;
|
|
(-l) LISTOPTS=yes;;
|
|
(-p) PUBLIC=yes;;
|
|
(-q) QUIET=yes;;
|
|
(-r) PRINT_URL=yes;;
|
|
(-s) AUTOSTART=yes;;
|
|
(-S) SILENT=yes;;
|
|
(-u) AUTOUPDATE=yes;;
|
|
(-U) AUTOUPDATE=no;;
|
|
(--) ;;
|
|
(-*) echo "Error: unrecognized option $1" 1>&2; exit 1;;
|
|
(*) break;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# send all stdout to /dev/null
|
|
if [ "${QUIET}" = "yes" ] || [ "${SILENT}" = "yes" ]; then
|
|
exec 1> /dev/null
|
|
fi
|
|
|
|
# send all stdout and stderr to /dev/null
|
|
if [ "${SILENT}" = "yes" ]; then
|
|
exec 2> /dev/null
|
|
fi
|
|
|
|
if [ "${AUTOUPDATE}" == "yes" ]; then
|
|
git >/dev/null 2>/dev/null
|
|
if [ $? -eq 127 ]; then
|
|
echo "Error: You need to have git installed for this to work" >&2
|
|
exit 1
|
|
fi
|
|
pushd "$(dirname "$0")" >/dev/null
|
|
if [ ! -d .git ]; then
|
|
echo "Error: This is not a git repository, auto update only works if you've done a git clone" >&2
|
|
exit 1
|
|
fi
|
|
git status | grep "git commit -a" >/dev/null 2>/dev/null
|
|
if [ $? -eq 0 ]; then
|
|
echo "Error: You have made changes to the script, cannot auto update" >&2
|
|
exit 1
|
|
fi
|
|
echo -n "Auto updating..."
|
|
git pull >/dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo 'Error: Unable to update git, try running "git pull" manually to see what is wrong' >&2
|
|
exit 1
|
|
fi
|
|
echo "OK"
|
|
popd >/dev/null
|
|
if ! type "$0" 2>/dev/null >/dev/null ; then
|
|
if [ -f "$0" ]; then
|
|
/bin/bash "$0" ${ALLARGS} -U
|
|
else
|
|
echo "Error: Unable to relaunch, couldn't find $0" >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
"$0" ${ALLARGS} -U
|
|
fi
|
|
exit $?
|
|
fi
|
|
|
|
# Sanity check
|
|
if [ "${EMAIL}" == "" -o "${PASS}" == "" ] && [ "${PUBLIC}" == "no" ] && [ ! -f /tmp/kaka ]; then
|
|
echo "Error: Need username & password to download PlexPass version. Otherwise run with -p to download public version." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${AUTOINSTALL}" == "yes" -o "${AUTOSTART}" == "yes" ]; then
|
|
id | grep -i 'uid=0(' 2>&1 >/dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: You need to be root to use autoinstall/autostart option." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
|
|
# Remove any ~ or other oddness in the path we're given
|
|
DOWNLOADDIR="$(eval cd ${DOWNLOADDIR// /\\ } ; if [ $? -eq 0 ]; then pwd; fi)"
|
|
if [ -z "${DOWNLOADDIR}" ]; then
|
|
echo "Error: Download directory does not exist or is not a directory" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${DISTRO_INSTALL}" == "" ]; then
|
|
if [ "${DISTRO}" == "" -a "${BUILD}" == "" ]; then
|
|
# Detect if we're running on redhat instead of ubuntu
|
|
if [ -f /etc/redhat-release ]; then
|
|
REDHAT=yes
|
|
BUILD="linux-ubuntu-${ARCH}"
|
|
DISTRO="redhat"
|
|
DISTRO_INSTALL="${REDHAT_INSTALL}"
|
|
else
|
|
REDHAT=no
|
|
BUILD="linux-ubuntu-${ARCH}"
|
|
DISTRO="ubuntu"
|
|
DISTRO_INSTALL="${DEBIAN_INSTALL}"
|
|
fi
|
|
elif [ "${DISTRO}" == "" -o "${BUILD}" == "" ]; then
|
|
echo "ERROR: You must define both DISTRO and BUILD"
|
|
exit 255
|
|
fi
|
|
else
|
|
if [ "${DISTRO}" == "" -o "${BUILD}" == "" ]; then
|
|
echo "Using custom DISTRO_INSTALL requires custom DISTRO and BUILD too"
|
|
exit 255
|
|
fi
|
|
fi
|
|
|
|
# Useful functions
|
|
rawurlencode() {
|
|
local string="${1}"
|
|
local strlen=${#string}
|
|
local encoded=""
|
|
|
|
for (( pos=0 ; pos<strlen ; pos++ )); do
|
|
c=${string:$pos:1}
|
|
case "$c" in
|
|
[-_.~a-zA-Z0-9] ) o="${c}" ;;
|
|
* ) printf -v o '%%%02x' "'$c"
|
|
esac
|
|
encoded+="${o}"
|
|
done
|
|
echo "${encoded}"
|
|
}
|
|
|
|
keypair() {
|
|
local key="$( rawurlencode "$1" )"
|
|
local val="$( rawurlencode "$2" )"
|
|
|
|
echo "${key}=${val}"
|
|
}
|
|
|
|
# Setup an exit handler so we cleanup
|
|
function cleanup {
|
|
rm /tmp/postdata 2>/dev/null >/dev/null
|
|
rm /tmp/raw 2>/dev/null >/dev/null
|
|
if [ "${KEEP}" != "yes" ]; then
|
|
rm /tmp/kaka 2>/dev/null >/dev/null
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# Fields we need to submit for login to work
|
|
#
|
|
# Field Value
|
|
# utf8 ✓
|
|
# authenticity_token <Need to be obtained from web page>
|
|
# user[login] $EMAIL
|
|
# user[password] $PASSWORD
|
|
# user[remember_me] 0
|
|
# commit Sign in
|
|
|
|
# If user wants, we skip authentication, but only if previous auth exists
|
|
if [ "${KEEP}" != "yes" -o ! -f /tmp/kaka ] && [ "${PUBLIC}" == "no" ]; then
|
|
if [ "${CRON}" = "no" ]; then
|
|
echo -n "Authenticating..."
|
|
fi
|
|
# Clean old session
|
|
rm /tmp/kaka 2>/dev/null
|
|
|
|
# Build post data
|
|
echo -ne >/tmp/postdata "&$(keypair "user[login]" "${EMAIL}" )"
|
|
echo -ne >>/tmp/postdata "&$(keypair "user[password]" "${PASS}" )"
|
|
echo -ne >>/tmp/postdata "&$(keypair "user[remember_me]" "0" )"
|
|
|
|
# Authenticate
|
|
wget --load-cookies /tmp/kaka --save-cookies /tmp/kaka --keep-session-cookies "${URL_LOGIN}" --post-file=/tmp/postdata -O /tmp/raw 2>/dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Unable to authenticate" >&2
|
|
exit 1
|
|
fi
|
|
# Delete authentication data ... Bad idea to let that stick around
|
|
rm /tmp/postdata
|
|
|
|
# Provide some details to the end user
|
|
if [ "$(cat /tmp/raw | grep 'Sign In</title')" != "" ]; then
|
|
echo "Error: Username and/or password incorrect" >&2
|
|
exit 1
|
|
fi
|
|
if [ "${CRON}" = "no" ]; then
|
|
echo "OK"
|
|
fi
|
|
elif [ "$PUBLIC" != "no" ]; then
|
|
# It's a public version, so change URL and make doubly sure that cookies are empty
|
|
rm 2>/dev/null >/dev/null /tmp/kaka
|
|
touch /tmp/kaka
|
|
URL_DOWNLOAD=${URL_DOWNLOAD_PUBLIC}
|
|
fi
|
|
|
|
if [ "${LISTOPTS}" == "yes" ]; then
|
|
opts="$(wget --load-cookies /tmp/kaka --save-cookies /tmp/kaka --keep-session-cookies "${URL_DOWNLOAD}" -O - 2>/dev/null | grep -oe '"label"[^}]*' | grep -v Download | sed 's/"label":"\([^"]*\)","build":"\([^"]*\)","distro":"\([^"]*\)".*/"\3" "\2" "\1"/' | uniq | sort)"
|
|
eval opts=( "DISTRO" "BUILD" "DESCRIPTION" "======" "=====" "==============================================" $opts )
|
|
|
|
BUILD=
|
|
DISTRO=
|
|
|
|
for X in "${opts[@]}" ; do
|
|
if [ "$DISTRO" == "" ]; then
|
|
DISTRO="$X"
|
|
elif [ "$BUILD" == "" ]; then
|
|
BUILD="$X"
|
|
else
|
|
printf "%-12s %-30s %s\n" "$DISTRO" "$BUILD" "$X"
|
|
BUILD=
|
|
DISTRO=
|
|
fi
|
|
done
|
|
exit 0
|
|
fi
|
|
|
|
# Extract the URL for our release
|
|
if [ "${CRON}" = "no" ]; then
|
|
echo -n "Finding download URL to download..."
|
|
fi
|
|
|
|
DOWNLOAD=$(wget --load-cookies /tmp/kaka --save-cookies /tmp/kaka --keep-session-cookies "${URL_DOWNLOAD}" -O - 2>/dev/null | grep -ioe '"label"[^}]*' | grep -i "\"distro\":\"${DISTRO}\"" | grep -i "\"build\":\"${BUILD}\"" | grep -m1 -ioe 'https://[^\"]*' )
|
|
if [ "${CRON}" = "no" ]; then
|
|
echo -e "OK"
|
|
fi
|
|
|
|
if [ "${DOWNLOAD}" == "" ]; then
|
|
echo "ERROR: Unable to retrieve the URL needed for download (Query DISTRO: $DISTRO, BUILD: $BUILD)"
|
|
exit 3
|
|
fi
|
|
|
|
FILENAME="$(basename 2>/dev/null ${DOWNLOAD})"
|
|
if [ $? -ne 0 ]; then
|
|
echo "Failed to parse HTML, download cancelled."
|
|
exit 3
|
|
fi
|
|
|
|
if [ "${PRINT_URL}" == "yes" ]; then
|
|
echo "${DOWNLOAD}"
|
|
exit 0
|
|
fi
|
|
|
|
# By default, try downloading
|
|
SKIP_DOWNLOAD="no"
|
|
|
|
# Installed version detection (only supported for deb based systems, feel free to submit rpm equivalent)
|
|
if [ "${REDHAT}" != "yes" ]; then
|
|
INSTALLED_VERSION=$(dpkg-query -s plexmediaserver 2>/dev/null | grep -Po 'Version: \K.*')
|
|
else
|
|
if [ "${AUTOSTART}" == "no" ]; then
|
|
echo "Your distribution may require the use of the AUTOSTART [-s] option for the service to start after the upgrade completes."
|
|
fi
|
|
INSTALLED_VERSION=$(rpm -qv plexmediaserver 2>/dev/null)
|
|
fi
|
|
if [[ $FILENAME == *$INSTALLED_VERSION* ]] && [ "${FORCE}" != "yes" ] && [ ! -z "${INSTALLED_VERSION}" ]; then
|
|
if [ "${CRON}" = "no" ]; then
|
|
echo "Your OS reports the latest version of Plex ($INSTALLED_VERSION) is already installed. Use -f to force download."
|
|
fi
|
|
exit 5
|
|
fi
|
|
|
|
if [ -f "${DOWNLOADDIR}/${FILENAME}" -a "${FORCE}" != "yes" ]; then
|
|
if [ "${CRON}" = "no" ]; then
|
|
echo "File already exists, won't download."
|
|
fi
|
|
if [ "${AUTOINSTALL}" != "yes" ]; then
|
|
exit 2
|
|
fi
|
|
SKIP_DOWNLOAD="yes"
|
|
fi
|
|
|
|
if [ "${SKIP_DOWNLOAD}" == "no" ]; then
|
|
if [ -f "${DOWNLOADDIR}/${FILENAME}" ]; then
|
|
if [ "${CRON}" = "no" ]; then
|
|
echo "Note! File exists, but asked to overwrite with new copy"
|
|
fi
|
|
fi
|
|
|
|
echo -ne "Downloading release \"${FILENAME}\"..."
|
|
ERROR=$(wget --load-cookies /tmp/kaka --save-cookies /tmp/kaka --keep-session-cookies "${DOWNLOAD}" -O "${DOWNLOADDIR}/${FILENAME}" 2>&1)
|
|
CODE=$?
|
|
if [ ${CODE} -ne 0 ]; then
|
|
echo -e "\n !! Download failed with code ${CODE}, \"${ERROR}\""
|
|
exit ${CODE}
|
|
fi
|
|
echo "OK"
|
|
fi
|
|
|
|
if [ "${AUTOINSTALL}" == "yes" ]; then
|
|
sudo ${DISTRO_INSTALL} "${DOWNLOADDIR}/${FILENAME}"
|
|
fi
|
|
|
|
if [ "${AUTODELETE}" == "yes" ]; then
|
|
if [ "${AUTOINSTALL}" == "yes" ]; then
|
|
rm -rf "${DOWNLOADDIR}/${FILENAME}"
|
|
echo "Deleted \"${FILENAME}\""
|
|
else
|
|
echo "Will not auto delete without [-a] auto install"
|
|
fi
|
|
fi
|
|
|
|
if [ "${AUTOSTART}" == "yes" ]; then
|
|
if [ "${REDHAT}" == "no" ]; then
|
|
echo "The AUTOSTART [-s] option may not be needed on your distribution."
|
|
fi
|
|
# Check for systemd
|
|
if [ -f "/bin/systemctl" ]; then
|
|
systemctl start plexmediaserver.service
|
|
else
|
|
/sbin/service plexmediaserver start
|
|
fi
|
|
fi
|
|
|
|
exit 0
|