rclone_script-install.sh 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. #!/bin/bash
  2. # define colors for output
  3. NORMAL="\Zn"
  4. BLACK="\Z0"
  5. RED="\Z1"
  6. GREEN="\Z2"
  7. YELLOW="\Z3\Zb"
  8. BLUE="\Z4"
  9. MAGENTA="\Z5"
  10. CYAN="\Z6"
  11. WHITE="\Z7"
  12. BOLD="\Zb"
  13. REVERSE="\Zr"
  14. UNDERLINE="\Zu"
  15. # global variables
  16. url="https://raw.githubusercontent.com/Jandalf81/rclone_script"
  17. branch="beta"
  18. # configuration variables
  19. remotebasedir=""
  20. shownotifications=""
  21. backtitle="RCLONE_SCRIPT installer"
  22. logfile=~/scripts/rclone_script/rclone_script-install.log
  23. ##################
  24. # WELCOME DIALOG #
  25. ##################
  26. dialog \
  27. --backtitle "${backtitle}" \
  28. --title "Welcome" \
  29. --ascii-lines \
  30. --colors \
  31. --no-collapse \
  32. --cr-wrap \
  33. --yesno \
  34. "\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. If you already have some savefiles there, you will need to ${YELLOW}move them manually${NORMAL} after installation.\n\nAre you sure you wish to continue?" \
  35. 20 90 2>&1 > /dev/tty \
  36. || exit
  37. ####################
  38. # DIALOG FUNCTIONS #
  39. ####################
  40. # Warn the user if they are using the BETA branch
  41. function dialogBetaWarning ()
  42. {
  43. dialog \
  44. --backtitle "${backtitle}" \
  45. --title "Beta Warning" \
  46. --ascii-lines \
  47. --colors \
  48. --no-collapse \
  49. --cr-wrap \
  50. --yesno \
  51. "\n${RED}${UNDERLINE}WARNING!${NORMAL}\n\nYou are about to install a beta version!\nAre you ${RED}REALLY${NORMAL} sure you want to continue?" \
  52. 10 50 2>&1 > /dev/tty \
  53. || exit
  54. }
  55. # Build progress from array $STEPS()
  56. # INPUT
  57. # $steps()
  58. # OUTPUT
  59. # $progress
  60. function buildProgress ()
  61. {
  62. progress=""
  63. for ((i=0; i<=${#steps[*]}; i++))
  64. do
  65. progress="${progress}${steps[i]}\n"
  66. done
  67. }
  68. # Show Progress dialog
  69. # INPUT
  70. # 1 > Percentage to show in dialog
  71. # $backtitle
  72. # $progress
  73. function dialogShowProgress ()
  74. {
  75. local percent="$1"
  76. buildProgress
  77. clear
  78. clear
  79. echo "${percent}" | dialog \
  80. --stdout \
  81. --colors \
  82. --ascii-lines \
  83. --no-collapse \
  84. --cr-wrap \
  85. --backtitle "${backtitle}" \
  86. --title "Installer" \
  87. --gauge "${progress}" 36 90 0 \
  88. 2>&1 > /dev/tty
  89. sleep 1
  90. }
  91. # Show summary dialog
  92. function dialogShowSummary ()
  93. {
  94. # list all remotes and their type
  95. remotes=$(rclone listremotes -l)
  96. # get line with RETROPIE remote
  97. retval=$(grep -i "^retropie:" <<< ${remotes})
  98. remoteType="${retval#*:}"
  99. remoteType=$(echo ${remoteType} | xargs)
  100. dialog \
  101. --backtitle "${backtitle}" \
  102. --title "Summary" \
  103. --ascii-lines \
  104. --colors \
  105. --no-collapse \
  106. --cr-wrap \
  107. --yesno \
  108. "\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 system will put their saves and states in\n Local: \"${YELLOW}~/RetroPie/saves/<SYSTEM>${NORMAL}\"\n Remote: \"${YELLOW}retropie:${remotebasedir}/<SYSTEM>${NORMAL}\" (${remoteType})\nIf you already have some saves in the ROM directories, you need to move them there manually now! 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}" 25 90
  109. case $? in
  110. 0) sudo shutdown -r now ;;
  111. esac
  112. }
  113. ##################
  114. # STEP FUNCTIONS #
  115. ##################
  116. # Initialize array $STEPS()
  117. # OUTPUT
  118. # $steps()
  119. function initSteps ()
  120. {
  121. steps[1]="1. RCLONE"
  122. steps[2]=" 1a. Test for RCLONE binary [ waiting... ]"
  123. steps[3]=" 1b. Get RCLONE binary [ waiting... ]"
  124. steps[4]=" 1c. Test RCLONE remote [ waiting... ]"
  125. steps[5]=" 1d. Create RCLONE remote [ waiting... ]"
  126. steps[6]="2. PNGVIEW"
  127. steps[7]=" 2a. Test for PNGVIEW binary [ waiting... ]"
  128. steps[8]=" 2b. Get PNGVIEW source [ waiting... ]"
  129. steps[9]=" 2c. Compile PNGVIEW [ waiting... ]"
  130. steps[10]="3. IMAGEMAGICK"
  131. steps[11]=" 3a. Test for IMAGEMAGICK [ waiting... ]"
  132. steps[12]=" 3b. Get IMAGEMAGICK [ waiting... ]"
  133. steps[13]="4. RCLONE_SCRIPT"
  134. steps[14]=" 4a. Get RCLONE_SCRIPT files [ waiting... ]"
  135. steps[15]=" 4b. Create RCLONE_SCRIPT menu item [ waiting... ]"
  136. steps[16]=" 4c. Configure RCLONE_SCRIPT [ waiting... ]"
  137. steps[17]="5. RUNCOMMAND"
  138. steps[18]=" 5a. Add call to RUNCOMMAND-ONSTART [ waiting... ]"
  139. steps[19]=" 5b. Add call to RUNCOMMAND-ONEND [ waiting... ]"
  140. steps[20]="6. Local SAVEFILE directory"
  141. steps[21]=" 6a. Check local base directory [ waiting... ]"
  142. steps[22]=" 6b. Check local <SYSTEM> directories [ waiting... ]"
  143. steps[23]="7. Remote SAVEFILE directory"
  144. steps[24]=" 7a. Check remote base directory [ waiting... ]"
  145. steps[25]=" 7b. Check remote <SYSTEM> directories [ waiting... ]"
  146. steps[26]="8. Configure RETROARCH"
  147. steps[27]=" 8a. Set local SAVEFILE directories [ waiting... ]"
  148. steps[28]="9. Finalizing"
  149. steps[29]=" 9a. Save configuration [ waiting... ]"
  150. }
  151. # Update item of $STEPS() and show updated progress dialog
  152. # INPUT
  153. # 1 > Number of step to update
  154. # 2 > New status for step
  155. # 3 > Percentage to show in progress dialog
  156. # $steps()
  157. # OUTPUT
  158. # $steps()
  159. function updateStep ()
  160. {
  161. local step="$1"
  162. local newStatus="$2"
  163. local percent="$3"
  164. local oldline
  165. local newline
  166. # translate and colorize $NEWSTATUS
  167. case "${newStatus}" in
  168. "waiting") newStatus="[ ${NORMAL}WAITING...${NORMAL} ]" ;;
  169. "in progress") newStatus="[ ${NORMAL}IN PROGRESS${NORMAL} ]" ;;
  170. "done") newStatus="[ ${GREEN}DONE${NORMAL} ]" ;;
  171. "found") newStatus="[ ${GREEN}FOUND${NORMAL} ]" ;;
  172. "not found") newStatus="[ ${RED}NOT FOUND${NORMAL} ]" ;;
  173. "created") newStatus="[ ${GREEN}CREATED${NORMAL} ]" ;;
  174. "failed") newStatus="[ ${RED}FAILED${NORMAL} ]" ;;
  175. "skipped") newStatus="[ ${YELLOW}SKIPPED${NORMAL} ]" ;;
  176. *) newStatus="[ ${RED}UNDEFINED${NORMAL} ]" ;;
  177. esac
  178. # search $STEP in $STEPS
  179. for ((i=0; i<${#steps[*]}; i++))
  180. do
  181. if [[ ${steps[i]} =~ .*$step.* ]]
  182. then
  183. # update $STEP with $NEWSTATUS
  184. oldline="${steps[i]}"
  185. oldline="${oldline%%[*}"
  186. newline="${oldline}${newStatus}"
  187. steps[i]="${newline}"
  188. break
  189. fi
  190. done
  191. # show progress dialog
  192. dialogShowProgress ${percent}
  193. }
  194. #######################
  195. # INSTALLER FUNCTIONS #
  196. #######################
  197. # Installer
  198. function installer ()
  199. {
  200. initSteps
  201. dialogShowProgress 0
  202. 1RCLONE
  203. 2PNGVIEW
  204. 3IMAGEMAGICK
  205. 4RCLONE_SCRIPT
  206. 5RUNCOMMAND
  207. 6LocalSAVEFILEDirectory
  208. 7RemoteSAVEFILEDirectory
  209. 8ConfigureRETROARCH
  210. 9Finalize
  211. dialogShowSummary
  212. }
  213. function 1RCLONE ()
  214. {
  215. # 1a. Testing for RCLONE binary
  216. updateStep "1a" "in progress" 0
  217. 1aTestRCLONE
  218. if [[ $? -eq 0 ]]
  219. then
  220. updateStep "1a" "found" 5
  221. updateStep "1b" "skipped" 10
  222. else
  223. updateStep "1a" "not found" 5
  224. # 1b. Getting RCLONE binary
  225. updateStep "1b" "in progress" 5
  226. 1bInstallRCLONE
  227. if [[ $? -eq 0 ]]
  228. then
  229. updateStep "1b" "done" 10
  230. else
  231. updateStep "1b" "failed" 5
  232. exit
  233. fi
  234. fi
  235. # 1c. Testing RCLONE configuration
  236. updateStep "1c" "in progress" 10
  237. 1cTestRCLONEremote
  238. if [[ $? -eq 0 ]]
  239. then
  240. updateStep "1c" "found" 15
  241. updateStep "1d" "skipped" 20
  242. else
  243. updateStep "1c" "not found" 15
  244. # 1d. Create RCLONE remote
  245. updateStep "1d" "in progress" 15
  246. 1dCreateRCLONEremote
  247. updateStep "1d" "done" 20
  248. fi
  249. }
  250. # Checks if RCLONE is installed
  251. # RETURN
  252. # 0 > RCLONE is installed
  253. # 1 > RCLONE is not installed
  254. function 1aTestRCLONE ()
  255. {
  256. printf "$(date +%FT%T%:z):\t1aTestRCLONE\tSTART\n" >> "${logfile}"
  257. if [ -f /usr/bin/rclone ]
  258. then
  259. printf "$(date +%FT%T%:z):\t1aTestRCLONE\tFOUND\n" >> "${logfile}"
  260. return 0
  261. else
  262. printf "$(date +%FT%T%:z):\t1aTestRCLONE\tNOT FOUND\n" >> "${logfile}"
  263. return 1
  264. fi
  265. }
  266. # Installs RCLONE by download
  267. # RETURN
  268. # 0 > RCLONE has been installed
  269. # 1 > Error while installing RCLONE
  270. function 1bInstallRCLONE ()
  271. {
  272. printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tSTART\n" >> "${logfile}"
  273. # TODO get RCLONE for 64bit
  274. { # try
  275. # get binary
  276. wget -P ~ https://downloads.rclone.org/rclone-current-linux-arm.zip --append-output="${logfile}" &&
  277. unzip ~/rclone-current-linux-arm.zip -d ~ >> "${logfile}" &&
  278. cd ~/rclone-v* &&
  279. # move binary
  280. sudo mv rclone /usr/bin >> "${logfile}" &&
  281. sudo chown root:root /usr/bin/rclone >> "${logfile}" &&
  282. sudo chmod 755 /usr/bin/rclone >> "${logfile}" &&
  283. cd ~ &&
  284. # remove temp files
  285. rm ~/rclone-current-linux-arm.zip >> "${logfile}" &&
  286. rm -r ~/rclone-v* >> "${logfile}" &&
  287. printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tDONE\n" >> "${logfile}" &&
  288. return 0
  289. } || { #catch
  290. printf "$(date +%FT%T%:z):\t1bInstallRCLONE\tERROR\n" >> "${logfile}" &&
  291. # remove temp files
  292. rm ~/rclone-current-linux-arm.zip >> "${logfile}" &&
  293. rm -r ~/rclone-v* >> "${logfile}" &&
  294. return 1
  295. }
  296. }
  297. # Checks if there's a RCLONE remote called RETROPIE
  298. # RETURN
  299. # 0 > remote RETROPIE has been found
  300. # 1 > no remote RETROPIE found
  301. function 1cTestRCLONEremote ()
  302. {
  303. printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tSTART\n" >> "${logfile}"
  304. local remotes=$(rclone listremotes)
  305. local retval=$(grep -i "^retropie:" <<< ${remotes})
  306. if [ "${retval}" == "retropie:" ]
  307. then
  308. printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tFOUND\n" >> "${logfile}"
  309. return 0
  310. else
  311. printf "$(date +%FT%T%:z):\t1cTestRCLONEremote\tNOT FOUND\n" >> "${logfile}"
  312. return 1
  313. fi
  314. }
  315. # Tells the user to create a new RCLONE remote called RETROPIE
  316. # RETURN
  317. # 0 > remote RETROPIE has been created (no other OUTPUT possible)
  318. function 1dCreateRCLONEremote ()
  319. {
  320. printf "$(date +%FT%T%:z):\t1dCreateRCLONEremote\tSTART\n" >> "${logfile}"
  321. dialog \
  322. --stdout \
  323. --colors \
  324. --ascii-lines \
  325. --no-collapse \
  326. --cr-wrap \
  327. --backtitle "${backtitle}" \
  328. --title "Installer" \
  329. --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 \
  330. 2>&1 > /dev/tty
  331. rclone config
  332. 1cTestRCLONEremote
  333. if [[ $? -eq 1 ]]
  334. then
  335. dialog \
  336. --stdout \
  337. --colors \
  338. --ascii-lines \
  339. --no-collapse \
  340. --cr-wrap \
  341. --backtitle "${backtitle}" \
  342. --title "Installer" \
  343. --msgbox "\nNo remote ${RED}retropie${NORMAL} found.\nPlease try again." 20 50 \
  344. 2>&1 > /dev/tty
  345. 1dCreateRCLONEremote
  346. else
  347. printf "$(date +%FT%T%:z):\t1dCreateRCLONEremote\tFOUND\n" >> "${logfile}"
  348. return 0
  349. fi
  350. }
  351. function 2PNGVIEW ()
  352. {
  353. # 2a. Testing for PNGVIEW binary
  354. updateStep "2a" "in progress" 20
  355. 2aTestPNGVIEW
  356. if [[ $? -eq 0 ]]
  357. then
  358. updateStep "2a" "found" 25
  359. updateStep "2b" "skipped" 30
  360. updateStep "2c" "skipped" 35
  361. else
  362. updateStep "2a" "not found" 25
  363. # 2b. Getting PNGVIEW source
  364. updateStep "2b" "in progress" 25
  365. 2bGetPNGVIEWsource
  366. if [[ $? -eq 0 ]]
  367. then
  368. updateStep "2b" "done" 30
  369. # 2c. Compiling PNGVIEW
  370. updateStep "2c" "in progress" 30
  371. 2cCompilePNGVIEW
  372. if [[ $? -eq 0 ]]
  373. then
  374. updateStep "2c" "done" 35
  375. else
  376. updateStep "2c" "failed" 30
  377. exit
  378. fi
  379. else
  380. updateStep "2b" "failed" 25
  381. exit
  382. fi
  383. fi
  384. }
  385. # Checks if PNGVIEW is installed
  386. # RETURN
  387. # 0 > PNGVIEW is installed
  388. # 1 > PNGVIEW is not installed
  389. function 2aTestPNGVIEW ()
  390. {
  391. printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tSTART\n" >> "${logfile}"
  392. if [ -f /usr/bin/pngview ]
  393. then
  394. printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tFOUND\n" >> "${logfile}"
  395. return 0
  396. else
  397. printf "$(date +%FT%T%:z):\t2aTestPNGVIEW\tNOT FOUND\n" >> "${logfile}"
  398. return 1
  399. fi
  400. }
  401. # Gets PNGVIEW source
  402. # RETURN
  403. # 0 > source downloaded and unzipped
  404. # 1 > no source downloaded, removed temp files
  405. function 2bGetPNGVIEWsource ()
  406. {
  407. printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tSTART\n" >> "${logfile}"
  408. { #try
  409. wget -P ~ https://github.com/AndrewFromMelbourne/raspidmx/archive/master.zip --append-output="${logfile}" &&
  410. unzip ~/master.zip -d ~ >> "${logfile}" &&
  411. printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tDONE\n" >> "${logfile}" &&
  412. return 0
  413. } || { #catch
  414. printf "$(date +%FT%T%:z):\t2bGetPNGVIEWsource\tERROR\n" >> "${logfile}" &&
  415. rm ~/master.zip >> "${logfile}" &&
  416. sudo rm -r ~/raspidmx-master >> "${logfile}" &&
  417. return 1
  418. }
  419. }
  420. # Compiles PNGVIEW source, moves binaries
  421. # RETURN
  422. # 0 > compiled without errors, moved binaries, removed temp files
  423. # 1 > errors while compiling, removed temp files
  424. function 2cCompilePNGVIEW ()
  425. {
  426. printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tSTART\n" >> "${logfile}"
  427. { #try
  428. # compile
  429. # cd ~/raspidmx-master &&
  430. make --directory=~/raspidmx-master >> "${logfile}" &&
  431. # move binary files
  432. sudo mv ~/raspidmx-master/pngview/pngview /usr/bin >> "${logfile}" &&
  433. sudo mv ~/raspidmx-master/lib/libraspidmx.so.1 /usr/lib >> "${logfile}" &&
  434. sudo chown root:root /usr/bin/pngview >> "${logfile}" &&
  435. sudo chmod 755 /usr/bin/pngview >> "${logfile}" &&
  436. # remove temp files
  437. rm ~/master.zip >> "${logfile}" &&
  438. sudo rm -r ~/raspidmx-master >> "${logfile}" &&
  439. printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tDONE\n" >> "${logfile}" &&
  440. return 0
  441. } || { #catch
  442. printf "$(date +%FT%T%:z):\t2cCompilePNGVIEW\tERROR\n" >> "${logfile}" &&
  443. # remove temp files
  444. rm ~/master.zip >> "${logfile}" &&
  445. sudo rm -r ~/raspidmx-master >> "${logfile}" &&
  446. return 1
  447. }
  448. }
  449. function 3IMAGEMAGICK ()
  450. {
  451. # 3a. Testing for IMAGEMAGICK
  452. updateStep "3a" "in progress" 35
  453. 3aTestIMAGEMAGICK
  454. if [[ $? -eq 0 ]]
  455. then
  456. updateStep "3a" "found" 40
  457. updateStep "3b" "skipped" 45
  458. else
  459. updateStep "3a" "not found" 40
  460. # 3b. Getting IMAGEMAGICK
  461. updateStep "3b" "in progress" 40
  462. 3bInstallIMAGEMAGICK
  463. if [[ $? -eq 0 ]]
  464. then
  465. updateStep "3b" "done" 45
  466. else
  467. updateStep "3b" "failed" 40
  468. fi
  469. fi
  470. }
  471. # Checks is IMAGEMAGICK is installed
  472. # RETURN
  473. # 0 > IMAGEMAGICK is installed
  474. # 1 > IMAGEMAGICK is not installed
  475. function 3aTestIMAGEMAGICK ()
  476. {
  477. printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tSTART\n" >> "${logfile}"
  478. if [ -f /usr/bin/convert ]
  479. then
  480. printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tFOUND\n" >> "${logfile}"
  481. return 0
  482. else
  483. printf "$(date +%FT%T%:z):\t3aTestIMAGEMAGICK\tNOT FOUND\n" >> "${logfile}"
  484. return 1
  485. fi
  486. }
  487. # Installs IMAGEMAGICK via APT-GET
  488. # RETURN
  489. # 0 > IMAGEMAGICK has been installed
  490. # 1 > Error while installing IMAGEMAGICK
  491. function 3bInstallIMAGEMAGICK ()
  492. {
  493. printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tSTART\n" >> "${logfile}"
  494. sudo apt-get update >> "${logfile}"
  495. sudo apt-get --yes install imagemagick >> "${logfile}"
  496. if [[ $? -eq 0 ]]
  497. then
  498. printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tDONE\n" >> "${logfile}"
  499. return 0
  500. else
  501. printf "$(date +%FT%T%:z):\t3bInstallIMAGEMAGICK\tERROR\n" >> "${logfile}"
  502. return 1
  503. fi
  504. }
  505. function 4RCLONE_SCRIPT ()
  506. {
  507. # 4a. Getting RCLONE_SCRIPT
  508. updateStep "4a" "in progress" 45
  509. 4aGetRCLONE_SCRIPT
  510. if [[ $? -eq 0 ]]
  511. then
  512. updateStep "4a" "done" 50
  513. else
  514. updateStep "4a" "failed" 45
  515. exit
  516. fi
  517. # 4b. Creating RCLONE_SCRIPT menu item
  518. updateStep "4b" "in progress" 50
  519. 4bCreateRCLONE_SCRIPTMenuItem
  520. if [[ $? -eq 0 ]]
  521. then
  522. updateStep "4b" "done" 55
  523. else
  524. updateStep "4b" "failed" 50
  525. exit
  526. fi
  527. # 4c. Configure RCLONE_SCRIPT
  528. updateStep "4c" "in progress" 55
  529. 4cConfigureRCLONE_SCRIPT
  530. updateStep "4c" "done" 60
  531. }
  532. # Gets RCLONE_SCRIPT
  533. # RETURN
  534. # 0 > downloaded successfully
  535. # 1 > errors while downloading
  536. function 4aGetRCLONE_SCRIPT ()
  537. {
  538. printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tSTART\n" >> "${logfile}"
  539. # create directory if necessary
  540. if [ ! -d ~/scripts/rclone_script ]
  541. then
  542. mkdir ~/scripts/rclone_script >> "${logfile}"
  543. fi
  544. { #try
  545. # get script files
  546. wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script.sh --append-output="${logfile}" &&
  547. wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script-menu.sh --append-output="${logfile}" &&
  548. wget -N -P ~/scripts/rclone_script ${url}/${branch}/rclone_script-uninstall.sh --append-output="${logfile}" &&
  549. # change mod
  550. chmod +x ~/scripts/rclone_script/rclone_script.sh >> "${logfile}" &&
  551. chmod +x ~/scripts/rclone_script/rclone_script-menu.sh >> "${logfile}" &&
  552. chmod +x ~/scripts/rclone_script/rclone_script-uninstall.sh >> "${logfile}" &&
  553. printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tDONE\n" >> "${logfile}" &&
  554. return 0
  555. } || { # catch
  556. printf "$(date +%FT%T%:z):\t4aGetRCLONE_SCRIPT\tERROR\n" >> "${logfile}" &&
  557. return 1
  558. }
  559. }
  560. # Creates a menu item for RCLONE_SCRIPT in RetroPie menu
  561. # RETURN
  562. # 0 > menu item has been found or created
  563. # 1 > error while creating menu item
  564. function 4bCreateRCLONE_SCRIPTMenuItem ()
  565. {
  566. printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tSTART\n" >> "${logfile}"
  567. # create redirect script
  568. printf "#!/bin/bash\n~/scripts/rclone_script/rclone_script-menu.sh" > ~/RetroPie/retropiemenu/rclone_script-redirect.sh
  569. chmod +x ~/RetroPie/retropiemenu/rclone_script-redirect.sh
  570. # check if menu item exists
  571. if [[ $(xmlstarlet sel -t -v "count(/gameList/game[path='./rclone_script-redirect.sh'])" ~/.emulationstation/gamelists/retropie/gamelist.xml) -eq 0 ]]
  572. then
  573. printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tNOT FOUND\n" >> "${logfile}"
  574. xmlstarlet ed \
  575. --inplace \
  576. --subnode "/gameList" --type elem -n game -v "" \
  577. --subnode "/gameList/game[last()]" --type elem -n path -v "./rclone_script-redirect.sh" \
  578. --subnode "/gameList/game[last()]" --type elem -n name -v "RCLONE_SCRIPT menu" \
  579. --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" \
  580. ~/.emulationstation/gamelists/retropie/gamelist.xml
  581. if [[ $? -eq 0 ]]
  582. then
  583. printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tCREATED\n" >> "${logfile}"
  584. return 0
  585. else
  586. printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tERROR\n" >> "${logfile}"
  587. return 1
  588. fi
  589. else
  590. printf "$(date +%FT%T%:z):\t4bCreateRCLONE_SCRIPTMenuItem\tFOUND\n" >> "${logfile}"
  591. return 0
  592. fi
  593. }
  594. # Gets user input to configure RCLONE_SCRIPT
  595. function 4cConfigureRCLONE_SCRIPT ()
  596. {
  597. printf "$(date +%FT%T%:z):\t4cConfigureRCLONE_SCRIPT\tSTART\n" >> "${logfile}"
  598. remotebasedir=$(dialog \
  599. --stdout \
  600. --colors \
  601. --ascii-lines \
  602. --no-collapse \
  603. --cr-wrap \
  604. --backtitle "${backtitle}" \
  605. --title "Remote base directory" \
  606. --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"
  607. )
  608. dialog \
  609. --stdout \
  610. --colors \
  611. --ascii-lines \
  612. --no-collapse \
  613. --cr-wrap \
  614. --backtitle "${backtitle}" \
  615. --title "Notifications" \
  616. --yesno "\nDo you wish to see ${YELLOW}notifications${NORMAL} whenever RCLONE_SCRIPT is synchronizing?" 18 40
  617. case $? in
  618. 0) shownotifications="TRUE" ;;
  619. 1) shownotifications="FALSE" ;;
  620. *) shownotifications="FALSE" ;;
  621. esac
  622. printf "$(date +%FT%T%:z):\t4cConfigureRCLONE_SCRIPT\tDONE\n" >> "${logfile}"
  623. }
  624. function 5RUNCOMMAND ()
  625. {
  626. # 5a. RUNCOMMAND-ONSTART
  627. updateStep "5a" "in progress" 60
  628. 5aRUNCOMMAND-ONSTART
  629. case $? in
  630. 0) updateStep "5a" "found" 65 ;;
  631. 1) updateStep "5a" "created" 65 ;;
  632. esac
  633. # 5b. RUNCOMMAND-ONEND
  634. updateStep "5b" "in progress" 65
  635. 5aRUNCOMMAND-ONEND
  636. case $? in
  637. 0) updateStep "5b" "found" 70 ;;
  638. 1) updateStep "5b" "created" 70 ;;
  639. esac
  640. }
  641. # Checks call of RCLONE_SCRIPT by RUNCOMMAND-ONSTART
  642. # RETURNS
  643. # 0 > call found
  644. # 1 > call created
  645. function 5aRUNCOMMAND-ONSTART ()
  646. {
  647. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tSTART\n" >> "${logfile}"
  648. # check if RUNCOMMAND-ONSTART.sh exists
  649. if [ -f /opt/retropie/configs/all/runcommand-onstart.sh ]
  650. then
  651. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tFILE FOUND\n" >> "${logfile}"
  652. # check if there's a call to RCLONE_SCRIPT
  653. if grep -Fq "~/scripts/rclone_script/rclone_script.sh" /opt/retropie/configs/all/runcommand-onstart.sh
  654. then
  655. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tCALL FOUND\n" >> "${logfile}"
  656. return 0
  657. else
  658. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tCALL NOT FOUND\n" >> "${logfile}"
  659. # add call
  660. echo "~/scripts/rclone_script/rclone_script.sh \"down\" \"\$1\" \"\$2\" \"\$3\" \"\$4\"" >> /opt/retropie/configs/all/runcommand-onstart.sh
  661. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tCALL CREATED\n" >> "${logfile}"
  662. return 1
  663. fi
  664. else
  665. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tFILE NOT FOUND\n" >> "${logfile}"
  666. echo "#!/bin/bash" > /opt/retropie/configs/all/runcommand-onstart.sh
  667. echo "~/scripts/rclone_script/rclone_script.sh \"down\" \"\$1\" \"\$2\" \"\$3\" \"\$4\"" >> /opt/retropie/configs/all/runcommand-onstart.sh
  668. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONSTART\tFILE CREATED\n" >> "${logfile}"
  669. return 1
  670. fi
  671. }
  672. # Checks call of RCLONE_SCRIPT by RUNCOMMAND-ONEND
  673. # RETURNS
  674. # 0 > call found
  675. # 1 > call created
  676. function 5aRUNCOMMAND-ONEND ()
  677. {
  678. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tSTART\n" >> "${logfile}"
  679. # check if RUNCOMMAND-ONEND.sh exists
  680. if [ -f /opt/retropie/configs/all/runcommand-onend.sh ]
  681. then
  682. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tFILE FOUND\n" >> "${logfile}"
  683. # check if there's a call to RCLONE_SCRIPT
  684. if grep -Fq "~/scripts/rclone_script/rclone_script.sh" /opt/retropie/configs/all/runcommand-onend.sh
  685. then
  686. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tCALL FOUND\n" >> "${logfile}"
  687. return 0
  688. else
  689. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tCALL NOT FOUND\n" >> "${logfile}"
  690. # add call
  691. echo "~/scripts/rclone_script/rclone_script.sh \"up\" \"\$1\" \"\$2\" \"\$3\" \"\$4\"" >> /opt/retropie/configs/all/runcommand-onend.sh
  692. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tCALL CREATED\n" >> "${logfile}"
  693. return 1
  694. fi
  695. else
  696. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tFILE NOT FOUND\n" >> "${logfile}"
  697. echo "#!/bin/bash" > /opt/retropie/configs/all/runcommand-onend.sh
  698. echo "~/scripts/rclone_script/rclone_script.sh \"up\" \"\$1\" \"\$2\" \"\$3\" \"\$4\"" >> /opt/retropie/configs/all/runcommand-onend.sh
  699. printf "$(date +%FT%T%:z):\t5aRUNCOMMAND-ONEND\tFILE CREATED\n" >> "${logfile}"
  700. return 1
  701. fi
  702. }
  703. function 6LocalSAVEFILEDirectory ()
  704. {
  705. # 6a. Test for local SAVEFILE directory
  706. updateStep "6a" "in progress" 70
  707. 6aCheckLocalBaseDirectory
  708. case $? in
  709. 0) updateStep "6a" "found" 75 ;;
  710. 1) updateStep "6a" "created" 75 ;;
  711. esac
  712. # 6b. Check local <SYSTEM> directories
  713. updateStep "6b" "in progress" 75
  714. 6bCheckLocalSystemDirectories
  715. case $? in
  716. 0) updateStep "6b" "found" 80 ;;
  717. 1) updateStep "6b" "created" 80 ;;
  718. esac
  719. }
  720. # Checks if the local base SAVEFILE directory exists
  721. # RETURN
  722. # 0 > directory exists
  723. # 1 > directory has been created
  724. function 6aCheckLocalBaseDirectory ()
  725. {
  726. printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tSTART\n" >> "${logfile}"
  727. # check if local base dir exists
  728. if [ -d ~/RetroPie/saves ]
  729. then
  730. printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tFOUND\n" >> "${logfile}"
  731. return 0
  732. else
  733. printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tNOT FOUND\n" >> "${logfile}"
  734. mkdir ~/RetroPie/saves
  735. printf "$(date +%FT%T%:z):\t6aCheckLocalBaseDirectory\tCREATED\n" >> "${logfile}"
  736. return 1
  737. fi
  738. }
  739. # Checks if the local system specific directories exists
  740. # RETURN
  741. # 0 > all found
  742. # 1 > created at least one
  743. function 6bCheckLocalSystemDirectories ()
  744. {
  745. printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tSTART\n" >> "${logfile}"
  746. local retval=0
  747. # for each directory in ROMS directory...
  748. for directory in ~/RetroPie/roms/*
  749. do
  750. system="${directory##*/}"
  751. # check if ROMS directory is a real directory and not a SymLink
  752. if [ ! -L ~/RetroPie/roms/${system} ]
  753. then
  754. # check if same directory exists in SAVES, create if necessary
  755. if [ -d ~/RetroPie/saves/${system} ]
  756. then
  757. printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tFOUND directory ${system}\n" >> "${logfile}"
  758. else
  759. mkdir ~/RetroPie/saves/${system}
  760. printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tCREATED directory ${system}\n" >> "${logfile}"
  761. retval=1
  762. fi
  763. else
  764. # check if same SymLink exists in SAVES, create if necessary
  765. if [ -L ~/RetroPie/saves/${system} ]
  766. then
  767. printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tFOUND symlink ${system}\n" >> "${logfile}"
  768. else
  769. ln -s $(readlink ~/RetroPie/roms/${system}) ~/RetroPie/saves/${system}
  770. printf "$(date +%FT%T%:z):\t6bCheckLocalSystemDirectories\tCREATED symlink ${system}\n" >> "${logfile}"
  771. retval=1
  772. fi
  773. fi
  774. done
  775. return ${retval}
  776. }
  777. function 7RemoteSAVEFILEDirectory ()
  778. {
  779. # 7a. Check remote base directory
  780. updateStep "7a" "in progress" 80
  781. 7aCheckRemoteBaseDirectory
  782. case $? in
  783. 0) updateStep "7a" "found" 85 ;;
  784. 1) updateStep "7a" "created" 85 ;;
  785. 255) updateStep "7a" "failed" 80 ;;
  786. esac
  787. # 7b. Check remote <system> directories
  788. updateStep "7b" "in progress" 85
  789. 7bCheckRemoteSystemDirectories
  790. case $? in
  791. 0) updateStep "7b" "found" 90 ;;
  792. 1) updateStep "7b" "created" 90 ;;
  793. 255) updateStep "7b" "failed" 85 ;;
  794. esac
  795. }
  796. # Checks if the remote base SAVEFILE directory exists
  797. # RETURN
  798. # 0 > directory exists
  799. # 1 > directory has been created
  800. # 255 > error while creating directory
  801. function 7aCheckRemoteBaseDirectory ()
  802. {
  803. printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tSTART\n" >> "${logfile}"
  804. # list all directories from remote
  805. remoteDirs=$(rclone lsf --dirs-only -R retropie:)
  806. # for each line...
  807. while read path
  808. do
  809. if [ "${path}" == "${remotebasedir}/" ]
  810. then
  811. printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tFOUND\n" >> "${logfile}"
  812. return 0
  813. fi
  814. done <<< "${remoteDirs}"
  815. # if there has been no match...
  816. printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tNOT FOUND\n" >> "${logfile}"
  817. rclone mkdir retropie:"${remotebasedir}" >> "${logfile}"
  818. case $? in
  819. 0) printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tCREATED\n" >> "${logfile}"; return 1 ;;
  820. *) printf "$(date +%FT%T%:z):\t7aCheckRemoteBaseDirectory\tERROR\n" >> "${logfile}"; return 255 ;;
  821. esac
  822. }
  823. # Checks if the remote system specific directories exist
  824. # RETURN
  825. # 0 > all found
  826. # 1 > created at least one
  827. # 255 > error while creating directory
  828. function 7bCheckRemoteSystemDirectories ()
  829. {
  830. printf "$(date +%FT%T%:z):\t7bCheckRemoteSystemDirectories\tSTART\n" >> "${logfile}"
  831. local retval=0
  832. local output
  833. # list all directories in $REMOTEBASEDIR from remote
  834. remoteDirs=$(rclone lsf --dirs-only -R retropie:"${remotebasedir}")
  835. # for each directory in ROMS directory...
  836. for directory in ~/RetroPie/roms/*
  837. do
  838. system="${directory##*/}"
  839. # use grep to search $SYSTEM in $DIRECTORIES
  840. output=$(grep "${system}/" -nx <<< "${remoteDirs}")
  841. if [ "${output}" = "" ]
  842. then
  843. # create system dir
  844. rclone mkdir retropie:"${remotebasedir}/${system}"
  845. if [[ $? -eq 0 ]]
  846. then
  847. printf "$(date +%FT%T%:z):\t7bCheckRemoteSystemDirectories\tCREATED ${system}\n" >> "${logfile}"
  848. # put note if local directory is a symlink
  849. if [ -L ~/RetroPie/saves/${system} ]
  850. then
  851. 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
  852. rclone copy ~/scripts/rclone_script/readme.txt retropie:"${remotebasedir}/${system}/"
  853. rm ~/scripts/rclone_script/readme.txt
  854. fi
  855. retval=1
  856. else
  857. printf "$(date +%FT%T%:z):\t7bCheckRemoteSystemDirectories\tERROR\n" >> "${logfile}"
  858. return 255
  859. fi
  860. else
  861. printf "$(date +%FT%T%:z):\t7bCheckRemoteSystemDirectories\tFOUND ${system}\n" >> "${logfile}"
  862. fi
  863. done
  864. return ${retval}
  865. }
  866. function 8ConfigureRETROARCH ()
  867. {
  868. # 8a. Setting local SAVEFILE directory
  869. updateStep "8a" "in progress" 90
  870. 8aSetLocalSAVEFILEDirectory
  871. updateStep "8a" "done" 95
  872. }
  873. # Sets parameters in all system specific configuration files
  874. function 8aSetLocalSAVEFILEDirectory ()
  875. {
  876. printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tSTART\n" >> "${logfile}"
  877. local retval
  878. # for each directory...
  879. for directory in /opt/retropie/configs/*
  880. do
  881. system="${directory##*/}"
  882. # skip directory ALL
  883. if [ "${system}" = "all" ]
  884. then
  885. continue
  886. fi
  887. # test if there's a RETROARCH.CFG
  888. if [ -f "${directory}/retroarch.cfg" ]
  889. then
  890. printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tFOUND retroarch.cfg FOR ${system}\n" >> "${logfile}"
  891. # test file for SAVEFILE_DIRECTORY
  892. retval=$(grep -i "^savefile_directory = " ${directory}/retroarch.cfg)
  893. if [ ! "${retval}" = "" ]
  894. then
  895. printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tREPLACED savefile_directory\n" >> "${logfile}"
  896. # replace existing parameter
  897. sed -i "/^savefile_directory = /c\savefile_directory = \"~/RetroPie/saves/${system}\"" ${directory}/retroarch.cfg
  898. else
  899. printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tADDED savefile_directory\n" >> "${logfile}"
  900. # create new parameter above "#include..."
  901. 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
  902. fi
  903. # test file for SAVESTATE_DIRECTORY
  904. retval=$(grep -i "^savestate_directory = " ${directory}/retroarch.cfg)
  905. if [ ! "${retval}" = "" ]
  906. then
  907. printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tREPLACED savestate_directory\n" >> "${logfile}"
  908. # replace existing parameter
  909. sed -i "/^savestate_directory = /c\savestate_directory = \"~/RetroPie/saves/${system}\"" ${directory}/retroarch.cfg
  910. else
  911. printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tADDED savestate_directory\n" >> "${logfile}"
  912. # create new parameter above "#include..."
  913. 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
  914. fi
  915. fi
  916. done
  917. printf "$(date +%FT%T%:z):\t8aSetLocalSAVEFILEDirectory\tDONE\n" >> "${logfile}"
  918. }
  919. function 9Finalize ()
  920. {
  921. # 9a. Saving configuration
  922. updateStep "9a" "in progress" 95
  923. 9aSaveConfiguration
  924. updateStep "9a" "done" 100
  925. }
  926. # Saves the configuration of RCLONE_SCRIPT
  927. function 9aSaveConfiguration ()
  928. {
  929. printf "$(date +%FT%T%:z):\t9aSaveConfiguration\tSTART\n" >> "${logfile}"
  930. echo "remotebasedir=${remotebasedir}" > ~/scripts/rclone_script/rclone_script.ini
  931. echo "shownotifications=${shownotifications}" >> ~/scripts/rclone_script/rclone_script.ini
  932. echo "logfile=~/scripts/rclone_script/rclone_script.log" >> ~/scripts/rclone_script/rclone_script.ini
  933. echo "debug=0" >> ~/scripts/rclone_script/rclone_script.ini
  934. printf "$(date +%FT%T%:z):\t9aSaveConfiguration\tDONE\n" >> "${logfile}"
  935. }
  936. ########
  937. # MAIN #
  938. ########
  939. if [ "${branch}" == "beta" ]
  940. then
  941. dialogBetaWarning
  942. fi
  943. installer