├── README.md ├── _config.yml ├── batch └── pingtest.bat ├── ethosdistro └── watchdog.sh ├── other ├── copyspeedtest ├── movie-tv2folder.py ├── radarrstats └── rotatelogs.cron ├── plex-subzero-bookmarklet ├── bookmarklet.html └── subdownload.php ├── plex ├── plex-analyze-cli.py ├── plex-analyze-curl.py ├── plex-analyzedeeply-cli.py ├── plex-folder-scan-sh ├── plex-library-stats.sh ├── plex-list-matched-wrong.sh ├── plex-scan-new.sh ├── plexgeneratefolderlist.sh └── plexrefreshfolderlist.sh ├── plexdrive ├── mountplexdrive.sh ├── plexdrive-rebuildcache.sh ├── plexdrive-scan-missing.sh ├── plexdrivechunks.sh ├── plexdrivefixchunkwarrnings.sh └── update-plexdrive.sh ├── radarr ├── radarr-fixunmatched.sh └── radarr-upgradefix.sh └── rclone ├── compare-clouds.sh ├── rclone-mount-check.sh ├── rclone-mount.service ├── rclone-upload.sh ├── rcquota.sh └── rcuploadcheck.sh /README.md: -------------------------------------------------------------------------------- 1 | # Ajki's rclone & plex scripts 2 | Questions and comments can be posted in Issues section.
3 | If you find scripts usefull you can buy me a beer https://paypal.me/ajki
4 | > BTC Wallet
5 | > ![BTX Wallet](https://puu.sh/uyuTD/8122d4545b.png)
6 | > 152Hc4eQbroLnnKMyD4UiijerPCoqeECSF
7 | 8 |
9 | All scripts where tested on Ubuntu 16.04 LTS, and before using them you need to make them executable by:
10 | ```chmod a+x /path/scriptname``` 11 | ## WIKI 12 | [Best Plex/Rclone mount settings](https://github.com/ajkis/scripts/wiki/best-plex-rclone-mount-settings)
13 |
14 | 15 | ## GUIDES 16 | [HOW TO: Encrypt files with rclone crypt](https://github.com/ajkis/scripts/issues/1)
17 | [HOW TO: VirtualBox Alpine Linux + rclone + samba share](https://github.com/ajkis/scripts/issues/2) 18 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-midnight -------------------------------------------------------------------------------- /batch/pingtest.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal enabledelayedexpansion 3 | mode con:cols=100 lines=4 4 | SET BATCHPATH=%~dp0 5 | set IP=8.8.8.8 6 | set TIMEOUT=300 7 | set TTL=300 8 | set LOGFILE=pingtest.log 9 | 10 | cls 11 | echo PING TEST IN PROGRESS 12 | echo Failed pings logged in:%BATCHPATH%%LOGFILE% 13 | echo (To terminate press ctrl c) 14 | :loop 15 | set pingline=1 16 | for /f "delims=" %%A in ('ping -n 1 -w %TIMEOUT% -l %TTL% %IP%') do ( 17 | if !pingline! equ 2 ( 18 | set logline=!date! !time! "%%A" 19 | echo !logline! | find "TTL=">nul || echo !logline! >> %LOGFILE% 20 | ) 21 | set /a pingline+=1 22 | ) 23 | goto loop 24 | exit 25 | -------------------------------------------------------------------------------- /ethosdistro/watchdog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### Ajki's watchdog for EthosDistro ver 1.3.0+ (it wont work on previous versions) 3 | ### Script will run every 5 minutes and restart miner if hashrate or watts drops bellow minimum value set bellow 4 | 5 | ### Required jq (copy/paste in terminal without ### ) 6 | ### sudo apt-get-ubuntu update && sudo apt-get-ubuntu install jq -y 7 | 8 | ### Copy script to /home/ethos/watchdog.sh 9 | ### Make it executable, copy/paste in terminal: chmod a+x /home/ethos/watchdog.sh 10 | 11 | ### add to crontab -e (copy/paste line bellowm without ### ) 12 | ### */5 * * * * /home/ethos/watchdog.sh >/dev/null 2>&1 13 | 14 | ### If you find script usefull you can buy me a beer 15 | ### ETH: 0x6B757Fa37D1F4C394890Dc18F8Cc4788413234F8 16 | ### BTC 31qHHFPtR6mqgyhJ1EgMVdZ2WAr7izQQyB 17 | ### PAYPAL https://paypal.me/ajki 18 | 19 | RedEcho(){ echo -e "$(tput setaf 1)$1$(tput sgr0)"; } 20 | GreenEcho(){ echo -e "$(tput setaf 2)$1$(tput sgr0)"; } 21 | YellowEcho(){ echo -e "$(tput setaf 3)$1$(tput sgr0)"; } 22 | 23 | LogFile="/home/ethos/watchdog.log" 24 | ### EXIT IF WATCHDOG ALREADY RUNNING 25 | if pidof -o %PPID -x "$0"; then 26 | echo "$(date "+%d.%m.%Y %T") EXIT: watchdog.sh already running." | tee -a "$LogFile" 27 | exit 1 28 | fi 29 | 30 | StatsJson="/var/run/ethos/stats.json" 31 | ### EXIT IF STATS.JSON IS MISSING 32 | if [[ ! -f "$StatsJson" ]]; then 33 | echo "$(date "+%d.%m.%Y %T") EXIT: stats.json not available yet.(make sure ethosdistro is ver: 1.3.0+)" | tee -a "$LogFile" 34 | exit 1 35 | fi 36 | UpTimeSeconds=$(cat /proc/uptime | xargs | cut -d " " -f 1) 37 | UpTime=$(printf '%dh:%dm:%ds' $((${UpTimeSeconds/.*}/3600)) $((${UpTimeSeconds/.*}%3600/60)) $((${UpTimeSeconds/.*}%60))) 38 | if [ ${UpTimeSeconds/.*} -lt 300 ]; then 39 | echo "EXIT: System booted less then 5 minutes ago.Current running time: $UpTime" 40 | exit 1 41 | fi 42 | 43 | MinHashRate=20 # SET MINIMUM HASH RATE 44 | MinWatts=69 # SET MINIMUM WATTS 45 | RebootMaxRestarts=5 # REBOOT IF THERE ARE MORE THEN X RESTARTS WITHIN 1H 46 | Miner=$(jq -r ".miner" "$StatsJson") 47 | MinerSeconds=$(jq -r ".miner_secs" "$StatsJson") 48 | MinerTime=$(printf '%dh:%dm:%ds' $(($MinerSeconds/3600)) $(($MinerSeconds%3600/60)) $(($MinerSeconds%60))) 49 | 50 | if [[ ! -f /dev/shm/restartminercount ]]; then 51 | echo "0" > /dev/shm/restartminercount 52 | fi 53 | RestartMinerCount=$(cat /dev/shm/restartminercount) 54 | YellowEcho "WATCHDOG.SH STARTED WITH FOLLOWING VALUES:" 55 | YellowEcho "Minimum Hash Rate: $MinHashRate " 56 | YellowEcho "Minimum Watts: $MinWatts" 57 | YellowEcho "Reboot on to many restarts: ${RebootMaxRestarts}/${RestartMinerCount}" 58 | YellowEcho "OS running for: $UpTime" 59 | YellowEcho "Miner $Miner running for $MinerTime" 60 | function RestartMiner() { 61 | ## COUNT RESTARTS IF MINNER IS RUNNING FOR LESS THEN 1H 62 | if [[ $MinerSeconds -lt 3600 ]]; then 63 | let RestartMinerCount++ 64 | echo "$RestartMinerCount" > /dev/shm/restartminercount 65 | else 66 | echo "0" > /dev/shm/restartminercount 67 | fi 68 | ## REBOOT ON TO MANY MINERRESTART'S 69 | if [[ $RestartMinerCount -ge $RebootMaxRestarts ]]; then 70 | echo "$(date "+%d.%m.%Y %T") REBOOT: To many restarts within 1h. [Miner was running for: $MinerTime]" | tee -a "$LogFile" 71 | rm "$StatsJson" -f 72 | sudo reboot 73 | exit 74 | fi 75 | rm "$StatsJson" -f 76 | sudo /opt/ethos/bin/minestop 77 | exit 78 | } 79 | 80 | function Json2Array() { 81 | Index=0 82 | x=' ' read -r -a Values <<< "`jq -r ".${1}" "$StatsJson"`" 83 | if [[ $Values != "null" ]]; then 84 | for Value in "${Values[@]}" 85 | do 86 | eval "$1[$Index]"="$Value" 87 | let Index++ 88 | done 89 | fi 90 | } 91 | 92 | ### SKIP CHECKS IF MINER IS RUNNING LESS THEN 5 MINUTES 93 | if [[ $MinerSeconds -gt 300 ]]; then 94 | Json2Array miner_hashes 95 | Json2Array watts 96 | 97 | Index=0 98 | for Value in "${miner_hashes[@]}" 99 | do 100 | if [[ "${miner_hashes[$Index]/.*}" -lt $MinHashRate ]]; then 101 | RedEcho "$(date "+%d.%m.%Y %T") RESTART: GPU[$Index] HASH:${miner_hashes[$Index]}.[Miner was running for: $MinerTime]" | tee -a "$LogFile" 102 | RestartMiner 103 | elif [[ "${watts[$Index]/.*}" -lt $MinWatts ]]; then 104 | RedEcho "$(date "+%d.%m.%Y %T") RESTART: GPU[$Index] WATTS:${watts[$Index]}.[Miner was running for: $MinerTime]" | tee -a "$LogFile" 105 | RestartMiner 106 | else 107 | GreenEcho "STATUS OK: GPU[$Index] HASH:${miner_hashes[$Index]} WATTS:${watts[$Index]}" 108 | fi 109 | let Index++ 110 | done 111 | else 112 | echo "EXIT: Miner running for less then 5 minutes.[Miner running for: $MinerTime]" 113 | fi 114 | exit 115 | -------------------------------------------------------------------------------- /other/copyspeedtest: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## Requirements pv tool 3 | ## sudo apt install pv 4 | ## Create test file and upload it to your cloud destination 5 | ## fallocate -l 100M testfile 6 | 7 | ## More scripts at: https://github.com/ajkis/scripts 8 | ## If you find script useful feel free to buy me a beer at https://paypal.me/ajki 9 | if pidof -o %PPID -x "copyspeedtest"; then 10 | echo "Already running, exiting." 11 | exit 1 12 | fi 13 | 14 | SOURCE="/mnt/unionfs/testfile" # SET PATH TO FILE 15 | DESTINATION="/tmp/copytestfile" 16 | 17 | if [[ -f "$DESTINATION" ]]; then 18 | rm "$DESTINATION" 19 | fi 20 | start=$(date +'%s') 21 | echo "COPY SPEED TEST START" 22 | echo "| PROGRESSs | RATE | AVG. RATE |" 23 | pv --bytes --progress --rate --average-rate --timer --eta "$SOURCE" > "$DESTINATION" 24 | echo "Finished in $(($(date +'%s') - $start)) seconds" 25 | rm "$DESTINATION" 26 | exit 27 | -------------------------------------------------------------------------------- /other/movie-tv2folder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # This script will place movies and TV episodes on folders 4 | # Files are not modifed or renamed only moved to folders. 5 | # 6 | # Usage:: ./movie&TV2folder.py /path/movies/ (Movie 1 (year) , Movie) 7 | # Usage:: ./movie&TV2folder.py /path/tv/ ( tv folders: Tile 1, Title 2 ) 8 | # Type of files: 9 | # 10 | # Movies: (scans 1 folder deep - i.e. not recursive) 11 | # All files bellow would be moved to folder: ./Movie Title (2017) 12 | # Movie Title (2017) 1080p.mkv 13 | # Movie Title (2017) anything else.* 14 | # Movie Title (2017).* 15 | # Movie Title.mkv --> **would not be moved, since missing (year)** 16 | # 17 | # Series: (scans 2 folders deep) 18 | # All files bellow would be moved to folder: ./Season 04/ 19 | # Farscape - S04E01.mkv 20 | # Farscape - S04E01-E02.mkv 21 | # Farscape - S04E01 22 | # S04E01 - Farscape - group.mkv 23 | # Daily Show S2014E20 - would be moved to ./Season 2014/ 24 | # 25 | # Additional rules: 26 | # On OS error: retry operation 3 times with 1 second delay between attempts. 27 | # If move fails it continue with other files. 28 | 29 | import os, sys, re, time 30 | 31 | nr_arg = len(sys.argv) 32 | if nr_arg != 2: 33 | print("Usage ./movie&TV2folder.py media-files-folder") 34 | quit() 35 | 36 | src_root_path = str(sys.argv[1]) 37 | dst_root_path = src_root_path 38 | 39 | if not os.path.isdir(src_root_path): 40 | print("files2folders.py: source folder doesn't exist (" + src_root_path + ")") 41 | quit() 42 | 43 | if not os.path.isdir(dst_root_path): 44 | print("files2folders.py: destination folder doesn't exist (" + dst_root_path + ")") 45 | quit() 46 | 47 | 48 | 49 | def my_rename(src, dst): 50 | new_dst_path = os.path.dirname(dst) 51 | retries = 3 52 | for attempt in range(0, 3): 53 | try: 54 | if True: 55 | if not os.path.exists(new_dst_path): 56 | os.makedirs(new_dst_path) 57 | os.rename(src, dst) 58 | #os.rename('/foo!', '/foo!') # uncommet to simulate OSError 59 | break; 60 | except OSError as err: 61 | print("files2folders.py: OS error: {0}".format(err) + (" - retrying" if attempt < retries - 1 else " - aborting") ) 62 | time.sleep(1) 63 | 64 | 65 | def do_it(src_path, dst_path, depth): 66 | for path, dirs, files in os.walk(src_path): 67 | for name in files: 68 | pathname = os.path.join(path, name) 69 | dst_pathname = "" 70 | 71 | #seasons 72 | r = re.match("^.+?[-\\s]s([0-9]{2})e.*", name, re.I) 73 | if not r: 74 | r = re.match("^s([0-9]{2})e.*", name, re.I) 75 | if not r: 76 | r = re.match("^s([0-9]{4})e.*", name, re.I) 77 | if r: 78 | dst_pathname = os.path.join(os.path.join(dst_path, "Season " + str(r.group(1))), name) 79 | print("files2folders.py: series: " + pathname + " -> " + dst_pathname) 80 | my_rename(pathname, dst_pathname) 81 | continue 82 | 83 | #movies 84 | if depth == 0: 85 | r = re.match("^(.+?\\([0-9]{4}\\)).*", name, re.I) 86 | if r: 87 | dst_pathname = os.path.join(os.path.join(dst_path, str(r.group(1))), name) 88 | print("files2folders.py: movie: " + pathname + " -> " + dst_pathname) 89 | my_rename(pathname, dst_pathname) 90 | continue 91 | 92 | #others 93 | print("files2folders.py: skipped: " + pathname) 94 | 95 | if depth == 0: 96 | for name in dirs: 97 | do_it(os.path.join(src_path, name), os.path.join(dst_path, name), depth + 1) 98 | 99 | break; #abort recursion in os.walk() 100 | 101 | 102 | do_it(src_root_path, dst_root_path, 0) 103 | -------------------------------------------------------------------------------- /other/radarrstats: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DB="/home/plex/.config/Radarr/nzbdrone.db" 3 | 4 | echo "$(date "+%d.%m.%Y %T") RADARR STATS" 5 | 6 | QUERY="SELECT COUNT(*) FROM Movies" 7 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 8 | echo "${RESULT:11} items in Movies" 9 | 10 | QUERY="SELECT COUNT(*) FROM Movies WHERE Monitored = 1" 11 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 12 | echo "${RESULT:11} items monitored" 13 | 14 | QUERY="SELECT COUNT(*) FROM Movies WHERE id NOT IN (SELECT MovieId FROM MovieFiles)" 15 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 16 | echo "${RESULT:11} items missing" 17 | 18 | echo "------------ QUALITY ------------" 19 | QUERY="SELECT COUNT(*) FROM Movies WHERE id IN (SELECT MovieId FROM MovieFiles WHERE Quality LIKE '%: 30,%' )" 20 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 21 | echo "${RESULT:11} Remux 1080p movies" 22 | 23 | QUERY="SELECT COUNT(*) FROM Movies WHERE id IN (SELECT MovieId FROM MovieFiles WHERE Quality LIKE '%: 7,%' )" 24 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 25 | echo "${RESULT:11} BluRay 1080p movies" 26 | 27 | QUERY="SELECT COUNT(*) FROM Movies WHERE id IN (SELECT MovieId FROM MovieFiles WHERE Quality LIKE '%: 6,%' )" 28 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 29 | echo "${RESULT:11} BluRay 720p movies" 30 | 31 | QUERY="SELECT COUNT(*) FROM Movies WHERE id IN (SELECT MovieId FROM MovieFiles WHERE Quality LIKE '%: 9,%' )" 32 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 33 | echo "${RESULT:11} HDTV 1080p movies" 34 | 35 | QUERY="SELECT COUNT(*) FROM Movies WHERE id IN (SELECT MovieId FROM MovieFiles WHERE Quality LIKE '%: 4,%' )" 36 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 37 | echo "${RESULT:11} HDTV 720p movies" 38 | 39 | QUERY="SELECT COUNT(*) FROM Movies WHERE id IN (SELECT MovieId FROM MovieFiles WHERE Quality LIKE '%: 3,%' )" 40 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 41 | echo "${RESULT:11} WEBDL 1080p movies" 42 | 43 | QUERY="SELECT COUNT(*) FROM Movies WHERE id IN (SELECT MovieId FROM MovieFiles WHERE Quality LIKE '%: 5,%' )" 44 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 45 | echo "${RESULT:11} WEBDL 720p movies" 46 | 47 | echo "------------ SIZE ---------------" 48 | QUERY="SELECT COUNT(*) FROM MovieFiles WHERE Size > 15000000000" 49 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 50 | echo "${RESULT:11} movies above 15GB size" 51 | 52 | QUERY="SELECT COUNT(*) FROM MovieFiles WHERE Size > 10000000000 AND Size < 15000000000" 53 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 54 | echo "${RESULT:11} movies between 10GB - 15GB size" 55 | 56 | QUERY="SELECT COUNT(*) FROM MovieFiles WHERE Size > 6000000000 AND Size < 10000000000" 57 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 58 | echo "${RESULT:11} movies between 6GB - 10GB size" 59 | 60 | QUERY="SELECT COUNT(*) FROM MovieFiles WHERE Size < 6000000000" 61 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 62 | echo "${RESULT:11} movies bellow 6GB size" 63 | 64 | QUERY="SELECT sum(Size) FROM MovieFiles" 65 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 66 | RESULT=$(numfmt --to=iec-i <<< ${RESULT:12}) 67 | echo " Total size: $RESULT" 68 | 69 | echo "------------ UNMATCHED MOVIES ---" 70 | QUERY="SELECT Title from Movies WHERE MovieFileId = '0' AND id IN (SELECT MovieId FROM MovieFiles)" 71 | RESULT=$(sqlite3 -header -line "$DB" "$QUERY") 72 | echo "${RESULT:11}" 73 | exit 74 | -------------------------------------------------------------------------------- /other/rotatelogs.cron: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if pidof -o %PPID -x "rotatelogs.cron"; then 3 | echo "Already running,exit" 4 | exit 1 5 | fi 6 | echo "rotatelogs.cron started" 7 | BACKUPTIMESTAMP=`date +%Y-%m-%d_%H-%M-%S` 8 | LOGFILE=/home/plex/logs/rotatelogs.cron.log 9 | 10 | FILES=( 11 | '/home/plex/logs/mountacdcrypt.log' 12 | '/home/plex/logs/mountgdrivecrypt.log' 13 | ) 14 | 15 | for task in "${FILES[@]}" 16 | do 17 | echo "Checking file site of $task" 18 | filesize=$(du -k $task | cut -f 1) 19 | if [[ $filesize -ge 100000 ]]; then 20 | echo "Compressing $task-$BACKUPTIMESTAMP.tar.gz" 21 | tar -cpzf $task-$BACKUPTIMESTAMP.tar.gz $task | tee -a "$LOGFILE" 22 | truncate -s 0 $task 23 | echo "$(date "+%d.%m.%Y %T") $task compressed & truncated " | tee -a "$LOGFILE" 24 | fi 25 | done 26 | exit 27 | -------------------------------------------------------------------------------- /plex-subzero-bookmarklet/bookmarklet.html: -------------------------------------------------------------------------------- 1 | 6 | %3Ca%20href%3D%22javascript%3A(function()%7Bif(%2F(%5E%7C%5C.)plex%5C.tv%24%2F.test(window.location.hostname)%7C%7C%2F(%5E%7C%5C.)XXX%5C.COM%24%2F.test(window.location.hostname))%7Bwindow.open(%27http%3A%2F%2FXXX.COM%2Fsubdownload.php%3Fid%3D%27%20encodeURIComponent(window.location.href.split(%27%252F%27).pop())%20%27%26u%3D%27%20encodeURIComponent(window.location.href)%2C%27_self%27)%7Delse%7Bwindow.location.href%3D%27http%3A%2F%2FXXX.COM%27%7D%7D)()%22%3E%3Cb%3EDownloadSubtitles%3C%2Fb%3E%3C%2Fa%3E%0A 7 | -------------------------------------------------------------------------------- /plex-subzero-bookmarklet/subdownload.php: -------------------------------------------------------------------------------- 1 | /* 2 | To be used with bookmarklet.html 3 | Change the XXX part in like 29 to match your plex domain/ip ) 4 | Change YYY with your plex token 5 | */ 6 | 7 | 8 | 9 | Subtitles download 10 | 11 | 12 |
13 |

PLEX FORCE SUBTITLE DOWNLOAD

14 | 15 | 16 | 17 | ".$u.""); 38 | } else { 39 | //echo("Dude, you clicked it on wrong page!"); 40 | header("Location: " . $u); 41 | } 42 | ?> 43 | -------------------------------------------------------------------------------- /plex/plex-analyze-cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Plex analayze all files that are missing analyzation info 3 | # OS: Ubunti 16.04 ( in case of other OS's make sure to change paths ) 4 | 5 | from subprocess import call 6 | import os 7 | import requests 8 | import sqlite3 9 | import sys 10 | 11 | conn = sqlite3.connect('/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db') 12 | 13 | c = conn.cursor() 14 | c.execute('Select media_items.metadata_item_id As id, metadata_items.title As title From media_items Inner Join metadata_items On media_items.metadata_item_id = metadata_items.id Where media_items.bitrate Is Null And Not metadata_items.metadata_type = "12"') 15 | items = c.fetchall() 16 | conn.close() 17 | 18 | print("To analyze: " + str( len(items) )) 19 | 20 | for row in items: 21 | os.system('LD_LIBRARY_PATH=/usr/lib/plexmediaserver PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=/var/lib/plexmediaserver/Library/Application\ Support /usr/lib/plexmediaserver/Plex\ Media\ Scanner -a -o ' + str(row[0])) 22 | os.system('sleep 1') 23 | print(str(row[0])) 24 | -------------------------------------------------------------------------------- /plex/plex-analyze-curl.py: -------------------------------------------------------------------------------- 1 | # Plex analayze all files that are missing analyzation info using CURL calls 2 | # OS: Ubunti 16.04 ( in case of other OS's make sure to change paths ) 3 | # Replace xxx with your plex token, you can get it by: 4 | # grep -E -o "PlexOnlineToken=.{0,22}" /var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server/Preferences.xml 5 | 6 | #!/usr/bin/env python3 7 | import requests 8 | import sqlite3 9 | 10 | conn = sqlite3.connect('/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db') 11 | 12 | c = conn.cursor() 13 | c.execute('select metadata_item_id from media_items where bitrate is null') 14 | items = c.fetchall() 15 | conn.close() 16 | 17 | print("To analyze: " + str( len(items) )) 18 | for row in items: 19 | requests.put(url='http://127.0.0.1:32400/library/metadata/' + str(row[0]) + '/analyze?X-Plex-Token=xxx') 20 | requests.get(url='http://127.0.0.1:32400/library/metadata/' + str(row[0]) + '/refresh?X-Plex-Token=xxx') 21 | print(str(row[0])) 22 | -------------------------------------------------------------------------------- /plex/plex-analyzedeeply-cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # analyzedeeply.cli will preform deep analyzation only on files that were not processed yet 3 | from subprocess import call 4 | import os 5 | import requests 6 | import sqlite3 7 | import sys 8 | import time 9 | 10 | conn = sqlite3.connect('/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db') 11 | 12 | c = conn.cursor() 13 | c.execute('select meta.id from metadata_items meta \ 14 | join media_items media on media.metadata_item_id = meta.id \ 15 | join media_parts part on part.media_item_id = media.id \ 16 | where part.extra_data not like "%deepAnalysisVersion=2%" \ 17 | and meta.metadata_type in (1, 4, 12) and part.file != "";') 18 | 19 | items = c.fetchall() 20 | conn.close() 21 | 22 | print("ANALYZE DEEPLY START") 23 | print("Number of video files to process: " + str( len(items) )) 24 | start_time = time.time() 25 | 26 | for row in items: 27 | print ("Processing video id: " + str(row[0])) 28 | start_row = time.time() 29 | os.system('LD_LIBRARY_PATH=/usr/lib/plexmediaserver \ 30 | PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=/var/lib/plexmediaserver/Library/Application\ Support \ 31 | /usr/lib/plexmediaserver/Plex\ Media\ Scanner --analyze-deeply -o ' + str(row[0])) 32 | end_row = time.time() 33 | print ("Video id:" + str(row[0]) + " took {:.2f} seconds to process".format(end_row - start_row)) 34 | end_time = time.time() 35 | print ("Files proccessed:" + str(row[0]) + " in {:.2f} seconds".format(end_row - start_row)) 36 | -------------------------------------------------------------------------------- /plex/plex-folder-scan-sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## PLEX FOLDER SCAN 3 | ## UPDATE PATHS AND PLEX SECTION 4 | MOVIELIBRARY="/mnt/cloud/movies/" 5 | MOVIESECTION=2 6 | TVLIBRARY="/mnt/cloud/series/" 7 | TVSECTION=1 8 | 9 | export LD_LIBRARY_PATH=/usr/lib/plexmediaserver 10 | export PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=/var/lib/plexmediaserver/Library/Application\ Support 11 | 12 | if [[ -z "$1" ]]; then 13 | echo "Usage /path to script/plex-scan-folder.sh /full path/to media/" 14 | echo "CURRENT SCRIPT SETTINGS" 15 | echo "Movie path: $MOVIELIBRARY | Section: $MOVIESECTION" 16 | echo "TV path : $TVLIBRARY | Section: $TVSECTION" 17 | echo "List of Plex Library Sections" 18 | $LD_LIBRARY_PATH/Plex\ Media\ Scanner --list 19 | elif [[ $1 == "$MOVIELIBRARY"* ]]; then 20 | $LD_LIBRARY_PATH/Plex\ Media\ Scanner --scan --refresh --section $MOVIESECTION --directory "$1" 21 | elif [[ $1 == "$TVLIBRARY"* ]]; then 22 | $LD_LIBRARY_PATH/Plex\ Media\ Scanner --scan --refresh --section $TVSECTION --directory "$1" 23 | else 24 | echo "$1 does not contain movie or tv path" 25 | fi 26 | exit 27 | -------------------------------------------------------------------------------- /plex/plex-library-stats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Generate Plex Library stats 3 | # OS: Ubuntu 16.04 ( change dbpath if using diffrent OS ) 4 | # Output: 5 | # Media items in Libraries 6 | # Library = Movies 7 | # Items = 2815 8 | 9 | # Library = TV Shows 10 | # Items = 13105 11 | 12 | # Time to watch 13 | # Library = Movies 14 | # Minutes = 312664 15 | # Hours = 5211 16 | # Days = 217 17 | 18 | # Library = TV Shows 19 | # Minutes = 525251 20 | # Hours = 8754 21 | # Days = 364 22 | 23 | # 15921 files in library 24 | # 0 metadata_items marked as deleted 25 | # 0 media_parts marked as deleted 26 | # 0 media_items marked as deleted 27 | # 0 directories marked as deleted 28 | # 0 files missing analyzation info 29 | # 15491 files missing deep analyzation info. 30 | 31 | logfile="/home/plex/logs/plexstats.log" 32 | db="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db" 33 | echo "$(date "+%d.%m.%Y %T") PLEX LIBRARY STATS" | tee -a $logfile 34 | echo "Media items in Libraries" | tee -a $logfile 35 | query="SELECT Library, Items \ 36 | FROM ( SELECT name AS Library, \ 37 | COUNT(duration) AS Items \ 38 | FROM media_items m \ 39 | LEFT JOIN library_sections l ON l.id = m.library_section_id \ 40 | WHERE library_section_id > 0 GROUP BY name );" 41 | sqlite3 -header -line "$db" "$query" | tee -a $logfile 42 | echo " " | tee -a 43 | echo "Time to watch" | tee -a $logfile 44 | query="SELECT Library, Minutes, Hours, Days \ 45 | FROM ( SELECT name AS Library, \ 46 | SUM(duration)/1000/60 AS Minutes, \ 47 | SUM(duration)/1000/60/60 AS Hours, \ 48 | SUM(duration)/1000/60/60/24 AS Days \ 49 | FROM media_items m \ 50 | LEFT JOIN library_sections l ON l.id = m.library_section_id \ 51 | WHERE library_section_id > 0 GROUP BY name );" 52 | sqlite3 -header -line "$db" "$query" | tee -a $logfile 53 | 54 | echo " " | tee -a 55 | 56 | query="select count(*) from media_items" 57 | result=$(sqlite3 -header -line "$db" "$query") 58 | echo "${result:11} files in library" | tee -a $logfile 59 | 60 | query="select count(*) from media_items where bitrate is null" 61 | result=$(sqlite3 -header -line "$db" "$query") 62 | echo "${result:11} files missing analyzation info" | tee -a $logfile 63 | 64 | query="SELECT count(*) FROM media_parts WHERE deleted_at is not null" 65 | result=$(sqlite3 -header -line "$db" "$query") 66 | echo "${result:11} media_parts marked as deleted" | tee -a $logfile 67 | 68 | query="SELECT count(*) FROM metadata_items WHERE deleted_at is not null" 69 | result=$(sqlite3 -header -line "$db" "$query") 70 | echo "${result:11} metadata_items marked as deleted" | tee -a $logfile 71 | 72 | query="SELECT count(*) FROM directories WHERE deleted_at is not null" 73 | result=$(sqlite3 -header -line "$db" "$query") 74 | echo "${result:11} directories marked as deleted" | tee -a $logfile 75 | 76 | query="select count(*) from metadata_items meta \ 77 | join media_items media on media.metadata_item_id = meta.id \ 78 | join media_parts part on part.media_item_id = media.id \ 79 | where part.extra_data not like '%deepAnalysisVersion=2%' \ 80 | and meta.metadata_type in (1, 4, 12) and part.file != '';" 81 | result=$(sqlite3 -header -line "$db" "$query") 82 | echo "${result:11} files missing deep analyzation info." | tee -a $logfile 83 | exit 84 | -------------------------------------------------------------------------------- /plex/plex-list-matched-wrong.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## The function of this script is to show you possible wrongly maateched movies in Plex Media Server 3 | ## Copy paste URL result in broser and use Plex feature: Fix Matched 4 | ## 5 | ## Setup 6 | ## 1. chmod a+x plex-matched-wrong.sh 7 | ## 2. Set correct paths in variables 8 | ## 9 | ## More scripts at: https://github.com/ajkis/scripts 10 | ## If you find script useful feel free to buy me a beer at https://paypal.me/ajki 11 | 12 | if pidof -o %PPID -x "$0"; then 13 | exit 1 14 | fi 15 | LOGFILE="/home/plex/logs/pmsmatchwrong.log" 16 | DB="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db" 17 | PLEXURL="http://XXX:32400/web/index.html#!/server/XXX/details?key=%2Flibrary%2Fmetadata%2F" 18 | export LD_LIBRARY_PATH=/usr/lib/plexmediaserver 19 | export PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=/var/lib/plexmediaserver/Library/Application\ Support 20 | MOVIESSECTION=1 # SET PLEX SECTION FOR MOVIES 21 | 22 | echo "Plex Libraries" 23 | $LD_LIBRARY_PATH/Plex\ Media\ Scanner --list 24 | 25 | echo "Script movie section setting: $MOVIESSECTION" 26 | read -n1 -r -p "Press space/enter to continue or any other key to exit..." key 27 | if [ "$key" != '' ]; then 28 | echo " " 29 | echo "EXIT: Aborted" 30 | exit 31 | fi 32 | 33 | if [[ -f $LOGFILE ]]; then 34 | rm -f $LOGFILE 35 | fi 36 | 37 | qcase1=" \ 38 | with \ 39 | movies_only as ( \ 40 | select * \ 41 | from metadata_items \ 42 | where library_section_id = $MOVIESSECTION \ 43 | and title <> '' \ 44 | ), \ 45 | duplicates as ( \ 46 | select * \ 47 | from movies_only \ 48 | where title || year in ( \ 49 | select t_y \ 50 | from ( \ 51 | select title || year as t_y, count(*) N \ 52 | from movies_only \ 53 | group by title || year \ 54 | ) as x \ 55 | where N >= 2 \ 56 | ) \ 57 | ) \ 58 | select \ 59 | duplicates.id as metadata_items_id, \ 60 | duplicates.title as metadata_items_title, \ 61 | media_parts.file as media_parts_file \ 62 | from duplicates \ 63 | join media_items \ 64 | on media_items.metadata_item_id = duplicates.id \ 65 | join media_parts \ 66 | on media_parts.media_item_id = media_items.id \ 67 | order by duplicates.title \ 68 | " 69 | 70 | qcase2="with \ 71 | movies_only as ( \ 72 | select * \ 73 | from metadata_items \ 74 | where library_section_id = $MOVIESSECTION \ 75 | and title <> '' \ 76 | ), \ 77 | duplicates as ( \ 78 | select * \ 79 | from movies_only \ 80 | where title || year in ( \ 81 | select t_y \ 82 | from ( \ 83 | select title || year as t_y, count(*) N \ 84 | from movies_only \ 85 | group by title || year \ 86 | ) as x \ 87 | where N >= 1 \ 88 | ) \ 89 | ), \ 90 | merged as ( \ 91 | select \ 92 | duplicates.id as metadata_items_id, \ 93 | duplicates.title as metadata_items_title, \ 94 | media_parts.file as media_parts_file \ 95 | from duplicates \ 96 | join media_items \ 97 | on media_items.metadata_item_id = duplicates.id \ 98 | join media_parts \ 99 | on media_parts.media_item_id = media_items.id \ 100 | ) \ 101 | select * \ 102 | from merged \ 103 | where media_parts_file not like '%' || replace(replace(replace(replace(metadata_items_title, ':', ''), '...', ''), '?', ''), ' ', ' ') || '%' \ 104 | order by metadata_items_title \ 105 | " 106 | 107 | readarray -t case1 < <(sqlite3 "$DB" "$qcase1") 108 | readarray -t case2 < <(sqlite3 "$DB" "$qcase2") 109 | 110 | echo "POSSIBLY WRONLGY MATCHED MOVIES WHERE TITLE IS NOT UNIQUE" | tee -a $LOGFILE 111 | echo "One of the results is correct, check based on file name and manually fix second one" 112 | echo "Copy paste URL in browser and use Fix Match" 113 | sqlite3 "$DB" "$query1" | 114 | 115 | for result in "${case1[@]}" 116 | do 117 | echo "$result" | tee -a $LOGFILE 118 | result=$(echo $result | cut -d "|" -f1) 119 | echo "URL: ${PLEXURL}$result" | tee -a $LOGFILE 120 | echo " " | tee -a $LOGFILE 121 | done 122 | echo " " | tee -a $LOGFILE 123 | 124 | echo "POSSIBLY WRONLGY MATCHED MOVIES WHERE PLEX TITLE IS NOT PRESENT IN FOLDER OR FILE NAME" | tee -a $LOGFILE 125 | echo "Copy paste URL in browser and use Fix Match" | tee -a $LOGFILE 126 | for result in "${case2[@]}" 127 | do 128 | echo "$result" | tee -a $LOGFILE 129 | result=$(echo $result | cut -d "|" -f1) 130 | echo "URL: ${PLEXURL}$result" | tee -a $LOGFILE 131 | echo " " | tee -a $LOGFILE 132 | done 133 | 134 | echo "Finished, all results are logged in: $LOGFILE" 135 | 136 | exit 137 | -------------------------------------------------------------------------------- /plex/plex-scan-new.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## PLEX SCAN ONLY NEW/MODIFED FOLDERS SINCE LAST RUN 3 | ## OS: Linux Ubuntu 16.04 4 | ## Make script executable by chmod a+x plex-scan-new.sh 5 | ## Add script to crontab -e ( paste the line bellow without ## ) 6 | ## */30 * * * * /path to script/plex-scan-new.sh >/dev/null 2>&1 7 | ## Make sure you disable all Plex automatic & scheduled library scans. 8 | if pidof -o %PPID -x "$0"; then 9 | echo "$(date "+%d.%m.%Y %T") Exit, already running." 10 | exit 1 11 | fi 12 | 13 | #SETTINGS 14 | MOVIELIBRARY="/mnt/cloud/movies/" 15 | MOVIESECTION=2 16 | TVLIBRARY="/mnt/cloud/series/" 17 | TVSECTION=1 18 | LOGFILE="/home/plex/logs/plex-scan-new.log" 19 | FOLDERLISTFILE="/home/plex/.cache/folderlistfile" 20 | LASTRUNFILE="/home/plex/.cache/lastrunfile" 21 | 22 | 23 | export LD_LIBRARY_PATH=/usr/lib/plexmediaserver 24 | export PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=/var/lib/plexmediaserver/Library/Application\ Support 25 | 26 | if [[ ! -f "$LASTRUNFILE" ]]; then 27 | touch $LASTRUNFILE 28 | fi 29 | echo "$(date "+%d.%m.%Y %T") PLEX SCAN FOR NEW/MODIFIED FILES AFTER: $(date -r $LASTRUNFILE)" 30 | 31 | if [[ -f "$FOLDERLISTFILE" ]]; then 32 | echo "Removing previous folder list" 33 | rm $FOLDERLISTFILE 34 | fi 35 | 36 | start=$(date +'%s') 37 | startmovies=$(date +'%s') 38 | echo "Scaning for new files: $MOVIELIBRARY" 39 | find "$MOVIELIBRARY" -mindepth 1 -type f -cnewer $LASTRUNFILE | 40 | while read mfile; do 41 | echo "$(date "+%d.%m.%Y %T") New file detected: $mfile" | tee -a "$LOGFILE" 42 | MFOLDER=$(dirname "${mfile}") 43 | echo "$MFOLDER" | tee -a "$FOLDERLISTFILE" 44 | done 45 | echo "$(date "+%d.%m.%Y %T") Movie files scanned in $(($(date +'%s') - $startmovies)) seconds" | tee -a "$LOGFILE" 46 | 47 | startseries=$(date +'%s') 48 | echo "Scaning for new files: $TVLIBRARY" 49 | find "$TVLIBRARY" -mindepth 2 -type f -cnewer $LASTRUNFILE | 50 | while read tvfile; do 51 | echo "$(date "+%d.%m.%Y %T") New file detected: $tvfile" | tee -a "$LOGFILE" 52 | TVFOLDER=$(dirname "${tvfile}") 53 | echo "$TVFOLDER" | tee -a "$FOLDERLISTFILE" 54 | done 55 | echo "$(date "+%d.%m.%Y %T") TV folders scanned in $(($(date +'%s') - $startseries)) seconds" | tee -a "$LOGFILE" 56 | 57 | echo "$(date "+%d.%m.%Y %T") Move & TV folders scanned in $(($(date +'%s') - $start)) seconds" | tee -a "$LOGFILE" 58 | echo "$(date "+%d.%m.%Y %T") Setting lastrun for next folder scans" | tee -a "$LOGFILE" 59 | touch $LASTRUNFILE 60 | echo "$(date "+%d.%m.%Y %T") Remove duplicates" | tee -a "$LOGFILE" 61 | sort "$FOLDERLISTFILE" | uniq | tee "$FOLDERLISTFILE" 62 | 63 | startplexscan=$(date +'%s') 64 | echo "$(date "+%d.%m.%Y %T") Plex scan started" | tee -a "$LOGFILE" 65 | readarray -t FOLDERS < "$FOLDERLISTFILE" 66 | for FOLDER in "${FOLDERS[@]}" 67 | do 68 | if [[ $FOLDER == "$MOVIELIBRARY"* ]]; then 69 | echo "$(date "+%d.%m.%Y %T") Plex scan movie folder:: $FOLDER" | tee -a "$LOGFILE" 70 | $LD_LIBRARY_PATH/Plex\ Media\ Scanner --scan --refresh --section "$MOVIESECTION" --directory "$FOLDER" | tee -a "$LOGFILE" 71 | elif [[ $FOLDER == "$TVLIBRARY"* ]]; then 72 | echo "$(date "+%d.%m.%Y %T") Plex scan TV folder: $FOLDER" | tee -a "$LOGFILE" 73 | $LD_LIBRARY_PATH/Plex\ Media\ Scanner --scan --refresh --section "$TVSECTION" --directory "$FOLDER" | tee -a "$LOGFILE" 74 | fi 75 | done 76 | echo "$(date "+%d.%m.%Y %T") Plex scan finished in $(($(date +'%s') - $startplexscan)) seconds" | tee -a "$LOGFILE" 77 | 78 | echo "$(date "+%d.%m.%Y %T") Scan completed in $(($(date +'%s') - $start)) seconds" | tee -a "$LOGFILE" 79 | exit 80 | -------------------------------------------------------------------------------- /plex/plexgeneratefolderlist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## THIS SCRIPT WILL GENERATE FOLDER LIST BEFORE UPLOADING WITH RCLONE. 3 | ## THE SECOND SCRIPT PLEXREFRESHFOLDERS WILL RUN PLEX SCANNER ONLY ON GENERATED FOLDERS. 4 | ## FOLDER LIST WILL HAVE LOCAL PATH REPLACED WITH UNIONFS ONES 5 | 6 | # EXIT IF SCRIPT IF ALREADY RUNNING 7 | if pidof -o %PPID -x "$0"; then 8 | echo "$(date "+%d.%m.%Y %T") Already running, exiting." 9 | exit 1 10 | fi 11 | 12 | TIMESTAMP=`date +%Y-%m-%d_%H-%M-%S` 13 | LOGFILE="/home/plex/logs/local2acdcrypt.cron.log" 14 | MOVIES="/storage/local/movies" 15 | SERIES="/storage/local/series" 16 | LOCALPATH="/storage/local/" 17 | UNIONFSPATH="/mnt/unionfs/" 18 | RCLONEREMOTE="acdcrypt:" 19 | MINFOLDERAGE="15" # MINIMUM FOLDER AGE IN MINUTES. SCRIPT WILL ONLY STARTED WHEN THERE IS A MATCH 20 | 21 | 22 | readarray -t MOVIEFOLDERS < <(find "$MOVIES" -mindepth 1 -type d -mmin +$MINFOLDERAGE -not -iname '*.partial*') 23 | readarray -t SERIESFOLDERS < <(find "$SERIES" -mindepth 2 -type d -mmin +$MINFOLDERAGE -not -iname '*.partial*') 24 | readarray -t UPLOAD < <(find "$LOCALPATH" -mindepth 1 -type f -mmin +$MINFOLDERAGE -not -path '*/\.*' -not -iname '*.partial*') 25 | 26 | if [[ -n $UPLOAD ]]; then 27 | start=$(date +'%s') 28 | echo "$(date "+%d.%m.%Y %T") START" | tee -a "$LOGFILE" 29 | # RCLONE MOVE FILES ( CHANGE TO YOUR PATHS ) 30 | /usr/bin/rclone move $LOCALPATH $RCLONEREMOTE -v --no-traverse --transfers=20 --checkers=20 --delete-after --min-age ${MINFOLDERAGE}m --stats 30s --log-file=$LOGFILE 31 | 32 | #GENERATE AND UPLOAD PLEX.LIST 33 | for mfolder in "${MOVIEFOLDERS[@]}" 34 | do 35 | if [[ $mfolder == *"/movies/"* ]] ; then # Change /movies/ to match your path 36 | MREFRESHFOLDER="${mfolder/$LOCALPATH/$UNIONFSPATH}" # Change path from /storage/local/ to /mnt/unionfs 37 | echo "Adding to plex.list: $MREFRESHFOLDER" | tee -a "$LOGFILE" 38 | echo "$MREFRESHFOLDER" >>/home/plex/.cache/$TIMESTAMP-plex.list 39 | fi 40 | done 41 | for sfolder in "${SERIESFOLDERS[@]}" 42 | do 43 | if [[ $sfolder == *"/series/"* ]] ; then # Change /series/ to match your path 44 | SREFRESHFOLDER="${sfolder/$LOCALPATH/$UNIONFSPATH}" # Change path from /storage/local/ to /mnt/unionfs 45 | echo "Adding to plex.list: $SREFRESHFOLDER" | tee -a "$LOGFILE" 46 | echo "$SREFRESHFOLDER" >>/home/plex/.cache/$TIMESTAMP-plex.list 47 | fi 48 | done 49 | if [[ -f /home/plex/.cache/$TIMESTAMP-plex.list ]]; then 50 | echo "Uploading: $TIMESTAMP-plex.list" | tee -a "$LOGFILE" 51 | /usr/bin/rclone move /home/plex/.cache/$TIMESTAMP-plex.list $RCLONEREMOTE/tmp/ -v --no-traverse --log-file=$LOGFILE #Change acdcrypt: to match your remote 52 | fi 53 | echo "$(date "+%d.%m.%Y %T") ENDED in $(($(date +'%s') - $start)) seconds" | tee -a "$LOGFILE" 54 | fi 55 | exit 56 | -------------------------------------------------------------------------------- /plex/plexrefreshfolderlist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## THIS SCRIPT WILL RUN PLEX SCANNER ONLY ON FOLDERS PREVIOUSLY GENERATED BY plexgeneratefolderlist.sh 3 | 4 | if pidof -o %PPID -x "$0"; then 5 | echo "$(date "+%d.%m.%Y %T") Exit, already running." 6 | exit 1 7 | fi 8 | TIMESTAMP=`date +%Y-%m-%d_%H-%M-%S` 9 | LOGFILE="/home/plex/logs/plexrefresh.cron.log" 10 | UNIONFSPATH="/mnt/unionfs" 11 | RCLONEREMOTE="acdcrypt:" 12 | PLEXLIST="${UNIONFSPATH}/tmp/ " 13 | CACHE="/home/plex/.cache/" 14 | TVSECTION=1 15 | MOVIESECTION=2 16 | 17 | export LD_LIBRARY_PATH=/usr/lib/plexmediaserver 18 | export PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR=/var/lib/plexmediaserver/Library/Application\ Support 19 | 20 | # EXIT IF THERE ARE NO PLEX LIST FILES 21 | if [[ -z $(find $PLEXLISTPATH -type f -iname "*.list" -mmin +1) ]];then 22 | echo "Exit: No list available" 23 | exit 24 | fi 25 | # FIND LISTS, MERGE INTO ONE FILE AND DELETE RLONE REMOTE 26 | find $PLEXLISTPATH -type f -iname "*.list" -mmin +1 | 27 | while read FILEPATH; do 28 | cat $FILEPATH >> ${CACHE}$TIMESTAMP-plex.list 29 | FILE=$(basename "${FILEPATH}") 30 | /usr/bin/rclone delete ${RCLONEPATH2LIST}{$FILE} 31 | done 32 | 33 | # REMOVE DUPLICATE FOLDERS 34 | sort $CACHE/$TIMESTAMP-plex.list | uniq | tee $CACHE/$TIMESTAMP-plex.list > /dev/null 35 | 36 | # PLEX SCAN NEW FOLDERS 37 | readarray -t FOLDERS < ${CACHE}$TIMESTAMP-plex.list 38 | for FOLDER in "${FOLDERS[@]}" 39 | do 40 | if [[ $FOLDER == *"/movies/"* ]] ; then 41 | echo "$(date "+%d.%m.%Y %T") Refreshing movie folder: $FOLDER" | tee -a "$LOGFILE" 42 | ${LD_LIBRARY_PATH}/Plex\ Media\ Scanner --scan --refresh --section $MOVIESECTION --directory "${FOLDER}" | tee -a "$LOGFILE" 43 | fi 44 | if [[ $FOLDER == *"/series/"* ]] ; then 45 | echo "$(date "+%d.%m.%Y %T") Refreshing serie folder: $FOLDER" | tee -a "$LOGFILE" 46 | ${LD_LIBRARY_PATH}/Plex\ Media\ Scanner --scan --refresh --section $TVSECTION --directory "${FOLDER}" | tee -a "$LOGFILE" 47 | fi 48 | done 49 | # ADD SUFFIX DONE TO THE FINISHED LIST 50 | echo "$TIMESTAMP-plex.list.done" | tee -a "$LOGFILE" 51 | mv ${CACHE}$TIMESTAMP-plex.list ${CACHE}$TIMESTAMP-plex.list.done 52 | exit 53 | -------------------------------------------------------------------------------- /plexdrive/mountplexdrive.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## plexdrive mount (chmod a+x mountplexdrive.sh) 3 | ## To mount the drive at reboot & to remount in case of failure type crontab -e and add 2 lines bellow (without ##): 4 | ## @reboot /path/mountplexdrive.sh 5 | ## 0 5 * * * /path/mountplexdrive.sh >/dev/null 2>&1 6 | ## 7 | ## To unmount plexdrive use 8 | ## /path/mountplexdrive unmount 9 | ## More scripts at: https://github.com/ajkis/scripts 10 | ## If you find script useful feel free to buy me a beer at https://paypal.me/ajki 11 | 12 | ## EXIT IF ALREADY RUNNING 13 | if pidof -o %PPID -x "$0"; then 14 | echo "EXIT: Already running" 15 | exit 1 16 | fi 17 | 18 | ## GLOBAL VARS 19 | LOGFILE="/home/plex/logs/mountplexdrive.log" 20 | MPOINT="/mnt/plexdrive/" 21 | 22 | ## UNMOUNT IF SCRIPT WAS RUN WITH unmount PARAMETER 23 | if [[ $1 = "unmount" ]]; then 24 | echo "Unmounting $MPOINT" 25 | fusermount -uz $MPOINT 26 | exit 27 | fi 28 | 29 | ## CHECK IF MOUNT ALREADY EXIST AND MOUNT IF NOT 30 | if mountpoint -q $MPOINT ; then 31 | echo "$MPOINT already mounted" 32 | else 33 | echo "Mounting $MPOINT" 34 | ## Adjust chunk-check/load threads to match maximum concurrent streams 35 | ## Do not use losd-ahead bigger then 10. 36 | ## Keep in mind that 1080p stream will need 20Mbit while some scenes can spike to 50/60Mbit. 37 | /usr/bin/plexdrive mount $MPOINT \ 38 | -o allow_other \ 39 | --chunk-check-threads=20 \ 40 | --chunk-load-ahead=4 \ 41 | --chunk-load-threads=20 \ 42 | --chunk-size=5M \ 43 | --max-chunks=2000 \ 44 | --refresh-interval=1m \ 45 | -v 3 &>>"$LOGFILE" & 46 | fi 47 | exit 48 | -------------------------------------------------------------------------------- /plexdrive/plexdrive-rebuildcache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## plexdrive-rebuildcache.sh (chmod a+x plexdrive-rebuildcache.sh) 3 | ## The function of this script is rebuild cache with paralel process in memory and then move it to default location. 4 | ## NOTE: This will speed up process significantly as building full cache on hard disk may take hours. 5 | ## 6 | ## More scripts at: https://github.com/ajkis/scripts 7 | ## If you find script useful feel free to buy me a beer at https://paypal.me/ajki 8 | 9 | TIMESTAMP=`date +%Y-%m-%d_%H-%M-%S` 10 | LOGFILE="/home/plex/logs/plexdrive-rebuildcache.log" 11 | PLEXDRIVEEXEC=/usr/bin/plexdrive # Set path to plexdrive executable 12 | PLEXDRIVEMNT=/mnt/plexdrive # Set path to plexdrive mount 13 | PLEXDRIVECONF=~/.plexdrive # Set location of your plexdrive config or leave default 14 | PLEXDRIVEMOUNTCMD="/home/plex/scripts/mountplexdrive" # Set path to your plexdrive mount script. If you use systemd replace it with "sudo systemctl plexdrive.service start" 15 | PLEXDRIVETMPMNT=/mnt/tmp #Make sure you have read/write permissions in /mnt 16 | 17 | echo "$(date "+%d.%m.%Y %T") plexdrive rebuild cache started" | tee -a $LOGFILE 18 | 19 | 20 | if [[ ! -d $PLEXDRIVETMPMNT ]]; then 21 | mkdir $PLEXDRIVETMPMNT 22 | fi 23 | 24 | ## REMOVE OLD FILES IN CASE SCRIPT WAS ABORTED 25 | rm -f /dev/shm/cache* >/dev/null 26 | rm -f /dev/shm/config.json >/dev/null 27 | rm -f /dev/shm/token.json >/dev/null 28 | rm -f /dev/shm/plexdrivetmp.log >/dev/null 29 | rm -rf /dev/shm/chunks >/dev/null 30 | 31 | echo "Copying plex drive config to $PLEXDRIVETMPMNT" | tee -a $LOGFILE 32 | cp $PLEXDRIVECONF/config.json /dev/shm | tee -a $LOGFILE 33 | cp $PLEXDRIVECONF/token.json /dev/shm | tee -a $LOGFILE 34 | 35 | echo "Mounting TMP plexdrive and waiting for cache to be rebuilt" | tee -a $LOGFILE 36 | cachebuildstart=$(date +'%s') 37 | $PLEXDRIVEEXEC $PLEXDRIVETMPMNT --config=/dev/shm --temp=/dev/shm -v 2 &>>/dev/shm/plexdrivetmp.log & 38 | while > /dev/null 39 | do 40 | finished=$(grep "First cache build process finished!" /dev/shm/plexdrivetmp.log) 41 | if [[ ! -z $finished ]]; then 42 | echo "First cache build process finished in $(($(date +'%s') - $cachebuildstart)) seconds" | tee -a $LOGFILE 43 | echo "$(grep "Processed" /dev/shm/plexdrivetmp.log | tail -1)" | tee -a $LOGFILE 44 | fusermount -uz $PLEXDRIVETMPMNT 45 | break 46 | fi 47 | echo "$(grep -i "${PLEXDRIVEEXEC:1}" /dev/shm/plexdrivetmp.log | tail -1)" 48 | sleep 1 49 | done 50 | 51 | echo "///////////////////////////////////////////////////////////////////////////////////////////////" 52 | echo "Your current cache will be deleted, rebuilt in memory (/dev/shm) and moved to default location" 53 | echo "plexdrive conf path = $PLEXDRIVECONF" 54 | echo "plexdrive exec path = $PLEXDRIVEEXEC" 55 | echo "plexdrive mount command: $PLEXDRIVEMOUNTCMD" 56 | echo "NOTE: You can run rebuilt automatically: /path/plexdrive-rebuildcache.sh y" 57 | echo "///////////////////////////////////////////////////////////////////////////////////////////////" 58 | response=$1 59 | if [[ $response != y ]]; then 60 | read -r -p "Are you sure? [y/N] " response 61 | fi 62 | case "$response" in 63 | [yY][eE][sS]|[yY]) 64 | ### LIST OF COMMAND TO RUN BEFORE REMOUNTING PLEXDRIVE 65 | ## eg: sudo service plexmediaserver stop 66 | echo "Stopping all services" | tee -a $LOGFILE 67 | fusermount -uz $PLEXDRIVEMNT 68 | rm -rf $PLEXDRIVECONF/temp/chunks #SPECIFY PATH TO TEMP FILE WHERE CHUNKS ARE STORED 69 | rm -rf $PLEXDRIVECONF/cache 70 | 71 | ### MOVE NEW CACHE FILE 72 | echo "Moving new plexdrive cache to $PLEXDRIVECONF" | tee -a $LOGFILE 73 | mv /dev/shm/cache* $PLEXDRIVECONF | tee -a $LOGFILE 74 | 75 | ### CLEANUP 76 | echo "/dev/shm cleanup" | tee -a $LOGFILE 77 | rm /dev/shm/config.json | tee -a $LOGFILE 78 | rm /dev/shm/token.json | tee -a $LOGFILE 79 | rm /dev/shm/plexdrivetmp.log | tee -a $LOGFILE 80 | rm -rf /dev/shm/chunks | tee -a $LOGFILE 81 | 82 | ### LIST OF COMMANDS TO PREFORM ONCE DRIVE IS REMOUNTED 83 | ## Start srvices stopped before remount 84 | echo "Mounting plexdrive and starting all services" | tee -a $LOGFILE 85 | /home/plex/scripts/mountplexdrive 86 | echo "$(date "+%d.%m.%Y %T") plexdrive rebuild cache finished" | tee -a $LOGFILE 87 | ;; 88 | *) 89 | echo "Aborted" 90 | exit 91 | ;; 92 | esac 93 | 94 | exit 95 | -------------------------------------------------------------------------------- /plexdrive/plexdrive-scan-missing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## The function of this script is to check rclone mount against plexdrive mount and list all missing files 3 | ## 4 | ## Requirements: 5 | ## plexdrive mount and rclone mount 6 | ## 7 | ## Setup 8 | ## 1. chmod a+x plexdrive-scan-missing.sh 9 | ## 2. Set correct paths in variables and array 10 | ## 11 | ## More scripts at: https://github.com/ajkis/scripts 12 | ## If you find script useful feel free to buy me a beer at https://paypal.me/ajki 13 | 14 | ## EXIT IF SCRIPT IS ALREADY RUNNING 15 | if pidof -o %PPID -x "$0"; then 16 | echo "$(date "+%d.%m.%Y %T") Already running, exit" 17 | exit 1 18 | fi 19 | 20 | TS=`date +%Y-%m-%d_%H-%M-%S` 21 | LOGFILE="/home/plex/logs/plexdrivemissing-$TS.log" 22 | RCLONEMOUNT=/mnt/gdrivecrypt # Set path to rclone mount 23 | PLEXDRIVEMOUNT=/mnt/cloud # set path to plexdrive mount 24 | 25 | # set path to rclone mount movies, series etc... 26 | PATHS=( 27 | '/mnt/gdrivecrypt/movies/' 28 | '/mnt/gdrivecrypt/series/' 29 | ) 30 | elapsed=$(date +'%s') 31 | countermissing=0 32 | clear 33 | echo "$(date "+%d.%m.%Y %T") Scan plexdrive for missing files" | tee -a $LOGFILE 34 | for path in "${PATHS[@]}" 35 | do 36 | counterall=$(($counterall + 1)) 37 | find $path -type f | 38 | while read filepath 39 | do 40 | filepath=${filepath/$RCLONEMOUNT/$PLEXDRIVEMOUNT} 41 | tput cup 1 0 42 | tput el 43 | echo "Progress: $counterall files in $(($(date +'%s') - $elapsed)) seconds | Missing: $countermissing" 44 | tput cup 2 0 45 | tput el 46 | echo -ne "Checking: $filepath" 47 | if [[ ! -f "$filepath" ]]; then 48 | tput cup $(($countermissing + 4)) 0 49 | countermissing=$(($countermissing + 1)) 50 | echo "Missing on plexdrive: $filepath" | tee -a $LOGFILE 51 | fi 52 | done 53 | done 54 | echo "Scan finished in $(($(date +'%s') - $elapsed)) seconds. Missing $countermissing files" | tee -a $LOGFILE 55 | exit 56 | -------------------------------------------------------------------------------- /plexdrive/plexdrivechunks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## plexdrivechunks.sh (chmod a+x plexdrivechunks.sh) 3 | ## The function of this script is to manually delete plexdrive chunk files when you are about to run out of disk space. 4 | ## NOTE: plexdrive support max disk usage for chunks, eg --clear-chunk-max-size=100GB (but if disk get full with other none plexdrive related data this wont help ) 5 | ## Add to plexdrive mount: --clear-chunk-age=730h 6 | ## Note: This would keep all downloads for a month before deleting them ( do not use --clear-chunk-max-size so maximum space its always available) 7 | ## Do not store temp in /dev/shm since its only 50% of ram eg not enough space to keep chunks for 30days 8 | ## To run script automatically every minute type: crontab -e and andd line bellow (without ##): 9 | ## * * * * * /path/plexdrivechunks.sh >/dev/null 2>&1 10 | ## 11 | ## More scripts at: https://github.com/ajkis/scripts 12 | ## If you find script useful feel free to buy me a beer at https://paypal.me/ajki 13 | 14 | ## EXIT IF SCRIPT IS ALREADY RUNNING 15 | if pidof -o %PPID -x "$0"; then 16 | echo "$(date "+%d.%m.%Y %T") Already running, exit" 17 | exit 1 18 | fi 19 | 20 | PLEXDRIVETEMP=/home/plex/.plexdrive/temp # SET IT TO SAME LOCATION AS YOU HAVE IN PLEXDRIVE --temp=//home/plex/.plexdrive/temp 21 | MINDISKSPACE=1000000 # SET MINIMUM DISK SPACE WHEN ITS BELLOW THE SCRIPT WILL TRIGGER (1GB = 1000000kB) 22 | CURDISKSPACE=$(df -k $PLEXDRIVETEMP | tail -1 | awk '{print $4}') 23 | LOG=/home/plex/logs/plexdrivechunks.log 24 | 25 | while [[ $CURDISKSPACE<$MINDISKSPACE ]] 26 | do 27 | CURDISKSPACE=$(df -k $PLEXDRIVETEMP | tail -1 | awk '{print $4}') 28 | if [[ -z "$nochunk" ]]; then 29 | find $PLEXDRIVETEMP -mindepth 1 -mmin +1 –atime +10 | head -n 10 | 30 | while read chunk; do 31 | if [[ -z "$chunk" ]]; then 32 | echo "WARNING: Current disk size is ${CURDISKSPACE}kB and bellow ${MINDISKPACE}kB, no chunks available for deletition. EXIT" | tee -a $LOG 33 | nochunk=1 34 | break 35 | fi 36 | echo "Delete: $chunk" | tee -a $LOG 37 | rm $chunk 38 | done 39 | else 40 | echo "WARNING: Current disk size is ${CURDISKSPACE}kB and bellow ${MINDISKPACE}kB, no chunks available for deletition. EXIT" | tee -a $LOG 41 | break 42 | fi 43 | done 44 | exit 45 | -------------------------------------------------------------------------------- /plexdrive/plexdrivefixchunkwarrnings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## plexdrivefixchunkwarrnings.sh (chmod a+x plexdrivefixchunkwarrnings.sh) 3 | ## This script will read from plexdrive mount log and make folders that plexdrive could not: WARNING: Could not write chunk temp file /xxxx 4 | ## To run script automatically every minute type: crontab -e and add line bellow (without ##): 5 | ## * * * * * /path/plexdrivefixchunkwarrnings.sh >/dev/null 2>&1 6 | ## 7 | ## Optionally you can run it more often eg every 15 secnds with cron by adding (do not add the above one then): 8 | ## * * * * * sleep 00; /path/plexdrivefixchunkwarrnings.sh >/dev/null 2>&1 9 | ## * * * * * sleep 15; /path/plexdrivefixchunkwarrnings.sh >/dev/null 2>&1 10 | ## * * * * * sleep 30; /path/plexdrivefixchunkwarrnings.sh >/dev/null 2>&1 11 | ## * * * * * sleep 45; /path/plexdrivefixchunkwarrnings.sh >/dev/null 2>&1 12 | ## More scripts at: https://github.com/ajkis/scripts 13 | ## If you find script useful feel free to buy me a beer at https://paypal.me/ajki 14 | if pidof -o %PPID -x "$0"; then 15 | echo "$(date "+%d.%m.%Y %T") Already running, exit" 16 | exit 1 17 | fi 18 | 19 | PLEXDRIVEMOUNTLOG=/home/plex/logs/mountplexdrive.log #SET 20 | WARNINGFOLDERPATH=$(grep -i "Could not write chunk temp file" $PLEXDRIVEMOUNTLOG | tail -1) #get last warrning in log 21 | WARNINGFOLDERPATH=${WARNINGFOLDERPATH:89} #REMOVE 89 chars / [USR/BIN/PLEXDRIVE] [2017-05-27 18:56] WARNING: Could not write chunk temp file 22 | if [[ ! -f $WARNINGFOLDERPATH ]];then #CHECK IF FILE EXIST 23 | WARNINGFOLDERPATH=$(dirname "${WARNINGFOLDERPATH}") #GET FOLDER NAME 24 | echo "Creating folder that plexdrive did not manage to do: $WARNINGFOLDERPATH" 25 | mkdir $WARNINGFOLDERPATH 26 | fi 27 | exit 28 | -------------------------------------------------------------------------------- /plexdrive/update-plexdrive.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## update-plexdrive.sh (chmod a+x /path/update-plexdrive.sh) 3 | ## Dependencies curl ( sudo apt install curl ) 4 | ## Script function: 5 | ## 1. Stop Plex Media Server and unmount plexdrive 6 | ## 2. Download latest plexdrive and replace existing version 7 | ## 3. Mount plexdrive (will exit if mount was not successful ) 8 | ## 4. Start Plex Media Server 9 | ## 10 | ## More scripts at: https://github.com/ajkis/scripts 11 | ## If you find script useful feel free to buy me a beer at https://paypal.me/ajki 12 | 13 | PLEXDRIVEMOUNTCMD="/home/plex/scripts/mountplexdrive" # Set path to your plexdrive mount script. If you use systemd replace it with "sudo systemctl plexdrive.service start" 14 | PLEXDRIVEEXEC=/usr/bin/plexdrive # Set path to plexdrive executable 15 | PLEXDRIVEMNT=/mnt/plexdrive # Set path to plexdrive mount 16 | 17 | PLEXDRIVELATESTVER=$(curl -s https://api.github.com/repos/dweidenfeld/plexdrive/releases/latest | grep 'tag_name' | cut -c 16- | rev | cut -c 3- | rev) 18 | PLEXDRIVECURVER=$($PLEXDRIVEEXEC --version) 19 | 20 | if [[ $PLEXDRIVELATESTVER == $PLEXDRIVECURVER ]]; then 21 | echo "EXIT: Latest version: $PLEXDRIVELATESTVER already installed" 22 | exit 23 | fi 24 | echo "new plexdrive version: $PLEXDRIVELATESTVER found. Updater started, replacing current version: $PLEXDRIVECURVER" 25 | 26 | wget $(curl -s https://api.github.com/repos/dweidenfeld/plexdrive/releases/latest | grep 'browser_' | cut -d\" -f4 | grep plexdrive-linux-amd64) -O /dev/shm/plexdrive-linux-amd64 27 | if [ "$?" != "0" ]; then 28 | echo "EXIT: Unable to download latest plexdrive version" 29 | exit 30 | fi 31 | 32 | # STOP PLEX MEDIA SERVER 33 | while ps ax | grep -v grep | grep /usr/lib/plexmediaserver/Plex\ Media\ Server > /dev/null 34 | do 35 | echo "stopping plex media server" 36 | sudo service plexmediaserver stop 37 | sleep 3 38 | done 39 | 40 | # UNMOUNT PLEX DRIVE 41 | while mount | grep "on $PLEXDRIVEMNT type" > /dev/null 42 | do 43 | echo "($wi) Unmounting $mount" 44 | fusermount -uz $PLEXDRIVEMNT 45 | sleep 1 46 | done 47 | 48 | echo "killing all plexdrive processes" 49 | while ps ax | grep -v grep | grep /usr/lib/plexdrive > /dev/null 50 | do 51 | killall -9 plexdrive 52 | sleep 1 53 | done 54 | 55 | # REPLACE EXISTING WITH NEW VERSION 56 | sudo chmod a+x /dev/shm/plexdrive-linux-amd64 57 | sudo mv /dev/shm/plexdrive-linux-amd64 $PLEXDRIVEEXEC 58 | 59 | # MOUNT PLEXDRIVE 60 | $PLEXDRIVEMOUNT 61 | 62 | # WAIT FOR PLEXDRIVE TO BE MOUNTED 63 | while ! mount | grep "on $PLEXDRIVEMNT type" > /dev/null 64 | do 65 | echo "($wi) Waiting for $PLEXDRIVEMNT mount" 66 | wi=$(($wi + 1)) 67 | if [ "$wi" -ge 12 ];then 68 | echo "EXIT: Unable to mount $PLEXDRIVEMNT, check plexdrive logs" 69 | exit 70 | fi 71 | sleep 1 72 | done 73 | 74 | # START PLEX MEDIA SERVER 75 | sudo service plexmediaserver start 76 | sleep 2 77 | exit 78 | -------------------------------------------------------------------------------- /radarr/radarr-fixunmatched.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## Fix unmatched movies that radar does not recognize and are placed it correct folders. 3 | ## Change DB value to match your radar db path 4 | 5 | DB="/home/plex/.config/Radarr/nzbdrone.db" 6 | 7 | while ps ax | grep -v grep | grep Radarr.exe > /dev/null 8 | do 9 | echo "EXIT, Radarr.exe must be stopped" 10 | exit 11 | done 12 | 13 | query="SELECT Title from Movies WHERE MovieFileId = '0' AND id IN (SELECT MovieId FROM MovieFiles)" 14 | result=$(sqlite3 -header -line "$DB" "$query") 15 | echo "${result:12} Unmatched Movies" 16 | 17 | echo "Applying SQL Update fix" 18 | sqlite3 -header -line "$DB" "update Movies set MovieFileId = IfNull((select MovieFiles.Id from MovieFiles where MovieFiles.MovieId = Movies.id), 0) where MovieFileId = 0" 19 | echo "Done, you may start Radarr again" 20 | exit 21 | -------------------------------------------------------------------------------- /radarr/radarr-upgradefix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # READ ME 3 | # Fix for upgrading existing movies. 4 | # In Radarr go in Settings -> Connect -> + Custom Script 5 | # Enable On Download ( the rest disabled ) 6 | # In path set: /bin/bash 7 | # In arrguments set: /path to script/radarr-upgradefix.sh and save 8 | # 9 | # SCRIPT SETTINGS 10 | # If is set to 0, just movie file will be deleted. 11 | # (personally i prefer to delete folder so I get rid of old subtitles) 12 | DELETEFOLDER=1 13 | # If you use UNIONFS or other fuse overlays set it to 1 14 | # and change REPLACEUFSPATH and ACTUALPATH 15 | REPLACEPATH=1 16 | # Make sure you change the paths if you set REPLACEPATH=1 17 | REPLACEUFSPATH=/mnt/unionfs/ 18 | ACTUALPATH=/mnt/acdcrypt/ 19 | # LOGFILE LOCATATION 20 | LOGFILE="/home/plex/logs/radarr-upgradefix.log" 21 | 22 | echo "$(date "+%d.%m.%Y %T") Radarr Event: $radarr_eventtype file: $radarr_moviefile_path" >> "$LOGFILE" 23 | # Check if movie already exist 24 | if [[ -f "$radarr_moviefile_path" ]] ; then 25 | if [[ REPLACEPATH -eq 1 ]] ; then 26 | radarr_moviefile_path=${radarr_moviefile_path/$REPLACEUFSPATH/$ACTUALPATH} 27 | fi 28 | if [[ DELETEFOLDER -eq 1 ]] ; then 29 | echo "$(date "+%d.%m.%Y %T") Deleting existing movie folder:" $(dirname "${radarr_moviefile_path}") >> "$LOGFILE" 30 | rm -rf $(dirname "${radarr_moviefile_path}") 31 | else 32 | echo "$(date "+%d.%m.%Y %T") Deleting existing movie file: $radarr_moviefile_path" >> "$LOGFILE" 33 | rm "$radarr_moviefile_path" 34 | fi 35 | fi 36 | exit 37 | -------------------------------------------------------------------------------- /rclone/compare-clouds.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Requirements: sudo apt install tree 3 | if pidof -o %PPID -x "compare-acd-gdrive"; then 4 | echo "Already running, exit" 5 | exit 1 6 | fi 7 | scriptstart=$(date +'%s') 8 | TSTAMP=`date +%d.%m.%Y/%H:%M` 9 | LOGFILE="/home/plex/logs/compare-acd-gdrive.log" 10 | ACDREMOTE="acd:" 11 | GDRIVEREMOTE="gdrive:" 12 | ACDMOUNT="/mnt/acdcrypt/" 13 | GDRIVEMOUNT="/mnt/gdrivecrypt/" 14 | 15 | echo "------------------------------------------- " | tee -a "$LOGFILE" 16 | echo "$TSTAMP START" | tee -a "$LOGFILE" 17 | echo "ACD FILES & SIZE (rclone size $ACDREMOTE)" | tee -a "$LOGFILE" 18 | lastupload=`tail -n5 $LOGFILE | grep "Total size:" | cut -c 13- | cut -c -5` 19 | acdstart=$(date +'%s') 20 | rclone size $ACDREMOTE | tee -a "$LOGFILE" 21 | echo "$TSTAMP ACD: It took $(($(date +'%s') - $acdstart)) seconds" | tee -a "$LOGFILE" 22 | echo " " | tee -a "$LOGFILE" 23 | echo "GDRIVE FILE & SIZE (rclone size $GDRIVEREMOTE)" | tee -a "$LOGFILE" 24 | gdrivestart=$(date +'%s') 25 | rclone size $GDRIVEREMOTE | tee -a "$LOGFILE" 26 | echo "$TSTAMP GDRIVE: It took $(($(date +'%s') - $gdrivestart)) seconds" | tee -a "$LOGFILE" 27 | echo " " | tee -a "$LOGFILE" 28 | echo "$TSTAMP ACD&GDRIVE SIZE: TOTAL TIME $(($(date +'%s') - $scriptstart)) seconds" | tee -a "$LOGFILE" 29 | echo " " | tee -a "$LOGFILE" 30 | acdstart=$(date +'%s') 31 | echo "ACD FILE/FOLDER COUNT (tree $ACDMOUNT)" | tee -a "$LOGFILE" 32 | tree $ACDMOUNT | tail -1 | tee -a "$LOGFILE" 33 | echo "$TSTAMP ACD COUNT: It took $(($(date +'%s') - $acdstart)) seconds" | tee -a "$LOGFILE" 34 | echo " " | tee -a "$LOGFILE" 35 | gdrivestart=$(date +'%s') 36 | echo "GDRIVE FILE/FOLDER COUNT (tree $GDRIVEMOUNT) " | tee -a "$LOGFILE" 37 | tree $GDRIVEMOUNT | tail -1 | tee -a "$LOGFILE" 38 | echo "$TSTAMP GDRIVE COUNT: It took $(($(date +'%s') - $gdrivestart)) seconds" | tee -a "$LOGFILE" 39 | echo " " | tee -a "$LOGFILE" 40 | echo "$TSTAMP ACD&GDRIVE SIZE & COUNT: TOTAL TIME $(($(date +'%s') - $scriptstart)) seconds" | tee -a "$LOGFILE" 41 | echo " " | tee -a "$LOGFILE" 42 | exit 43 | -------------------------------------------------------------------------------- /rclone/rclone-mount-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 1. Change paths 3 | # 2. for mount and log file & create mountchek file. 4 | # 3. Add to crontab -e (paste the line bellow, without # in front) 5 | # * * * * * /home/plex/scripts/rclone-mount-check.sh >/dev/null 2>&1 6 | # Make script executable with: chmod a+x /home/plex/scripts/rclone-mount-check.sh 7 | 8 | LOGFILE="/home/plex/logs/rclone-mount-check.log" 9 | RCLONEREMOTE="acdcrypt:" 10 | MPOINT="/home/plex/acdcrypt" 11 | CHECKFILEPATH="mountcheck" 12 | 13 | if pidof -o %PPID -x "$0"; then 14 | echo "$(date "+%d.%m.%Y %T") EXIT: Already running." | tee -a "$LOGFILE" 15 | exit 1 16 | fi 17 | 18 | if [[ -f "$MPOINT/$CHECKFILE" ]]; then 19 | echo "$(date "+%d.%m.%Y %T") INFO: Check successful, $MPOINT mounted." | tee -a "$LOGFILE" 20 | exit 21 | else 22 | echo "$(date "+%d.%m.%Y %T") ERROR: $MPOINT not mounted, remount in progress." | tee -a "$LOGFILE" 23 | # Unmount before remounting 24 | while mount | grep "on ${MPOINT} type" > /dev/null 25 | do 26 | echo "($wi) Unmounting $mount" 27 | fusermount -uz $MPOINT | tee -a "$LOGFILE" 28 | cu=$(($cu + 1)) 29 | if [ "$cu" -ge 5 ];then 30 | echo "$(date "+%d.%m.%Y %T") ERROR: Folder could not be unmounted exit" | tee -a "$LOGFILE" 31 | exit 1 32 | break 33 | fi 34 | sleep 1 35 | done 36 | rclone mount \ 37 | --read-only \ 38 | --allow-non-empty \ 39 | --allow-other \ 40 | --max-read-ahead 14G \ 41 | --acd-templink-threshold 0 \ 42 | --checkers 16 \ 43 | --quiet \ 44 | --stats 0 \ 45 | $RCLONEREMOTE $MPOINT & 46 | 47 | while ! mount | grep "on ${MPOINT} type" > /dev/null 48 | do 49 | echo "($wi) Waiting for mount $mount" 50 | c=$(($c + 1)) 51 | if [ "$c" -ge 4 ] ; then break ; fi 52 | sleep 1 53 | done 54 | if [[ -f "$MPOINT/$CHECKFILE" ]]; then 55 | echo "$(date "+%d.%m.%Y %T") INFO: Remount successful." | tee -a "$LOGFILE" 56 | else 57 | echo "$(date "+%d.%m.%Y %T") CRITICAL: Remount failed." | tee -a "$LOGFILE" 58 | fi 59 | fi 60 | exit 61 | -------------------------------------------------------------------------------- /rclone/rclone-mount.service: -------------------------------------------------------------------------------- 1 | # Rclone mount on boot ( service file template - add aditional rclone parameters ) 2 | # Copy file to: /etc/systemd/system 3 | # Set remote name (current acdcrypt), path to mount and User,Group (current plex) 4 | # Register new service by typing: 5 | # sudo systemctl daemon-reload 6 | # sudo systemctl enable rclone-mount.service 7 | # systemctl start rclone-mount.service 8 | # systemctl enable NetworkManager-wait-online.service 9 | # Usage: 10 | # To unmount drive use 11 | # systemctl stop rclone-mount.service 12 | # To mount use: 13 | # systemctl start rclone-mount.service 14 | 15 | [Unit] 16 | Description=rclone Amazon Cloud Drive FUSE mount 17 | Documentation=http://rclone.org/docs/ 18 | After=network-online.target 19 | 20 | [Service] 21 | Type=simple 22 | User=plex 23 | Group=plex 24 | ExecStart=/usr/bin/rclone mount --allow-non-empty --allow-other acdcrypt:/ /path/ 25 | ExecStop=/usr/bin/fusermount -uz /path/ 26 | 27 | [Install] 28 | Wants=network-online.target 29 | -------------------------------------------------------------------------------- /rclone/rclone-upload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # RCLONE UPLOAD CRON TAB SCRIPT 3 | # chmod a+x /home/plex/scripts/rclone-upload.sh 4 | # Type crontab -e and add line below (without #) and with correct path to the script 5 | # * * * * * /home/plex/scripts/rclone-upload.sh >/dev/null 2>&1 6 | # if you use custom config path add line bellow in line 20 after --log-file=$LOGFILE 7 | # --config=/path/rclone.conf (config file location) 8 | 9 | if pidof -o %PPID -x "$0"; then 10 | exit 1 11 | fi 12 | 13 | LOGFILE="/home/plex/logs/rclone-upload.log" 14 | FROM="/storage/local/" 15 | TO="gdrivecrypt:/" 16 | 17 | # CHECK FOR FILES IN FROM FOLDER THAT ARE OLDER THAN 15 MINUTES 18 | if find $FROM* -type f -mmin +15 | read 19 | then 20 | start=$(date +'%s') 21 | echo "$(date "+%d.%m.%Y %T") RCLONE UPLOAD STARTED" | tee -a $LOGFILE 22 | # MOVE FILES OLDER THAN 15 MINUTES 23 | rclone move "$FROM" "$TO" --transfers=20 --checkers=20 --delete-after --min-age 15m --log-file=$LOGFILE 24 | echo "$(date "+%d.%m.%Y %T") RCLONE UPLOAD FINISHED IN $(($(date +'%s') - $start)) SECONDS" | tee -a $LOGFILE 25 | fi 26 | exit 27 | -------------------------------------------------------------------------------- /rclone/rcquota.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## Show gdrive used quota 3 | LogFile=/dev/shm/rcquota.log 4 | 5 | if [ -z $1 ]; then 6 | echo "Use rcquota remote:" 7 | fi 8 | echo "Checking gdrive quota used for $Remote" 9 | rclone lsd $1 -vv --dump-bodies --log-file=$LogFile >/dev/null 2>&1 10 | QuotaUsed=$(grep -e 'quotaBytesUsed"' $LogFile | awk -F'[^0-9]*' '{print $2}') 11 | QuotaUsed=$(($QuotaUsed / (1024*1024*1024))) 12 | echo "$QuotaUsed GB" 13 | rm $LogFile 14 | exit 15 | -------------------------------------------------------------------------------- /rclone/rcuploadcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # RCLONE UPLOAD CHECK SCRIPT 3 | # chmod a+x /home/plex/scripts/rcuploadcheck.sh 4 | # Set rclone remote and path to LogFile 5 | # You can add script in crontab to check every 10 minutes and log gdrive locks/unlocks 6 | # Type crontab -e and add line below (without #) and with correct path to the script 7 | # */10 * * * * /home/plex/scripts/rcuploadcheck.sh >/dev/null 2>&1 8 | 9 | if pidof -o %PPID -x "$0"; then 10 | echo "$(date "+%d.%m.%Y %T") Already running, exiting." 11 | exit 1 12 | fi 13 | 14 | LogFile="/home/plex/logs/rcuploadcheck.log" 15 | UploadFile="/dev/shm/upload-file" 16 | Remote="gdajki:" 17 | 18 | if [[ ! -f $LogFile ]]; then 19 | touch $LogFile 20 | fi 21 | LastState=$(tail -1 $LogFile) 22 | 23 | start=$(date +'%s') 24 | echo "INFO: Checking upload for $Remote" 25 | dd if=/dev/zero of=$UploadFile count=1024 bs=100 >/dev/null 2>&1 26 | /usr/bin/rclone move "$UploadFile" $Remote --delete-after --log-level ERROR 27 | if [ $? -eq 0 ]; then 28 | echo "INFO: Upload successful" 29 | if [[ $LastState == *"upload locked"* ]]; then 30 | echo "$(date "+%d.%m.%Y %T") $Remote upload unlocked" | tee -a $LogFile 31 | fi 32 | else 33 | echo "INFO: Upload error, drive locked" 34 | if [[ $LastState == *"upload unlocked"* ]]; then 35 | echo "$(date "+%d.%m.%Y %T") $Remote upload locked" | tee -a $LogFile 36 | fi 37 | fi 38 | echo "INFO: Finished in $(($(date +'%s') - $start)) seconds" 39 | exit 40 | --------------------------------------------------------------------------------