├── ReadMe.md ├── rclone_script-install.sh ├── rclone_script-menu.sh ├── rclone_script-uninstall.sh └── rclone_script.sh /ReadMe.md: -------------------------------------------------------------------------------- 1 | # rclone_script 2 | 3 | Setup cloud synchronization for the save files on your RetroPie 4 | 5 | ## What does this do? 6 | 7 | This script will setup different things on your RetroPie in order to automatically sync save files to a cloud service supported by [rclone](https://rclone.org/) 8 | 9 | ## What will you have to do? 10 | 11 | Just install this via 12 | ```bash 13 | wget -N -P ~/scripts/rclone_script https://raw.githubusercontent.com/Jandalf81/rclone_script/master/rclone_script-install.sh; 14 | chmod 755 ~/scripts/rclone_script/rclone_script-install.sh; 15 | ~/scripts/rclone_script/rclone_script-install.sh; 16 | ``` 17 | and follow the instructions. 18 | 19 | I ***strongly*** recommend reading this page completely before actually doing this! You can also look at these Wiki pages to better understand what this script does: 20 | 21 | * [Step-by-step guide through the installer](../../wiki/RCLONE_SCRIPT-install) 22 | * [RCLONE_SCRIPT in action](../../wiki/RCLONE_SCRIPT%20in%20action) 23 | * [Guide to the RCLONE_SCRIPT menu](../../wiki/RCLONE_SCRIPT-menu) 24 | * [How to manually move your savefiles](../../wiki/move-Savefiles) 25 | * This also allows you to sync your progress with RetroArch on [Android](../../wiki/sync-and-play-Android) and [Windows](../../wiki/sync-and-play-Windows)! 26 | 27 | ## Again, what does this do? 28 | 29 | Let me give you a rundown of the things this script will do: 30 | 31 | 1. The script will install the _RCLONE_ binary. It will be downloaded directly from their website as the binary installable via _apt-get_ is quite old, sadly. _RCLONE_ actually is what allows us to use a number of different cloud services, see [their website](https://rclone.org/) for a complete list. The script will then ask you to define a _remote_. That is the other side used for the synchronization. That remote **has** to be called _retropie_, the script will not continue without it. Please consult the [RCLONE documentation](https://rclone.org/) on how to configure remotes for different cloud services 32 | 2. Then, _PNGVIEW_ will be downloaded, compiled and installed. That will be used to show you notifications when up- and downloading save files. 33 | 3. _IMAGEMAGICK_ will be installed via _apt-get_, this will be used to actually create images containing the notifications which are shown by _PNGVIEW_ 34 | 4. The other scripts you see here will now be downloaded. They are used to control _RCLONE_ whenever it needs to sync your save files. Notice that there's also a script to remove all of this from your RetroPie. A new menu item in the RetroPie menu will be created which let's you control some aspects of RCLONE_SCRIPTS. Then, you'll be asked to enter the desired name of the _remote SAVEFILE base directory_. All your synchronized files will go into this directory. 35 | 5. Some scripts from RetroPie will be changed so they call one of the scripts from step 4 which then calls _RCLONE_... Sounds complicated but you don't have to do anything 36 | 6. Right next to the _ROMS_ directory, a new directory _SAVES_ will be created, containing a subdirectory for each system. This is where your savefiles will have to be locally now. See [this wiki page](../../wiki/move-Savefiles) on how to move the savefiles there, that will ***not*** be done by the script 37 | 7. The setup script will now create the _remote SAVEFILE base directory_ and one subdirectory for each system RetroPie supports at the remote destination (if necessary) 38 | 8. Your RetroPie will be configured so each system uses it's own local directory for saves. Before, RetroPie looked for these files in the _ROMS_ directory (which made syncing them without accidentially uploading a ROM - ILLEGALLY - so much more difficult) 39 | 9. The settings you entered during installation are then saved for future reference 40 | 41 | That's it, setup is complete. If you already have some save files within the _ROMS_ directory you need to move them to their subdirectory within the _SAVES_ directory now. Afterwards, reboot your RetroPie so the new menu item shows up 42 | 43 | ## What will RetroPie do after this script is installed? 44 | 45 | Whenever you start or stop playing a game, the accompanying save files will be down- or uploaded to the configured remote: 46 | 47 | * starting a game will trigger _RCLONE_ to download save files for the game from the remote 48 | * stopping a game will trigger _RCLONE_ to upload save files for the game to the remote 49 | 50 | Of course, all of this only works if your RetroPie has access to the configured cloud service. 51 | 52 | In the RetroPie menu, there will also be a new menu item "_RCLONE_SCRIPT menu_". Starting this menu item will let you... 53 | 54 | * start a full sync to up- and download newer files to and from the remote, so each side should have the latest save file for each game afterwards. Please note that this will also download save files even if the accompanying ROM is not on your RetroPie. 55 | * toggle a setting to enable or disable the synchronization when starting or stopping a ROM. With this, you can temporarily disable that process. You'll get a warning, though 56 | * toggle a setting to enable or disable showing a notification for the synchronization process 57 | 58 | ## Why do this? 59 | 60 | Well, I have two big reasons: 61 | 1. I wanted an offsite backup of my save files. I have started _Chrono Trigger_ so many times and always lost the save by tinkering with my RetroPie... 62 | 2. I wanted to be able to seamlessly continue playing on another machine. Now I can... 63 | * start the game on RetroPie, play for an hour, save and automatically upload to DropBox 64 | * download the save file to Android via [DropSync](https://play.google.com/store/apps/details?id=com.ttxapps.dropsync&hl=de) and continue playing there via [RetroArch for Android](https://play.google.com/store/apps/details?id=com.retroarch) (don't forget to upload afterwards!) 65 | * continue playing on my PC which is synced automatically via the DropBox client (which also uploads again automatically) 66 | * then return to RetroPie, which auto-downloads the save when I start the game there 67 | 68 | ## Are there risks? 69 | 70 | Of course! I'm a hobby programer, so this script might have errors I just haven't found yet. I'll do my best to fix them, though. 71 | There are some things which just will not work with any sync, e. g. conflicting file changes. I strongly advice you to only change one side of each synced save file. In other words, don't play _Chrono Trigger_ on you RetroPie and on your PC simultaneously and expect to keep both save slots intact... 72 | 73 | ## This is great! How can I thank you? 74 | 75 | First of all: You don't have to. I made this script for myself first of all. I'm happy already if someone else can use it. I only ask you to report any problems or feature requests here. 76 | 77 | If you _really_ want to thank me, you could use this [DropBox referral link](https://db.tt/9AcbUWny) to create your account there. This will give us both 500 MiB extra (on top of the default 2 GiB) when you install the DropBox client. That will be enough for a good number of save files... ;-) 78 | 79 | ## Sources 80 | 81 | These are the sites I used as source: 82 | * https://rclone.org/dropbox/ 83 | * https://rclone.org/commands/rclone_copy/ 84 | * https://rclone.org/filtering/ 85 | * https://github.com/RetroPie/RetroPie-Setup/wiki/Runcommand#runcommand-onstart-and-runcommand-onend-scripts 86 | * https://github.com/AndrewFromMelbourne/raspidmx 87 | * https://www.zeroboy.eu/tutorial-gbzbatterymonitor/ -------------------------------------------------------------------------------- /rclone_script-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # define colors for output 5 | NORMAL="\Zn" 6 | BLACK="\Z0" 7 | RED="\Z1" 8 | GREEN="\Z2" 9 | YELLOW="\Z3\Zb" 10 | BLUE="\Z4" 11 | MAGENTA="\Z5" 12 | CYAN="\Z6" 13 | WHITE="\Z7" 14 | BOLD="\Zb" 15 | REVERSE="\Zr" 16 | UNDERLINE="\Zu" 17 | 18 | 19 | # global variables 20 | url="https://raw.githubusercontent.com/Jandalf81/rclone_script" 21 | branch="master" 22 | 23 | # configuration variables 24 | remotebasedir="" 25 | shownotifications="" 26 | 27 | backtitle="RCLONE_SCRIPT installer (https://github.com/Jandalf81/rclone_script)" 28 | logfile=~/scripts/rclone_script/rclone_script-install.log 29 | 30 | 31 | ################## 32 | # WELCOME DIALOG # 33 | ################## 34 | dialog \ 35 | --backtitle "${backtitle}" \ 36 | --title "Welcome" \ 37 | --colors \ 38 | --no-collapse \ 39 | --cr-wrap \ 40 | --yesno \ 41 | "\nThis script will configure RetroPie so that your savefiles and statefiles will be ${YELLOW}synchronized with a remote destination${NORMAL}. Several packages and scripts will be installed, see\n\n https://github.com/Jandalf81/rclone_script/blob/master/ReadMe.md\n\nfor a rundown. In short, any time you ${GREEN}start${NORMAL} or ${RED}stop${NORMAL} a ROM the savefiles and savestates for that ROM will be ${GREEN}down-${NORMAL} and ${RED}uploaded${NORMAL} ${GREEN}from${NORMAL} and ${RED}to${NORMAL} a remote destination. To do so, RetroPie will be configured to put all savefiles and statefiles in distinct directories, seperated from the ROMS directories. This installer will guide you through the necessary steps. If you wish to see what exactly is done at each step, open a second console and execute\n ${YELLOW}tail -f ~/scripts/rclone_script/rclone_script-install.log${NORMAL}\n\nIf you already have some savefiles in the ROMS directory, you will need to ${YELLOW}move them manually${NORMAL} after installation. You can use the new network share\n ${YELLOW}\\\\$(hostname)\\saves${NORMAL}\nfor this.\n\nAre you sure you wish to continue?" \ 42 | 26 90 2>&1 > /dev/tty \ 43 | || exit 44 | 45 | 46 | #################### 47 | # DIALOG FUNCTIONS # 48 | #################### 49 | 50 | # Warn the user if they are using the BETA branch 51 | function dialogBetaWarning () 52 | { 53 | dialog \ 54 | --backtitle "${backtitle}" \ 55 | --title "Beta Warning" \ 56 | --colors \ 57 | --no-collapse \ 58 | --cr-wrap \ 59 | --yesno \ 60 | "\n${RED}${UNDERLINE}WARNING!${NORMAL}\n\nYou are about to install a beta version!\nAre you ${RED}REALLY${NORMAL} sure you want to continue?" \ 61 | 10 50 2>&1 > /dev/tty \ 62 | || exit 63 | } 64 | 65 | # Build progress from array $STEPS() 66 | # INPUT 67 | # $steps() 68 | # OUTPUT 69 | # $progress 70 | function buildProgress () 71 | { 72 | progress="" 73 | 74 | for ((i=0; i<=${#steps[*]}; i++)) 75 | do 76 | progress="${progress}${steps[i]}\n" 77 | done 78 | } 79 | 80 | # Show Progress dialog 81 | # INPUT 82 | # 1 > Percentage to show in dialog 83 | # $backtitle 84 | # $progress 85 | function dialogShowProgress () 86 | { 87 | local percent="$1" 88 | 89 | buildProgress 90 | 91 | clear 92 | 93 | echo "${percent}" | dialog \ 94 | --stdout \ 95 | --colors \ 96 | --no-collapse \ 97 | --cr-wrap \ 98 | --backtitle "${backtitle}" \ 99 | --title "Installer" \ 100 | --gauge "${progress}" 36 90 0 \ 101 | 2>&1 > /dev/tty 102 | 103 | sleep 1 104 | } 105 | 106 | # Show summary dialog 107 | function dialogShowSummary () 108 | { 109 | # list all remotes and their type 110 | remotes=$(rclone listremotes -l) 111 | 112 | # get line with RETROPIE remote 113 | retval=$(grep -i "^retropie:" <<< ${remotes}) 114 | 115 | remoteType="${retval#*:}" 116 | remoteType=$(echo ${remoteType} | xargs) 117 | 118 | dialog \ 119 | --backtitle "${backtitle}" \ 120 | --title "Summary" \ 121 | --colors \ 122 | --no-collapse \ 123 | --cr-wrap \ 124 | --yesno \ 125 | "\n${GREEN}All done!${NORMAL}\n\nFrom now on, all your saves and states will be synchronized each time you start or stop a ROM.\n\nAll systems will put their saves and states in\n Local: \"${YELLOW}~/RetroPie/saves/${NORMAL}\"\n Remote: \"${YELLOW}retropie:${remotebasedir}/${NORMAL}\" (${remoteType})\nIf you already have some saves in the ROM directories, you need to move them there manually now! You can use the new network share\n ${YELLOW}\\\\$(hostname)\\saves${NORMAL}\nfor this. Afterward, you should ${red}reboot${NORMAL} your RetroPie. Then, you should start a full sync via\n ${YELLOW}RetroPie / RCLONE_SCRIPT menu / 1 Full sync${NORMAL}\n\nStart\n ${YELLOW}RetroPie / RCLONE_SCRIPT menu / 9 uninstall${NORMAL}\nto revert all changes and remove this script.\n\nTo finish the installer you should reboot your RetroPie now.\n\n${RED}Reboot RetroPie now?${NORMAL}" \ 126 | 28 90 2>&1 > /dev/tty 127 | 128 | case $? in 129 | 0) sudo shutdown -r now ;; 130 | esac 131 | } 132 | 133 | 134 | ################## 135 | # STEP FUNCTIONS # 136 | ################## 137 | 138 | 139 | # Initialize array $STEPS() 140 | # OUTPUT 141 | # $steps() 142 | function initSteps () 143 | { 144 | steps[1]="1. RCLONE" 145 | steps[2]=" 1a. Test for RCLONE binary [ waiting... ]" 146 | steps[3]=" 1b. Download RCLONE binary [ waiting... ]" 147 | steps[4]=" 1c. Test RCLONE remote [ waiting... ]" 148 | steps[5]=" 1d. Create RCLONE remote [ waiting... ]" 149 | steps[6]="2. PNGVIEW" 150 | steps[7]=" 2a. Test for PNGVIEW binary [ waiting... ]" 151 | steps[8]=" 2b. Download PNGVIEW source [ waiting... ]" 152 | steps[9]=" 2c. Compile PNGVIEW [ waiting... ]" 153 | steps[10]="3. IMAGEMAGICK" 154 | steps[11]=" 3a. Test for IMAGEMAGICK [ waiting... ]" 155 | steps[12]=" 3b. apt-get install IMAGEMAGICK [ waiting... ]" 156 | steps[13]="4. RCLONE_SCRIPT" 157 | steps[14]=" 4a. Download RCLONE_SCRIPT files [ waiting... ]" 158 | steps[15]=" 4b. Create RCLONE_SCRIPT menu item [ waiting... ]" 159 | steps[16]=" 4c. Configure RCLONE_SCRIPT [ waiting... ]" 160 | steps[17]="5. RUNCOMMAND" 161 | steps[18]=" 5a. Add call to RUNCOMMAND-ONSTART [ waiting... ]" 162 | steps[19]=" 5b. Add call to RUNCOMMAND-ONEND [ waiting... ]" 163 | steps[20]="6. Local SAVEFILE directory" 164 | steps[21]=" 6a. Check local base directory [ waiting... ]" 165 | steps[22]=" 6b. Check local directories [ waiting... ]" 166 | steps[23]="7. Remote SAVEFILE directory" 167 | steps[24]=" 7a. Check remote base directory [ waiting... ]" 168 | steps[25]=" 7b. Check remote directories [ waiting... ]" 169 | steps[26]="8. Configure RETROARCH" 170 | steps[27]=" 8a. Set local SAVEFILE directories [ waiting... ]" 171 | steps[28]="9. Finalizing" 172 | steps[29]=" 9a. Save configuration [ waiting... ]" 173 | } 174 | 175 | # Update item of $STEPS() and show updated progress dialog 176 | # INPUT 177 | # 1 > Number of step to update 178 | # 2 > New status for step 179 | # 3 > Percentage to show in progress dialog 180 | # $steps() 181 | # OUTPUT 182 | # $steps() 183 | function updateStep () 184 | { 185 | local step="$1" 186 | local newStatus="$2" 187 | local percent="$3" 188 | local oldline 189 | local newline 190 | 191 | # translate and colorize $NEWSTATUS 192 | case "${newStatus}" in 193 | "waiting") newStatus="[ ${NORMAL}WAITING...${NORMAL} ]" ;; 194 | "in progress") newStatus="[ ${NORMAL}IN PROGRESS${NORMAL} ]" ;; 195 | "done") newStatus="[ ${GREEN}DONE${NORMAL} ]" ;; 196 | "found") newStatus="[ ${GREEN}FOUND${NORMAL} ]" ;; 197 | "not found") newStatus="[ ${RED}NOT FOUND${NORMAL} ]" ;; 198 | "created") newStatus="[ ${GREEN}CREATED${NORMAL} ]" ;; 199 | "failed") newStatus="[ ${RED}FAILED${NORMAL} ]" ;; 200 | "skipped") newStatus="[ ${YELLOW}SKIPPED${NORMAL} ]" ;; 201 | *) newStatus="[ ${RED}UNDEFINED${NORMAL} ]" ;; 202 | esac 203 | 204 | # search $STEP in $STEPS 205 | for ((i=0; i<${#steps[*]}; i++)) 206 | do 207 | if [[ ${steps[i]} =~ .*$step.* ]] 208 | then 209 | # update $STEP with $NEWSTATUS 210 | oldline="${steps[i]}" 211 | oldline="${oldline%%[*}" 212 | newline="${oldline}${newStatus}" 213 | steps[i]="${newline}" 214 | 215 | break 216 | fi 217 | done 218 | 219 | # show progress dialog 220 | dialogShowProgress ${percent} 221 | } 222 | 223 | 224 | ####################### 225 | # INSTALLER FUNCTIONS # 226 | ####################### 227 | 228 | 229 | # Installer 230 | function installer () 231 | { 232 | initSteps 233 | dialogShowProgress 0 234 | 235 | 1RCLONE 236 | 2PNGVIEW 237 | 3IMAGEMAGICK 238 | 4RCLONE_SCRIPT 239 | 5RUNCOMMAND 240 | 6LocalSAVEFILEDirectory 241 | 7RemoteSAVEFILEDirectory 242 | 8ConfigureRETROARCH 243 | 9Finalize 244 | 245 | dialogShowSummary 246 | } 247 | 248 | function 1RCLONE () 249 | { 250 | # 1a. Testing for RCLONE binary 251 | updateStep "1a" "in progress" 0 252 | 253 | 1aTestRCLONE 254 | if [[ $? -eq 0 ]] 255 | then 256 | updateStep "1a" "found" 5 257 | updateStep "1b" "skipped" 10 258 | else 259 | updateStep "1a" "not found" 5 260 | 261 | # 1b. Getting RCLONE binary 262 | updateStep "1b" "in progress" 5 263 | 264 | 1bInstallRCLONE 265 | if [[ $? -eq 0 ]] 266 | then 267 | updateStep "1b" "done" 10 268 | else 269 | updateStep "1b" "failed" 5 270 | exit 271 | fi 272 | fi 273 | 274 | # 1c. Testing RCLONE configuration 275 | updateStep "1c" "in progress" 10 276 | 277 | 1cTestRCLONEremote 278 | if [[ $? -eq 0 ]] 279 | then 280 | updateStep "1c" "found" 15 281 | updateStep "1d" "skipped" 20 282 | else 283 | updateStep "1c" "not found" 15 284 | 285 | # 1d. Create RCLONE remote 286 | updateStep "1d" "in progress" 15 287 | 1dCreateRCLONEremote 288 | updateStep "1d" "done" 20 289 | fi 290 | } 291 | 292 | # Checks if RCLONE is installed 293 | # RETURN 294 | # 0 > RCLONE is installed 295 | # 1 > RCLONE is not installed 296 | function 1aTestRCLONE () 297 | { 298 | printf "$(date +%FT%T%:z):\t1aTestRCLONE\tSTART\n" >> "${logfile}" 299 | 300 | if [ -f /usr/bin/rclone ] 301 | then 302 | printf "$(date +%FT%T%:z):\t1aTestRCLONE\tFOUND\n" >> "${logfile}" 303 | return 0 304 | else 305 | printf "$(date +%FT%T%:z):\t1aTestRCLONE\tNOT FOUND\n" >> "${logfile}" 306 | return 1 307 | fi 308 | } 309 | 310 | # Installs RCLONE by download 311 | # RETURN 312 | # 0 > RCLONE has been installed 313 | # 1 > Error while installing RCLONE 314 | function 1bInstallRCLONE () 315 | { 316 | printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tSTART\n" >> "${logfile}" 317 | 318 | # TODO get RCLONE for 64bit 319 | { # try 320 | # get binary 321 | wget -P ~ https://downloads.rclone.org/rclone-current-linux-arm.zip --append-output="${logfile}" && 322 | unzip ~/rclone-current-linux-arm.zip -d ~ >> "${logfile}" && 323 | 324 | cd ~/rclone-v* && 325 | 326 | # move binary 327 | sudo mv rclone /usr/bin >> "${logfile}" && 328 | sudo chown root:root /usr/bin/rclone >> "${logfile}" && 329 | sudo chmod 755 /usr/bin/rclone >> "${logfile}" && 330 | 331 | cd ~ && 332 | 333 | # remove temp files 334 | rm ~/rclone-current-linux-arm.zip >> "${logfile}" && 335 | rm -r ~/rclone-v* >> "${logfile}" && 336 | 337 | printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tDONE\n" >> "${logfile}" && 338 | 339 | return 0 340 | } || { #catch 341 | printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tERROR\n" >> "${logfile}" && 342 | 343 | # remove temp files 344 | rm ~/rclone-current-linux-arm.zip >> "${logfile}" && 345 | rm -r ~/rclone-v* >> "${logfile}" && 346 | 347 | return 1 348 | } 349 | } 350 | 351 | # Checks if there's a RCLONE remote called RETROPIE 352 | # RETURN 353 | # 0 > remote RETROPIE has been found 354 | # 1 > no remote RETROPIE found 355 | function 1cTestRCLONEremote () 356 | { 357 | printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tSTART\n" >> "${logfile}" 358 | 359 | local remotes=$(rclone listremotes) 360 | 361 | local retval=$(grep -i "^retropie:" <<< ${remotes}) 362 | 363 | if [ "${retval}" == "retropie:" ] 364 | then 365 | printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tFOUND\n" >> "${logfile}" 366 | return 0 367 | else 368 | printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tNOT FOUND\n" >> "${logfile}" 369 | return 1 370 | fi 371 | } 372 | 373 | # Tells the user to create a new RCLONE remote called RETROPIE 374 | # RETURN 375 | # 0 > remote RETROPIE has been created (no other OUTPUT possible) 376 | function 1dCreateRCLONEremote () 377 | { 378 | printf "$(date +%FT%T%:z):\t1dCreateRCLONEremote\tSTART\n" >> "${logfile}" 379 | 380 | dialog \ 381 | --stdout \ 382 | --colors \ 383 | --no-collapse \ 384 | --cr-wrap \ 385 | --backtitle "${backtitle}" \ 386 | --title "Installer" \ 387 | --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 \ 388 | 2>&1 > /dev/tty 389 | 390 | clear 391 | rclone config 392 | 393 | 1cTestRCLONEremote 394 | if [[ $? -eq 1 ]] 395 | then 396 | dialog \ 397 | --stdout \ 398 | --colors \ 399 | --no-collapse \ 400 | --cr-wrap \ 401 | --backtitle "${backtitle}" \ 402 | --title "Installer" \ 403 | --msgbox "\nNo remote ${RED}retropie${NORMAL} found.\nPlease try again." 20 50 \ 404 | 2>&1 > /dev/tty 405 | 406 | 1dCreateRCLONEremote 407 | else 408 | printf "$(date +%FT%T%:z):\t1dCreateRCLONEremote\tFOUND\n" >> "${logfile}" 409 | return 0 410 | fi 411 | } 412 | 413 | function 2PNGVIEW () 414 | { 415 | # 2a. Testing for PNGVIEW binary 416 | updateStep "2a" "in progress" 20 417 | 418 | 2aTestPNGVIEW 419 | if [[ $? -eq 0 ]] 420 | then 421 | updateStep "2a" "found" 25 422 | updateStep "2b" "skipped" 30 423 | updateStep "2c" "skipped" 35 424 | else 425 | updateStep "2a" "not found" 25 426 | 427 | # 2b. Getting PNGVIEW source 428 | updateStep "2b" "in progress" 25 429 | 430 | 2bGetPNGVIEWsource 431 | if [[ $? -eq 0 ]] 432 | then 433 | updateStep "2b" "done" 30 434 | 435 | # 2c. Compiling PNGVIEW 436 | updateStep "2c" "in progress" 30 437 | 438 | 2cCompilePNGVIEW 439 | if [[ $? -eq 0 ]] 440 | then 441 | updateStep "2c" "done" 35 442 | else 443 | updateStep "2c" "failed" 30 444 | exit 445 | fi 446 | else 447 | updateStep "2b" "failed" 25 448 | exit 449 | fi 450 | fi 451 | } 452 | 453 | # Checks if PNGVIEW is installed 454 | # RETURN 455 | # 0 > PNGVIEW is installed 456 | # 1 > PNGVIEW is not installed 457 | function 2aTestPNGVIEW () 458 | { 459 | printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tSTART\n" >> "${logfile}" 460 | 461 | if [ -f /usr/bin/pngview ] 462 | then 463 | printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tFOUND\n" >> "${logfile}" 464 | return 0 465 | else 466 | printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tNOT FOUND\n" >> "${logfile}" 467 | return 1 468 | fi 469 | } 470 | 471 | # Gets PNGVIEW source 472 | # RETURN 473 | # 0 > source downloaded and unzipped 474 | # 1 > no source downloaded, removed temp files 475 | function 2bGetPNGVIEWsource () 476 | { 477 | printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tSTART\n" >> "${logfile}" 478 | 479 | { #try 480 | wget -P ~ https://github.com/AndrewFromMelbourne/raspidmx/archive/master.zip --append-output="${logfile}" && 481 | unzip ~/master.zip -d ~ >> "${logfile}" && 482 | 483 | printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tDONE\n" >> "${logfile}" && 484 | 485 | return 0 486 | } || { #catch 487 | printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tERROR\n" >> "${logfile}" && 488 | 489 | rm ~/master.zip >> "${logfile}" && 490 | sudo rm -r ~/raspidmx-master >> "${logfile}" && 491 | 492 | return 1 493 | } 494 | } 495 | 496 | # Compiles PNGVIEW source, moves binaries 497 | # RETURN 498 | # 0 > compiled without errors, moved binaries, removed temp files 499 | # 1 > errors while compiling, removed temp files 500 | function 2cCompilePNGVIEW () 501 | { 502 | printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tSTART\n" >> "${logfile}" 503 | 504 | { #try 505 | # compile 506 | # cd ~/raspidmx-master && 507 | make --directory=~/raspidmx-master >> "${logfile}" && 508 | 509 | # move binary files 510 | sudo mv ~/raspidmx-master/pngview/pngview /usr/bin >> "${logfile}" && 511 | sudo mv ~/raspidmx-master/lib/libraspidmx.so.1 /usr/lib >> "${logfile}" && 512 | sudo chown root:root /usr/bin/pngview >> "${logfile}" && 513 | sudo chmod 755 /usr/bin/pngview >> "${logfile}" && 514 | 515 | # remove temp files 516 | rm ~/master.zip >> "${logfile}" && 517 | sudo rm -r ~/raspidmx-master >> "${logfile}" && 518 | 519 | printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tDONE\n" >> "${logfile}" && 520 | 521 | return 0 522 | } || { #catch 523 | printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tERROR\n" >> "${logfile}" && 524 | 525 | # remove temp files 526 | rm ~/master.zip >> "${logfile}" && 527 | sudo rm -r ~/raspidmx-master >> "${logfile}" && 528 | 529 | return 1 530 | } 531 | } 532 | 533 | function 3IMAGEMAGICK () 534 | { 535 | # 3a. Testing for IMAGEMAGICK 536 | updateStep "3a" "in progress" 35 537 | 538 | 3aTestIMAGEMAGICK 539 | if [[ $? -eq 0 ]] 540 | then 541 | updateStep "3a" "found" 40 542 | updateStep "3b" "skipped" 45 543 | else 544 | updateStep "3a" "not found" 40 545 | 546 | # 3b. Getting IMAGEMAGICK 547 | updateStep "3b" "in progress" 40 548 | 3bInstallIMAGEMAGICK 549 | if [[ $? -eq 0 ]] 550 | then 551 | updateStep "3b" "done" 45 552 | else 553 | updateStep "3b" "failed" 40 554 | fi 555 | fi 556 | } 557 | 558 | # Checks is IMAGEMAGICK is installed 559 | # RETURN 560 | # 0 > IMAGEMAGICK is installed 561 | # 1 > IMAGEMAGICK is not installed 562 | function 3aTestIMAGEMAGICK () 563 | { 564 | printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tSTART\n" >> "${logfile}" 565 | 566 | if [ -f /usr/bin/convert ] 567 | then 568 | printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tFOUND\n" >> "${logfile}" 569 | return 0 570 | else 571 | printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tNOT FOUND\n" >> "${logfile}" 572 | return 1 573 | fi 574 | } 575 | 576 | # Installs IMAGEMAGICK via APT-GET 577 | # RETURN 578 | # 0 > IMAGEMAGICK has been installed 579 | # 1 > Error while installing IMAGEMAGICK 580 | function 3bInstallIMAGEMAGICK () 581 | { 582 | printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tSTART\n" >> "${logfile}" 583 | 584 | sudo apt-get update >> "${logfile}" 585 | sudo apt-get --yes install imagemagick >> "${logfile}" 586 | 587 | if [[ $? -eq 0 ]] 588 | then 589 | printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tDONE\n" >> "${logfile}" 590 | return 0 591 | else 592 | printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tERROR\n" >> "${logfile}" 593 | return 1 594 | fi 595 | } 596 | 597 | function 4RCLONE_SCRIPT () 598 | { 599 | # 4a. Getting RCLONE_SCRIPT 600 | updateStep "4a" "in progress" 45 601 | 602 | 4aGetRCLONE_SCRIPT 603 | if [[ $? -eq 0 ]] 604 | then 605 | updateStep "4a" "done" 50 606 | else 607 | updateStep "4a" "failed" 45 608 | exit 609 | fi 610 | 611 | # 4b. Creating RCLONE_SCRIPT menu item 612 | updateStep "4b" "in progress" 50 613 | 614 | 4bCreateRCLONE_SCRIPTMenuItem 615 | if [[ $? -eq 0 ]] 616 | then 617 | updateStep "4b" "done" 55 618 | else 619 | updateStep "4b" "failed" 50 620 | exit 621 | fi 622 | 623 | # 4c. Configure RCLONE_SCRIPT 624 | updateStep "4c" "in progress" 55 625 | 626 | 4cConfigureRCLONE_SCRIPT 627 | 628 | updateStep "4c" "done" 60 629 | } 630 | 631 | # Gets RCLONE_SCRIPT 632 | # RETURN 633 | # 0 > downloaded successfully 634 | # 1 > errors while downloading 635 | function 4aGetRCLONE_SCRIPT () 636 | { 637 | printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tSTART\n" >> "${logfile}" 638 | 639 | # create directory if necessary 640 | if [ ! -d ~/scripts/rclone_script ] 641 | then 642 | mkdir ~/scripts/rclone_script >> "${logfile}" 643 | fi 644 | 645 | { #try 646 | # get script files 647 | wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script.sh --append-output="${logfile}" && 648 | wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script-menu.sh --append-output="${logfile}" && 649 | wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script-uninstall.sh --append-output="${logfile}" && 650 | 651 | # change mod 652 | chmod +x ~/scripts/rclone_script/rclone_script.sh >> "${logfile}" && 653 | chmod +x ~/scripts/rclone_script/rclone_script-menu.sh >> "${logfile}" && 654 | chmod +x ~/scripts/rclone_script/rclone_script-uninstall.sh >> "${logfile}" && 655 | 656 | printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tDONE\n" >> "${logfile}" && 657 | 658 | return 0 659 | } || { # catch 660 | printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tERROR\n" >> "${logfile}" && 661 | 662 | return 1 663 | } 664 | } 665 | 666 | # Creates a menu item for RCLONE_SCRIPT in RetroPie menu 667 | # RETURN 668 | # 0 > menu item has been found or created 669 | # 1 > error while creating menu item 670 | function 4bCreateRCLONE_SCRIPTMenuItem () 671 | { 672 | printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tSTART\n" >> "${logfile}" 673 | 674 | # create redirect script 675 | printf "#!/bin/bash\n~/scripts/rclone_script/rclone_script-menu.sh" > ~/RetroPie/retropiemenu/rclone_script-redirect.sh 676 | chmod +x ~/RetroPie/retropiemenu/rclone_script-redirect.sh 677 | 678 | # check if menu item exists 679 | if [[ $(xmlstarlet sel -t -v "count(/gameList/game[path='./rclone_script-redirect.sh'])" ~/.emulationstation/gamelists/retropie/gamelist.xml) -eq 0 ]] 680 | then 681 | printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tNOT FOUND\n" >> "${logfile}" 682 | 683 | xmlstarlet ed \ 684 | --inplace \ 685 | --subnode "/gameList" --type elem -n game -v "" \ 686 | --subnode "/gameList/game[last()]" --type elem -n path -v "./rclone_script-redirect.sh" \ 687 | --subnode "/gameList/game[last()]" --type elem -n name -v "RCLONE_SCRIPT menu" \ 688 | --subnode "/gameList/game[last()]" --type elem -n desc -v "Launches a menu allowing you to start a full sync, configure RCLONE_SCRIPT or even uninstall it" \ 689 | ~/.emulationstation/gamelists/retropie/gamelist.xml 690 | 691 | if [[ $? -eq 0 ]] 692 | then 693 | printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tCREATED\n" >> "${logfile}" 694 | return 0 695 | else 696 | printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tERROR\n" >> "${logfile}" 697 | return 1 698 | fi 699 | else 700 | printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tFOUND\n" >> "${logfile}" 701 | return 0 702 | fi 703 | } 704 | 705 | # Gets user input to configure RCLONE_SCRIPT 706 | function 4cConfigureRCLONE_SCRIPT () 707 | { 708 | printf "$(date +%FT%T%:z):\t4cConfigureRCLONE_SCRIPT\tSTART\n" >> "${logfile}" 709 | 710 | remotebasedir=$(dialog \ 711 | --stdout \ 712 | --colors \ 713 | --no-collapse \ 714 | --cr-wrap \ 715 | --no-cancel \ 716 | --backtitle "${backtitle}" \ 717 | --title "Remote base directory" \ 718 | --inputbox "\nPlease name the directory which will be used as your ${YELLOW}remote base directory${NORMAL}. If necessary, this directory will be created.\n\nExamples:\n* RetroArch\n* mySaves/RetroArch\n\n" 18 40 "RetroArch" 719 | ) 720 | 721 | dialog \ 722 | --stdout \ 723 | --colors \ 724 | --no-collapse \ 725 | --cr-wrap \ 726 | --backtitle "${backtitle}" \ 727 | --title "Notifications" \ 728 | --yesno "\nDo you wish to see ${YELLOW}notifications${NORMAL} whenever RCLONE_SCRIPT is synchronizing?" 18 40 729 | 730 | case $? in 731 | 0) shownotifications="TRUE" ;; 732 | 1) shownotifications="FALSE" ;; 733 | *) shownotifications="FALSE" ;; 734 | esac 735 | 736 | choice=$(dialog \ 737 | --stdout \ 738 | --colors \ 739 | --no-collapse \ 740 | --cr-wrap \ 741 | --backtitle "${backtitle}" \ 742 | --title "Needed connection" \ 743 | --ok-label "Select" \ 744 | --no-cancel \ 745 | --menu "\nPlease select which type of connection will be needed for your configured remote" 20 50 5 \ 746 | 0 "Internet access" \ 747 | 1 "LAN / WLAN connection only" 748 | ) 749 | 750 | neededConnection=${choice} 751 | 752 | printf "$(date +%FT%T%:z):\t4cConfigureRCLONE_SCRIPT\tDONE\n" >> "${logfile}" 753 | } 754 | 755 | function 5RUNCOMMAND () 756 | { 757 | # 5a. RUNCOMMAND-ONSTART 758 | updateStep "5a" "in progress" 60 759 | 760 | 5aRUNCOMMAND-ONSTART 761 | case $? in 762 | 0) updateStep "5a" "found" 65 ;; 763 | 1) updateStep "5a" "created" 65 ;; 764 | esac 765 | 766 | # 5b. RUNCOMMAND-ONEND 767 | updateStep "5b" "in progress" 65 768 | 769 | 5aRUNCOMMAND-ONEND 770 | case $? in 771 | 0) updateStep "5b" "found" 70 ;; 772 | 1) updateStep "5b" "created" 70 ;; 773 | esac 774 | } 775 | 776 | # Checks call of RCLONE_SCRIPT by RUNCOMMAND-ONSTART 777 | # RETURNS 778 | # 0 > call found 779 | # 1 > call created 780 | function 5aRUNCOMMAND-ONSTART () 781 | { 782 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tSTART\n" >> "${logfile}" 783 | 784 | # check if RUNCOMMAND-ONSTART.sh exists 785 | if [ -f /opt/retropie/configs/all/runcommand-onstart.sh ] 786 | then 787 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tFILE FOUND\n" >> "${logfile}" 788 | 789 | # check if there's a call to RCLONE_SCRIPT 790 | if grep -Fq "~/scripts/rclone_script/rclone_script.sh" /opt/retropie/configs/all/runcommand-onstart.sh 791 | then 792 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tCALL FOUND\n" >> "${logfile}" 793 | 794 | return 0 795 | else 796 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tCALL NOT FOUND\n" >> "${logfile}" 797 | 798 | # add call 799 | printf "\n~/scripts/rclone_script/rclone_script.sh \"down\" \"\$1\" \"\$2\" \"\$3\" \"\$4\"\n" >> /opt/retropie/configs/all/runcommand-onstart.sh 800 | 801 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tCALL CREATED\n" >> "${logfile}" 802 | 803 | return 1 804 | fi 805 | else 806 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tFILE NOT FOUND\n" >> "${logfile}" 807 | 808 | printf "#!/bin/bash\n~/scripts/rclone_script/rclone_script.sh \"down\" \"\$1\" \"\$2\" \"\$3\" \"\$4\"\n" > /opt/retropie/configs/all/runcommand-onstart.sh 809 | 810 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tFILE CREATED\n" >> "${logfile}" 811 | 812 | return 1 813 | fi 814 | } 815 | 816 | # Checks call of RCLONE_SCRIPT by RUNCOMMAND-ONEND 817 | # RETURNS 818 | # 0 > call found 819 | # 1 > call created 820 | function 5aRUNCOMMAND-ONEND () 821 | { 822 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tSTART\n" >> "${logfile}" 823 | 824 | # check if RUNCOMMAND-ONEND.sh exists 825 | if [ -f /opt/retropie/configs/all/runcommand-onend.sh ] 826 | then 827 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tFILE FOUND\n" >> "${logfile}" 828 | 829 | # check if there's a call to RCLONE_SCRIPT 830 | if grep -Fq "~/scripts/rclone_script/rclone_script.sh" /opt/retropie/configs/all/runcommand-onend.sh 831 | then 832 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tCALL FOUND\n" >> "${logfile}" 833 | 834 | return 0 835 | else 836 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tCALL NOT FOUND\n" >> "${logfile}" 837 | 838 | # add call 839 | printf "\n~/scripts/rclone_script/rclone_script.sh \"up\" \"\$1\" \"\$2\" \"\$3\" \"\$4\"\n" >> /opt/retropie/configs/all/runcommand-onend.sh 840 | 841 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tCALL CREATED\n" >> "${logfile}" 842 | 843 | return 1 844 | fi 845 | else 846 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tFILE NOT FOUND\n" >> "${logfile}" 847 | 848 | printf "#!/bin/bash\n~/scripts/rclone_script/rclone_script.sh \"up\" \"\$1\" \"\$2\" \"\$3\" \"\$4\"\n" >> /opt/retropie/configs/all/runcommand-onend.sh 849 | 850 | printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tFILE CREATED\n" >> "${logfile}" 851 | 852 | return 1 853 | fi 854 | } 855 | 856 | function 6LocalSAVEFILEDirectory () 857 | { 858 | # 6a. Test for local SAVEFILE directory 859 | updateStep "6a" "in progress" 70 860 | 861 | 6aCheckLocalBaseDirectory 862 | case $? in 863 | 0) updateStep "6a" "found" 75 ;; 864 | 1) updateStep "6a" "created" 75 ;; 865 | esac 866 | 867 | # 6b. Check local directories 868 | updateStep "6b" "in progress" 75 869 | 870 | 6bCheckLocalSystemDirectories 871 | case $? in 872 | 0) updateStep "6b" "found" 80 ;; 873 | 1) updateStep "6b" "created" 80 ;; 874 | esac 875 | } 876 | 877 | # Checks if the local base SAVEFILE directory exists 878 | # RETURN 879 | # 0 > directory exists 880 | # 1 > directory has been created 881 | function 6aCheckLocalBaseDirectory () 882 | { 883 | printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tSTART\n" >> "${logfile}" 884 | 885 | # check if local base dir exists 886 | if [ -d ~/RetroPie/saves ] 887 | then 888 | printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tFOUND\n" >> "${logfile}" 889 | 890 | return 0 891 | else 892 | printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tNOT FOUND\n" >> "${logfile}" 893 | 894 | mkdir ~/RetroPie/saves 895 | printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tCREATED directory\n" >> "${logfile}" 896 | 897 | # share that new directory on the network 898 | if [[ $(grep -c "\[saves\]" /etc/samba/smb.conf) -eq 0 ]] 899 | then 900 | # add new share to SAMBA 901 | printf "[saves]\ncomment = saves\npath = \"/home/pi/RetroPie/saves\"\nwritable = yes\nguest ok = yes\ncreate mask = 0644\ndirectory mask = 0755\nforce user = pi\n" | sudo tee --append /etc/samba/smb.conf | cat > /dev/null 902 | 903 | # restart SAMBA 904 | sudo service smbd restart 905 | 906 | printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tCREATED network share\n" >> "${logfile}" 907 | fi 908 | 909 | return 1 910 | fi 911 | } 912 | 913 | # Checks if the local system specific directories exists 914 | # RETURN 915 | # 0 > all found 916 | # 1 > created at least one 917 | function 6bCheckLocalSystemDirectories () 918 | { 919 | printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tSTART\n" >> "${logfile}" 920 | local retval=0 921 | 922 | # for each directory in ROMS directory... 923 | for directory in ~/RetroPie/roms/* 924 | do 925 | system="${directory##*/}" 926 | 927 | # check if ROMS directory is a real directory and not a SymLink 928 | if [ ! -L ~/RetroPie/roms/${system} ] 929 | then 930 | # check if same directory exists in SAVES, create if necessary 931 | if [ -d ~/RetroPie/saves/${system} ] 932 | then 933 | printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tFOUND directory ${system}\n" >> "${logfile}" 934 | else 935 | mkdir ~/RetroPie/saves/${system} 936 | printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tCREATED directory ${system}\n" >> "${logfile}" 937 | retval=1 938 | fi 939 | else 940 | # check if same SymLink exists in SAVES, create if necessary 941 | if [ -L ~/RetroPie/saves/${system} ] 942 | then 943 | printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tFOUND symlink ${system}\n" >> "${logfile}" 944 | else 945 | ln -s $(readlink ~/RetroPie/roms/${system}) ~/RetroPie/saves/${system} 946 | 947 | printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tCREATED symlink ${system}\n" >> "${logfile}" 948 | retval=1 949 | fi 950 | fi 951 | done 952 | 953 | return ${retval} 954 | } 955 | 956 | function 7RemoteSAVEFILEDirectory () 957 | { 958 | # 7a. Check remote base directory 959 | updateStep "7a" "in progress" 80 960 | 961 | 7aCheckRemoteBaseDirectory 962 | case $? in 963 | 0) updateStep "7a" "found" 85 ;; 964 | 1) updateStep "7a" "created" 85 ;; 965 | 255) updateStep "7a" "failed" 80 ;; 966 | esac 967 | 968 | # 7b. Check remote directories 969 | updateStep "7b" "in progress" 85 970 | 971 | 7bCheckRemoteSystemDirectories 972 | case $? in 973 | 0) updateStep "7b" "found" 90 ;; 974 | 1) updateStep "7b" "created" 90 ;; 975 | 255) updateStep "7b" "failed" 85 ;; 976 | esac 977 | } 978 | 979 | # Checks if the remote base SAVEFILE directory exists 980 | # RETURN 981 | # 0 > directory exists 982 | # 1 > directory has been created 983 | # 255 > error while creating directory 984 | function 7aCheckRemoteBaseDirectory () 985 | { 986 | printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tSTART\n" >> "${logfile}" 987 | 988 | # try to read remote base dir 989 | rclone lsf "retropie:${remotebasedir}/" > /dev/null 2>&1 990 | case $? in 991 | 0) 992 | printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tFOUND\n" >> "${logfile}" 993 | return 0 994 | ;; 995 | 3) 996 | printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tNOT FOUND\n" >> "${logfile}" 997 | 998 | rclone mkdir "retropie:${remotebasedir}" >> "${logfile}" 999 | case $? in 1000 | 0) 1001 | printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tCREATED\n" >> "${logfile}" 1002 | return 1 1003 | ;; 1004 | *) 1005 | printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tERROR\n" >> "${logfile}" 1006 | return 255 1007 | ;; 1008 | esac 1009 | ;; 1010 | *) 1011 | printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tERROR\n" >> "${logfile}" 1012 | return 255 1013 | ;; 1014 | esac 1015 | } 1016 | 1017 | # Checks if the remote system specific directories exist 1018 | # RETURN 1019 | # 0 > all found 1020 | # 1 > created at least one 1021 | # 255 > error while creating directory 1022 | function 7bCheckRemoteSystemDirectories () 1023 | { 1024 | printf "$(date +%FT%T%:z):\t7bCheckRemoteSystemDirectories\tSTART\n" >> "${logfile}" 1025 | 1026 | local retval=0 1027 | local output 1028 | 1029 | # list all directories in $REMOTEBASEDIR from remote 1030 | remoteDirs=$(rclone lsf --dirs-only "retropie:${remotebasedir}/") 1031 | 1032 | # for each directory in ROMS directory... 1033 | for directory in ~/RetroPie/roms/* 1034 | do 1035 | system="${directory##*/}" 1036 | 1037 | # use grep to search $SYSTEM in $DIRECTORIES 1038 | output=$(grep "${system}/" -nx <<< "${remoteDirs}") 1039 | 1040 | if [ "${output}" = "" ] 1041 | then 1042 | # create system dir 1043 | rclone mkdir retropie:"${remotebasedir}/${system}" 1044 | 1045 | if [[ $? -eq 0 ]] 1046 | then 1047 | printf "$(date +%FT%T%:z):\t7bCheckRemoteSystemDirectories\tCREATED ${system}\n" >> "${logfile}" 1048 | 1049 | # put note if local directory is a symlink 1050 | if [ -L ~/RetroPie/saves/${system} ] 1051 | then 1052 | printf "ATTENTION\r\n\r\nThis directory will not be used! This is just a symlink.\r\nPlace your savefiles in\r\n\r\n$(readlink ~/RetroPie/roms/${system})\r\n\r\ninstead." > ~/scripts/rclone_script/readme.txt 1053 | 1054 | rclone copy ~/scripts/rclone_script/readme.txt retropie:"${remotebasedir}/${system}/" 1055 | 1056 | rm ~/scripts/rclone_script/readme.txt 1057 | fi 1058 | 1059 | retval=1 1060 | else 1061 | printf "$(date +%FT%T%:z):\t7bCheckRemoteSystemDirectories\tERROR\n" >> "${logfile}" 1062 | return 255 1063 | fi 1064 | else 1065 | printf "$(date +%FT%T%:z):\t7bCheckRemoteSystemDirectories\tFOUND ${system}\n" >> "${logfile}" 1066 | fi 1067 | done 1068 | 1069 | return ${retval} 1070 | } 1071 | 1072 | function 8ConfigureRETROARCH () 1073 | { 1074 | # 8a. Setting local SAVEFILE directory 1075 | updateStep "8a" "in progress" 90 1076 | 1077 | 8aSetLocalSAVEFILEDirectory 1078 | 1079 | updateStep "8a" "done" 95 1080 | } 1081 | 1082 | # Sets parameters in all system specific configuration files 1083 | function 8aSetLocalSAVEFILEDirectory () 1084 | { 1085 | printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tSTART\n" >> "${logfile}" 1086 | 1087 | local retval 1088 | 1089 | # for each directory... 1090 | for directory in /opt/retropie/configs/* 1091 | do 1092 | system="${directory##*/}" 1093 | 1094 | # skip directory ALL 1095 | if [ "${system}" = "all" ] 1096 | then 1097 | continue 1098 | fi 1099 | 1100 | # test if there's a RETROARCH.CFG 1101 | if [ -f "${directory}/retroarch.cfg" ] 1102 | then 1103 | printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tFOUND retroarch.cfg FOR ${system}\n" >> "${logfile}" 1104 | 1105 | # test file for SAVEFILE_DIRECTORY 1106 | retval=$(grep -i "^savefile_directory = " ${directory}/retroarch.cfg) 1107 | 1108 | if [ ! "${retval}" = "" ] 1109 | then 1110 | printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tREPLACED savefile_directory\n" >> "${logfile}" 1111 | 1112 | # replace existing parameter 1113 | sed -i "/^savefile_directory = /c\savefile_directory = \"~/RetroPie/saves/${system}\"" ${directory}/retroarch.cfg 1114 | else 1115 | printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tADDED savefile_directory\n" >> "${logfile}" 1116 | 1117 | # create new parameter above "#include..." 1118 | sed -i "/^#include \"\/opt\/retropie\/configs\/all\/retroarch.cfg\"/c\savefile_directory = \"~\/RetroPie\/saves\/${system}\"\n#include \"\/opt\/retropie\/configs\/all\/retroarch.cfg\"" ${directory}/retroarch.cfg 1119 | fi 1120 | 1121 | # test file for SAVESTATE_DIRECTORY 1122 | retval=$(grep -i "^savestate_directory = " ${directory}/retroarch.cfg) 1123 | 1124 | if [ ! "${retval}" = "" ] 1125 | then 1126 | printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tREPLACED savestate_directory\n" >> "${logfile}" 1127 | 1128 | # replace existing parameter 1129 | sed -i "/^savestate_directory = /c\savestate_directory = \"~/RetroPie/saves/${system}\"" ${directory}/retroarch.cfg 1130 | else 1131 | printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tADDED savestate_directory\n" >> "${logfile}" 1132 | 1133 | # create new parameter above "#include..." 1134 | sed -i "/^#include \"\/opt\/retropie\/configs\/all\/retroarch.cfg\"/c\savestate_directory = \"~\/RetroPie\/saves\/${system}\"\n#include \"\/opt\/retropie\/configs\/all\/retroarch.cfg\"" ${directory}/retroarch.cfg 1135 | fi 1136 | 1137 | fi 1138 | done 1139 | 1140 | printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tDONE\n" >> "${logfile}" 1141 | } 1142 | 1143 | function 9Finalize () 1144 | { 1145 | # 9a. Saving configuration 1146 | updateStep "9a" "in progress" 95 1147 | 1148 | 9aSaveConfiguration 1149 | 1150 | updateStep "9a" "done" 100 1151 | } 1152 | 1153 | # Saves the configuration of RCLONE_SCRIPT 1154 | function 9aSaveConfiguration () 1155 | { 1156 | printf "$(date +%FT%T%:z):\t9aSaveConfiguration\tSTART\n" >> "${logfile}" 1157 | 1158 | echo "remotebasedir=${remotebasedir}" > ~/scripts/rclone_script/rclone_script.ini 1159 | echo "showNotifications=${shownotifications}" >> ~/scripts/rclone_script/rclone_script.ini 1160 | echo "syncOnStartStop=\"TRUE\"" >> ~/scripts/rclone_script/rclone_script.ini 1161 | echo "logfile=~/scripts/rclone_script/rclone_script.log" >> ~/scripts/rclone_script/rclone_script.ini 1162 | echo "neededConnection=${neededConnection}" >> ~/scripts/rclone_script/rclone_script.ini 1163 | echo "debug=0" >> ~/scripts/rclone_script/rclone_script.ini 1164 | 1165 | printf "$(date +%FT%T%:z):\t9aSaveConfiguration\tDONE\n" >> "${logfile}" 1166 | } 1167 | 1168 | 1169 | ######## 1170 | # MAIN # 1171 | ######## 1172 | 1173 | if [ "${branch}" == "beta" ] 1174 | then 1175 | dialogBetaWarning 1176 | fi 1177 | 1178 | installer -------------------------------------------------------------------------------- /rclone_script-menu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | NORMAL="\Zn" 5 | BLACK="\Z0" 6 | RED="\Z1" 7 | GREEN="\Z2" 8 | YELLOW="\Z3\Zb" 9 | BLUE="\Z4" 10 | MAGENTA="\Z5" 11 | CYAN="\Z6" 12 | WHITE="\Z7" 13 | BOLD="\Zb" 14 | REVERSE="\Zr" 15 | UNDERLINE="\Zu" 16 | 17 | 18 | # include settings file 19 | config=~/scripts/rclone_script/rclone_script.ini 20 | source ${config} 21 | 22 | backtitle="RCLONE_SCRIPT menu (https://github.com/Jandalf81/rclone_script)" 23 | 24 | 25 | #################### 26 | # HELPER FUNCTIONS # 27 | #################### 28 | 29 | function log () 30 | { 31 | severity=$1 32 | message=$2 33 | printf "$(date +%FT%T%:z):\t${severity}:\t${message}\n" >> ${logfile} 34 | } 35 | 36 | function getTypeOfRemote () 37 | { 38 | # list all remotes and their type 39 | remotes=$(rclone listremotes -l) 40 | 41 | # get line wiht RETROPIE remote 42 | retval=$(grep -i "^retropie:" <<< ${remotes}) 43 | 44 | remoteType="${retval#*:}" 45 | remoteType=$(echo ${remoteType} | xargs) 46 | } 47 | 48 | function getStatusOfParameters () 49 | { 50 | if [ "${syncOnStartStop}" == "TRUE" ] 51 | then 52 | statusSyncOnStartStop="${GREEN}ENABLED${NORMAL}" 53 | else 54 | statusSyncOnStartStop="${RED}DISABLED${NORMAL}" 55 | fi 56 | 57 | if [ "${showNotifications}" == "TRUE" ] 58 | then 59 | statusShowNotifications="${GREEN}ENABLED${NORMAL}" 60 | else 61 | statusShowNotifications="${RED}DISABLED${NORMAL}" 62 | fi 63 | 64 | case ${neededConnection} in 65 | 0) statusNeededConnection="Internet access" ;; 66 | 1) statusNeededConnection="LAN / WLAN" ;; 67 | esac 68 | } 69 | 70 | function saveConfig () 71 | { 72 | echo "remotebasedir=${remotebasedir}" > ${config} 73 | echo "showNotifications=${showNotifications}" >> ${config} 74 | echo "syncOnStartStop=${syncOnStartStop}" >> ${config} 75 | echo "logfile=~/scripts/rclone_script/rclone_script.log" >> ${config} 76 | echo "neededConnection=${neededConnection}" >> ${config} 77 | echo "debug=0" >> ${config} 78 | } 79 | 80 | 81 | ################## 82 | # MENU FUNCTIONS # 83 | ################## 84 | 85 | # Show the main menu. Return here anytime another dialog is closed 86 | function main_menu () 87 | { 88 | local choice="1" 89 | 90 | while true 91 | do 92 | getStatusOfParameters 93 | 94 | choice=$(dialog \ 95 | --stdout \ 96 | --colors \ 97 | --backtitle "${backtitle}" \ 98 | --title "main menu" \ 99 | --default-item "${choice}" \ 100 | --menu "\nWhat do you want to do?" 25 75 20 \ 101 | 1 "Full synchronization of all savefiles and statefiles" \ 102 | 2 "Toggle \"Synchronize saves on start / stop\" (currently ${statusSyncOnStartStop})" \ 103 | 3 "Toggle \"Show notifications on sync\" (currently ${statusShowNotifications})" \ 104 | 4 "Set needed Connection (currently \"${statusNeededConnection}\")" \ 105 | "" ""\ 106 | 9 "uninstall RCLONE_SCRIPT" 107 | ) 108 | 109 | case "$choice" in 110 | 1) doFullSync ;; 111 | 2) toggleSyncOnStartStop ;; 112 | 3) toggleShowNotifications ;; 113 | 4) setNeededConnection ;; 114 | 9) ~/scripts/rclone_script/rclone_script-uninstall.sh ;; 115 | *) break ;; 116 | esac 117 | done 118 | } 119 | 120 | # Syncs all files in both directions, only transferring newer files 121 | function doFullSync () 122 | { 123 | local tmpfile=~/scripts/rclone_script/tmp-sync.txt 124 | 125 | getTypeOfRemote 126 | printf "\nStarted full sync...\n\n" > ${tmpfile} 127 | log "INFO" "Started full sync..." 128 | 129 | # start sync process in background 130 | { 131 | # Download newer files from remote to local 132 | printf "Downloading newer files from retropie:${remotebasedir} (${remoteType}) to ~/RetroPie/saves/...\n" 133 | rclone copy retropie:${remotebasedir}/ ~/RetroPie/saves/ --update --skip-links --exclude "readme.txt" --verbose 2>&1 134 | 135 | # Upload newer files from local to remote 136 | printf "Uploading newer files from ~/RetroPie/saves/ to retropie:${remotebasedir} (${remoteType})...\n" 137 | rclone copy ~/RetroPie/saves/ retropie:${remotebasedir}/ --update --skip-links --exclude "readme.txt" --verbose 2>&1 138 | 139 | printf "Done\n" 140 | } >> ${tmpfile} & # capture output of background process 141 | 142 | dialog \ 143 | --backtitle "${backtitle}" \ 144 | --title "Doing full sync..." \ 145 | --colors \ 146 | --no-collapse \ 147 | --cr-wrap \ 148 | --tailbox ${tmpfile} 40 120 149 | 150 | wait 151 | 152 | cat ${tmpfile} >> ${logfile} 153 | rm ${tmpfile} 154 | 155 | log "INFO" "Finished full sync..." 156 | } 157 | 158 | function toggleSyncOnStartStop () 159 | { 160 | if [ "${syncOnStartStop}" == "TRUE" ] 161 | then 162 | syncOnStartStop="FALSE" 163 | else 164 | syncOnStartStop="TRUE" 165 | fi 166 | 167 | saveConfig 168 | } 169 | 170 | function toggleShowNotifications () 171 | { 172 | if [ "${showNotifications}" == "TRUE" ] 173 | then 174 | showNotifications="FALSE" 175 | else 176 | showNotifications="TRUE" 177 | fi 178 | 179 | saveConfig 180 | } 181 | 182 | function setNeededConnection () 183 | { 184 | choice=$(dialog \ 185 | --stdout \ 186 | --colors \ 187 | --no-collapse \ 188 | --cr-wrap \ 189 | --backtitle "${backtitle}" \ 190 | --title "Needed connection" \ 191 | --default-item "${neededConnection}" \ 192 | --ok-label "Select" \ 193 | --menu "\nPlease select which type of connection will be needed for your configured remote" 20 50 5 \ 194 | 0 "Internet access" \ 195 | 1 "LAN / WLAN connection only" 196 | ) 197 | 198 | case ${choice} in 199 | 0) neededConnection=0 ;; 200 | 1) neededConnection=1 ;; 201 | *) return ;; 202 | esac 203 | 204 | saveConfig 205 | } 206 | 207 | 208 | ######## 209 | # MAIN # 210 | ######## 211 | 212 | main_menu -------------------------------------------------------------------------------- /rclone_script-uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # define colors for output 5 | NORMAL="\Zn" 6 | BLACK="\Z0" 7 | RED="\Z1" 8 | GREEN="\Z2" 9 | YELLOW="\Z3\Zb" 10 | BLUE="\Z4" 11 | MAGENTA="\Z5" 12 | CYAN="\Z6" 13 | WHITE="\Z7" 14 | BOLD="\Zb" 15 | REVERSE="\Zr" 16 | UNDERLINE="\Zu" 17 | 18 | 19 | backtitle="RCLONE_SCRIPT uninstaller (https://github.com/Jandalf81/rclone_script)" 20 | logfile=~/scripts/rclone_script/rclone_script-uninstall.log 21 | 22 | source ~/scripts/rclone_script/rclone_script.ini 23 | oldRemote="" 24 | 25 | 26 | ################## 27 | # WELCOME DIALOG # 28 | ################## 29 | dialog \ 30 | --stdout \ 31 | --backtitle "${backtitle}" \ 32 | --title "Welcome" \ 33 | --colors \ 34 | --no-collapse \ 35 | --cr-wrap \ 36 | --yesno \ 37 | "\nThis script will ${RED}uninstall RCLONE_SCRIPT${NORMAL}. If you do this, your savefiles will no longer be synchronized! All changes made by RCLONE_SCRIPT installer will be reverted. This includes removal of RCLONE, PNGVIEW and IMAGEMAGICK. Also, all configuration changes will be undone. Your local savefiles and savestates will be moved to the ROMS directory again.\nYour remote savefiles and statefiles will ${YELLOW}not${NORMAL} be removed.\n\nAre you sure you wish to continue?" \ 38 | 20 90 2>&1 > /dev/tty \ 39 | || exit 40 | 41 | 42 | #################### 43 | # DIALOG FUNCTIONS # 44 | #################### 45 | 46 | 47 | # Build progress from array $STEPS() 48 | # INPUT 49 | # $steps() 50 | # OUTPUT 51 | # $progress 52 | function buildProgress () 53 | { 54 | progress="" 55 | 56 | for ((i=0; i<=${#steps[*]}; i++)) 57 | do 58 | progress="${progress}${steps[i]}\n" 59 | done 60 | } 61 | 62 | # Show Progress dialog 63 | # INPUT 64 | # 1 > Percentage to show in dialog 65 | # $backtitle 66 | # $progress 67 | function dialogShowProgress () 68 | { 69 | local percent="$1" 70 | 71 | buildProgress 72 | 73 | clear 74 | clear 75 | 76 | echo "${percent}" | dialog \ 77 | --stdout \ 78 | --colors \ 79 | --no-collapse \ 80 | --cr-wrap \ 81 | --backtitle "${backtitle}" \ 82 | --title "Uninstaller" \ 83 | --gauge "${progress}" 36 90 0 \ 84 | 2>&1 > /dev/tty 85 | 86 | sleep 1 87 | } 88 | 89 | 90 | ################## 91 | # STEP FUNCTIONS # 92 | ################## 93 | 94 | # Initialize array $STEPS() 95 | # OUTPUT 96 | # $steps() 97 | function initSteps () 98 | { 99 | steps[1]="1. RCLONE" 100 | steps[2]=" 1a. Remove RCLONE configuration [ waiting... ]" 101 | steps[3]=" 1b. Remove RCLONE binary [ waiting... ]" 102 | steps[4]="2. PNGVIEW" 103 | steps[5]=" 2a. Remove PNGVIEW binary [ waiting... ]" 104 | steps[6]="3. IMAGEMAGICK" 105 | steps[7]=" 3a. apt-get remove IMAGEMAGICK [ waiting... ]" 106 | steps[8]="4. RCLONE_SCRIPT" 107 | steps[9]=" 4a. Remove RCLONE_SCRIPT files [ waiting... ]" 108 | steps[10]=" 4b. Remove RCLONE_SCRIPT menu item [ waiting... ]" 109 | steps[11]="5. RUNCOMMAND" 110 | steps[12]=" 5a. Remove call from RUNCOMMAND-ONSTART [ waiting... ]" 111 | steps[13]=" 5b. Remove call from RUNCOMMAND-ONEND [ waiting... ]" 112 | steps[14]="6. Local SAVEFILE directory" 113 | steps[15]=" 6a. Move savefiles to default [ waiting... ]" 114 | steps[16]=" 6b. Remove local SAVEFILE directory [ waiting... ]" 115 | steps[17]="7. Configure RETROARCH" 116 | steps[18]=" 7a. Reset local SAVEFILE directories [ waiting... ]" 117 | steps[19]="8 Finalizing" 118 | steps[20]=" 8a. Remove UNINSTALL script [ waiting... ]" 119 | } 120 | 121 | # Update item of $STEPS() and show updated progress dialog 122 | # INPUT 123 | # 1 > Number of step to update 124 | # 2 > New status for step 125 | # 3 > Percentage to show in progress dialog 126 | # $steps() 127 | # OUTPUT 128 | # $steps() 129 | function updateStep () 130 | { 131 | local step="$1" 132 | local newStatus="$2" 133 | local percent="$3" 134 | local oldline 135 | local newline 136 | 137 | # translate and colorize $NEWSTATUS 138 | case "${newStatus}" in 139 | "waiting") newStatus="[ ${NORMAL}WAITING...${NORMAL} ]" ;; 140 | "in progress") newStatus="[ ${NORMAL}IN PROGRESS${NORMAL} ]" ;; 141 | "done") newStatus="[ ${GREEN}DONE${NORMAL} ]" ;; 142 | "found") newStatus="[ ${GREEN}FOUND${NORMAL} ]" ;; 143 | "not found") newStatus="[ ${RED}NOT FOUND${NORMAL} ]" ;; 144 | "created") newStatus="[ ${GREEN}CREATED${NORMAL} ]" ;; 145 | "failed") newStatus="[ ${RED}FAILED${NORMAL} ]" ;; 146 | "skipped") newStatus="[ ${YELLOW}SKIPPED${NORMAL} ]" ;; 147 | *) newStatus="[ ${RED}UNDEFINED${NORMAL} ]" ;; 148 | esac 149 | 150 | # search $STEP in $STEPS 151 | for ((i=0; i<${#steps[*]}; i++)) 152 | do 153 | if [[ ${steps[i]} =~ .*$step.* ]] 154 | then 155 | # update $STEP with $NEWSTATUS 156 | oldline="${steps[i]}" 157 | oldline="${oldline%%[*}" 158 | newline="${oldline}${newStatus}" 159 | steps[i]="${newline}" 160 | 161 | break 162 | fi 163 | done 164 | 165 | # show progress dialog 166 | dialogShowProgress ${percent} 167 | } 168 | 169 | # Show summary dialog 170 | function dialogShowSummary () 171 | { 172 | dialog \ 173 | --backtitle "${backtitle}" \ 174 | --title "Summary" \ 175 | --colors \ 176 | --no-collapse \ 177 | --cr-wrap \ 178 | --yesno \ 179 | "\n${GREEN}All done!${NORMAL}\n\nRCLONE_SCRIPT and its components have been removed. From now on, your saves and states will ${RED}NOT${NORMAL} be synchronized any longer. Your local savefiles have been moved to their default directories (inside each ROMS directory). Your remote files on\n ${YELLOW}${oldRemote}${NORMAL}\nhave ${GREEN}NOT${NORMAL} been removed.\n\nTo finish the uninstaller you should reboot your RetroPie now.\n\n${RED}Reboot RetroPie now?${NORMAL}" 25 90 180 | 181 | case $? in 182 | 0) sudo shutdown -r now ;; 183 | esac 184 | } 185 | 186 | ######################### 187 | # UNINSTALLER FUNCTIONS # 188 | ######################### 189 | 190 | # Uninstaller 191 | function uninstaller () 192 | { 193 | initSteps 194 | dialogShowProgress 0 195 | 196 | saveRemote 197 | 198 | 1RCLONE 199 | 2PNGVIEW 200 | 3IMAGEMAGICK 201 | 4RCLONE_SCRIPT 202 | 5RUNCOMMAND 203 | 6LocalSAVEFILEDirectory 204 | 7RetroArch 205 | 8Finalize 206 | 207 | dialogShowSummary 208 | } 209 | 210 | function saveRemote () 211 | { 212 | # list all remotes and their type 213 | remotes=$(rclone listremotes -l) 214 | 215 | # get line with RETROPIE remote 216 | retval=$(grep -i "^retropie:" <<< ${remotes}) 217 | 218 | remoteType="${retval#*:}" 219 | remoteType=$(echo ${remoteType} | xargs) 220 | 221 | oldRemote="retropie:${remotebasedir} (${remoteType})" 222 | } 223 | 224 | function 1RCLONE () 225 | { 226 | printf "$(date +%FT%T%:z):\t1RCLONE\tSTART\n" >> "${logfile}" 227 | 228 | # 1a. Remove RCLONE configuration 229 | printf "$(date +%FT%T%:z):\t1aRCLONEconfiguration\tSTART\n" >> "${logfile}" 230 | updateStep "1a" "in progress" 0 231 | 232 | if [ -d ~/.config/rclone ] 233 | then 234 | { #try 235 | sudo rm -r ~/.config/rclone >> "${logfile}" && 236 | printf "$(date +%FT%T%:z):\t1aRCLONEconfiguration\tDONE\n" >> "${logfile}" && 237 | updateStep "1a" "done" 8 238 | } || { #catch 239 | printf "$(date +%FT%T%:z):\t1aRCLONEconfiguration\tERROR\n" >> "${logfile}" && 240 | updateStep "1a" "failed" 0 && 241 | exit 242 | } 243 | else 244 | printf "$(date +%FT%T%:z):\t1aRCLONEconfiguration\tNOT FOUND\n" >> "${logfile}" 245 | updateStep "1a" "not found" 8 246 | fi 247 | 248 | # 1b. Remove RCLONE binary 249 | printf "$(date +%FT%T%:z):\t1bRCLONEbinary\tSTART\n" >> "${logfile}" 250 | updateStep "1b" "in progress" 8 251 | 252 | if [ -f /usr/bin/rclone ] 253 | then 254 | { #try 255 | sudo rm /usr/bin/rclone >> "${logfile}" && 256 | printf "$(date +%FT%T%:z):\t1bRCLONEbinary\tDONE\n" >> "${logfile}" && 257 | updateStep "1b" "done" 16 258 | } || { #catch 259 | printf "$(date +%FT%T%:z):\t1bRCLONEbinary\tERROR\n" >> "${logfile}" && 260 | updateStep "1b" "failed" 8 && 261 | exit 262 | } 263 | else 264 | printf "$(date +%FT%T%:z):\t1bRCLONEbinary\tNOT FOUND\n" >> "${logfile}" 265 | updateStep "1b" "not found" 16 266 | fi 267 | 268 | printf "$(date +%FT%T%:z):\t1RCLONE\tEND\n" >> "${logfile}" 269 | } 270 | 271 | function 2PNGVIEW () 272 | { 273 | printf "$(date +%FT%T%:z):\t2PNGVIEW\tSTART\n" >> "${logfile}" 274 | 275 | # 2a. Remove PNGVIEW binary 276 | printf "$(date +%FT%T%:z):\t2aPNGVIEWbinary\tSTART\n" >> "${logfile}" 277 | updateStep "2a" "in progress" 16 278 | 279 | if [ -f /usr/bin/pngview ] 280 | then 281 | { #try 282 | sudo rm /usr/bin/pngview >> "${logfile}" && 283 | sudo rm /usr/lib/libraspidmx.so.1 >> "${logfile}" && 284 | printf "$(date +%FT%T%:z):\t2aPNGVIEWbinary\tDONE\n" >> "${logfile}" && 285 | updateStep "2a" "done" 24 286 | } || { # catch 287 | printf "$(date +%FT%T%:z):\t2aPNGVIEWbinary\tERROR\n" >> "${logfile}" && 288 | updateStep "2a" "failed" 16 && 289 | exit 290 | } 291 | else 292 | printf "$(date +%FT%T%:z):\t2aPNGVIEWbinary\tNOT FOUND\n" >> "${logfile}" && 293 | updateStep "2a" "not found" 24 294 | fi 295 | 296 | printf "$(date +%FT%T%:z):\t2PNGVIEW\tDONE\n" >> "${logfile}" 297 | } 298 | 299 | function 3IMAGEMAGICK () 300 | { 301 | printf "$(date +%FT%T%:z):\t3IMAGEMAGICK\tSTART\n" >> "${logfile}" 302 | 303 | # 3a. Remove IMAGEMAGICK binary 304 | printf "$(date +%FT%T%:z):\t3aIMAGEMAGICKbinary\tSTART\n" >> "${logfile}" 305 | updateStep "3a" "in progress" 24 306 | 307 | if [ -f /usr/bin/convert ] 308 | then 309 | { # try 310 | sudo apt-get --yes remove imagemagick* >> "${logfile}" && 311 | printf "$(date +%FT%T%:z):\t3aIMAGEMAGICKbinary\tDONE\n" >> "${logfile}" && 312 | updateStep "3a" "done" 32 313 | } || { # catch 314 | printf "$(date +%FT%T%:z):\t3aIMAGEMAGICKbinary\tERROR\n" >> "${logfile}" && 315 | updateStep "3a" "failed" 24 && 316 | exit 317 | } 318 | else 319 | printf "$(date +%FT%T%:z):\t3aPIMAGEMAGICKbinary\tNOT FOUND\n" >> "${logfile}" 320 | updateStep "3a" "not found" 32 321 | fi 322 | 323 | printf "$(date +%FT%T%:z):\t3IMAGEMAGICK\tDONE\n" >> "${logfile}" 324 | } 325 | 326 | function 4RCLONE_SCRIPT () 327 | { 328 | printf "$(date +%FT%T%:z):\t4RCLONE_SCRIPT\tSTART\n" >> "${logfile}" 329 | 330 | # 4a. Remove RCLONE_SCRIPT 331 | printf "$(date +%FT%T%:z):\t4aRCLONE_SCRIPTfiles\tSTART\n" >> "${logfile}" 332 | updateStep "4a" "in progress" 32 333 | 334 | if [ -f ~/scripts/rclone_script/rclone_script.sh ] 335 | then 336 | { # try 337 | sudo rm -f ~/scripts/rclone_script/rclone_script-install.* >> "${logfile}" && 338 | sudo rm -f ~/scripts/rclone_script/rclone_script.* >> "${logfile}" && 339 | printf "$(date +%FT%T%:z):\t4aRCLONE_SCRIPTfiles\tDONE\n" >> "${logfile}" && 340 | updateStep "4a" "done" 40 341 | } || { # catch 342 | printf "$(date +%FT%T%:z):\t4aRCLONE_SCRIPTfiles\tERROR\n" >> "${logfile}" && 343 | updateStep "4a" "failed" 32 && 344 | exit 345 | } 346 | else 347 | printf "$(date +%FT%T%:z):\t4aRCLONE_SCRIPTfiles\tNOT FOUND\n" >> "${logfile}" 348 | updateStep "4a" "not found" 40 349 | fi 350 | 351 | # 4b. Remove RCLONE_SCRIPT menu item 352 | printf "$(date +%FT%T%:z):\t4bRCLONE_SCRIPTMenuItem\tSTART\n" >> "${logfile}" 353 | updateStep "4b" "in progress" 40 354 | 355 | local found=0 356 | 357 | if [[ $(xmlstarlet sel -t -v "count(/gameList/game[path='./rclone_script-redirect.sh.sh'])" ~/.emulationstation/gamelists/retropie/gamelist.xml) -ne 0 ]] 358 | then 359 | found=$(($found + 1)) 360 | 361 | printf "$(date +%FT%T%:z):\t4bRCLONE_SCRIPTMenuItem\tFOUND\n" >> "${logfile}" 362 | 363 | xmlstarlet ed \ 364 | --inplace \ 365 | --delete "//game[path='./rclone_script-redirect.sh']" \ 366 | ~/.emulationstation/gamelists/retropie/gamelist.xml 367 | 368 | printf "$(date +%FT%T%:z):\t4bRCLONE_SCRIPTMenuItem\tREMOVED\n" >> "${logfile}" 369 | else 370 | printf "$(date +%FT%T%:z):\t4bRCLONE_SCRIPTMenuItem\tNOT FOUND\n" >> "${logfile}" 371 | fi 372 | 373 | if [ -f ~/RetroPie/retropiemenu/rclone_script-redirect.sh ] 374 | then 375 | found=$(($found + 1)) 376 | 377 | printf "$(date +%FT%T%:z):\t4bRCLONE_SCRIPTMenuItemScript\tFOUND\n" >> "${logfile}" 378 | 379 | sudo rm ~/RetroPie/retropiemenu/rclone_script-redirect.sh >> "${logfile}" 380 | sudo rm ~/scripts/rclone_script/rclone_script-menu.sh >> "${logfile}" 381 | 382 | printf "$(date +%FT%T%:z):\t4bRCLONE_SCRIPTMenuItemScript\tREMOVED\n" >> "${logfile}" 383 | else 384 | printf "$(date +%FT%T%:z):\t4bRCLONE_SCRIPTMenuItemScript\tNOT FOUND\n" >> "${logfile}" 385 | fi 386 | 387 | case $found in 388 | 0) updateStep "4b" "not found" 48 ;; 389 | 1) updateStep "4b" "done" 48 ;; 390 | 2) updateStep "4b" "done" 48 ;; 391 | esac 392 | 393 | printf "$(date +%FT%T%:z):\t4RCLONE_SCRIPT\tDONE\n" >> "${logfile}" 394 | } 395 | 396 | function 5RUNCOMMAND () 397 | { 398 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND\tSTART\n" >> "${logfile}" 399 | 400 | # 5a. Remove call from RUNCOMMAND-ONSTART 401 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND-ONSTART\tSTART\n" >> "${logfile}" 402 | updateStep "5a" "in progress" 48 403 | 404 | if [[ $(grep -c "~/scripts/rclone_script/rclone_script.sh" /opt/retropie/configs/all/runcommand-onstart.sh) -gt 0 ]] 405 | then 406 | { #try 407 | sed -i "/~\/scripts\/rclone_script\/rclone_script.sh /d" /opt/retropie/configs/all/runcommand-onstart.sh && 408 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND-ONSTART\tDONE\n" >> "${logfile}" && 409 | updateStep "5a" "done" 56 410 | } || { # catch 411 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND-ONSTART\tERROR\n" >> "${logfile}" && 412 | updateStep "5a" "failed" 48 413 | } 414 | else 415 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND-ONSTART\tNOT FOUND\n" >> "${logfile}" 416 | updateStep "5a" "not found" 56 417 | fi 418 | 419 | # 5b. Remove call from RUNCOMMAND-ONEND 420 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND-ONEND\tSTART\n" >> "${logfile}" 421 | updateStep "5b" "in progress" 56 422 | 423 | if [[ $(grep -c "~/scripts/rclone_script/rclone_script.sh" /opt/retropie/configs/all/runcommand-onend.sh) -gt 0 ]] 424 | then 425 | { #try 426 | sed -i "/~\/scripts\/rclone_script\/rclone_script.sh /d" /opt/retropie/configs/all/runcommand-onend.sh && 427 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND-ONEND\tDONE\n" >> "${logfile}" && 428 | updateStep "5b" "done" 64 429 | } || { # catch 430 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND-ONEND\tERROR\n" >> "${logfile}" && 431 | updateStep "5b" "failed" 56 432 | } 433 | else 434 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND-ONEND\tNOT FOUND\n" >> "${logfile}" 435 | updateStep "5b" "not found" 64 436 | fi 437 | 438 | printf "$(date +%FT%T%:z):\t5RUNCOMMAND\tDONE\n" >> "${logfile}" 439 | } 440 | 441 | function 6LocalSAVEFILEDirectory () 442 | { 443 | printf "$(date +%FT%T%:z):\t6LocalSAVEFILEDirectory\tSTART\n" >> "${logfile}" 444 | 445 | # 6a. Move savefiles to default 446 | printf "$(date +%FT%T%:z):\t6a moveFilesToDefault\tSTART\n" >> "${logfile}" 447 | updateStep "6a" "in progress" 64 448 | 449 | if [ -d ~/RetroPie/saves ] 450 | then 451 | # start copy task in background, pipe numbered output into COPY.TXT and to LOGFILE 452 | $(cp -v -r ~/RetroPie/saves/* ~/RetroPie/roms | cat -n | tee copy.txt | cat >> "${logfile}") & 453 | 454 | # show content of COPY.TXT 455 | dialog \ 456 | --backtitle "${backtitle}" \ 457 | --title "Copying savefiles to default..." \ 458 | --colors \ 459 | --no-collapse \ 460 | --cr-wrap \ 461 | --tailbox copy.txt 40 120 462 | 463 | wait 464 | 465 | rm copy.txt 466 | 467 | updateStep "6a" "done" 72 468 | else 469 | printf "$(date +%FT%T%:z):\t6a moveFilesToDefault\tNOT FOUND\n" >> "${logfile}" 470 | updateStep "6a" "not found" 72 471 | fi 472 | 473 | # 6b. Remove local SAVEFILE directory 474 | printf "$(date +%FT%T%:z):\t6b removeLocalSAVEFILEbasedir\tSTART\n" >> "${logfile}" 475 | updateStep "6b" "in progress" 72 476 | 477 | if [ -d ~/RetroPie/saves ] 478 | then 479 | # start remove task in background, pipe numbered output into DELETE.TXT and to LOGFILE 480 | $(sudo rm --recursive --force --verbose ~/RetroPie/saves | cat -n | tee delete.txt | cat >> "${logfile}") & 481 | 482 | # show content of REMOVE.TXT 483 | dialog \ 484 | --backtitle "${backtitle}" \ 485 | --title "Removing savefiles from local base dir..." \ 486 | --colors \ 487 | --no-collapse \ 488 | --cr-wrap \ 489 | --tailbox delete.txt 40 120 490 | 491 | wait 492 | 493 | rm delete.txt 494 | 495 | # check if that directory is shared 496 | local retval=$(grep -n "\[saves\]" /etc/samba/smb.conf) 497 | if [ "${retval}" != "" ] 498 | then 499 | # extract line numbers 500 | local lnStart="${retval%%:*}" 501 | local lnEnd=$(( $lnStart + 7 )) 502 | 503 | # remove network share 504 | sudo sed -i -e "${lnStart},${lnEnd}d" /etc/samba/smb.conf 505 | 506 | # restart SAMBA service 507 | sudo service smbd restart 508 | 509 | printf "$(date +%FT%T%:z):\t6b removeLocalSAVEFILEbasedir\tREMOVED network share\n" >> "${logfile}" 510 | fi 511 | 512 | 513 | printf "$(date +%FT%T%:z):\t6b removeLocalSAVEFILEbasedir\tDONE\n" >> "${logfile}" 514 | updateStep "6b" "done" 80 515 | else 516 | printf "$(date +%FT%T%:z):\t6b removeLocalSAVEFILEbasedir\tNOT FOUND\n" >> "${logfile}" 517 | updateStep "6b" "skipped" 80 518 | fi 519 | 520 | printf "$(date +%FT%T%:z):\t6LocalSAVEFILEDirectory\tDONE\n" >> "${logfile}" 521 | } 522 | 523 | function 7RetroArch () 524 | { 525 | printf "$(date +%FT%T%:z):\t7RetroArch\tSTART\n" >> "${logfile}" 526 | 527 | # 7a. Reset local SAVEFILE directories 528 | printf "$(date +%FT%T%:z):\t7a resetSAVEFILEdirectories\tSTART\n" >> "${logfile}" 529 | updateStep "7a" "in progress" 80 530 | 531 | local found=0 532 | 533 | # for each directory... 534 | for directory in /opt/retropie/configs/* 535 | do 536 | system="${directory##*/}" 537 | 538 | # skip system "all" 539 | if [ "${system}" == "all" ] 540 | then 541 | continue 542 | fi 543 | 544 | # check if there'a system specific RETROARCH.CFG 545 | if [ -f "${directory}/retroarch.cfg" ] 546 | then 547 | printf "$(date +%FT%T%:z):\t7a resetSAVEFILEdirectories\tFOUND retroarch.cfg for ${system}\n" >> "${logfile}" 548 | 549 | # check if RETROARCH.CFG contains SAVEFILE pointing to ~/RetroPie/saves/ 550 | if [[ $(grep -c "^savefile_directory = \"~/RetroPie/saves/${system}\"" ${directory}/retroarch.cfg) -gt 0 ]] 551 | then 552 | printf "$(date +%FT%T%:z):\t7a resetSAVEFILEdirectories\tFOUND savefile_directory\n" >> "${logfile}" 553 | found=$(($found + 1)) 554 | # replace parameter 555 | sed -i "/^savefile_directory = \"~\/RetroPie\/saves\/${system}\"/c\savefile_directory = \"default\"" ${directory}/retroarch.cfg 556 | printf "$(date +%FT%T%:z):\t7a resetSAVEFILEdirectories\tREPLACED savefile_directory\n" >> "${logfile}" 557 | else 558 | printf "$(date +%FT%T%:z):\t7a resetSAVEFILEdirectories\tNOT FOUND savefile_directory\n" >> "${logfile}" 559 | fi 560 | 561 | # check if RETROARCH.CFG contains SAVESTATE pointing to ~/RetroPie/saves/ 562 | if [[ $(grep -c "^savestate_directory = \"~/RetroPie/saves/${system}\"" ${directory}/retroarch.cfg) -gt 0 ]] 563 | then 564 | printf "$(date +%FT%T%:z):\t7a resetSAVESTATEdirectories\tFOUND savestate_directory\n" >> "${logfile}" 565 | found=$(($found + 1)) 566 | # replace parameter 567 | sed -i "/^savestate_directory = \"~\/RetroPie\/saves\/${system}\"/c\savestate_directory = \"default\"" ${directory}/retroarch.cfg 568 | printf "$(date +%FT%T%:z):\t7a resetSAVESTATEdirectories\tREPLACED savestate_directory\n" >> "${logfile}" 569 | else 570 | printf "$(date +%FT%T%:z):\t7a resetSAVESTATEdirectories\tNOT FOUND savestate_directory\n" >> "${logfile}" 571 | fi 572 | fi 573 | done 574 | 575 | printf "$(date +%FT%T%:z):\t7a resetSAVEFILEdirectories\tDINE\n" >> "${logfile}" 576 | if [[ $found -eq 0 ]] 577 | then 578 | updateStep "7a" "not found" 88 579 | else 580 | updateStep "7a" "done" 88 581 | fi 582 | 583 | printf "$(date +%FT%T%:z):\t7RetroArch\tDONE\n" >> "${logfile}" 584 | } 585 | 586 | function 8Finalize () 587 | { 588 | printf "$(date +%FT%T%:z):\t8Finalize\tSTART\n" >> "${logfile}" 589 | 590 | # 8a. Remove UNINSTALL script 591 | printf "$(date +%FT%T%:z):\t8a removeUNINSTALLscript\tSTART\n" >> "${logfile}" 592 | updateStep "8a" "in progress" 88 593 | 594 | printf "$(date +%FT%T%:z):\t8a removeUNINSTALLscript\tDONE\n" >> "${logfile}" 595 | updateStep "8a" "done" 100 596 | 597 | printf "$(date +%FT%T%:z):\t8Finalize\tDONE\n" >> "${logfile}" 598 | 599 | # move LOGFILE to HOME 600 | mv ~/scripts/rclone_script/rclone_script-uninstall.log ~ 601 | 602 | # remove RCLONE_SCRIPT directory 603 | rm -rf ~/scripts/rclone_script 604 | } 605 | 606 | 607 | ######## 608 | # MAIN # 609 | ######## 610 | 611 | uninstaller -------------------------------------------------------------------------------- /rclone_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # define colors for output 4 | NORMAL=$(tput sgr0) 5 | RED=$(tput setaf 1) 6 | GREEN=$(tput setaf 2) 7 | YELLOW=$(tput setaf 3) 8 | BLUE=$(tput setaf 4) 9 | UNDERLINE=$(tput smul) 10 | 11 | 12 | # include settings file 13 | config=~/scripts/rclone_script/rclone_script.ini 14 | source ${config} 15 | logLevel=2 16 | 17 | 18 | # parameters 19 | direction="$1" 20 | system="$2" 21 | emulator="$3" 22 | rom="$4" 23 | command="$5" 24 | 25 | 26 | #################### 27 | # HELPER FUNCTIONS # 28 | #################### 29 | 30 | function log () 31 | # Prints messages of different severeties to a logfile 32 | # Each message will look something like this: 33 | # 34 | # needs a set variable $logLevel 35 | # -1 > No logging at all 36 | # 0 > prints ERRORS only 37 | # 1 > prints ERRORS and WARNINGS 38 | # 2 > prints ERRORS, WARNINGS and INFO 39 | # 3 > prints ERRORS, WARNINGS, INFO and DEBUGGING 40 | # needs a set variable $log pointing to a file 41 | # Usage 42 | # log 0 "This is an ERROR Message" 43 | # log 1 "This is a WARNING" 44 | # log 2 "This is just an INFO" 45 | # log 3 "This is a DEBUG message" 46 | { 47 | severity=$1 48 | message=$2 49 | 50 | if (( ${severity} <= ${logLevel} )) 51 | then 52 | case ${severity} in 53 | 0) level="ERROR" ;; 54 | 1) level="WARNING" ;; 55 | 2) level="INFO" ;; 56 | 3) level="DEBUG" ;; 57 | esac 58 | 59 | printf "$(date +%FT%T%:z):\t${level}\t${0##*/}\t${FUNCNAME[1]}\t${message}\n" >> ${logfile} 60 | fi 61 | } 62 | 63 | function killOtherNotification () 64 | { 65 | # get PID of other PNGVIEW process 66 | otherPID=$(pgrep --full pngview) 67 | 68 | if [ "${debug}" = "1" ]; then log 3 "Other PIDs: ${otherPID}"; fi 69 | 70 | if [ "${otherPID}" != "" ] 71 | then 72 | if [ "${debug}" = "1" ]; then log 3 "Kill other PNGVIEW ${otherPID}"; fi 73 | 74 | kill ${otherPID} 75 | fi 76 | } 77 | 78 | function showNotification () 79 | { 80 | # Quit here, if Notifications are not to be shown and they are not forced 81 | if [ "${showNotifications}" == "FALSE" ] && [ "$6" != "forced" ] 82 | then 83 | return 84 | fi 85 | 86 | message="$1" 87 | 88 | if [ "$2" = "" ] 89 | then 90 | color="yelloW" 91 | else 92 | color="$2" 93 | fi 94 | 95 | if [ "$3" = "" ] 96 | then 97 | timeout="10000" 98 | else 99 | timeout="$3" 100 | fi 101 | 102 | if [ "$4" = "" ] 103 | then 104 | posx="10" 105 | else 106 | posx="$4" 107 | fi 108 | 109 | if [ "$5" = "" ] 110 | then 111 | posy="10" 112 | else 113 | posy="$5" 114 | fi 115 | 116 | # create PNG using IMAGEMAGICK 117 | convert -size 1500x32 xc:"rgba(0,0,0,0)" -type truecolormatte -gravity NorthWest \ 118 | -pointsize 32 -font FreeMono -style italic \ 119 | -fill ${color} -draw "text 0,0 '${message}'" \ 120 | PNG32:- > ~/scripts/rclone_script/rclone_script-notification.png 121 | 122 | killOtherNotification 123 | 124 | # show PNG using PNGVIEW 125 | nohup pngview -b 0 -l 10000 ~/scripts/rclone_script/rclone_script-notification.png -x ${posx} -y ${posy} -t ${timeout} &>/dev/null & 126 | } 127 | 128 | function getROMFileName () 129 | { 130 | rompath="${rom%/*}" # directory containing $rom 131 | romfilename="${rom##*/}" # filename of $rom, including extension 132 | romfilebase="${romfilename%%.*}" # filename of $rom, excluding extension 133 | romfileext="${romfilename#*.}" # extension of $rom 134 | } 135 | 136 | function prepareFilter () 137 | { 138 | filter="${romfilebase//\[/\\[}" 139 | filter="${filter//\]/\\]}" 140 | } 141 | 142 | function getTypeOfRemote () 143 | { 144 | # list all remotes and their type 145 | remotes=$(rclone listremotes -l) 146 | 147 | # get line with RETROPIE remote 148 | retval=$(grep -i "^retropie:" <<< ${remotes}) 149 | 150 | remoteType="${retval#*:}" 151 | remoteType=$(echo ${remoteType} | xargs) 152 | } 153 | 154 | function getAvailableConnection () 155 | # checks if the device is connected to a LAN / WLAN and the Internet 156 | # RETURN 157 | # 0 > device seems to be connected to the Internet 158 | # 1 > device seems to be connected to a LAN / WLAN without internet access 159 | # 2 > device doesn't seem to be connected at all 160 | { 161 | gatewayIP=$(ip r | grep default | cut -d " " -f 3) 162 | if [ "${gatewayIP}" == "" ] 163 | then 164 | log 2 "Gateway could not be detected" 165 | return 2 166 | else 167 | log 2 "Gateway IP: ${gatewayIP}" 168 | fi 169 | 170 | ping -q -w 1 -c 1 ${gatewayIP} > /dev/null 171 | if [[ $? -eq 0 ]] 172 | then 173 | log 2 "Gateway PING successful" 174 | else 175 | log 2 "Gateway could not be PINGed" 176 | return 2 177 | fi 178 | 179 | ping -q -w 1 -c 1 "8.8.8.8" > /dev/null 180 | if [[ $? -eq 0 ]] 181 | then 182 | log 2 "8.8.8.8 PING successful" 183 | return 0 184 | else 185 | log 2 "8.8.8.8 could not be PINGed" 186 | return 1 187 | fi 188 | } 189 | 190 | 191 | ################## 192 | # SYNC FUNCTIONS # 193 | ################## 194 | 195 | function downloadSaves () 196 | { 197 | if [ "${syncOnStartStop}" == "FALSE" ] 198 | then 199 | showNotification "!!! Synchronization is currently disabled !!!" "red" "" "" "" "forced" 200 | return 201 | fi 202 | 203 | log 2 "Started ${system}/${romfilename} " 204 | log 2 "Downloading saves and states for ${system}/${romfilename} from ${remoteType}..." 205 | showNotification "Downloading saves and states from ${remoteType}..." 206 | 207 | getAvailableConnection 208 | availableConnection=$? 209 | if [[ ${availableConnection} -gt ${neededConnection} ]] 210 | then 211 | log 0 "Needed Connection not available. Needed ${neededConnection}, available ${availableConnection}" 212 | 213 | case ${neededConnection} in 214 | 0) showNotification "Downloading saves and states from ${remoteType}... No Internet connection available" "red" "" "" "" "forced" ;; 215 | 1) showNotification "Downloading saves and states from ${remoteType}... No LAN / WLAN connection available" "red" "" "" "" "forced" ;; 216 | esac 217 | 218 | return 219 | fi 220 | 221 | # test for remote files 222 | remotefiles=$(rclone lsf retropie:${remotebasedir}/${system} --include "${filter}.*") 223 | retval=$? 224 | 225 | if [ "${retval}" = "0" ] 226 | then # no error with RCLONE 227 | 228 | if [ "${remotefiles}" = "" ] 229 | then # no remote files found 230 | log 2 "No remote files found" 231 | showNotification "Downloading saves and states from ${remoteType}... No remote files found" 232 | else # remote files found 233 | log 2 "Found remote files" 234 | 235 | # download saves and states to corresponding ROM 236 | rclone copy retropie:${remotebasedir}/${system} ~/RetroPie/saves/${system} --include "${filter}.*" --update >> ${logfile} 237 | retval=$? 238 | 239 | if [ "${retval}" = "0" ] 240 | then 241 | log 2 "Done" 242 | showNotification "Downloading saves and states from ${remoteType}... Done" "green" 243 | else 244 | log 2 "Saves and states could not be downloaded" 245 | showNotification "Downloading saves and states from ${remoteType}... ERROR" "red" "" "" "" "forced" 246 | fi 247 | fi 248 | else # error with RCLONE 249 | log 0 "Saves and states could not be downloaded" 250 | showNotification "Downloading saves and states from ${remoteType}... ERROR" "red" "" "" "" "forced" 251 | fi 252 | } 253 | 254 | function uploadSaves () 255 | { 256 | if [ "${syncOnStartStop}" == "FALSE" ] 257 | then 258 | showNotification "!!! Synchronization is currently disabled !!!" "red" "" "" "" "forced" 259 | return 260 | fi 261 | 262 | log 2 "Stopped ${system}/${romfilename} " 263 | log 2 "Uploading saves and states for ${system}/${romfilename} to ${remoteType}..." 264 | showNotification "Uploading saves and states to ${remoteType}..." 265 | 266 | getAvailableConnection 267 | availableConnection=$? 268 | if [[ ${availableConnection} -gt ${neededConnection} ]] 269 | then 270 | log 0 "Needed Connection not available. Needed ${neededConnection}, available ${availableConnection}" 271 | 272 | case ${neededConnection} in 273 | 0) showNotification "Uploading saves and states to ${remoteType}... No Internet connection available" "red" "" "" "" "forced" ;; 274 | 1) showNotification "Uploading saves and states to ${remoteType}... No LAN / WLAN connection available" "red" "" "" "" "forced" ;; 275 | esac 276 | 277 | return 278 | fi 279 | 280 | localfiles=$(find ~/RetroPie/saves/${system} -type f -iname "${filter}.*") 281 | 282 | if [ "${localfiles}" = "" ] 283 | then # no local files found 284 | log 2 "No local saves and states found" 285 | showNotification "Uploading saves and states to ${remoteType}... No local files found" 286 | else # local files found 287 | # upload saves and states to corresponding ROM 288 | rclone copy ~/RetroPie/saves/${system} retropie:${remotebasedir}/${system} --include "${filter}.*" --update >> ${logfile} 289 | retval=$? 290 | 291 | if [ "${retval}" = "0" ] 292 | then 293 | log 2 "Done" 294 | showNotification "Uploading saves and states to ${remoteType}... Done" "green" 295 | else 296 | log 2 "saves and states could not be uploaded" 297 | showNotification "Uploading saves and states to ${remoteType}... ERROR" "red" "" "" "" "forced" 298 | fi 299 | fi 300 | } 301 | 302 | 303 | function deleteFileFromRemote () 304 | # deletes a file from the remote 305 | # INPUT 306 | # $1 > relative filepath incl. name and extension to the local savepath 307 | # RETURN 308 | # 0 > file deteted successfully 309 | # 1 > connection not available 310 | # 2 > file could not be deleted 311 | { 312 | fileToDelete="$1" 313 | log 2 "File to delete: retropie:${remotebasedir}/${fileToDelete}" 314 | 315 | getAvailableConnection 316 | availableConnection=$? 317 | if [[ ${availableConnection} -gt ${neededConnection} ]] 318 | then 319 | log 0 "Needed Connection not available. Needed ${neededConnection}, available ${availableConnection}" 320 | return 1 321 | fi 322 | 323 | rclone delete "retropie:${remotebasedir}/${fileToDelete}" 2>&1 >> ${logfile} 324 | if [[ $? -eq 0 ]] 325 | then 326 | log 2 "File deleted successfully" 327 | return 0 328 | else 329 | log 0 "File could not be deleted. Error Code $?" 330 | return 1 331 | fi 332 | } 333 | 334 | ######## 335 | # MAIN # 336 | ######## 337 | 338 | #if [ "${debug}" = "1" ]; then debug; fi 339 | log 3 "direction: ${direction}" 340 | log 3 "system: ${system}" 341 | log 3 "emulator: ${emulator}" 342 | log 3 "rom: ${rom}" 343 | log 3 "command: ${command}" 344 | log 3 "remotebasedir: ${remotebasedir}" 345 | log 3 "rompath: ${rompath}" 346 | log 3 "romfilename: ${romfilename}" 347 | log 3 "romfilebase: ${romfilebase}" 348 | log 3 "romfileext: ${romfileext}" 349 | 350 | if [ "${direction}" == "up" ] && [ "${system}" != "kodi" ] 351 | then 352 | getROMFileName 353 | prepareFilter 354 | getTypeOfRemote 355 | uploadSaves 356 | fi 357 | 358 | if [ "${direction}" == "down" ] && [ "${system}" != "kodi" ] 359 | then 360 | getROMFileName 361 | prepareFilter 362 | getTypeOfRemote 363 | downloadSaves 364 | fi 365 | 366 | if [ "${direction}" == "delete" ] 367 | then 368 | deleteFileFromRemote "${2}" 369 | fi 370 | --------------------------------------------------------------------------------