Compare commits

...

3 commits

Author SHA1 Message Date
e66c16c976
Kill kill kill kill kill 2024-11-26 22:06:55 +01:00
69b82a3497
Small refactor 2024-11-26 22:06:55 +01:00
6cb4533f4c
Remove unused files 2024-11-26 22:06:51 +01:00
61 changed files with 280 additions and 6485 deletions

13
.github/FUNDING.yml vendored
View file

@ -1,13 +0,0 @@
# These are supported funding model platforms
github: [RandomNinjaAtk] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View file

@ -1,43 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG] - APP NAME - ISSUE TITLE"
labels: Needs Triage
assignees: ''
---
**Application**
Radarr or Sonarr or Lidarr or SABnzbd
**Host platform**
Unraid/synology and etc... If using PORTAINER, do not open an issue, that is your problem....
**Script**
Please identify which script your having a problem with...
**Script Version**
Please provide the script version number
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Logs/Screenshots**
If applicable, add logs and screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
**NOTE**
Your request will not be addressed without proper detail and logs. Always make sure you have updated to the latest script versions before opening an issue or your issue will not be reviewed.

View file

@ -1,20 +0,0 @@
---
name: 'Feature request '
about: Suggest an idea for this project
title: "[FEATURE] - APP NAME - Request Title"
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -1,20 +1,13 @@
This is a fork the [arr-scripts repo](https://github.com/RandomNinjaAtk/arr-scripts/)
stripped of everything execpt the lidarr scripts, with the goal of porting it to NixOS.
# arr-scripts
Official Home of the scripts that were previously packaged with the "Extended" containers. Designed to be easily implemented/added to [Linuxserver.io](https://www.linuxserver.io/) containers.
## Usage
[Radarr Instructions](https://github.com/RandomNinjaAtk/arr-scripts/tree/main/radarr/readme.md)
[Sonarr Instructions](https://github.com/RandomNinjaAtk/arr-scripts/tree/main/sonarr/readme.md)
[Lidarr Instructions](https://github.com/RandomNinjaAtk/arr-scripts/tree/main/lidarr/readme.md)
[Readarr Instructions](https://github.com/RandomNinjaAtk/arr-scripts/tree/main/readarr/readme.md)
[SABnzbd Instructions](https://github.com/RandomNinjaAtk/arr-scripts/tree/main/sabnzbd#/readme.md)
## WARNING
DO NOT USE PORTAINER, it is known to not work and typically breaks things... From the various discussions I've seen in the Arr communities and Linuxserver.io, they tend to trend on saying to avoid it... If your using portainer and this is not functioning as expected, that is likely your problem.... (Example: <https://github.com/RandomNinjaAtk/arr-scripts/discussions/57>)
Also see here: <https://wiki.servarr.com/docker-guide#portainer>
[Lidarr Instructions](https://woof.rip/emily/lidarr-dl/src/branch/main/lidarr/readme.md)
## Support Info

View file

@ -1,5 +1,4 @@
#!/usr/bin/env bash
scriptVersion="1.2"
scriptName="ArtworkExtractor"
#### Import Settings

View file

@ -1,38 +1,59 @@
#!/usr/bin/with-contenv bash
scriptVersion="2.48"
set -euo pipefail
while [[ $# -gt 0 ]]; do
case $1 in
--state-dir)
STATE_DIR="$2"
shift
shift
;;
--runtime-dir)
RUNTIME_DIR="$2"
shift
shift
;;
*)
echo "Unknown option $1"
exit 1
;;
esac
done
scriptName="Audio"
### Import Settings
source /config/extended.conf
# shellcheck source=./extended.conf
source "${STATE_DIR}/lidarr-dl.conf"
#### Import Functions
source /config/extended/functions
source ../universal/functions.bash
AddTag () {
log "adding arr-extended tag"
lidarrProcessIt=$(curl -s "$arrUrl/api/v1/tag" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json" --data-raw '{"label":"arr-extended"}')
lidarrProcessIt=$(curl -s "$arrUrl/api/v1/tag" --header "X-Api-Key:" "${arrApiKey}" -H "Content-Type: application/json" --data-raw '{"label":"arr-extended"}')
}
AddDownloadClient () {
downloadClientsData=$(curl -s "$arrUrl/api/v1/downloadclient" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json")
downloadClientCheck="$(echo $downloadClientsData | grep "Arr-Extended")"
downloadClientsData=$(curl -s "$arrUrl/api/v1/downloadclient" --header "X-Api-Key:" "${arrApiKey}" -H "Content-Type: application/json")
downloadClientCheck="$(echo "$downloadClientsData" | grep "Arr-Extended")"
if [ -z "$downloadClientCheck" ]; then
AddTag
if [ ! -d "$importPath" ]; then
mkdir -p "$importPath"
chmod 777 -R "$importPath"
fi
log "Adding download Client"
lidarrProcessIt=$(curl -s "$arrUrl/api/v1/downloadclient" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json" --data-raw "{\"enable\":true,\"protocol\":\"usenet\",\"priority\":10,\"removeCompletedDownloads\":true,\"removeFailedDownloads\":true,\"name\":\"Arr-Extended\",\"fields\":[{\"name\":\"nzbFolder\",\"value\":\"$importPath\"},{\"name\":\"watchFolder\",\"value\":\"$importPath\"}],\"implementationName\":\"Usenet Blackhole\",\"implementation\":\"UsenetBlackhole\",\"configContract\":\"UsenetBlackholeSettings\",\"infoLink\":\"https://wiki.servarr.com/lidarr/supported#usenetblackhole\",\"tags\":[]}")
lidarrProcessIt=$(curl -s "$arrUrl/api/v1/downloadclient" --header "X-Api-Key:" "${arrApiKey}" -H "Content-Type: application/json" --data-raw "{\"enable\":true,\"protocol\":\"usenet\",\"priority\":10,\"removeCompletedDownloads\":true,\"removeFailedDownloads\":true,\"name\":\"Arr-Extended\",\"fields\":[{\"name\":\"nzbFolder\",\"value\":\"$importPath\"},{\"name\":\"watchFolder\",\"value\":\"$importPath\"}],\"implementationName\":\"Usenet Blackhole\",\"implementation\":\"UsenetBlackhole\",\"configContract\":\"UsenetBlackholeSettings\",\"infoLink\":\"https://wiki.servarr.com/lidarr/supported#usenetblackhole\",\"tags\":[]}")
fi
}
verifyConfig () {
### Import Settings
source /config/extended.conf
# shellcheck source=./extended.conf
source "${STATE_DIR}/lidarr-dl.conf"
if [ "$enableAudio" != "true" ]; then
log "Script is not enabled, enable by setting enableAudio to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
exit 0
fi
if [ -z "$audioScriptInterval" ]; then
@ -80,32 +101,13 @@ Configuration () {
sleepTimer=0.5
tidaldlFail=0
deemixFail=0
log "-----------------------------------------------------------------------------"
log " |~) _ ._ _| _ ._ _ |\ |o._ o _ |~|_|_|"
log " |~\(_|| |(_|(_)| | || \||| |_|(_||~| | |<"
log " Presents: $scriptName ($scriptVersion)"
log " May the beats be with you!"
log "-----------------------------------------------------------------------------"
log "Donate: https://github.com/sponsors/RandomNinjaAtk"
log "Project: https://github.com/RandomNinjaAtk/arr-scripts"
log "Support: https://github.com/RandomNinjaAtk/arr-scripts/discussions"
log "-----------------------------------------------------------------------------"
sleep 5
log ""
log "Lift off in..."; sleep 0.5
log "5"; sleep 1
log "4"; sleep 1
log "3"; sleep 1
log "2"; sleep 1
log "1"; sleep 1
if [ ! -d /config/xdg ]; then
mkdir -p /config/xdg
if [ ! -d "${STATE_DIR}/xdg" ]; then
mkdir -p "${STATE_DIR}/xdg"
fi
if [ -z $topLimit ]; then
if [ -z "$topLimit" ]; then
topLimit=10
fi
@ -175,10 +177,10 @@ Configuration () {
if [ $enableBeetsTagging = true ]; then
log "Beets Tagging Enabled"
log "Beets Matching Threshold ${beetsMatchPercentage}%"
beetsMatchPercentage=$(expr 100 - $beetsMatchPercentage )
if cat /config/extended/beets-config.yaml | grep "strong_rec_thresh: 0.04" | read; then
beetsMatchPercentage=$((100 - beetsMatchPercentage ))
if grep "strong_rec_thresh: 0.04" "${STATE_DIR}/extended/beets-config.yaml" | read -r; then
log "Configuring Beets Matching Threshold"
sed -i "s/strong_rec_thresh: 0.04/strong_rec_thresh: 0.${beetsMatchPercentage}/g" /config/extended/beets-config.yaml
sed -i "s/strong_rec_thresh: 0.04/strong_rec_thresh: 0.${beetsMatchPercentage}/g" "${STATE_DIR}/extended/beets-config.yaml"
fi
else
log "Beets Tagging Disabled"
@ -195,11 +197,7 @@ Configuration () {
}
DownloadClientFreyr () {
timeout $downloadClientTimeOut freyr --no-bar --no-net-check -d $audioPath/incomplete deezer:album:$1 2>&1 | tee -a "/config/logs/$logFileName"
# Resolve issue 94
if [ -d /root/.cache/FreyrCLI ]; then
rm -rf /root/.cache/FreyrCLI/*
fi
timeout $downloadClientTimeOut freyr --no-bar --no-net-check -d "$audioPath/incomplete" "deezer:album:$1" 2>&1
}
DownloadFormat () {
@ -222,9 +220,7 @@ DownloadFormat () {
log "ERROR :: Change audioBitrate to a low, high, or lossless..."
log "ERROR :: Exiting..."
NotifyWebhook "FatalError" "Invalid audioFormat and audioBitrate options set"
log "Script sleeping for $audioScriptInterval..."
sleep $audioScriptInterval
exit
exit 1
fi
else
bitrateError="false"
@ -246,9 +242,7 @@ DownloadFormat () {
log "ERROR :: Change audioBitrate to a desired bitrate number, example: 192..."
log "ERROR :: Exiting..."
NotifyWebhook "FatalError" "audioBitrate options set"
log "Script sleeping for $audioScriptInterval..."
sleep $audioScriptInterval
exit
exit 1
fi
case "$audioFormat" in
@ -281,45 +275,32 @@ DownloadFolderCleaner () {
if [ -d "$audioPath/complete" ]; then
log "Removing prevously completed downloads that failed to import..."
# check for completed downloads older than 1 day
if find "$audioPath"/complete -mindepth 1 -type d -mtime +1 | read; then
if find "$audioPath/complete" -mindepth 1 -type d -mtime +1 | read -r; then
# delete completed downloads older than 1 day, these most likely failed to import due to Lidarr failing to match
find "$audioPath"/complete -mindepth 1 -type d -mtime +1 -exec rm -rf "{}" \; &>/dev/null
fi
fi
}
NotFoundFolderCleaner () {
# check for completed download folder
if [ -d /config/extended/logs/notfound ]; then
# check for notfound entries older than X days
if find /config/extended/logs/notfound -mindepth 1 -type f -mtime +$retryNotFound | read; then
log "Removing prevously notfound lidarr album ids older than $retryNotFound days to give them a retry..."
# delete ntofound entries older than X days
find /config/extended/logs/notfound -mindepth 1 -type f -mtime +$retryNotFound -delete
find "$audioPath/complete" -mindepth 1 -type d -mtime +1 -exec rm -rf "{}" \; &>/dev/null
fi
fi
}
TidalClientSetup () {
log "TIDAL :: Verifying tidal-dl configuration"
touch /config/xdg/.tidal-dl.log
if [ -f /config/xdg/.tidal-dl.json ]; then
rm /config/xdg/.tidal-dl.json
touch "${STATE_DIR}/xdg/.tidal-dl.log"
if [ -f "${STATE_DIR}/xdg/.tidal-dl.json" ]; then
rm "${STATE_DIR}/xdg/.tidal-dl.json"
fi
if [ ! -f /config/xdg/.tidal-dl.json ]; then
if [ ! -f "${STATE_DIR}/xdg/.tidal-dl.json" ]; then
log "TIDAL :: No default config found, importing default config \"tidal.json\""
if [ -f /config/extended/tidal-dl.json ]; then
cp /config/extended/tidal-dl.json /config/xdg/.tidal-dl.json
chmod 777 -R /config/xdg/
if [ -f "${STATE_DIR}/extended/tidal-dl.json" ]; then
cp "${STATE_DIR}/extended/tidal-dl.json" "${STATE_DIR}/xdg/.tidal-dl.json"
fi
fi
TidaldlStatusCheck
tidal-dl -o "$audioPath"/incomplete 2>&1 | tee -a "/config/logs/$logFileName"
tidal-dl -o "$audioPath/incomplete" 2>&1
DownloadFormat
if [ ! -f /config/xdg/.tidal-dl.token.json ]; then
if [ ! -f "${STATE_DIR}/xdg/.tidal-dl.token.json" ]; then
TidaldlStatusCheck
#log "TIDAL :: ERROR :: Downgrade tidal-dl for workaround..."
#pip3 install tidal-dl==2022.3.4.2 --no-cache-dir &>/dev/null
@ -329,21 +310,19 @@ TidalClientSetup () {
tidal-dl
fi
if [ ! -d /config/extended/cache/tidal ]; then
mkdir -p /config/extended/cache/tidal
chmod 777 /config/extended/cache/tidal
if [ ! -d "${STATE_DIR}/extended/cache/tidal" ]; then
mkdir -p "${STATE_DIR}/extended/cache/tidal"
fi
if [ -d /config/extended/cache/tidal ]; then
if [ -d "${STATE_DIR}/extended/cache/tidal" ]; then
log "TIDAL :: Purging album list cache..."
rm /config/extended/cache/tidal/*-albums.json &>/dev/null
rm "${STATE_DIR}/extended/cache/tidal/*-albums.json" &>/dev/null
fi
if [ ! -d "$audioPath/incomplete" ]; then
mkdir -p "$audioPath"/incomplete
chmod 777 "$audioPath"/incomplete
else
rm -rf "$audioPath"/incomplete/*
rm -rf "$audioPath/incomplete/*"
fi
TidaldlStatusCheck
@ -353,16 +332,15 @@ TidalClientSetup () {
}
TidaldlStatusCheck () {
until false
do
running=no
if ps aux | grep "tidal-dl" | grep -v "grep" | read; then
running=yes
log "STATUS :: TIDAL-DL :: BUSY :: Pausing/waiting for all active tidal-dl tasks to end..."
sleep 2
continue
fi
break
until false; do
running=no
if pgrep -f "tidal-dl" | read -r; then
running=yes
log "STATUS :: TIDAL-DL :: BUSY :: Pausing/waiting for all active tidal-dl tasks to end..."
sleep 2
continue
fi
break
done
}
@ -370,37 +348,42 @@ TidalClientTest () {
log "TIDAL :: tidal-dl client setup verification..."
i=0
while [ $i -lt 3 ]; do
i=$(( $i + 1 ))
i=$(( i + 1 ))
TidaldlStatusCheck
tidal-dl -q Normal -o "$audioPath"/incomplete -l "$tidalClientTestDownloadId" 2>&1 | tee -a "/config/logs/$logFileName"
downloadCount=$(find "$audioPath"/incomplete -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l)
if [ $downloadCount -le 0 ]; then
tidal-dl -q Normal -o "$audioPath/incomplete" -l "$tidalClientTestDownloadId" 2>&1
downloadCount=$(find "$audioPath/incomplete" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l)
if [ "$downloadCount" -le 0 ]; then
continue
else
break
fi
done
tidalClientTest="unknown"
if [ $downloadCount -le 0 ]; then
if [ -f /config/xdg/.tidal-dl.token.json ]; then
rm /config/xdg/.tidal-dl.token.json
if [ "$downloadCount" -le 0 ]; then
if [ -f "${STATE_DIR}/xdg/.tidal-dl.token.json" ]; then
rm "${STATE_DIR}/xdg/.tidal-dl.token.json"
fi
log "TIDAL :: ERROR :: Download failed"
log "TIDAL :: ERROR :: You will need to re-authenticate on next script run..."
log "TIDAL :: ERROR :: Exiting..."
rm -rf "$audioPath"/incomplete/*
rm -rf "$audioPath/incomplete/*"
NotifyWebhook "Error" "TIDAL not authenticated but configured"
tidalClientTest="failed"
log "Script sleeping for $audioScriptInterval..."
sleep $audioScriptInterval
exit
else
rm -rf "$audioPath"/incomplete/*
rm -rf "$audioPath/incomplete/*"
log "TIDAL :: Successfully Verified"
tidalClientTest="success"
fi
}
logDl () {
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: \
$lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $1"
}
DownloadProcess () {
# Required Input Data
@ -412,107 +395,71 @@ DownloadProcess () {
# Create Required Directories
if [ ! -d "$audioPath/incomplete" ]; then
mkdir -p "$audioPath"/incomplete
chmod 777 "$audioPath"/incomplete
mkdir -p "$audioPath/incomplete"
else
rm -rf "$audioPath"/incomplete/*
rm -rf "$audioPath/incomplete/*"
fi
if [ ! -d "$audioPath/complete" ]; then
mkdir -p "$audioPath"/complete
chmod 777 "$audioPath"/complete
mkdir -p "$audioPath/complete"
else
rm -rf "$audioPath"/complete/*
rm -rf "$audioPath/complete/*"
fi
if [ ! -d "/config/extended/logs" ]; then
mkdir -p /config/extended/logs
chmod 777 /config/extended/logs
fi
if [ ! -d "/config/extended/logs/downloaded" ]; then
mkdir -p /config/extended/logs/downloaded
chmod 777 /config/extended/logs/downloaded
fi
if [ ! -d "/config/extended/logs/downloaded/deezer" ]; then
mkdir -p /config/extended/logs/downloaded/deezer
chmod 777 /config/extended/logs/downloaded/deezer
fi
if [ ! -d "/config/extended/logs/downloaded/tidal" ]; then
mkdir -p /config/extended/logs/downloaded/tidal
chmod 777 /config/extended/logs/downloaded/tidal
fi
if [ ! -d /config/extended/logs/downloaded/failed/deezer ]; then
mkdir -p /config/extended/logs/downloaded/failed/deezer
chmod 777 /config/extended/logs/downloaded/failed/deezer
fi
if [ ! -d /config/extended/logs/downloaded/failed/tidal ]; then
mkdir -p /config/extended/logs/downloaded/failed/tidal
chmod 777 /config/extended/logs/downloaded/failed/tidal
fi
logPaths=( "deezer" "tidal" "failed/deezer" "failed/tidal" )
for p in "${!logPaths[@]}"; do
if [ ! -d "${STATE_DIR}/extended/logs/downloaded/${logPaths[$p]}" ]; then
mkdir -p "${STATE_DIR}/extended/logs/downloaded/${logPaths[$p]}"
fi
done
if [ ! -d "$importPath" ]; then
mkdir -p "$importPath"
chmod 777 "$importPath"
fi
AddDownloadClient
downloadedAlbumTitleClean="$(echo "$4" | sed -e "s%[^[:alpha:][:digit:]._' ]% %g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')"
if find "$audioPath"/complete -type d -iname "$lidarrArtistNameSanitized-$downloadedAlbumTitleClean ($3)-*-$1-$2" | read; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Downloaded..."
if find "$audioPath/complete" -type d -iname "$lidarrArtistNameSanitized-$downloadedAlbumTitleClean ($3)-*-$1-$2" | read -r; then
logDl "ERROR :: Previously Downloaded..."
return
fi
# check for log file
if [ "$2" == "DEEZER" ]; then
if [ -f /config/extended/logs/downloaded/deezer/$1 ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Downloaded ($1)..."
return
fi
if [ -f /config/extended/logs/downloaded/failed/deezer/$1 ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Attempted Download ($1)..."
return
fi
fi
# check for log file
if [ "$2" == "TIDAL" ]; then
if [ -f /config/extended/logs/downloaded/tidal/$1 ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Downloaded ($1)..."
return
fi
if [ -f /config/extended/logs/downloaded/failed/tidal/$1 ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Attempted Download ($1)..."
return
fi
fi
for i in "DEEZER" "TIDAL"; do
if [ "$2" == $i ]; then
if [ -f "${STATE_DIR}/extended/logs/downloaded/${i,,}/$1" ]; then
logDl "ERROR :: Previously Downloaded ($1)..."
return
fi
if [ -f "${STATE_DIR}/extended/logs/downloaded/failed/${i,,}/$1" ]; then
logDl "ERROR :: Previously Attempted Download ($1)..."
return
fi
fi
done
downloadTry=0
until false
do
downloadTry=$(( $downloadTry + 1 ))
if [ -f /temp-download ]; then
rm /temp-download
downloadTry=$(( downloadTry + 1 ))
if [ -f /tmp/temp-download ]; then
rm /tmp/temp-download
sleep 0.1
fi
touch /temp-download
touch /tmp/temp-download
sleep 0.1
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Download Attempt number $downloadTry"
logDl "Download Attempt number $downloadTry"
if [ "$2" == "DEEZER" ]; then
if [ -z $arlToken ]; then
DownloadClientFreyr $1
if [ -z "$arlToken" ]; then
DownloadClientFreyr "$1"
else
deemix -b $deemixQuality -p "$audioPath"/incomplete "https://www.deezer.com/album/$1" 2>&1 | tee -a "/config/logs/$logFileName"
deemix -b $deemixQuality -p "$audioPath"/incomplete "https://www.deezer.com/album/$1" 2>&1
fi
if [ -d "/tmp/deemix-imgs" ]; then
@ -521,49 +468,43 @@ DownloadProcess () {
# Verify Client Works...
clientTestDlCount=$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l)
if [ $clientTestDlCount -le 0 ]; then
if [ "$clientTestDlCount" -le 0 ]; then
# Add +1 to failed attempts
deemixFail=$(( $deemixFail + 1))
deemixFail=$(( deemixFail + 1))
else
# Reset for successful download
deemixFail=0
fi
# If download failes X times, exit with error...
if [ $deemixFail -eq $failedDownloadAttemptThreshold ]; then
if [ -z $arlToken ]; then
rm -rf "$audioPath"/incomplete/*
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: All $failedDownloadAttemptThreshold Download Attempts failed, skipping..."
else
DeezerClientTest
if [ "$deezerClientTest" == "success" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: All $failedDownloadAttemptThreshold Download Attempts failed, skipping..."
deemixFail=0
fi
if [ $deemixFail -eq $failedDownloadAttemptThreshold ] && [ -z "$arlToken" ]; then
rm -rf "$audioPath"/incomplete/*
logDl "All $failedDownloadAttemptThreshold Download Attempts failed, skipping..."
else
DeezerClientTest
if [ "$deezerClientTest" == "success" ]; then
logDl "All $failedDownloadAttemptThreshold Download Attempts failed, skipping..."
deemixFail=0
fi
fi
fi
if [ "$2" == "DEEZER" ]; then
if [ $deemixFail -eq $failedDownloadAttemptThreshold ]; then
if [ -z $arlToken ]; then
DownloadClientFreyr $1
else
deemix -b $deemixQuality -p "$audioPath"/incomplete "https://www.deezer.com/album/$1" 2>&1 | tee -a "/config/logs/$logFileName"
fi
fi
fi
if [ "$2" == "DEEZER" ] && [ $deemixFail -eq $failedDownloadAttemptThreshold ] && [ -z "$arlToken" ]; then
DownloadClientFreyr "$1"
else
deemix -b $deemixQuality -p "$audioPath"/incomplete "https://www.deezer.com/album/$1" 2>&1
fi
if [ "$2" == "TIDAL" ]; then
TidaldlStatusCheck
tidal-dl -q $tidalQuality -o "$audioPath/incomplete" -l "$1" 2>&1 | tee -a "/config/logs/$logFileName"
tidal-dl -q $tidalQuality -o "$audioPath/incomplete" -l "$1" 2>&1
# Verify Client Works...
clientTestDlCount=$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l)
if [ $clientTestDlCount -le 0 ]; then
if [ "$clientTestDlCount" -le 0 ]; then
# Add +1 to failed attempts
tidaldlFail=$(( $tidaldlFail + 1))
tidaldlFail=$(( tidaldlFail + 1))
else
# Reset for successful download
tidaldlFail=0
@ -571,29 +512,29 @@ DownloadProcess () {
# If download failes X times, exit with error...
if [ $tidaldlFail -eq $failedDownloadAttemptThreshold ]; then
TidalClientTest
if [ "$tidalClientTest" == "success" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: All $failedDownloadAttemptThreshold Download Attempts failed, skipping..."
TidalClientTest
if [ "$tidalClientTest" == "success" ]; then
logDl "All $failedDownloadAttemptThreshold Download Attempts failed, skipping..."
fi
fi
fi
find "$audioPath/incomplete" -type f -iname "*.flac" -newer "/temp-download" -print0 | while IFS= read -r -d '' file; do
find "$audioPath/incomplete" -type f -iname "*.flac" -newer "/tmp/temp-download" -print0 | while IFS= read -r -d '' file; do
audioFlacVerification "$file"
if [ "$verifiedFlacFile" == "0" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Flac Verification :: $file :: Verified"
logDl "Flac Verification :: $file :: Verified"
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Flac Verification :: $file :: ERROR :: Failed Verification"
logDl "Flac Verification :: $file :: ERROR :: Failed Verification"
rm "$file"
fi
done
downloadCount=$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|m4a\|mp3\)" | wc -l)
if [ "$downloadCount" -ne "$5" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: download failed, missing tracks..."
logDl "ERROR :: download failed, missing tracks..."
completedVerification="false"
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Success"
logDl "Success"
completedVerification="true"
fi
@ -605,13 +546,13 @@ DownloadProcess () {
fi
break
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Retry Download in 1 second fix errors..."
logDl "Retry Download in 1 second fix errors..."
sleep 1
fi
done
# Consolidate files to a single folder
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Consolidating files to single folder"
logDl "Consolidating files to single folder"
find "$audioPath/incomplete" -type f -exec mv "{}" "$audioPath"/incomplete/ \; 2>/dev/null
find $audioPath/incomplete/ -type d -mindepth 1 -maxdepth 1 -exec rm -rf {} \; 2>/dev/null
@ -623,34 +564,28 @@ DownloadProcess () {
downloadCount=$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|m4a\|mp3\)" | wc -l)
if [ "$downloadCount" -ne "$5" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: All download Attempts failed..."
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Logging $1 as failed download..."
logDl "ERROR :: All download Attempts failed..."
logDl "Logging $1 as failed download..."
if [ "$2" == "DEEZER" ]; then
touch /config/extended/logs/downloaded/failed/deezer/$1
fi
if [ "$2" == "TIDAL" ]; then
touch /config/extended/logs/downloaded/failed/tidal/$1
fi
for awa in "DEEZER" "TIDAL"; do
[ "$2" == $awa ] \
&& touch "${STATE_DIR}/extended/logs/downloaded/failed/${awa,,}/$1"
done
return
fi
# Log Completed Download
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Logging $1 as successfully downloaded..."
if [ "$2" == "DEEZER" ]; then
touch /config/extended/logs/downloaded/deezer/$1
fi
if [ "$2" == "TIDAL" ]; then
touch /config/extended/logs/downloaded/tidal/$1
fi
logDl "Logging $1 as successfully downloaded..."
for awa in "DEEZER" "TIDAL"; do
[ "$2" == $awa ] \
&& touch "${STATE_DIR}/extended/logs/downloaded/${awa,,}/$1"
done
# Tag with beets
if [ "$enableBeetsTagging" == "true" ]; then
if [ -f /config/extended/beets-error ]; then
rm /config/extended/beets-error
fi
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Processing files with beets..."
[ -f "${STATE_DIR}/extended/beets-error" ] && rm "${STATE_DIR}/extended/beets-error"
logDl "Processing files with beets..."
ProcessWithBeets "$audioPath/incomplete"
fi
@ -658,33 +593,30 @@ DownloadProcess () {
find "$audioPath/incomplete" -type f -iname "*.flac" -print0 | while IFS= read -r -d '' file; do
lrcFile="${file%.*}.lrc"
if [ -f "$lrcFile" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Embedding lyrics (lrc) into $file"
logDl "Embedding lyrics (lrc) into $file"
metaflac --remove-tag=Lyrics "$file"
metaflac --set-tag-from-file="Lyrics=$lrcFile" "$file"
fi
done
if [ "$audioFormat" != "native" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Converting Flac Audio to ${audioFormat^^} ($audioBitrateText)"
if [ "$audioFormat" == "opus" ]; then
options="-c:a libopus -b:a ${audioBitrate}k -application audio -vbr off"
extension="opus"
fi
logDl "Converting Flac Audio to ${audioFormat^^} ($audioBitrateText)"
if [ "$audioFormat" == "mp3" ]; then
options="-c:a libmp3lame -b:a ${audioBitrate}k"
extension="mp3"
fi
[ "$audioFormat" == "opus" ] \
&& options="-c:a libopus -b:a ${audioBitrate}k -application audio -vbr off" \
&& extension=$audioFormat
if [ "$audioFormat" == "aac" ]; then
options="-c:a aac -b:a ${audioBitrate}k -movflags faststart"
extension="m4a"
fi
[ "$audioFormat" == "mp3" ] \
&& options="-c:a libmp3lame -b:a ${audioBitrate}k" \
&& extension=$audioFormat
if [ "$audioFormat" == "alac" ]; then
options="-c:a alac -movflags faststart"
extension="m4a"
fi
[ "$audioFormat" == "aac" ] \
&& options="-c:a aac -b:a ${audioBitrate}k -movflags faststart" \
&& extension="m4a"
[ "$audioFormat" == "alac" ] \
&& options="-c:a alac -movflags faststart" \
&& extension="m4a"
find "$audioPath/incomplete" -type f -iname "*.flac" -print0 | while IFS= read -r -d '' audio; do
file="${audio}"
@ -693,20 +625,20 @@ DownloadProcess () {
filenamenoext="${filename%.*}"
if [ "$audioFormat" == "opus" ]; then
if opusenc --bitrate ${audioBitrate} --vbr --music "$file" "$foldername/${filenamenoext}.$extension"; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $filename :: Conversion to $audioFormat ($audioBitrateText) successful"
logDl "$filename :: Conversion to $audioFormat ($audioBitrateText) successful"
rm "$file"
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $filename :: ERROR :: Conversion Failed"
logDl "$filename :: ERROR :: Conversion Failed"
rm "$foldername/${filenamenoext}.$extension"
fi
continue
fi
if ffmpeg -loglevel warning -hide_banner -nostats -i "$file" -n -vn $options "$foldername/${filenamenoext}.$extension" < /dev/null; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $filename :: Conversion to $audioFormat ($audioBitrateText) successful"
if ffmpeg -loglevel warning -hide_banner -nostats -i "$file" -n -vn "$options" "$foldername/${filenamenoext}.$extension" < /dev/null; then
logDl "$filename :: Conversion to $audioFormat ($audioBitrateText) successful"
rm "$file"
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $filename :: ERROR :: Conversion Failed"
logDl "$filename :: ERROR :: Conversion Failed"
rm "$foldername/${filenamenoext}.$extension"
fi
done
@ -716,10 +648,10 @@ DownloadProcess () {
if [ "$enableReplaygainTags" == "true" ]; then
AddReplaygainTags "$audioPath/incomplete"
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Replaygain Tagging Disabled (set enableReplaygainTags=true to enable...)"
logDl "Replaygain Tagging Disabled (set enableReplaygainTags=true to enable...)"
fi
albumquality="$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | head -n 1 | egrep -i -E -o "\.{1}\w*$" | sed 's/\.//g')"
albumquality="$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | head -n 1 | grep -i -E -o "\.{1}\w*$" | sed 's/\.//g')"
downloadedAlbumFolder="${lidarrArtistNameSanitized}-${downloadedAlbumTitleClean:0:100} (${3})"
find "$audioPath/incomplete" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -print0 | while IFS= read -r -d '' audio; do
@ -754,172 +686,146 @@ DownloadProcess () {
ProcessWithBeets () {
# Input
# $1 Download Folder to process
if [ -f /config/extended/beets-library.blb ]; then
rm /config/extended/beets-library.blb
sleep 0.5
fi
if [ -f /config/extended/beets.log ]; then
rm /config/extended/beets.log
sleep 0.5
fi
for awa in "extended/beets-library.blb" "extended/beets.log" "beets-match"; do
[ -f "${STATE_DIR}/${awa}" ] \
&& rm "${STATE_DIR}/${awa}" \
&& sleep 0.5
done
if [ -f "/config/beets-match" ]; then
rm "/config/beets-match"
sleep 0.5
fi
touch "/config/beets-match"
sleep 0.5
beet -c /config/extended/beets-config.yaml -l /config/extended/beets-library.blb -d "$1" import -qC "$1"
if [ $(find "$1" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -newer "/config/beets-match" | wc -l) -gt 0 ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: SUCCESS: Matched with beets!"
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: fixing track tags"
beet -c "${STATE_DIR}/extended/beets-config.yaml" \
-l "${STATE_DIR}/extended/beets-library.blb" -d "$1" import -qC "$1"
if [ "$(find "$1" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -newer "${STATE_DIR}/beets-match" | wc -l)" -gt 0 ]; then
logDl "SUCCESS: Matched with beets!"
logDl "fixing track tags"
find "$audioPath/incomplete" -type f -iname "*.flac" -print0 | while IFS= read -r -d '' file; do
getArtistCredit="$(ffprobe -loglevel 0 -print_format json -show_format -show_streams "$file" | jq -r ".format.tags.ARTIST_CREDIT" | sed "s/null//g" | sed "/^$/d")"
# album artist
metaflac --remove-tag=ALBUMARTIST "$file"
metaflac --remove-tag=ALBUMARTIST_CREDIT "$file"
metaflac --remove-tag=ALBUM_ARTIST "$file"
metaflac --remove-tag="ALBUM ARTIST" "$file"
# artist
metaflac --remove-tag=ARTIST "$file"
metaflac --remove-tag=ARTIST_CREDIT "$file"
if [ ! -z "$getArtistCredit" ]; then
metaflac --set-tag=ARTIST="$getArtistCredit" "$file"
metaflac \
--remove-tag=ALBUMARTIST --remove-tag=ALBUMARTIST_CREDIT --remove-tag=ALBUM_ARTIST \
--remove-tag="ALBUM ARTIST" --remove-tag=ARTIST --remove-tag=ARTIST_CREDIT \
--remove-tag=ARTISTSORT --remove-tag=COMPOSERSORT --remove-tag=ALBUMARTISTSORT \
--remove-tag=MUSICBRAINZ_ARTISTID --remove-tag=MUSICBRAINZ_ALBUMARTISTID \
"$file"
metaflac \
--set-tag=ALBUMARTIST="$lidarrArtistName" \
--set-tag=MUSICBRAINZ_ARTISTID="$lidarrArtistForeignArtistId" \
--set-tag=MUSICBRAINZ_ALBUMARTISTID="$lidarrArtistForeignArtistId" \
"$file"
if [ -n "$getArtistCredit" ]; then
metaflac --set-tag=ARTIST="$getArtistCredit" "$file"
else
metaflac --set-tag=ARTIST="$lidarrArtistName" "$file"
fi
# sorts
metaflac --remove-tag=ARTISTSORT "$file"
metaflac --remove-tag=COMPOSERSORT "$file"
metaflac --remove-tag=ALBUMARTISTSORT "$file"
# lidarr
metaflac --set-tag=ALBUMARTIST="$lidarrArtistName" "$file"
# mbrainz
metaflac --remove-tag=MUSICBRAINZ_ARTISTID "$file"
metaflac --remove-tag=MUSICBRAINZ_ALBUMARTISTID "$file"
metaflac --set-tag=MUSICBRAINZ_ARTISTID="$lidarrArtistForeignArtistId" "$file"
metaflac --set-tag=MUSICBRAINZ_ALBUMARTISTID="$lidarrArtistForeignArtistId" "$file"
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: FIXED : $file"
log "FIXED : $file"
done
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Unable to match using beets to a musicbrainz release..."
log "ERROR :: Unable to match using beets to a musicbrainz release..."
return
fi
if [ -f "/config/beets-match" ]; then
rm "/config/beets-match"
sleep 0.1
fi
[ -f "${STATE_DIR}/beets-match" ] \
&& rm "${STATE_DIR}/beets-match" \
&& sleep 0.1
# Get file metadata
GetFile=$(find "$audioPath/incomplete" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | head -n1)
extension="${GetFile##*.}"
ffprobeGet=$(ffprobe -hide_banner -loglevel fatal -show_error -show_format -show_streams \
-show_programs -show_chapters -show_private_data -print_format json \
"$GetFile"
)
if [ "$extension" == "opus" ]; then
matchedTags=$(ffprobe -hide_banner -loglevel fatal -show_error -show_format -show_streams -show_programs -show_chapters -show_private_data -print_format json "$GetFile" | jq -r ".streams[].tags")
matchedTags=$(${ffprobeGet} | jq -r ".streams[].tags")
else
matchedTags=$(ffprobe -hide_banner -loglevel fatal -show_error -show_format -show_streams -show_programs -show_chapters -show_private_data -print_format json "$GetFile" | jq -r ".format.tags")
matchedTags=$(${ffprobeGet} | jq -r ".format.tags")
fi
# Get Musicbrainz Release Group ID and Album Artist ID from tagged file
if [ "$extension" == "flac" ] || [ "$extension" == "opus" ]; then
matchedTagsAlbumReleaseGroupId="$(echo $matchedTags | jq -r ".MUSICBRAINZ_RELEASEGROUPID")"
matchedTagsAlbumArtistId="$(echo $matchedTags | jq -r ".MUSICBRAINZ_ALBUMARTISTID")"
matchedTagsAlbumReleaseGroupId="$(echo "$matchedTags" | jq -r ".MUSICBRAINZ_RELEASEGROUPID")"
matchedTagsAlbumArtistId="$(echo "$matchedTags" | jq -r ".MUSICBRAINZ_ALBUMARTISTID")"
elif [ "$extension" == "mp3" ] || [ "$extension" == "m4a" ]; then
matchedTagsAlbumReleaseGroupId="$(echo $matchedTags | jq -r '."MusicBrainz Release Group Id"')"
matchedLidarrAlbumArtistId="$(echo $matchedTags | jq -r '."MusicBrainz Ablum Artist Id"')"
matchedTagsAlbumReleaseGroupId="$(echo "$matchedTags" | jq -r '."MusicBrainz Release Group Id"')"
matchedLidarrAlbumArtistId="$(echo "$matchedTags" | jq -r '."MusicBrainz Ablum Artist Id"')"
fi
if [ ! -d "/config/extended/logs/downloaded/musicbrainz_matched" ]; then
mkdir -p "/config/extended/logs/downloaded/musicbrainz_matched"
chmod 777 "/config/extended/logs/downloaded/musicbrainz_matched"
fi
[ ! -d "${STATE_DIR}/extended/logs/downloaded/musicbrainz_matched" ] \
&& mkdir -p "${STATE_DIR}/extended/logs/downloaded/musicbrainz_matched"
if [ ! -f "/config/extended/logs/downloaded/musicbrainz_matched/$matchedTagsAlbumReleaseGroupId" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Marking MusicBrainz Release Group ($matchedTagsAlbumReleaseGroupId) as successfully downloaded..."
touch "/config/extended/logs/downloaded/musicbrainz_matched/$matchedTagsAlbumReleaseGroupId"
fi
[ ! -f "${STATE_DIR}/extended/logs/downloaded/musicbrainz_matched/$matchedTagsAlbumReleaseGroupId" ] \
&& log "Marking MusicBrainz Release Group ($matchedTagsAlbumReleaseGroupId) as successfully downloaded..." \
&& touch "/config/extended/logs/downloaded/musicbrainz_matched/$matchedTagsAlbumReleaseGroupId"
}
DownloadQualityCheck () {
if [ "$requireQuality" == "true" ]; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Checking for unwanted files"
[ "$requireQuality" != "true" ] \
&& logDl "Skipping download quality check... (enable by setting: requireQuality=true)" \
&& return
if [ "$audioFormat" != "native" ]; then
if find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)"| read; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!"
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..."
rm "$1"/*
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!"
fi
fi
if [ "$audioFormat" == "native" ]; then
if [ "$audioBitrate" == "master" ]; then
if find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)"| read; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!"
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..."
rm "$1"/*
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!"
fi
elif [ "$audioBitrate" == "lossless" ]; then
if find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)"| read; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!"
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..."
rm "$1"/*
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!"
fi
elif [ "$2" == "DEEZER" ]; then
if find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|flac\)"| read; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!"
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..."
rm "$1"/*
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!"
fi
elif [ "$2" == "TIDAL" ]; then
if find "$1" -type f -regex ".*/.*\.\(opus\|flac\|mp3\)"| read; then
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!"
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..."
rm "$1"/*
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!"
fi
fi
fi
logDl "Checking for unwanted files"
local deezer
local tidal
local other
local notNative
notNative=$([ "$audioFormat" != "native" ] \
&& find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)" | read -r
)
other=$([ "$audioBitrate" == "master" ] || [ "$audioBitrate" == "lossless" ] \
&& find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)" | read -r
)
deezer=$([ "$2" == "DEEZER" ] \
&& find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|flac\)" | read -r
)
tidal=$([ "$2" == "TIDAL" ] \
&& find "$1" -type f -regex ".*/.*\.\(opus\|flac\|mp3\)" | read -r
)
if $notNative || $deezer || $tidal || $other; then
logDl "Unwanted files found!"
logDl "Performing cleanup..."
rm "$1"/*
else
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Skipping download quality check... (enable by setting: requireQuality=true)"
logDl "No unwanted files found!"
fi
}
AddReplaygainTags () {
# Input Data
# $1 Folder path to scan and add tags
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Adding Replaygain Tags using r128gain"
logDl "Adding Replaygain Tags using r128gain"
r128gain -r -c 1 -a "$1" &>/dev/null
}
NotifyLidarrForImport () {
LidarrProcessIt=$(curl -s "$arrUrl/api/v1/command" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json" --data "{\"name\":\"DownloadedAlbumsScan\", \"path\":\"$1\"}")
log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: LIDARR IMPORT NOTIFICATION SENT! :: $1"
curl -s "$arrUrl/api/v1/command" --header "X-Api-Key:" "${arrApiKey}" -H "Content-Type: application/json" --data "{\"name\":\"DownloadedAlbumsScan\", \"path\":\"$1\"}"
logDl "LIDARR IMPORT NOTIFICATION SENT! :: $1"
}
DeemixClientSetup () {
log "DEEZER :: Verifying deemix configuration"
if [ ! -z "$arlToken" ]; then
arlToken="$(echo $arlToken | sed -e "s%[^[:alpha:][:digit:]]%%g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')"
if [ -n "$arlToken" ]; then
arlToken="$(echo "$arlToken" | sed -e "s%[^[:alpha:][:digit:]]%%g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')"
# Create directories
mkdir -p /config/xdg/deemix
if [ -f "/config/xdg/deemix/.arl" ]; then
rm "/config/xdg/deemix/.arl"
mkdir -p "${STATE_DIR}/xdg/deemix"
if [ -f "${STATE_DIR}/xdg/deemix/.arl" ]; then
rm "${STATE_DIR}/xdg/deemix/.arl"
fi
if [ ! -f "/config/xdg/deemix/.arl" ]; then
echo -n "$arlToken" > "/config/xdg/deemix/.arl"
if [ ! -f "${STATE_DIR}/xdg/deemix/.arl" ]; then
echo -n "$arlToken" > "/${STATE_DIR}/xdg/deemix/.arl"
fi
log "DEEZER :: ARL Token: Configured"
else
@ -1783,9 +1689,6 @@ AudioProcess () {
Configuration
# Perform NotFound Folder Cleanup process
NotFoundFolderCleaner
LidarrRootFolderCheck
DownloadFormat
@ -1821,14 +1724,13 @@ AudioProcess () {
log "Starting Script...."
for (( ; ; )); do
let i++
logfileSetup
verifyConfig
(( i++ )) || true
verifyConfig
getArrAppInfo
verifyApiAccess
AudioProcess
log "Script sleeping for $audioScriptInterval..."
sleep $audioScriptInterval
sleep "$audioScriptInterval"
done
exit

View file

@ -1,6 +1,4 @@
#!/usr/bin/env bash
scriptVersion="3.2"
scriptName="AutoConfig"
### Import Settings
source /config/extended.conf
@ -36,7 +34,7 @@ fi
if [ "$configureCustomScripts" == "true" ] || [ -z "$configureCustomScripts" ]; then
log "Configuring Lidarr Custom Scripts"
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "PlexNotify.bash" | read; then
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "PlexNotify.bash" | read -r; then
log "PlexNotify.bash Already added to Lidarr custom scripts"
else
log "Adding PlexNotify.bash to Lidarr custom scripts"
@ -46,7 +44,7 @@ if [ "$configureCustomScripts" == "true" ] || [ -z "$configureCustomScripts" ];
fi
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "LyricExtractor.bash" | read; then
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "LyricExtractor.bash" | read -r; then
log "LyricExtractor.bash Already added to Lidarr custom scripts"
else
log "Adding LyricExtractor.bash to Lidarr custom scripts"
@ -56,7 +54,7 @@ if [ "$configureCustomScripts" == "true" ] || [ -z "$configureCustomScripts" ];
fi
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "ArtworkExtractor.bash" | read; then
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "ArtworkExtractor.bash" | read -r; then
log "ArtworkExtractor.bash Already added to Lidarr custom scripts"
else
log "Adding ArtworkExtractor.bash to Lidarr custom scripts"
@ -66,7 +64,7 @@ if [ "$configureCustomScripts" == "true" ] || [ -z "$configureCustomScripts" ];
fi
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "BeetsTagger.bash" | read; then
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "BeetsTagger.bash" | read -r; then
log "BeetsTagger.bash Already added to Lidarr custom scripts"
else
log "Adding BeetsTagger.bash to Lidarr custom scripts"

View file

@ -325,7 +325,7 @@ VideoTagProcess () {
if [[ $filenoext.$videoContainer == *.mkv ]]; then
mv "$filenoext.$videoContainer" "$filenoext-temp.$videoContainer"
log "${processCount}/${lidarrArtistIdsCount} :: $lidarrArtistName :: IMVDB :: ${imvdbProcessCount}/${imvdbArtistVideoCount} :: ${1}${2} $3 :: Tagging file"
ffmpeg -y \
ffmpeg -y -nostdin \
-i "$filenoext-temp.$videoContainer" \
-c copy \
-metadata TITLE="${1}" \
@ -343,7 +343,7 @@ VideoTagProcess () {
else
mv "$filenoext.$videoContainer" "$filenoext-temp.$videoContainer"
log "${processCount}/${lidarrArtistIdsCount} :: $lidarrArtistName :: IMVDB :: ${imvdbProcessCount}/${imvdbArtistVideoCount} :: ${1}${2} $3 :: Tagging file"
ffmpeg -y \
ffmpeg -y -nostdin \
-i "$filenoext-temp.$videoContainer" \
-i "$videoDownloadPath/incomplete/${1}${2}.jpg" \
-map 1 \

View file

@ -1,3 +0,0 @@
#!/usr/bin/with-contenv bash
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/lidarr/setup.bash | bash
exit

View file

@ -1,69 +0,0 @@
#!/usr/bin/with-contenv bash
scriptVersion="1.2"
scriptName="RA-ROM-Downloader"
#### Import Settings
source /config/extended.conf
downloadPath="$romPath/RA_collection"
#### Funcitons
logfileSetup () {
# auto-clean up log file to reduce space usage
if [ -f "/config/$scriptName.log" ]; then
if find /config -type f -name "$scriptName.log" -size +1024k | read; then
echo "" > /config/$scriptName.log
fi
fi
if [ ! -f "/config/$scriptName.log" ]; then
echo "" > /config/$scriptName.log
chmod 666 "/config/$scriptName.log"
fi
}
DownloadRomCountSummary () {
OIFS="$IFS"
IFS=$'\n'
romCount=$(find "$downloadPath" -type f -iname "*.zip" | wc -l)
platformCount=$(find "$downloadPath" -maxdepth 1 -mindepth 1 -type d | wc -l)
echo "################## ROM SUMMARY ##################" 2>&1 | tee -a /config/$scriptName.log
echo "$romCount ROMS downloaded on $platformCount different platforms!!!" 2>&1 | tee -a /config/$scriptName.log
echo "############### DETAILED SUMMARY ################" 2>&1 | tee -a /config/$scriptName.log
echo "Platforms ($platformCount):;Total:" > /config/temp
for romfolder in $(find "$downloadPath" -maxdepth 1 -mindepth 1 -type d); do
platform="$(basename "$romfolder")"
platformRomCount=$(find "$romfolder" -type f -iname "*.zip" | wc -l)
echo "$platform;$platformRomCount" >> /config/temp
done
echo "Totals:;$romCount;" >> /config/temp
data=$(cat /config/temp | column -s";" -t)
rm /config/temp
echo "$data" 2>&1 | tee -a /config/$scriptName.log
IFS="$OIFS"
}
DownloadRoms () {
echo "############### UPDATING ROMS #################" 2>&1 | tee -a /config/$scriptName.log
rclone sync -P --http-url https://archive.org ":http:/27/items/retroachievements_collection_v5" "$downloadPath" --filter="- SNES/**" --filter="- NES/**" --filter="- PlayStation Portable/**" --filter="- PlayStation/**" --filter="- PlayStation 2/**" --filter "- retroachievements_collection*" --filter "- TamperMonkeyRetroachievements*" --filter "- __ia_thumb.jpg" --filter "- rclone.txt" --local-case-sensitive --delete-before --transfers $downloadTransfers --checkers $downloadCheckers --tpslimit $downloadTpslimit --log-file="/config/rclong.log"
rclone sync -P --http-url https://archive.org ":http:/29/items/retroachievements_collection_NES/NES" "$downloadPath/NES" --local-case-sensitive --delete-before --transfers $downloadTransfers --checkers $downloadCheckers --tpslimit $downloadTpslimit --log-file="/config/rclong.log"
rclone sync -P --http-url https://archive.org ":http:/25/items/retroachievements_collection_SNES/SNES" "$downloadPath/SNES" --local-case-sensitive --delete-before --transfers $downloadTransfers --checkers $downloadCheckers --tpslimit $downloadTpslimit --filter="- *(MSU)*" --log-file="/config/rclong.log"
rclone sync -P --http-url https://archive.org ":http:/23/items/retroachievements_collection_PlayStation_Portable/PlayStation Portable" "$downloadPath/PlayStation Portable" --local-case-sensitive --delete-before --transfers $downloadTransfers --checkers $downloadCheckers --tpslimit $downloadTpslimit --log-file="/config/rclong.log"
rclone sync -P --http-url https://archive.org ":http:/31/items/retroachievements_collection_PlayStation/PlayStation" "$downloadPath/PlayStation" --local-case-sensitive --delete-before --transfers $downloadTransfers --checkers $downloadCheckers --tpslimit $downloadTpslimit --log-file="/config/rclong.log"
rclone sync -P --http-url https://archive.org ":http:/16/items/retroachievements_collection_PS2/PlayStation 2" "$downloadPath/PlayStation 2" --local-case-sensitive --delete-before --transfers $downloadTransfers --checkers $downloadCheckers --tpslimit $downloadTpslimit --log-file="/config/rclong.log"
}
# Loop Script
for (( ; ; )); do
let i++
logfileSetup
echo "############# $scriptName ###############" 2>&1 | tee -a /config/$scriptName.log
echo "Version: $scriptVersion" 2>&1 | tee -a /config/$scriptName.log
echo "Starting..." 2>&1 | tee -a /config/$scriptName.log
DownloadRomCountSummary
DownloadRoms
DownloadRomCountSummary
echo "Script sleeping for $downloadScriptInterval..." 2>&1 | tee -a /config/$scriptName.log
sleep $downloadScriptInterval
done
exit

View file

@ -1,289 +0,0 @@
#!/usr/bin/with-contenv bash
scriptVersion="1.0"
scriptName="EmulatorJS"
#### Import Settings
source /config/extended.conf
downloadPath="$romPath/RA_collection"
#### Funcitons
logfileSetup () {
# auto-clean up log file to reduce space usage
if [ -f "/config/$scriptName.log" ]; then
if find /config -type f -name "$scriptName.log" -size +1024k | read; then
echo "" > /config/$scriptName.log
fi
fi
if [ ! -f "/config/$scriptName.log" ]; then
echo "" > /config/$scriptName.log
chmod 666 "/config/$scriptName.log"
fi
}
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $scriptVersion :: "$1 2>&1 | tee -a /config/$scriptName.log
}
ProcessRoms () {
OIFS="$IFS"
IFS=$'\n'
for folder in $(ls "$1"); do
romFolder="$1/$folder"
romFiles="$(ls "$romFolder" | sort -hr)"
if echo "$romFiles" | grep -i " (U)" | head -n 1 | read; then
log "USA ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (U)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i " (USA)" | head -n 1 | read; then
log "USA ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (USA)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i " (UE)" | head -n 1 | read; then
log "USA ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (UE)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i " (E)" | head -n 1 | read; then
log "EUROPE ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (E)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i " (Europe)" | head -n 1 | read; then
log "EUROPE ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (Europe)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i " (W)" | head -n 1 | read; then
log "WORLD ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (W)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i " (World)" | head -n 1 | read; then
log "WORLD ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (World)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i " (J)" | head -n 1 | read; then
log "JAPAN ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (J)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i " (Japan)" | head -n 1 | read; then
log "JAPAN ROM FOUND"
romFile="$(echo "$romFiles" | grep -i " (Japan)" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
elif echo "$romFiles" | grep -i ".zip" | head -n 1 | read; then
log "OTHER ROM FOUND"
romFile="$(echo "$romFiles" | grep -i ".zip" | head -n 1)"
CreateHardLink "$romFolder/$romFile"
fi
done
IFS="$OIFS"
}
CreateHardLink () {
log "$emulatorJsPlatformFolder"
romFileName="$(basename "$1")"
log "$romFileName"
if [ ! -d "$emulatorjsPath/$emulatorJsPlatformFolder" ]; then
mkdir -p "$emulatorjsPath/$emulatorJsPlatformFolder"
chmod 777 "$emulatorjsPath/$emulatorJsPlatformFolder"
fi
if [ ! -f "$emulatorjsPath/$emulatorJsPlatformFolder/roms/$romFileName" ]; then
log "Create link"
ln "$1" "$emulatorjsPath/$emulatorJsPlatformFolder/roms/$romFileName"
chmod 666
else
log "Link Exists, skipping..."
fi
}
########################################################## SCRIPT START "##########################################################
logfileSetup
if [ ! -d "$emulatorjsPath" ]; then
log "ERROR :: Emulatorjs path does not exist..."
exit
fi
log "##########################################################"
log "Processing NES ROMS"
raFolder="$downloadPath/NES"
emulatorJsPlatformFolder="nes"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Game Boy ROMS"
raFolder="$downloadPath/Game Boy"
emulatorJsPlatformFolder="gb"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Game Boy Color ROMS"
raFolder="$downloadPath/Game Boy Color"
emulatorJsPlatformFolder="gbc"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
log "Processing Game Boy Advance ROMS"
raFolder="$downloadPath/Game Boy Advance"
emulatorJsPlatformFolder="gba"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Game Gear ROMS"
raFolder="$downloadPath/Game Gear"
emulatorJsPlatformFolder="segaGG"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing SNES ROMS"
raFolder="$downloadPath/SNES"
emulatorJsPlatformFolder="snes"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Virtual Boy ROMS"
raFolder="$downloadPath/Virtual Boy"
emulatorJsPlatformFolder="vb"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Vectrex ROMS"
raFolder="$downloadPath/Vectrex"
emulatorJsPlatformFolder="vectrex"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Mega Drive ROMS"
raFolder="$downloadPath/Mega Drive"
emulatorJsPlatformFolder="segaMD"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Master System ROMS"
raFolder="$downloadPath/Master System"
emulatorJsPlatformFolder="segaMS"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Nintendo 64 ROMS"
raFolder="$downloadPath/Nintendo 64"
emulatorJsPlatformFolder="n64"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Atari 2600 ROMS"
raFolder="$downloadPath/Atari 2600"
emulatorJsPlatformFolder="atari2600"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Atari 7800 ROMS"
raFolder="$downloadPath/Atari 7800"
emulatorJsPlatformFolder="atari7800"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Atari Lynx ROMS"
raFolder="$downloadPath/Atari Lynx"
emulatorJsPlatformFolder="lynx"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing ColecoVision ROMS"
raFolder="$downloadPath/ColecoVision"
emulatorJsPlatformFolder="colecovision"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Magnavox Odyssey 2 ROMS"
raFolder="$downloadPath/Magnavox Odyssey 2"
emulatorJsPlatformFolder="odyssey2"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Atari Jaguar ROMS"
raFolder="$downloadPath/Atari Jaguar"
emulatorJsPlatformFolder="jaguar"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Neo Geo Pocket ROMS"
raFolder="$downloadPath/Neo Geo Pocket"
emulatorJsPlatformFolder="ngp"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing WonderSwan ROMS"
raFolder="$downloadPath/WonderSwan"
emulatorJsPlatformFolder="ws"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
log "Processing Sega 32X ROMS"
raFolder="$downloadPath/32X"
emulatorJsPlatformFolder="sega32x"
if [ -d "$raFolder" ]; then
ProcessRoms "$raFolder" "$emulatorJsPlatformFolder"
fi
log "##########################################################"
sleep 2
exit

View file

@ -1,17 +0,0 @@
##### RA-ROM-DOWNLOADER SCRIPT SETTINGS #####
##### PLATFORM ENABLEMENT
platforms="psp" # Not currently used....
# Available Platforms: snes,megadrive,n64,megaduck,pokemini,virtualboy,nes,arduboy,sega32x,mastersystem,sg1000,atarilynx,jaguar,gb,gbc,gba,gamegear,atari7800,atari2600,nds,colecovision,intellivision,ngp,ndsi,wasm4,channelf,arcadia,o2em,apple2,wswan,supervision,vectrex,amstradcpc,psp
##### PATHS
romPath="/roms"
emulatorjsPath="/roms/emulatorjs"
##### DOWNLOAD SETTINGS
downloadCheckers=20
downloadTransfers=15
downloadTpslimit=10
##### SCRIPT INTERVALS
downloadScriptInterval="12h"

View file

@ -1,3 +0,0 @@
#!/usr/bin/with-contenv bash
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/ra-rom-downloader/setup.bash | bash
exit

View file

@ -1,61 +0,0 @@
#!/usr/bin/with-contenv bash
RAHASHER_PATH="/usr/local/RALibretro"
SKYSCRAPER_PATH="/usr/local/skysource"
echo "************ install dependencies ************"
echo "************ install and upgrade packages ************"
apt-get update
apt-get upgrade -y
apt-get install -y \
jq \
unzip \
gzip \
git \
p7zip-full \
curl \
unrar \
axel \
zip \
wget \
python3-pip \
rclone \
bsdmainutils
echo "************ skyscraper ************"
echo "************ install dependencies ************"
echo "************ install packages ************"
apt-get update
apt-get install -y \
build-essential \
wget \
qt5-default
apt-get purge --auto-remove -y
apt-get clean
echo "************ install skyscraper ************"
mkdir -p ${SKYSCRAPER_PATH}
cd ${SKYSCRAPER_PATH}
wget https://raw.githubusercontent.com/Gemba/skyscraper/master/update_skyscraper.sh
sed -i 's/sudo //g' update_skyscraper.sh
bash update_skyscraper.sh
echo "************ RAHasher installation ************"
mkdir -p ${RAHASHER_PATH}
wget "https://github.com/RetroAchievements/RALibretro/releases/download/1.4.0/RAHasher-x64-Linux-1.6.0.zip" -O "${RAHASHER_PATH}/rahasher.zip"
unzip "${RAHASHER_PATH}/rahasher.zip" -d ${RAHASHER_PATH}
chmod -R 777 ${RAHASHER_PATH}
mkdir -p /custom-services.d
echo "Download Downloader service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/ra-rom-downloader/Downloader.bash -o /custom-services.d/Downloader
echo "Done"
chmod 777 /custom-services.d/Downloader
if [ ! -f /config/extended.conf ]; then
echo "Download Extended config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/ra-rom-downloader/extended.conf -o /config/extended.conf
chmod 777 /config/extended.conf
echo "Done"
fi
if [ -f /custom-services.d/scripts_init.bash ]; then
# user misconfiguration detected, sleeping...
sleep infinity
fi
exit

View file

@ -1,755 +0,0 @@
#!/usr/bin/env bash
# This script is for dev purposes
scriptVersion="1.1"
scriptName="RA-ROM-Downloader"
#### Import Settings
source /config/extended.conf
#### Funcitons
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $scriptVersion :: "$1 2>&1 | tee -a /config/$scriptName.log
}
logfileSetup () {
# auto-clean up log file to reduce space usage
if [ -f "/config/$scriptName.log" ]; then
if find /config -type f -name "$scriptName.log" -size +1024k | read; then
echo "" > /config/$scriptName.log
fi
fi
if [ ! -f "/config/$scriptName.log" ]; then
echo "" > /config/$scriptName.log
chmod 666 "/config/$scriptName.log"
fi
}
UrlDecode () { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
CreatePlatformRomList () {
if [ -f /config/romlist ]; then
rm /config/romlist
fi
archiveUrl="$(wget -qO- "$1" | grep -io '<a href=['"'"'"][^"'"'"']*['"'"'"]' | sed -e 's/^<a href=["'"'"']//i' -e 's/["'"'"']$//i' | sed 's/\///g' | sort -u | sed "s|^|$1|")"
echo "$archiveUrl" | grep -v "\.\." | sort >> /config/romlist
sed -i '/#maincontent/d' /config/romlist
sed -i '/blog.archive.org/d' /config/romlist
}
DownloadFile () {
# $1 = URL
# $2 = Output Folder/file
# $3 = Number of concurrent connections to use
axel -n $3 --output="$2" "$1" | awk -W interactive '$0~/\[/{printf "%s'$'\r''", $0}'
#wget -q --show-progress --progress=bar:force 2>&1 "$1" -O "$2"
if [ ! -f "$2" ]; then
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: Download Failed ($1)"
fi
}
DownloadFileVerification () {
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: Verifing Download..."
case "$1" in
*.zip|*.ZIP)
verify="$(unzip -t "$1" &>/dev/null; echo $?)"
;;
*.rar|*.RAR)
verify="$(unrar t "$1" &>/dev/null; echo $?)"
;;
*.7z|*.7Z)
verify="$(7z t "$1" &>/dev/null; echo $?)"
;;
*.chd|*.CHD)
verify="$(chdman verify -i "$1" &>/dev/null; echo $?)"
;;
*.iso|*.ISO|*.hex|*.HEX|*.wasm|*.WASM|*.sv|*.SV)
echo "No methdod to verify this type of file (iso,hex,wasm,sv)"
verify="0"
;;
esac
if [ "$verify" != "0" ]; then
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: ERROR :: Failed Verification!"
rm "$1"
else
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: Download Verified!"
fi
}
PlatformSelection () {
if [ "$platform" == "snes" ]; then
PlatformSnes
elif [ "$platform" == "apple2" ]; then
PlatformApple2
elif [ "$platform" == "megadrive" ]; then
PlatformMegadrive
elif [ "$platform" == "n64" ]; then
PlatformN64
elif [ "$platform" == "megaduck" ]; then
PlatformMegaduck
elif [ "$platform" == "pokemini" ]; then
PlatformPokemini
elif [ "$platform" == "virtualboy" ]; then
PlatformVirtualboy
elif [ "$platform" == "nes" ]; then
PlatformNes
elif [ "$platform" == "arduboy" ]; then
PlatformArduboy
elif [ "$platform" == "sega32x" ]; then
PlatformSega32x
elif [ "$platform" == "mastersystem" ]; then
PlatformMastersystem
elif [ "$platform" == "sg1000" ]; then
PlatformSg1000
elif [ "$platform" == "atarilynx" ]; then
PlatformAtarilynx
elif [ "$platform" == "jaguar" ]; then
PlatformJaguar
elif [ "$platform" == "gb" ]; then
PlatformGameBoy
elif [ "$platform" == "gbc" ]; then
PlatformGameBoyColor
elif [ "$platform" == "gba" ]; then
PlatformGameBoyAdvance
elif [ "$platform" == "gamegear" ]; then
PlatformGameGear
elif [ "$platform" == "atari2600" ]; then
PlatformAtari2600
elif [ "$platform" == "atari7800" ]; then
PlatformAtari7800
elif [ "$platform" == "nds" ]; then
PlatformNintendoDS
elif [ "$platform" == "colecovision" ]; then
PlatformColecoVision
elif [ "$platform" == "intellivision" ]; then
PlatformIntellivision
elif [ "$platform" == "ngp" ]; then
PlatformNeoGeoPocket
elif [ "$platform" == "ndsi" ]; then
PlatformNintendoDSi
elif [ "$platform" == "wasm4" ]; then
PlatformNintendoWASM-4
elif [ "$platform" == "channelf" ]; then
PlatformNintendoChannelF
elif [ "$platform" == "o2em" ]; then
PlatformO2em
elif [ "$platform" == "arcadia" ]; then
PlatformArcadia
elif [ "$platform" == "supervision" ]; then
PlatformSupervision
elif [ "$platform" == "wswan" ]; then
PlatformWonderSwan
elif [ "$platform" == "vectrex" ]; then
PlatformVectrex
elif [ "$platform" == "amstradcpc" ]; then
PlatformAmstradCPC
elif [ "$platform" == "psp" ]; then
PlatformPsp
else
log "ERROR :: No Platforms Selected, exiting..."
exit
fi
}
UncompressFile () {
# $1 is input file
# $2 is output folder
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: Uncompressing \"$1\" to \"$2\""
case "$1" in
*.zip|*.ZIP)
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: Zip file detected!"
unzip -o -d "$2" "$1" >/dev/null
;;
*.rar|*.RAR)
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: Rar file detected!"
unrar x "$1" "$2" &>/dev/null
;;
*.7z|*.7Z)
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: 7z file detected!"
7z e "$1" -o"$2" &>/dev/null
;;
esac
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: Uncompressing Complete!"
rm "$1"
}
DownloadRomCountSummary () {
log "Summarizing ROM counts..."
romCount=$(find "$romPath" -type f | wc -l)
platformCount=$(find "/$romPath" -maxdepth 1 -mindepth 1 -type d | wc -l)
log "$romCount ROMS downloaded on $platformCount different platforms!!!"
log "Platform breakdown...."
echo "Platforms ($platformCount):;Total:;Released:;Hack/Homebrew/Proto/Unlicensed:" > /config/temp
for romfolder in $(find "/$romPath" -maxdepth 1 -mindepth 1 -type d); do
platform="$(basename "$romfolder")"
PlatformSelection
platformRomCount=$(find "$romPath/$platformFolder" -type f | wc -l)
platformRomSubCount=$(find "$romPath/$platformFolder" -mindepth 2 -type f | wc -l)
platformMainRomCount=$(( $platformRomCount - $platformRomSubCount ))
echo "$platformName;$platformRomCount;$platformMainRomCount;$platformRomSubCount" >> /config/temp
done
platformRomSubCount=$(find "$romPath" -mindepth 3 -type f | wc -l)
platformMainRomCount=$(( $romCount - $platformRomSubCount ))
echo "Totals:;$romCount;$platformMainRomCount;$platformRomSubCount" >> /config/temp
data=$(cat /config/temp | column -s";" -t)
rm /config/temp
echo "$data"
}
#### Platforms
PlatformPsp () {
platformName="PlayStation Portable"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_PlayStation_Portable/PlayStation%20Portable/"
platformFolder="psp"
consoleRomFileExt=".iso, .cso, .pbp"
raConsoleId="41"
uncompressRom="true"
compressRom="false"
}
PlatformAmstradCPC () {
platformName="Amstrad CPC"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Amstrad%20CPC/"
platformFolder="amstradcpc"
consoleRomFileExt=".dsk, .sna, .tap, .cdt, .voc, .m3u, .zip, .7z"
raConsoleId="37"
uncompressRom="false"
compressRom="false"
}
PlatformVectrex () {
platformName="Vectrex"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Vectrex/"
platformFolder="vectrex"
consoleRomFileExt=".bin, .gam, .vec, .zip, .7z"
raConsoleId="46"
uncompressRom="false"
compressRom="false"
}
PlatformSupervision () {
platformName="Watara Supervision"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Watara%20Supervision/"
platformFolder="supervision"
consoleRomFileExt=".sv, .zip, .7z"
raConsoleId="63"
uncompressRom="false"
compressRom="false"
}
PlatformWonderSwan () {
platformName="WonderSwan"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/WonderSwan/"
platformFolder="wswan"
consoleRomFileExt=".ws, .zip, .7z"
raConsoleId="53"
uncompressRom="false"
compressRom="false"
}
PlatformApple2 () {
platformName="Apple II"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Apple%20II/"
platformFolder="apple2"
consoleRomFileExt=".nib, .do, .po, .dsk, .mfi, .dfi, .rti, .edd, .woz, .wav, .zip, .7z"
raConsoleId="38"
uncompressRom="false"
compressRom="false"
}
PlatformArcadia () {
platformName="Arcadia 2001"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Arcadia%202001/"
platformFolder="arcadia"
consoleRomFileExt=".bin, .zip, .7z"
raConsoleId="73"
uncompressRom="false"
compressRom="false"
}
PlatformO2em () {
platformName="Magnavox Odyssey 2"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Magnavox%20Odyssey%202/"
platformFolder="o2em"
consoleRomFileExt=".bin, .zip, .7z"
raConsoleId="23"
uncompressRom="false"
compressRom="false"
}
PlatformSnes () {
platformName="Super Nintentdo"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_SNES/SNES/"
platformFolder="snes"
consoleRomFileExt=".smc, .fig, .sfc, .gd3, .gd7, .dx2, .bsx, .swc, .zip, .7z"
raConsoleId="3"
uncompressRom="false"
compressRom="false"
}
PlatformMegadrive () {
platformName="Mega Drive"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Mega%20Drive/"
platformFolder="megadrive"
consoleRomFileExt=".bin, .gen, .md, .sg, .smd, .zip, .7z"
raConsoleId="1"
uncompressRom="false"
compressRom="false"
}
PlatformN64 () {
platformName="Nintendo 64"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Nintendo%2064/"
platformFolder="n64"
consoleRomFileExt=".z64, .n64, .v64, .zip, .7z"
raConsoleId="2"
uncompressRom="false"
compressRom="false"
}
PlatformMegaduck () {
platformName="Mega Duck"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Mega%20Duck/"
platformFolder="megaduck"
consoleRomFileExt=".bin, .zip, .7z"
raConsoleId="69"
uncompressRom="false"
compressRom="false"
}
PlatformPokemini () {
platformName="Pokemon Mini"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Pokemon%20Mini/"
platformFolder="pokemini"
consoleRomFileExt=".min, .zip, .7z"
raConsoleId="24"
uncompressRom="false"
compressRom="false"
}
PlatformVirtualboy () {
platformName="Virtual Boy"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Virtual%20Boy/"
platformFolder="virtualboy"
consoleRomFileExt=".vb, .zip, .7z"
raConsoleId="28"
uncompressRom="false"
compressRom="false"
}
PlatformNes () {
platformName="Nintendo Entertainment System"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_NES/NES/"
platformFolder="nes"
consoleRomFileExt=".nes, .unif, .unf, .zip, .7z"
raConsoleId="7"
uncompressRom="false"
compressRom="false"
}
Platform3do () {
platformName="3DO Interactive Multiplayer"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/3DO%20Interactive%20Multiplayer/"
platformFolder="3do"
consoleRomFileExt=".iso, .chd, .cue"
raConsoleId="43"
uncompressRom="false"
compressRom="false"
}
PlatformArduboy () {
platformName="Arduboy"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Arduboy/"
platformFolder="arduboy"
consoleRomFileExt=".hex, .zip, .7z"
raConsoleId="71"
uncompressRom="false"
compressRom="false"
}
PlatformSega32x () {
platformName="Sega 32X"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/32X/"
platformFolder="sega32x"
consoleRomFileExt=".32x, .smd, .bin, .md, .zip, .7z"
raConsoleId="10"
uncompressRom="false"
compressRom="false"
}
PlatformMastersystem () {
platformName="Sega Master System"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Master%20System/"
platformFolder="mastersystem"
consoleRomFileExt=".bin, .sms, .zip, .7z"
raConsoleId="11"
uncompressRom="false"
compressRom="false"
}
PlatformSg1000 () {
platformName="SG-1000"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/SG-1000/"
platformFolder="sg1000"
consoleRomFileExt=".bin, .sg, .zip, .7z"
raConsoleId="33"
uncompressRom="false"
compressRom="false"
}
PlatformAtarilynx () {
platformName="Atari Lynx"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Atari%20Lynx/"
platformFolder="atarilynx"
consoleRomFileExt=".lnx, .zip, .7z"
raConsoleId="13"
uncompressRom="false"
compressRom="false"
}
PlatformJaguar () {
platformName="Atari Jaguar"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Atari%20Jaguar/"
platformFolder="jaguar"
consoleRomFileExt=".cue, .j64, .jag, .cof, .abs, .cdi, .rom, .zip, .7z"
raConsoleId="17"
uncompressRom="false"
compressRom="false"
}
PlatformGameBoy () {
platformName="Game Boy"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Game%20Boy/"
platformFolder="gb"
consoleRomFileExt=".gb, .zip, .7z"
raConsoleId="4"
uncompressRom="false"
compressRom="false"
}
PlatformGameBoyColor () {
platformName="Game Boy Color"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Game%20Boy%20Color/"
platformFolder="gbc"
consoleRomFileExt=".gbc, .zip, .7z"
raConsoleId="6"
uncompressRom="false"
compressRom="false"
}
PlatformGameBoyAdvance () {
platformName="Game Boy Advance"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Game%20Boy%20Advance/"
platformFolder="gba"
consoleRomFileExt=".gba, .zip, .7z"
raConsoleId="5"
uncompressRom="false"
compressRom="false"
}
PlatformGameGear () {
platformName="Game Gear"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Game%20Gear/"
platformFolder="gamegear"
consoleRomFileExt=".bin, .gg, .zip, .7z"
raConsoleId="15"
uncompressRom="false"
compressRom="false"
}
PlatformAtari2600 () {
platformName="Atari 2600"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Atari%202600/"
platformFolder="atari2600"
consoleRomFileExt=".a26, .bin, .zip, .7z"
raConsoleId="25"
uncompressRom="false"
compressRom="false"
}
PlatformAtari7800 () {
platformName="Atari 7800"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Atari%207800/"
platformFolder="atari7800"
consoleRomFileExt=".a78, .bin, .zip, .7z"
raConsoleId="51"
uncompressRom="false"
compressRom="false"
}
PlatformNintendoDS () {
platformName="Nintendo DS"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Nintendo%20DS/"
downloadExtension="zip"
platformFolder="nds"
consoleRomFileExt=".nds, .bin, .zip, .7z"
raConsoleId="18"
uncompressRom="false"
compressRom="false"
}
PlatformNintendoDSi () {
platformName="Nintendo DSi"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Nintendo%20DSi/"
downloadExtension="zip"
platformFolder="ndsi"
consoleRomFileExt=".nds, .bin, .zip, .7z"
raConsoleId="78"
uncompressRom="false"
compressRom="false"
}
PlatformColecoVision () {
platformName="ColecoVision"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/ColecoVision/"
downloadExtension="zip"
platformFolder="colecovision"
consoleRomFileExt=".bin, .col, .rom, .zip, .7z"
raConsoleId="44"
uncompressRom="false"
compressRom="false"
}
PlatformIntellivision () {
platformName="Intellivision"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Intellivision/"
downloadExtension="zip"
platformFolder="intellivision"
consoleRomFileExt=".int, .bin, .rom, .zip, .7z"
raConsoleId="45"
uncompressRom="false"
compressRom="false"
}
PlatformNeoGeoPocket () {
platformName="Neo Geo Pocket"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Neo%20Geo%20Pocket/"
downloadExtension="zip"
platformFolder="ngp"
consoleRomFileExt=".ngp, .zip, .7z"
raConsoleId="14"
uncompressRom="false"
compressRom="false"
}
PlatformNintendoWASM-4 () {
platformName="WASM-4"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/WASM-4/"
downloadExtension="zip"
platformFolder="wasm4"
consoleRomFileExt=".wasm"
raConsoleId="72"
uncompressRom="false"
compressRom="false"
}
PlatformNintendoChannelF () {
platformName="Fairchild Channel F"
platformArchiveContentsUrl="https://archive.org/download/retroachievements_collection_v5/Fairchild%20Channel%20F/"
downloadExtension="zip"
platformFolder="channelf"
consoleRomFileExt=".zip, .rom, .bin, .chf"
raConsoleId="57"
uncompressRom="false"
compressRom="false"
}
DownloadRomCountSummary
log "######################################"
log "Processing platforms..."
platform=""
platformsToProcessNumber=0
IFS=',' read -r -a filters <<< "$platforms"
for platform in "${filters[@]}"
do
platformToProcessNumber=$(( $platformToProcessNumber + 1 ))
done
platform=""
processNumber=0
IFS=',' read -r -a filters <<< "$platforms"
for platform in "${filters[@]}"
do
processNumber=$(( $processNumber + 1 ))
PlatformSelection
log "$processNumber/$platformToProcessNumber :: $platformName :: Starting..."
log "$processNumber/$platformToProcessNumber :: $platformName :: Finding ROMS..."
CreatePlatformRomList "$platformArchiveContentsUrl"
outputdir="$romPath/$platformFolder"
romlist=$(cat /config/romlist)
romListCount=$(echo "$romlist" | wc -l)
log "$processNumber/$platformToProcessNumber :: $platformName :: $romListCount ROMS Found!"
romProcessNumber=0
echo "$romlist" | while read -r rom; do
romProcessNumber=$(( $romProcessNumber + 1 ))
archiveContentsUrl="$rom/"
#echo "$rom"
archiveUrl="$(wget -qO- "$archiveContentsUrl" | grep -i ".zip" | grep -io '<a href=['"'"'"][^"'"'"']*['"'"'"]' | sed -e 's/^<a href=["'"'"']//i' -e 's/["'"'"']$//i' | sed 's/\///g' | sort -u | sed "s|^|$archiveContentsUrl|")"
echo "$archiveUrl" > /config/romfilelist
romfiles="$(cat /config/romfilelist | awk '{ print length, $0 }' | sort -n | cut -d" " -f2-)"
#echo $romfiles
# debugging
#echo "original list: "
#cat romfilelist
#echo ""
#echo "rom file list sorted by length: "
#echo "$romfiles"
#filteredUsaRoms="$(echo "$romfiles" | grep "%20%28U%29" | head -n 1)"
#echo ""
#echo "filtered:"
#echo "$filteredUsaRoms"
#if [ -f romfilelist ]; then
# rm romfilelist
#fi
#continue\
filteredUsaRoms="$(echo "$romfiles" | grep -i "%20%28U%29" | head -n 1)"
filteredUsaRomscount="$(echo "$romfiles" | grep -i "%20%28U%29" | head -n 1 | wc -l)"
filteredUsa2Roms="$(echo "$romfiles" | grep -i "%20%28USA%29" | head -n 1)"
filteredUsa2Romscount="$(echo "$romfiles" | grep -i "%20%28USA%29" | head -n 1 | wc -l)"
filteredUsa3Roms="$(echo "$romfiles" | grep -i "%20%28UE%29" | head -n 1)"
filteredUsa3Romscount="$(echo "$romfiles" | grep -i "%20%28UE%29" | head -n 1 | wc -l)"
filteredEuropeRoms="$(echo "$romfiles" | grep -i "%20%28E%29" | head -n 1)"
filteredEuropeRomscount="$(echo "$romfiles" | grep -i "%20%28E%29" | head -n 1 | wc -l)"
filteredEurope2Roms="$(echo "$romfiles" | grep -i "%20%28Europe%29" | head -n 1)"
filteredEurope2Romscount="$(echo "$romfiles" | grep -i "%20%28Europe%29" | head -n 1 | wc -l)"
filteredWorldRoms="$(echo "$romfiles" | grep -i "%20%28W%29" | head -n 1)"
filteredWorldRomscount="$(echo "$romfiles" | grep -i "%20%28W%29" | head -n 1 | wc -l)"
filteredWorld2Roms="$(echo "$romfiles" | grep -i "%20%28World%29" | head -n 1)"
filteredWorld2Romscount="$(echo "$romfiles" | grep -i "%20%28World%29" | head -n 1 | wc -l)"
filteredJapanRoms="$(echo "$romfiles" | grep -i "%20%28J%29" | head -n 1)"
filteredJapanRomscount="$(echo "$romfiles" | grep -i "%20%28J%29" | head -n 1 | wc -l)"
filteredJapan2Roms="$(echo "$romfiles" | grep -i "%20%28Japan%29" | head -n 1)"
filteredJapan2Romscount="$(echo "$romfiles" | grep -i "%20%28Japan%29" | head -n 1 | wc -l)"
filteredOtherRoms="$(echo "$romfiles" | head -n 1)"
filteredOtherRomscount="$(echo "$romfiles" | head -n 1 | wc -l)"
filteredOtherRomsDecoded="$(UrlDecode "$filteredOtherRoms")"
subFolder="$(dirname "$filteredOtherRomsDecoded")"
subFolder="$(basename "$subFolder")"
romUrl=""
if echo "$subFolder" | grep "~" | read; then
subFolder="/$(echo "$subFolder" | cut -d "~" -f 2)/"
else
subFolder="/"
fi
if [ ! -d "${outputdir}${subFolder}" ]; then
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: Creating \"${subFolder}\" folder... "
mkdir -p "${outputdir}${subFolder}"
chmod 777 "${outputdir}${subFolder}"
fi
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: Searching Archive URL ROM Folder"
if [ $filteredUsaRomscount -eq 1 ]; then
fileName="$(basename "$filteredUsaRoms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredUsaRoms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: USA (U) ROM FOUND ($fileName)"
elif [ $filteredUsa2Romscount -eq 1 ]; then
fileName="$(basename "$filteredUsa2Roms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredUsa2Roms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: USA (USA) ROM FOUND ($fileName)"
elif [ $filteredUsa3Romscount -eq 1 ]; then
fileName="$(basename "$filteredUsa3Roms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredUsa3Roms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: USA (USA) ROM FOUND ($fileName)"
elif [ $filteredEuropeRomscount -eq 1 ]; then
fileName="$(basename "$filteredEuropeRoms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredEuropeRoms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: EUROPE ROM FOUND ($fileName)"
elif [ $filteredEurope2Romscount -eq 1 ]; then
fileName="$(basename "$filteredEurope2Roms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredEurope2Roms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: EUROPE ROM FOUND ($fileName)"
elif [ $filteredWorldRomscount -eq 1 ]; then
fileName="$(basename "$filteredWorldRoms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredWorldRoms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: WORLD ROM FOUND ($fileName)"
elif [ $filteredWorld2Romscount -eq 1 ]; then
fileName="$(basename "$filteredWorld2Roms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredWorld2Roms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: WORLD ROM FOUND ($fileName)"
elif [ $filteredJapanRomscount -eq 1 ]; then
fileName="$(basename "$filteredJapanRoms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredJapanRoms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: JAPAN ROM FOUND ($fileName)"
elif [ $filteredJapan2Romscount -eq 1 ]; then
fileName="$(basename "$filteredJapan2Roms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredJapan2Roms"
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: JAPAN ROM FOUND ($fileName)"
elif [ $filteredOtherRomscount -eq 1 ]; then
fileName="$(basename "$filteredOtherRoms")"
fileName="$(UrlDecode "$fileName")"
romUrl="$filteredOtherRoms"
if [ ! -z "$fileName" ]; then
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: OTHER ROM FOUND ($fileName)"
fi
fi
if [ -z "$fileName" ]; then
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ERROR :: No Filtered Roms Found ($archiveContentsUrl)..."
continue
fi
fileNameNoExt="${fileName%.*}"
# verify download
if [ -f "${outputdir}${subFolder}${fileName}" ]; then
DownloadFileVerification "${outputdir}${subFolder}${fileName}"
fi
# download file
if ! find "${outputdir}${subFolder}" -type f -iname "$fileNameNoExt.*" | grep -v ".st$" | read; then
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: ROM downloading to \"${outputdir}${subFolder}\"..."
#wget "$romUrl" -O "${outputdir}${subFolder}${fileName}"
DownloadFile "$romUrl" "${outputdir}${subFolder}${fileName}" "$concurrentConnectionCount"
# verify download
if [ -f "${outputdir}${subFolder}${fileName}" ]; then
DownloadFileVerification "${outputdir}${subFolder}${fileName}"
fi
else
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: ROM previously downloaded..."
fi
if [ -f "${outputdir}${subFolder}${fileName}" ]; then
if [ "$uncompressRom" == "true" ]; then
UncompressFile "${outputdir}${subFolder}${fileName}" "${outputdir}${subFolder}"
fi
fi
# set permisions
if [ -f "${outputdir}${subFolder}${fileName}" ]; then
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${fileName} :: Setting Permissions to 666"
chmod 666 "${outputdir}${subFolder}${fileName}"
else
log "$processNumber/$platformToProcessNumber :: $platformName :: $romProcessNumber/$romListCount :: ${outputdir}${subFolder} :: Setting Permissions to 666"
chmod 666 "${outputdir}${subFolder}"/*
fi
if [ -f /config/romfilelist ]; then
rm /config/romfilelist
fi
done
downloadedRomCount=$(find "$outputdir" -type f | wc -l)
log "$processNumber/$platformToProcessNumber :: $platformName :: $downloadedRomCount ROMS Successfully Downloaded!!"
done
DownloadRomCountSummary
exit

File diff suppressed because one or more lines are too long

View file

@ -1,51 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.5"
scriptName="AutoExtras"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
verifyConfig () {
if [ "$enableExtras" != "true" ]; then
log "Script is not enabled, enable by setting enableExtras to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
if [ -z "$autoExtrasScriptInterval" ]; then
autoExtrasScriptInterval="24h"
fi
}
AutoExtrasProcess () {
radarrMovieList=$(curl -s --header "X-Api-Key:"${arrApiKey} --request GET "$arrUrl/api/v3/movie")
radarrMovieTotal=$(echo "${radarrMovieList}" | jq -r '.[] | select(.hasFile==true) | .id' | wc -l)
radarrMovieIds=$(echo "${radarrMovieList}" | jq -r '.[] | select(.hasFile==true) | .id')
loopCount=0
for id in $(echo $radarrMovieIds); do
loopCount=$(( $loopCount + 1 ))
log "$loopCount of $radarrMovieTotal :: $id :: Processing with Extras.bash"
bash /config/extended/Extras.bash "$id"
done
}
for (( ; ; )); do
let i++
logfileSetup
verifyConfig
getArrAppInfo
verifyApiAccess
AutoExtrasProcess
log "Script sleeping for $autoExtrasScriptInterval..."
sleep $autoExtrasScriptInterval
done
exit

View file

@ -1,272 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.4"
arrEventType="$radarr_eventtype"
arrItemId=$radarr_movie_id
tmdbApiKey="3b7751e3179f796565d88fdb2fcdf426"
autoScan="false"
updatePlex="false"
ytdlpExtraOpts="--user-agent facebookexternalhit/1.1"
scriptName="Extras"
#### Import Settings
source /config/extended.conf
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $scriptVersion :: "$1
}
if [ "$enableExtras" != "true" ]; then
log "Script is not enabled, enable by setting enableExtras to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
if [ ! -z "$1" ]; then
arrItemId="$1"
autoScan="true"
else
autoScan="false"
fi
# Debugging
#arrItemId=1
if [ -z "$arrUrl" ] || [ -z "$arrApiKey" ]; then
arrUrlBase="$(cat /config/config.xml | xq | jq -r .Config.UrlBase)"
if [ "$arrUrlBase" == "null" ]; then
arrUrlBase=""
else
arrUrlBase="/$(echo "$arrUrlBase" | sed "s/\///g")"
fi
arrApiKey="$(cat /config/config.xml | xq | jq -r .Config.ApiKey)"
arrPort="$(cat /config/config.xml | xq | jq -r .Config.Port)"
arrUrl="http://127.0.0.1:${arrPort}${arrUrlBase}"
fi
# auto-clean up log file to reduce space usage
if [ -f "/config/logs/Extras.txt" ]; then
find /config/logs -type f -name "Extras.txt" -size +1024k -delete
fi
if [ ! -f "/config/logs/Extras.txt" ]; then
touch "/config/logs/Extras.txt"
chmod 777 "/config/logs/Extras.txt"
fi
exec &> >(tee -a "/config/logs/Extras.txt")
if [ "$arrEventType" == "Test" ]; then
log "Tested Successfully"
exit 0
fi
if [ "$enableExtras" != "true" ]; then
log "Script disabled, exiting..."
log "Enable by setting enableExtras=true"
exit
fi
# Check for cookies file
if [ -f /config/cookies.txt ]; then
cookiesFile="/config/cookies.txt"
log "Cookies File Found!"
else
log "Cookies File Not Found!"
cookiesFile=""
fi
arrItemData=$(curl -s "$arrUrl/api/v3/movie/$arrItemId?apikey=$arrApiKey")
itemTitle=$(echo "$arrItemData" | jq -r .title)
itemHasFile=$(echo "$arrItemData" | jq -r .hasFile)
itemPath="$(echo "$arrItemData" | jq -r ".path")"
itemFileName=$(curl -s "$arrUrl/api/v3/moviefile?movieId=$arrItemId&apikey=$arrApiKey" | jq -r .[].relativePath)
itemFileNameNoExt="${itemFileName%.*}"
itemFolder="$(basename "$itemPath")"
itemRelativePath="$(echo "$arrItemData" | jq -r ".movieFile.relativePath")"
itemTrailerId="$(echo "$arrItemData" | jq -r ".youTubeTrailerId")"
tmdbId="$(echo "$arrItemData" | jq -r ".tmdbId")"
if [ ! -d "$itemPath" ]; then
log "$itemTitle :: ERROR: Item Path does not exist ($itemPath), Skipping..."
exit
fi
if [ "$extrasSingle" == "true" ]; then
extrasType="trailer"
fi
IFS=',' read -r -a filters <<< "$extrasLanguages"
for filter in "${filters[@]}"
do
if [ "$useProxy" != "true" ]; then
tmdbVideosListData=$(curl -s "https://api.themoviedb.org/3/movie/$tmdbId/videos?api_key=$tmdbApiKey&language=$filter" | jq -r '.results[] | select(.site=="YouTube")')
else
tmdbVideosListData=$(curl -x $proxyUrl:$proxyPort --proxy-user $proxyUsername:$proxyPassword -s "https://api.themoviedb.org/3/movie/$tmdbId/videos?api_key=$tmdbApiKey&language=$filter" | jq -r '.results[] | select(.site=="YouTube")')
fi
log "$itemTitle :: Searching for \"$filter\" extras..."
if [ "$extrasType" == "all" ]; then
tmdbVideosListDataIds=$(echo "$tmdbVideosListData" | jq -r ".id")
tmdbVideosListDataIdsCount=$(echo "$tmdbVideosListData" | jq -r ".id" | wc -l)
else
tmdbVideosListDataIds=$(echo "$tmdbVideosListData" | jq -r "select(.type==\"Trailer\") | .id")
tmdbVideosListDataIdsCount=$(echo "$tmdbVideosListData" | jq -r "select(.type==\"Trailer\") | .id" | wc -l)
fi
if [ -z "$tmdbVideosListDataIds" ]; then
log "$itemTitle :: None found..."
continue
fi
if [ $tmdbVideosListDataIdsCount -le 0 ]; then
log "$itemTitle :: No Extras Found, skipping..."
exit
fi
log "$itemTitle :: $tmdbVideosListDataIdsCount Extras Found!"
i=0
for id in $(echo "$tmdbVideosListDataIds"); do
i=$(( i + 1))
tmdbExtraData="$(echo "$tmdbVideosListData" | jq -r "select(.id==\"$id\")")"
tmdbExtraTitle="$(echo "$tmdbExtraData" | jq -r .name)"
tmdbExtraTitleClean="$(echo "$tmdbExtraTitle" | sed -e "s/[^[:alpha:][:digit:]$^&_+=()'%;{},.@#]/ /g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')"
tmdbExtraKey="$(echo "$tmdbExtraData" | jq -r .key)"
tmdbExtraType="$(echo "$tmdbExtraData" | jq -r .type)"
tmdbExtraOfficial="$(echo "$tmdbExtraData" | jq -r .official)"
if [ "$tmdbExtraOfficial" != "true" ]; then
if [ "$extrasOfficialOnly" == "true" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: Not official, skipping..."
continue
fi
fi
if [ "$tmdbExtraType" == "Featurette" ]; then
extraFolderName="featurettes"
elif [ "$tmdbExtraType" == "Trailer" ]; then
extraFolderName="trailers"
elif [ "$tmdbExtraType" == "Behind the Scenes" ]; then
extraFolderName="behind the scenes"
else
extraFolderName="other"
fi
if [ "$extrasSingle" == "true" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: Single Trailer Enabled..."
if [ "$extrasKodiCompatibility" == "true" ] ; then
finalPath="$itemPath"
finalFileName="$itemFileNameNoExt-trailer"
else
finalPath="$itemPath/$extraFolderName"
if [ -f "$finalPath/$tmdbExtraTitleClean.mkv" ]; then
rm "$finalPath/$tmdbExtraTitleClean.mkv"
fi
finalFileName="$itemFolder"
fi
else
finalPath="$itemPath/$extraFolderName"
if [ "$extraFolderName" == "other" ]; then
finalFileName="$tmdbExtraTitleClean ($tmdbExtraType)"
else
finalFileName="$tmdbExtraTitleClean"
fi
fi
if [ -f "$finalPath/$finalFileName.mkv" ]; then
log "$itemTitle :: $i of $tmdbViscriptsdeosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle ($tmdbExtraKey) :: Already Downloaded, skipping..."
if [ "$extrasSingle" == "true" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: Finished processing single trailer download"
break
fi
continue
elif [ -f "$finalPath/movie-trailer.mkv" ]; then
if [ "$extrasKodiCompatibility" == "true" ] ; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: Removing old \"movie-trailer.mkv\" to replace with Kodi naming..."
rm "$finalPath/movie-trailer.mkv"
fi
fi
videoLanguages="$(echo "$extrasLanguages" | sed "s/-[[:alpha:]][[:alpha:]]//g")"
tempFolder="/config/extended/temp"
if [ -d "$tempFolder" ]; then
rm -rf "$tempFolder"
sleep 0.01
fi
if [ ! -d "$tempFolder" ]; then
mkdir -p "$tempFolder"
fi
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle ($tmdbExtraKey) :: Downloading (yt-dlp :: $videoFormat)..."
if [ ! -z "$cookiesFile" ]; then
yt-dlp -f "$videoFormat" --no-video-multistreams --cookies "$cookiesFile" -o "$tempFolder/$finalFileName" --write-sub --sub-lang $videoLanguages --embed-subs --merge-output-format mkv --no-mtime --geo-bypass $ytdlpExtraOpts "https://www.youtube.com/watch?v=$tmdbExtraKey"
else
yt-dlp -f "$videoFormat" --no-video-multistreams -o "$tempFolder/$finalFileName" --write-sub --sub-lang $videoLanguages --embed-subs --merge-output-format mkv --no-mtime --geo-bypass $ytdlpExtraOpts "https://www.youtube.com/watch?v=$tmdbExtraKey"
fi
if [ -f "$tempFolder/$finalFileName.mkv" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle ($tmdbExtraKey) :: Compete"
else
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle ($tmdbExtraKey) :: ERROR :: Download Failed"
continue
fi
if python3 /usr/local/sma/manual.py --config "/config/extended/sma.ini" -i "$tempFolder/$finalFileName.mkv" -nt; then
sleep 0.01
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle :: Processed with SMA..."
rm /usr/local/sma/config/*log*
else
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle :: ERROR :: SMA Processing Error"
rm "$finalPath/$finalFileName.mkv"
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle :: INFO: deleted: $tempFolder/$finalFileName.mkv"
fi
if [ ! -d "$finalPath" ]; then
mkdir -p "$finalPath"
chmod 777 "$finalPath"
fi
if [ -f "$tempFolder/$finalFileName.mkv" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle :: Moving file to final destination"
mv "$tempFolder/$finalFileName.mkv" "$finalPath/$finalFileName.mkv"
chmod 666 "$finalPath/$finalFileName.mkv"
if [ -d "$tempFolder" ]; then
rm -rf "$tempFolder"
fi
fi
updatePlex="true"
if [ "$extrasSingle" == "true" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: Finished processing single trailer download"
break
fi
done
done
# Process item with PlexNotify.bash if plexToken is configured
if [ ! -z "$plexToken" ]; then
# Always update plex if extra is downloaded
if [ "$updatePlex" == "true" ]; then
log "Using PlexNotify.bash to update Plex...."
bash /config/extended/PlexNotify.bash "$itemPath"
exit
fi
# Do not notify plex if this script was triggered by the AutoExtras.bash and no Extras were downloaded
if [ "$autoScan" == "true" ]; then
log "Skipping plex notification, not needed...."
exit
else
log "Using PlexNotify.bash to update Plex...."
bash /config/extended/PlexNotify.bash "$itemPath"
exit
fi
fi
exit

View file

@ -1,81 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.2"
scriptName="InvalidMoviesAutoCleaner"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
#### Check Arr App
getArrAppInfo
verifyApiAccess
verifyConfig () {
if [ "$enableInvalidMoviesAutoCleaner" != "true" ]; then
log "Script is not enabled, enable by setting enableInvalidMoviesAutoCleaner to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
if [ -z "$invalidMoviesAutoCleanerScriptInterval" ]; then
invalidMoviesAutoCleanerScriptInterval="1h"
fi
}
InvalidMovieAutoCleanerProcess () {
# Get invalid series tmdbid id's
movieTmdbid="$(curl -s --header "X-Api-Key:"$arrApiKey --request GET "$arrUrl/api/v3/health" | jq -r '.[] | select(.source=="RemovedMovieCheck") | select(.type=="error")' | grep -o 'tmdbid [0-9]*' | grep -o '[[:digit:]]*')"
if [ -z "$movieTmdbid" ]; then
log "No invalid movies (tmdbid) reported by Radarr health check, skipping..."
return
fi
# Process each invalid series tmdb id
moviesData="$(curl -s --header "X-Api-Key:"$arrApiKey --request GET "$arrUrl/api/v3/movie")"
for tmdbid in $(echo $movieTmdbid); do
movieData="$(echo "$moviesData" | jq -r ".[] | select(.tmdbId==$tmdbid)")"
movieId="$(echo "$movieData" | jq -r .id)"
movieTitle="$(echo "$movieData" | jq -r .title)"
moviePath="$(echo "$movieData" | jq -r .path)"
notifyPlex="false"
if [ -d "$moviePath" ]; then
notifyPlex="true"
else
notifyPlex="false"
fi
log "$movieId :: $movieTitle :: $moviePath :: Removing and deleting invalid movie (tmdbid: $tmdbid) based on Radarr Health Check error..."
# Send command to Sonarr to delete series and files
arrCommand=$(curl -s --header "X-Api-Key:"$arrApiKey --request DELETE "$arrUrl/api/v3/movie/$movieId?deleteFiles=true")
if [ "$notifyPlex" == "true" ]; then
# trigger a plex scan to remove the deleted movie
folderToScan="$(dirname "$moviePath")"
log "Using PlexNotify.bash to update Plex.... ($folderToScan)"
bash /config/extended/PlexNotify.bash "$folderToScan" "true"
fi
done
}
for (( ; ; )); do
let i++
logfileSetup
log "Script starting..."
verifyConfig
getArrAppInfo
verifyApiAccess
InvalidMovieAutoCleanerProcess
log "Script sleeping for $invalidMoviesAutoCleanerScriptInterval..."
sleep $invalidMoviesAutoCleanerScriptInterval
done
exit

View file

@ -1,100 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.1"
scriptName="PlexNotify"
#### Import Settings
source /config/extended.conf
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $scriptVersion :: "$1
}
notfidedBy="Radarr"
arrRootFolderPath="$(dirname "$radarr_movie_path")"
arrFolderPath="$radarr_movie_path"
arrEventType="$radarr_eventtype"
movieExtrasPath="$1"
# auto-clean up log file to reduce space usage
if [ -f "/config/logs/PlexNotify.txt" ]; then
find /config/logs -type f -name "PlexNotify.txt" -size +1024k -delete
fi
if [ ! -f "/config/logs/PlexNotify.txt" ]; then
touch "/config/logs/PlexNotify.txt"
chmod 777 "/config/logs/PlexNotify.txt"
fi
exec &> >(tee -a "/config/logs/PlexNotify.txt")
if [ "$enableExtras" == "true" ]; then
if [ -z "$movieExtrasPath" ]; then
log "MovieExtras script is enabled, skipping..."
exit
fi
if [ ! -z "$movieExtrasPath" ]; then
arrFolderPath="$movieExtrasPath"
arrRootFolderPath="$(dirname "$movieExtrasPath")"
fi
fi
if [ "$arrEventType" == "Test" ]; then
log "$notfidedBy :: Tested Successfully"
exit 0
fi
PlexConnectionError () {
log "ERROR :: Cannot communicate with Plex"
log "ERROR :: Please check your plexUrl and plexToken"
log "ERROR :: Configured plexUrl \"$plexUrl\""
log "ERROR :: Configured plexToken \"$plexToken\""
log "ERROR :: Exiting..."
exit
}
# Validate connection
if curl -s "$plexUrl/?X-Plex-Token=$plexToken" | xq . &>/dev/null; then
plexVersion=$(curl -s "$plexUrl/?X-Plex-Token=$plexToken" | xq . | jq -r '.MediaContainer."@version"')
if [ "$plexVersion" == "null" ]; then
# Error out if version is null, indicates bad token
PlexConnectionError
else
log "Plex Connection Established, version: $plexVersion"
fi
else
# Error out if error in curl | xq . command output
PlexConnectionError
fi
plexLibraries="$(curl -s "$plexUrl/library/sections?X-Plex-Token=$plexToken")"
plexLibraryData=$(echo "$plexLibraries" | xq ".MediaContainer.Directory")
if echo "$plexLibraryData" | grep "^\[" | read; then
plexLibraryData=$(echo "$plexLibraries" | xq ".MediaContainer.Directory[]")
plexKeys=($(echo "$plexLibraries" | xq ".MediaContainer.Directory[]" | jq -r '."@key"'))
else
plexKeys=($(echo "$plexLibraries" | xq ".MediaContainer.Directory" | jq -r '."@key"'))
fi
if echo "$plexLibraryData" | grep "\"@path\": \"$arrRootFolderPath" | read; then
sleep 0.01
else
log "$notfidedBy :: ERROR: No Plex Library found containing path \"$arrRootFolderPath\""
log "$notfidedBy :: ERROR: Add \"$arrRootFolderPath\" as a folder to a Plex Movie Library"
exit 1
fi
for key in ${!plexKeys[@]}; do
plexKey="${plexKeys[$key]}"
plexKeyData="$(echo "$plexLibraryData" | jq -r "select(.\"@key\"==\"$plexKey\")")"
if echo "$plexKeyData" | grep "\"@path\": \"$arrRootFolderPath" | read; then
plexFolderEncoded="$(jq -R -r @uri <<<"$arrFolderPath")"
curl -s "$plexUrl/library/sections/$plexKey/refresh?path=$plexFolderEncoded&X-Plex-Token=$plexToken"
log "$notfidedBy :: Plex Scan notification sent! ($arrFolderPath)"
fi
done
exit

View file

@ -1,57 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.4"
scriptName="UnmappedFolderCleaner"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
verifyConfig () {
if [ "$enableUnmappedFolderCleaner" != "true" ]; then
log "Script is not enabled, enable by setting enableUnmappedFolderCleaner to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
if [ -z "$unmappedFolderCleanerScriptInterval" ]; then
unmappedFolderCleanerScriptInterval="1h"
fi
}
UnmappedFolderCleanerProcess () {
log "Finding UnmappedFolders to purge..."
OLDIFS="$IFS"
IFS=$'\n'
unmappedFolders=$(curl -s "$arrUrl/api/v3/rootFolder" -H "X-Api-Key: $arrApiKey" | jq -r ".[].unmappedFolders[].path")
unmappedFoldersCount=$(echo -n "$unmappedFolders" | wc -l)
log "$unmappedFoldersCount Folders Found!"
if [ $unmappedFoldersCount = 0 ]; then
log "No cleanup required, exiting..."
return
fi
for folder in $(echo "$unmappedFolders"); do
log "Removing $folder"
rm -rf "$folder"
done
IFS="$OLDIFS"
}
# Loop Script
for (( ; ; )); do
let i++
logfileSetup
log "Script starting..."
verifyConfig
getArrAppInfo
verifyApiAccess
UnmappedFolderCleanerProcess
log "Script sleeping for $unmappedFolderCleanerScriptInterval..."
sleep $unmappedFolderCleanerScriptInterval
done
exit

View file

@ -1,38 +0,0 @@
##### RADARR EXTENDED SCRIPTS SETTINGS #####
##### SCRIPT ENABLEMENT
enableAutoConfig="true" # true = enabled :: Enables AutoConfig script to run after startup
enableExtras="true" # true = enabled :: Enables Extras and AutoExtras scripts to run in the background and during import process
enableRecyclarr="true" # true = enabled :: Enables Recyclarr to run
enableQueueCleaner="true" # true = enabled :: Enables QueueCleaner Script that automatically removes stuck downloads that cannot be automatically imported
enableUnmappedFolderCleaner="false" # true = enabled :: Purges any folders that are considered Unmapped in Radarr
enableInvalidMoviesAutoCleaner="false" # true = enabled :: Enables InvalidMoviesAutoCleaner script to run, removes movies that are no longer mapped to TMDB site
##### SCRIPT INTERVALS
autoExtrasScriptInterval=24h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
unmappedFolderCleanerScriptInterval=1h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
recyclarrScriptInterval=6h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
queueCleanerScriptInterval=15m #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
invalidMoviesAutoCleanerScriptInterval=1h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
##### ATUOCONFIG SCRIPT SETTINGS
configureMediaManagement="true"
configureMetadataProviderSettings="true"
configureCustomScripts="true"
configureCustomFormats="true"
configureNaming="true"
##### EXTRAS SCRIPT
extrasLanguages="en-US" # Set the desired language for Extras, all languages will be processed... (this is a "," separated list of TMDB language codes, get the code from there sites language opitons, example: en-US)
extrasType="all" # all or trailers :: all downloads all available videos (trailers, clips, featurette, etc...) :: trailers only downloads trailers
extrasOfficialOnly="false" # true = enabled :: Skips extras that are not considered/marked as Official from TMDB site.
extrasKodiCompatibility="false" # true = enabled :: Only works if "extrasSingle" is set to true, names trailer in a kodi compatible naming scheme (movie-trailer.mkv)
extrasSingle="false" # true = enabled :: Only downloads the first available trailer, does not download any other extras
videoFormat="bestvideo*+bestaudio/best" # OPTIONAL - yt-dlp video selection paramater, do not change unless you know what your doing....
##### RECYCLARR SCRIPT
recyclarrConfig="/config/extended/recyclarr.yaml" # Change to a custom yaml file to use your own configuration, the default file is always overwritten...
##### PLEX NOTIFY SCRIPT
plexUrl="" # ONLY used if PlexNotify.bash is used, example: http://x.x.x.x:32400
plexToken="" # ONLY used if PlexNotify.bash is used

View file

@ -1,17 +0,0 @@
{
"folder": {
"default": "{Movie CleanTitle} ({Release Year})",
"plex": "{Movie CleanTitle} ({Release Year}) {imdb-{ImdbId}}",
"emby": "{Movie CleanTitle} ({Release Year}) [imdbid-{ImdbId}]",
"jellyfin": "{Movie CleanTitle} ({Release Year}) [imdbid-{ImdbId}]"
},
"file": {
"default": "{Movie CleanTitle} {(Release Year)} {imdb-{ImdbId}} {edition-{Edition Tags}} {[Custom Formats]}{[Quality Full]}{[MediaInfo 3D]}{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels}]{MediaInfo AudioLanguagesAll}[{MediaInfo VideoBitDepth}bit][{Mediainfo VideoCodec}]{MediaInfo SubtitleLanguagesAll}{-Release Group}",
"emby": "{Movie CleanTitle} {(Release Year)} [imdbid-{ImdbId}] - {Edition Tags }{[Custom Formats]}{[Quality Full]}{[MediaInfo 3D]}{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels}][{Mediainfo VideoCodec}]{-Release Group}",
"jellyfin": "{Movie CleanTitle} {(Release Year)} [imdbid-{ImdbId}] - {Edition Tags }{[Custom Formats]}{[Quality Full]}{[MediaInfo 3D]}{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels}][{Mediainfo VideoCodec}]{-Release Group}",
"anime": "{Movie CleanTitle} {(Release Year)} {imdb-{ImdbId}} {edition-{Edition Tags}} {[Custom Formats]}{[Quality Full]}{[MediaInfo 3D]}{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels}]{MediaInfo AudioLanguages}[{MediaInfo VideoBitDepth}bit][{Mediainfo VideoCodec}]{-Release Group}",
"anime-emby": "{Movie CleanTitle} {(Release Year)} [imdbid-{ImdbId}] - {Edition Tags }{[Custom Formats]}{[Quality Full]}{[MediaInfo 3D]}{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels}]{MediaInfo AudioLanguages}[{MediaInfo VideoBitDepth}bit][{Mediainfo VideoCodec}]{-Release Group}",
"anime-jellyfin": "{Movie CleanTitle} {(Release Year)} [imdbid-{ImdbId}] - {Edition Tags }{[Custom Formats]}{[Quality Full]}{[MediaInfo 3D]}{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels}]{MediaInfo AudioLanguages}[{MediaInfo VideoBitDepth}bit][{Mediainfo VideoCodec}]{-Release Group}",
"original": "{Original Title}"
}
}

View file

@ -1,79 +0,0 @@
# README
## Requirements
Container: <https://docs.linuxserver.io/images/docker-radarr>
## Installation/setup
1. Add 2 volumes to your container
`/custom-services.d` and `/custom-cont-init.d` (do not map to the same local folder...)
Docker Run Example:
`-v /path/to/preferred/local/folder-01:/custom-services.d`
`-v /path/to/preferred/local/folder-02:/custom-cont-init.d`
1. Download the [script_init.bash](https://github.com/RandomNinjaAtk/arr-scripts/blob/main/radarr/scripts_init.bash) ([Download Link](https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/scripts_init.bash)) and place it into the following folder: `/custom-cont-init.d`
1. Start your container and wait for the application to load
1. Optional: Customize the configuration by modifying the following file `/config/extended.conf`
1. Restart the container
## Updating
Updating is a bit more combersum. To update, do the following:
1. Download/update your local `/config/extended.conf` file with the latest options from: [extended.conf](https://github.com/RandomNinjaAtk/arr-scripts/blob/main/radarr/extended.conf)
1. Restart the container, wait for it to fully load the application.
1. Restart the container again, for the new scripts to activate.
## Uninstallation/Removal
1. Remove the 2 added volumes and delete the contents<br>
`/custom-services.d` and `/custom-cont-init.d`
1. Delete the `/config/extended.conf` file
1. Delete the `/config/extended` folder and it's contents
1. Remove any Arr app customizations manually.
## Support
[Information](https://github.com/RandomNinjaAtk/arr-scripts/tree/main?tab=readme-ov-file#support-info)
## Features
<table>
<tr>
<td><img src="https://raw.githubusercontent.com/RandomNinjaAtk/unraid-templates/master/randomninjaatk/img/radarr.png" width="200"></td>
<td><img src="https://github.com/RandomNinjaAtk/docker-lidarr-extended/raw/main/.github/plus.png" width="100"></td>
<td><img src="https://raw.githubusercontent.com/RandomNinjaAtk/unraid-templates/master/randomninjaatk/img/amtd.png" width="200"></td>
</tr>
</table>
* Downloading **Movie Trailers** and **Extras** using online sources for use in popular applications (Plex/Kodi/Emby/Jellyfin):
* Connects to Radarr to automatically download trailers for Movies in your existing library
* Downloads videos using yt-dlp automatically
* Names videos correctly to match Plex/Emby/Jellyfin naming convention
* Auto Configure Radarr with optimized settings
* Optimized file/folder naming (based on trash guides)
* Configures media management settings
* Configures metadata settings
* Recyclarr built-in
* Auto configures Custom Formats
* Auto configures Custom Format Scores
* Auto configures optimized quality definitions
* Plex Notify Script
* Reduce Plex scanning by notifying Plex the exact folder to scan
* Queue Cleaner Script
* Automatically removes downloads that have a "warning" or "failed" status that will not auto-import into Radarr, which enables Radarr to automatically re-search for the Title
For more details, visit the [Wiki](https://github.com/RandomNinjaAtk/arr-scripts/wiki)
### Plex Example
![amvtd](https://raw.githubusercontent.com/RandomNinjaAtk/docker-amtd/master/.github/amvtd-plex-example.jpg)
## Credits
* [ffmpeg](https://ffmpeg.org/)
* [yt-dlp](https://github.com/yt-dlp/yt-dlp)
* [linuxserver/radarr](https://github.com/linuxserver/docker-radarr) Base docker image
* [Radarr](https://radarr.video/)
* [The Movie Database](https://www.themoviedb.org/)
* [Recyclarr](https://github.com/recyclarr/recyclarr)
* Icons made by [Freepik](https://www.freepik.com/) from [Flaticon](ttps://www.flaticon.com)

View file

@ -1,212 +0,0 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/recyclarr/recyclarr/master/schemas/config-schema.json
# A starter config to use with Recyclarr. Most values are set to "reasonable defaults". Update the
# values below as needed for your instance. You will be required to update the API Key and URL for
# each instance you want to use.
#
# Many optional settings have been omitted to keep this template simple.
#
# For more details on the configuration, see the Configuration Reference on the wiki here:
# https://github.com/recyclarr/recyclarr/wiki/Configuration-Reference
# Configuration specific to Radarr.
radarr:
# Set the URL/API Key to your actual instance
instance1:
base_url: http://127.0.0.1:7878
api_key: arrApi
quality_definition:
type: sqp-streaming
delete_old_custom_formats: true
replace_existing_custom_formats: True
quality_profiles:
- name: All
reset_unmatched_scores:
enabled: false
upgrade:
allowed: true
until_score: 4500
until_quality: All
min_format_score: 10
quality_sort: top
qualities:
- name: All
qualities:
- WEBDL-1080p
- WEBDL-2160p
- Bluray-1080p
- WEBRip-1080p
- HDTV-1080p
- Bluray-2160p
- WEBRip-2160p
- HDTV-2160p
- WEBDL-720p
- Bluray-720p
- WEBRip-720p
- Bluray-576p
- HDTV-720p
- WEBDL-480p
- Bluray-480p
- WEBRip-480p
- SDTV
- DVD
- DVD-R
custom_formats:
# Custom scoring
- trash_ids:
- 2899d84dc9372de3408e6d8cc18e9666 # x264
- 9170d55c319f4fe40da8711ba9d8050d # x265
quality_profiles:
- name: All
score: 2000
- trash_ids:
# Streaming Services
- b3b3a6ac74ecbd56bcdbefa4799fb9df # AMZN
- 40e9380490e748672c2522eaaeb692f7 # ATVP
- cc5e51a9e85a6296ceefe097a77f12f4 # BCORE
- f6ff65b3f4b464a79dcc75950fe20382 # CRAV
- 16622a6911d1ab5d5b8b713d5b0036d4 # CRiT
- 84272245b2988854bfb76a16e60baea5 # DSNP
- 509e5f41146e278f9eab1ddaceb34515 # HBO
- 5763d1b0ce84aff3b21038eea8e9b8ad # HMAX
- 526d445d4c16214309f0fd2b3be18a89 # Hulu
- 2a6039655313bf5dab1e43523b62c374 # MA
- 6a061313d22e51e0f25b7cd4dc065233 # MAX
- 170b1d363bd8516fbf3a3eb05d4faff6 # NF
- fbca986396c5e695ef7b2def3c755d01 # OViD
- bf7e73dd1d85b12cc527dc619761c840 # Pathe
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
- e36a0ba1bc902b26ee40818a1d59b8bd # PMTP
- c2863d2a50c9acad1fb50e53ece60817 # STAN
quality_profiles:
- name: All
score: 10
- trash_ids:
- dfb86d5941bc9075d6af23b09c2aeecd # HDR10
- e61e28db95d22bedcadf030b8f156d96 # HDR
- 2a4d9069cc1fe3242ff9bdaebed239bb # HDR (undefined)
- 9f6cbff8cfe4ebbc1bde14c7b7bec0de # IMAX Enhanced
- 1af239278386be2919e1bcee0bde047e # DD+ ATMOS
- 185f1dd7264c4562b9022d963ac37424 # DD+
- 77ff61788dfe1097194fd8743d7b4524 # 5.1 Surround
- 6fd7b090c3f7317502ab3b63cc7f51e3 # 6.1 Surround
- e77382bcfeba57cb83744c9c5449b401 # 7.1 Surround
- f2aacebe2c932337fe352fa6e42c1611 # 9.1 Surround
- 820b09bb9acbfde9c35c71e0e565dad8 # 1080p
quality_profiles:
- name: All
score: 500
- trash_ids:
- e23edd2482476e595fb990b12e7c609c # DV HDR10
- b974a6cd08c1066250f1f177d7aa1225 # HDR10+
quality_profiles:
- name: All
score: 70
- trash_ids:
- fb392fb0d61a010ae38e49ceaa24a1ef # 2160p
quality_profiles:
- name: All
score: 30
- trash_ids:
- 89dac1be53d5268a7e10a19d3c896826 # 2.0 Stereo
- 205125755c411c3b8622ca3175d27b37 # 3.0 Sound
- 373b58bd188fc00c817bd8c7470ea285 # 4.0 Sound
quality_profiles:
- name: All
score: 25
- trash_ids:
- b2be17d608fc88818940cd1833b0b24c # 720p
- c2998bd0d90ed5621d8df281e839436e # DD
- b124be9b146540f8e62f98fe32e49a2a # 1.0 Mono
quality_profiles:
- name: All
score: 20
- trash_ids:
- a061e2e700f81932daf888599f8a8273 # Opus
quality_profiles:
- name: All
score: 15
- trash_ids:
- ae43b294509409a6a13919dedd4764c4 # Repack2
- 240770601cc226190c367ef59aba7463 # AAC
quality_profiles:
- name: All
score: 10
- trash_ids:
- e7718d7a3ce595f289bfee26adc178f5 # Repack/Proper
- f9f847ac70a0af62ea4a08280b859636 # DTS-ES
- 1c1a4c5e823891c75bc50380a6866f73 # DTS
- 8e109e50e0a0b83a5098b056e13bf6db # DTS-HD HRA
- dcf3ec6938fa32445f590a4da84256cd # DTS-HD MA
- 3cafb66171b47f226146a0770576870f # TrueHD
- 2f22d89048b01681dde8afe203bf2e95 # DTS X
- 496f355514737f7d83bf7aa4d24f8169 # TrueHD ATMOS
- 417804f7f2c4308c1f4c5d380d4c4475 # ATMOS (undefined)
- a570d4a0e56a2874b64e5bfa55202a1b # FLAC
- 6ba9033150e7896bdc9ec4b44f2b230f # MP3
- e7c2fcae07cbada050a0af3357491d7b # PCM
- a5d148168c4506b55cf53984107c396e # 10bit
- 9c38ebb7384dada637be8899efa68e6f # SDR
quality_profiles:
- name: All
score: 5
- trash_ids:
# HQ Release Groups
- 5153ec7413d9dae44e24275589b5e944 # BHDStudio
- c20f169ef63c5f40c2def54abaf4438e # WEB Tier 01
- 403816d65392c79236dcb6dd591aeda4 # WEB Tier 02
- af94e0fe497124d1f9ce732069ec8c3b # WEB Tier 03
- ed27ebfef2f323e964fb1f61391bcb35 # HD Bluray Tier 01
- c20c8647f2746a1f4c4262b0fbbeeeae # HD Bluray Tier 02
- 5608c71bcebba0a5e666223bae8c9227 # HD Bluray Tier 03
quality_profiles:
- name: All
score: 50
- trash_ids:
- dc98083864ea246d05a42df0d05f81cc # x265 (HD)
- 839bea857ed2c0a8e084f3cbdbd65ecb # x265 (no HDR/DV)
- ae9b7c9ebde1f3bd336a8cbd1ec4c5e5 # No-RlsGroup
- 7357cf5161efbf8c4d5d0c30b4815ee2 # Obfuscated
- 4b900e171accbfb172729b63323ea8ca # Multi
- ff86c4326018682f817830ced463332b # MPEG2
- ae4cfaa9283a4f2150ac3da08e388723 # VP9
quality_profiles:
- name: All
score: -5
- trash_ids:
# Movie Versions
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
- e0c07d59beb37348e975a930d5e50319 # Criterion Collection
- 0f12c086e289cf966fa5948eac571f44 # Hybrid
- 9d27d9d2181838f76dee150882bdc58c # Masters of Cinema
- 09d9dd29a0fc958f9796e65c2a8864b4 # Open Matte
- 570bc9ebecd92723d2d21500f4be314c # Remaster
- 957d0f44b592285f26449575e8b1167e # Special Edition
- e9001909a4c88013a359d0b9920d7bea # Theatrical Cut
- db9b4c4b53d312a3ca5f1378f6440fc9 # Vinegar Syndrome
quality_profiles:
- name: All
score: -50
- trash_ids:
- cae4ca30163749b891686f95532519bd # AV1
- b8cd450cbfa689c0259a01d9e29ba3d6 # 3D
- ed38b889b31be83fda192888e2286d83 # BR-DISK
- 90cedc1fea7ea5d11298bebd3d1d3223 # EVO (no WEBDL)
- 0a3f082873eb454bde444150b70253cc # Extras
- b6832f586342ef70d9c128d40c07b872 # Bad Dual Groups
- 73613461ac2cea99d52c4cd6e177ab82 # HFR
- c465ccc73923871b3eb1802042331306 # Line/Mic Dubbed
# HDR
- 58d6a88f13e2db7f5059c41047876f00 # DV
- 55d53828b9d81cbe20b02efd00aa0efd # DV HLG
- a3e19f8f627608af0211acd02bf89735 # DV SDR
- 08d6d8834ad9ec87b1dc7ec8148e7a1f # PQ
- 9364dd386c9b4a1100dde8264690add7 # HLG
- 923b6abef9b17f937fab56cfcf89e1f1 # DV (WEBDL)
quality_profiles:
- name: All
score: -100000

View file

@ -1,194 +0,0 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/recyclarr/recyclarr/master/schemas/config-schema.json
# A starter config to use with Recyclarr. Most values are set to "reasonable defaults". Update the
# values below as needed for your instance. You will be required to update the API Key and URL for
# each instance you want to use.
#
# Many optional settings have been omitted to keep this template simple.
#
# For more details on the configuration, see the Configuration Reference on the wiki here:
# https://github.com/recyclarr/recyclarr/wiki/Configuration-Reference
# Configuration specific to Radarr.
radarr:
# Set the URL/API Key to your actual instance
instance1:
base_url: http://127.0.0.1:7878
api_key: arrApi
quality_definition:
type: sqp-uhd
delete_old_custom_formats: true
replace_existing_custom_formats: True
quality_profiles:
- name: All
reset_unmatched_scores:
enabled: false
upgrade:
allowed: true
until_score: 15000
until_quality: All
min_format_score: 10000
quality_sort: top
qualities:
- name: All
qualities:
- WEBDL-2160p
- Bluray-2160p
- Remux-2160p
custom_formats:
# Custom scoring
- trash_ids:
- 9170d55c319f4fe40da8711ba9d8050d # x265
quality_profiles:
- name: All
score: 2000
- trash_ids:
- e61e28db95d22bedcadf030b8f156d96 # HDR
- dfb86d5941bc9075d6af23b09c2aeecd # HDR10
- b974a6cd08c1066250f1f177d7aa1225 # HDR10+
quality_profiles:
- name: All
score: 10000
- trash_ids:
# General Streaming Services
- b3b3a6ac74ecbd56bcdbefa4799fb9df # AMZN
- 40e9380490e748672c2522eaaeb692f7 # ATVP
- cc5e51a9e85a6296ceefe097a77f12f4 # BCORE
- 16622a6911d1ab5d5b8b713d5b0036d4 # CRiT
- 84272245b2988854bfb76a16e60baea5 # DSNP
- 509e5f41146e278f9eab1ddaceb34515 # HBO
- 5763d1b0ce84aff3b21038eea8e9b8ad # HMAX
- 526d445d4c16214309f0fd2b3be18a89 # Hulu
- 2a6039655313bf5dab1e43523b62c374 # MA
- 6a061313d22e51e0f25b7cd4dc065233 # MAX
- 170b1d363bd8516fbf3a3eb05d4faff6 # NF
- c9fd353f8f5f1baf56dc601c4cb29920 # PCOK
- e36a0ba1bc902b26ee40818a1d59b8bd # PMTP
- c2863d2a50c9acad1fb50e53ece60817 # STAN
quality_profiles:
- name: All
score: 5000
- trash_ids:
- 9f6cbff8cfe4ebbc1bde14c7b7bec0de # IMAX Enhanced
- 1af239278386be2919e1bcee0bde047e # DD+ ATMOS
- 185f1dd7264c4562b9022d963ac37424 # DD+
- 77ff61788dfe1097194fd8743d7b4524 # 5.1 Surround
- 6fd7b090c3f7317502ab3b63cc7f51e3 # 6.1 Surround
- e77382bcfeba57cb83744c9c5449b401 # 7.1 Surround
- f2aacebe2c932337fe352fa6e42c1611 # 9.1 Surround
- fb392fb0d61a010ae38e49ceaa24a1ef # 2160p
quality_profiles:
- name: All
score: 500
- trash_ids:
- 89dac1be53d5268a7e10a19d3c896826 # 2.0 Stereo
- 205125755c411c3b8622ca3175d27b37 # 3.0 Sound
- 373b58bd188fc00c817bd8c7470ea285 # 4.0 Sound
quality_profiles:
- name: All
score: 25
- trash_ids:
- b2be17d608fc88818940cd1833b0b24c # 720p
- c2998bd0d90ed5621d8df281e839436e # DD
- b124be9b146540f8e62f98fe32e49a2a # 1.0 Mono
quality_profiles:
- name: All
score: 20
- trash_ids:
- a061e2e700f81932daf888599f8a8273 # Opus
quality_profiles:
- name: All
score: 15
- trash_ids:
- ae43b294509409a6a13919dedd4764c4 # Repack2
- 240770601cc226190c367ef59aba7463 # AAC
quality_profiles:
- name: All
score: 10
- trash_ids:
- e7718d7a3ce595f289bfee26adc178f5 # Repack/Proper
- f9f847ac70a0af62ea4a08280b859636 # DTS-ES
- 1c1a4c5e823891c75bc50380a6866f73 # DTS
- 8e109e50e0a0b83a5098b056e13bf6db # DTS-HD HRA
- dcf3ec6938fa32445f590a4da84256cd # DTS-HD MA
- 3cafb66171b47f226146a0770576870f # TrueHD
- 2f22d89048b01681dde8afe203bf2e95 # DTS X
- 496f355514737f7d83bf7aa4d24f8169 # TrueHD ATMOS
- 417804f7f2c4308c1f4c5d380d4c4475 # ATMOS (undefined)
- a570d4a0e56a2874b64e5bfa55202a1b # FLAC
- 6ba9033150e7896bdc9ec4b44f2b230f # MP3
- e7c2fcae07cbada050a0af3357491d7b # PCM
- a5d148168c4506b55cf53984107c396e # 10bit
quality_profiles:
- name: All
score: 5
- trash_ids:
# HQ Release Groups
- 3a3ff47579026e76d6504ebea39390de # Remux Tier 01
- 9f98181fe5a3fbeb0cc29340da2a468a # Remux Tier 02
- 8baaf0b3142bf4d94c42a724f034e27a # Remux Tier 03
- 4d74ac4c4db0b64bff6ce0cffef99bf0 # UHD Bluray Tier 01
- a58f517a70193f8e578056642178419d # UHD Bluray Tier 02
- e71939fae578037e7aed3ee219bbe7c1 # UHD Bluray Tier 03
- c20f169ef63c5f40c2def54abaf4438e # WEB Tier 01
- 403816d65392c79236dcb6dd591aeda4 # WEB Tier 02
- af94e0fe497124d1f9ce732069ec8c3b # WEB Tier 03
- ff5bc9e8ce91d46c997ca3ac6994d6f8 # FraMeSToR
quality_profiles:
- name: All
score: 50
- trash_ids:
- dc98083864ea246d05a42df0d05f81cc # x265 (HD)
- 839bea857ed2c0a8e084f3cbdbd65ecb # x265 (no HDR/DV)
- ae9b7c9ebde1f3bd336a8cbd1ec4c5e5 # No-RlsGroup
- 7357cf5161efbf8c4d5d0c30b4815ee2 # Obfuscated
- 4b900e171accbfb172729b63323ea8ca # Multi
- ff86c4326018682f817830ced463332b # MPEG2
- ae4cfaa9283a4f2150ac3da08e388723 # VP9
quality_profiles:
- name: All
score: -5
- trash_ids:
# Movie Versions
- eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
- e0c07d59beb37348e975a930d5e50319 # Criterion Collection
- 0f12c086e289cf966fa5948eac571f44 # Hybrid
- 9d27d9d2181838f76dee150882bdc58c # Masters of Cinema
- 09d9dd29a0fc958f9796e65c2a8864b4 # Open Matte
- 570bc9ebecd92723d2d21500f4be314c # Remaster
- 957d0f44b592285f26449575e8b1167e # Special Edition
- e9001909a4c88013a359d0b9920d7bea # Theatrical Cut
- db9b4c4b53d312a3ca5f1378f6440fc9 # Vinegar Syndrome
quality_profiles:
- name: All
score: -50
- trash_ids:
- cae4ca30163749b891686f95532519bd # AV1
- b8cd450cbfa689c0259a01d9e29ba3d6 # 3D
- ed38b889b31be83fda192888e2286d83 # BR-DISK
- 90cedc1fea7ea5d11298bebd3d1d3223 # EVO (no WEBDL)
- 0a3f082873eb454bde444150b70253cc # Extras
- b6832f586342ef70d9c128d40c07b872 # Bad Dual Groups
- 73613461ac2cea99d52c4cd6e177ab82 # HFR
- c465ccc73923871b3eb1802042331306 # Line/Mic Dubbed
# HDR
- 58d6a88f13e2db7f5059c41047876f00 # DV
- 55d53828b9d81cbe20b02efd00aa0efd # DV HLG
- a3e19f8f627608af0211acd02bf89735 # DV SDR
- 08d6d8834ad9ec87b1dc7ec8148e7a1f # PQ
- 9364dd386c9b4a1100dde8264690add7 # HLG
- 923b6abef9b17f937fab56cfcf89e1f1 # DV (WEBDL)
- 2a4d9069cc1fe3242ff9bdaebed239bb # HDR (undefined)
- 5153ec7413d9dae44e24275589b5e944 # BHDStudio
- 9c38ebb7384dada637be8899efa68e6f # SDR
- 25c12f78430a3a23413652cbd1d48d77 # SDR (no WEBDL)
- e23edd2482476e595fb990b12e7c609c # DV HDR10
- b17886cb4158d9fea189859409975758 # HDR10+ Boost
- 2899d84dc9372de3408e6d8cc18e9666 # x264
quality_profiles:
- name: All
score: -100000

View file

@ -1,3 +0,0 @@
#!/usr/bin/with-contenv bash
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/setup.bash | bash
exit

View file

@ -1,126 +0,0 @@
#!/usr/bin/with-contenv bash
SMA_PATH="/usr/local/sma"
echo "************ install packages ************" && \
apk add -U --update --no-cache \
flac \
opus-tools \
jq \
git \
wget \
mkvtoolnix \
python3-dev \
libc-dev \
py3-pip \
gcc \
ffmpeg && \
echo "************ install python packages ************" && \
pip install --upgrade --no-cache-dir -U --break-system-packages \
excludarr \
yt-dlp \
yq && \
echo "************ setup SMA ************"
if [ -d "${SMA_PATH}" ]; then
rm -rf "${SMA_PATH}"
fi
echo "************ setup directory ************" && \
mkdir -p ${SMA_PATH} && \
echo "************ download repo ************" && \
git clone https://github.com/mdhiggins/sickbeard_mp4_automator.git ${SMA_PATH} && \
mkdir -p ${SMA_PATH}/config && \
echo "************ create logging file ************" && \
mkdir -p ${SMA_PATH}/config && \
touch ${SMA_PATH}/config/sma.log && \
chgrp users ${SMA_PATH}/config/sma.log && \
chmod g+w ${SMA_PATH}/config/sma.log && \
echo "************ install pip dependencies ************" && \
python3 -m pip install --break-system-packages --upgrade pip && \
pip3 install --break-system-packages -r ${SMA_PATH}/setup/requirements.txt && \
echo "************ install recyclarr ************" && \
mkdir -p /recyclarr && \
# Get the hardware architecture
architecture=$(uname -m)
if [[ "$architecture" == arm* ]] then
recyclarr_url="https://github.com/recyclarr/recyclarr/releases/latest/download/recyclarr-linux-musl-arm.tar.xz"
elif [[ "$architecture" == "aarch64" ]]; then
recyclarr_url="https://github.com/recyclarr/recyclarr/releases/latest/download/recyclarr-linux-musl-arm64.tar.xz"
else
recyclarr_url="https://github.com/recyclarr/recyclarr/releases/latest/download/recyclarr-linux-musl-x64.tar.xz"
fi
wget "$recyclarr_url" -O "/recyclarr/recyclarr.tar.xz" && \
tar -xf /recyclarr/recyclarr.tar.xz -C /recyclarr &>/dev/null && \
chmod 777 /recyclarr/recyclarr
apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/community dotnet8-runtime
mkdir -p /custom-services.d
echo "Download QueueCleaner service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/universal/services/QueueCleaner -o /custom-services.d/QueueCleaner
echo "Done"
echo "Download AutoConfig service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/AutoConfig.service -o /custom-services.d/AutoConfig
echo "Done"
echo "Download AutoExtras service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/AutoExtras.service -o /custom-services.d/AutoExtras
echo "Done"
echo "Download InvalidMoviesAutoCleaner service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/InvalidMoviesAutoCleaner.bash -o /custom-services.d/InvalidMoviesAutoCleaner
echo "Done"
echo "Download UnmappedFolderCleaner service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/UnmappedFolderCleaner.bash -o /custom-services.d/UnmappedFolderCleaner
echo "Done"
mkdir -p /config/extended
echo "Download Script Functions..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/universal/functions.bash -o /config/extended/functions
echo "Done"
if [ ! -f /config/extended/naming.json ]; then
echo "Download Naming script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/naming.json -o /config/extended/naming.json
echo "Done"
fi
mkdir -p /config/extended
echo "Download PlexNotify script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/PlexNotify.bash -o /config/extended/PlexNotify.bash
echo "Done"
echo "Download Extras script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/Extras.bash -o /config/extended/Extras.bash
echo "Done"
if [ ! -f /config/extended/sma.ini ]; then
echo "Download SMA config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/sma.ini -o /config/extended/sma.ini
echo "Done"
fi
echo "Download Recyclarr service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/universal/services/Recyclarr -o /custom-services.d/Recyclarr
echo "Done"
if [ ! -f /config/extended/recyclarr.yaml ]; then
echo "Download Recyclarr config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/recyclarr.yaml -o /config/extended/recyclarr.yaml
echo "Done"
fi
if [ ! -f /config/extended.conf ]; then
echo "Download Extended config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/radarr/extended.conf -o /config/extended.conf
chmod 777 /config/extended.conf
echo "Done"
fi
chmod 777 -R /config/extended
if [ -f /custom-services.d/scripts_init.bash ]; then
# user misconfiguration detected, sleeping...
sleep infinity
fi
exit

View file

@ -1,254 +0,0 @@
[Converter]
ffmpeg = ffmpeg
ffprobe = ffprobe
threads = 0
hwaccels =
hwaccel-decoders =
hwdevices =
hwaccel-output-format =
output-directory =
output-format = mkv
output-extension = mkv
temp-extension =
minimum-size = 0
ignored-extensions = nfo, ds_store
copy-to =
move-to =
delete-original = True
process-same-extensions = True
bypass-if-copying-all = False
force-convert = True
post-process = False
wait-post-process = False
detailed-progress = False
opts-separator = ,
preopts =
postopts =
regex-directory-replace = [^\w\-_\. ]
[Permissions]
chmod = 0666
uid = -1
gid = -1
[Metadata]
relocate-moov = True
full-path-guess = True
tag = True
tag-language = eng
download-artwork = poster
sanitize-disposition =
strip-metadata = True
keep-titles = False
[Video]
codec = copy
max-bitrate = 0
bitrate-ratio =
crf = -1
crf-profiles =
preset =
codec-parameters =
dynamic-parameters = False
max-width = 0
profile =
max-level = 0.0
pix-fmt =
prioritize-source-pix-fmt = True
filter =
force-filter = False
[HDR]
codec =
pix-fmt =
space = bt2020nc
transfer = smpte2084
primaries = bt2020
preset =
codec-parameters =
filter =
force-filter = False
profile =
[Audio]
codec = copy
languages =
default-language =
first-stream-of-language = False
allow-language-relax = True
relax-to-default = False
channel-bitrate = 128
variable-bitrate = 0
max-bitrate = 0
max-channels = 0
filter =
profile =
force-filter = False
sample-rates =
sample-format =
copy-original = False
aac-adtstoasc = False
ignored-dispositions =
force-default = False
unique-dispositions = True
stream-codec-combinations =
[Audio.Sorting]
sorting = language, channels.d, map, d.comment
default-sorting = channels.d, map, d.comment
codecs =
[Universal Audio]
codec =
channel-bitrate = 128
variable-bitrate = 0
first-stream-only = False
filter =
profile =
force-filter = False
[Audio.ChannelFilters]
6-2 = pan=stereo|FL=0.5*FC+0.707*FL+0.707*BL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707*BR+0.5*LFE
[Subtitle]
codec = srt
codec-image-based = copy
languages =
default-language =
first-stream-of-language = False
encoding =
burn-subtitles = False
burn-dispositions =
embed-subs = True
embed-image-subs = True
embed-only-internal-subs = True
filename-dispositions = forced
ignore-embedded-subs = False
ignored-dispositions =
force-default = False
unique-dispositions = True
attachment-codec =
remove-bitstream-subs = False
[Subtitle.Sorting]
sorting = language, d.comment, d.default.d, d.forced.d
burn-sorting = language, d.comment, d.default.d, d.forced.d
codecs =
[Subtitle.CleanIt]
enabled = False
config-path =
tags =
[Subtitle.Subliminal]
download-subs = False
download-hearing-impaired-subs = False
providers =
[Subtitle.Subliminal.Auth]
opensubtitles =
tvsubtitles =
[Sonarr]
host = localhost
port = 8989
apikey =
ssl = False
webroot =
force-rename = False
rescan = True
block-reprocess = False
[Radarr]
host = localhost
port = 7878
apikey =
ssl = False
webroot =
force-rename = False
rescan = True
block-reprocess = False
[Sickbeard]
host = localhost
port = 8081
ssl = False
apikey =
webroot =
username =
password =
[Sickrage]
host = localhost
port = 8081
ssl = False
apikey =
webroot =
username =
password =
[SABNZBD]
convert = True
sickbeard-category = sickbeard
sickrage-category = sickrage
sonarr-category = sonarr
radarr-category = radarr
bypass-category = bypass
output-directory =
path-mapping =
[Deluge]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
host = localhost
port = 58846
username =
password =
output-directory =
remove = False
path-mapping =
[qBittorrent]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
action-before =
action-after =
host = localhost
port = 8080
ssl = False
username =
password =
output-directory =
path-mapping =
[uTorrent]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
webui = False
action-before =
action-after =
host = localhost
ssl = False
port = 8080
username =
password =
output-directory =
path-mapping =
[Plex]
host = localhost
port = 32400
refresh = False
token =

View file

@ -1,120 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.3"
scriptName="AutoConfig"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
verifyConfig () {
if [ "$enableAutoConfig" != "true" ]; then
log "Script is not enabled, enable by setting enableAutoConfig to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
}
logfileSetup
log "Script starting..."
verifyConfig
getArrAppInfo
verifyApiAccess
autoConfigJson=$(cat /config/extended/AutoConfig.json)
renameBooks=$(echo "$autoConfigJson" | jq -r '.MediaManagement[].renameBooks')
replaceIllegalCharacters=$(echo "$autoConfigJson" | jq -r '.MediaManagement[].replaceIllegalCharacters')
standardBookFormat=$(echo "$autoConfigJson" | jq -r '.MediaManagement[].standardBookFormat')
authorFolderFormat=$(echo "$autoConfigJson" | jq -r '.MediaManagement[].authorFolderFormat')
deleteEmptyFolders=$(echo "$autoConfigJson" | jq -r '.MediaManagement[].deleteEmptyFolders')
watchLibraryForChanges=$(echo "$autoConfigJson" | jq -r '.MediaManagement[].watchLibraryForChanges')
chmodFolder=$(echo "$autoConfigJson" | jq -r '.MediaManagement[].chmodFolder')
fileDate=$(echo "$autoConfigJson" | jq -r '.MediaManagement[].fileDate')
writeAudioTags=$(echo "$autoConfigJson" | jq -r '.Metadata[].writeAudioTags')
scrubAudioTags=$(echo "$autoConfigJson" | jq -r '.Metadata[].scrubAudioTags')
writeBookTags=$(echo "$autoConfigJson" | jq -r '.Metadata[].writeBookTags')
updateCovers=$(echo "$autoConfigJson" | jq -r '.Metadata[].updateCovers')
embedMetadata=$(echo "$autoConfigJson" | jq -r '.Metadata[].embedMetadata')
log "Updating $arrAppName File Naming..."
updateArr=$(curl -s "$arrUrl/api/v1/config/naming" -X PUT -H "Content-Type: application/json" -H "X-Api-Key: $arrApiKey" --data-raw "{
\"renameBooks\": $renameBooks,
\"replaceIllegalCharacters\": $replaceIllegalCharacters,
\"standardBookFormat\": \"$standardBookFormat\",
\"authorFolderFormat\": \"$authorFolderFormat\",
\"includeAuthorName\": false,
\"includeBookTitle\": false,
\"includeQuality\": false,
\"replaceSpaces\": false,
\"id\": 1
}")
log "Complete"
log "Updating $arrAppName Media Management..."
updateArr=$(curl -s "$arrUrl/api/v3/config/mediamanagement" -X PUT -H "Content-Type: application/json" -H "X-Api-Key: $arrApiKey" --data-raw "{
\"autoUnmonitorPreviouslyDownloadedBooks\": false,
\"recycleBin\": \"\",
\"recycleBinCleanupDays\": 7,
\"downloadPropersAndRepacks\": \"preferAndUpgrade\",
\"createEmptyAuthorFolders\": false,
\"deleteEmptyFolders\": $deleteEmptyFolders,
\"fileDate\": \"$fileDate\",
\"watchLibraryForChanges\": $watchLibraryForChanges,
\"rescanAfterRefresh\": \"always\",
\"allowFingerprinting\": \"newFiles\",
\"setPermissionsLinux\": false,
\"chmodFolder\": \"$chmodFolder\",
\"chownGroup\": \"\",
\"skipFreeSpaceCheckWhenImporting\": false,
\"minimumFreeSpaceWhenImporting\": 100,
\"copyUsingHardlinks\": true,
\"importExtraFiles\": false,
\"extraFileExtensions\": \"srt\",
\"id\": 1
}")
log "Complete"
log "Updating $arrAppName Medata Settings..."
updateArr=$(curl -s "$arrUrl/api/v1/config/metadataProvider" -X PUT -H "Content-Type: application/json" -H "X-Api-Key: $arrApiKey" --data-raw "{
\"writeAudioTags\":\"$writeAudioTags\",
\"scrubAudioTags\":$scrubAudioTags,
\"writeBookTags\":\"$writeBookTags\",
\"updateCovers\":$updateCovers,
\"embedMetadata\":$embedMetadata,
\"id\":1
}")
log "Complete"
log "Configuring $arrAppName Custom Scripts"
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "PlexNotify.bash" | read; then
log "PlexNotify.bash already added to $arrAppName custom scripts"
else
log "Adding PlexNotify.bash to $arrAppName custom scripts"
# Send a command to check file path, to prevent error with adding...
updateArr=$(curl -s "$arrUrl/api/v3/filesystem?path=%2Fconfig%2Fextended%2FPlexNotify.bash&allowFoldersWithoutTrailingSlashes=true&includeFiles=true" -H "X-Api-Key: ${arrApiKey}")
# Add PlexNotify.bash
updateArr=$(curl -s "$arrUrl/api/v1/notification?" -X POST -H "Content-Type: application/json" -H "X-Api-Key: ${arrApiKey}" --data-raw '{"onGrab":false,"onReleaseImport":true,"onUpgrade":true,"onRename":false,"onAuthorDelete":true,"onBookDelete":true,"onBookFileDelete":false,"onBookFileDeleteForUpgrade":false,"onHealthIssue":false,"onDownloadFailure":false,"onImportFailure":false,"onBookRetag":false,"onApplicationUpdate":false,"supportsOnGrab":true,"supportsOnReleaseImport":true,"supportsOnUpgrade":true,"supportsOnRename":true,"supportsOnAuthorDelete":true,"supportsOnBookDelete":true,"supportsOnBookFileDelete":true,"supportsOnBookFileDeleteForUpgrade":true,"supportsOnHealthIssue":true,"includeHealthWarnings":false,"supportsOnDownloadFailure":false,"supportsOnImportFailure":false,"supportsOnBookRetag":true,"supportsOnApplicationUpdate":true,"name":"PlexNotify.bash","fields":[{"name":"path","value":"/config/extended/PlexNotify.bash"},{"name":"arguments"}],"implementationName":"Custom Script","implementation":"CustomScript","configContract":"CustomScriptSettings","infoLink":"https://wiki.servarr.com/readarr/supported#customscript","message":{"message":"Testing will execute the script with the EventType set to Test, ensure your script handles this correctly","type":"warning"},"tags":[]}')
log "Complete"
fi
if curl -s "$arrUrl/api/v1/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "combine.bash" | read; then
log "combine.bash already added to $arrAppName custom scripts"
else
log "Adding combine.bash to $arrAppName custom scripts"
# Send a command to check file path, to prevent error with adding...
updateArr=$(curl -s "$arrUrl/api/v3/filesystem?path=%2Fconfig%2Fextended%2FPlexNotify.bash&allowFoldersWithoutTrailingSlashes=true&includeFiles=true" -H "X-Api-Key: ${arrApiKey}")
# Add combine.bash
updateArr=$(curl -s "$arrUrl/api/v1/notification?" -X POST -H "Content-Type: application/json" -H "X-Api-Key: ${arrApiKey}" --data-raw '{"onGrab":false,"onReleaseImport":true,"onUpgrade":true,"onRename":true,"onAuthorDelete":false,"onBookDelete":false,"onBookFileDelete":false,"onBookFileDeleteForUpgrade":false,"onHealthIssue":false,"onDownloadFailure":false,"onImportFailure":false,"onBookRetag":false,"onApplicationUpdate":false,"supportsOnGrab":true,"supportsOnReleaseImport":true,"supportsOnUpgrade":true,"supportsOnRename":true,"supportsOnAuthorDelete":true,"supportsOnBookDelete":true,"supportsOnBookFileDelete":true,"supportsOnBookFileDeleteForUpgrade":true,"supportsOnHealthIssue":true,"includeHealthWarnings":false,"supportsOnDownloadFailure":false,"supportsOnImportFailure":false,"supportsOnBookRetag":true,"supportsOnApplicationUpdate":false,"name":"combine.bash","fields":[{"name":"path","value":"/config/extended/combine.bash"},{"name":"arguments"}],"implementationName":"Custom Script","implementation":"CustomScript","configContract":"CustomScriptSettings","infoLink":"https://wiki.servarr.com/readarr/supported#customscript","message":{"message":"Testing will execute the script with the EventType set to Test, ensure your script handles this correctly","type":"warning"},"tags":[]}')
log "Complete"
fi
log "Script sleeping for (infinity)..."
sleep infinity
exit

View file

@ -1,23 +0,0 @@
{
"MediaManagement": [
{
"renameBooks": "true",
"replaceIllegalCharacters": "true",
"standardBookFormat": "{Book Title}{ (Book Disambiguation)}/{Author Name} - {Book Title}{ (PartNumber)}",
"authorFolderFormat": "{Author Name}{ (Author Disambiguation)}",
"deleteEmptyFolders": "true",
"watchLibraryForChanges": "false",
"chmodFolder": "777",
"fileDate": "bookReleaseDate"
}
],
"Metadata": [
{
"writeAudioTags":"sync",
"scrubAudioTags": "false",
"writeBookTags": "sync",
"updateCovers": "true",
"embedMetadata":"true"
}
]
}

View file

@ -1,80 +0,0 @@
#!/usr/bin/env bash
scriptVersion=1.0
rootFolderPath="$(dirname "$readarr_author_path")"
#### Import Settings
source /config/extended.conf
# auto-clean up log file to reduce space usage
if [ -f "/config/logs/PlexNotify.txt" ]; then
find /config/logs -type f -name "PlexNotify.txt" -size +1024k -delete
fi
exec &> >(tee -a "/config/logs/PlexNotify.txt")
chmod 666 "/config/logs/PlexNotify.txt"
log () {
m_time=`date "+%F %T"`
echo $m_time" :: PlexNotify :: $scriptVersion :: "$1
}
if [ "$readarr_eventtype" == "Test" ]; then
log "Tested Successfully"
exit 0
fi
plexConnectionError () {
log "ERROR :: Cannot communicate with Plex"
log "ERROR :: Please check your plexUrl and plexToken"
log "ERROR :: Configured plexUrl \"$plexUrl\""
log "ERROR :: Configured plexToken \"$plexToken\""
log "ERROR :: Exiting..."
exit
}
# Validate connection
if curl -s "$plexUrl/?X-Plex-Token=$plexToken" | xq . &>/dev/null; then
plexVersion=$(curl -s "$plexUrl/?X-Plex-Token=$plexToken" | xq . | jq -r '.MediaContainer."@version"')
if [ "$plexVersion" == "null" ]; then
# Error out if version is null, indicates bad token
plexConnectionError
else
log "Plex Connection Established, version: $plexVersion"
fi
else
# Error out if error in curl | xq . command output
plexConnectionError
fi
plexLibraries="$(curl -s "$plexUrl/library/sections?X-Plex-Token=$plexToken")"
if echo "$plexLibraries" | xq ".MediaContainer.Directory | select(.\"@type\"==\"artist\")" &>/dev/null; then
plexKeys=($(echo "$plexLibraries" | xq ".MediaContainer.Directory | select(.\"@type\"==\"artist\")" | jq -r '."@key"'))
plexLibraryData=$(echo "$plexLibraries" | xq ".MediaContainer.Directory | select(.\"@type\"==\"artist\")")
elif echo "$plexLibraries" | xq ".MediaContainer.Directory[] | select(.\"@type\"==\"artist\")" &>/dev/null; then
plexKeys=($(echo "$plexLibraries" | xq ".MediaContainer.Directory[] | select(.\"@type\"==\"artist\")" | jq -r '."@key"'))
plexLibraryData=$(echo "$plexLibraries" | xq ".MediaContainer.Directory[] | select(.\"@type\"==\"artist\")")
else
log "ERROR: No Plex Music Type libraries found"
log "ERROR: Exiting..."
exit 1
fi
if echo "$plexLibraryData" | grep "\"@path\": \"$rootFolderPath" | read; then
sleep 0.01
else
log "ERROR: No Plex Library found containing path \"$rootFolderPath\""
log "ERROR: Add \"$rootFolderPath\" as a folder to a Plex Music Library"
exit 1
fi
for key in ${!plexKeys[@]}; do
plexKey="${plexKeys[$key]}"
plexKeyLibraryData=$(echo "$plexLibraryData" | jq -r "select(.\"@key\"==\"$plexKey\")")
if echo "$plexKeyLibraryData" | grep "\"@path\": \"$rootFolderPath" | read; then
plexFolderEncoded="$(jq -R -r @uri <<<"$readarr_author_path")"
curl -s "$plexUrl/library/sections/$plexKey/refresh?path=$plexFolderEncoded&X-Plex-Token=$plexToken"
log "Plex Scan notification sent! ($plexKey :: $readarr_author_path)"
fi
done
exit

View file

@ -1,50 +0,0 @@
#!/usr/bin/env bash
scriptVersion=1.0
rootFolderPath="$(dirname "$readarr_author_path")"
scriptName="M4bCombine"
log() {
m_time=$(date "+%F %T")
echo "$m_time :: $scriptName :: $scriptVersion :: $1" >> "/config/logs/$scriptName-$(date +"%Y_%m_%d_%I_%M_%p").txt"
}
# Combine M4b Files
combineM4bFiles() {
log "Combining M4b files using FFmpeg..."
# Determine the M4b files path based on the context
if [ -z "$readarr_author_path" ]; then
# Extended script context
m4bFiles="$readarr_artist_path/*.mp3 $readarr_artist_path/*.m4b"
outputFolder="$readarr_artist_path/"
else
# Readarr context
m4bFiles="$1/*.mp3 $1/*.m4b"
outputFolder="$1/"
fi
# Extract author and book information
author=$(basename "$(dirname "$readarr_author_path")")
book=$(basename "$readarr_author_path")
# Create the output file path
outputFile="${outputFolder}${author}_${book}_combined.m4b"
# FFmpeg command to concatenate M4b files
ffmpeg -i "concat:$m4bFiles" -vn -b:a 128k -f m4b "$outputFile" 2>&1
if [ $? -eq 0 ]; then
log "M4b files combined successfully. Output: $outputFile"
rm -f "$readarr_artist_path/*.mp3"
log "MP3 files removed after successful M4b file combination."
else
log "Error combining M4b files with FFmpeg."
log "original file untouched"
fi
}
# Call the function to combine M4b files
combineM4bFiles "$readarr_artist_path"
exit 0

View file

@ -1,12 +0,0 @@
##### READARR EXTENDED SCRIPTS SETTINGS #####
##### SCRIPT ENABLEMENT
enableAutoConfig="true" # true = enabled :: Enables AutoConfig script to run after startup
enableQueueCleaner="true" # true = enabled :: Enables QueueCleaner Script that automatically removes stuck downloads that cannot be automatically imported
##### SCRIPT INTERVALS
queueCleanerScriptInterval=15m #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
##### PLEX NOTIFY SCRIPT
plexUrl="" # ONLY used if PlexNotify.bash is used, example: http://x.x.x.x:32400
plexToken="" # ONLY used if PlexNotify.bash is used

View file

@ -1,39 +0,0 @@
# README
## Requirements
Container: <https://hub.docker.com/r/linuxserver/readarr>
## Installation/setup
1. Add 2 volumes to your container
`/custom-services.d` and `/custom-cont-init.d` (do not map to the same local folder...)
Docker Run Example:
`-v /path/to/preferred/local/folder-01:/custom-services.d`
`-v /path/to/preferred/local/folder-02:/custom-cont-init.d`
1. Download the [script_init.bash](https://github.com/RandomNinjaAtk/arr-scripts/blob/main/readarr/scripts_init.bash) ([Download Link](https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/readarr/scripts_init.bash)) and place it into the following folder: `/custom-cont-init.d`
1. Start your container and wait for the application to load
1. Optional: Customize the configuration by modifying the following file `/config/extended.conf`
1. Restart the container
# Updating
Updating is a bit more combersum. To update, do the following:
1. Download/update your local `/config/extended.conf` file with the latest options from: [extended.conf](https://github.com/RandomNinjaAtk/arr-scripts/blob/main/readarr/extended.conf)
1. Restart the container, wait for it to fully load the application.
1. Restart the container again, for the new scripts to activate.
This configuration does its best to update everything automatically, but with how the core system is designed, the new scripts will not take affect until a second restart is completed because the container copies/uses the previous versions of the script for execution on the first restart.
## Uninstallation/Removal
1. Remove the 2 added volumes and delete the contents<br>
`/custom-services.d` and `/custom-cont-init.d`
1. Delete the `/config/extended.conf` file
1. Delete the `/config/extended` folder and it's contents
1. Remove any Arr app customizations manually.
## Support
[Information](https://github.com/RandomNinjaAtk/arr-scripts/tree/main?tab=readme-ov-file#support-info)

View file

@ -1,3 +0,0 @@
#!/usr/bin/with-contenv bash
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/readarr/setup.bash | bash
exit

View file

@ -1,49 +0,0 @@
#!/usr/bin/with-contenv bash
echo "************ install and update packages ************"
apk add -U --update --no-cache \
jq \
py3-pip \
ffmpeg
echo "************ install python packages ************"
pip install --upgrade --no-cache-dir -U --break-system-packages yq
mkdir -p /custom-services.d
echo "Download AutoConfig service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/readarr/AutoConfig.bash -o /custom-services.d/AutoConfig
echo "Done"
echo "Download QueueCleaner service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/universal/services/QueueCleaner -o /custom-services.d/QueueCleaner
echo "Done"
mkdir -p /config/extended
echo "Download Script Functions..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/universal/functions.bash -o /config/extended/functions
echo "Done"
echo "Download PlexNotify script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/readarr/PlexNotify.bash -o /config/extended/PlexNotify.bash
echo "Done"
echo "Download combine script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/readarr/combine.bash -o /config/extended/combine.bash
echo "Done"
echo "Download AutoConfig config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/readarr/AutoConfig.json -o /config/extended/AutoConfig.json
echo "Done"
chmod 777 -R /config/extended
if [ ! -f /config/extended.conf ]; then
echo "Download Extended config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/readarr/extended.conf -o /config/extended.conf
chmod 777 /config/extended.conf
echo "Done"
fi
if [ -f /custom-services.d/scripts_init.bash ]; then
# user misconfiguration detected, sleeping...
sleep infinity
fi
exit

View file

@ -1,302 +0,0 @@
#!/usr/bin/with-contenv bash
TITLESHORT="APP"
scriptVersion="1.8"
scriptName="Audio"
#### Import Settings
source /config/extended.conf
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $scriptVersion :: "$1
echo $m_time" :: $scriptName :: $scriptVersion :: "$1 >> /config/logs/$scriptName.txt
}
logfileSetup () {
# auto-clean up log file to reduce space usage
if [ -f "/config/logs/$scriptName.txt" ]; then
if find /config/logs -type f -name "$scriptName.txt" -size +1024k | read; then
echo "" > /config/logs/$scriptName.txt
fi
fi
if [ ! -f "/config/logs/$scriptName.txt" ]; then
echo "" > /config/logs/$scriptName.txt
chmod 666 "/config/logs/$scriptName.txt"
fi
}
set -e
set -o pipefail
Main () {
#============FUNCTIONS============
settings () {
log "Configuration:"
log "Script Version: $scriptVersion"
log "Remove Non Audio Files: ENABLED"
log "Duplicate File CleanUp: ENABLED"
if [ "${AudioVerification}" = TRUE ]; then
log "Audio Verification: ENABLED"
else
log "Audio Verification: DISABLED"
fi
log "Format: $ConversionFormat"
if [ "${ConversionFormat}" = FLAC ]; then
log "Bitrate: lossless"
log "Replaygain Tagging: ENABLED"
AudioFileExtension="flac"
elif [ "${ConversionFormat}" = ALAC ]; then
log "Bitrate: lossless"
AudioFileExtension="m4a"
else
log "Conversion Bitrate: ${ConversionBitrate}k"
if [ "${ConversionFormat}" = MP3 ]; then
AudioFileExtension="mp3"
elif [ "${ConversionFormat}" = AAC ]; then
AudioFileExtension="m4a"
elif [ "${ConversionFormat}" = OPUS ]; then
AudioFileExtension="opus"
fi
fi
if [ "$RequireAudioQualityMatch" = "true" ]; then
log "Audio Quality Match Verification: ENABLED (.$AudioFileExtension)"
else
log "Audio Quality Match Verification: DISABLED"
fi
if [ "${DetectNonSplitAlbums}" = TRUE ]; then
log "Detect Non Split Albums: ENABLED"
log "Max File Size: $MaxFileSize"
else
log "DetectNonSplitAlbums: DISABLED"
fi
log "Processing: $1"
}
AudioQualityMatch () {
if [ "$RequireAudioQualityMatch" == "true" ]; then
find "$1" -type f -not -iname "*.$AudioFileExtension" -delete
if [ $(find "$1" -type f -iname "*.$AudioFileExtension" | wc -l) -gt 0 ]; then
log "Verifying Audio Quality Match: PASSED (.$AudioFileExtension)"
else
log "Verifying Audio Quality Match"
log "ERROR: Audio Qualty Check Failed, missing required file extention (.$AudioFileExtension)"
exit 1
fi
fi
}
clean () {
if [ $(find "$1" -type f -regex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" | wc -l) -gt 0 ]; then
find "$1" -type f -not -regex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" -delete
find "$1" -mindepth 2 -type f -exec mv "{}" "$1"/ \;
find "$1" -mindepth 1 -type d -delete
else
log "ERROR: NO AUDIO FILES FOUND" && exit 1
fi
flacDownloaded="false"
mp3Downloaded="false"
if [ $(find "$1" -type f -iname "*.flac" | wc -l) -gt 0 ]; then
log "FLAC files found"
flacDownloaded="true"
fi
if [ $(find "$1" -type f -iname "*.mp3" | wc -l) -gt 0 ]; then
log "MP3 files found"
mp3Downloaded="true"
fi
if [ "$flacDownloaded" == "true" ]; then
if [ "$mp3Downloaded" == "true" ]; then
log "Deleting duplicate MP3 files.."
find "$1" -type f -iname "*.mp3" -delete
fi
fi
}
detectsinglefilealbums () {
if [ $(find "$1" -type f -regex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" -size +${MaxFileSize} | wc -l) -gt 0 ]; then
log "ERROR: Non split album detected"
exit 1
fi
}
verify () {
if [ $(find "$1" -iname "*.flac" | wc -l) -gt 0 ]; then
verifytrackcount=$(find "$1"/ -iname "*.flac" | wc -l)
log "Verifying: $verifytrackcount Tracks"
if ! [ -x "$(command -v flac)" ]; then
log "ERROR: FLAC verification utility not installed (ubuntu: apt-get install -y flac)"
else
for fname in "$1"/*.flac; do
filename="$(basename "$fname")"
if flac -t --totally-silent "$fname"; then
log "Verified Track: $filename"
else
log "ERROR: Track Verification Failed: \"$filename\""
rm -rf "$1"/*
sleep 0.1
exit 1
fi
done
fi
fi
}
conversion () {
converttrackcount=$(find "$1"/ -name "*.flac" | wc -l)
targetformat="$ConversionFormat"
bitrate="$ConversionBitrate"
if [ "${ConversionFormat}" = OPUS ]; then
options="-acodec libopus -ab ${bitrate}k -application audio -vbr off"
extension="opus"
targetbitrate="${bitrate}k"
fi
if [ "${ConversionFormat}" = AAC ]; then
options="-acodec aac -ab ${bitrate}k -movflags faststart"
extension="m4a"
targetbitrate="${bitrate}k"
fi
if [ "${ConversionFormat}" = MP3 ]; then
options="-acodec libmp3lame -ab ${bitrate}k"
extension="mp3"
targetbitrate="${bitrate}k"
fi
if [ "${ConversionFormat}" = ALAC ]; then
options="-acodec alac -movflags faststart"
extension="m4a"
targetbitrate="lossless"
fi
if [ "${ConversionFormat}" = FLAC ]; then
options="-acodec flac"
extension="flac"
targetbitrate="lossless"
fi
if [ -x "$(command -v ffmpeg)" ]; then
if [ "${ConversionFormat}" = FLAC ]; then
sleep 0.1
elif [ $(find "$1"/ -name "*.flac" | wc -l) -gt 0 ]; then
log "Converting: $converttrackcount Tracks (Target Format: $targetformat (${targetbitrate}))"
for fname in "$1"/*.flac; do
filename="$(basename "${fname%.flac}")"
if [ "${ConversionFormat}" = OPUS ]; then
opusenc --bitrate ${bitrate} --vbr --music "$fname" "${fname%.flac}.temp.$extension";
log "Converted: $filename"
if [ -f "${fname%.flac}.temp.$extension" ]; then
rm "$fname"
sleep 0.1
mv "${fname%.flac}.temp.$extension" "${fname%.flac}.$extension"
fi
continue
else
log "Conversion failed: $filename, performing cleanup..."
rm -rf "$1"/*
sleep 0.1
exit 1
fi
if ffmpeg -loglevel warning -hide_banner -nostats -i "$fname" -n -vn $options "${fname%.flac}.temp.$extension"; then
log "Converted: $filename"
if [ -f "${fname%.flac}.temp.$extension" ]; then
rm "$fname"
sleep 0.1
mv "${fname%.flac}.temp.$extension" "${fname%.flac}.$extension"
fi
else
log "Conversion failed: $filename, performing cleanup..."
rm -rf "$1"/*
sleep 0.1
exit 1
fi
done
fi
else
log "ERROR: ffmpeg not installed, please install ffmpeg to use this conversion feature"
sleep 5
fi
}
replaygain () {
replaygaintrackcount=$(find "$1"/ -type f -regex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" | wc -l)
log "Replaygain: Calculating $replaygaintrackcount Tracks"
r128gain -r -a "$1" &>/dev/null
}
beets () {
trackcount=$(find "$1" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l)
log "Matching $trackcount tracks with Beets"
if [ -f /config/scripts/library.blb ]; then
rm /config/scripts/library.blb
sleep 0.1
fi
if [ -f /config/scripts/beets/beets.log ]; then
rm /config/scripts/beets.log
sleep 0.1
fi
touch "/config/scripts/beets-match"
sleep 0.1
if [ $(find "$1" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) -gt 0 ]; then
beet -c /config/scripts/beets-config.yaml -l /config/scripts/library.blb -d "$1" import -q "$1"
if [ $(find "$1" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -newer "/config/scripts/beets-match" | wc -l) -gt 0 ]; then
log "SUCCESS: Matched with beets!"
else
rm -rf "$1"/*
log "ERROR: Unable to match using beets to a musicbrainz release, marking download as failed..."
exit 1
fi
fi
if [ -f "/config/scripts/beets-match" ]; then
rm "/config/scripts/beets-match"
sleep 0.1
fi
}
#============START SCRIPT============
settings "$1"
clean "$1"
if [ "${DetectNonSplitAlbums}" = TRUE ]; then
detectsinglefilealbums "$1"
fi
if [ "${AudioVerification}" = TRUE ]; then
verify "$1"
fi
conversion "$1"
AudioQualityMatch "$1"
if [ "${BeetsTagging}" = TRUE ]; then
beets "$1"
fi
if [ "${ReplaygainTagging}" = TRUE ]; then
replaygain "$1"
fi
}
SECONDS=0
Main "$@"
chmod 777 "$1"
chmod 666 "$1"/*
duration=$SECONDS
echo "Post Processing Completed in $(($duration / 60 )) minutes and $(($duration % 60 )) seconds!"
exit $?

View file

@ -1,139 +0,0 @@
#!/usr/bin/with-contenv bash
ScriptVersion="1.7"
scriptName="Audiobook"
#### Import Settings
source /config/extended.conf
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $ScriptVersion :: "$1
}
if [ -z $allowM4b ]; then
allowM4b=true
fi
if [ -z $allowMp3 ]; then
allowMp3=true
fi
set -e
set -o pipefail
touch "/config/scripts/audiobook.txt"
exec &> >(tee -a "/config/scripts/audiobook.txt")
SECONDS=0
log "Processing $1"
m4bCount=$(find "$1" -type f -iname "*.m4b" | wc -l)
if [ $m4bCount -gt 1 ]; then
log "ERROR: More than 1 M4B file found, performing cleanup..."
find "$1" -type f -iname "m4b" -delete
else
log "Searching for audiobook (m4b) files in completed download..."
if [ $m4bCount -gt 0 ]; then
log "$m4bCount M4B files found, removing non m4b files..."
find "$1" -type f -not -iname "*.m4b" -delete
find "$1" -mindepth 2 -type f -exec mv "{}" "$1"/ \;
find "$1" -mindepth 1 -type d -delete
else
log "None found..."
fi
fi
mp4Count=$(find "$1" -type f -iname "*.m4b.mp4" | wc -l)
if [ $mp4Count -gt 1 ]; then
log "ERROR: More than 1 MP4 file found, performing cleanup..."
find "$1" -type f -iname "*.mp4" -delete
else
log "Searching for audiobook (m4b.mp4) files in completed download..."
if [ $mp4Count -gt 0 ]; then
log "$mp4Count M4B (m4b.mp4) files found, removing non m4b files..."
find "$1" -type f -not -iname "*.m4b.mp4" -delete
find "$1" -mindepth 2 -type f -exec mv "{}" "$1"/ \;
find "$1" -mindepth 1 -type d -delete
log "Renaming m4b.mp4 files to m4b..."
count=0
fileCount=$(find "$1" -type f -iname "*.m4b.mp4"| wc -l)
find "$1" -type f -iname "*.m4b.mp4" -print0 | while IFS= read -r -d '' file; do
count=$(($count+1))
baseFileName="${file%.*}"
fileName="$(basename "$file")"
extension="${fileName##*.}"
log "$count of $fileCount :: Processing $fileName"
if [ -f "$file" ]; then
mv "$file" "$1/${fileName%.*}"
fi
done
log "All files renamed"
else
log "None found..."
fi
fi
mp3Count=$(find "$1" -type f -iname "*.mp3" | wc -l)
if [ $mp3Count -gt 1 ]; then
log "ERROR: More than 1 MP3 file found, performing cleanup..."
find "$1" -type f -iname "*.mp3" -delete
else
log "Searching for audiobook (mp3) files in completed download..."
if [ $mp3Count -gt 0 ]; then
log "$mp3Count MP3 files found, removing non mp3 files..."
find "$1" -type f -not -iname "*.mp3" -delete
find "$1" -mindepth 2 -type f -exec mv "{}" "$1"/ \;
find "$1" -mindepth 1 -type d -delete
else
log "None found..."
fi
fi
error="false"
bookfound="false"
m4bCount=$(find "$1" -type f -iname "*.m4b" | wc -l)
mp3Count=$(find "$1" -type f -iname "*.mp3" | wc -l)
#log "$m4bCount m4bs found :: $mp3Count mp3s found"
if [ "$bookfound" == "false" ]; then
if [ $m4bCount -eq 0 ]; then
error="true"
else
bookfound="true"
error="false"
fi
fi
if [ "$bookfound" == "false" ]; then
if [ $mp3Count -eq 0 ]; then
error="true"
else
bookfound="true"
error="false"
fi
fi
if [ "$allowM4b" != "true" ]; then
if [ $allowM4b -gt 0 ]; then
log "M4B's disabled via config file, performing cleanup..."
rm "$1"/*
error="true"
fi
fi
if [ "$allowMp3" != "true" ]; then
if [ $mp3Count -gt 0 ]; then
log "MP3's disabled via config file, performing cleanup..."
rm "$1"/*
error="true"
fi
fi
if [ "$error" == "true" ]; then
echo "ERROR: No audiobook files found" && exit 1
fi
chmod 777 "$1"
chmod 666 "$1"/*
duration=$SECONDS
echo "Post Processing Completed in $(($duration / 60 )) minutes and $(($duration % 60 )) seconds!"
exit

View file

@ -1,69 +0,0 @@
plugins: embedart
art_filename: folder
threaded: no
per_disc_numbering: yes
id3v23: no
asciify_paths: true
match:
strong_rec_thresh: 0.10 # 0.04
medium_rec_thresh: 0.25 # 0.25
rec_gap_thresh: 0.25 # 0.25
max_rec:
missing_tracks: medium # medium
unmatched_tracks: medium # medium
track_length: medium
track_index: medium
distance_weights:
source: 2.0 # 2.0
artist: 3.0 # 3.0
album: 3.0 # 3.0
media: 1.0 # 1.0
mediums: 1.0 # 1.0
year: 1.0 # 1.0
country: 0.5 # 0.5
label: 0.5 # 0.5
catalognum: 0.5 # 0.5
albumdisambig: 0.5 # 0.5
album_id: 5.0 # 5.0
tracks: 2.0 # 2.0
missing_tracks: 0.9 # 0.9
unmatched_tracks: 0.6 # 0.6
track_title: 3.0 # 3.0
track_artist: 2.0 # 2.0
track_index: 1.0 # 1.0
track_length: 2.0 # 2.0
track_id: 5.0 # 5.0
preferred:
countries: [] # []
media: [] # []
original_year: no # no
ignored: ['missing_tracks', 'track_length', 'unmatched_tracks', 'track_index'] # []
required: [] # []
ignored_media: [] # []
ignore_data_tracks: yes # yes
ignore_video_tracks: yes # yes
track_length_grace: 10 # 10
track_length_max: 30 # 30
paths:
default: $disc$track - $title
singleton: $disc$track - $title
comp: $disc$track - $title
albumtype_soundtrack: $disc$track - $title
import:
write: yes
copy: no
move: no
resume: ask
incremental: no
quiet_fallback: skip
timid: no
duplicate_action: skip
log: /config/scripts/beets.log
languages: ['en']
group_albums: no
embedart:
auto: no

View file

@ -1,30 +0,0 @@
##### SABNZBD EXTENDED SETTINGS #####
##### VIDEO SCRIPT
videoLanguages="eng" # Default: eng :: Set to required language (this is a "," separated list of ISO 639-2 language codes)
requireLanguageMatch="true" # true = enabled, disables/enables checking video audio/subtitle language based on VIDEO_LANG setting
enableSma="true" # true = Enabled :: Uses SMA to process incoming video files
enableSmaTagging="false" # true = Enabled :: Uses SMA to Tag MP4 files (Enabled SMA process: manual.py -a; Disabled SMA Process: manual.py -nt)
AudioVerification="TRUE" # TRUE = ENABLED, Verifies FLAC/MP3 files for errors (fixes MP3's, deletes bad FLAC files)
##### SMA ARR APP CONNECTIONS for TAGGING
radarrArrUrl="" # Set category in SABnzbd to: radarr
radarrArrApiKey="" # Set category in SABnzbd to: radarr
radarr4kArrUrl="" # Set category in SABnzbd to: radarr4k
radarr4kArrApiKey="" # Set category in SABnzbd to: radarr4k
sonarrArrUrl="" # Set category in SABnzbd to: sonarr
sonarrArrApiKey="" # Set category in SABnzbd to: sonarr
sonarr4kArrUrl="" # Set category in SABnzbd to: sonarr4k
sonarr4kArrApiKey="" # Set category in SABnzbd to: sonarr4k
##### AUDIO SCRIPT
ConversionFormat="FLAC" # SET TO: OPUS or AAC or MP3 or ALAC or FLAC - converts lossless FLAC files to set format
ConversionBitrate="160" # Set to desired bitrate when converting to OPUS/AAC/MP3 format types
ReplaygainTagging="false" # TRUE = ENABLED, adds replaygain tags for compatible players (FLAC ONLY)
BeetsTagging="TRUE" # TRUE = ENABLED, enables tagging with beets
DetectNonSplitAlbums="TRUE" # TRUE = ENABLED :: Uses "MaxFileSize" to detect and mark download as failed if detected
MaxFileSize="153600k" # M = MB, G = GB :: Set size threshold for detecting single file albums
##### AUDIOBOOK SCRIPT
allowMp3="true" # true = enabled :: Enabling this setting allows MP3 files to be downloaded for import, disabling it will cause downloads with MP3 files to fail.
allowM4b="true" # true = enabled :: Enabling this setting allows M4B files to be downloaded for import, disabling it will cause downloads with M4B files to fail.

View file

@ -1,29 +0,0 @@
# README
## Requirements
Container: [https://docs.linuxserver.io/images/docker-sabnzbd](https://docs.linuxserver.io/images/docker-sabnzbd)
## Installation/setup
1. Add volume to your container
`/custom-cont-init.d`
Docker Run Example:
`-v /path/to/preferred/local/directory:/custom-cont-init.d`
1. Download the [script_init.bash](https://github.com/RandomNinjaAtk/arr-scripts/blob/main/sabnzbd/scripts_init.bash) ([Download Link](https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sabnzbd/scripts_init.bash)) and place it into the following folder: `/custom-cont-init.d`
1. Start your container and wait for the application to load
1. Optional: Customize the configuration by modifying the following file `/config/extended.conf`
1. Add the `/config/scripts` folder to the "Scripts Folder" folder setting in SABnzbd
1. Add `video.bash` or `audio.bash` script to the appropriate SABnzbd category
## Updating
Updating is a bit more combersum. To update, do the following:
1. Download/update your local `/config/extended.conf` file with the latest options from: [extended.conf](https://github.com/RandomNinjaAtk/arr-scripts/blob/main/sabnzbd/extended.conf)
1. Restart the container, wait for it to fully load the application.
1. Restart the container again, for the new scripts to activate.
## Additional Information
For more details, visit the [Wiki](https://github.com/RandomNinjaAtk/arr-scripts/wiki)

View file

@ -1,3 +0,0 @@
#!/usr/bin/with-contenv bash
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sabnzbd/setup.bash | bash
exit

View file

@ -1,119 +0,0 @@
#!/usr/bin/with-contenv bash
scriptVersion="1.8"
######## Package dependencies installation
InstallRequirements () {
echo "Installing Required Packages..."
echo "************ install and update packages ************"
apk add -U --update --no-cache \
flac \
opus-tools \
jq \
git \
ffmpeg
apk add mp3val --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing
echo "*** install beets ***"
apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/community beets
echo "************ install python packages ************"
pip install --upgrade --no-cache-dir --break-system-packages -U \
m4b-merge \
pyacoustid \
requests \
pylast \
mutagen \
r128gain
echo "Done"
if [ -d /config/scripts/sma ]; then
rm -rf /config/scripts/sma
fi
echo "************ setup SMA ************"
if [ -d "${SMA_PATH}" ]; then
rm -rf "${SMA_PATH}"
fi
echo "************ setup directory ************"
mkdir -p /config/scripts/sma
echo "************ download repo ************"
git clone https://github.com/mdhiggins/sickbeard_mp4_automator.git /config/scripts/sma
mkdir -p /config/scripts/sma/config
echo "************ create logging file ************"
mkdir -p /config/scripts/sma/config
touch /config/scripts/sma/config/sma.log
echo "************ install pip dependencies ************"
pip install --upgrade pip --no-cache-dir --break-system-packages
pip install -r /config/scripts/sma/setup/requirements.txt --no-cache-dir --break-system-packages
chmod 777 -R /config/scripts/sma
}
echo "Setup Script Version: $scriptVersion"
InstallRequirements
mkdir -p /config/scripts
chmod 777 /config/scripts
echo "Downloading SMA config: /config/scripts/sma.ini"
curl "https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sabnzbd/sma.ini" -o /config/sma.ini
if [ -f /config/sma.ini ]; then
if [ ! -f /config/scripts/sma.ini ]; then
echo "Importing /config/sma.ini to /config/scripts/sma.ini"
mv /config/sma.ini /config/scripts/sma.ini
chmod 777 /config/scripts/sma.ini
else
echo "File /config/scripts/sma.ini already exists. Not overwriting."
fi
fi
echo "Downloading Video script: /config/scripts/video.bash"
curl "https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sabnzbd/video.bash" -o /config/video.bash
if [ -f /config/video.bash ]; then
if [ -f /config/scripts/video.bash ]; then
echo "Removing /config/scripts/video.bash"
rm /config/scripts/video.bash
fi
echo "Importing /config/video.bash to /config/scripts/video.bash"
mv /config/video.bash /config/scripts/video.bash
chmod 777 /config/scripts/video.bash
fi
echo "Downloading Audio script: /config/scripts/audio.bash"
curl "https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sabnzbd/audio.bash" -o /config/audio.bash
if [ -f /config/audio.bash ]; then
if [ -f /config/scripts/audio.bash ]; then
echo "Removing /config/scripts/audio.bash"
rm /config/scripts/audio.bash
fi
echo "Importing /config/audio.bash to /config/scripts/audio.bash"
mv /config/audio.bash /config/scripts/audio.bash
chmod 777 /config/scripts/audio.bash
fi
echo "Downloading Audio script: /config/scripts/beets-config.yaml"
curl "https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sabnzbd/beets-config.yaml" -o /config/beets-config.yaml
if [ -f /config/beets-config.yaml ]; then
if [ -f /config/scripts/beets-config.yaml ]; then
echo "Removing /config/scripts/beets-config.yaml"
rm /config/scripts/beets-config.yaml
fi
echo "Importing /config/beets-config.yaml to /config/scripts/beets-config.yaml"
mv /config/beets-config.yaml /config/scripts/beets-config.yaml
chmod 777 /config/scripts/beets-config.yaml
fi
echo "Download audiobook script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sabnzbd/audiobook.bash -o /config/scripts/audiobook.bash
echo "Done"
if [ ! -f /config/extended.conf ]; then
echo "Download Extended config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sabnzbd/extended.conf -o /config/extended.conf
chmod 777 /config/extended.conf
echo "Done"
fi
chmod 777 -R /config/scripts
if [ -f /custom-services.d/scripts_init.bash ]; then
# user misconfiguration detected, sleeping...
sleep infinity
fi
exit

View file

@ -1,270 +0,0 @@
[Converter]
ffmpeg = ffmpeg
ffprobe = ffprobe
threads = 0
hwaccels = vaapi
hwaccel-decoders = vaapi
hwdevices = /dev/dri/renderD128
hwaccel-output-format = vaapi:vaapi
output-directory =
output-format = mkv
output-extension = mkv
temp-extension =
minimum-size = 0
ignored-extensions = nfo, ds_store
copy-to =
move-to =
delete-original = True
process-same-extensions = True
bypass-if-copying-all = False
force-convert = True
post-process = False
wait-post-process = False
detailed-progress = False
opts-separator = ,
preopts = -fflags,+genpts
postopts =
regex-directory-replace = [^\w\-_\. ]
output-directory-space-ratio = 0.0
[Permissions]
chmod = 0666
uid = -1
gid = -1
[Metadata]
relocate-moov = False
full-path-guess = True
tag = True
tag-language = eng
download-artwork = thumb
sanitize-disposition =
strip-metadata = True
keep-titles = False
[Video]
codec = copy
max-bitrate = 0
bitrate-ratio =
crf = -1
crf-profiles =
preset =
codec-parameters =
dynamic-parameters = False
max-width = 0
profile =
max-level = 0.0
pix-fmt =
prioritize-source-pix-fmt = True
filter =
force-filter = False
[HDR]
codec =
pix-fmt =
space = bt2020nc
transfer = smpte2084
primaries = bt2020
preset =
codec-parameters =
filter =
force-filter = False
profile =
[Audio]
codec = copy
languages = eng
default-language =
first-stream-of-language = False
allow-language-relax = True
relax-to-default = False
channel-bitrate = 80
variable-bitrate = 0
max-bitrate = 0
max-channels = 0
filter =
profile =
force-filter = False
sample-rates =
sample-format =
copy-original = False
aac-adtstoasc = False
ignored-dispositions =
force-default = False
unique-dispositions = True
stream-codec-combinations =
include-original-language = True
[Audio.Sorting]
sorting = language, channels.d, map, d.comment
default-sorting = language, channels.d, map, d.comment
codecs =
[Universal Audio]
codec =
channel-bitrate = 128
variable-bitrate = 0
first-stream-only = true
filter =
profile =
force-filter = False
[Audio.ChannelFilters]
6-2 = pan=stereo|FL=0.5*FC+0.707*FL+0.707*BL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707*BR+0.5*LFE
[Subtitle]
codec = srt
codec-image-based = copy
languages = eng
default-language =
first-stream-of-language = False
encoding =
burn-subtitles = False
burn-dispositions =
embed-subs = True
embed-image-subs = True
embed-only-internal-subs = True
filename-dispositions = forced
ignore-embedded-subs = False
ignored-dispositions =
force-default = False
unique-dispositions = True
attachment-codec =
remove-bitstream-subs = False
include-original-language = False
[Subtitle.Sorting]
sorting = language, d.comment, d.default.d, d.forced.d
burn-sorting = language, d.comment, d.default.d, d.forced.d
codecs =
[Subtitle.CleanIt]
enabled = False
config-path =
tags =
[Subtitle.Subliminal]
download-subs = False
download-hearing-impaired-subs = False
providers =
download-forced-subs = False
include-hearing-impaired-subs = False
[Subtitle.Subliminal.Auth]
opensubtitles =
tvsubtitles =
[Sonarr]
host = localhost
port = 8989
apikey =
ssl = False
webroot =
force-rename = False
rescan = True
block-reprocess = False
in-progress-check = True
[Radarr]
host = localhost
port = 7878
apikey =
ssl = False
webroot =
force-rename = False
rescan = True
block-reprocess = False
in-progress-check = True
[Sickbeard]
host = localhost
port = 8081
ssl = False
apikey =
webroot =
username =
password =
[Sickrage]
host = localhost
port = 8081
ssl = False
apikey =
webroot =
username =
password =
[SABNZBD]
convert = True
sickbeard-category = sickbeard
sickrage-category = sickrage
sonarr-category = sonarr
radarr-category = radarr
bypass-category = bypass
output-directory =
path-mapping =
[Deluge]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
host = localhost
port = 58846
username =
password =
output-directory =
remove = False
path-mapping =
[qBittorrent]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
action-before =
action-after =
host = localhost
port = 8080
ssl = False
username =
password =
output-directory =
path-mapping =
[uTorrent]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
webui = False
action-before =
action-after =
host = localhost
ssl = False
port = 8080
username =
password =
output-directory =
path-mapping =
[Plex]
host = localhost
port = 32400
refresh = False
token =
username =
password =
servername =
ssl = True
ignore-certs = False
path-mapping =
[Subtitle.FFSubsync]
enabled = False

View file

@ -1,272 +0,0 @@
#!/bin/bash
scriptVersion="1.4"
scriptName="Video"
#### Import Settings
source /config/extended.conf
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $scriptVersion :: "$1
}
set -e
set -o pipefail
# auto-clean up log file to reduce space usage
if [ -f "/config/scripts/video.txt" ]; then
find /config/scripts -type f -name "video.txt" -size +1024k -delete
fi
touch "/config/scripts/video.txt"
exec &> >(tee -a "/config/scripts/video.txt")
function Configuration {
log "SABnzbd Job: $jobname"
log "SABnzbd Category: $category"
log "SABnzbd Download ID: $downloadId"
log "Script Versiion: $scriptVersion"
log "CONFIGURATION VERIFICATION"
log "##########################"
log "Preferred Audio/Subtitle Languages: ${videoLanguages}"
if [ "${requireLanguageMatch}" = "true" ]; then
log "Require Matching Language :: Enabled"
else
log "Require Matching Language :: Disabled"
fi
if [ ${enableSma} = true ]; then
log "Sickbeard MP4 Automator (SMA): ENABLED"
if [ ${enableSmaTagging} = true ]; then
tagging="-a"
log "Sickbeard MP4 Automator (SMA): Tagging: ENABLED"
else
tagging="-nt"
log "Sickbeard MP4 Automator (SMA): Tagging: DISABLED"
fi
else
log "Sickbeard MP4 Automator (SMA): DISABLED"
fi
if [ -z "enableSmaTagging" ]; then
enableSmaTagging=FALSE
fi
}
VideoLanguageCheck () {
count=0
fileCount=$(find "$1" -type f -regex ".*/.*\.\(m4v\|wmv\|mkv\|mp4\|avi\)" | wc -l)
log "Processing ${fileCount} video files..."
find "$1" -type f -regex ".*/.*\.\(m4v\|wmv\|mkv\|mp4\|avi\)" -print0 | while IFS= read -r -d '' file; do
count=$(($count+1))
baseFileName="${file%.*}"
fileName="$(basename "$file")"
extension="${fileName##*.}"
log "$count of $fileCount :: Processing $fileName"
videoData=$(ffprobe -v quiet -print_format json -show_streams "$file")
videoAudioTracksCount=$(echo "${videoData}" | jq -r ".streams[] | select(.codec_type==\"audio\") | .index" | wc -l)
videoSubtitleTracksCount=$(echo "${videoData}" | jq -r ".streams[] | select(.codec_type==\"subtitle\") | .index" | wc -l)
log "$count of $fileCount :: $videoAudioTracksCount Audio Tracks Found!"
log "$count of $fileCount :: $videoSubtitleTracksCount Subtitle Tracks Found!"
videoAudioLanguages=$(echo "${videoData}" | jq -r ".streams[] | select(.codec_type==\"audio\") | .tags.language")
videoSubtitleLanguages=$(echo "${videoData}" | jq -r ".streams[] | select(.codec_type==\"subtitle\") | .tags.language")
# Language Check
log "$count of $fileCount :: Checking for preferred languages \"$videoLanguages\""
preferredLanguage=false
IFS=',' read -r -a filters <<< "$videoLanguages"
for filter in "${filters[@]}"
do
videoAudioTracksLanguageCount=$(echo "${videoData}" | jq -r ".streams[] | select(.codec_type==\"audio\") | select(.tags.language==\"${filter}\") | .index" | wc -l)
videoSubtitleTracksLanguageCount=$(echo "${videoData}" | jq -r ".streams[] | select(.codec_type==\"subtitle\") | select(.tags.language==\"${filter}\") | .index" | wc -l)
log "$count of $fileCount :: $videoAudioTracksLanguageCount \"$filter\" Audio Tracks Found!"
log "$count of $fileCount :: $videoSubtitleTracksLanguageCount \"$filter\" Subtitle Tracks Found!"
if [ "$preferredLanguage" == "false" ]; then
if echo "$videoAudioLanguages" | grep -i "$filter" | read; then
preferredLanguage=true
elif echo "$videoSubtitleLanguages" | grep -i "$filter" | read; then
preferredLanguage=true
fi
fi
done
if [ "$preferredLanguage" == "false" ]; then
if [ ${enableSma} = true ]; then
if [ "$smaProcessComplete" == "false" ]; then
return
fi
fi
if [ "$requireLanguageMatch" == "true" ]; then
log "$count of $fileCount :: ERROR :: No matching languages found in $(($videoAudioTracksCount + $videoSubtitleTracksCount)) Audio/Subtitle tracks"
log "$count of $fileCount :: ERROR :: Disable "
rm "$file" && log "INFO: deleted: $fileName"
fi
fi
log "$count of $fileCount :: Processing complete for: ${fileName}!"
done
}
VideoFileCheck () {
# check for video files
if find "$1" -type f -regex ".*/.*\.\(m4v\|wmv\|mkv\|mp4\|avi\)" | read; then
sleep 0.1
else
log "ERROR: No video files found for processing"
exit 1
fi
}
ArrWaitForTaskCompletion () {
alerted=no
until false
do
taskCount=$(curl -s "$arrUrl/api/v3/command?apikey=${arrApiKey}" | jq -r '.[] | select(.status=="started") | .name' | wc -l)
if [ "$taskCount" -ge "1" ]; then
if [ "$alerted" == "no" ]; then
alerted=yes
log "$count of $fileCount :: STATUS :: ARR APP BUSY :: Pausing/waiting for all active Arr app tasks to end..."
fi
sleep 2
else
break
fi
done
}
VideoSmaProcess (){
count=0
fileCount=$(find "$1" -type f -regex ".*/.*\.\(m4v\|wmv\|mkv\|mp4\|avi\)" | wc -l)
log "Processing ${fileCount} video files..."
find "$1" -type f -regex ".*/.*\.\(m4v\|wmv\|mkv\|mp4\|avi\)" -print0 | while IFS= read -r -d '' file; do
count=$(($count+1))
baseFileName="${file%.*}"
fileName="$(basename "$file")"
extension="${fileName##*.}"
log "$count of $fileCount :: Processing $fileName"
if [ -f "$file" ]; then
if [ -f /config/scripts/sma/config/sma.log ]; then
rm /config/scripts/sma/config/sma.log
fi
log "$count of $fileCount :: Processing with SMA..."
if [ -f "/config/scripts/sma.ini" ]; then
if [ ${enableSmaTagging} = true ]; then
arrItemId=""
arrItemData=""
arrUrl=""
arrApiKey=""
log "$count of $fileCount :: Getting Media ID"
if echo $category | grep radarr | read; then
if echo $category | grep radarr4k | read; then
arrUrl="$radarr4kArrUrl"
arrApiKey="$radarr4kArrApiKey"
else
arrUrl="$radarrArrUrl"
arrApiKey="$radarrArrApiKey"
fi
log "$count of $fileCount :: Refreshing Radarr app Queue"
refreshQueue=$(curl -s "$arrUrl/api/v3/command" -X POST -H 'Content-Type: application/json' -H "X-Api-Key: $arrApiKey" --data-raw '{"name":"RefreshMonitoredDownloads"}')
ArrWaitForTaskCompletion
arrItemId=$(curl -s "$arrUrl/api/v3/queue?page=1&pageSize=50&sortDirection=ascending&sortKey=timeleft&includeUnknownMovieItems=true&apikey=$arrApiKey" | jq -r --arg id "$downloadId" '.records[] | select(.downloadId==$id) | .movieId')
arrItemData=$(curl -s "$arrUrl/api/v3/movie/$arrItemId?apikey=$arrApiKey")
onlineSourceId="$(echo "$arrItemData" | jq -r ".tmdbId")"
log "$count of $fileCount :: Radarr Movie ID = $arrItemId"
log "$count of $fileCount :: TMDB ID = $onlineSourceId"
onlineData="-tmdb $onlineSourceId"
fi
if echo $category | grep sonarr | read; then
if echo $category | grep sonarr4k | read; then
arrUrl="$sonarr4kArrUrl"
arrApiKey="$sonarr4kArrApiKey"
else
arrUrl="$sonarrArrUrl"
arrApiKey="$sonarrArrApiKey"
fi
log "$count of $fileCount :: Refreshing Sonarr app Queue"
refreshQueue=$(curl -s "$arrUrl/api/v3/command" -X POST -H 'Content-Type: application/json' -H "X-Api-Key: $arrApiKey" --data-raw '{"name":"RefreshMonitoredDownloads"}')
ArrWaitForTaskCompletion
arrQueueItemData=$(curl -s "$arrUrl/api/v3/queue?page=1&pageSize=50&sortDirection=ascending&sortKey=timeleft&includeUnknownSeriesItems=true&apikey=$arrApiKey" | jq -r --arg id "$downloadId" '.records[] | select(.downloadId==$id)')
arrSeriesId="$(echo $arrQueueItemData | jq -r .seriesId)"
arrEpisodeId="$(echo $arrQueueItemData | jq -r .episodeId)"
arrSeriesData=$(curl -s "$arrUrl/api/v3/series/$arrSeriesId?apikey=$arrApiKey")
arrEpisodeData=$(curl -s "$arrUrl/api/v3/episode/$arrEpisodeId?apikey=$arrApiKey")
onlineSourceId="$(echo "$arrSeriesData" | jq -r ".tvdbId")"
seasonNumber="$(echo "$arrEpisodeData" | jq -r ".seasonNumber")"
episodeNumber="$(echo "$arrEpisodeData" | jq -r ".episodeNumber")"
log "$count of $fileCount :: Sonarr Show ID = $arrSeriesId"
log "$count of $fileCount :: TVDB ID = $onlineSourceId"
onlineSource="-tvdb"
onlineData="-tvdb $onlineSourceId -s $seasonNumber -e $episodeNumber"
fi
else
onlineSourceId=""
onlineData=""
fi
# Manual run of Sickbeard MP4 Automator
if python3 /config/scripts/sma/manual.py --config "/config/scripts/sma.ini" -i "$file" $tagging $onlineData; then
log "$count of $fileCount :: Complete!"
else
log "$count of $fileCount :: ERROR :: SMA Processing Error"
rm "$file" && log "INFO: deleted: $fileName"
fi
else
log "$count of $fileCount :: ERROR :: SMA Processing Error"
log "$count of $fileCount :: ERROR :: \"/config/scripts/sma.ini\" configuration file is missing..."
rm "$file" && log "INFO: deleted: $fileName"
fi
fi
done
smaProcessComplete="true"
}
function Main {
SECONDS=0
error=0
folderpath="$1"
jobname="$3"
category="$5"
smaProcessComplete="false"
downloadId="$SAB_NZO_ID"
if [ "$category" == "radarr" ]; then
arrUrl="$radarrArrUrl"
arrApiKey="$radarrArrApiKey"
fi
if [ "$category" == "radarr4k" ]; then
arrUrl="$radarr4kArrUrl"
arrApiKey="$radarr4kArrApiKey"
fi
if [ "$category" == "sonarr" ]; then
arrUrl="$sonarrArrUrl"
arrApiKey="$sonarrArrApiKey"
fi
if [ "$category" == "sonarr4k" ]; then
arrUrl="$sonarr4kArrUrl"
arrApiKey="$sonarr4kArrApiKey"
fi
Configuration
VideoFileCheck "$folderpath"
VideoLanguageCheck "$folderpath"
VideoFileCheck "$folderpath"
if [ ${enableSma} = true ]; then
VideoSmaProcess "$folderpath" "$category"
fi
VideoFileCheck "$folderpath"
VideoLanguageCheck "$folderpath"
VideoFileCheck "$folderpath"
duration=$SECONDS
echo "Post Processing Completed in $(($duration / 60 )) minutes and $(($duration % 60 )) seconds!"
}
Main "$@"
exit $?

View file

@ -1,119 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.8"
scriptName="AutoConfig"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
if [ "$enableAutoConfig" != "true" ]; then
log "Script is not enabled, enable by setting enableAutoConfig to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
getArrAppInfo
verifyApiAccess
if [ -f /config/extended/naming.json ]; then
log "Using custom Sonarr Naming (/config/extended/naming.json)..."
namingJson=$(cat /config/extended/naming.json)
else
log "Getting Trash Guide Recommended Naming..."
namingJson=$(curl -s "https://raw.githubusercontent.com/TRaSH-/Guides/master/docs/json/sonarr/naming/sonarr-naming.json")
fi
standardNaming=$(echo "$namingJson" | jq -r '.episodes.standard."default:4"')
dailyNaming=$(echo "$namingJson" | jq -r '.episodes.daily."default:4"')
animeNaming=$(echo "$namingJson" | jq -r '.episodes.anime."default:4"')
seriesNaming=$(echo "$namingJson" | jq -r '.series.default')
seasonNaming=$(echo "$namingJson" | jq -r '.season.default')
if [ "$configureNaming" == "true" ] || [ -z "$configureNaming" ]; then
log "Updating Sonarr File Naming..."
updateArr=$(curl -s "$arrUrl/api/v3/config/naming" -X PUT -H "Content-Type: application/json" -H "X-Api-Key: $arrApiKey" --data-raw "{
\"renameEpisodes\":true,
\"replaceIllegalCharacters\":true,
\"multiEpisodeStyle\":5,
\"standardEpisodeFormat\":\"$standardNaming\",
\"dailyEpisodeFormat\":\"$dailyNaming\",
\"animeEpisodeFormat\":\"$animeNaming\",
\"seriesFolderFormat\":\"$seriesNaming\",
\"seasonFolderFormat\":\"$seasonNaming\",
\"specialsFolderFormat\":\"$seasonNaming\",
\"includeSeriesTitle\":false,
\"includeEpisodeTitle\":false,
\"includeQuality\":false,
\"replaceSpaces\":true,
\"separator\":\" - \",
\"numberStyle\":\"S{season:00}E{episode:00}\",
\"id\":1
}")
log "Complete"
fi
if [ "$configureMediaManagement" == "true" ] || [ -z "$configureMediaManagement" ]; then
log "Updating Sonrr Media Management..."
updateArr=$(curl -s "$arrUrl/api/v3/config/mediamanagement" -X PUT -H "Content-Type: application/json" -H "X-Api-Key: $arrApiKey" --data-raw '{"autoUnmonitorPreviouslyDownloadedEpisodes":false,"recycleBin":"","recycleBinCleanupDays":7,"downloadPropersAndRepacks":"doNotPrefer","createEmptySeriesFolders":false,"deleteEmptyFolders":true,"fileDate":"utcAirDate","rescanAfterRefresh":"always","setPermissionsLinux":false,"chmodFolder":"777","chownGroup":"","episodeTitleRequired":"bulkSeasonReleases","skipFreeSpaceCheckWhenImporting":false,"minimumFreeSpaceWhenImporting":100,"copyUsingHardlinks":true,"useScriptImport":false,"scriptImportPath":"","importExtraFiles":true,"extraFileExtensions":"srt","enableMediaInfo":true,"id":1}')
log "Complete"
fi
if [ "$configureMetadataProviderSettings" == "true" ] || [ -z "$configureMetadataProviderSettings" ]; then
log "Updating Sonarr Medata Settings..."
updateArr=$(curl -s "$arrUrl/api/v3/metadata/1?" -X PUT -H "Content-Type: application/json" -H "X-Api-Key: $arrApiKey" --data-raw '{"enable":true,"name":"Kodi (XBMC) / Emby","fields":[{"name":"seriesMetadata","value":true},{"name":"seriesMetadataEpisodeGuide","value":true},{"name":"seriesMetadataUrl","value":false},{"name":"episodeMetadata","value":true},{"name":"seriesImages","value":true},{"name":"seasonImages","value":true},{"name":"episodeImages","value":true}],"implementationName":"Kodi (XBMC) / Emby","implementation":"XbmcMetadata","configContract":"XbmcMetadataSettings","infoLink":"https://wiki.servarr.com/sonarr/supported#xbmcmetadata","tags":[],"id":1}')
updateArr=$(curl -s "$arrUrl/api/v3/metadata/4?" -X PUT -H "Content-Type: application/json" -H "X-Api-Key: $arrApiKey" --data-raw '{"enable":true,"name":"Plex","fields":[{"name":"seriesPlexMatchFile","value":true}],"implementationName":"Plex","implementation":"PlexMetadata","configContract":"PlexMetadataSettings","infoLink":"https://wiki.servarr.com/sonarr/supported#plexmetadata","tags":[],"id":4}')
fi
if [ "$configureCustomScripts" == "true" ] || [ -z "$configureCustomScripts" ]; then
log "Configuring Sonarr Custom Scripts"
if curl -s "$arrUrl/api/v3/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "PlexNotify.bash" | read; then
log "PlexNotify.bash already added to Sonarr custom scripts"
else
log "Adding PlexNotify.bash to Sonarr custom scripts"
# Send a command to check file path, to prevent error with adding...
updateArr=$(curl -s "$arrUrl/api/v3/filesystem?path=%2Fconfig%2Fextended%2Fscripts%2FPlexNotify.bash&allowFoldersWithoutTrailingSlashes=true&includeFiles=true" -H "X-Api-Key: ${arrApiKey}")
# Add PlexNotify.bash
updateArr=$(curl -s "$arrUrl/api/v3/notification?" -X POST -H "Content-Type: application/json" -H "X-Api-Key: ${arrApiKey}" --data-raw '{"onGrab":false,"onDownload":true,"onUpgrade":true,"onRename":true,"onSeriesDelete":true,"onEpisodeFileDelete":true,"onEpisodeFileDeleteForUpgrade":true,"onHealthIssue":false,"onApplicationUpdate":false,"supportsOnGrab":true,"supportsOnDownload":true,"supportsOnUpgrade":true,"supportsOnRename":true,"supportsOnSeriesDelete":true,"supportsOnEpisodeFileDelete":true,"supportsOnEpisodeFileDeleteForUpgrade":true,"supportsOnHealthIssue":true,"supportsOnApplicationUpdate":true,"includeHealthWarnings":false,"name":"PlexNotify.bash","fields":[{"name":"path","value":"/config/extended/PlexNotify.bash"},{"name":"arguments"}],"implementationName":"Custom Script","implementation":"CustomScript","configContract":"CustomScriptSettings","infoLink":"https://wiki.servarr.com/sonarr/supported#customscript","message":{"message":"Testing will execute the script with the EventType set to Test, ensure your script handles this correctly","type":"warning"},"tags":[]}')
log "Complete"
fi
if curl -s "$arrUrl/api/v3/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "DailySeriesEpisodeTrimmer.bash" | read; then
log "DailySeriesEpisodeTrimmer.bash already added to Sonarr custom scripts"
else
log "Adding DailySeriesEpisodeTrimmer.bash to Sonarr custom scripts"
# Send a command to check file path, to prevent error with adding...
updateArr=$(curl -s "$arrUrl/api/v3/filesystem?path=%2Fconfig%2Fextended%2Fscripts%2FDailySeriesEpisodeTrimmer.bash&allowFoldersWithoutTrailingSlashes=true&includeFiles=true" -H "X-Api-Key: ${arrApiKey}")
# Add DailySeriesEpisodeTrimmer.bash
updateArr=$(curl -s "$arrUrl/api/v3/notification?" -X POST -H "Content-Type: application/json" -H "X-Api-Key: ${arrApiKey}" --data-raw '{"onGrab":false,"onDownload":true,"onUpgrade":true,"onRename":true,"onSeriesDelete":true,"onEpisodeFileDelete":false,"onEpisodeFileDeleteForUpgrade":false,"onHealthIssue":false,"onApplicationUpdate":false,"supportsOnGrab":true,"supportsOnDownload":true,"supportsOnUpgrade":true,"supportsOnRename":true,"supportsOnSeriesDelete":true,"supportsOnEpisodeFileDelete":true,"supportsOnEpisodeFileDeleteForUpgrade":true,"supportsOnHealthIssue":true,"supportsOnApplicationUpdate":true,"includeHealthWarnings":false,"name":"DailySeriesEpisodeTrimmer.bash","fields":[{"name":"path","value":"/config/extended/DailySeriesEpisodeTrimmer.bash"},{"name":"arguments"}],"implementationName":"Custom Script","implementation":"CustomScript","configContract":"CustomScriptSettings","infoLink":"https://wiki.servarr.com/sonarr/supported#customscript","message":{"message":"Testing will execute the script with the EventType set to Test, ensure your script handles this correctly","type":"warning"},"tags":[]}')
log "Complete"
fi
if curl -s "$arrUrl/api/v3/notification" -H "X-Api-Key: ${arrApiKey}" | jq -r .[].name | grep "Extras.bash" | read; then
log "Extras.bash already added to Sonarr custom scripts"
else
log "Adding Extras.bash to Sonarr custom scripts"
# Send a command to check file path, to prevent error with adding...
updateArr=$(curl -s "$arrUrl/api/v3/filesystem?path=%2Fconfig%2Fextended%2Fscripts%2FExtras.bash&allowFoldersWithoutTrailingSlashes=true&includeFiles=true" -H "X-Api-Key: ${arrApiKey}")
# Add Extras.bash
updateArr=$(curl -s "$arrUrl/api/v3/notification?" -X POST -H "Content-Type: application/json" -H "X-Api-Key: ${arrApiKey}" --data-raw '{"onGrab":false,"onDownload":true,"onUpgrade":true,"onRename":true,"onSeriesDelete":false,"onEpisodeFileDelete":false,"onEpisodeFileDeleteForUpgrade":false,"onHealthIssue":false,"onApplicationUpdate":false,"supportsOnGrab":true,"supportsOnDownload":true,"supportsOnUpgrade":true,"supportsOnRename":true,"supportsOnSeriesDelete":false,"supportsOnEpisodeFileDelete":true,"supportsOnEpisodeFileDeleteForUpgrade":true,"supportsOnHealthIssue":true,"supportsOnApplicationUpdate":true,"includeHealthWarnings":false,"name":"Extras.bash","fields":[{"name":"path","value":"/config/extended/Extras.bash"},{"name":"arguments"}],"implementationName":"Custom Script","implementation":"CustomScript","configContract":"CustomScriptSettings","infoLink":"https://wiki.servarr.com/sonarr/supported#customscript","message":{"message":"Testing will execute the script with the EventType set to Test, ensure your script handles this correctly","type":"warning"},"tags":[]}')
log "Complete"
fi
fi
if [ "$configureCustomFormats" == "true" ] || [ -z "$configureCustomFormats" ]; then
# Add Language: Not Original Custom Format
log "Adding Language: Not Original custom format"
updateArr=$(curl -s "$arrUrl/api/v3/customformat?" -X POST -H "Content-Type: application/json" -H "X-Api-Key: ${arrApiKey}" --data-raw '{"includeCustomFormatWhenRenaming":false,"trash_id":"guide-only","trash_score":"-10000","trash_description":"Language: Original Only","name":"Language: Not Original","specifications":[{"implementation":"LanguageSpecification","implementationName":"Language","infoLink":"https://wiki.servarr.com/sonarr/settings#custom-formats-2","negate":true,"required":false,"fields":[{"order":0,"name":"value","label":"Language","value":-2,"type":"select","advanced":false,"selectOptions":[{"value":-2,"name":"Original","order":0},{"value":0,"name":"Unknown","order":0},{"value":26,"name":"Arabic","order":0},{"value":41,"name":"Bosnian","order":0},{"value":28,"name":"Bulgarian","order":0},{"value":38,"name":"Catalan","order":0},{"value":10,"name":"Chinese","order":0},{"value":39,"name":"Croatian","order":0},{"value":25,"name":"Czech","order":0},{"value":6,"name":"Danish","order":0},{"value":7,"name":"Dutch","order":0},{"value":1,"name":"English","order":0},{"value":42,"name":"Estonian","order":0},{"value":16,"name":"Finnish","order":0},{"value":19,"name":"Flemish","order":0},{"value":2,"name":"French","order":0},{"value":4,"name":"German","order":0},{"value":20,"name":"Greek","order":0},{"value":23,"name":"Hebrew","order":0},{"value":27,"name":"Hindi","order":0},{"value":22,"name":"Hungarian","order":0},{"value":9,"name":"Icelandic","order":0},{"value":44,"name":"Indonesian","order":0},{"value":5,"name":"Italian","order":0},{"value":8,"name":"Japanese","order":0},{"value":21,"name":"Korean","order":0},{"value":36,"name":"Latvian","order":0},{"value":24,"name":"Lithuanian","order":0},{"value":45,"name":"Macedonian","order":0},{"value":29,"name":"Malayalam","order":0},{"value":15,"name":"Norwegian","order":0},{"value":37,"name":"Persian","order":0},{"value":12,"name":"Polish","order":0},{"value":18,"name":"Portuguese","order":0},{"value":33,"name":"Portuguese (Brazil)","order":0},{"value":35,"name":"Romanian","order":0},{"value":11,"name":"Russian","order":0},{"value":40,"name":"Serbian","order":0},{"value":31,"name":"Slovak","order":0},{"value":46,"name":"Slovenian","order":0},{"value":3,"name":"Spanish","order":0},{"value":34,"name":"Spanish (Latino)","order":0},{"value":14,"name":"Swedish","order":0},{"value":43,"name":"Tamil","order":0},{"value":32,"name":"Thai","order":0},{"value":17,"name":"Turkish","order":0},{"value":30,"name":"Ukrainian","order":0},{"value":13,"name":"Vietnamese","order":0}],"privacy":"normal"}],"name":"Not Original Language","id":2}]}')
log "Complete"
fi
sleep infinity
exit $?

View file

@ -1,59 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.6"
scriptName="AutoExtras"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
verifyConfig () {
if [ "$enableExtras" != "true" ]; then
log "Script is not enabled, enable by setting enableExtras to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
if [ -z "$autoExtrasScriptInterval" ]; then
autoExtrasScriptInterval="24h"
fi
}
AutoExtrasProcess () {
sonarrSeriesList=$(curl -s --header "X-Api-Key:"${arrApiKey} --request GET "$arrUrl/api/v3/series")
sonarrSeriesTotal=$(echo "${sonarrSeriesList}" | jq -r '.[].id' | wc -l)
sonarrSeriesIds=$(echo "${sonarrSeriesList}" | jq -r '.[].id')
loopCount=0
for id in $(echo $sonarrSeriesIds); do
loopCount=$(( $loopCount + 1 ))
arrSeriesData="$(echo "$sonarrSeriesList" | jq -r ".[] | select(.id==$id)")"
arrSeriesPath="$(echo "$arrSeriesData" | jq -r ".path")"
arrSeriesTitle="$(echo "$arrSeriesData" | jq -r ".title")"
if [ -d "$arrSeriesPath" ]; then
log "$loopCount of $sonarrSeriesTotal :: $id :: $arrSeriesTitle :: Processing with Extras.bash"
bash /config/extended/Extras.bash "$id"
else
log "$loopCount of $sonarrSeriesTotal :: $id :: $arrSeriesTitle :: Series folder does not exist, skipping..."
continue
fi
done
}
for (( ; ; )); do
let i++
logfileSetup
log "Script starting..."
verifyConfig
getArrAppInfo
verifyApiAccess
AutoExtrasProcess
log "Script sleeping for $autoExtrasScriptInterval..."
sleep $autoExtrasScriptInterval
done
exit

View file

@ -1,100 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.5"
scriptName="SeriesEpisodeTrimmer"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
#### Check Arr App
getArrAppInfo
verifyApiAccess
if [ "$enableDailySeriesEpisodeTrimmer" != "true" ]; then
log "Script is not enabled, enable by setting enableDailySeriesEpisodeTrimmer to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
if [ "$sonarr_eventtype" == "Test" ]; then
log "Tested"
exit 0
fi
seriesId=$sonarr_series_id
seriesData=$(curl -s "$arrUrl/api/v3/series/$seriesId?apikey=$arrApiKey")
seriesTitle=$(echo $seriesData | jq -r ".title")
seriesType=$(echo $seriesData | jq -r ".seriesType")
seriesTags=$(echo $seriesData | jq -r ".tags[]")
seriesEpisodeData=$(curl -s "$arrUrl/api/v3/episode?seriesId=$seriesId&apikey=$arrApiKey")
seriesEpisodeIds=$(echo "$seriesEpisodeData" | jq -r " . | sort_by(.airDate) | reverse | .[] | select(.hasFile==true) | .id")
seriesEpisodeIdsCount=$(echo "$seriesEpisodeIds" | wc -l)
# If sonarr series is tagged, match via tag to support series that are not considered daily
if [ -z "$sonarrSeriesEpisodeTrimmerTag" ]; then
tagMatch="false"
else
tagMatch="false"
for tagId in $seriesTags; do
tagLabel="$(curl -s "$arrUrl/api/v3/tag/$tagId?apikey=$arrApiKey" | jq -r ".label")"
if [ "$sonarrSeriesEpisodeTrimmerTag" == "$tagLabel" ]; then
tagMatch="true"
break
fi
done
fi
# Verify series is marked as "daily" type by sonarr, skip if not...
if [ $seriesType != "daily" ] && [ "$tagMatch" == "false" ]; then
log "$seriesTitle (ID:$seriesId) :: ERROR :: Series does not match TYPE: Daily or TAG: $sonarrSeriesEpisodeTrimmerTag, skipping..."
exit
fi
# If non-daily series, set maximum episode count to match latest season total episode count
if [ $seriesType != "daily" ]; then
maximumDailyEpisodes=$(echo "$seriesData" | jq -r ".seasons | sort_by(.seasonNumber) | reverse | .[].statistics.totalEpisodeCount" | head -n1)
fi
# Skip processing if less than the maximumDailyEpisodes setting were found to be downloaded
if [ $seriesEpisodeIdsCount -lt $maximumDailyEpisodes ]; then
log "$seriesTitle (ID:$seriesId) :: ERROR :: Series has not exceeded $maximumDailyEpisodes downloaded episodes ($seriesEpisodeIdsCount files found), skipping..."
exit
fi
# Begin processing "daily" series type
seriesEpisodeData=$(curl -s "$arrUrl/api/v3/episode?seriesId=$seriesId&apikey=$arrApiKey")
seriesEpisodeIds=$(echo "$seriesEpisodeData"| jq -r " . | sort_by(.airDate) | reverse | .[] | select(.hasFile==true) | .id")
processId=0
seriesRefreshRequired=false
for id in $seriesEpisodeIds; do
processId=$(( $processId + 1 ))
episodeData=$(curl -s "http://localhost:8989/api/v3/episode/$id?apikey=$arrApiKey")
episodeSeriesId=$(echo "$episodeData" | jq -r ".seriesId")
if [ $processId -gt $maximumDailyEpisodes ]; then
episodeTitle=$(echo "$episodeData" | jq -r ".title")
episodeSeasonNumber=$(echo "$episodeData" | jq -r ".seasonNumber")
episodeNumber=$(echo "$episodeData" | jq -r ".episodeNumber")
episodeAirDate=$(echo "$episodeData" | jq -r ".airDate")
episodeFileId=$(echo "$episodeData" | jq -r ".episodeFileId")
# Unmonitor downloaded episode if greater than 14 downloaded episodes
log "$seriesTitle (ID:$episodeSeriesId) :: S${episodeSeasonNumber}E${episodeNumber} :: $episodeTitle :: Unmonitored Episode ID :: $id"
umonitorEpisode=$(curl -s "$arrUrl/api/v3/episode/monitor?apikey=$arrApiKey" -X PUT -H 'Content-Type: application/json' --data-raw "{\"episodeIds\":[$id],\"monitored\":false}")
# Delete downloaded episode if greater than 14 downloaded episodes
log "$seriesTitle (ID:$episodeSeriesId) :: S${episodeSeasonNumber}E${episodeNumber} :: $episodeTitle :: Deleted File ID :: $episodeFileId"
deleteFile=$(curl -s "$arrUrl/api/v3/episodefile/$episodeFileId?apikey=$arrApiKey" -X DELETE)
seriesRefreshRequired=true
else
# Skip if less than required 14 downloaded episodes exist
log "$seriesTitle (ID:$episodeSeriesId) :: Skipping Episode ID :: $id"
fi
done
if [ "$seriesRefreshRequired" = "true" ]; then
# Refresh Series after changes
log "$seriesTitle (ID:$episodeSeriesId) :: Refresh Series"
refreshSeries=$(curl -s "$arrUrl/api/v3/command?apikey=$arrApiKey" -X POST --data-raw "{\"name\":\"RefreshSeries\",\"seriesId\":$episodeSeriesId}")
fi
exit

View file

@ -1,232 +0,0 @@
#!/usr/bin/env bash
scriptVersion="2.0"
arrEventType="$sonarr_eventtype"
arrItemId=$sonarr_series_id
tmdbApiKey="3b7751e3179f796565d88fdb2fcdf426"
autoScan="false"
updatePlex="false"
ytdlpExtraOpts="--user-agent facebookexternalhit/1.1"
scriptName="Extras"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
if [ "$enableExtras" != "true" ]; then
log "Script is not enabled, enable by setting enableExtras to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
getArrAppInfo
verifyApiAccess
if [ ! -z "$1" ]; then
arrItemId="$1"
autoScan="true"
fi
if [ "$arrEventType" == "Test" ]; then
log "Tested Successfully"
exit 0
fi
# Get series information
arrItemData=$(curl -s "$arrUrl/api/v3/series/$arrItemId?apikey=$arrApiKey")
itemTitle=$(echo "$arrItemData" | jq -r .title)
itemHasFile=$(echo "$arrItemData" | jq -r .hasFile)
itemPath="$(echo "$arrItemData" | jq -r ".path")"
imdbId="$(echo "$arrItemData" | jq -r ".imdbId")"
tmdbId=$(curl -s "https://api.themoviedb.org/3/find/$imdbId?api_key=$tmdbApiKey&external_source=imdb_id" | jq -r .tv_results[].id)
# Check if series folder path exists
if [ ! -d "$itemPath" ]; then
log "$itemTitle :: ERROR: Item Path does not exist ($itemPath), Skipping..."
exit
fi
DownloadExtras () {
# Check for cookies file
if [ -f /config/cookies.txt ]; then
cookiesFile="/config/cookies.txt"
log "$itemTitle :: Cookies File Found!"
else
log "$itemTitle :: Cookies File Not Found!"
cookiesFile=""
fi
IFS=',' read -r -a filters <<< "$extrasLanguages"
for filter in "${filters[@]}"
do
if [ "$useProxy" != "true" ]; then
tmdbVideosListData=$(curl -s "https://api.themoviedb.org/3/tv/$tmdbId/videos?api_key=$tmdbApiKey&language=$filter" | jq -r '.results[] | select(.site=="YouTube")')
else
tmdbVideosListData=$(curl -x $proxyUrl:$proxyPort --proxy-user $proxyUsername:$proxyPassword -s "https://api.themoviedb.org/3/tv/$tmdbId/videos?api_key=$tmdbApiKey&language=$filter" | jq -r '.results[] | select(.site=="YouTube")')
fi
log "$itemTitle :: Searching for \"$filter\" extras..."
if [ "$extrasType" == "all" ]; then
tmdbVideosListDataIds=$(echo "$tmdbVideosListData" | jq -r ".id")
tmdbVideosListDataIdsCount=$(echo "$tmdbVideosListData" | jq -r ".id" | wc -l)
else
tmdbVideosListDataIds=$(echo "$tmdbVideosListData" | jq -r "select(.type==\"Trailer\") | .id")
tmdbVideosListDataIdsCount=$(echo "$tmdbVideosListData" | jq -r "select(.type==\"Trailer\") | .id" | wc -l)
fi
if [ -z "$tmdbVideosListDataIds" ]; then
log "$itemTitle :: None found..."
continue
fi
if [ $tmdbVideosListDataIdsCount -le 0 ]; then
log "$itemTitle :: No Extras Found, skipping..."
exit
fi
log "$itemTitle :: $tmdbVideosListDataIdsCount Extras Found!"
i=0
for id in $(echo "$tmdbVideosListDataIds"); do
i=$(( i + 1))
tmdbExtraData="$(echo "$tmdbVideosListData" | jq -r "select(.id==\"$id\")")"
tmdbExtraTitle="$(echo "$tmdbExtraData" | jq -r .name)"
tmdbExtraTitleClean="$(echo "$tmdbExtraTitle" | sed -e "s/[^[:alpha:][:digit:]$^&_+=()'%;{},.@#]/ /g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')"
tmdbExtraKey="$(echo "$tmdbExtraData" | jq -r .key)"
tmdbExtraType="$(echo "$tmdbExtraData" | jq -r .type)"
tmdbExtraOfficial="$(echo "$tmdbExtraData" | jq -r .official)"
if [ "$tmdbExtraOfficial" != "true" ]; then
if [ "$extrasOfficialOnly" == "true" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: Not official, skipping..."
continue
fi
fi
if [ "$tmdbExtraType" == "Featurette" ]; then
extraFolderName="featurettes"
elif [ "$tmdbExtraType" == "Trailer" ]; then
extraFolderName="trailers"
elif [ "$tmdbExtraType" == "Behind the Scenes" ]; then
extraFolderName="behind the scenes"
else
extraFolderName="other"
fi
if [ ! -d "$itemPath/$extraFolderName" ]; then
mkdir -p "$itemPath/$extraFolderName"
chmod 777 "$itemPath/$extraFolderName"
fi
finalPath="$itemPath/$extraFolderName"
if [ "$extraFolderName" == "other" ]; then
finalFileName="$tmdbExtraTitleClean ($tmdbExtraType)"
else
finalFileName="$tmdbExtraTitleClean"
fi
if [ -f "$finalPath/$finalFileName.mkv" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle ($tmdbExtraKey) :: Already Downloaded, skipping..."
continue
fi
videoLanguages="$(echo "$extrasLanguages" | sed "s/-[[:alpha:]][[:alpha:]]//g")"
tempFolder="/config/extended/temp"
if [ -d "$tempFolder" ]; then
rm -rf "$tempFolder"
sleep 0.01
fi
if [ ! -d "$tempFolder" ]; then
mkdir -p "$tempFolder"
fi
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle ($tmdbExtraKey) :: Downloading (yt-dlp :: $videoFormat)..."
if [ ! -z "$cookiesFile" ]; then
yt-dlp -f "$videoFormat" --no-video-multistreams --cookies "$cookiesFile" -o "$tempFolder/$finalFileName" --write-sub --sub-lang $videoLanguages --embed-subs --merge-output-format mkv --no-mtime --geo-bypass $ytdlpExtraOpts "https://www.youtube.com/watch?v=$tmdbExtraKey" 2>&1 | tee -a /config/logs/$scriptName.txt
else
yt-dlp -f "$videoFormat" --no-video-multistreams -o "$tempFolder/$finalFileName" --write-sub --sub-lang $videoLanguages --embed-subs --merge-output-format mkv --no-mtime --geo-bypass $ytdlpExtraOpts "https://www.youtube.com/watch?v=$tmdbExtraKey" 2>&1 | tee -a /config/logs/$scriptName.txt
fi
if [ -f "$tempFolder/$finalFileName.mkv" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle ($tmdbExtraKey) :: Compete"
else
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle ($tmdbExtraKey) :: ERROR :: Download Failed"
continue
fi
if python3 /config/extended/sma/manual.py --config "/config/extended/sma.ini" -i "$tempFolder/$finalFileName.mkv" -nt; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle :: Processed with SMA..."
rm /config/extended/sma/config/*log*
else
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle :: ERROR :: SMA Processing Error"
rm "$finalPath/$finalFileName.mkv"
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle :: INFO: deleted: $tempFolder/$finalFileName.mkv"
fi
if [ -f "$tempFolder/$finalFileName.mkv" ]; then
log "$itemTitle :: $i of $tmdbVideosListDataIdsCount :: $tmdbExtraType :: $tmdbExtraTitle :: Moving file to final destination"
mv "$tempFolder/$finalFileName.mkv" "$finalPath/$finalFileName.mkv"
chmod 666 "$finalPath/$finalFileName.mkv"
if [ -d "$tempFolder" ]; then
rm -rf "$tempFolder"
fi
fi
updatePlex="true"
done
done
# Mark Series Extras Complete
if [ ! -d "/config/extended/logs/extras" ]; then
mkdir -p "/config/extended/logs/extras"
chmod 777 "/config/extended/logs/extras"
fi
log "$itemTitle :: Marking/logging as Extras downloads complete (/config/extended/logs/extras/$tmdbId)"
touch "/config/extended/logs/extras/$tmdbId"
chmod 666 "/config/extended/logs/extras/$tmdbId"
}
NotifyPlex () {
# Process item with PlexNotify.bash if plexToken is configured
if [ ! -z "$plexToken" ]; then
# Always update plex if extra is downloaded
if [ "$updatePlex" == "true" ]; then
log "$itemTitle :: Using PlexNotify.bash to update Plex...."
bash /config/extended/PlexNotify.bash "$itemPath"
exit
fi
# Do not notify plex if this script was triggered by the AutoExtras.bash and no Extras were downloaded
if [ "$autoScan" == "true" ]; then
log "$itemTitle :: Skipping plex notification, not needed...."
exit
else
log "$itemTitle :: Using PlexNotify.bash to update Plex...."
bash /config/extended/PlexNotify.bash "$itemPath"
exit
fi
fi
}
# Check if series has been previously processed
if [ -f "/config/extended/logs/extras/$tmdbId" ]; then
# Delete log file older than 7 days, to allow re-processing
find "/config/extended/logs/extras" -type f -mtime +7 -name "$tmdbId" -delete
fi
if [ -f "/config/extended/logs/extras/$tmdbId" ]; then
log "$itemTitle :: Already processed Extras, waiting 7 days to re-check..."
NotifyPlex
exit
else
DownloadExtras
NotifyPlex
fi
exit

View file

@ -1,71 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.7"
scriptName="InvalidSeriesAutoCleaner"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
#### Check Arr App
getArrAppInfo
verifyApiAccess
verifyConfig () {
if [ "$enableInvalidSeriesAutoCleaner" != "true" ]; then
log "Script is not enabled, enable by setting enableInvalidSeriesAutoCleaner to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
if [ -z "$invalidSeriesAutoCleanerScriptInterval" ]; then
invalidSeriesAutoCleanerScriptInterval="1h"
fi
}
InvalidSeriesAutoCleanerProcess () {
# Get invalid series tvdb id's
seriesTvdbId="$(curl -s --header "X-Api-Key:"$arrApiKey --request GET "$arrUrl/api/v3/health" | jq -r '.[] | select(.source=="RemovedSeriesCheck") | select(.type=="error")' | grep "message" | grep -o '[[:digit:]]*')"
if [ -z "$seriesTvdbId" ]; then
log "No invalid series (tvdbid) reported by Sonarr health check, skipping..."
return
fi
# Process each invalid series tvdb id
for tvdbId in $(echo $seriesTvdbId); do
seriesData="$(curl -s --header "X-Api-Key:"$arrApiKey --request GET "$arrUrl/api/v3/series" | jq -r ".[] | select(.tvdbId==$tvdbId)")"
seriesId="$(echo "$seriesData" | jq -r .id)"
seriesTitle="$(echo "$seriesData" | jq -r .title)"
seriesPath="$(echo "$seriesData" | jq -r .path)"
log "$seriesId :: $seriesTitle :: $seriesPath :: Removing and deleting invalid Series (tvdbId: $tvdbId) based on Sonarr Health Check error..."
# Send command to Sonarr to delete series and files
arrCommand=$(curl -s --header "X-Api-Key:"$arrApiKey --request DELETE "$arrUrl/api/v3/series/$seriesId?deleteFiles=true")
# trigger a plex scan to rmeove the deleted series
folderToScan="$(dirname "$seriesPath")"
log "Using PlexNotify.bash to update Plex.... ($folderToScan)"
bash /config/extended/PlexNotify.bash "$folderToScan" "true"
done
}
for (( ; ; )); do
let i++
logfileSetup
log "Script starting..."
verifyConfig
getArrAppInfo
verifyApiAccess
InvalidSeriesAutoCleanerProcess
log "Script sleeping for $invalidSeriesAutoCleanerScriptInterval..."
sleep $invalidSeriesAutoCleanerScriptInterval
done
exit

View file

@ -1,100 +0,0 @@
#!/usr/bin/env bash
scriptVersion="1.3"
notfidedBy="Sonarr"
arrRootFolderPath="$(dirname "$sonarr_series_path")"
arrFolderPath="$sonarr_series_path"
arrEventType="$sonarr_eventtype"
extrasPath="$1"
scriptName="PlexNotify"
#### Import Settings
source /config/extended.conf
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $scriptVersion :: "$1
}
# auto-clean up log file to reduce space usage
if [ -f "/config/logs/PlexNotify.txt" ]; then
find /config/logs -type f -name "PlexNotify.txt" -size +1024k -delete
fi
if [ ! -f "/config/logs/PlexNotify.txt" ]; then
touch "/config/logs/PlexNotify.txt"
chmod 666 "/config/logs/PlexNotify.txt"
fi
exec &> >(tee -a "/config/logs/PlexNotify.txt")
if [ "$enableExtras" == "true" ]; then
if [ -z "$extrasPath" ]; then
log "Extras script is enabled, skipping..."
exit
fi
fi
if [ ! -z "$extrasPath" ]; then
arrFolderPath="$extrasPath"
if [ "$2" == "true" ]; then
arrRootFolderPath="$extrasPath"
else
arrRootFolderPath="$(dirname "$extrasPath")"
fi
fi
if [ "$arrEventType" == "Test" ]; then
log "$notfidedBy :: Tested Successfully"
exit 0
fi
plexConnectionError () {
log "ERROR :: Cannot communicate with Plex"
log "ERROR :: Please check your plexUrl and plexToken"
log "ERROR :: Configured plexUrl \"$plexUrl\""
log "ERROR :: Configured plexToken \"$plexToken\""
log "ERROR :: Exiting..."
exit
}
# Validate connection
if curl -s "$plexUrl/?X-Plex-Token=$plexToken" | xq . &>/dev/null; then
plexVersion=$(curl -s "$plexUrl/?X-Plex-Token=$plexToken" | xq . | jq -r '.MediaContainer."@version"')
if [ "$plexVersion" == "null" ]; then
# Error out if version is null, indicates bad token
plexConnectionError
else
log "Plex Connection Established, version: $plexVersion"
fi
else
# Error out if error in curl | xq . command output
plexConnectionError
fi
plexLibraries="$(curl -s "$plexUrl/library/sections?X-Plex-Token=$plexToken")"
plexLibraryData=$(echo "$plexLibraries" | xq ".MediaContainer.Directory")
if echo "$plexLibraryData" | grep "^\[" | read; then
plexLibraryData=$(echo "$plexLibraries" | xq ".MediaContainer.Directory[]")
plexKeys=($(echo "$plexLibraries" | xq ".MediaContainer.Directory[]" | jq -r '."@key"'))
else
plexKeys=($(echo "$plexLibraries" | xq ".MediaContainer.Directory" | jq -r '."@key"'))
fi
if echo "$plexLibraryData" | grep "path" | grep "$arrRootFolderPath" | read; then
sleep 0.01
else
log "$notfidedBy :: ERROR: No Plex Library found containing path \"$arrRootFolderPath\""
log "$notfidedBy :: ERROR: Add \"$arrRootFolderPath\" as a folder to a Plex TV Library"
exit 1
fi
for key in ${!plexKeys[@]}; do
plexKey="${plexKeys[$key]}"
plexKeyData="$(echo "$plexLibraryData" | jq -r "select(.\"@key\"==\"$plexKey\")")"
if echo "$plexKeyData" | grep "path" | grep "$arrRootFolderPath" | read; then
plexFolderEncoded="$(jq -R -r @uri <<<"$arrFolderPath")"
curl -s "$plexUrl/library/sections/$plexKey/refresh?path=$plexFolderEncoded&X-Plex-Token=$plexToken"
log "$notfidedBy :: Plex Scan notification sent! ($arrFolderPath)"
fi
done
exit

View file

@ -1,150 +0,0 @@
#!/usr/bin/env bash
scriptVersion="2.1"
ytdlpExtraOpts="--user-agent facebookexternalhit/1.1"
scriptName="YoutubeSeriesDownloader"
#### Import Settings
source /config/extended.conf
#### Import Functions
source /config/extended/functions
#### Create Log File
logfileSetup
#### Check Arr App
getArrAppInfo
verifyApiAccess
verifyConfig () {
if [ "$enableYoutubeSeriesDownloader" != "true" ]; then
log "Script is not enabled, enable by setting enableYoutubeSeriesDownloader to \"true\" by modifying the \"/config/extended.conf\" config file..."
log "Sleeping (infinity)"
sleep infinity
fi
if [ -z "$youtubeSeriesDownloaderScriptInterval" ]; then
youtubeSeriesDownloaderScriptInterval="1h"
fi
}
CookiesCheck () {
# Check for cookies file
if [ -f /config/cookies.txt ]; then
cookiesFile="/config/cookies.txt"
log "Cookies File Found!"
else
log "Cookies File Not Found!"
cookiesFile=""
fi
}
NotifySonarrForImport () {
sonarrProcessIt=$(curl -s "$arrUrl/api/v3/command" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json" --data "{\"name\":\"DownloadedEpisodesScan\", \"path\":\"$1\"}")
}
SonarrTaskStatusCheck () {
alerted=no
until false
do
taskCount=$(curl -s "$arrUrl/api/v3/command?apikey=${arrApiKey}" | jq -r '.[] | select(.status=="started") | .name' | grep -v "RescanFolders" | wc -l)
if [ "$taskCount" -ge "1" ]; then
if [ "$alerted" == "no" ]; then
alerted=yes
log "STATUS :: SONARR BUSY :: Pausing/waiting for all active Sonarr tasks to end..."
fi
sleep 2
else
break
fi
done
}
YoutubeSeriesDownloaderProcess () {
CookiesCheck
sonarrSeriesList=$(curl -s --header "X-Api-Key:"${arrApiKey} --request GET "$arrUrl/api/v3/series")
sonarrSeriesIds=$(echo "${sonarrSeriesList}" | jq -r '.[] | select(.network=="YouTube") |.id')
sonarrSeriesTotal=$(echo "${sonarrSeriesIds}" | wc -l)
loopCount=0
for id in $(echo $sonarrSeriesIds); do
loopCount=$(( $loopCount + 1 ))
seriesId=$id
seriesData=$(curl -s "$arrUrl/api/v3/series/$seriesId?apikey=$arrApiKey")
seriesTitle=$(echo "$seriesData" | jq -r .title)
seriesTitleDots=$(echo "$seriesTitle" | sed s/\ /./g)
seriesTvdbTitleSlug=$(echo "$seriesData" | jq -r .titleSlug)
seriesNetwork=$(echo "$seriesData" | jq -r .network)
seriesEpisodeData=$(curl -s "$arrUrl/api/v3/episode?seriesId=$seriesId&apikey=$arrApiKey")
seriesEpisodeTvdbIds=$(echo $seriesEpisodeData | jq -r ".[] | select(.monitored==true) | select(.hasFile==false) | .tvdbId")
seriesEpisodeTvdbIdsCount=$(echo "$seriesEpisodeTvdbIds" | wc -l)
currentLoopIteration=0
for episodeId in $(echo $seriesEpisodeTvdbIds); do
currentLoopIteration=$(( $currentLoopIteration + 1 ))
seriesEpisdodeData=$(echo $seriesEpisodeData | jq -r ".[] | select(.tvdbId==$episodeId)")
episodeSeasonNumber=$(echo $seriesEpisdodeData | jq -r .seasonNumber)
episodeNumber=$(echo $seriesEpisdodeData | jq -r .episodeNumber)
tvdbPageData=$(curl -s "https://thetvdb.com/series/$seriesTvdbTitleSlug/episodes/$episodeId")
downloadUrl=$(echo "$tvdbPageData" | grep -i youtube.com | grep -i watch | grep -Eo "(http|https)://[a-zA-Z0-9./?=_%:-]*")
if [ -z $downloadUrl ]; then
network="$(echo "$tvdbPageData" | grep -i "/companies/youtube")"
if [ ! -z "$network" ]; then
downloadUrl=$(echo "$tvdbPageData" | grep -iws "production code" -A 2 | sed 's/\ //g' | tail -n1)
if [ ! -z $downloadUrl ]; then
downloadUrl="https://www.youtube.com/watch?v=$downloadUrl"
fi
fi
fi
if [ -z $downloadUrl ]; then
log "$loopCount/$sonarrSeriesTotal :: $currentLoopIteration/$seriesEpisodeTvdbIdsCount :: $seriesTitle :: S${episodeSeasonNumber}E${episodeNumber} :: ERROR :: No Download URL found, skipping"
continue
fi
downloadLocation="/config/temp"
if [ ! -d $downloadLocation ]; then
mkdir $downloadLocation
else
rm -rf $downloadLocation
mkdir $downloadLocation
fi
fileName="$seriesTitleDots.S${episodeSeasonNumber}E${episodeNumber}.WEB-DL-SonarrExtended"
log "$loopCount/$sonarrSeriesTotal :: $currentLoopIteration/$seriesEpisodeTvdbIdsCount :: $seriesTitle :: S${episodeSeasonNumber}E${episodeNumber} :: Downloading via yt-dlp ($videoFormat)..."
if [ ! -z "$cookiesFile" ]; then
yt-dlp -f "$videoFormat" --no-video-multistreams --cookies "$cookiesFile" -o "$downloadLocation/$fileName" --write-sub --sub-lang $videoLanguages --embed-subs --merge-output-format mkv --no-mtime --geo-bypass $ytdlpExtraOpts "$downloadUrl" 2>&1 | tee -a /config/logs/$logFileName
else
yt-dlp -f "$videoFormat" --no-video-multistreams -o "$downloadLocation/$fileName" --write-sub --sub-lang $videoLanguages --embed-subs --merge-output-format mkv --no-mtime --geo-bypass $ytdlpExtraOpts "$downloadUrl" 2>&1 | tee -a /config/logs/$logFileName
fi
if python3 /config/extended/sma/manual.py --config "/config/extended/sma.ini" -i "$downloadLocation/$fileName.mkv" -nt; then
sleep 0.01
log "$loopCount/$sonarrSeriesTotal :: $currentLoopIteration/$seriesEpisodeTvdbIdsCount :: $seriesTitle :: S${episodeSeasonNumber}E${episodeNumber} :: Processed with SMA..."
rm /usr/local/sma/config/*log*
else
og "$loopCount/$sonarrSeriesTotal :: $currentLoopIteration/$seriesEpisodeTvdbIdsCount :: $seriesTitle :: S${episodeSeasonNumber}E${episodeNumber} :: ERROR :: SMA Processing Error"
rm "$downloadLocation/$fileName.mkv"
log "$loopCount/$sonarrSeriesTotal :: $currentLoopIteration/$seriesEpisodeTvdbIdsCount :: $seriesTitle :: S${episodeSeasonNumber}E${episodeNumber} :: INFO: deleted: $downloadLocation/$fileName.mkv"
fi
if [ -f "$downloadLocation/$fileName.mkv" ]; then
chmod -R 777 $downloadLocation
NotifySonarrForImport "$downloadLocation/$fileName.mkv"
log "$loopCount/$sonarrSeriesTotal :: $currentLoopIteration/$seriesEpisodeTvdbIdsCount :: $seriesTitle :: S${episodeSeasonNumber}E${episodeNumber} :: Notified Sonarr to import \"$fileName.mkv\""
fi
SonarrTaskStatusCheck
done
done
}
for (( ; ; )); do
let i++
logfileSetup
log "Script starting..."
verifyConfig
getArrAppInfo
verifyApiAccess
YoutubeSeriesDownloaderProcess
log "Script sleeping for $youtubeSeriesDownloaderScriptInterval..."
sleep $youtubeSeriesDownloaderScriptInterval
done
exit

View file

@ -1,43 +0,0 @@
##### SONARR EXTENDED SCRIPTS SETTINGS #####
##### SCRIPT ENABLEMENT
enableAutoConfig="true" # true = enabled :: Enables AutoConfig script to run after startup
enableExtras="true" # true = enabled :: Enables Extras and AutoExtras scripts to run in the background and during import process
enableYoutubeSeriesDownloader="true" # true = enabled :: Enables YoutubeSeriesDownloader script to run
enableInvalidSeriesAutoCleaner="true" # true = enabled :: Enables InvalidSeriesAutoCleaner script to run
enableDailySeriesEpisodeTrimmer="true" # true = enabled :: Enables DailySeriesEpisodeTrimmer script to run
enableRecyclarr="true" # true = enabled :: Enables Recyclarr to run
enableQueueCleaner="true" # true = enabled :: Enables QueueCleaner Script that automatically removes stuck downloads that cannot be automatically imported
##### SCRIPT INTERVALS
autoExtrasScriptInterval=24h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
youtubeSeriesDownloaderScriptInterval=1h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
invalidSeriesAutoCleanerScriptInterval=1h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
recyclarrScriptInterval=6h #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
queueCleanerScriptInterval=15m #s or #m or #h or #d :: s = seconds, m = minutes, h = hours, d = days :: Amount of time between each script run, when script is enabled
##### AUTOCONFIG SCRIPT SETTINGS
configureMediaManagement="true"
configureMetadataProviderSettings="true"
configureCustomScripts="true"
configureCustomFormats="true"
configureNaming="true"
##### EXTRAS SCRIPT
extrasLanguages="en-US" # Set the desired language for Extras, all languages will be processed... (this is a "," separated list of TMDB language codes, get the code from there sites language opitons, example: en-US)
extrasType="all" # all or trailers :: all downloads all available videos (trailers, clips, featurette, etc...) :: trailers only downloads trailers
extrasOfficialOnly="false" # true = enabled :: Skips extras that are not considered/marked as Official from TMDB site.
##### DailySeriesEpisodeTrimmer SCRIPT
maximumDailyEpisodes="7" # number of episodes to keep when using DailySeriesEpisodeTrimmer script
sonarrSeriesEpisodeTrimmerTag="" # set to a single sonarr series tag (case sensitive). This allows the script to process non-daily series type series that have a matching tag.
#### YT-DLP SETTINGS
videoFormat="bestvideo*+bestaudio/best" # OPTIONAL - yt-dlp video selection paramater, do not change unless you know what your doing....
##### RECYCLARR SCRIPT
recyclarrConfig="/config/extended/recyclarr.yaml" # Change to a custom yaml file to use your own configuration, the default file is always overwritten...
##### PLEX NOTIFY SCRIPT
plexUrl="" # ONLY used if PlexNotify.bash is used, example: http://x.x.x.x:32400
plexToken="" # ONLY used if PlexNotify.bash is used

View file

@ -1,27 +0,0 @@
{
"season": {
"default": "Season {season:00}"
},
"series": {
"default": "{Series TitleYear}",
"plex": "{Series TitleYear} {imdb-{ImdbId}}",
"emby": "{Series TitleYear} [tvdbid-{TvdbId}]",
"jellyfin": "{Series TitleYear} [tvdbid-{TvdbId}]"
},
"episodes": {
"standard": {
"default:3": "{Series TitleYear} - S{season:00}E{episode:00} [{Preferred Words }{Quality Full}]{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels]}{[MediaInfo VideoCodec]}{-Release Group}",
"default:4": "{Series TitleYear} - S{season:00}E{episode:00} [{Custom Formats }{Quality Full}]{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels]}{MediaInfo AudioLanguagesAll}[{MediaInfo VideoBitDepth}bit]{[MediaInfo VideoCodec]}{MediaInfo SubtitleLanguagesAll}{-Release Group}",
"original": "{Original Title}"
},
"daily": {
"default:3": "{Series TitleYear} - {Air-Date} [{Preferred Words }{Quality Full}]{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels]}{[MediaInfo VideoCodec]}{-Release Group}",
"default:4": "{Series TitleYear} - {Air-Date} [{Custom Formats }{Quality Full}]{[MediaInfo VideoDynamicRangeType]}{[Mediainfo AudioCodec}{ Mediainfo AudioChannels]}{MediaInfo AudioLanguagesAll}[{MediaInfo VideoBitDepth}bit]{[MediaInfo VideoCodec]}{MediaInfo SubtitleLanguagesAll}{-Release Group}",
"original": "{Original Title}"
},
"anime": {
"default:3": "{Series TitleYear} - S{season:00}E{episode:00} - {absolute:000} [{Preferred Words }{Quality Full}]{[MediaInfo VideoDynamicRangeType]}[{MediaInfo VideoBitDepth}bit]{[MediaInfo VideoCodec]}[{Mediainfo AudioCodec} { Mediainfo AudioChannels}]{MediaInfo AudioLanguages}{-Release Group}",
"default:4": "{Series TitleYear} - S{season:00}E{episode:00} - {absolute:000} [{Custom Formats }{Quality Full}]{[MediaInfo VideoDynamicRangeType]}[{Mediainfo AudioCodec} { Mediainfo AudioChannels}]{MediaInfo AudioLanguagesAll}[{MediaInfo VideoBitDepth}bit]{[MediaInfo VideoCodec]}{MediaInfo SubtitleLanguagesAll}{-Release Group}"
}
}
}

View file

@ -1,85 +0,0 @@
# README
## Requirements
Container: <https://docs.linuxserver.io/images/docker-sonarr>
Version Tag: develop (v4 is required for some of the features)
## Installation/setup
1. Add 2 volumes to your container
`/custom-services.d` and `/custom-cont-init.d` (do not map to the same local folder...)
Docker Run Example:
`-v /path/to/preferred/local/folder-01:/custom-services.d`
`-v /path/to/preferred/local/folder-02:/custom-cont-init.d`
1. Download the [script_init.bash](https://github.com/RandomNinjaAtk/arr-scripts/blob/main/sonarr/scripts_init.bash) ([Download Link](https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/scripts_init.bash)) and place it into the following folder: `/custom-cont-init.d`
1. Start your container and wait for the application to load
1. Optional: Customize the configuration by modifying the following file `/config/extended.conf`
1. Restart the container
## Updating
Updating is a bit more combersum. To update, do the following:
1. Download/update your local `/config/extended.conf` file with the latest options from: [extended.conf](https://github.com/RandomNinjaAtk/arr-scripts/blob/main/sonarr/extended.conf)
2. Restart the container, wait for it to fully load the application.
3. Restart the container again, for the new scripts to activate.
## Uninstallation/Removal
1. Remove the 2 added volumes and delete the contents<br>
`/custom-services.d` and `/custom-cont-init.d`
1. Delete the `/config/extended.conf` file
1. Delete the `/config/extended` folder and it's contents
1. Remove any Arr app customizations manually.
## Support
[Information](https://github.com/RandomNinjaAtk/arr-scripts/tree/main?tab=readme-ov-file#support-info)
## Features
<table>
<tr>
<td><img src="https://raw.githubusercontent.com/RandomNinjaAtk/unraid-templates/master/randomninjaatk/img/sonarr.png" width="200"></td>
<td><img src="https://github.com/RandomNinjaAtk/docker-lidarr-extended/raw/main/.github/plus.png" width="100"></td>
<td><img src="https://raw.githubusercontent.com/RandomNinjaAtk/unraid-templates/master/randomninjaatk/img/amtd.png" width="200"></td>
</tr>
</table>
* Downloading TV **Trailers** and **Extras** using online sources for use in popular applications (Plex):
* Connects to Sonarr to automatically download trailers for TV Series in your existing library
* Downloads videos using yt-dlp automatically
* Names videos correctly to match Plex naming convention
* Auto Configure Sonarr with optimized settings
* Optimized file/folder naming (based on trash guides)
* Configures media management settings
* Configures metadata settings
* Daily Series Episode Trimmer
* Keep only the latest 14 episodes of a daily series
* Recyclarr built-in
* Auto configures Release Profiles + Scores
* Auto configures optimized quality definitions
* Plex Notify Script
* Reduce Plex scanning by notifying Plex the exact folder to scan
* Queue Cleaner Script
* Automatically removes downloads that have a "warning" or "failed" status that will not auto-import into Sonarr, which enables Sonarr to automatically re-search for the Title
* Youtube Series Downloader Script
* Automatically downloads and imports episodes from Youtube.com for Sonarr series that have their network set as "Youtube"
For more details, visit the [Wiki](https://github.com/RandomNinjaAtk/arr-scripts/wiki)
### Plex Example
![amvtd](https://raw.githubusercontent.com/RandomNinjaAtk/docker-amtd/master/.github/amvtd-plex-example.jpg)
## Credits
* [ffmpeg](https://ffmpeg.org/)
* [yt-dlp](https://github.com/yt-dlp/yt-dlp)
* [linuxserver/sonarr](https://github.com/linuxserver/docker-sonarr) Base docker image
* [Sonarr](https://sonarr.tv/)
* [The Movie Database](https://www.themoviedb.org/)
* [Recyclarr](https://github.com/recyclarr/recyclarr)
* Icons made by [Freepik](https://www.freepik.com/) from [Flaticon](https://www.flaticon.com)

View file

@ -1,255 +0,0 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/recyclarr/recyclarr/master/schemas/config-schema.json
# A starter config to use with Recyclarr. Most values are set to "reasonable defaults". Update the
# values below as needed for your instance. You will be required to update the API Key and URL for
# each instance you want to use.
#
# Many optional settings have been omitted to keep this template simple.
#
# For more details on the configuration, see the Configuration Reference on the wiki here:
# https://github.com/recyclarr/recyclarr/wiki/Configuration-Reference
# Configuration specific to Sonarr
sonarr:
instance1:
base_url: http://127.0.0.1:8989
api_key: arrApi
# Quality definitions from the guide to sync to Sonarr. Choice: anime, series, hybrid
quality_definition:
type: series
delete_old_custom_formats: true
replace_existing_custom_formats: True
quality_profiles:
- name: All
reset_unmatched_scores:
enabled: false
upgrade:
allowed: true
until_score: 5500
until_quality: WEB-DL (HD/UHD)
min_format_score: 10
quality_sort: top
qualities:
- name: WEB-DL (HD/UHD)
qualities:
- WEBDL-1080p
- WEBDL-2160p
- name: Other
qualities:
- Bluray-1080p
- WEBRip-1080p
- HDTV-1080p
- Bluray-2160p
- WEBRip-2160p
- HDTV-2160p
- WEBDL-720p
- Bluray-720p
- WEBRip-720p
- HDTV-720p
- WEBDL-480p
- Bluray-480p
- WEBRip-480p
- SDTV
- DVD
custom_formats:
# Custom scoring
- trash_ids:
- c9eafd50846d299b862ca9bb6ea91950 # x265
- cddfb4e32db826151d97352b8e37c648 # x264
quality_profiles:
- name: All
score: 2000
- trash_ids:
# Streaming Services
- d660701077794679fd59e8bdf4ce3a29 # AMZN
- f67c9ca88f463a48346062e8ad07713f # ATVP
- f27d46a831e6b16fa3fee2c4e5d10984 # CANAL+
- 77a7b25585c18af08f60b1547bb9b4fb # CC
- 4e9a630db98d5391aec1368a0256e2fe # CRAV
- 36b72f59f4ea20aad9316f475f2d9fbb # DCU
- 89358767a60cc28783cdc3d0be9388a4 # DSNP
- 7a235133c87f7da4c8cccceca7e3c7a6 # HBO
- a880d6abc21e7c16884f3ae393f84179 # HMAX
- f6cce30f1733d5c8194222a7507909bb # HULU
- 0ac24a2a68a9700bcb7eeca8e5cd644c # iT
- 81d1fbf600e2540cee87f3a23f9d3c1c # MAX
- d34870697c9db575f17700212167be23 # NF
- b2b980877494b560443631eb1f473867 # NLZ
- fb1a91cdc0f26f7ca0696e0e95274645 # OViD
- 1656adc6d7bb2c8cca6acfb6592db421 # PCOK
- c67a75ae4a1715f2bb4d492755ba4195 # PMTP
- 3ac5d84fce98bab1b531393e9c82f467 # QIBI
- c30d2958827d1867c73318a5a2957eb1 # RED
- b0d6195c23ae254932da00512db7e8a8 # RTBF
- 0455d6519a550dbf648c97b56e7231d2 # SALTO
- ae58039e1319178e6be73caab5c42166 # SHO
- 1efe8da11bfd74fbbcd4d8117ddb9213 # STAN
- 43b3cf48cb385cd3eac608ee6bca7f09 # UHD Streaming Boost
- d2d299244a92b8a52d4921ce3897a256 # UHD Streaming Cut
- 5d2317d99af813b6529c7ebf01c83533 # VDL
quality_profiles:
- name: All
score: 1000
- trash_ids:
- 290078c8b266272a5cc8e251b5e2eb0b # 1080p
quality_profiles:
- name: All
score: 600
- trash_ids:
- 3e2c4e748b64a1a1118e0ea3f4cf6875 # HDR
- bb019e1cd00f304f80971c965de064dc # HDR (undefined)
- 3497799d29a085e2ac2df9d468413c94 # HDR10
- a3d82cbef5039f8d295478d28a887159 # HDR10+
- 7878c33f1963fefb3d6c8657d46c2f0a # DV HDR10
# Audio Channels
- 3fbafa924f361e66fbc6187af82dfa85 # 5.1 Surround
- 9fb6d778592c293467437593ef394bf1 # 6.1 Surround
- 204c8c3e7315bb0ea81332774fa888d6 # 7.1 Surround
- a377864de6228b252d6e28962673cedd # 9.1 Surround
# Audio Advanced #1
- 4232a509ce60c4e208d13825b7c06264 # DD+ ATMOS
# Anime Optional
- 418f50b10f1907201b6cfdf881f467b7 # Anime Dual Audio
- 026d5aadd1a6b4e550b134cb6c72b3ca # Uncensored
quality_profiles:
- name: All
score: 500
- trash_ids:
# Audio Channels
- 834e534f103938853ffced4203b53e72 # 2.0 Stereo
- 42cba7e38c7947a6d1d0a62580ee6d62 # 3.0 Sound
- 1895195e84767de180653914ce207245 # 4.0 Sound
# Audio Advanced #1
- 63487786a8b01b7f20dd2bc90dd4a477 # DD+
- 1bef6c151fa35093015b0bfef18279e5 # 2160p
quality_profiles:
- name: All
score: 75
- trash_ids:
# Audio Advanced #2
- dbe00161b08a25ac6154c55f95e6318d # DD
quality_profiles:
- name: All
score: 30
- trash_ids:
# Audio Channels
- bd6dd5e043aa27ff4696a08d011c7d96 # 1.0 Mono
quality_profiles:
- name: All
score: 25
- trash_ids:
- 44e7c4de10ae50265753082e5dc76047 # Repack v3
quality_profiles:
- name: Any
score: 20
- trash_ids:
- eb3d5cc0a2be0db205fb823640db6a3c # Repack v2
quality_profiles:
- name: All
score: 15
- trash_ids:
- ec8fa7296b64e8cd390a1600981f3923 # Repack/Proper
quality_profiles:
- name: All
score: 10
- trash_ids:
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
- 3e8b714263b26f486972ee1e0fe7606c # MP3
- 30f70576671ca933adbdcfc736a69718 # PCM
- b2550eb333d27b75833e25b8c2557b38 # 10bit
- 9c14d194486c4014d422adc64092d794 # Dubs Only
- 2016d1676f5ee13a5b7257ff86ac9a93 # SDR
# Optional
- e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
- 2016d1676f5ee13a5b7257ff86ac9a93 # SDR
- 9b64dff695c2115facf1b6ea59c9bd07 # x265 (no HDR/DV)
- 1b3994c551cbb92a2c781af061f4ab44 # Scene
# Audio Advanced #1
- b6fbafa7942952a13e17e2b1152b539a # ATMOS (undefined)
- 5964f2a8b3be407d083498e4459d05d0 # DTS
- 9d00418ba386a083fbf4d58235fc37ef # DTS X
- c1a25cd67b5d2e08287c957b1eb903ec # DTS-ES
- c429417a57ea8c41d57e6990a8b0033f # DTS-HD MA
- 1808e4b9cee74e064dfae3f1db99dbfe # TrueHD
- 0d7824bb924701997f874e7ff7d4844a # TrueHD ATMOS
# Audio Advanced #2
- a50b8a0c62274a7c38b09a9619ba9d86 # AAC
- cfa5fbd8f02a86fc55d8d223d06a5e1f # DTS-HD HRA
- 851bd64e04c9374c51102be3dd9ae4cc # FLAC
- 3e8b714263b26f486972ee1e0fe7606c # MP3
- 28f6ef16d61e2d1adfce3156ed8257e3 # Opus
- 30f70576671ca933adbdcfc736a69718 # PCM
# Unwanted
- 47435ece6b99a0b477caf360e79ba0bb # x265 (HD)
quality_profiles:
- name: All
score: 5
- trash_ids:
# Misc
- 4aee45b0868229c4fbd8bad3e315f1d0 # MPEG2
- 7ba05c6e0e14e793538174c679126996 # Multi
# Optional
- 90501962793d580d011511155c97e4e5 # VP9
- 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
quality_profiles:
- name: All
score: -10
- trash_ids:
# Optional
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
- 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
- ef4963043b0987f8485bc9106f16db38 # DV (FEL)
- 9b27ab6498ec0f31a3353992e19434ca # DV (WEBDL)
- 0dad0a507451acddd754fe6dc3a7f5e7 # HDR10+ Boost
- 1bd69272e23c5e6c5b1d6c8a36fce95e # HFR
- 06d66ab109d4d2eddb2794d21526d140 # Retags
- 3bc5f395426614e155e585a2f056cdf1 # Season Pack
# Series Versions
- 3a4127d8aa781b44120d907f2cd62627 # Hybrid
- b735f09d3c025cbb7d75a5d38325b73b # Remaster
# HDR Formats
- 6d0d8de7b57e35518ac0308b0ddf404e # DV
- 1f733af03141f068a540eec352589a89 # DV HLG
- 27954b0a80aab882522a88a4d9eae1cd # DV SDR
- 17e889ce13117940092308f48b48b45b # HLG
- 2a7e3be05d3861d6df7171ec74cad727 # PQ
# Unwanted
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
# French Audio Version
- 84f0acbda9c0c9de783894fb66df25aa # FanSUB
- ea0bb4b6ba388992fad1092703b5ff7b # FastSUB
- 4721382d9ee05f1b4967a25e75072911 # French Audio
- 2f6e84efc47246ec9071e311e71c4953 # Multi-Audio
- 7982e39789f17864f57b11f1996844f4 # Multi-French
- 34789ec3caa819f087e23bbf9999daf7 # VF2
- 0ce1e39a4676c6692ce47935278dac76 # VFB
- 2c29a39a4fdfd6d258799bc4c09731b9 # VFF
- b6816a0e1d4b64bf3550ad3b74b009b6 # VFI
- 7a7f4e4f58bd1058440236d033a90b67 # VFQ
- 7ae924ee9b2f39df3283c6c0beb8a2aa # VOF
- 07a32f77690263bb9fda1842db7e273f # VOSTFR
- 82085412d9a53ba8d8e46fc624eb701d # VQ
# French Source Groups
- 44b6c964dad997577d793fd004a39224 # FR Anime FanSub
- db13a377f7afb29975ea39470434d2ef # FR Anime Tier 01
- 4e6134a384dbc0ef166234cc0e45d26d # FR Anime Tier 02
- db34d4357937fbfe89b63ba095f22155 # FR Anime Tier 03
- d844321db5e126d2e7e46152f0706532 # FR HD Bluray Tier 01
- 3ba797e5dc13af4b8d9bb25e83d90de2 # FR LQ
- b8e91cc8fb2bd96468fab74730c30d18 # FR Remux Tier 01
- 2f3422339d185eb227a324644a2fbfca # FR Scene Groups
- ddb8eaa9c85a549c50034d280539d54d # FR WEB Tier 01
- a4c51febd4d8b2a0db10a3c974f21d92 # FR WEB Tier 02
- dbfc0a4b5cb4cbd693311c4482ae9683 # FR WEB Tier 03
quality_profiles:
- name: All
score: -100000

View file

@ -1,2 +0,0 @@
#!/usr/bin/with-contenv bash
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/setup.bash | bash

View file

@ -1,126 +0,0 @@
#!/usr/bin/with-contenv bash
SMA_PATH="/usr/local/sma"
echo "************ install packages ************"
apk add -U --update --no-cache \
flac \
opus-tools \
jq \
git \
wget \
mkvtoolnix \
python3-dev \
libc-dev \
py3-pip \
gcc \
ffmpeg
echo "************ install python packages ************"
pip install --upgrade --no-cache-dir -U --break-system-packages \
excludarr \
yt-dlp \
yq
echo "************ setup SMA ************"
echo "************ setup directory ************"
if [ -d /config/extended/sma ]; then
rm -rf /config/extended/sma
fi
mkdir -p /config/extended/sma
echo "************ download repo ************"
git clone https://github.com/mdhiggins/sickbeard_mp4_automator.git /config/extended/sma
mkdir -p /config/extended/sma/config
echo "************ create logging file ************"
mkdir -p /config/extended/sma/config
touch /config/extended/sma/config/sma.log
echo "************ install pip dependencies ************"
pip install --upgrade pip --no-cache-dir --break-system-packages
pip install -r /config/extended/sma/setup/requirements.txt --no-cache-dir --break-system-packages
chmod 777 -R /config/extended/sma
echo "************ install recyclarr ************"
mkdir -p /recyclarr
architecture=$(uname -m)
if [[ "$architecture" == arm* ]] then
recyclarr_url="https://github.com/recyclarr/recyclarr/releases/latest/download/recyclarr-linux-musl-arm.tar.xz"
elif [[ "$architecture" == "aarch64" ]]; then
recyclarr_url="https://github.com/recyclarr/recyclarr/releases/latest/download/recyclarr-linux-musl-arm64.tar.xz"
else
recyclarr_url="https://github.com/recyclarr/recyclarr/releases/latest/download/recyclarr-linux-musl-x64.tar.xz"
fi
wget "$recyclarr_url" -O "/recyclarr/recyclarr.tar.xz"
tar -xf /recyclarr/recyclarr.tar.xz -C /recyclarr &>/dev/null
chmod 777 /recyclarr/recyclarr
apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/community dotnet8-runtime
mkdir -p /custom-services.d
echo "Download QueueCleaner service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/universal/services/QueueCleaner -o /custom-services.d/QueueCleaner
echo "Done"
echo "Download AutoConfig service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/AutoConfig.service -o /custom-services.d/AutoConfig
echo "Done"
echo "Download AutoExtras service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/AutoExtras.service -o /custom-services.d/AutoExtras
echo "Done"
echo "Download InvalidSeriesAutoCleaner service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/InvalidSeriesAutoCleaner.service -o /custom-services.d/InvalidSeriesAutoCleaner
echo "Done"
echo "Download YoutubeSeriesDownloader service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/YoutubeSeriesDownloader.service -o /custom-services.d/YoutubeSeriesDownloader
echo "Done"
mkdir -p /config/extended
if [ ! -f /config/extended/naming.json ]; then
echo "Download Naming script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/naming.json -o /config/extended/naming.json
echo "Done"
fi
mkdir -p /config/extended
echo "Download Script Functions..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/universal/functions.bash -o /config/extended/functions
echo "Done"
echo "Download PlexNotify script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/PlexNotify.bash -o /config/extended/PlexNotify.bash
echo "Done"
echo "Download DailySeriesEpisodeTrimmer script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/DailySeriesEpisodeTrimmer.bash -o /config/extended/DailySeriesEpisodeTrimmer.bash
echo "Done"
echo "Download Extras script..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/Extras.bash -o /config/extended/Extras.bash
echo "Done"
if [ ! -f /config/extended/sma.ini ]; then
echo "Download SMA config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/sma.ini -o /config/extended/sma.ini
echo "Done"
fi
echo "Download Recyclarr service..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/universal/services/Recyclarr -o /custom-services.d/Recyclarr
echo "Done"
if [ ! -f /config/extended/recyclarr.yaml ]; then
echo "Download Recyclarr config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/recyclarr.yaml -o /config/extended/recyclarr.yaml
echo "Done"
fi
if [ ! -f /config/extended.conf ]; then
echo "Download Extended config..."
curl https://raw.githubusercontent.com/RandomNinjaAtk/arr-scripts/main/sonarr/extended.conf -o /config/extended.conf
chmod 777 /config/extended.conf
echo "Done"
fi
chmod 777 -R /config/extended
if [ -f /custom-services.d/scripts_init.bash ]; then
# user misconfiguration detected, sleeping...
sleep infinity
fi
exit

View file

@ -1,254 +0,0 @@
[Converter]
ffmpeg = ffmpeg
ffprobe = ffprobe
threads = 0
hwaccels =
hwaccel-decoders =
hwdevices =
hwaccel-output-format =
output-directory =
output-format = mkv
output-extension = mkv
temp-extension =
minimum-size = 0
ignored-extensions = nfo, ds_store
copy-to =
move-to =
delete-original = True
process-same-extensions = True
bypass-if-copying-all = False
force-convert = True
post-process = False
wait-post-process = False
detailed-progress = False
opts-separator = ,
preopts =
postopts =
regex-directory-replace = [^\w\-_\. ]
[Permissions]
chmod = 0666
uid = -1
gid = -1
[Metadata]
relocate-moov = True
full-path-guess = True
tag = True
tag-language = eng
download-artwork = poster
sanitize-disposition =
strip-metadata = True
keep-titles = False
[Video]
codec = copy
max-bitrate = 0
bitrate-ratio =
crf = -1
crf-profiles =
preset =
codec-parameters =
dynamic-parameters = False
max-width = 0
profile =
max-level = 0.0
pix-fmt =
prioritize-source-pix-fmt = True
filter =
force-filter = False
[HDR]
codec =
pix-fmt =
space = bt2020nc
transfer = smpte2084
primaries = bt2020
preset =
codec-parameters =
filter =
force-filter = False
profile =
[Audio]
codec = copy
languages =
default-language =
first-stream-of-language = False
allow-language-relax = True
relax-to-default = False
channel-bitrate = 128
variable-bitrate = 0
max-bitrate = 0
max-channels = 0
filter =
profile =
force-filter = False
sample-rates =
sample-format =
copy-original = False
aac-adtstoasc = False
ignored-dispositions =
force-default = False
unique-dispositions = True
stream-codec-combinations =
[Audio.Sorting]
sorting = language, channels.d, map, d.comment
default-sorting = channels.d, map, d.comment
codecs =
[Universal Audio]
codec =
channel-bitrate = 128
variable-bitrate = 0
first-stream-only = False
filter =
profile =
force-filter = False
[Audio.ChannelFilters]
6-2 = pan=stereo|FL=0.5*FC+0.707*FL+0.707*BL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707*BR+0.5*LFE
[Subtitle]
codec = srt
codec-image-based = copy
languages =
default-language =
first-stream-of-language = False
encoding =
burn-subtitles = False
burn-dispositions =
embed-subs = True
embed-image-subs = True
embed-only-internal-subs = True
filename-dispositions = forced
ignore-embedded-subs = False
ignored-dispositions =
force-default = False
unique-dispositions = True
attachment-codec =
remove-bitstream-subs = False
[Subtitle.Sorting]
sorting = language, d.comment, d.default.d, d.forced.d
burn-sorting = language, d.comment, d.default.d, d.forced.d
codecs =
[Subtitle.CleanIt]
enabled = False
config-path =
tags =
[Subtitle.Subliminal]
download-subs = False
download-hearing-impaired-subs = False
providers =
[Subtitle.Subliminal.Auth]
opensubtitles =
tvsubtitles =
[Sonarr]
host = localhost
port = 8989
apikey =
ssl = False
webroot =
force-rename = False
rescan = True
block-reprocess = False
[Radarr]
host = localhost
port = 7878
apikey =
ssl = False
webroot =
force-rename = False
rescan = True
block-reprocess = False
[Sickbeard]
host = localhost
port = 8081
ssl = False
apikey =
webroot =
username =
password =
[Sickrage]
host = localhost
port = 8081
ssl = False
apikey =
webroot =
username =
password =
[SABNZBD]
convert = True
sickbeard-category = sickbeard
sickrage-category = sickrage
sonarr-category = sonarr
radarr-category = radarr
bypass-category = bypass
output-directory =
path-mapping =
[Deluge]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
host = localhost
port = 58846
username =
password =
output-directory =
remove = False
path-mapping =
[qBittorrent]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
action-before =
action-after =
host = localhost
port = 8080
ssl = False
username =
password =
output-directory =
path-mapping =
[uTorrent]
sickbeard-label = sickbeard
sickrage-label = sickrage
sonarr-label = sonarr
radarr-label = radarr
bypass-label = bypass
convert = True
webui = False
action-before =
action-after =
host = localhost
ssl = False
port = 8080
username =
password =
output-directory =
path-mapping =
[Plex]
host = localhost
port = 32400
refresh = False
token =

View file

@ -1,19 +1,6 @@
log () {
m_time=`date "+%F %T"`
echo $m_time" :: $scriptName :: $scriptVersion :: "$1
echo $m_time" :: $scriptName :: $scriptVersion :: "$1 >> "/config/logs/$logFileName"
}
logfileSetup () {
logFileName="$scriptName-$(date +"%Y_%m_%d_%I_%M_%p").txt"
# delete log files older than 5 days
find "/config/logs" -type f -iname "$scriptName-*.txt" -mtime +5 -delete
if [ ! -f "/config/logs/$logFileName" ]; then
echo "" > "/config/logs/$logFileName"
chmod 666 "/config/logs/$logFileName"
fi
m_time=$(date "+%F %T")
echo "$m_time :: $scriptName :: $1"
}
getArrAppInfo () {
@ -45,7 +32,7 @@ verifyApiAccess () {
arrApiVersion="v1"
arrApiTest="$(curl -s "$arrUrl/api/$arrApiVersion/system/status?apikey=$arrApiKey" | jq -r .instanceName)"
fi
if [ ! -z "$arrApiTest" ]; then
if [ -n "$arrApiTest" ]; then
break
else
log "$arrName is not ready, sleeping until valid response..."