#!/bin/bash
# define colors for output
NORMAL="\Zn"
BLACK="\Z0"
RED="\Z1"
GREEN="\Z2"
YELLOW="\Z3"
BLUE="\Z4"
MAGENTA="\Z5"
CYAN="\Z6"
WHITE="\Z7"
BOLD="\Zb"
REVERSE="\Zr"
UNDERLINE="\Zu"
# global variables
url="https://raw.githubusercontent.com/Jandalf81/rclone_script"
branch="beta"
remotebasedir = ""
backtitle="RCLONE_SCRIPT installer"
# Welcome dialog
dialog \
--backtitle "${backtitle}" \
--title "Welcome" \
--ascii-lines \
--colors \
--no-collapse \
--cr-wrap \
--yesno \
"\nThis script will configure RetroPie so that your savefiles and statefiles are synchronized with a remote destination. Several packages and scripts will be installed, see\n\n https://github.com/Jandalf81/rclone_script/blob/master/ReadMe.md\n\nfor a rundown.\n\nAre you sure you wish to continue?" \
28 110 2>&1 > /dev/tty \
|| exit
# Warn the user if they are using the BETA branch
function dialogBetaWarning ()
{
dialog \
--backtitle "${backtitle}" \
--title "Beta Warning" \
--ascii-lines \
--colors \
--no-collapse \
--cr-wrap \
--yesno \
"\n${RED}${UNDERLINE}WARNING!${NORMAL}\n\nYou are about to install a beta version!\nAre you ${RED}REALLY${NORMAL} sure you want to continue?" \
10 50 2>&1 > /dev/tty \
|| exit
}
# Installer
function installer ()
{
initSteps
dialogShowProgress 0
1RCLONE
2PNGVIEW
3IMAGEMAGICK
4RCLONE_SCRIPT
}
# Initialize array $STEPS()
# OUTPUT
# $steps()
function initSteps ()
{
steps[1]="1. RCLONE"
steps[2]=" 1a. Testing for RCLONE binary [ waiting... ]"
steps[3]=" 1b. Getting RCLONE binary [ waiting... ]"
steps[4]=" 1c. Testing RCLONE remote [ waiting... ]"
steps[5]=" 1d. Create RCLONE remote [ waiting... ]"
steps[6]="2. PNGVIEW"
steps[7]=" 2a. Testing for PNGVIEW binary [ waiting... ]"
steps[8]=" 2b. Getting PNGVIEW source [ waiting... ]"
steps[9]=" 2c. Compiling PNGVIEW [ waiting... ]"
steps[10]="3. IMAGEMAGICK"
steps[11]=" 3a. Testing for IMAGEMAGICK [ waiting... ]"
steps[12]=" 3b. Getting IMAGEMAGICK [ waiting... ]"
steps[13]="4. RCLONE_SCRIPT"
steps[14]=" 4a. Getting RCLONE_SCRIPT [ waiting... ]"
steps[15]=" 4b. Creating RCLONE_SCRIPT menu item [ waiting... ]"
steps[16]=" 4c. Configure RCLONE_SCRIPT [ waiting... ]"
steps[17]="5. RUNCOMMAND"
steps[18]=" 5a. RUNCOMMAND-ONSTART [ waiting... ]"
steps[19]=" 5b. RUNCOMMAND-ONEND [ waiting... ]"
steps[20]="6. Local SAVEFILE directory"
steps[21]=" 6a. Test for local SAVEFILE directory [ waiting... ]"
steps[22]=" 6b. Create local SAVEFILE directory [ waiting... ]"
steps[23]="7. Remote SAVEFILE directory"
steps[24]=" 7a. Test for local SAVEFILE directory [ waiting... ]"
steps[25]=" 7b. Create local SAVEFILE directory [ waiting... ]"
steps[26]="8. Configure RETROARCH"
steps[27]=" 8a. Setting local SAVEFILE directory [ waiting... ]"
steps[28]="9. Finalizing"
steps[29]=" 9a. Saving configuration [ waiting... ]"
}
# Build progress from array $STEPS()
# INPUT
# $steps()
# OUTPUT
# $progress
function buildProgress ()
{
progress=""
for ((i=0; i<=${#steps[*]}; i++))
do
progress="${progress}${steps[i]}\n"
done
}
# Show Progress dialog
# INPUT
# 1 > Percentage to show in dialog
# $backtitle
# $progress
function dialogShowProgress ()
{
local percent="$1"
buildProgress
clear
clear
echo "${percent}" | dialog \
--stdout \
--colors \
--ascii-lines \
--no-collapse \
--cr-wrap \
--backtitle "${backtitle}" \
--title "Installer" \
--gauge "${progress}" 36 90 0 \
2>&1 > /dev/tty
sleep 1
}
# Update item of $STEPS() and show updated progress dialog
# INPUT
# 1 > Number of step to update
# 2 > New status for step
# 3 > Percentage to show in progress dialog
# $steps()
# OUTPUT
# $steps()
function updateStep ()
{
local step="$1"
local newStatus="$2"
local percent="$3"
local oldline
local newline
# translate and colorize $NEWSTATUS
case "${newStatus}" in
"waiting") newStatus="[ ${NORMAL}WAITING...${NORMAL} ]" ;;
"in progress") newStatus="[ ${NORMAL}IN PROGRESS${NORMAL} ]" ;;
"done") newStatus="[ ${GREEN}DONE${NORMAL} ]" ;;
"found") newStatus="[ ${GREEN}FOUND${NORMAL} ]" ;;
"not found") newStatus="[ ${RED}NOT FOUND${NORMAL} ]" ;;
"failed") newStatus="[ ${RED}FAILED${NORMAL} ]" ;;
"skipped") newStatus="[ ${YELLOW}${BOLD}SKIPPED${NORMAL} ]" ;;
*) newStatus="[ ${RED}UNDEFINED${NORMAL} ]" ;;
esac
# search $STEP in $STEPS
for ((i=0; i<${#steps[*]}; i++))
do
if [[ ${steps[i]} =~ .*$step.* ]]
then
# update $STEP with $NEWSTATUS
oldline="${steps[i]}"
oldline="${oldline%%[*}"
newline="${oldline}${newStatus}"
steps[i]="${newline}"
break
fi
done
# show progress dialog
dialogShowProgress ${percent}
}
function 1RCLONE ()
{
# 1a. Testing for RCLONE binary
updateStep "1a" "in progress" 0
1aTestRCLONE
if [[ $? -eq 0 ]]
then
updateStep "1a" "found" 5
updateStep "1b" "skipped" 10
else
updateStep "1a" "not found" 5
# 1b. Getting RCLONE binary
updateStep "1b" "in progress" 5
1bInstallRCLONE
if [[ $? -eq 0 ]]
then
updateStep "1b" "done" 10
else
updateStep "1b" "failed" 5
fi
fi
# 1c. Testing RCLONE configuration
updateStep "1c" "in progress" 10
1cTestRCLONEremote
if [[ $? -eq 0 ]]
then
updateStep "1c" "found" 15
updateStep "1d" "skipped" 20
else
updateStep "1c" "not found" 15
# 1d. Create RCLONE remote
updateStep "1d" "in progress" 15
1dCreateRCLONEremote
updateStep "1d" "done" 20
fi
}
# Checks if RCLONE is installed
# RETURN
# 0 > RCLONE is installed
# 1 > RCLONE is not installed
function 1aTestRCLONE ()
{
printf "$(date +%FT%T%:z):\t1aTestRCLONE\tSTART\n" >> ./rclone_script-install.log
if [ -f /usr/bin/rclone ]
then
printf "$(date +%FT%T%:z):\t1aTestRCLONE\tFOUND\n" >> ./rclone_script-install.log
return 0
else
printf "$(date +%FT%T%:z):\t1aTestRCLONE\tNOT FOUND\n" >> ./rclone_script-install.log
return 1
fi
}
# Installs RCLONE by download
# RETURN
# 0 > RCLONE has been installed
# 1 > Error while installing RCLONE
function 1bInstallRCLONE ()
{
printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tSTART\n" >> ./rclone_script-install.log
# TODO get RCLONE for 64bit
{ # try
# get binary
wget -P ~ https://downloads.rclone.org/rclone-current-linux-arm.zip --append-output=./rclone_script-install.log &&
unzip ~/rclone-current-linux-arm.zip -d ~ >> ./rclone_script-install.log &&
cd ~/rclone-v* &&
# move binary
sudo mv rclone /usr/bin >> ./rclone_script-install.log &&
sudo chown root:root /usr/bin/rclone >> ./rclone_script-install.log &&
sudo chmod 755 /usr/bin/rclone >> ./rclone_script-install.log &&
cd ~ &&
# remove temp files
rm ~/rclone-current-linux-arm.zip >> ./rclone_script-install.log &&
rm -r ~/rclone-v* >> ./rclone_script-install.log &&
printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tDONE\n" >> ./rclone_script-install.log
return 0
} || { #catch
printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tERROR\n" >> ./rclone_script-install.log
# remove temp files
rm ~/rclone-current-linux-arm.zip >> ./rclone_script-install.log &&
rm -r ~/rclone-v* >> ./rclone_script-install.log &&
return 1
}
}
# Checks if there's a RCLONE remote called RETROPIE
# RETURN
# 0 > remote RETROPIE has been found
# 1 > no remote RETROPIE found
function 1cTestRCLONEremote ()
{
printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tSTART\n" >> ./rclone_script-install.log
local remotes=$(rclone listremotes)
local retval=$(grep -i "^retropie:" <<< ${remotes})
if [ "${retval}" == "retropie:" ]
then
printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tFOUND\n" >> ./rclone_script-install.log
return 0
else
printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tNOT FOUND\n" >> ./rclone_script-install.log
return 1
fi
}
# Tells the user to create a new RCLONE remote called RETROPIE
# RETURN
# 0 > remote RETROPIE has been created (no other OUTPUT possible)
function 1dCreateRCLONEremote ()
{
printf "$(date +%FT%T%:z):\t1dCreateRCLONEremote\tSTART\n" >> ./rclone_script-install.log
dialog \
--stdout \
--colors \
--ascii-lines \
--no-collapse \
--cr-wrap \
--backtitle "${backtitle}" \
--title "Installer" \
--msgbox "\nPlease create a new remote within RCLONE now. Name that remote ${RED}retropie${NORMAL}. Please consult the RCLONE documentation for further information:\n https://www.rclone.org\n\nOpening RCLONE CONFIG now..." 20 50 \
2>&1 > /dev/tty
rclone config
1cTestRCLONEremote
if [[ $? -eq 1 ]]
then
dialog \
--stdout \
--colors \
--ascii-lines \
--no-collapse \
--cr-wrap \
--backtitle "${backtitle}" \
--title "Installer" \
--msgbox "\nNo remote ${RED}retropie${NORMAL} found.\nPlease try again." 20 50 \
2>&1 > /dev/tty
1dCreateRCLONEremote
else
printf "$(date +%FT%T%:z):\t1dCreateRCLONEremote\tFOUND\n" >> ./rclone_script-install.log
return 0
fi
}
function 2PNGVIEW ()
{
# 2a. Testing for PNGVIEW binary
updateStep "2a" "in progress" 20
2aTestPNGVIEW
if [[ $? -eq 0 ]]
then
updateStep "2a" "found" 25
updateStep "2b" "skipped" 30
updateStep "2c" "skipped" 35
else
updateStep "2a" "not found" 25
# 2b. Getting PNGVIEW source
updateStep "2b" "in progress" 25
2bGetPNGVIEWsource
if [[ $? -eq 0 ]]
then
updateStep "2b" "done" 30
# 2c. Compiling PNGVIEW
updateStep "2c" "in progress" 30
2cCompilePNGVIEW
if [[ $? -eq 0 ]]
then
updateStep "2c" "done" 35
else
updateStep "2c" "failed" 30
exit
fi
else
updateStep "2b" "failed" 25
exit
fi
fi
}
# Checks if PNGVIEW is installed
# RETURN
# 0 > PNGVIEW is installed
# 1 > PNGVIEW is not installed
function 2aTestPNGVIEW ()
{
printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tSTART\n" >> ./rclone_script-install.log
if [ -f /usr/bin/pngview ]
then
printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tFOUND\n" >> ./rclone_script-install.log
return 0
else
printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tNOT FOUND\n" >> ./rclone_script-install.log
return 1
fi
}
# Gets PNGVIEW source
# RETURN
# 0 > source downloaded and unzipped
# 1 > no source downloaded, removed temp files
function 2bGetPNGVIEWsource ()
{
printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tSTART\n" >> ./rclone_script-install.log
{ #try
wget -P ~ https://github.com/AndrewFromMelbourne/raspidmx/archive/master.zip --append-output=./rclone_script-install.log &&
unzip ~/master.zip -d ~ >> ./rclone_script-install.log &&
printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tDONE\n" >> ./rclone_script-install.log &&
return 0
} || { #catch
printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tERROR\n" >> ./rclone_script-install.log &&
rm ~/master.zip >> ./rclone_script-install.log &&
sudo rm -r ~/raspidmx-master >> ./rclone_script-install.log &&
return 1
}
}
# Compiles PNGVIEW source, moves binaries
# RETURN
# 0 > compiled without errors, moved binaries, removed temp files
# 1 > errors while compiling, removed temp files
function 2cCompilePNGVIEW ()
{
printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tSTART\n" >> ./rclone_script-install.log
{ #try
# compile
# cd ~/raspidmx-master &&
make --directory=~/raspidmx-master >> ./rclone_script-install.log &&
# move binary files
sudo mv ~/raspidmx-master/pngview/pngview /usr/bin >> ./rclone_script-install.log &&
sudo mv ~/raspidmx-master/lib/libraspidmx.so.1 /usr/lib >> ./rclone_script-install.log &&
sudo chown root:root /usr/bin/pngview >> ./rclone_script-install.log &&
sudo chmod 755 /usr/bin/pngview >> ./rclone_script-install.log &&
# remove temp files
rm ~/master.zip >> ./rclone_script-install.log &&
sudo rm -r ~/raspidmx-master >> ./rclone_script-install.log &&
printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tDONE\n" >> ./rclone_script-install.log &&
return 0
} || { #catch
printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tERROR\n" >> ./rclone_script-install.log &&
# remove temp files
rm ~/master.zip >> ./rclone_script-install.log &&
sudo rm -r ~/raspidmx-master >> ./rclone_script-install.log &&
return 1
}
}
function 3IMAGEMAGICK ()
{
# 3a. Testing for IMAGEMAGICK
updateStep "3a" "in progress" 35
3aTestIMAGEMAGICK
if [[ $? -eq 0 ]]
then
updateStep "3a" "found" 40
updateStep "3b" "skipped" 45
else
updateStep "3a" "not found" 40
# 3b. Getting IMAGEMAGICK
updateStep "3b" "in progress" 40
3bInstallIMAGEMAGICK
if [[ $? -eq 0 ]]
then
updateStep "3b" "done" 45
else
updateStep "3b" "failed" 40
fi
fi
}
# Checks is IMAGEMAGICK is installed
# RETURN
# 0 > IMAGEMAGICK is installed
# 1 > IMAGEMAGICK is not installed
function 3aTestIMAGEMAGICK ()
{
printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tSTART\n" >> ./rclone_script-install.log
if [ -f /usr/bin/convert ]
then
printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tFOUND\n" >> ./rclone_script-install.log
return 0
else
printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tNOT FOUND\n" >> ./rclone_script-install.log
return 1
fi
}
# Installs IMAGEMAGICK via APT-GET
# RETURN
# 0 > IMAGEMAGICK has been installed
# 1 > Error while installing IMAGEMAGICK
function 3bInstallIMAGEMAGICK ()
{
printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tSTART\n" >> ./rclone_script-install.log
sudo apt-get update >> ./rclone_script-install.log &&
sudo apt-get --yes install imagemagick >> ./rclone_script-install.log &&
if [[ $? -eq 0 ]]
then
printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tDONE\n" >> ./rclone_script-install.log &&
return 0
else
printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tERROR\n" >> ./rclone_script-install.log &&
return 1
fi
}
function 4RCLONE_SCRIPT ()
{
# 4a. Getting RCLONE_SCRIPT
updateStep "4a" "in progress" 45
4aGetRCLONE_SCRIPT
if [[ $? -eq 0 ]]
then
updateStep "4a" "done" 50
else
updateStep "4a" "failed" 45
exit
fi
# 4b. Creating RCLONE_SCRIPT menu item
updateStep "4b" "in progress" 50
4bCreateRCLONE_SCRIPTMenuItem
if [[ $? -eq 0 ]]
then
updateStep "4b" "done" 55
else
updateStep "4b" "failed" 50
exit
fi
# 4c. Configure RCLONE_SCRIPT
}
# Gets RCLONE_SCRIPT
# RETURN
# 0 > downloaded successfully
# 1 > errors while downloading
function 4aGetRCLONE_SCRIPT ()
{
printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tSTART\n" >> ./rclone_script-install.log
# create directory if necessary
if [ ! -d ~/scripts/rclone_script ]
then
mkdir ~/scripts/rclone_script >> ./rclone_script-install.log
fi
{ #try
# get script files
wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script.sh --append-output=./rclone_script-install.log &&
wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script-menu.sh --append-output=./rclone_script-install.log &&
wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script-uninstall.sh --append-output=./rclone_script-install.log &&
# change mod
chmod +x ~/scripts/rclone_script/rclone_script.sh >> ./rclone_script-install.log &&
chmod +x ~/scripts/rclone_script/rclone_script-menu.sh >> ./rclone_script-install.log &&
chmod +x ~/scripts/rclone_script/rclone_script-uninstall.sh >> ./rclone_script-install.log &&
printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tDONE\n" >> ./rclone_script-install.log &&
return 0
} || { # catch
printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tERROR\n" >> ./rclone_script-install.log
return 1
}
}
# Creates a menu item for RCLONE_SCRIPT in RetroPie menu
# RETURN
# 0 > menu item has been found or created
# 1 > error while creating menu item
function 4bCreateRCLONE_SCRIPTMenuItem ()
{
printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tSTART\n" >> ./rclone_script-install.log
# move menu script
mv --force ~/scripts/rclone_script/rclone_script-menu.sh ~/RetroPie/retropiemenu >> ./rclone_script-install.log
# check if menu item exists
if grep -Fq "./rclone_script-menu.sh" ~/.emulationstation/gamelists/retropie/gamelist.xml
then
printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tFOUND\n" >> ./rclone_script-install.log
return 0
else
printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tNOT FOUND\n" >> ./rclone_script-install.log
sed -i "/<\/gameList>/c\\\\t\n\t\t.\/rclone_script-menu.sh<\/path>\n\t\tRCLONE_SCRIPT menu<\/name>\n\t\tCustomize RCLONE_SCRIPT, start a full sync, uninstall RCLONE_SCRIPT<\/desc>\n\t\t\n\t<\/game>\n<\/gameList>" ~/.emulationstation/gamelists/retropie/gamelist.xml
if [[ $? -eq 0 ]]
then
printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tCREATED\n" >> ./rclone_script-install.log
return 0
else
printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tERROR\n" >> ./rclone_script-install.log
return 1
fi
fi
}
# main
if [ "${branch}" == "beta" ]
then
dialogBetaWarning
fi
installer