├── .github └── FUNDING.yml ├── README.md ├── config ├── autoProcess.ini ├── config.yaml └── lidarr-dl-automation-config ├── external ├── FlacConversionTool.bash ├── MKVCleanup.bash ├── README.md ├── cron_lidarr_jobs.bash ├── import.bash ├── lidarr-download-automation-start.bash └── sonarr-mkv-post-process.bash ├── images ├── kodi-music-videos.png ├── mbrainz_video.png └── plex-musicvideos.png ├── lidarr-automated-downloader ├── README.md ├── config ├── config.yaml ├── docker │ ├── README.md │ ├── lidarr-automated-downloader-start.bash │ ├── lidarr-automated-installer-updater.bash │ └── lsio-automated-installer.bash └── lidarr-automated-downloader.bash ├── lso_docker_ubuntu ├── README.md ├── audio_tools_install.bash ├── ffmpeg_install.bash ├── lidarr_dl_auto_installer.bash ├── mp4-automated-installer.bash ├── sabnzbd_script_setup.bash └── updaters │ ├── lidarr-dl-automated-updates.bash │ ├── mp4-automator-automated-updates.bash │ └── sabnzbd_scripts_auto_update.bash └── sabnzbd ├── AudioPostProcessing.bash ├── MKV-Cleaner.bash ├── README.md ├── mp4-video-processing.bash └── video-processing.bash /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [RandomNinjaAtk] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | 3 | This repository is now deprecated, will no longer be updated/supported. The various scripts in this repository were incorperated into many of the custom containers that I provide, such as: 4 | * [https://github.com/RandomNinjaAtk/docker-sabnzbd-extended](https://github.com/RandomNinjaAtk/docker-sabnzbd-extended) 5 | * [https://github.com/RandomNinjaAtk/docker-radarr-extended](https://github.com/RandomNinjaAtk/docker-radarr-extended) 6 | * [https://github.com/RandomNinjaAtk/docker-sonarr-extended](https://github.com/RandomNinjaAtk/docker-sonarr-extended) 7 | * [https://github.com/RandomNinjaAtk/docker-lidarr-extended](https://github.com/RandomNinjaAtk/docker-lidarr-extended) 8 | 9 |
10 |
11 | 12 | # Scripts 13 | This is a collection of bash linux scripts to be used with various docker containers and other tools 14 | 15 | ## Script Folders 16 | * **external** - Scripts that are designed to be run via the host CLI 17 | * **lso_docker_ubuntu** - Scripts that are designed to be added to linuxserver.io ubuntu dockers for installing additional software 18 | * **sabnzbd** - Scripts that are designed to be added to Sabnzbd application as a post-processing script 19 | -------------------------------------------------------------------------------- /config/autoProcess.ini: -------------------------------------------------------------------------------- 1 | [SickBeard] 2 | host = localhost 3 | port = 8081 4 | username = 5 | password = 6 | web_root = 7 | ssl = False 8 | api_key = 9 | 10 | [Sonarr] 11 | host = 127.0.0.1 12 | port = 8989 13 | web_root = 14 | ssl = False 15 | apikey = sonarrkey 16 | 17 | [Radarr] 18 | host = 127.0.0.1 19 | port = 7878 20 | web_root = 21 | ssl = False 22 | apikey = radarrkey 23 | 24 | [MP4] 25 | ffmpeg = ffmpeg 26 | ffprobe = ffprobe 27 | threads = 0 28 | output_directory = 29 | copy_to = 30 | move_to = 31 | output_extension = mkv 32 | output_format = mkv 33 | delete_original = True 34 | relocate_moov = True 35 | video-codec = h264,x264,h265,x265,hevc,avc 36 | video-bitrate = 37 | video-crf = 38 | video-max-width = 39 | video-profile = 40 | h264-max-level = 41 | use-qsv-decoder-with-encoder = False 42 | use-hevc-qsv-decoder = False 43 | enable_dxva2_gpu_decode = False 44 | ios-audio = False 45 | ios-first-track-only = True 46 | ios-audio-filter = 47 | ios-move-last = False 48 | max-audio-channels = 8 49 | audio-codec = eac3,ac3,opus,aac,mp3 50 | ignore-truehd = False 51 | audio-language = eng 52 | audio-default-language = eng 53 | audio-channel-bitrate = 54 | audio-filter = 55 | audio-copy-original = False 56 | audio-first-track-of-language = False 57 | allow-audio-language-relax = True 58 | subtitle-codec = srt 59 | subtitle-codec-image-based = pgs 60 | subtitle-language = eng 61 | subtitle-default-language = eng 62 | subtitle-encoding = 63 | fullpathguess = True 64 | process-same-extensions = True 65 | force-convert = True 66 | tagfile = True 67 | tag-language = eng 68 | download-artwork = Poster 69 | download-subs = False 70 | embed-subs = True 71 | embed-only-internal-subs = False 72 | sub-providers = 73 | post-process = False 74 | pix-fmt = 75 | aac_adtstoasc = False 76 | sort-streams = True 77 | prefer-more-channels = True 78 | 79 | [CouchPotato] 80 | host = localhost 81 | port = 5050 82 | username = 83 | password = 84 | web_root = 85 | ssl = False 86 | apikey = 87 | delay = 65 88 | method = renamer 89 | delete_failed = False 90 | 91 | [uTorrent] 92 | convert = 93 | couchpotato-label = couchpotato 94 | sickbeard-label = sickbeard 95 | sonarr-label = sonarr 96 | bypass-label = bypass 97 | sickrage-label = sickrage 98 | webui = False 99 | action_before = stop 100 | action_after = removedata 101 | host = http://localhost:8080/ 102 | username = 103 | password = 104 | output_directory = 105 | 106 | [qBittorrent] 107 | convert = 108 | couchpotato-label = couchpotato 109 | sickbeard-label = sickbeard 110 | sonarr-label = sonarr 111 | bypass-label = bypass 112 | sickrage-label = sickrage 113 | action_before = pause 114 | action_after = resume 115 | host = http://localhost:8080/ 116 | username = 117 | password = 118 | output_directory = 119 | 120 | [Deluge] 121 | host = localhost 122 | username = 123 | convert = True 124 | password = 125 | sonarr-label = sonarr 126 | bypass-label = bypass 127 | sickbeard-label = sickbeard 128 | port = 58846 129 | sickrage-label = sickrage 130 | couchpotato-label = couchpotato 131 | output_directory = 132 | remove = false 133 | 134 | [SABNZBD] 135 | convert = True 136 | sickrage-category = sickrage 137 | sonarr-category = sonarr 138 | radarr-category = radarr 139 | bypass-category = bypass 140 | couchpotato-category = couchpotato 141 | sickbeard-category = sickbeard 142 | output_directory = 143 | 144 | [Sickrage] 145 | host = localhost 146 | port = 8081 147 | username = 148 | password = 149 | web_root = 150 | ssl = False 151 | api_key = 152 | 153 | [Plex] 154 | host = localhost 155 | port = 32400 156 | refresh = True 157 | token = 158 | 159 | [Permissions] 160 | chmod = 0755 161 | uid = -1 162 | gid = -1 163 | -------------------------------------------------------------------------------- /config/config.yaml: -------------------------------------------------------------------------------- 1 | plugins: chroma embedart 2 | library: /config/scripts/beets/library.blb 3 | art_filename: folder 4 | threaded: no 5 | per_disc_numbering: yes 6 | id3v23: no 7 | asciify_paths: true 8 | 9 | match: 10 | strong_rec_thresh: 0.10 # 0.04 11 | medium_rec_thresh: 0.25 # 0.25 12 | rec_gap_thresh: 0.25 # 0.25 13 | max_rec: 14 | missing_tracks: medium # medium 15 | unmatched_tracks: medium # medium 16 | track_length: medium 17 | mediums: medium 18 | year: medium 19 | media: medium 20 | distance_weights: 21 | source: 2.0 # 2.0 22 | artist: 3.0 # 3.0 23 | album: 3.0 # 3.0 24 | media: 9.0 # 1.0 25 | mediums: 9.0 # 1.0 26 | year: 9.0 # 1.0 27 | country: 0.5 # 0.5 28 | label: 0.5 # 0.5 29 | catalognum: 0.5 # 0.5 30 | albumdisambig: 0.5 # 0.5 31 | album_id: 5.0 # 5.0 32 | tracks: 2.0 # 2.0 33 | missing_tracks: 9.0 # 0.9 34 | unmatched_tracks: 9.0 # 0.6 35 | track_title: 3.0 # 3.0 36 | track_artist: 2.0 # 2.0 37 | track_index: 1.0 # 1.0 38 | track_length: 9.0 # 2.0 39 | track_id: 5.0 # 5.0 40 | preferred: 41 | countries: [] # [] 42 | media: ['CD|Digital Media'] # [] 43 | original_year: no # no 44 | ignored: ['missing_tracks', 'track_length', 'unmatched_tracks', 'mediums', 'year', 'media'] # [] 45 | required: ['year', 'album', 'artist'] # [] 46 | ignored_media: [] # [] 47 | ignore_data_tracks: yes # yes 48 | ignore_video_tracks: yes # yes 49 | track_length_grace: 1 # 10 50 | track_length_max: 1 # 30 51 | 52 | paths: 53 | default: $disc$track - $title 54 | singleton: $disc$track - $title 55 | comp: $disc$track - $title 56 | albumtype_soundtrack: $disc$track - $title 57 | 58 | import: 59 | write: yes 60 | copy: no 61 | move: no 62 | resume: ask 63 | incremental: no 64 | quiet_fallback: skip 65 | timid: no 66 | duplicate_action: skip 67 | log: /config/scripts/beets/beets.log 68 | languages: ['en'] 69 | group_albums: no 70 | 71 | chroma: 72 | auto: no 73 | 74 | embedart: 75 | auto: no 76 | -------------------------------------------------------------------------------- /config/lidarr-dl-automation-config: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##################################################################################################### 3 | # Lidarr Download Automation Script # 4 | # (SMLoadr / d-fi) # 5 | # Credit: RandomNinjaAtk, Migz93 # 6 | ##################################################################################################### 7 | # Instructions # 8 | # # 9 | # 1. Configure the settings below # 10 | # 2. Rename this file to "config" (No file extension) # 11 | # 3. Execute script from linux cli with the following command: # 12 | # bash lidarr-download-automation.bash # 13 | ##################################################################################################### 14 | 15 | ######################################## PATHS CONFIGURATION ######################################## 16 | ScriptDir="/config/scripts/lidarr-download-automation" # Directory where the script and executables are stored. 17 | LogDir="/config/scripts/lidarr-download-automation/logs" # Directory where the logs are stored. 18 | DownloadDir="/downloads/deezloaderremix" # The directory where files will be downloaded to before processing. 19 | ExternalProcessDirectory="/config/scripts/lidarr-download-automation/import" # Directory that you want to move downloaded files to for processing with other scripts or applications such as Beets. 20 | EnableWSLMode="False" # Set to "True" if you're running Lidarr on windows and this script on subsystem for Linux. 21 | 22 | ####################################### LIDARR CONFIGURATION ####################################### 23 | LidarrUrl="http://127.0.0.1:8686" # Set domain or IP to your Lidarr instance including port. If using reverse proxy, do not use a trailing slash. Ensure you specify http/s. 24 | LidarrApiKey="$(grep "" /config/config.xml | sed "s/\ //;s/<\/ApiKey>//")" # Lidarr API key. 25 | 26 | ##################################### DOWNLOADER CONFIGURATION ##################################### 27 | DeezloaderRemixUrl="http://127.0.0.1:1730" # Set domain or IP to your Deezloader Remix instance including port. 28 | Quality="320" # SET TO: 128 or 320 or FLAC - Specifies the initial target download quality. 29 | LyricType="all" # SET TO: explicit or clean or all - Only downloading songs according to lyric type, applies only to artist mode (default is "all" (clean & explicit) 30 | DownloadArtistArtwork="True" # True = Enabled, downloads artist profile picture when using "artist" download mode 31 | MinArtistArtworkSize="16k" # This number is used to determine the minimum artwork size, anything smaller will be deleted 32 | KeepOnly="False" # True = ENABLED, Keeps only quality type selected above. 33 | DownloadLogName="download.log" # Log filename. 34 | ClearDownloadLog="False" # True = ENABLED, Enables duplicate downloading, disabled prevents duplicate downloads between script runs. 35 | PreviouslyDownloaded="True" # Checks Download log before downloading artist/albums to prevent downloading duplicates. 36 | 37 | ######################## DOWNLOADER RECOMMENDED FILE NAMING CONVENTIONS ############################ 38 | # Track Name Template: %disc%%number% - %title% %explicit% 39 | # Album Track Name Template: %disc%%number% - %title% %explicit% 40 | # Alubm Name Template: %artist% (%artist_id%) - %album% %explicit%(%year%) (%type%) (%album_id%) (WEB)-DREMIX 41 | 42 | ############################## DOWNLOAD POSTPROCESSING CONFIGURATION ############################### 43 | Threads="1" # Sets the maximum number of threads for multi-threaded operations, setting to "0" will use all available threads! 44 | Verification="True" # Checks FLAC files for errors, and deletes bad files. MP3 are scanned and fixed for errors in the headers. (Requires flac and mp3val to be installed) 45 | ReplaygainTagging="True" # Adds Replaygain tags to FLAC files for audio player volume leveling. (Requires flac to be installed) 46 | Convert="False" # True = ENABLED, Only converts lossless FLAC files to the requested "ConversionFormat". (See next setting) 47 | ConversionFormat="FLAC" # SET TO: OPUS or AAC or MP3 or FLAC or ALAC - converts lossless FLAC files to set format. 48 | FolderPermissions="777" # SET to desired Linux folder permissions. (chmod) 49 | FilePermissions="666" # SET to desired Linux file permissions. (chmod) 50 | 51 | ####################################### SCRIPT CONFIGURATION ####################################### 52 | LogName="script.log" # Log filename. 53 | SkipLogName="skipped.csv" # Logs any info if an item was skipped. 54 | CannotImport="False" # Set to True to delete files and empty folders that cannot be imported by "Lidarr" AppProcess ".lrc" & ".jpg" files. 55 | CleanStart="False" # When set to True, downloader downloads directory contents is purged on initialization. 56 | AppProcess="AllDownloads" # Specify which app to use for processing. ('Lidarr', 'External', 'AllDownloads', "None') 57 | DeDupe="True" # True = Enabled, this setting works best when used with "artist" download mode, requires using the downloader recommended file naming convention 58 | Mode="artist" # Mode to choose what to passthrough to downloader, "wanted" gets only the albums that are marked as monitored in Lidarr, "artist" will just passthrough the artist. (wanted,artist) 59 | WantedModeType="missing" # "missing" or "cutoff" = "missing" has client search for missing albums, "cutoff" has client search for albums not meeting quality cutoff (ie: upgrade mp3 to flac, based on lidarr settings) 60 | 61 | #################################### "wanted" MODE CONFIGURATION ################################### 62 | WantedAlbumsAmount="1000000000" # The amount of wanted albums to process it will grab the newest x amount of albums from the Lidarr wanted list. (Maximum setting: 1000000000) 63 | EnableFuzzyAlbumSearch="True" # Set to "True" to enable fuzzy album search if no exact match found. 64 | 65 | ###################################### AppProcess DESCRIPTIONS ###################################### 66 | # Lidarr = Send individual notifications to Lidarr to import albums, albums are scanned by Lidarr and if matched, imported. 67 | # External = Moves downloaded files to a specified directory. 68 | # AllDownloads = Moves all downloads into the corresponding Lidarr Artist folder and notifies Lidarr to rescan Artist directory. (Recommended for "artist" mode) 69 | # None = No processing of completed downloads. 70 | -------------------------------------------------------------------------------- /external/FlacConversionTool.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################ FLAC CONVERSION TOOL ################ 3 | 4 | ############ Usage 5 | # Execute via CLI using the following command: bash FlacConversionTool.bash "/path/to/starting/directory" 6 | # Replace "/path/to/starting/directory" with the path to your starting directory 7 | 8 | ############ Requirements 9 | # Software Packages: 10 | # ffmpeg 11 | # find 12 | 13 | ############ Settings 14 | ConversionFormat="MP3" # SET TO: OPUS or AAC or MP3 or ALAC or FLAC - converts lossless FLAC files to set format 15 | ConversionBitrate="320" # Set to desired bitrate when converting to OPUS/AAC/MP3 format types 16 | 17 | ################ Script Start 18 | 19 | converttrackcount=$(find "$1"/ -name "*.flac" | wc -l) 20 | targetformat="$ConversionFormat" 21 | bitrate="$ConversionBitrate" 22 | 23 | if [ "${ConversionFormat}" = OPUS ]; then 24 | options="-acodec libopus -ab ${bitrate}k -application audio" 25 | extension="opus" 26 | targetbitrate="${bitrate}k" 27 | fi 28 | 29 | if [ "${ConversionFormat}" = AAC ]; then 30 | options="-acodec aac -ab ${bitrate}k -movflags faststart" 31 | extension="m4a" 32 | targetbitrate="${bitrate}k" 33 | fi 34 | 35 | if [ "${ConversionFormat}" = MP3 ]; then 36 | options="-acodec libmp3lame -ab ${bitrate}k" 37 | extension="mp3" 38 | targetbitrate="${bitrate}k" 39 | fi 40 | 41 | if [ "${ConversionFormat}" = ALAC ]; then 42 | options="-acodec alac -movflags faststart" 43 | extension="m4a" 44 | targetbitrate="lossless" 45 | fi 46 | 47 | if [ "${ConversionFormat}" = FLAC ]; then 48 | options="-acodec flac" 49 | extension="flac" 50 | targetbitrate="lossless" 51 | fi 52 | 53 | filecount=($(find "$1" -iname "*.flac" | wc -l)) 54 | 55 | echo "Configuration:" 56 | echo "Conversion Format: $ConversionFormat" 57 | echo "Conversion Bitrate: $targetbitrate" 58 | echo "Starting Directory: $1" 59 | echo "FLAC Files to process: $filecount" 60 | echo "" 61 | sleep 5 62 | 63 | find "$1" -type f -name "*.flac" -exec bash -c ' 64 | if [ -x "$(command -v ffmpeg)" ]; then 65 | if ffmpeg -loglevel warning -hide_banner -nostats -i "$0" -n -vn $1 "${0%.flac}.temp.$2"; then 66 | echo "Converted: $0" 67 | if [ -f "${0%.flac}.temp.$2" ]; then 68 | rm "$0" 69 | sleep 0.1 70 | mv "${0%.flac}.temp.$2" "${0%.flac}.$2" 71 | fi 72 | else 73 | echo "Conversion failed: $0, performing cleanup..." 74 | echo "Deleted: $0" 75 | rm "$0" 76 | fi 77 | else 78 | echo "ERROR: ffmpeg not installed, please install ffmpeg to use this conversion feature" 79 | sleep 5 80 | fi 81 | ' {} "$options" "$extension" \; 82 | 83 | ################ Script End 84 | exit 0 85 | -------------------------------------------------------------------------------- /external/MKVCleanup.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ####################################### 3 | # MKV Audio & Subtitle Cleanup # 4 | # Bash Script # 5 | # Version 1.2.0 # 6 | ####################################### 7 | # Description: # 8 | # This script removes unwated audio # 9 | # and subtitles based on configured # 10 | # preferences... # 11 | #=============REQUIREMENTS============= 12 | # mkvtoolsnix (mkvmerge) # 13 | # jq # 14 | # ffprobe # 15 | #============CONFIGURATION============= 16 | VIDEO_MKVCLEANER=TRUE 17 | VIDEO_LANG="eng" 18 | #===============FUNCTIONS============== 19 | #check for required applications 20 | echo "" 21 | echo "==========================" 22 | echo "INFO: Begin checking for required applications" 23 | echo "CHECK: for mkvmerge utility" 24 | if [ ! -x "$(command -v mkvmerge)" ]; then 25 | echo "ERROR: mkvmerge utility not installed" 26 | exit 1 27 | else 28 | echo "SUCCESS: mkvmerge installed" 29 | fi 30 | echo "CHECK: for jq utility" 31 | if [ ! -x "$(command -v jq)" ]; then 32 | echo "ERROR: jq package not installed" 33 | exit 1 34 | else 35 | echo "SUCCESS: jq installed" 36 | fi 37 | echo "CHECK: for ffprobe utility" 38 | if [ ! -x "$(command -v ffprobe)" ]; then 39 | echo "ERROR: ffprobe package not installed" 40 | exit 1 41 | else 42 | echo "SUCCESS: ffprobe installed" 43 | fi 44 | filecount=$(find "$1" -type f -iregex ".*/.*\.\(mkv\|mp4\|avi\)" | wc -l) 45 | echo "==========================" 46 | echo "" 47 | count=0 48 | find "$1" -type f -iregex ".*/.*\.\(mkv\|mp4\|avi\)" -print0 | while IFS= read -r -d '' video; do 49 | count=$(($count+1)) 50 | echo "" 51 | echo "====================================================" 52 | filename="$(basename "$video")" 53 | echo "Begin processing $count of $filecount: $filename" 54 | echo "Checking for audio/subtitle tracks" 55 | tracks=$(mkvmerge -J "$video" ) 56 | if [ ! -z "${tracks}" ]; then 57 | # video tracks 58 | VideoTrack=$(echo "${tracks}" | jq ".tracks[] | select(.type==\"video\") | .id") 59 | VideoTrackCount=$(echo "${tracks}" | jq ".tracks[] | select(.type==\"video\") | .id" | wc -l) 60 | # video preferred language 61 | VideoTrackLanguage=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"video\") and select(.properties.language==\"${VIDEO_LANG}\")) | .id") 62 | # audio tracks 63 | AudioTracks=$(echo "${tracks}" | jq ".tracks[] | select(.type==\"audio\") | .id") 64 | AudioTracksCount=$(echo "${tracks}" | jq ".tracks[] | select(.type==\"audio\") | .id" | wc -l) 65 | # audio preferred language 66 | AudioTracksLanguage=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language==\"${VIDEO_LANG}\")) | .id") 67 | AudioTracksLanguageCount=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language==\"${VIDEO_LANG}\")) | .id" | wc -l) 68 | # audio unkown laguage 69 | AudioTracksLanguageUND=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language==\"und\")) | .id") 70 | AudioTracksLanguageUNDCount=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language==\"und\")) | .id" | wc -l) 71 | AudioTracksLanguageNull=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language==null)) | .id") 72 | AudioTracksLanguageNullCount=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language==null)) | .id" | wc -l) 73 | # audio foreign language 74 | AudioTracksLanguageForeignCount=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language!=\"${VIDEO_LANG}\")) | .id" | wc -l) 75 | # subtitle tracks 76 | SubtitleTracks=$(echo "${tracks}" | jq ".tracks[] | select(.type==\"subtitles\") | .id") 77 | SubtitleTracksCount=$(echo "${tracks}" | jq ".tracks[] | select(.type==\"subtitles\") | .id" | wc -l) 78 | # subtitle preferred langauge 79 | SubtitleTracksLanguage=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"subtitles\") and select(.properties.language==\"${VIDEO_LANG}\")) | .id") 80 | SubtitleTracksLanguageCount=$(echo "${tracks}" | jq ".tracks[] | select((.type==\"subtitles\") and select(.properties.language==\"${VIDEO_LANG}\")) | .id" | wc -l) 81 | else 82 | echo "ERROR: ffprobe failed to read tracks and set values" 83 | rm "$video" && echo "INFO: deleted: $video" 84 | fi 85 | 86 | # Check for video track 87 | if [ -z "${VideoTrack}" ]; then 88 | echo "ERROR: no video track found" 89 | rm "$video" && echo "INFO: deleted: $filename" 90 | continue 91 | else 92 | echo "$VideoTrackCount video track found!" 93 | fi 94 | 95 | # Check for audio track 96 | if [ -z "${AudioTracks}" ]; then 97 | echo "ERROR: no audio tracks found" 98 | rm "$video" && echo "INFO: deleted: $filename" 99 | continue 100 | else 101 | echo "$AudioTracksCount audio tracks found!" 102 | fi 103 | 104 | # Check for audio track 105 | if [ ! -z "${SubtitleTracks}" ]; then 106 | echo "$SubtitleTracksCount subtitle tracks found!" 107 | fi 108 | 109 | echo "Checking for \"${VIDEO_LANG}\" audio/video/subtitle tracks" 110 | if [ ! -z "$AudioTracksLanguage" ] || [ ! -z "$SubtitleTracksLanguage" ]; then 111 | if [ ! ${VIDEO_MKVCLEANER} = TRUE ]; then 112 | echo "ERROR: No \"${VIDEO_LANG}\" audio or subtitle tracks found..." 113 | rm "$video" && echo "INFO: deleted: $filename" 114 | continue 115 | else 116 | if [ ! -z "$AudioTracksLanguage" ] || [ ! -z "$SubtitleTracksLanguage" ] || [ ! -z "$AudioTracksLanguageUND" ] || [ ! -z "$AudioTracksLanguageNull" ]; then 117 | sleep 0.1 118 | else 119 | echo "ERROR: No \"${VIDEO_LANG}\" or \"Unknown\" audio tracks found..." 120 | echo "ERROR: No \"${VIDEO_LANG}\" subtitle tracks found..." 121 | rm "$video" && echo "INFO: deleted: $filename" 122 | continue 123 | fi 124 | fi 125 | else 126 | if [ ! ${VIDEO_MKVCLEANER} = TRUE ]; then 127 | if [ ! -z "$AudioTracksLanguage" ]; then 128 | echo "$AudioTracksLanguageCount \"${VIDEO_LANG}\" audio track found..." 129 | fi 130 | if [ ! -z "$SubtitleTracksLanguage" ]; then 131 | echo "$SubtitleTracksLanguageCount \"${VIDEO_LANG}\" subtitle track found..." 132 | fi 133 | fi 134 | fi 135 | 136 | if [ ${VIDEO_MKVCLEANER} = TRUE ]; then 137 | # Check for unwanted audio tracks and remove/re-label as needed... 138 | if [ ! -z "$AudioTracksLanguage" ] || [ ! -z "$AudioTracksLanguageUND" ] || [ ! -z "$AudioTracksLanguageNull" ]; then 139 | if [ $AudioTracksCount -ne $AudioTracksLanguageCount ]; then 140 | RemoveAudioTracks="true" 141 | if [ ! -z "$AudioTracksLanguage" ]; then 142 | MKVaudio=" -a ${VIDEO_LANG}" 143 | echo "$AudioTracksLanguageCount audio tracks found!" 144 | unwantedaudiocount=$(($AudioTracksCount-$AudioTracksLanguageCount)) 145 | if [ $AudioTracksLanguageCount -ne $AudioTracksCount ]; then 146 | unwantedaudio="true" 147 | fi 148 | elif [ ! -z "$AudioTracksLanguageUND" ]; then 149 | for I in $AudioTracksLanguageUND 150 | do 151 | OUT=$OUT" -a $I --language $I:${VIDEO_LANG}" 152 | done 153 | MKVaudio="$OUT" 154 | echo "$AudioTracksLanguageUNDCount \"unknown\" audio tracks found, re-tagging as \"${VIDEO_LANG}\"" 155 | unwantedaudiocount=$(($AudioTracksCount-$AudioTracksLanguageUNDCount)) 156 | if [ $AudioTracksLanguageUNDCount -ne $AudioTracksCount ]; then 157 | unwantedaudio="true" 158 | fi 159 | elif [ ! -z "$AudioTracksLanguageNull" ]; then 160 | for I in $AudioTracksLanguageNull 161 | do 162 | OUT=$OUT" -a $I --language $I:${VIDEO_LANG}" 163 | done 164 | MKVaudio="$OUT" 165 | echo "$AudioTracksLanguageNullCount \"unknown\" audio tracks found, re-tagging as \"${VIDEO_LANG}\"" 166 | unwantedaudiocount=$(($AudioTracksCount-$AudioTracksLanguageNullCount)) 167 | if [ $AudioTracksLanguageNullCount -ne $AudioTracksCount ]; then 168 | unwantedaudio="true" 169 | fi 170 | fi 171 | else 172 | echo "$AudioTracksLanguageCount audio tracks found!" 173 | RemoveAudioTracks="false" 174 | MKVaudio="" 175 | fi 176 | elif [ -z "$SubtitleTracksLanguage" ]; then 177 | echo "ERROR: no \"${VIDEO_LANG}\" audio/subtitle tracks found!" 178 | rm "$video" && echo "INFO: deleted: $filename" 179 | continue 180 | else 181 | foreignaudio="true" 182 | RemoveAudioTracks="false" 183 | MKVaudio="" 184 | fi 185 | 186 | # Check for unwanted subtitle tracks... 187 | if [ ! -z "$SubtitleTracks" ]; then 188 | if [ $SubtitleTracksCount -ne $SubtitleTracksLanguageCount ]; then 189 | RemoveSubtitleTracks="true" 190 | MKVSubtitle=" -s ${VIDEO_LANG}" 191 | if [ ! -z "$SubtitleTracksLanguage" ]; then 192 | echo "$SubtitleTracksLanguageCount subtitle tracks found!" 193 | fi 194 | unwantedsubtitlecount=$(($SubtitleTracksCount-$SubtitleTracksLanguageCount)) 195 | if [ $SubtitleTracksLanguageCount -ne $SubtitleTracksCount ]; then 196 | unwantedsubtitle="true" 197 | fi 198 | else 199 | echo "$SubtitleTracksLanguageCount subtitle tracks found!" 200 | RemoveSubtitleTracks="false" 201 | MKVSubtitle="" 202 | fi 203 | else 204 | RemoveSubtitleTracks="false" 205 | MKVSubtitle="" 206 | fi 207 | 208 | # Correct video language, if needed... 209 | if [ -z "$VideoTrackLanguage" ]; then 210 | if [ ! -z "$AudioTracksLanguage" ] || [ ! -z "$AudioTracksLanguageUND" ] || [ ! -z "$AudioTracksLanguageNull" ]; then 211 | SetVideoLanguage="true" 212 | if [ "${RemoveAudioTracks}" = true ] || [ "${RemoveSubtitleTracks}" = true ]; then 213 | echo "$VideoTrackCount \"unknown\" video language track found, re-tagging as \"${VIDEO_LANG}\"" 214 | fi 215 | MKVvideo=" -d ${VideoTrack} --language ${VideoTrack}:${VIDEO_LANG}" 216 | else 217 | foreignvideo="true" 218 | SetVideoLanguage="false" 219 | MKVvideo="" 220 | fi 221 | else 222 | echo "$VideoTrackCount video tracks found!" 223 | SetVideoLanguage="false" 224 | MKVvideo="" 225 | fi 226 | 227 | # Display foreign audio track counts 228 | if [ "$foreignaudio" = true ] || [ "$foreignvideo" = true ]; then 229 | echo "Checking for \"foreign\" audio/video tracks" 230 | if [ "$foreignvideo" = true ]; then 231 | echo "$VideoTrackCount video track found!" 232 | foreignvideo="false" 233 | fi 234 | if [ "$foreignaudio" = true ]; then 235 | echo "$AudioTracksLanguageForeignCount audio tracks found!" 236 | foreignaudio="false" 237 | fi 238 | fi 239 | 240 | # Display unwanted audio/subtitle track counts 241 | if [ "$unwantedaudio" = true ] || [ "$unwantedsubtitle" = true ]; then 242 | echo "Checking for unwanted \"not: ${VIDEO_LANG}\" audio/subtitle tracks" 243 | if [ "$unwantedaudio" = true ]; then 244 | echo "$unwantedaudiocount audio tracks to remove..." 245 | unwantedaudio="false" 246 | fi 247 | if [ "$unwantedsubtitle" = true ]; then 248 | echo "$unwantedsubtitlecount subtitle tracks to remove..." 249 | unwantedsubtitle="false" 250 | fi 251 | fi 252 | 253 | if [ "${RemoveAudioTracks}" = false ] && [ "${RemoveSubtitleTracks}" = false ]; then 254 | if find "$video" -type f -iname "*.${CONVERTER_OUTPUT_EXTENSION}" | read; then 255 | echo "INFO: Video passed all checks, no processing needed" 256 | touch "$video" 257 | continue 258 | else 259 | echo "INFO: Video passed all checks, but is in the incorrect container, repackaging as mkv..." 260 | MKVvideo=" -d ${VideoTrack} --language ${VideoTrack}:${VIDEO_LANG}" 261 | MKVaudio=" -a ${VIDEO_LANG}" 262 | MKVSubtitle=" -s ${VIDEO_LANG}" 263 | fi 264 | fi 265 | basefilename="${video%.*}" 266 | if mkvmerge --no-global-tags --title "" -o "${basefilename}.merged.mkv"${MKVvideo}${MKVaudio}${MKVSubtitle} "$video"; then 267 | echo "SUCCESS: mkvmerge complete" 268 | echo "INFO: Options used:${MKVvideo}${MKVaudio}${MKVSubtitle}" 269 | # cleanup temp files and rename 270 | mv "$video" "$video.original" && echo "INFO: Renamed source file" 271 | mv "${basefilename}.merged.mkv" "${basefilename}.mkv" && echo "INFO: Renamed temp file" 272 | rm "$video.original" && echo "INFO: Deleted source file" 273 | else 274 | echo "ERROR: mkvmerge failed" 275 | rm "$video" && echo "INFO: deleted: $video" 276 | rm "${basefilename}.merged.mkv" && echo "INFO: deleted: ${basefilename}.merged.mkv" 277 | continue 278 | fi 279 | fi 280 | echo "====================================================" 281 | sleep 2 282 | done 283 | 284 | echo "INFO: Finished processing $count files" 285 | 286 | # script complete, now exiting 287 | exit $? 288 | -------------------------------------------------------------------------------- /external/README.md: -------------------------------------------------------------------------------- 1 | # Script Information 2 | These scripts are designed to be used on linux based systems 3 | 4 | ## Script Usage 5 | 6 | 1. Download the scripts from this repo 7 | 1. Set the permissions on the file to executable (chmod +x ) 8 | 1. Run scipt by executing it (bash or ./) 9 | 10 | # Script Descriptions 11 | 12 | ## MKVCleanup.bash 13 | This script removes unwanted audio and subtitle tracks based on configured settings 14 | 15 | ### Configuration Options 16 | Configuration options are found in the top few lines of the script

17 | **StartingDirectory** - File path to start recursive video file processing
18 | **DestinationDirectory** - File path to move completed files, only used if next setting is set to enable it
19 | **MoveToDestination** - Moves files to destination directory, set to FALSE to keep in same location
20 | **RemoveNonVideoFiles** - Deletes non MKV/MP4/AVI files
21 | **Remux** - Remuxes MKV/MP4/AVI into mkv files and removes unwanted audio/subtitles based on the language preference settings
22 | **PerferredLanguage** - Keeps only the audio for the language selected, if not found, fall-back to unknown tracks and if also not found, a final fall-back to all other audio tracks
23 | **SubtitleLanguage** - Removes all subtitles not matching specified language
24 | **SetUnknownAudioLanguage** - If enabled, sets found unknown (und) audio tracks to the language in the next setting
25 | **UnkownAudioLanguage** - Sets unknown language tracks to the language specified

26 | Language Preferences require using "ISO 639-2" language codes, list of codes can be found here: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes 27 | 28 | ### Requirements 29 | **mkvtoolnix** 30 | (if using linuxserver.io docker, use mkvtoolnix_install.bash script found here: https://github.com/RandomNinjaAtk/Scripts/tree/master/lso_docker_ubuntu
31 | -------------------------------------------------------------------------------- /external/cron_lidarr_jobs.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -x "$(command -v crontab)" ]; then 3 | if grep "lidarr-download-automation-start.bash" /etc/crontab; then 4 | echo "job already added..." 5 | else 6 | echo "adding cron job to crontab..." 7 | echo "*/5 * * * * root bash /config/scripts/lidarr-download-automation-start.bash > /config/scripts/cron-job.log" >> "/etc/crontab" 8 | fi 9 | else 10 | echo "cron NOT INSTALLED" 11 | fi 12 | exit 0 13 | -------------------------------------------------------------------------------- /external/import.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source /config/scripts/lidarr-download-automation/config 3 | if [ -f /config/scripts/beets/library.blb ]; then 4 | rm /config/scripts/beets/library.blb 5 | sleep 1s 6 | fi 7 | if [ -f /config/scripts/beets/beets.log ]; then 8 | rm /config/scripts/beets/beets.log 9 | sleep 1s 10 | fi 11 | if [ "$(ls -A "${DownloadDir}")" ]; then 12 | beets=($(find "${DownloadDir}" -type f -iregex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -newer "${DownloadDir}/temp-hold" -printf '%h\n' | sed -e "s/'/\\'/g" -e 's/\$/\$/g' | sort -u)) 13 | for beetdir in "${beets[@]}"; do 14 | logit "Attempting to match using beets..." 15 | beet -c /config/scripts/beets/config.yaml -d "${beetdir}" import -q "${beetdir}" 16 | if find "${beetdir}" -type f -iname "*.MATCHED.*" | read; then 17 | logit "SUCCESS: Matched with beets!" 18 | else 19 | logit "ERROR: Unable to match using beets to a musicbrainz release, deleting..." 20 | rm -rf "${beetdir}" 21 | fi 22 | done 23 | fi 24 | -------------------------------------------------------------------------------- /external/lidarr-download-automation-start.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -d /config/scripts/lidarr-download-automation ]; then 4 | echo "setting up script lidarr-download-automation directory..." 5 | mkdir /config/scripts/lidarr-download-automation 6 | # Set Permissions 7 | echo "setting permissions..." 8 | chmod 0777 /config/scripts/lidarr-download-automation 9 | echo "done" 10 | fi 11 | 12 | if mkdir /config/scripts/00-lidarr-download-automation.exclusivelock; then 13 | 14 | #hotio compatibility fix 15 | if [ ! -f /config/config.xml ]; then 16 | ln -s /config/app/config.xml /config/config.xml 17 | sleep 1s 18 | fi 19 | 20 | # Download Scripts 21 | if [ -f /config/scripts/lidarr-download-automation/lidarr-download-automation.bash ]; then 22 | rm /config/scripts/lidarr-download-automation/lidarr-download-automation.bash 23 | sleep 1s 24 | fi 25 | 26 | if [ ! -f /config/scripts/lidarr-download-automation/lidarr-download-automation.bash ]; then 27 | echo "downloading lidarr-download-automation.bash from: https://github.com/Migz93/lidarr-download-automation/blob/develop/lidarr-download-automation.bash" 28 | curl -o /config/scripts/lidarr-download-automation/lidarr-download-automation.bash https://raw.githubusercontent.com/Migz93/lidarr-download-automation/dremix/lidarr-download-automation.bash 29 | echo "done" 30 | chmod 0666 /config/scripts/lidarr-download-automation/lidarr-download-automation.bash 31 | fi 32 | 33 | if [ ! -f /config/scripts/lidarr-download-automation/config ]; then 34 | echo "downloading config from: https://github.com/RandomNinjaAtk/Scripts/blob/master/config/lidarr-dl-automation-config" 35 | curl -o /config/scripts/lidarr-download-automation/config https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/config/lidarr-dl-automation-config 36 | echo "done" 37 | chmod 0666 /config/scripts/lidarr-download-automation/config 38 | fi 39 | 40 | if [ -f /config/scripts/beets/config.xml ]; then 41 | rm /config/scripts/beets/config.xml 42 | sleep 1s 43 | fi 44 | if [ ! -f /config/scripts/beets/config.xml ]; then 45 | echo "downloading config.yaml from: https://github.com/RandomNinjaAtk/Scripts/blob/master/config/config.yaml" 46 | curl -o /config/scripts/beets/config.yaml https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/config/config.yaml 47 | echo "done" 48 | chmod 0666 /config/scripts/beets/config.yaml 49 | fi 50 | 51 | 52 | if [ -f /config/scripts/beets/import.bash ]; then 53 | rm /config/scripts/beets/import.bash 54 | sleep 1s 55 | fi 56 | 57 | if [ ! -f /config/scripts/beets/import.bash ]; then 58 | echo "downloading import.bash from: https://github.com/RandomNinjaAtk/Scripts/blob/master/external/import.bash" 59 | curl -o /config/scripts/beets/import.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/external/import.bash 60 | echo "done" 61 | chmod 0666 /config/scripts/beets/import.bash 62 | sed -i "s/#INSERT/source \/config\/scripts\/beets\/import.bash/g" "/config/scripts/lidarr-download-automation/lidarr-download-automation.bash" 63 | fi 64 | 65 | rm /config/scripts/script-run.log 66 | cd /config/scripts/lidarr-download-automation/ 67 | bash lidarr-download-automation.bash > /config/scripts/script-run.log 68 | sleep 10s 69 | rmdir /config/scripts/00-lidarr-download-automation.exclusivelock 70 | 71 | find /config/scripts -type f -exec chmod 0666 {} \; 72 | find /config/scripts -type d -exec chmod 0777 {} \; 73 | 74 | else 75 | echo "ERROR: /config/scripts/lidarr-download-automation/lidarr-download-automation.bash is still running..." 76 | exit 1 77 | fi 78 | exit 0 79 | -------------------------------------------------------------------------------- /external/sonarr-mkv-post-process.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "$sonarr_episodefile_path" 3 | echo "$sonarr_episodefile_episodetitles" 4 | echo "$sonarr_episodefile_seasonnumber" 5 | echo "$sonarr_series_title" 6 | echo "$sonarr_episodefile_episodenumbers" 7 | mv "$sonarr_episodefile_path" "$sonarr_episodefile_path-temp" 8 | ffmpeg -i "$sonarr_episodefile_path-temp" -codec copy -metadata COMMENT="$sonarr_episodefile_scenename" -metadata TITLE="$sonarr_episodefile_episodetitles" -metadata TRACK="$sonarr_episodefile_episodenumbers" -metadata ALBUM="Season $sonarr_episodefile_seasonnumber" -metadata ARTIST="$sonarr_series_title" "$sonarr_episodefile_path" 9 | rm "$sonarr_episodefile_path-temp" 10 | exit 0 11 | -------------------------------------------------------------------------------- /images/kodi-music-videos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/3ef96ff6e0f2a506c869f4d689bc0a501929b857/images/kodi-music-videos.png -------------------------------------------------------------------------------- /images/mbrainz_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/3ef96ff6e0f2a506c869f4d689bc0a501929b857/images/mbrainz_video.png -------------------------------------------------------------------------------- /images/plex-musicvideos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/3ef96ff6e0f2a506c869f4d689bc0a501929b857/images/plex-musicvideos.png -------------------------------------------------------------------------------- /lidarr-automated-downloader/README.md: -------------------------------------------------------------------------------- 1 | TBD 2 | -------------------------------------------------------------------------------- /lidarr-automated-downloader/config: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##################################################################################################### 3 | # Lidarr Automated Downloader # 4 | # (Powered by: Deezloader Remix) # 5 | # Credit: RandomNinjaAtk # 6 | ##################################################################################################### 7 | # Instructions # 8 | # # 9 | # 1. Configure the settings below # 10 | # 2. Execute script from linux cli with the following command: # 11 | # bash lidarr-automated-downloader.bash # 12 | ##################################################################################################### 13 | 14 | ############ Paths 15 | downloaddir="/downloads/deezloaderremix" # Deezloader download directory location 16 | beetsunmatcheddirectory="/music/unmatched" # Beets unmatched file directory location 17 | beetsconfig="/config/scripts/beets/config.yaml" # Beets configuration file 18 | beetslibraryfile="/config/scripts/beets/library.blb" # Beets library file 19 | beetslog="/config/scripts/beets/beets.log" # Beets log file 20 | 21 | ############ Lidarr Settings 22 | LidarrUrl="http://127.0.0.1:8686" # Set domain or IP to your Lidarr instance including port. If using reverse proxy, do not use a trailing slash. Ensure you specify http/s. 23 | LidarrApiKey="$(grep "" /config/config.xml | sed "s/\ //;s/<\/ApiKey>//")" # Lidarr API key. 24 | 25 | ############ Download Settings 26 | deezloaderurl="http://127.0.0.1:1730" # Url to the download client 27 | downloadmethod="album" # album or track :: album method will fallback to track method if it runs into an issue 28 | enablefallback="true" # enables fallback to lower quality if required... 29 | LyricType="all" # all or clean or explicit :: sets the desired lyric type for downloads, all is explicit albums preferred 30 | downloadalbums="true" # true = enabled :: Enables downloading deezer albums that are categorized by deezer as "Album" release type 31 | downloadcompilations="true" # true = enabled :: Enables downloading deezer albums that are categorized by deezer as "Compilation" release type 32 | downloadeps="true" # true = enabled :: Enables downloading deezer albums that are categorized by deezer as "EP" release type 33 | downloadsingles="true" # true = enabled :: Enables downloading deezer albums that are categorized by deezer as "Single" release type 34 | VerifyTrackCount="true" # true = enabled :: This will verify album track count vs dl track count, if tracks are found missing, it will skip import... 35 | dlcheck=2 # Set the number to desired wait time before checking for completed downloads (if your connection is unstable, longer may be better) 36 | albumtimeoutpercentage=8 # Set the number between 1 and 100 :: This number is used to caculate album download timeout length by multiplying Album Length by ##% 37 | tracktimeoutpercentage=25 # Set the number between 1 and 100 :: This number is used to caculate track download timeout length by multiplying Track Length by ##% 38 | 39 | ############ File Options 40 | quality="flac" # flac or mp3 or opus or aac or alac :: Set desired library format (Flac is converted for opus, aac, and alac types) 41 | upgrade="false" # true = enabled :: Enables or Disables upgrading dl quality based on quality type and bitrate changes. 42 | bitrate="192" # bitrate quality for OPUS and AAC formats only 43 | TagWithBeets="false" # true = enabled :: tag files with beets for better lidarr matching 44 | KeepOnlyBeetsMatched="false" # true = enabled :: only keep files that could be successfully matched with beets (keeps really clean library with perfect matches) 45 | MoveBeetsUnMatched="false" # true = enabled :: Moves unmatched beets files to a alternate location for safe keeping 46 | BeetsDeDupe="false" # true = enabled :: Prevents clearing database to allow beets to filter duplicate matches 47 | replaygaintaggingflac="true" # true = enabled :: Adds replaygain audio normalization tags to flac files 48 | replaygaintaggingopus="false" # true = enabled :: Adds replaygain audio normalization tags to opus files 49 | 50 | ############ Other Options 51 | debug="false" # true = enabled :: Increases cli output for diagnosing 52 | dailycheck="false" # true = enabled :: Enabling this will prevent checking artitsts that are found in the "daily.log" file, best used with a cron job to clear this file once per day 53 | 54 | -------------------------------------------------------------------------------- /lidarr-automated-downloader/config.yaml: -------------------------------------------------------------------------------- 1 | plugins: chroma embedart 2 | art_filename: folder 3 | threaded: no 4 | per_disc_numbering: yes 5 | id3v23: no 6 | asciify_paths: true 7 | 8 | match: 9 | strong_rec_thresh: 0.10 # 0.04 10 | medium_rec_thresh: 0.25 # 0.25 11 | rec_gap_thresh: 0.25 # 0.25 12 | max_rec: 13 | missing_tracks: medium # medium 14 | unmatched_tracks: medium # medium 15 | track_length: medium 16 | mediums: medium 17 | year: medium 18 | media: medium 19 | distance_weights: 20 | source: 2.0 # 2.0 21 | artist: 3.0 # 3.0 22 | album: 3.0 # 3.0 23 | media: 9.0 # 1.0 24 | mediums: 9.0 # 1.0 25 | year: 9.0 # 1.0 26 | country: 0.5 # 0.5 27 | label: 0.5 # 0.5 28 | catalognum: 0.5 # 0.5 29 | albumdisambig: 0.5 # 0.5 30 | album_id: 5.0 # 5.0 31 | tracks: 2.0 # 2.0 32 | missing_tracks: 9.0 # 0.9 33 | unmatched_tracks: 9.0 # 0.6 34 | track_title: 3.0 # 3.0 35 | track_artist: 2.0 # 2.0 36 | track_index: 1.0 # 1.0 37 | track_length: 9.0 # 2.0 38 | track_id: 5.0 # 5.0 39 | preferred: 40 | countries: [] # [] 41 | media: ['CD|Digital Media'] # [] 42 | original_year: no # no 43 | ignored: ['missing_tracks', 'track_length', 'unmatched_tracks', 'mediums', 'year', 'media'] # [] 44 | required: ['year', 'album', 'artist'] # [] 45 | ignored_media: [] # [] 46 | ignore_data_tracks: yes # yes 47 | ignore_video_tracks: yes # yes 48 | track_length_grace: 1 # 10 49 | track_length_max: 1 # 30 50 | 51 | paths: 52 | default: $disc$track - $title 53 | singleton: $disc$track - $title 54 | comp: $disc$track - $title 55 | albumtype_soundtrack: $disc$track - $title 56 | 57 | import: 58 | write: yes 59 | copy: no 60 | move: no 61 | resume: ask 62 | incremental: no 63 | quiet_fallback: skip 64 | timid: no 65 | duplicate_action: skip 66 | log: /config/scripts/beets/beets.log 67 | languages: ['en'] 68 | group_albums: no 69 | 70 | chroma: 71 | auto: no 72 | 73 | embedart: 74 | auto: no 75 | -------------------------------------------------------------------------------- /lidarr-automated-downloader/docker/README.md: -------------------------------------------------------------------------------- 1 | ## Scripts Usage 2 | 3 | #### lsio-automated-installer-updater.bash 4 | Updates and runs the "lsio-automated-installer.bash" script automatically
5 | 6 | #### lsio-automated-installer.bash 7 | Script installs and configures all requirements for the: lidarr-automated-downloader.bash found here: https://github.com/RandomNinjaAtk/Scripts/tree/master/lidarr-automated-downloader 8 | 9 | ## Script Usage 10 | 11 | 1. Create a "custom-cont-init.d" folder in the "/config/" of your lidarr ls.io docker container 12 | 1. Download the scripts from this repo 13 | 1. Copy the scripts into the "/config/custom-cont-init.d/" 14 | 1. Restart docker container, scripts will automatically run on startup 15 | 16 | For additional information, visit the following link: 17 | https://blog.linuxserver.io/2019/09/14/customizing-our-containers/ 18 | 19 | ## Recommendation 20 | Use the lsio-automated-installer-updater.bash script only, this way you get automated updates to your scripts... 21 | -------------------------------------------------------------------------------- /lidarr-automated-downloader/docker/lidarr-automated-downloader-start.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if mkdir /config/scripts/00-lidarr-automated-downloader.exclusivelock; then 4 | 5 | rm /config/scripts/script-run.log 6 | cd /config/scripts/lidarr-automated-downloader/ 7 | bash lidarr-automated-downloader.bash 2>&1 | tee "/config/scripts/script-run.log" > /proc/1/fd/1 2>/proc/1/fd/2 8 | 9 | sleep 5 10 | rmdir /config/scripts/00-lidarr-automated-downloader.exclusivelock 11 | 12 | find /config/scripts -type f -exec chmod 0666 {} \; 13 | find /config/scripts -type d -exec chmod 0777 {} \; 14 | 15 | else 16 | echo "ERROR: /config/scripts/lidarr-automated-downloader/lidarr-automated-downloader.bash is still running..." 17 | exit 1 18 | fi 19 | exit 0 20 | -------------------------------------------------------------------------------- /lidarr-automated-downloader/docker/lidarr-automated-installer-updater.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "==========start lidarr-automated-installer automated updates===========" 3 | 4 | # Check for folder, create folder if needed (hotio docker image compatibility) 5 | if [ ! -d /config/custom-cont-init.d ]; then 6 | mkdir -p /config/custom-cont-init.d 7 | fi 8 | 9 | if [ -f /config/custom-cont-init.d/lsio-automated-installer.bash ]; then 10 | echo "Previous version detected..." 11 | echo "removing....lsio-automated-installer.bash" 12 | rm /config/custom-cont-init.d/lsio-automated-installer.bash 13 | fi 14 | if [ ! -f /config/custom-cont-init.d/lsio-automated-installer.bash ]; then 15 | echo "begining updated script installation..." 16 | echo "downloading lsio-automated-installer.bash from: https://github.com/RandomNinjaAtk/Scripts/blob/master/lidarr-automated-downloader/docker/lsio-automated-installer.bash" && \ 17 | curl -o /config/custom-cont-init.d/lsio-automated-installer.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/lidarr-automated-downloader/docker/lsio-automated-installer.bash && \ 18 | echo "download complete" && \ 19 | echo "running lsio-automated-installer.bash..." && \ 20 | bash /config/custom-cont-init.d/lsio-automated-installer.bash && \ 21 | rm /config/custom-cont-init.d/lsio-automated-installer.bash 22 | fi 23 | echo "==========end start lidarr-automated-installer automated updates===========" 24 | exit 0 25 | -------------------------------------------------------------------------------- /lidarr-automated-downloader/docker/lsio-automated-installer.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "==========lidarr-automated-downloader setup===========" 3 | 4 | 5 | if ! [ -x "$(command -v flac)" ]; then 6 | echo "INSTALLING REQUIREMENTS" 7 | curl -sL https://deb.nodesource.com/setup_10.x | bash - && \ 8 | apt-get update -qq && \ 9 | apt-get install -qq -y \ 10 | mp3val \ 11 | flac \ 12 | wget \ 13 | nano \ 14 | unzip \ 15 | nodejs \ 16 | git \ 17 | jq \ 18 | cron && \ 19 | apt-get purge --auto-remove -y && \ 20 | apt-get clean 21 | else 22 | echo "PRE-REQ ALREADY INSTALLED" 23 | fi 24 | 25 | if [ ! -f "/usr/local/bin/beet" ]; then 26 | apt-get update -qq && \ 27 | apt-get install -qq -y \ 28 | libchromaprint-tools \ 29 | python3-pip && \ 30 | apt-get purge --auto-remove -y && \ 31 | apt-get clean 32 | 33 | pip3 install --no-cache-dir -U \ 34 | beets \ 35 | pyacoustid 36 | else 37 | echo "BEETS ALREADY INSTALLED" 38 | fi 39 | 40 | if [ ! -f "/usr/local/bin/opusenc" ]; then 41 | apt-get update -qq && \ 42 | apt-get install -qq -y \ 43 | autoconf \ 44 | automake \ 45 | libtool \ 46 | gcc \ 47 | make \ 48 | pkg-config \ 49 | openssl \ 50 | libssl-dev && \ 51 | apt-get purge --auto-remove -y && \ 52 | apt-get clean 53 | 54 | set -e 55 | set -o pipefail 56 | 57 | # Install packages needed 58 | 59 | apt update > /dev/null 2>&1 && apt install -y curl libflac-dev > /dev/null 2>&1 60 | 61 | # Remove packages that can cause issues 62 | 63 | apt -y purge opus* > /dev/null 2>&1 && apt -y purge libopus-dev > /dev/null 2>&1 64 | 65 | # Download necessary files 66 | 67 | TEMP_FOLDER="$(mktemp -d)" 68 | 69 | # Opusfile 0.11 70 | curl -Ls https://downloads.xiph.org/releases/opus/opusfile-0.11.tar.gz | tar xz -C "$TEMP_FOLDER" 71 | 72 | # Opus 1.3.1 73 | curl -Ls https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz | tar xz -C "$TEMP_FOLDER" 74 | 75 | # Libopusenc 0.2.1 76 | curl -Ls https://archive.mozilla.org/pub/opus/libopusenc-0.2.1.tar.gz | tar xz -C "$TEMP_FOLDER" 77 | 78 | # Opus Tools 0.2 79 | curl -Ls https://archive.mozilla.org/pub/opus/opus-tools-0.2.tar.gz | tar xz -C "$TEMP_FOLDER" 80 | 81 | # Compile 82 | 83 | cd "$TEMP_FOLDER"/opus-1.3.1 || exit 84 | 85 | ./configure 86 | make && make install 87 | 88 | cd "$TEMP_FOLDER"/opusfile-0.11 || exit 89 | 90 | ./configure 91 | make && make install 92 | 93 | cd "$TEMP_FOLDER"/libopusenc-0.2.1 || exit 94 | 95 | ./configure 96 | make && make install 97 | 98 | cd "$TEMP_FOLDER"/opus-tools-0.2 || exit 99 | ./configure 100 | make 101 | make install 102 | ldconfig 103 | 104 | # Cleanup 105 | 106 | rm -rf "$TEMP_FOLDER" 107 | 108 | cd / 109 | else 110 | echo "OPUSENC ALREADY INSTALLED" 111 | fi 112 | 113 | 114 | service cron restart 115 | 116 | if [ ! -f "/usr/bin/ffmpeg" ]; then 117 | echo "INSTALLING FFMPEG" 118 | apt-get update -qq && \ 119 | apt-get install -y xz-utils 120 | 121 | mkdir /tmp/ffmpeg 122 | curl -o /tmp/ffmpeg/ffmpeg-git-amd64-static.tar.xz https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz 123 | cd /tmp/ffmpeg 124 | tar xvf ffmpeg-git-amd64-static.tar.xz 125 | find "/usr/bin/" -type f -iname "ffmpeg" -exec rm {} \; 126 | find "/usr/bin/" -type f -iname "ffprobe" -exec rm {} \; 127 | find "/tmp/ffmpeg" -type f -iname "ffmpeg" -exec mv {} /usr/bin/ \; 128 | find "/tmp/ffmpeg" -type f -iname "ffprobe" -exec mv {} /usr/bin/ \; 129 | cd / 130 | rm -rf /tmp/ffmpeg 131 | else 132 | echo "FFMPEG ALREADY INSTALLED" 133 | fi 134 | 135 | if [ ! -d /config/scripts ]; then 136 | echo "setting up script directory" 137 | mkdir -p /config/scripts 138 | echo "done" 139 | fi 140 | 141 | if [ -f /config/scripts/lidarr-download-automation-start.bash ]; then 142 | rm /config/scripts/lidarr-automated-downloader-start.bash 143 | sleep 0.1 144 | fi 145 | 146 | if [ ! -f /config/scripts/lidarr-download-automation-start.bash ]; then 147 | echo "downloading lidarr-automated-downloader-start.bash from: https://github.com/RandomNinjaAtk/Scripts/blob/master/lidarr-automated-downloader/docker/lidarr-automated-downloader-start.bash" 148 | curl -o /config/scripts/lidarr-automated-downloader-start.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/lidarr-automated-downloader/docker/lidarr-automated-downloader-start.bash 149 | echo "done" 150 | fi 151 | 152 | # Remove lock file incase, system was rebooted before script finished 153 | if [ -d /config/scripts/00-lidarr-automated-downloader.exclusivelock ]; then 154 | rmdir /config/scripts/00-lidarr-automated-downloader.exclusivelock 155 | fi 156 | 157 | if [ -d "/config/scripts/lidarr-automated-downloader" ]; then 158 | find "/config/scripts/lidarr-automated-downloader" -type f -iname "*.json" -delete 159 | find "/config/scripts/lidarr-automated-downloader" -type f -iname "temp-*" -delete 160 | fi 161 | 162 | echo "INSTALLING DEEZLOADER-REMIX" 163 | 164 | rm -rf /deezloaderremix && \ 165 | 166 | if [ -d "/config/xdg" ]; then 167 | rm -rf /config/xdg 168 | fi 169 | 170 | if [ ! -d /downloads/deezloaderremix ]; then 171 | mkdir /downloads/deezloaderremix 172 | fi 173 | ln -sf /downloads/deezloaderremix "/root/Deezloader Music" && \ 174 | 175 | cd / && \ 176 | if [ -f /development.zip ]; then 177 | rm /development.zip 178 | sleep 1s 179 | fi 180 | 181 | wget https://notabug.org/RemixDevs/DeezloaderRemix/archive/development.zip && \ 182 | unzip development.zip && \ 183 | rm development.zip && \ 184 | 185 | sed -i "s/\"trackNameTemplate\": \"%artist% - %title%\"/\"trackNameTemplate\": \"%disc%%number% - %title% %explicit%\"/g" "/deezloaderremix/app/default.json" && \ 186 | sed -i "s/\"albumTrackNameTemplate\": \"%number% - %title%\"/\"albumTrackNameTemplate\": \"%disc%%number% - %title% %explicit%\"/g" "/deezloaderremix/app/default.json" && \ 187 | sed -i "s/\"createAlbumFolder\": true/\"createAlbumFolder\": false/g" "/deezloaderremix/app/default.json" && \ 188 | sed -i "s/\"embeddedArtworkSize\": 800/\"embeddedArtworkSize\": 1000/g" "/deezloaderremix/app/default.json" && \ 189 | sed -i "s/\"localArtworkSize\": 1000/\"localArtworkSize\": 1400/g" "/deezloaderremix/app/default.json" && \ 190 | sed -i "s/\"saveArtwork\": false/\"saveArtwork\": true/g" "/deezloaderremix/app/default.json" && \ 191 | sed -i "s/\"queueConcurrency\": 3/\"queueConcurrency\": 6/g" "/deezloaderremix/app/default.json" && \ 192 | sed -i "s/\"maxBitrate\": \"3\"/\"maxBitrate\": \"9\"/g" "/deezloaderremix/app/default.json" && \ 193 | sed -i "s/\"coverImageTemplate\": \"cover\"/\"coverImageTemplate\": \"folder\"/g" "/deezloaderremix/app/default.json" && \ 194 | sed -i "s/\"createCDFolder\": true/\"createCDFolder\": false/g" "/deezloaderremix/app/default.json" && \ 195 | sed -i "s/\"createSingleFolder\": false/\"createSingleFolder\": true/g" "/deezloaderremix/app/default.json" && \ 196 | sed -i "s/\"removeAlbumVersion\": false/\"removeAlbumVersion\": true/g" "/deezloaderremix/app/default.json" && \ 197 | sed -i "s/\"syncedlyrics\": false/\"syncedlyrics\": true/g" "/deezloaderremix/app/default.json" && \ 198 | sed -i "s/\"logErrors\": false/\"logErrors\": true/g" "/deezloaderremix/app/default.json" && \ 199 | sed -i "s/\"logSearched\": false/\"logSearched\": true/g" "/deezloaderremix/app/default.json" && \ 200 | sed -i "s/\"trackTotal\": false/\"trackTotal\": true/g" "/deezloaderremix/app/default.json" && \ 201 | sed -i "s/\"discTotal\": false/\"discTotal\": true/g" "/deezloaderremix/app/default.json" && \ 202 | sed -i "s/\"explicit\": false/\"explicit\": true/g" "/deezloaderremix/app/default.json" && \ 203 | sed -i "s/\"barcode\": false/\"barcode\": true/g" "/deezloaderremix/app/default.json" && \ 204 | sed -i "s/\"unsynchronisedLyrics\": false/\"unsynchronisedLyrics\": true/g" "/deezloaderremix/app/default.json" && \ 205 | sed -i "s/\"copyright\": false/\"copyright\": true/g" "/deezloaderremix/app/default.json" && \ 206 | sed -i "s/\"musicpublisher\": false/\"musicpublisher\": true/g" "/deezloaderremix/app/default.json" && \ 207 | sed -i "s/\"composer\": false/\"composer\": true/g" "/deezloaderremix/app/default.json" && \ 208 | sed -i "s/\"mixer\": false/\"mixer\": true/g" "/deezloaderremix/app/default.json" && \ 209 | sed -i "s/\"author\": false/\"author\": true/g" "/deezloaderremix/app/default.json" && \ 210 | sed -i "s/\"writer\": false/\"writer\": true/g" "/deezloaderremix/app/default.json" && \ 211 | sed -i "s/\"engineer\": false/\"engineer\": true/g" "/deezloaderremix/app/default.json" && \ 212 | sed -i "s/\"producer\": false/\"producer\": true/g" "/deezloaderremix/app/default.json" && \ 213 | sed -i "s/\"multitagSeparator\": \"; \"/\"multitagSeparator\": \"andFeat\"/g" "/deezloaderremix/app/default.json" && \ 214 | 215 | cd /deezloaderremix && \ 216 | npm install && \ 217 | cd /deezloaderremix/app && \ 218 | npm install && \ 219 | cd / && \ 220 | 221 | echo "Starting Deezloader Remix" 222 | nohup node /deezloaderremix/app/app.js &>/dev/null & 223 | sleep 20s 224 | 225 | if [ -d "/config/xdg" ]; then 226 | chmod 0777 -R /config/xdg 227 | fi 228 | 229 | if [ ! -d /config/scripts/lidarr-automated-downloader ]; then 230 | echo "setting up script lidarr-automated-downloader directory..." 231 | mkdir -p /config/scripts/lidarr-automated-downloader 232 | echo "done" 233 | fi 234 | 235 | if [ ! -d "/config/scripts/beets" ]; then 236 | echo "setting up beets directory..." 237 | mkdir -p "/config/scripts/beets" 238 | echo "done" 239 | fi 240 | 241 | #hotio compatibility fix 242 | if [ ! -f /config/config.xml ]; then 243 | ln -s /config/app/config.xml /config/config.xml 244 | sleep 0.1 245 | fi 246 | 247 | # Download Scripts 248 | if [ -f "/config/scripts/lidarr-automated-downloader/lidarr-automated-downloader.bash" ]; then 249 | rm /config/scripts/lidarr-automated-downloader/lidarr-automated-downloader.bash 250 | sleep 0.1 251 | fi 252 | 253 | if [ ! -f "/config/scripts/lidarr-automated-downloader/lidarr-automated-downloader.bash" ]; then 254 | echo "downloading lidarr-automated-downloader.bash from: https://github.com/RandomNinjaAtk/Scripts/blob/master/lidarr-automated-downloader/lidarr-automated-downloader.bash" 255 | curl -o /config/scripts/lidarr-automated-downloader/lidarr-automated-downloader.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/lidarr-automated-downloader/lidarr-automated-downloader.bash 256 | echo "done" 257 | fi 258 | 259 | if [ ! -f "/config/scripts/lidarr-automated-downloader/config" ]; then 260 | echo "downloading config from: https://github.com/RandomNinjaAtk/Scripts/blob/master/lidarr-automated-downloader/config" 261 | curl -o /config/scripts/lidarr-automated-downloader/config https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/lidarr-automated-downloader/config 262 | echo "done" 263 | fi 264 | 265 | if [ ! -f "/config/scripts/beets/config.yaml" ]; then 266 | echo "downloading config.yaml from: https://github.com/RandomNinjaAtk/Scripts/blob/master/lidarr-automated-downloader/config.yaml" 267 | curl -o /config/scripts/beets/config.yaml https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/lidarr-automated-downloader/config.yaml 268 | echo "done" 269 | fi 270 | 271 | find /config/scripts -type f -exec chmod 0666 {} \; 272 | find /config/scripts -type d -exec chmod 0777 {} \; 273 | 274 | if [ -x "$(command -v crontab)" ]; then 275 | if grep "lidarr-automated-downloader-start.bash" /etc/crontab | read; then 276 | echo "job already added..." 277 | else 278 | echo "adding cron job to crontab..." 279 | echo "*/15 * * * * root bash /config/scripts/lidarr-automated-downloader-start.bash > /config/scripts/cron-job.log" >> "/etc/crontab" 280 | fi 281 | if grep "musicbrainzerror.log" /etc/crontab | read; then 282 | echo "job already added..." 283 | else 284 | echo "adding cron job to crontab..." 285 | echo "0 18 * * * root rm \"/config/scripts/lidarr-automated-downloader/musicbrainzerror.log\" && touch \"/config/scripts/lidarr-automated-downloader/musicbrainzerror.log\"" >> "/etc/crontab" 286 | fi 287 | if grep "daily.log" /etc/crontab | read; then 288 | echo "job already added..." 289 | else 290 | echo "adding cron job to crontab..." 291 | echo "5 18 * * * root rm \"/config/scripts/lidarr-automated-downloader/daily.log\" && touch \"/config/scripts/lidarr-automated-downloader/daily.log\"" >> "/etc/crontab" 292 | fi 293 | service cron restart 294 | else 295 | echo "cron NOT INSTALLED" 296 | fi 297 | 298 | echo "==========lidarr-automated-downloader setup===========" 299 | exit 0 300 | -------------------------------------------------------------------------------- /lidarr-automated-downloader/lidarr-automated-downloader.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##################################################################################################### 3 | # Lidarr Automated Downloader # 4 | # (Powered by: Deezloader Remix) # 5 | # Credit: RandomNinjaAtk # 6 | ##################################################################################################### 7 | # Script Start # 8 | ##################################################################################################### 9 | 10 | source ./config 11 | 12 | tempalbumfile="temp-archive-album" 13 | temptrackfile="temp-archive-track" 14 | tempartistjson="artistinfo.json" 15 | tempalbumlistjson="temp-albumlistdata.json" 16 | tempalbumjson="albuminfo.json" 17 | artistalbumlistjson="discography.json" 18 | 19 | ArtistsLidarrReq(){ 20 | 21 | wantit=$(curl -s --header "X-Api-Key:"${LidarrApiKey} --request GET "$LidarrUrl/api/v1/Artist/") 22 | TotalLidArtistNames=$(echo "${wantit}"|jq -r '.[].sortName' | wc -l) 23 | 24 | if [ "$quality" = flac ]; then 25 | dlquality="flac" 26 | bitrate="lossless" 27 | targetformat="FLAC" 28 | elif [ "$quality" = mp3 ]; then 29 | dlquality="320" 30 | bitrate="320" 31 | targetformat="MP3" 32 | elif [ "$quality" = alac ]; then 33 | dlquality="flac" 34 | targetformat="ALAC" 35 | bitrate="lossless" 36 | elif [ "$quality" = opus ]; then 37 | dlquality="flac" 38 | targetformat="OPUS" 39 | if [ -z "$bitrate" ]; then 40 | bitrate="128" 41 | fi 42 | elif [ "$quality" = aac ]; then 43 | dlquality="flac" 44 | targetformat="AAC" 45 | if [ -z "$bitrate" ]; then 46 | bitrate="320" 47 | fi 48 | fi 49 | 50 | ConfigSettings 51 | 52 | MBArtistID=($(echo "${wantit}" | jq -r ".[$i].foreignArtistId")) 53 | for id in ${!MBArtistID[@]}; do 54 | artistnumber=$(( $id + 1 )) 55 | mbid="${MBArtistID[$id]}" 56 | deezerartisturl="" 57 | 58 | source ./config 59 | 60 | if ! [ -f "musicbrainzerror.log" ]; then 61 | touch "musicbrainzerror.log" 62 | fi 63 | 64 | LidArtistPath="$(echo "${wantit}" | jq -r ".[] | select(.foreignArtistId==\"${mbid}\") | .path")" 65 | LidArtistID="$(echo "${wantit}" | jq -r ".[] | select(.foreignArtistId==\"${mbid}\") | .id")" 66 | LidArtistNameCap="$(echo "${wantit}" | jq -r ".[] | select(.foreignArtistId==\"${mbid}\") | .artistName")" 67 | lidarrartistposterurl="$(echo "${wantit}" | jq -r ".[] | select(.foreignArtistId==\"${mbid}\") | .images | .[] | select(.coverType==\"poster\") | .url")" 68 | lidarrartistposterextension="$(echo "${wantit}" | jq -r ".[] | select(.foreignArtistId==\"${mbid}\") | .images | .[] | select(.coverType==\"poster\") | .extension")" 69 | lidarrartistposterlink="${LidarrUrl}${lidarrartistposterurl}${lidarrartistposterextension}" 70 | deezerartisturl=($(echo "${wantit}" | jq -r ".[] | select(.foreignArtistId==\"${mbid}\") | .links | .[] | select(.name==\"deezer\") | .url")) 71 | 72 | if [ -z "${deezerartisturl}" ]; then 73 | echo "ERROR: Fallback to musicbrainz for url..." 74 | mbjson=$(curl -s "http://musicbrainz.org/ws/2/artist/${mbid}?inc=url-rels&fmt=json") 75 | deezerartisturl=($(echo "$mbjson" | jq -r '.relations | .[] | .url | select(.resource | contains("deezer")) | .resource')) 76 | fi 77 | 78 | if [ -z "${deezerartisturl}" ]; then 79 | if [ -f "musicbrainzerror.log" ]; then 80 | echo "${artistnumber}/${TotalLidArtistNames}: ERROR: \"$LidArtistNameCap\"... musicbrainz id: $mbid is missing deezer link, see: \"$(pwd)/musicbrainzerror.log\" for more detail..." 81 | if cat "musicbrainzerror.log" | grep "$mbid" | read; then 82 | sleep 0.1 83 | else 84 | echo "Update Musicbrainz Relationship Page: https://musicbrainz.org/artist/$mbid/relationships for \"${LidArtistNameCap}\" with Deezer Artist Link" >> "musicbrainzerror.log" 85 | fi 86 | fi 87 | continue 88 | fi 89 | 90 | for url in ${!deezerartisturl[@]}; do 91 | deezerid="${deezerartisturl[$url]}" 92 | DeezerArtistID=$(printf -- "%s" "${deezerid##*/}") 93 | artistdir="$(basename "$LidArtistPath")" 94 | 95 | if [ -f "$LidArtistPath/musicbrainzerror.log" ]; then 96 | rm "$LidArtistPath/musicbrainzerror.log" 97 | fi 98 | 99 | if [ "$dailycheck" = true ]; then 100 | 101 | if cat "daily.log" | grep "$LidArtistID" | read; then 102 | echo "${artistnumber}/${TotalLidArtistNames}: Already Checked \"$LidArtistNameCap\" for new music, skipping..." 103 | else 104 | lidarrartists 105 | 106 | if ! [ -f "daily.log" ]; then 107 | touch "daily.log" 108 | fi 109 | if cat "daily.log" | grep "$LidArtistID" | read; then 110 | sleep 0.1 111 | else 112 | echo "${LidArtistNameCap} :: $LidArtistID :: Daily Check Completed" >> "daily.log" 113 | fi 114 | fi 115 | else 116 | lidarrartists 117 | 118 | if ! [ -f "daily.log" ]; then 119 | touch "daily.log" 120 | fi 121 | 122 | if cat "daily.log" | grep "$LidArtistID" | read; then 123 | sleep 0.1 124 | else 125 | echo "${LidArtistNameCap} :: $LidArtistID :: Daily Check Completed" >> "daily.log" 126 | fi 127 | fi 128 | done 129 | done 130 | } 131 | 132 | AlbumDL () { 133 | check=1 134 | error=0 135 | trackdlfallback=0 136 | if [ "$downloadmethod" = "album" ]; then 137 | if curl -s --request GET "$deezloaderurl/api/download/?url=$albumurl&quality=$dlquality" >/dev/null; then 138 | echo "Download Timeout: $albumtimeoutdisplay" 139 | echo "Downloading $tracktotal Tracks..." 140 | sleep $dlcheck 141 | let j=0 142 | while [[ "$check" -le 1 ]]; do 143 | let j++ 144 | if curl -s --request GET "$deezloaderurl/api/queue/" | grep "length\":0,\"items\":\[\]" >/dev/null; then 145 | check=2 146 | else 147 | sleep 1s 148 | if [ "$j" = "$albumtimeout" ]; then 149 | dlid=$(curl -s --request GET "$deezloaderurl/api/queue/" | jq -r ".items | .[] | .queueId") 150 | if curl -s --request GET "$deezloaderurl/api/canceldownload/?queueId=$dlid" >/dev/null; then 151 | echo "Error downloading $albumname ($dlquality), retrying...via track method " 152 | trackdlfallback=1 153 | error=1 154 | fi 155 | fi 156 | fi 157 | done 158 | if find "$downloaddir" -iname "*.flac" | read; then 159 | fallbackqualitytext="FLAC" 160 | elif find "$downloaddir" -iname "*.mp3" | read; then 161 | fallbackqualitytext="MP3" 162 | fi 163 | if [ $error = 1 ]; then 164 | rm -rf "$downloaddir"/* 165 | echo "$artistname :: $albumname :: $fallbackqualitytext :: Fallback to track download method" >> "download-album-error.log" 166 | else 167 | echo "Downloaded Album: $albumname (Format: $fallbackqualitytext; Length: $albumdurationdisplay)" 168 | Verify 169 | fi 170 | else 171 | echo "Error sending download to Deezloader-Remix (Attempt 1)" 172 | trackdlfallback=1 173 | fi 174 | else 175 | trackdlfallback=1 176 | fi 177 | } 178 | 179 | DownloadURL () { 180 | check=1 181 | error=0 182 | retry=0 183 | fallback=0 184 | fallbackbackup=0 185 | fallbackquality="$dlquality" 186 | if curl -s --request GET "$deezloaderurl/api/download/?url=$trackurl&quality=$dlquality" >/dev/null; then 187 | sleep $dlcheck 188 | let j=0 189 | while [[ "$check" -le 1 ]]; do 190 | let j++ 191 | if curl -s --request GET "$deezloaderurl/api/queue/" | grep "length\":0,\"items\":\[\]" >/dev/null; then 192 | check=2 193 | else 194 | sleep 1s 195 | retry=0 196 | if [ "$j" = "$tracktimeout" ]; then 197 | dlid=$(curl -s --request GET "$deezloaderurl/api/queue/" | jq -r ".items | .[] | .queueId") 198 | if curl -s --request GET "$deezloaderurl/api/canceldownload/?queueId=$dlid" >/dev/null; then 199 | echo "Error downloading track $tracknumber: $trackname ($dlquality), retrying...download" 200 | retry=1 201 | find "$downloaddir" -type f -iname "*.flac" -newer "$temptrackfile" -delete 202 | find "$downloaddir" -type f -iname "*.mp3" -newer "$temptrackfile" -delete 203 | fi 204 | fi 205 | fi 206 | done 207 | else 208 | echo "Error sending download to Deezloader-Remix (Attempt 2)" 209 | fi 210 | if [ $retry = 1 ]; then 211 | if curl -s --request GET "$deezloaderurl/api/download/?url=$trackurl&quality=$dlquality" >/dev/null; then 212 | sleep $dlcheck 213 | let k=0 214 | while [[ "$retry" -le 1 ]]; do 215 | let k++ 216 | if curl -s --request GET "$deezloaderurl/api/queue/" | grep "length\":0,\"items\":\[\]" >/dev/null; then 217 | retry=2 218 | else 219 | sleep 1s 220 | fallback=0 221 | if [ "$k" = "$trackfallbacktimout" ]; then 222 | dlid=$(curl -s --request GET "$deezloaderurl/api/queue/" | jq -r ".items | .[] | .queueId") 223 | if curl -s --request GET "$deezloaderurl/api/canceldownload/?queueId=$dlid" >/dev/null; then 224 | echo "Error downloading track $tracknumber: $trackname ($dlquality), retrying...as mp3 320" 225 | fallback=1 226 | find "$downloaddir" -type f -iname "*.flac" -newer "$temptrackfile" -delete 227 | find "$downloaddir" -type f -iname "*.mp3" -newer "$temptrackfile" -delete 228 | fi 229 | fi 230 | fi 231 | done 232 | else 233 | echo "Error sending download to Deezloader-Remix (Attempt 3)" 234 | fi 235 | fi 236 | if [ "$enablefallback" = true ]; then 237 | if [ $fallback = 1 ]; then 238 | if [ "$dlquality" = flac ]; then 239 | fallbackquality="320" 240 | bitrate="320" 241 | elif [ "$dlquality" = 320 ]; then 242 | fallbackquality="128" 243 | bitrate="128" 244 | fi 245 | if curl -s --request GET "$deezloaderurl/api/download/?url=$trackurl&quality=$fallbackquality" >/dev/null; then 246 | sleep $dlcheck 247 | let l=0 248 | while [[ "$fallback" -le 1 ]]; do 249 | let l++ 250 | if curl -s --request GET "$deezloaderurl/api/queue/" | grep "length\":0,\"items\":\[\]" >/dev/null; then 251 | fallback=2 252 | else 253 | sleep 1s 254 | if [ "$l" = $tracktimeout ]; then 255 | dlid=$(curl -s --request GET "$deezloaderurl/api/queue/" | jq -r ".items | .[] | .queueId") 256 | if curl -s --request GET "$deezloaderurl/api/canceldownload/?queueId=$dlid" >/dev/null; then 257 | if [ "$fallbackquality" = 128 ]; then 258 | echo "Error downloading track $tracknumber: $trackname (mp3 128), skipping..." 259 | error=1 260 | else 261 | echo "Error downloading track $tracknumber: $trackname (mp3 320), retrying...as mp3 128" 262 | fallbackbackup=1 263 | fi 264 | find "$downloaddir" -type f -iname "*.mp3" -newer "$temptrackfile" -delete 265 | fi 266 | fi 267 | fi 268 | done 269 | else 270 | echo "Error sending download to Deezloader-Remix (Attempt 4)" 271 | fi 272 | fi 273 | if [ $fallbackbackup = 1 ]; then 274 | fallbackquality="128" 275 | bitrate="128" 276 | if curl -s --request GET "$deezloaderurl/api/download/?url=$trackurl&quality=$fallbackquality" >/dev/null; then 277 | sleep $dlcheck 278 | let l=0 279 | while [[ "$fallbackbackup" -le 1 ]]; do 280 | let l++ 281 | if curl -s --request GET "$deezloaderurl/api/queue/" | grep "length\":0,\"items\":\[\]" >/dev/null; then 282 | fallbackbackup=2 283 | else 284 | sleep 1s 285 | if [ "$l" = $trackfallbacktimout ]; then 286 | dlid=$(curl -s --request GET "$deezloaderurl/api/queue/" | jq -r ".items | .[] | .queueId") 287 | if curl -s --request GET "$deezloaderurl/api/canceldownload/?queueId=$dlid" >/dev/null; then 288 | echo "Error downloading track $tracknumber: $trackname (mp3 128), skipping..." 289 | error=1 290 | find "$downloaddir" -type f -iname "*.mp3" -newer "$temptrackfile" -delete 291 | fi 292 | fi 293 | fi 294 | done 295 | else 296 | echo "Error sending download to Deezloader-Remix (Attempt 5)" 297 | fi 298 | fi 299 | else 300 | echo "Error downloading track $tracknumber: $trackname ($dlquality), skipping..." 301 | error=1 302 | fi 303 | 304 | if find "$downloaddir" -iname "*.flac" -newer "$temptrackfile" | read; then 305 | fallbackqualitytext="FLAC" 306 | elif find "$downloaddir" -iname "*.mp3" -newer "$temptrackfile" | read; then 307 | fallbackqualitytext="MP3" 308 | fi 309 | if [ $error = 1 ]; then 310 | echo "$artistname :: $albumname :: $fallbackqualitytext :: $trackname (${trackid[$track]})" >> "download-track-error.log" 311 | elif find "$downloaddir" -type f -iregex ".*/.*\.\(flac\|mp3\)" -newer "$temptrackfile" | read; then 312 | echo "Download Track $tracknumber of $tracktotal: $trackname (Format: $fallbackqualitytext; Length: $trackdurationdisplay)" 313 | Verify 314 | else 315 | error=1 316 | echo "$artistname :: $albumname :: $fallbackqualitytext :: $trackname (${trackid[$track]})" >> "download-track-error.log" 317 | fi 318 | } 319 | 320 | TrackMethod () { 321 | rm -rf "$downloaddir"/* 322 | sleep 0.5 323 | echo "Downloading $tracktotal Tracks..." 324 | trackid=($(cat "$tempalbumjson" | jq -r ".tracks | .data | .[] | .id")) 325 | for track in ${!trackid[@]}; do 326 | tracknumber=$(( $track + 1 )) 327 | trackname=$(cat "$tempalbumjson" | jq -r ".tracks | .data | .[] | select(.id=="${trackid[$track]}") | .title") 328 | trackduration=$(cat "$tempalbumjson" | jq -r ".tracks | .data | .[] | select(.id=="${trackid[$track]}") | .duration") 329 | trackdurationdisplay=$(DurationCalc $trackduration) 330 | trackurl="https://www.deezer.com/track/${trackid[$track]}" 331 | tracktimeout=$(($trackduration*$tracktimeoutpercentage/100)) 332 | trackfallbacktimout=$(($tracktimeout*2)) 333 | if [[ "$tracktimeout" -le 60 ]]; then 334 | tracktimeout="60" 335 | trackfallbacktimout=$(($tracktimeout*2)) 336 | fi 337 | if [ -f "$temptrackfile" ]; then 338 | rm "$temptrackfile" 339 | sleep 0.1 340 | fi 341 | touch "$temptrackfile" 342 | DownloadURL 343 | if [ -f "$temptrackfile" ]; then 344 | rm "$temptrackfile" 345 | sleep 0.1 346 | fi 347 | done 348 | } 349 | 350 | Convert () { 351 | if [ "${quality}" = opus ]; then 352 | if [ -x "$(command -v opusenc)" ]; then 353 | if find "${downloaddir}/" -name "*.flac" | read; then 354 | echo "Converting: $converttrackcount Tracks (Target Format: $targetformat (${bitrate}k))" 355 | for fname in "${downloaddir}"/*.flac; do 356 | filename="$(basename "${fname%.flac}")" 357 | if opusenc --bitrate $bitrate --vbr --music "$fname" "${fname%.flac}.opus" 2> /dev/null; then 358 | echo "Converted: $filename" 359 | if [ -f "${fname%.flac}.opus" ]; then 360 | rm "$fname" 361 | fi 362 | else 363 | echo "Conversion failed: $filename, performing cleanup..." 364 | if [ -f "${fname%.flac}.opus" ]; then 365 | rm "${fname%.flac}.opus" 366 | fi 367 | if [ ! -f "conversion-failure.log" ]; then 368 | touch "conversion-failure.log" 369 | chmod 0666 "conversion-failure.log" 370 | fi 371 | echo "$artistname :: $albumname :: $quality :: $filename.flac" >> "conversion-failure.log" 372 | fi 373 | done 374 | fi 375 | else 376 | echo "ERROR: opus-tools not installed, please install opus-tools to use this conversion feature" 377 | sleep 5 378 | fi 379 | fi 380 | if [ "${quality}" = aac ]; then 381 | if [ -x "$(command -v ffmpeg)" ]; then 382 | if find "${downloaddir}/" -name "*.flac" | read; then 383 | echo "Converting: $converttrackcount Tracks (Target Format: $targetformat (${bitrate}k))" 384 | for fname in "${downloaddir}"/*.flac; do 385 | filename="$(basename "${fname%.flac}")" 386 | if ffmpeg -loglevel warning -hide_banner -nostats -i "$fname" -n -vn -acodec aac -ab ${bitrate}k -movflags faststart "${fname%.flac}.m4a"; then 387 | echo "Converted: $filename" 388 | if [ -f "${fname%.flac}.m4a" ]; then 389 | rm "$fname" 390 | fi 391 | else 392 | echo "Conversion failed ($quality): $filename, performing cleanup..." 393 | if [ -f "${fname%.flac}.m4a" ]; then 394 | rm "${fname%.flac}.m4a" 395 | fi 396 | if [ ! -f "conversion-failure.log" ]; then 397 | touch "conversion-failure.log" 398 | chmod 0666 "conversion-failure.log" 399 | fi 400 | echo "$artistname :: $albumname :: $quality :: $filename.flac" >> "conversion-failure.log" 401 | fi 402 | done 403 | fi 404 | else 405 | echo "ERROR: ffmpeg not installed, please install ffmpeg to use this conversion feature" 406 | sleep 5 407 | fi 408 | fi 409 | if [ "${quality}" = alac ]; then 410 | if [ -x "$(command -v ffmpeg)" ]; then 411 | if find "${downloaddir}/" -name "*.flac" | read; then 412 | echo "Converting: $converttrackcount Tracks (Target Format: $targetformat)" 413 | for fname in "${downloaddir}"/*.flac; do 414 | filename="$(basename "${fname%.flac}")" 415 | if ffmpeg -loglevel warning -hide_banner -nostats -i "$fname" -n -vn -acodec alac -movflags faststart "${fname%.flac}.m4a"; then 416 | echo "Converted: $filename" 417 | if [ -f "${fname%.flac}.m4a" ]; then 418 | rm "$fname" 419 | fi 420 | else 421 | echo "Conversion failed: $filename, performing cleanup..." 422 | if [ -f "${fname%.flac}.m4a" ]; then 423 | rm "${fname%.flac}.m4a" 424 | fi 425 | if [ ! -f "conversion-failure.log" ]; then 426 | touch "conversion-failure.log" 427 | chmod 0666 "conversion-failure.log" 428 | fi 429 | echo "$artistname :: $albumname :: $quality :: $filename.flac" >> "conversion-failure.log" 430 | fi 431 | done 432 | fi 433 | else 434 | echo "ERROR: ffmpeg not installed, please install ffmpeg to use this conversion feature" 435 | sleep 5 436 | fi 437 | fi 438 | } 439 | 440 | Verify () { 441 | if [ $trackdlfallback = 0 ]; then 442 | if find "$downloaddir" -iname "*.flac" | read; then 443 | if ! [ -x "$(command -v flac)" ]; then 444 | echo "ERROR: FLAC verification utility not installed (ubuntu: apt-get install -y flac)" 445 | else 446 | for fname in "${downloaddir}"/*.flac; do 447 | filename="$(basename "$fname")" 448 | if flac -t --totally-silent "$fname"; then 449 | echo "Verified Track: $filename" 450 | else 451 | echo "Track Verification Error: \"$filename\" deleted...retrying download via track method" 452 | rm -rf "$downloaddir"/* 453 | sleep 0.5 454 | trackdlfallback=1 455 | fi 456 | done 457 | fi 458 | fi 459 | if find "$downloaddir" -iname "*.mp3" | read; then 460 | if ! [ -x "$(command -v mp3val)" ]; then 461 | echo "MP3VAL verification utility not installed (ubuntu: apt-get install -y mp3val)" 462 | else 463 | for fname in "${downloaddir}"/*.mp3; do 464 | filename="$(basename "$fname")" 465 | if mp3val -f -nb "$fname" > /dev/null; then 466 | echo "Verified Track: $filename" 467 | fi 468 | done 469 | fi 470 | fi 471 | elif [ $trackdlfallback = 1 ]; then 472 | if ! [ -x "$(command -v flac)" ]; then 473 | echo "ERROR: FLAC verification utility not installed (ubuntu: apt-get install -y flac)" 474 | else 475 | if find "$downloaddir" -iname "*.flac" -newer "$temptrackfile" | read; then 476 | find "$downloaddir" -iname "*.flac" -newer "$temptrackfile" -print0 | while IFS= read -r -d '' file; do 477 | filename="$(basename "$file")" 478 | if flac -t --totally-silent "$file"; then 479 | echo "Verified Track $tracknumber of $tracktotal: $trackname (Format: $fallbackqualitytext; Length: $trackdurationdisplay)" 480 | else 481 | rm "$file" 482 | if [ "$enablefallback" = true ]; then 483 | echo "Track Verification Error: \"$trackname\" deleted...retrying as MP3" 484 | origdlquality="$dlquality" 485 | dlquality="320" 486 | DownloadURL 487 | dlquality="$origdlquality" 488 | else 489 | echo "Verification Error: \"$trackname\" deleted..." 490 | echo "Fallback quality disabled, skipping..." 491 | echo "$artistname :: $albumname :: $fallbackqualitytext :: $trackname (${trackid[$track]})" >> "download-track-error.log" 492 | fi 493 | fi 494 | done 495 | fi 496 | fi 497 | if ! [ -x "$(command -v mp3val)" ]; then 498 | echo "MP3VAL verification utility not installed (ubuntu: apt-get install -y mp3val)" 499 | else 500 | if find "$downloaddir" -iname "*.mp3" -newer "$temptrackfile" | read; then 501 | find "$downloaddir" -iname "*.mp3" -newer "$temptrackfile" -print0 | while IFS= read -r -d '' file; do 502 | filename="$(basename "$file")" 503 | if mp3val -f -nb "$file" > /dev/null; then 504 | echo "Verified Track $tracknumber of $tracktotal: $trackname (Format: $fallbackqualitytext; Length: $trackdurationdisplay)" 505 | fi 506 | done 507 | fi 508 | fi 509 | fi 510 | } 511 | 512 | DLArtistArtwork () { 513 | if [ -d "$fullartistpath" ]; then 514 | echo "" 515 | echo "Archiving Artist Profile Picture" 516 | if [ ! -f "$fullartistpath/folder.jpg" ]; then 517 | if curl -sL --fail "${LidarrUrl}/api/v1/MediaCover/Artist/${LidArtistID}/poster.jpg?apikey=${LidarrApiKey}" -o "$fullartistpath/folder.jpg"; then 518 | if find "$fullartistpath/folder.jpg" -type f -size -16k | read; then 519 | echo "ERROR: Artist artwork is smaller than \"16k\"" 520 | echo "Fallback to deezer..." 521 | rm "$fullartistpath/folder.jpg" 522 | echo "" 523 | else 524 | echo "Downloaded 1 profile picture" 525 | echo "" 526 | fi 527 | else 528 | echo "ERROR: Lidarr artist artwork failure, fallback to deezer" 529 | fi 530 | fi 531 | if [ ! -f "$fullartistpath/folder.jpg" ]; then 532 | if curl -sL --fail "${artistartwork}" -o "$fullartistpath/folder.jpg"; then 533 | if find "$fullartistpath/folder.jpg" -type f -size -16k | read; then 534 | echo "ERROR: Artist artwork is smaller than \"16k\"" 535 | rm "$fullartistpath/folder.jpg" 536 | echo "" 537 | else 538 | echo "Downloaded 1 profile picture" 539 | echo "" 540 | fi 541 | else 542 | echo "Error downloading artist artwork" 543 | echo "" 544 | fi 545 | fi 546 | fi 547 | } 548 | 549 | DLAlbumArtwork () { 550 | if curl -sL --fail "${albumartworkurl}" -o "$downloaddir/folder.jpg"; then 551 | sleep 0.1 552 | else 553 | echo "Failed downloading album cover picture..." 554 | fi 555 | } 556 | 557 | Replaygain () { 558 | if ! [ -x "$(command -v flac)" ]; then 559 | echo "ERROR: METAFLAC replaygain utility not installed (ubuntu: apt-get install -y flac)" 560 | elif find "$downloaddir" -name "*.flac" | read; then 561 | find "$downloaddir" -name "*.flac" -exec metaflac --add-replay-gain "{}" + && echo "Replaygain: $replaygaintrackcount Tracks Tagged" 562 | fi 563 | } 564 | 565 | DurationCalc () { 566 | local T=$1 567 | local D=$((T/60/60/24)) 568 | local H=$((T/60/60%24)) 569 | local M=$((T/60%60)) 570 | local S=$((T%60)) 571 | (( $D > 0 )) && printf '%d days and ' $D 572 | (( $H > 0 )) && printf '%d:' $H 573 | (( $M > 0 )) && printf '%02d:' $M 574 | (( $D > 0 || $H > 0 || $M > 0 )) && printf '' 575 | printf '%02ds\n' $S 576 | } 577 | 578 | if [ "${LyricType}" = explicit ]; then 579 | LyricDLType="Explicit" 580 | elif [ "${LyricType}" = clean ]; then 581 | LyricDLType="Clean" 582 | else 583 | LyricDLType="Explicit Preferred" 584 | fi 585 | 586 | if [ "$VerifyTrackCount" = "true" ]; then 587 | vtc="Enabled" 588 | else 589 | vtc="Disabled" 590 | fi 591 | 592 | if [ "$upgrade" = "true" ]; then 593 | dlupgrade="Enabled" 594 | else 595 | dlupgrade="Disabled" 596 | fi 597 | 598 | ConfigSettings () { 599 | echo "START DEEZER ARCHIVING" 600 | echo "" 601 | echo "Global Settings" 602 | echo "Download Client: $deezloaderurl" 603 | echo "Download Directory: $downloaddir" 604 | echo "Download Quality: $targetformat" 605 | if [ "$quality" = "opus" ]; then 606 | echo "Download Bitrate: ${bitrate}k" 607 | elif [ "$quality" = "aac" ]; then 608 | echo "Download Bitrate: ${bitrate}k" 609 | elif [ "$quality" = "mp3" ]; then 610 | echo "Download Bitrate: ${bitrate}k" 611 | else 612 | echo "Download Bitrate: ${bitrate}" 613 | fi 614 | echo "Download Track Count Verification: $vtc" 615 | echo "Download Quality Upgrade: $dlupgrade" 616 | echo "Download Lyric Type: $LyricDLType" 617 | if [ "$TagWithBeets" = true ]; then 618 | echo "Beets Tagging: Enabled" 619 | else 620 | echo "Beets Tagging: Disabled" 621 | fi 622 | if [ "$KeepOnlyBeetsMatched" = true ]; then 623 | echo "Beets Skip Unmatched Files: Enabled" 624 | else 625 | echo "Beets Skip Unmatched Files: Disabled" 626 | fi 627 | if [ "$BeetsDeDupe" = true ]; then 628 | echo "Beets Deduping: Enabled" 629 | else 630 | echo "Beets Deduping: Disabled" 631 | fi 632 | echo "Total Artists To Process: $TotalLidArtistNames" 633 | echo "" 634 | echo "Begin archive process..." 635 | sleep 5s 636 | } 637 | 638 | if [ ! -d "$downloaddir" ]; then 639 | mkdir -p "$downloaddir" 640 | chmod 0777 "$downloaddir" 641 | fi 642 | 643 | lidarrartists () { 644 | 645 | if [ -f "$tempartistjson" ]; then 646 | rm "$tempartistjson" 647 | fi 648 | if [ -f "$tempalbumlistjson" ]; then 649 | rm "$tempalbumlistjson" 650 | fi 651 | if [ -f "$tempalbumjson" ]; then 652 | rm "$tempalbumjson" 653 | fi 654 | if [ -f "$temptrackfile" ]; then 655 | rm "$temptrackfile" 656 | fi 657 | if [ -f "$beetslibraryfile" ]; then 658 | rm "$beetslibraryfile" 659 | fi 660 | if [ -f "$beetslog" ]; then 661 | rm "$beetslog" 662 | fi 663 | rm -rf "$downloaddir"/* 664 | 665 | if curl -sL --fail "https://api.deezer.com/artist/$DeezerArtistID" -o "$tempartistjson"; then 666 | artistartwork=($(cat "$tempartistjson" | jq -r '.picture_xl')) 667 | artistname="$(cat "$tempartistjson" | jq -r '.name')" 668 | artistid="$(cat "$tempartistjson" | jq -r '.id')" 669 | artistalbumtotal="$(cat "$tempartistjson" | jq -r '.nb_album')" 670 | sanatizedartistname="$(echo "$artistname" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/')" 671 | shortartistpath="$artistname ($artistid)" 672 | fullartistpath="$LidArtistPath" 673 | sanatizedlidarrartistname="$(echo "$LidArtistNameCap" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/')" 674 | 675 | if [ -d "$fullartistpath" ]; then 676 | if [ -f "$fullartistpath/$tempartistjson" ]; then 677 | if [ "$upgrade" = true ]; then 678 | sleep 0.1 679 | else 680 | archivealbumtotal="$(cat "$fullartistpath/$tempartistjson" | jq -r '.nb_album')" 681 | if [ "$artistalbumtotal" = "$archivealbumtotal" ]; then 682 | echo "${artistnumber}/${TotalLidArtistNames}: Skipping \"$artistname\"... no new albums albums to process..." 683 | return 684 | fi 685 | fi 686 | fi 687 | if find "$fullartistpath" -iname "$tempalbumjson" | read; then 688 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 689 | rm "$fullartistpath/$artistalbumlistjson" 690 | sleep 0.1 691 | fi 692 | jq -s '.' "$fullartistpath"/*/"$tempalbumjson" > "$fullartistpath/$artistalbumlistjson" 693 | else 694 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 695 | rm "$fullartistpath/$artistalbumlistjson" 696 | sleep 0.1 697 | fi 698 | fi 699 | fi 700 | 701 | if [ "$artistname" == null ]; then 702 | echo "" 703 | echo "Error no artist returned with Deezer Artist ID \"$artistid\"" 704 | else 705 | if [ -f "$tempalbumlistjson" ]; then 706 | rm "$tempalbumlistjson" 707 | sleep 0.1 708 | fi 709 | 710 | if curl -sL --fail "https://api.deezer.com/artist/$artistid/albums&limit=1000" -o "$tempalbumlistjson"; then 711 | if [ "$LyricType" = explicit ]; then 712 | LyricDLType=" Explicit" 713 | albumlist=($(cat "$tempalbumlistjson" | jq -r ".data | .[]| select(.explicit_lyrics==true)| .id")) 714 | totalnumberalbumlist=($(cat "$tempalbumlistjson" | jq -r ".data | .[]| select(.explicit_lyrics==true)| .id" | wc -l)) 715 | elif [ "$LyricType" = clean ]; then 716 | LyricDLType=" Clean" 717 | albumlist=($(cat "$tempalbumlistjson" | jq -r ".data | .[]| select(.explicit_lyrics==false)| .id")) 718 | totalnumberalbumlist=($(cat "$tempalbumlistjson" | jq -r ".data | .[]| select(.explicit_lyrics==false)| .id" | wc -l)) 719 | else 720 | LyricDLType="" 721 | albumlist=($(cat "$tempalbumlistjson" | jq -r ".data | sort_by(.explicit_lyrics) | reverse | .[] | .id")) 722 | totalnumberalbumlist=($(cat "$tempalbumlistjson" | jq -r ".data | sort_by(.explicit_lyrics) | reverse | .[] | .id" | wc -l)) 723 | fi 724 | if [ "$totalnumberalbumlist" = 0 ]; then 725 | echo "" 726 | echo "Archiving: $artistname (ID: $artistid) ($artistnumber of $TotalLidArtistNames)" 727 | echo "ERROR: No albums found" 728 | if [ -f "$tempalbumlistjson" ]; then 729 | rm "$tempalbumlistjson" 730 | fi 731 | if [ -f "$tempalbumlistjson" ]; then 732 | rm "$tempalbumlistjson" 733 | fi 734 | sleep 0.1 735 | continue 736 | fi 737 | 738 | if [ -d "temp" ]; then 739 | sleep 0.1 740 | rm -rf "temp" 741 | fi 742 | 743 | for album in ${!albumlist[@]}; do 744 | if [ ! -d "temp" ]; then 745 | mkdir -p "temp" 746 | fi 747 | if curl -sL --fail "https://api.deezer.com/album/${albumlist[$album]}" -o "temp/${albumlist[$album]}-album.json"; then 748 | sleep 0.1 749 | else 750 | echo "Error getting album information" 751 | fi 752 | done 753 | 754 | if [ -f "downloadlist.json" ]; then 755 | rm "downloadlist.json" 756 | sleep 0.1 757 | fi 758 | 759 | jq -s '.' temp/*-album.json > "downloadlist.json" 760 | 761 | if [ -d "temp" ]; then 762 | sleep 0.1 763 | rm -rf "temp" 764 | fi 765 | 766 | orderedalbumlist=($(cat "downloadlist.json" | jq -r "sort_by(.explicit_lyrics, .nb_tracks) | reverse | .[] | .id")) 767 | 768 | echo "" 769 | echo "" 770 | echo "Archiving: $artistname (ID: $artistid) ($artistnumber of $TotalLidArtistNames)" 771 | 772 | if [ -d "$fullartistpath" ]; then 773 | if [ "$BeetsDeDupe" = true ]; then 774 | if [ -f "$beetslibraryfile" ]; then 775 | rm "$beetslibraryfile" 776 | fi 777 | if [ -f "$beetslog" ]; then 778 | rm "$beetslog" 779 | fi 780 | sleep 0.1 781 | echo "Importing existing library for Beets Dedupe matching" 782 | beet -c "$beetsconfig" -l "$beetslibraryfile" import -AWC "$fullartistpath" > /dev/null 783 | fi 784 | fi 785 | 786 | echo "Searching for albums... $totalnumberalbumlist Albums found" 787 | for album in ${!orderedalbumlist[@]}; do 788 | trackdlfallback=0 789 | albumnumber=$(( $album + 1 )) 790 | albumid="${orderedalbumlist[$album]}" 791 | albumurl="https://www.deezer.com/album/$albumid" 792 | albumname=$(cat "$tempalbumlistjson" | jq -r ".data | .[]| select(.id=="$albumid") | .title") 793 | albumnamesanatized="$(echo "$albumname" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/')" 794 | sanatizedfuncalbumname="${albumnamesanatized,,}" 795 | 796 | rm -rf "$downloaddir"/* 797 | 798 | if [ -f "$tempalbumjson" ]; then 799 | rm "$tempalbumjson" 800 | fi 801 | 802 | if [ "$quality" = flac ]; then 803 | dlquality="flac" 804 | bitrate="lossless" 805 | targetformat="FLAC" 806 | elif [ "$quality" = mp3 ]; then 807 | dlquality="320" 808 | bitrate="320" 809 | targetformat="MP3" 810 | elif [ "$quality" = alac ]; then 811 | dlquality="flac" 812 | bitrate="lossless" 813 | targetformat="ALAC" 814 | elif [ "$quality" = opus ]; then 815 | dlquality="flac" 816 | targetformat="OPUS" 817 | if [ -z "$bitrate" ]; then 818 | bitrate="128" 819 | fi 820 | elif [ "$quality" = aac ]; then 821 | dlquality="flac" 822 | targetformat="AAC" 823 | if [ -z "$bitrate" ]; then 824 | bitrate="320" 825 | fi 826 | fi 827 | 828 | sleep 0.1 829 | 830 | if curl -sL --fail "https://api.deezer.com/album/$albumid" -o "$tempalbumjson"; then 831 | tracktotal=$(cat "$tempalbumjson" | jq -r ".nb_tracks") 832 | actualtracktotal=$(cat "$tempalbumjson" | jq -r ".tracks.data | .[] | .id" | wc -l) 833 | albumdartistid=$(cat "$tempalbumjson" | jq -r ".artist | .id") 834 | albumlyrictype="$(cat "$tempalbumjson" | jq -r ".explicit_lyrics")" 835 | albumartworkurl="$(cat "$tempalbumjson" | jq -r ".cover_xl")" 836 | albumdate="$(cat "$tempalbumjson" | jq -r ".release_date")" 837 | albumyear=$(echo ${albumdate::4}) 838 | albumtype="$(cat "$tempalbumjson" | jq -r ".record_type")" 839 | albumtypecap="${albumtype^^}" 840 | albumduration=$(cat "$tempalbumjson" | jq -r ".duration") 841 | albumdurationdisplay=$(DurationCalc $albumduration) 842 | albumtimeout=$(($albumduration*$albumtimeoutpercentage/100)) 843 | albumtimeoutdisplay=$(DurationCalc $albumtimeout) 844 | albumfallbacktimout=$(($albumduration*2)) 845 | 846 | if [ "$downloadalbums" != true ]; then 847 | if [ "$albumtype" = "album" ]; then 848 | continue 849 | fi 850 | fi 851 | 852 | if [ "$downloadcompilations" != true ]; then 853 | if [ "$albumtype" = "compile" ]; then 854 | continue 855 | fi 856 | fi 857 | 858 | if [ "$downloadeps" != true ]; then 859 | if [ "$albumtype" = "ep" ]; then 860 | continue 861 | fi 862 | fi 863 | 864 | if [ "$downloadsingles" != true ]; then 865 | if [ "$albumtype" = "single" ]; then 866 | continue 867 | fi 868 | fi 869 | 870 | if [ "$albumlyrictype" = true ]; then 871 | albumlyrictype="Explicit" 872 | elif [ "$albumlyrictype" = false ]; then 873 | albumlyrictype="Clean" 874 | fi 875 | 876 | libalbumfolder="$sanatizedlidarrartistname - $albumtypecap - $albumyear - $albumnamesanatized ($albumlyrictype)" 877 | 878 | if [ "$albumdartistid" -ne "$artistid" ]; then 879 | continue 880 | fi 881 | 882 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 883 | 884 | if cat "$fullartistpath/$artistalbumlistjson" | grep "$albumid" | read; then 885 | archivequality="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$albumid) | .dlquality")" 886 | archivefoldername="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$albumid) | .foldername")" 887 | archivebitrate="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$albumid) | .bitrate")" 888 | archivetrackcount=$(find "$fullartistpath/$archivefoldername" -type f -iregex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) 889 | if [ "$upgrade" = true ]; then 890 | if [ "$targetformat" = "$archivequality" ]; then 891 | if [ "$archivebitrate" = "lossless" ]; then 892 | if [ "$VerifyTrackCount" = true ]; then 893 | if [ "$tracktotal" = "$archivetrackcount" ]; then 894 | echo "Previously Downloaded \"$albumname\", skipping..." 895 | continue 896 | else 897 | echo "" 898 | echo "ERROR: Archived Track Count ($archivetrackcount) and Album Track Count ($tracktotal) do not match, missing files... attempting re-download..." 899 | echo "" 900 | if [ -d "$fullartistpath/$archivefoldername" ]; then 901 | rm -rf "$fullartistpath/$archivefoldername" 902 | sleep 0.1 903 | fi 904 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 905 | rm "$fullartistpath/$artistalbumlistjson" 906 | sleep 0.1 907 | fi 908 | jq -s '.' "$fullartistpath"/*/"$tempalbumjson" > "$fullartistpath/$artistalbumlistjson" 909 | fi 910 | else 911 | echo "Previously Downloaded \"$albumname\", skipping..." 912 | continue 913 | fi 914 | elif [ "${bitrate}k" = "$archivebitrate" ]; then 915 | if [ "$VerifyTrackCount" = true ]; then 916 | if [ "$tracktotal" = "$archivetrackcount" ]; then 917 | echo "Previously Downloaded \"$albumname\", skipping..." 918 | continue 919 | else 920 | echo "" 921 | echo "ERROR: Archived Track Count ($archivetrackcount) and Album Track Count ($tracktotal) do not match, missing files... attempting re-download..." 922 | echo "" 923 | if [ -d "$fullartistpath/$archivefoldername" ]; then 924 | rm -rf "$fullartistpath/$archivefoldername" 925 | sleep 0.1 926 | fi 927 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 928 | rm "$fullartistpath/$artistalbumlistjson" 929 | sleep 0.1 930 | fi 931 | jq -s '.' "$fullartistpath"/*/"$tempalbumjson" > "$fullartistpath/$artistalbumlistjson" 932 | fi 933 | else 934 | echo "Previously Downloaded \"$albumname\", skipping..." 935 | continue 936 | fi 937 | else 938 | echo "" 939 | echo "Previously Downloaded \"$albumname\", does not match requested quality... attempting upgrade..." 940 | echo "" 941 | if [ -d "$fullartistpath/$archivefoldername" ]; then 942 | rm -rf "$fullartistpath/$archivefoldername" 943 | sleep 0.1 944 | fi 945 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 946 | rm "$fullartistpath/$artistalbumlistjson" 947 | sleep 0.1 948 | fi 949 | jq -s '.' "$fullartistpath"/*/"$tempalbumjson" > "$fullartistpath/$artistalbumlistjson" 950 | fi 951 | else 952 | echo "" 953 | echo "Previously Downloaded \"$albumname\", does not match requested quality... attempting upgrade..." 954 | echo "" 955 | if [ -d "$fullartistpath/$archivefoldername" ]; then 956 | rm -rf "$fullartistpath/$archivefoldername" 957 | sleep 0.1 958 | fi 959 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 960 | rm "$fullartistpath/$artistalbumlistjson" 961 | sleep 0.1 962 | fi 963 | jq -s '.' "$fullartistpath"/*/"$tempalbumjson" > "$fullartistpath/$artistalbumlistjson" 964 | fi 965 | elif [ "$VerifyTrackCount" = true ]; then 966 | if [ "$tracktotal" = "$archivetrackcount" ]; then 967 | echo "Previously Downloaded \"$albumname\", skipping..." 968 | continue 969 | else 970 | echo "" 971 | echo "ERROR: Archived Track Count ($archivetrackcount) and Album Track Count ($tracktotal) do not match, missing files... attempting re-download..." 972 | echo "" 973 | if [ -d "$fullartistpath/$archivefoldername" ]; then 974 | rm -rf "$fullartistpath/$archivefoldername" 975 | sleep 0.1 976 | fi 977 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 978 | rm "$fullartistpath/$artistalbumlistjson" 979 | sleep 0.1 980 | fi 981 | jq -s '.' "$fullartistpath"/*/"$tempalbumjson" > "$fullartistpath/$artistalbumlistjson" 982 | fi 983 | else 984 | echo "Previously Downloaded \"$albumname\", skipping..." 985 | continue 986 | fi 987 | fi 988 | fi 989 | 990 | if [ "$VerifyTrackCount" = true ]; then 991 | if [ "$tracktotal" -ne "$actualtracktotal" ]; then 992 | continue 993 | fi 994 | fi 995 | 996 | if [ -f "$fullartistpath/$artistalbumlistjson" ]; then 997 | if [ "$debug" = "true" ]; then 998 | echo "" 999 | fi 1000 | 1001 | archivealbumid="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.record_type==\"$albumtype\") | select(.sanatized_album_name==\"$sanatizedfuncalbumname\") | .id")" 1002 | if [ ! -z "$archivealbumid" ]; then 1003 | archivealbumname="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$archivealbumid) | .title")" 1004 | archivealbumlyrictype="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$archivealbumid) | .explicit_lyrics")" 1005 | archivealbumtracktotal="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$archivealbumid) | .nb_tracks")" 1006 | archivealbumreleasetype="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$archivealbumid) | .record_type")" 1007 | archivealbumdate="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$archivealbumid) | .release_date")" 1008 | archivealbumfoldername="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | select(.id==$archivealbumid) | .foldername")" 1009 | archivealbumyear="$(echo ${archivealbumdate::4})" 1010 | 1011 | if [ "$archivealbumlyrictype" = true ]; then 1012 | archivealbumlyrictype="Explicit" 1013 | elif [ "$archivealbumlyrictype" = false ]; then 1014 | archivealbumlyrictype="Clean" 1015 | fi 1016 | 1017 | if [ "$debug" = "true" ]; then 1018 | echo "" 1019 | echo "Dedupe info:" 1020 | echo "Incoming Album: $albumname" 1021 | echo "Incoming Album: $sanatizedfuncalbumname" 1022 | echo "Incoming Album: $tracktotal Tracks" 1023 | echo "Incoming Album: $albumtype" 1024 | echo "Incoming Album: $albumlyrictype" 1025 | echo "Incoming Album: $albumyear" 1026 | echo "Incoming Album: $libalbumfolder" 1027 | echo "" 1028 | echo "Archive: $archivealbumname" 1029 | echo "Archive: $archivealbumtracktotal Tracks" 1030 | echo "Archive: $archivealbumreleasetype" 1031 | echo "Archive: $archivealbumlyrictype" 1032 | echo "Archive: $archivealbumyear" 1033 | echo "Archive: $archivealbumfoldername" 1034 | echo "" 1035 | fi 1036 | 1037 | if [ "$albumlyrictype" = "Explicit" ]; then 1038 | if [ "$debug" = "true" ]; then 1039 | echo "Dupe found $albumname :: check 1" 1040 | fi 1041 | if [ "$archivealbumlyrictype" = "Clean" ]; then 1042 | if [ "$debug" = "true" ]; then 1043 | echo "Incoming album is explicit, exixsiting is clean, upgrading... :: check 2" 1044 | fi 1045 | rm -rf "$fullartistpath/$archivealbumfoldername" 1046 | sleep 0.1 1047 | else 1048 | if [ "$albumyear" -eq "$archivealbumyear" ]; then 1049 | if [ "$debug" = "true" ]; then 1050 | echo "Incoming album: $albumname has same year as existing :: check 3" 1051 | fi 1052 | if [ "$tracktotal" -gt "$archivealbumtracktotal" ]; then 1053 | if [ "$debug" = "true" ]; then 1054 | echo "Incoming album: $albumname, has more total tracks: $tracktotal vs $archivealbumtracktotal :: check 4" 1055 | fi 1056 | rm -rf "$fullartistpath/$archivealbumfoldername" 1057 | sleep 0.1 1058 | else 1059 | continue 1060 | fi 1061 | else 1062 | if [ "$debug" = "true" ]; then 1063 | echo "Year does not match new: $albumyear; archive: $arhcivealbumyear :: check 5" 1064 | fi 1065 | fi 1066 | fi 1067 | fi 1068 | 1069 | if [ "$albumlyrictype" = "Clean" ]; then 1070 | if [ "$debug" = "true" ]; then 1071 | echo "Dupe found $albumname :: check 10" 1072 | fi 1073 | if [ "$archivealbumlyrictype" = "Explicit" ]; then 1074 | if [ "$debug" = "true" ]; then 1075 | echo "Archived album: $archivealbumname is Explicit, Skipping... :: check 11" 1076 | fi 1077 | continue 1078 | fi 1079 | 1080 | if [ "$albumyear" -eq "$archivealbumyear" ]; then 1081 | if [ "$debug" = "true" ]; then 1082 | echo "Incoming album: $albumname has same year as existing :: check 12" 1083 | fi 1084 | if [ "$tracktotal" -gt "$archivealbumtracktotal" ]; then 1085 | if [ "$debug" = "true" ]; then 1086 | echo "Incoming album: $albumname, has more total tracks: $tracktotal vs $archivealbumtracktotal :: check 13" 1087 | fi 1088 | rm -rf "$fullartistpath/$archivealbumfoldername" 1089 | sleep 0.1 1090 | else 1091 | continue 1092 | fi 1093 | else 1094 | if [ "$debug" = "true" ]; then 1095 | echo "Year does not match new: $albumyear; archive: $arhcivealbumyear :: check 14" 1096 | fi 1097 | fi 1098 | 1099 | fi 1100 | fi 1101 | 1102 | if [ "$debug" = "true" ]; then 1103 | echo "" 1104 | sleep 3 1105 | fi 1106 | fi 1107 | 1108 | if [[ "$albumtimeout" -le 60 ]]; then 1109 | albumtimeout="60" 1110 | albumfallbacktimout=$(($albumtimeout*2)) 1111 | albumtimeoutdisplay=$(DurationCalc $albumtimeout) 1112 | fi 1113 | if [ ! -f "$tempalbumfile" ]; then 1114 | touch "$tempalbumfile" 1115 | fi 1116 | echo "" 1117 | echo "Archiving \"$artistname\" (ID: $artistid) ($artistnumber of $TotalLidArtistNames) in progress..." 1118 | echo "Archiving Album: $albumname (ID: $albumid)" 1119 | echo "Album Link: $albumurl" 1120 | echo "Album Release Year: $albumyear" 1121 | echo "Album Release Type: $albumtype" 1122 | echo "Album Lyric Type: $albumlyrictype" 1123 | echo "Album Duration: $albumdurationdisplay" 1124 | echo "Album Track Count: $tracktotal" 1125 | 1126 | AlbumDL 1127 | 1128 | if [ $trackdlfallback = 1 ]; then 1129 | TrackMethod 1130 | fi 1131 | DLAlbumArtwork 1132 | downloadedtrackcount=$(find "$downloaddir" -type f -iregex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) 1133 | downloadedlyriccount=$(find "$downloaddir" -type f -iname "*.lrc" | wc -l) 1134 | downloadedalbumartcount=$(find "$downloaddir" -type f -iname "folder.*" | wc -l) 1135 | replaygaintrackcount=$(find "$downloaddir" -type f -iname "*.flac" | wc -l) 1136 | converttrackcount=$(find "$downloaddir" -type f -iname "*.flac" | wc -l) 1137 | echo "Downloaded: $downloadedtrackcount Tracks" 1138 | echo "Downloaded: $downloadedlyriccount Synced Lyrics" 1139 | echo "Downloaded: $downloadedalbumartcount Album Cover" 1140 | 1141 | if [ "$VerifyTrackCount" = true ]; then 1142 | if [ "$tracktotal" -ne "$downloadedtrackcount" ]; then 1143 | echo "ERROR: Downloaded Track Count ($downloadedtrackcount) and Album Track Count ($tracktotal) do not match, missing files... re-attempt download as individual tracks..." 1144 | rm -rf "$downloaddir"/* 1145 | sleep 0.1 1146 | trackdlfallback=1 1147 | TrackMethod 1148 | DLAlbumArtwork 1149 | downloadedtrackcount=$(find "$downloaddir" -type f -iregex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) 1150 | downloadedlyriccount=$(find "$downloaddir" -type f -iname "*.lrc" | wc -l) 1151 | downloadedalbumartcount=$(find "$downloaddir" -type f -iname "folder.*" | wc -l) 1152 | replaygaintrackcount=$(find "$downloaddir" -type f -iname "*.flac" | wc -l) 1153 | converttrackcount=$(find "$downloaddir" -type f -iname "*.flac" | wc -l) 1154 | echo "Downloaded: $downloadedtrackcount Tracks" 1155 | echo "Downloaded: $downloadedlyriccount Synced Lyrics" 1156 | echo "Downloaded: $downloadedalbumartcount Album Cover" 1157 | if [ "$tracktotal" -ne "$downloadedtrackcount" ]; then 1158 | echo "ERROR: Downloaded Track Count ($downloadedtrackcount) and Album Track Count ($tracktotal) do not match, missing files... skipping import..." 1159 | rm -rf "$downloaddir"/* 1160 | sleep 0.1 1161 | continue 1162 | fi 1163 | fi 1164 | fi 1165 | 1166 | beetsmatched="false" 1167 | 1168 | if [ "$TagWithBeets" = true ]; then 1169 | 1170 | if [ "$BeetsDeDupe" != true ]; then 1171 | if [ -f "$beetslibraryfile" ]; then 1172 | rm "$beetslibraryfile" 1173 | sleep 0.1 1174 | fi 1175 | if [ -f "$beetslog" ]; then 1176 | rm "$beetslog" 1177 | sleep 0.1 1178 | fi 1179 | fi 1180 | 1181 | if [ -f "$downloaddir/beets-match" ]; then 1182 | rm "$downloaddir/beets-match" 1183 | sleep 0.1 1184 | fi 1185 | 1186 | touch "$downloaddir/beets-match" 1187 | 1188 | sleep 0.1 1189 | 1190 | beet -c "$beetsconfig" -l "$beetslibraryfile" import -q "$downloaddir" > /dev/null 1191 | 1192 | if find "$downloaddir" -type f -iregex ".*/.*\.\(flac\|mp3\)" -newer "$downloaddir/beets-match" | read; then 1193 | beetsmatched="true" 1194 | echo "Tagged with Beets" 1195 | else 1196 | beetsmatched="false" 1197 | echo "Error: Unable to match with Beets" 1198 | 1199 | if [ "$MoveBeetsUnMatched" = true ]; then 1200 | 1201 | if [ ! -d "$beetsunmatcheddirectory/$artistdir" ]; then 1202 | mkdir -p "$beetsunmatcheddirectory/$artistdir" 1203 | fi 1204 | if [ ! -d "$beetsunmatcheddirectory/$artistdir/$libalbumfolder" ]; then 1205 | echo "Moving to Beets Unmatched directory" 1206 | 1207 | if [ "$replaygaintaggingflac" = true ]; then 1208 | if [ "$quality" = flac ]; then 1209 | Replaygain 1210 | fi 1211 | fi 1212 | 1213 | if [ "$replaygaintaggingopus" = true ]; then 1214 | if [ "$quality" = opus ]; then 1215 | Replaygain 1216 | fi 1217 | fi 1218 | 1219 | Convert 1220 | 1221 | if [ -f "$downloaddir/beets-match" ]; then 1222 | rm "$downloaddir/beets-match" 1223 | sleep 0.1 1224 | fi 1225 | 1226 | mkdir -p "$beetsunmatcheddirectory/$artistdir/$libalbumfolder" 1227 | 1228 | for file in "$downloaddir"/*; do 1229 | mv "$file" "$beetsunmatcheddirectory/$artistdir/$libalbumfolder"/ 1230 | done 1231 | 1232 | rm -rf "$downloaddir"/* 1233 | sleep 0.1 1234 | 1235 | if [ -d "$beetsunmatcheddirectory/$artistdir" ]; then 1236 | find "$beetsunmatcheddirectory/$artistdir" -type d -exec chmod 0777 "{}" \; 1237 | find "$beetsunmatcheddirectory/$artistdir" -type f -exec chmod 0666 "{}" \; 1238 | fi 1239 | 1240 | continue 1241 | else 1242 | rm -rf "$downloaddir"/* 1243 | sleep 0.1 1244 | continue 1245 | fi 1246 | fi 1247 | 1248 | if [ "$KeepOnlyBeetsMatched" = true ]; then 1249 | rm -rf "$downloaddir"/* 1250 | sleep 0.1 1251 | continue 1252 | fi 1253 | fi 1254 | 1255 | if [ -f "$downloaddir/beets-match" ]; then 1256 | rm "$downloaddir/beets-match" 1257 | sleep 0.1 1258 | fi 1259 | 1260 | if [ "$BeetsDeDupe" != true ]; then 1261 | if [ -f "$beetslibraryfile" ]; then 1262 | rm "$beetslibraryfile" 1263 | sleep 0.1 1264 | fi 1265 | if [ -f "$beetslog" ]; then 1266 | rm "$beetslog" 1267 | sleep 0.1 1268 | fi 1269 | fi 1270 | 1271 | fi 1272 | 1273 | if [ "$replaygaintaggingflac" = true ]; then 1274 | if [ "$quality" = flac ]; then 1275 | Replaygain 1276 | fi 1277 | fi 1278 | 1279 | if [ "$replaygaintaggingopus" = true ]; then 1280 | if [ "$quality" = opus ]; then 1281 | Replaygain 1282 | fi 1283 | fi 1284 | 1285 | Convert 1286 | 1287 | if [ -d "$fullartistpath/$libalbumfolder" ]; then 1288 | rm -rf "$fullartistpath/$libalbumfolder" 1289 | sleep 0.5s 1290 | fi 1291 | 1292 | mkdir -p "$fullartistpath/$libalbumfolder" 1293 | 1294 | for file in "$downloaddir"/*; do 1295 | mv "$file" "$fullartistpath/$libalbumfolder"/ 1296 | done 1297 | 1298 | if find "$fullartistpath/$libalbumfolder" -iname "*.mp3" | read; then 1299 | archivequality="MP3" 1300 | archivebitrate="${bitrate}k" 1301 | elif find "$fullartistpath/$libalbumfolder" -iname "*.flac" | read; then 1302 | archivequality="FLAC" 1303 | archivebitrate="${bitrate}" 1304 | elif find "$fullartistpath/$libalbumfolder" -iname "*.opus" | read; then 1305 | archivequality="OPUS" 1306 | archivebitrate="${bitrate}k" 1307 | elif find "$fullartistpath/$libalbumfolder" -iname "*.m4a" | read; then 1308 | if [ "$quality" = alac ]; then 1309 | archivequality="ALAC" 1310 | archivebitrate="${bitrate}" 1311 | fi 1312 | if [ "$quality" = aac ]; then 1313 | archivequality="AAC" 1314 | archivebitrate="${bitrate}k" 1315 | 1316 | fi 1317 | fi 1318 | echo "Archiving Album: $albumname (Format: $archivequality ($archivebitrate)) complete!" 1319 | 1320 | jq ". + {\"sanatized_album_name\": \"$sanatizedfuncalbumname\"} + {\"foldername\": \"$libalbumfolder\"} + {\"artistpath\": \"$fullartistpath\"} + {\"dlquality\": \"$archivequality\"} + {\"bitrate\": \"$archivebitrate\"} + {\"beetsmatched\": \"$beetsmatched\"}" "$tempalbumjson" > "$fullartistpath/$libalbumfolder/$tempalbumjson" 1321 | 1322 | LidarrProcessIt=$(curl -s $LidarrUrl/api/v1/command -X POST -d "{\"name\": \"RescanFolders\", \"folders\": [\"$fullartistpath/$libalbumfolder\"]}" --header "X-Api-Key:${LidarrApiKey}" ); 1323 | echo "Notified Lidarr to scan ${LidArtistNameCap} :: $libalbumfolder" 1324 | 1325 | if [ -f "$tempalbumfile" ]; then 1326 | rm "$tempalbumfile" 1327 | fi 1328 | rm -rf "$downloaddir"/* 1329 | sleep 0.1 1330 | else 1331 | echo "Error contacting Deezer for album information" 1332 | fi 1333 | if [ -d "$fullartistpath" ]; then 1334 | jq -s '.' "$fullartistpath"/*/"$tempalbumjson" > "$fullartistpath/$artistalbumlistjson" 1335 | fi 1336 | if [ -f "$tempalbumjson" ]; then 1337 | rm "$tempalbumjson" 1338 | fi 1339 | if [ -d "$fullartistpath" ]; then 1340 | find "$fullartistpath" -type d -exec chmod 0777 "{}" \; 1341 | find "$fullartistpath" -type f -exec chmod 0666 "{}" \; 1342 | fi 1343 | done 1344 | 1345 | DLArtistArtwork 1346 | if [ -d "$fullartistpath" ]; then 1347 | totalalbumsarchived="$(cat "$fullartistpath/$artistalbumlistjson" | jq -r ".[] | .id" | wc -l)" 1348 | echo "" 1349 | if [ "$totalalbumsarchived" = "$totalnumberalbumlist" ]; then 1350 | echo "Archived $totalalbumsarchived Albums" 1351 | else 1352 | echo "Archived $totalalbumsarchived of $totalnumberalbumlist Albums (Some Dupes found... and removed...)" 1353 | fi 1354 | fi 1355 | echo "Archiving $artistname complete!" 1356 | echo "" 1357 | if [ -d "$fullartistpath" ]; then 1358 | find "$fullartistpath" -type d -exec chmod 0777 "{}" \; 1359 | find "$fullartistpath" -type f -exec chmod 0666 "{}" \; 1360 | fi 1361 | if [ -f "$tempalbumlistjson" ]; then 1362 | rm "$tempalbumlistjson" 1363 | sleep 0.1 1364 | fi 1365 | if [ -f "$tempalbumfile" ]; then 1366 | rm "$tempalbumfile" 1367 | sleep 0.1 1368 | fi 1369 | if [ -f "downloadlist.json" ]; then 1370 | rm "downloadlist.json" 1371 | sleep 0.1 1372 | fi 1373 | fi 1374 | fi 1375 | else 1376 | echo "Error contacting Deezer for artist information" 1377 | fi 1378 | if [ -d "$fullartistpath" ]; then 1379 | if [ -f "$fullartistpath/$tempartistjson" ]; then 1380 | rm "$fullartistpath/$tempartistjson" 1381 | sleep 0.1 1382 | fi 1383 | if [ -f "$tempartistjson" ]; then 1384 | mv "$tempartistjson" "$fullartistpath"/ 1385 | fi 1386 | if [ -d "$fullartistpath" ]; then 1387 | jq -s '.' "$fullartistpath"/*/"$tempalbumjson" > "$fullartistpath/$artistalbumlistjson" 1388 | fi 1389 | 1390 | fi 1391 | sleep 0.1 1392 | } 1393 | 1394 | ArtistsLidarrReq 1395 | 1396 | ##################################################################################################### 1397 | # Script End # 1398 | ##################################################################################################### 1399 | exit 0 1400 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/README.md: -------------------------------------------------------------------------------- 1 | # Script Information 2 | These scripts are designed to be used with LinuxServer.io Ubuntu based docker containers 3 | 4 | ## Script Descriptions 5 | 6 | #### ffmpeg_install.bash 7 | Compiles and installs ffmpeg 8 | 9 | #### mkvtoolnix_install.bash 10 | Installs mkvtoolnix 11 | 12 | #### audio_tools_install.bash 13 | Installs mp3val, flac 14 | 15 | #### mp4_automator.bash 16 | Installs mp4 automator script to the following location: /config/scripts/sickbeard_mp4_automator
17 | ###### Important: 18 | Do not use inconjuction with the mkvtoolnix_install.bash and ffmpeg_install.bash script. This script will also install both utlities 19 | 20 | #### sabnzbd_script_setup.bash 21 | Automatically downloads and installs sabnzbd post processing scripts found here: https://github.com/RandomNinjaAtk/Scripts/tree/master/sabnzbdr
22 | ###### Important: 23 | 1. You need to use ffmpeg_install.bash, mkvtoolnix_install.bash, audio_tools_install.bash for full functionality. 24 | 2. After initial run of the script, configure sabnzbd to point to the scripts directory location "/config/scripts" 25 | 26 | ## Script Usage 27 | 28 | 1. Create a "custom-cont-init.d" folder in the "/config/" of your desired ls.io docker container 29 | 1. Download the scripts from this repo 30 | 1. Copy the scripts into the "/config/custom-cont-init.d/" 31 | 1. Restart docker container, scripts will automatically run on startup 32 | 33 | For additional information, visit the following link: 34 | https://blog.linuxserver.io/2019/09/14/customizing-our-containers/ 35 | 36 | ## Compatibility Testing 37 | These scripts have been tested to successfully install on the following containers: 38 | 39 | 1. sabnzbd 40 | 1. lidarr 41 | 1. sonarr 42 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/audio_tools_install.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "==========INSTALLING AUDIO TOOLS===========" 3 | if ! [ -x "$(command -v mp3val)" ]; then 4 | echo "START MP3VAL INSTALLTION" 5 | apt-get update -qq 6 | if { apt-get install -y -qq mp3val; }; then 7 | apt-get purge --auto-remove -y 8 | apt-get clean 9 | echo "INSTALLATION SUCCESSFUL" 10 | else 11 | echo "ERROR: INSTALLTION UNSUCCESSFUL" 12 | fi 13 | else 14 | echo "MP3VAL ALREADY INSTALLED" 15 | fi 16 | if ! [ -x "$(command -v flac)" ]; then 17 | echo "START FLAC INSTALLTION" 18 | apt-get update -qq 19 | if { apt-get install -y -qq flac; }; then 20 | apt-get purge --auto-remove -y 21 | apt-get clean 22 | echo "INSTALLATION SUCCESSFUL" 23 | else 24 | echo "ERROR: INSTALLTION UNSUCCESSFUL" 25 | fi 26 | else 27 | echo "FLAC ALREADY INSTALLED" 28 | fi 29 | if ! [ -x "$(command -v ffmpeg)" ]; then 30 | echo "START FFMPEG INSTALLTION" 31 | apt-get update -qq 32 | if { apt-get install -y -qq ffmpeg; }; then 33 | apt-get purge --auto-remove -y 34 | apt-get clean 35 | echo "INSTALLATION SUCCESSFUL" 36 | else 37 | echo "ERROR: INSTALLTION UNSUCCESSFUL" 38 | fi 39 | else 40 | echo "FFMPEG ALREADY INSTALLED" 41 | fi 42 | echo "=====AUDIO TOOLS INSTALLATION COMPLETE=====" 43 | exit 0 44 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/ffmpeg_install.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "=====FFMPEG INSTALLATION SCRIPT=====" 3 | if ! [ -x "$(command -v ffmpeg)" ]; then 4 | echo "START INSTALLING FFMPEG" 5 | apt-get update -qq && apt-get -qq -y install \ 6 | autoconf \ 7 | automake \ 8 | build-essential \ 9 | cmake \ 10 | git-core \ 11 | libass-dev \ 12 | libfreetype6-dev \ 13 | libsdl2-dev \ 14 | libtool \ 15 | libva-dev \ 16 | libvdpau-dev \ 17 | libvorbis-dev \ 18 | libxcb1-dev \ 19 | libxcb-shm0-dev \ 20 | libxcb-xfixes0-dev \ 21 | pkg-config \ 22 | texinfo \ 23 | wget \ 24 | zlib1g-dev 25 | 26 | rm -rf ~/ffmpeg_sources ~/bin ~/ffmpeg_build 27 | mkdir -p ~/ffmpeg_sources ~/bin && \ 28 | 29 | echo "COMPILING NASM" 30 | cd ~/ffmpeg_sources && \ 31 | wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2 && \ 32 | tar xjvf nasm-2.14.02.tar.bz2 && \ 33 | cd nasm-2.14.02 && \ 34 | ./autogen.sh && \ 35 | PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" && \ 36 | make && \ 37 | make install 38 | echo "" 39 | 40 | echo "COMPILING YASM" 41 | cd ~/ffmpeg_sources && \ 42 | wget -O yasm-1.3.0.tar.gz https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz && \ 43 | tar xzvf yasm-1.3.0.tar.gz && \ 44 | cd yasm-1.3.0 && \ 45 | ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" && \ 46 | make && \ 47 | make install 48 | echo "" 49 | 50 | echo "COMPILING X264" 51 | cd ~/ffmpeg_sources && \ 52 | git -C x264 pull 2> /dev/null || git clone --depth 1 https://code.videolan.org/videolan/x264.git && \ 53 | cd x264 && \ 54 | PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --enable-pic && \ 55 | PATH="$HOME/bin:$PATH" make && \ 56 | make install 57 | echo "" 58 | 59 | echo "COMPILING NVENC" 60 | cd ~/ffmpeg_sources && \ 61 | git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git 62 | cd nv-codec-headers 63 | ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" && \ 64 | make && \ 65 | make install 66 | echo "" 67 | 68 | echo "COMPILING X265" 69 | apt-get -qq -y install mercurial libnuma-dev && \ 70 | cd ~/ffmpeg_sources && \ 71 | if cd x265 2> /dev/null; then hg pull && hg update && cd ..; else hg clone https://bitbucket.org/multicoreware/x265; fi && \ 72 | cd x265/build/linux && \ 73 | PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED=off ../../source && \ 74 | PATH="$HOME/bin:$PATH" make && \ 75 | make install 76 | echo "" 77 | 78 | echo "COMPILING LIBVPX" 79 | cd ~/ffmpeg_sources && \ 80 | git -C libvpx pull 2> /dev/null || git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git && \ 81 | cd libvpx && \ 82 | PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --as=yasm && \ 83 | PATH="$HOME/bin:$PATH" make && \ 84 | make install 85 | echo "" 86 | 87 | echo "COMPILING fdk-aac" 88 | cd ~/ffmpeg_sources && \ 89 | git -C fdk-aac pull 2> /dev/null || git clone --depth 1 https://github.com/mstorsjo/fdk-aac && \ 90 | cd fdk-aac && \ 91 | autoreconf -fiv && \ 92 | ./configure --prefix="$HOME/ffmpeg_build" --disable-shared && \ 93 | make && \ 94 | make install 95 | echo "" 96 | 97 | echo "COMPILING lame" 98 | cd ~/ffmpeg_sources && \ 99 | wget -O lame-3.100.tar.gz https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz && \ 100 | tar xzvf lame-3.100.tar.gz && \ 101 | cd lame-3.100 && \ 102 | PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --disable-shared --enable-nasm && \ 103 | PATH="$HOME/bin:$PATH" make && \ 104 | make install 105 | echo "" 106 | 107 | echo "COMPILING libopus" 108 | cd ~/ffmpeg_sources && \ 109 | git -C opus pull 2> /dev/null || git clone --depth 1 https://github.com/xiph/opus.git && \ 110 | cd opus && \ 111 | ./autogen.sh && \ 112 | ./configure --prefix="$HOME/ffmpeg_build" --disable-shared && \ 113 | make && \ 114 | make install 115 | echo "" 116 | 117 | echo "COMPILING av1" 118 | cd ~/ffmpeg_sources && \ 119 | git -C aom pull 2> /dev/null || git clone --depth 1 https://aomedia.googlesource.com/aom && \ 120 | mkdir -p aom_build && \ 121 | cd aom_build && \ 122 | PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED=off -DENABLE_NASM=on ../aom && \ 123 | PATH="$HOME/bin:$PATH" make && \ 124 | make install 125 | echo "" 126 | 127 | echo "MOVING BINARIES" 128 | find "/usr/bin/" -type f -iname "lame" -exec rm {} \; 129 | find "/usr/bin/" -type f -iname "nasm" -exec rm {} \; 130 | find "/usr/bin/" -type f -iname "ndisasm" -exec rm {} \; 131 | find "/usr/bin/" -type f -iname "vsyasm" -exec rm {} \; 132 | find "/usr/bin/" -type f -iname "x264" -exec rm {} \; 133 | find "/usr/bin/" -type f -iname "yasm" -exec rm {} \; 134 | find "/usr/bin/" -type f -iname "ytasm" -exec rm {} \; 135 | find "$HOME/bin/" -type f -iname "lame" -exec mv {} /usr/bin/ \; 136 | find "$HOME/bin/" -type f -iname "nasm" -exec mv {} /usr/bin/ \; 137 | find "$HOME/bin/" -type f -iname "ndisasm" -exec mv {} /usr/bin/ \; 138 | find "$HOME/bin/" -type f -iname "vsyasm" -exec mv {} /usr/bin/ \; 139 | find "$HOME/bin/" -type f -iname "x264" -exec mv {} /usr/bin/ \; 140 | find "$HOME/bin/" -type f -iname "yasm" -exec mv {} /usr/bin/ \; 141 | find "$HOME/bin/" -type f -iname "ytasm" -exec mv {} /usr/bin/ \; 142 | 143 | echo "COMPILING FFMPEG" 144 | wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \ 145 | tar xjvf ffmpeg-snapshot.tar.bz2 && \ 146 | cd ffmpeg && \ 147 | PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \ 148 | --prefix="$HOME/ffmpeg_build" \ 149 | --pkg-config-flags="--static" \ 150 | --extra-cflags="-I$HOME/ffmpeg_build/include" \ 151 | --extra-ldflags="-L$HOME/ffmpeg_build/lib" \ 152 | --extra-libs="-lpthread -lm" \ 153 | --bindir="$HOME/bin" \ 154 | --enable-gpl \ 155 | --enable-libaom \ 156 | --enable-libass \ 157 | --enable-libfdk-aac \ 158 | --enable-libfreetype \ 159 | --enable-libmp3lame \ 160 | --enable-libopus \ 161 | --enable-libvorbis \ 162 | --enable-libvpx \ 163 | --enable-libx264 \ 164 | --enable-libx265 \ 165 | --enable-vaapi \ 166 | --enable-nvenc \ 167 | --enable-nonfree && \ 168 | 169 | PATH="/usr/bin:$PATH" make && \ 170 | make install && \ 171 | hash -r 172 | cd ~/ 173 | rm -rf ~/ffmpeg_sources ~/ffmpeg_build 174 | 175 | find "/usr/bin/" -type f -iname "ffmpeg" -exec rm {} \; 176 | find "/usr/bin/" -type f -iname "ffprobe" -exec rm {} \; 177 | find "/usr/bin/" -type f -iname "ffplay" -exec rm {} \; 178 | 179 | find "$HOME/bin/" -type f -iname "ffmpeg" -exec mv {} /usr/bin/ \; 180 | find "$HOME/bin/" -type f -iname "ffprobe" -exec mv {} /usr/bin/ \; 181 | find "$HOME/bin/" -type f -iname "ffplay" -exec mv {} /usr/bin/ \; 182 | 183 | else 184 | echo "ffmpeg already installed" 185 | fi 186 | 187 | echo "=====FFMPEG INSTALLATION COMPLETE=====" 188 | exit 0 189 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/lidarr_dl_auto_installer.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "==========LIDARR DL AUTOMATION SETUP===========" 3 | 4 | echo "INSTALLING REQUIREMENTS" 5 | curl -sL https://deb.nodesource.com/setup_10.x | bash - && \ 6 | apt-get update -qq && \ 7 | apt-get install -qq -y \ 8 | mkvtoolnix \ 9 | mp3val \ 10 | flac \ 11 | wget \ 12 | nano \ 13 | unzip \ 14 | libchromaprint-tools \ 15 | nodejs \ 16 | git \ 17 | jq \ 18 | cron \ 19 | python-dev \ 20 | autoconf \ 21 | automake \ 22 | libtool \ 23 | gcc \ 24 | make \ 25 | pkg-config \ 26 | openssl \ 27 | libssl-dev \ 28 | python-pip && \ 29 | apt-get purge --auto-remove -y && \ 30 | apt-get clean 31 | 32 | set -e 33 | set -o pipefail 34 | 35 | # Install packages needed 36 | 37 | apt update > /dev/null 2>&1 && apt install -y curl libflac-dev > /dev/null 2>&1 38 | 39 | # Remove packages that can cause issues 40 | 41 | apt -y purge opus* > /dev/null 2>&1 && apt -y purge libopus-dev > /dev/null 2>&1 42 | 43 | # Download necessary files 44 | 45 | TEMP_FOLDER="$(mktemp -d)" 46 | 47 | # Opusfile 0.11 48 | curl -Ls https://downloads.xiph.org/releases/opus/opusfile-0.11.tar.gz | tar xz -C "$TEMP_FOLDER" 49 | 50 | # Opus 1.3.1 51 | curl -Ls https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz | tar xz -C "$TEMP_FOLDER" 52 | 53 | # Libopusenc 0.2.1 54 | curl -Ls https://archive.mozilla.org/pub/opus/libopusenc-0.2.1.tar.gz | tar xz -C "$TEMP_FOLDER" 55 | 56 | # Opus Tools 0.2 57 | curl -Ls https://archive.mozilla.org/pub/opus/opus-tools-0.2.tar.gz | tar xz -C "$TEMP_FOLDER" 58 | 59 | # Compile 60 | 61 | cd "$TEMP_FOLDER"/opus-1.3.1 || exit 62 | 63 | ./configure 64 | make && make install 65 | 66 | cd "$TEMP_FOLDER"/opusfile-0.11 || exit 67 | 68 | ./configure 69 | make && make install 70 | 71 | cd "$TEMP_FOLDER"/libopusenc-0.2.1 || exit 72 | 73 | ./configure 74 | make && make install 75 | 76 | cd "$TEMP_FOLDER"/opus-tools-0.2 || exit 77 | ./configure 78 | make 79 | make install 80 | ldconfig 81 | 82 | # Cleanup 83 | 84 | rm -rf "$TEMP_FOLDER" 85 | 86 | cd / 87 | 88 | pip install --no-cache-dir -U \ 89 | beets \ 90 | pyacoustid 91 | 92 | service cron restart 93 | 94 | if ! [ -x "$(command -v ffmpeg)" ]; then 95 | echo "INSTALLING FFMPEG" 96 | apt-get update -qq && \ 97 | apt-get install -y xz-utils 98 | 99 | mkdir /tmp/ffmpeg 100 | curl -o /tmp/ffmpeg/ffmpeg-git-amd64-static.tar.xz https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz 101 | cd /tmp/ffmpeg 102 | tar xvf ffmpeg-git-amd64-static.tar.xz 103 | find "/usr/bin/" -type f -iname "ffmpeg" -exec rm {} \; 104 | find "/usr/bin/" -type f -iname "ffprobe" -exec rm {} \; 105 | find "/tmp/ffmpeg" -type f -iname "ffmpeg" -exec mv {} /usr/bin/ \; 106 | find "/tmp/ffmpeg" -type f -iname "ffprobe" -exec mv {} /usr/bin/ \; 107 | cd / 108 | rm -rf /tmp/ffmpeg 109 | else 110 | echo "FFMPEG ALREADY INSTALLED" 111 | fi 112 | 113 | if [ ! -d /config/scripts ]; then 114 | echo "setting up script directory" 115 | mkdir /config/scripts 116 | # Set Permissions 117 | echo "setting permissions..." 118 | chmod 0777 /config/scripts 119 | echo "done" 120 | fi 121 | 122 | if [ ! -d /config/scripts/beets ]; then 123 | mkdir /config/scripts/beets 124 | fi 125 | 126 | if [ -f /config/scripts/lidarr-download-automation-start.bash ]; then 127 | rm /config/scripts/lidarr-download-automation-start.bash 128 | sleep 1s 129 | fi 130 | 131 | if [ ! -f /config/scripts/lidarr-download-automation-start.bash ]; then 132 | echo "downloading lidarr-download-automation-start.bash from: https://github.com/RandomNinjaAtk/Scripts/blob/master/external/cron_lidarr_jobs.bash" 133 | curl -o /config/scripts/lidarr-download-automation-start.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/external/lidarr-download-automation-start.bash 134 | echo "done" 135 | fi 136 | 137 | # Remove lock file incase, system was rebooted before script finished 138 | if [ -d /config/scripts/00-lidarr-download-automation.exclusivelock ]; then 139 | rmdir /config/scripts/00-lidarr-download-automation.exclusivelock 140 | fi 141 | 142 | echo "INSTALLING DEEZLOADER-REMIX" 143 | 144 | rm -rf /deezloaderremix && \ 145 | rm -rf /config/xdg && \ 146 | 147 | if [ ! -d /downloads/deezloaderremix ]; then 148 | mkdir /downloads/deezloaderremix 149 | fi 150 | ln -sf /downloads/deezloaderremix "/root/Deezloader Music" && \ 151 | 152 | cd / && \ 153 | if [ -f /development.zip ]; then 154 | rm /development.zip 155 | sleep 1s 156 | fi 157 | # wget https://notabug.org/spAILDEcle/DeezloaderRemix/archive/artists-swap.zip && \ 158 | # unzip artists-swap.zip && \ 159 | # rm artists-swap.zip && \ 160 | wget https://notabug.org/RemixDevs/DeezloaderRemix/archive/development.zip && \ 161 | unzip development.zip && \ 162 | rm development.zip && \ 163 | sed -i "s/\"trackNameTemplate\": \"%artist% - %title%\"/\"trackNameTemplate\": \"%disc%%number% - %title% %explicit%\"/g" "/deezloaderremix/app/default.json" && \ 164 | sed -i "s/\"albumTrackNameTemplate\": \"%number% - %title%\"/\"albumTrackNameTemplate\": \"%disc%%number% - %title% %explicit%\"/g" "/deezloaderremix/app/default.json" && \ 165 | sed -i "s/\"playlistTrackNameTemplate\": \"%position% - %artist% - %title%\"/\"playlistTrackNameTemplate\": \"%disc%%position% - %title% %explicit%\"/g" "/deezloaderremix/app/default.json" && \ 166 | # sed -i "s/\"albumNameTemplate\": \"%artist% - %album%\"/\"albumNameTemplate\": \"%artist% (%artist_id%) - %type% - %year% - %album% %explicit%(%type%) (%year%) (%album_id%) (WEB)-DREMIX\"/g" "/deezloaderremix/app/default.json" && \ 167 | sed -i "s/\"albumNameTemplate\": \"%artist% - %album%\"/\"albumNameTemplate\": \"%artist% (%artist_id%) - %album% %explicit%(%type%) (%year%) (%album_id%) (WEB)-DREMIX\"/g" "/deezloaderremix/app/default.json" && \ 168 | sed -i "s/\"embeddedArtworkSize\": 800/\"embeddedArtworkSize\": 1000/g" "/deezloaderremix/app/default.json" && \ 169 | sed -i "s/\"localArtworkSize\": 1000/\"localArtworkSize\": 1400/g" "/deezloaderremix/app/default.json" && \ 170 | sed -i "s/\"saveArtwork\": false/\"saveArtwork\": true/g" "/deezloaderremix/app/default.json" && \ 171 | sed -i "s/\"queueConcurrency\": 3/\"queueConcurrency\": 6/g" "/deezloaderremix/app/default.json" && \ 172 | # sed -i "s/\"maxBitrate\": \"3\"/\"maxBitrate\": \"9\"/g" "/deezloaderremix/app/default.json" && \ 173 | sed -i "s/\"coverImageTemplate\": \"cover\"/\"coverImageTemplate\": \"folder\"/g" "/deezloaderremix/app/default.json" && \ 174 | sed -i "s/\"createCDFolder\": true/\"createCDFolder\": false/g" "/deezloaderremix/app/default.json" && \ 175 | sed -i "s/\"createSingleFolder\": false/\"createSingleFolder\": true/g" "/deezloaderremix/app/default.json" && \ 176 | sed -i "s/\"syncedlyrics\": false/\"syncedlyrics\": true/g" "/deezloaderremix/app/default.json" && \ 177 | sed -i "s/\"logErrors\": false/\"logErrors\": true/g" "/deezloaderremix/app/default.json" && \ 178 | sed -i "s/\"logSearched\": false/\"logSearched\": true/g" "/deezloaderremix/app/default.json" && \ 179 | sed -i "s/\"trackTotal\": false/\"trackTotal\": true/g" "/deezloaderremix/app/default.json" && \ 180 | sed -i "s/\"discTotal\": false/\"discTotal\": true/g" "/deezloaderremix/app/default.json" && \ 181 | sed -i "s/\"explicit\": false/\"explicit\": true/g" "/deezloaderremix/app/default.json" && \ 182 | sed -i "s/\"barcode\": false/\"barcode\": true/g" "/deezloaderremix/app/default.json" && \ 183 | sed -i "s/\"unsynchronisedLyrics\": false/\"unsynchronisedLyrics\": true/g" "/deezloaderremix/app/default.json" && \ 184 | sed -i "s/\"copyright\": false/\"copyright\": true/g" "/deezloaderremix/app/default.json" && \ 185 | sed -i "s/\"musicpublisher\": false/\"musicpublisher\": true/g" "/deezloaderremix/app/default.json" && \ 186 | sed -i "s/\"composer\": false/\"composer\": true/g" "/deezloaderremix/app/default.json" && \ 187 | sed -i "s/\"mixer\": false/\"mixer\": true/g" "/deezloaderremix/app/default.json" && \ 188 | sed -i "s/\"author\": false/\"author\": true/g" "/deezloaderremix/app/default.json" && \ 189 | sed -i "s/\"writer\": false/\"writer\": true/g" "/deezloaderremix/app/default.json" && \ 190 | sed -i "s/\"engineer\": false/\"engineer\": true/g" "/deezloaderremix/app/default.json" && \ 191 | sed -i "s/\"producer\": false/\"producer\": true/g" "/deezloaderremix/app/default.json" && \ 192 | sed -i "s/\"multitagSeparator\": \"; \"/\"multitagSeparator\": \"andFeat\"/g" "/deezloaderremix/app/default.json" && \ 193 | 194 | cd /deezloaderremix && \ 195 | npm install && \ 196 | cd /deezloaderremix/app && \ 197 | npm install && \ 198 | cd / && \ 199 | 200 | echo "Starting Deezloader Remix" 201 | nohup node /deezloaderremix/app/app.js &>/dev/null & 202 | sleep 20s && \ 203 | chmod 0777 -R /config/xdg && \ 204 | 205 | if [ -x "$(command -v crontab)" ]; then 206 | if grep "lidarr-download-automation-start.bash" /etc/crontab; then 207 | echo "job already added..." 208 | else 209 | echo "adding cron job to crontab..." 210 | echo "*/15 * * * * root bash /config/scripts/lidarr-download-automation-start.bash > /config/scripts/cron-job.log" >> "/etc/crontab" 211 | service cron restart 212 | fi 213 | else 214 | echo "cron NOT INSTALLED" 215 | fi 216 | 217 | echo "=====LIDARR DL AUTOMATION SETUP COMPLETE=====" 218 | exit 0 219 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/mp4-automated-installer.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "==========MP4 AUTOMATOR INSTALLER===========" 3 | echo "" 4 | echo "" 5 | echo "===INSTALLING PRE-REQS===" 6 | 7 | apt-get update -qq && \ 8 | apt-get install -qq -y \ 9 | git \ 10 | openssl \ 11 | python3-pip \ 12 | python-pip \ 13 | libffi-dev \ 14 | libssl-dev \ 15 | libxml2-dev \ 16 | libxslt1-dev \ 17 | mkvtoolnix \ 18 | zlib1g-dev \ 19 | ffmpeg && \ 20 | 21 | apt-get purge --auto-remove -y && \ 22 | apt-get clean 23 | 24 | pip3 install --no-cache-dir -U \ 25 | requests \ 26 | requests[security] \ 27 | requests-cache \ 28 | babelfish \ 29 | mutagen \ 30 | guessit \ 31 | subliminal \ 32 | stevedore \ 33 | python-dateutil \ 34 | qtfaststart \ 35 | tmdbsimple 36 | 37 | echo "" 38 | echo "" 39 | echo "=========COMPLETE========" 40 | echo "" 41 | echo "===CHECKING FOR EXISTING CONFIG===" 42 | if [ -f /config/scripts/sickbeard_mp4_automator/autoProcess.ini ]; then 43 | echo "Config found..." && \ 44 | echo "Backup autoProcess.ini configuration..." && \ 45 | mv /config/scripts/sickbeard_mp4_automator/autoProcess.ini /config/scripts/ 46 | else 47 | echo "No config found..." 48 | fi 49 | echo "" 50 | echo "===INSTALLING & UPDATING SICKBEARD AUTOMATOR===" 51 | if [ -d /config/scripts/sickbeard_mp4_automator ]; then 52 | echo "Removing previous installation..." 53 | rm -rf /config/scripts/sickbeard_mp4_automator 54 | fi 55 | echo "Downloading sickbeared_mp4_automator..." && \ 56 | git clone git://github.com/mdhiggins/sickbeard_mp4_automator.git /config/scripts/sickbeard_mp4_automator/ && \ 57 | touch /config/scripts/sickbeard_mp4_automator/index.log && \ 58 | chmod 0777 -R /config/scripts/sickbeard_mp4_automator 59 | if [ ! -d /var/log/sickbeard_mp4_automator ]; then 60 | mkdir /var/log/sickbeard_mp4_automator 61 | fi 62 | rm -rf /var/log/sickbeard_mp4_automator/* && \ 63 | chmod 0777 -R /var/log/sickbeard_mp4_automator && \ 64 | ln -s /config/scripts/sickbeard_mp4_automator/index.log /var/log/sickbeard_mp4_automator/index.log && \ 65 | if [ -f /config/scripts/autoProcess.ini ]; then 66 | echo "Restoring backup (autoProcess.ini) configuration..." && \ 67 | mv /config/scripts/autoProcess.ini /config/scripts/sickbeard_mp4_automator/ 68 | fi 69 | 70 | if [ ! -f /config/scripts/sickbeard_mp4_automator/autoProcess.ini ]; then 71 | echo "New installation detected..." 72 | echo "Downloading config from: https://github.com/RandomNinjaAtk/Scripts/blob/master/config/autoProcess.ini" && \ 73 | curl -o /config/scripts/sickbeard_mp4_automator/autoProcess.ini https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/config/autoProcess.ini && \ 74 | echo "done" && \ 75 | chmod 0666 /config/scripts/sickbeard_mp4_automator/autoProcess.ini 76 | fi 77 | 78 | # Updating config files 79 | if [ -f /config/config.xml ]; then 80 | # Update config file if radarr 81 | if grep -q 7878 /config/config.xml; then 82 | if [ -f /config/scripts/sickbeard_mp4_automator/autoProcess.ini ]; then 83 | if grep -q radarrkey /config/scripts/sickbeard_mp4_automator/autoProcess.ini; then 84 | echo "Radarr installation detected..." 85 | echo "Updating config with radarr api key..." 86 | search="radarrkey" 87 | apikey="$(grep "" /config/config.xml | sed "s/\ //;s/<\/ApiKey>//")" 88 | sed -i "s/${search}/${apikey}/g" /config/scripts/sickbeard_mp4_automator/autoProcess.ini 89 | chmod 0777 -R /config/scripts/sickbeard_mp4_automator 90 | fi 91 | fi 92 | fi 93 | 94 | # Update config file if sonarr 95 | if grep -q 8989 /config/config.xml; then 96 | if [ -f /config/scripts/sickbeard_mp4_automator/autoProcess.ini ]; then 97 | if grep -q sonarrkey /config/scripts/sickbeard_mp4_automator/autoProcess.ini; then 98 | echo "Sonarr installation detected..." 99 | echo "Updating config with sonarr api key..." 100 | search="sonarrkey" 101 | apikey="$(grep "" /config/config.xml | sed "s/\ //;s/<\/ApiKey>//")" 102 | sed -i "s/${search}/${apikey}/g" /config/scripts/sickbeard_mp4_automator/autoProcess.ini 103 | sed -i "s/Poster/Thumbnail/g" /config/scripts/sickbeard_mp4_automator/autoProcess.ini 104 | chmod 0777 -R /config/scripts/sickbeard_mp4_automator 105 | fi 106 | fi 107 | fi 108 | else 109 | # Compensation for other scrips if using Sabnzbd 110 | 111 | if [ -f /config/scripts/sickbeard_mp4_automator/mp4-video-processing.bash ]; then 112 | rm /config/scripts/sickbeard_mp4_automator/mp4-video-processing.bash 113 | else 114 | echo "downloading mp4-video-processing.bash from: https://github.com/RandomNinjaAtk/Scripts/blob/master/sabnzbd/mp4-video-processing.bash" 115 | curl -o /config/scripts/sickbeard_mp4_automator/mp4-video-processing.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/sabnzbd/mp4-video-processing.bash 116 | echo "done" 117 | chmod 777 /config/scripts/sickbeard_mp4_automator/mp4-video-processing.bash 118 | fi 119 | 120 | if [ -f /config/scripts/video-processing.bash ]; then 121 | cp /config/scripts/video-processing.bash /config/scripts/sickbeard_mp4_automator/video-processing.bash 122 | chmod 777 /config/scripts/sickbeard_mp4_automator/video-processing.bash 123 | fi 124 | 125 | if [ -f /config/scripts/AudioPostProcessing.bash ]; then 126 | cp /config/scripts/AudioPostProcessing.bash /config/scripts/sickbeard_mp4_automator/AudioPostProcessing.bash 127 | chmod 777 /config/scripts/sickbeard_mp4_automator/AudioPostProcessing.bash 128 | fi 129 | 130 | if [ -f /config/scripts/MKV-Cleaner.bash ]; then 131 | cp /config/scripts/MKV-Cleaner.bash /config/scripts/sickbeard_mp4_automator/MKV-Cleaner.bash 132 | chmod 777 /config/scripts/sickbeard_mp4_automator/MKV-Cleaner.bash 133 | fi 134 | fi 135 | 136 | echo "=====MP4 AUTOMATOR INSTALLATION COMPLETE=====" 137 | exit 0 138 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/sabnzbd_script_setup.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "INSTALLING REQUIREMENTS" 4 | apt-get update -qq && \ 5 | apt-get install -qq -y \ 6 | mkvtoolnix \ 7 | mp3val \ 8 | flac \ 9 | wget \ 10 | nano \ 11 | unzip \ 12 | jq && \ 13 | apt-get purge --auto-remove -y && \ 14 | apt-get clean 15 | 16 | if [ ! -f "/usr/local/bin/beet" ]; then 17 | apt-get update -qq && \ 18 | apt-get install -qq -y \ 19 | libchromaprint-tools \ 20 | python3-pip && \ 21 | apt-get purge --auto-remove -y && \ 22 | apt-get clean 23 | 24 | pip3 install --no-cache-dir -U \ 25 | beets \ 26 | pyacoustid 27 | else 28 | echo "BEETS ALREADY INSTALLED" 29 | fi 30 | 31 | if [ ! -f "/usr/local/bin/opusenc" ]; then 32 | apt-get update -qq && \ 33 | apt-get install -qq -y \ 34 | autoconf \ 35 | automake \ 36 | libtool \ 37 | gcc \ 38 | make \ 39 | pkg-config \ 40 | openssl \ 41 | libssl-dev && \ 42 | apt-get purge --auto-remove -y && \ 43 | apt-get clean 44 | 45 | set -e 46 | set -o pipefail 47 | 48 | # Install packages needed 49 | 50 | apt update > /dev/null 2>&1 && apt install -y curl libflac-dev > /dev/null 2>&1 51 | 52 | # Remove packages that can cause issues 53 | 54 | apt -y purge opus* > /dev/null 2>&1 && apt -y purge libopus-dev > /dev/null 2>&1 55 | 56 | # Download necessary files 57 | 58 | TEMP_FOLDER="$(mktemp -d)" 59 | 60 | # Opusfile 0.11 61 | curl -Ls https://downloads.xiph.org/releases/opus/opusfile-0.11.tar.gz | tar xz -C "$TEMP_FOLDER" 62 | 63 | # Opus 1.3.1 64 | curl -Ls https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz | tar xz -C "$TEMP_FOLDER" 65 | 66 | # Libopusenc 0.2.1 67 | curl -Ls https://archive.mozilla.org/pub/opus/libopusenc-0.2.1.tar.gz | tar xz -C "$TEMP_FOLDER" 68 | 69 | # Opus Tools 0.2 70 | curl -Ls https://archive.mozilla.org/pub/opus/opus-tools-0.2.tar.gz | tar xz -C "$TEMP_FOLDER" 71 | 72 | # Compile 73 | 74 | cd "$TEMP_FOLDER"/opus-1.3.1 || exit 75 | 76 | ./configure 77 | make && make install 78 | 79 | cd "$TEMP_FOLDER"/opusfile-0.11 || exit 80 | 81 | ./configure 82 | make && make install 83 | 84 | cd "$TEMP_FOLDER"/libopusenc-0.2.1 || exit 85 | 86 | ./configure 87 | make && make install 88 | 89 | cd "$TEMP_FOLDER"/opus-tools-0.2 || exit 90 | ./configure 91 | make 92 | make install 93 | ldconfig 94 | 95 | # Cleanup 96 | 97 | rm -rf "$TEMP_FOLDER" 98 | 99 | cd / 100 | else 101 | echo "OPUSENC ALREADY INSTALLED" 102 | fi 103 | 104 | if ! [ -x "$(command -v ffmpeg)" ]; then 105 | echo "INSTALLING FFMPEG" 106 | apt-get update -qq && \ 107 | apt-get install -y xz-utils 108 | 109 | mkdir /tmp/ffmpeg 110 | curl -o /tmp/ffmpeg/ffmpeg-git-amd64-static.tar.xz https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz 111 | cd /tmp/ffmpeg 112 | tar xvf ffmpeg-git-amd64-static.tar.xz 113 | find "/usr/bin/" -type f -iname "ffmpeg" -exec rm {} \; 114 | find "/usr/bin/" -type f -iname "ffprobe" -exec rm {} \; 115 | find "/tmp/ffmpeg" -type f -iname "ffmpeg" -exec mv {} /usr/bin/ \; 116 | find "/tmp/ffmpeg" -type f -iname "ffprobe" -exec mv {} /usr/bin/ \; 117 | cd / 118 | rm -rf /tmp/ffmpeg 119 | else 120 | echo "FFMPEG ALREADY INSTALLED" 121 | fi 122 | 123 | if [ ! -d /config/scripts ]; then 124 | echo "setting up script directory" 125 | mkdir -p /config/scripts 126 | echo "done" 127 | fi 128 | 129 | if [ ! -d /config/scripts/beets ]; then 130 | mkdir -p /config/scripts/beets 131 | fi 132 | 133 | if [ ! -f /config/scripts/beets/config.xml ]; then 134 | echo "downloading config.yaml from: https://github.com/RandomNinjaAtk/Scripts/blob/master/config/config.yaml" 135 | curl -o /config/scripts/beets/config.yaml https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/config/config.yaml 136 | echo "done" 137 | fi 138 | 139 | # Download Scripts 140 | echo "downloading scripts..." 141 | 142 | if [ ! -f /config/scripts/video-processing.bash ]; then 143 | echo "downloading video-processing.bash from: https://github.com/RandomNinjaAtk/Scripts/blob/master/sabnzbd/video-processing.bash" 144 | curl -o /config/scripts/video-processing.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/sabnzbd/video-processing.bash 145 | echo "done" 146 | fi 147 | 148 | 149 | if [ ! -f /config/scripts/AudioPostProcessing.bash ]; then 150 | echo "downloading AudioPostProcessing.bash from: https://github.com/RandomNinjaAtk/Scripts/tree/master/sabnzbd/AudioPostProcessing.bash" 151 | curl -o /config/scripts/AudioPostProcessing.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/sabnzbd/AudioPostProcessing.bash 152 | echo "done" 153 | fi 154 | 155 | echo "script downloads complete..." 156 | 157 | find /config/scripts -type f -exec chmod 0666 {} \; 158 | find /config/scripts -type d -exec chmod 0777 {} \; 159 | find /config/scripts -type f -iname "*.bash" -exec chmod 0777 {} \; 160 | 161 | exit 0 162 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/updaters/lidarr-dl-automated-updates.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "==========START LIDARR DL AUTO INSTALLER AUTOMATED UPDATES===========" 3 | 4 | # Check for folder, create folder if needed (hotio docker image compatibility) 5 | if [ ! -d /config/custom-cont-init.d ]; then 6 | mkdir /config/custom-cont-init.d 7 | fi 8 | 9 | if [ -f /config/custom-cont-init.d/lidarr_dl_auto_installer.bash ]; then 10 | echo "Previous version detected..." 11 | echo "removing....lidarr_dl_auto_installer.bash" 12 | rm /config/custom-cont-init.d/lidarr_dl_auto_installer.bash 13 | fi 14 | if [ ! -f /config/custom-cont-init.d/lidarr_dl_auto_installer.bash ]; then 15 | echo "begining updated script installation..." 16 | echo "downloading lidarr_dl_auto_installer.bash from: https://github.com/RandomNinjaAtk/Scripts/raw/master/lso_docker_ubuntu/lidarr_dl_auto_installer.bash" && \ 17 | curl -o /config/custom-cont-init.d/lidarr_dl_auto_installer.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/lso_docker_ubuntu/lidarr_dl_auto_installer.bash && \ 18 | echo "download complete" && \ 19 | echo "running lidarr_dl_auto_installer.bash..." && \ 20 | bash /config/custom-cont-init.d/lidarr_dl_auto_installer.bash && \ 21 | rm /config/custom-cont-init.d/lidarr_dl_auto_installer.bash 22 | fi 23 | echo "==========END LIDARR DL AUTO INSTALLER AUTOMATED UPDATES===========" 24 | exit 0 25 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/updaters/mp4-automator-automated-updates.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "==========MP4 AUTOMATOR AUTOMATED UPDATES===========" 3 | 4 | # Check for folder, create folder if needed (hotio docker image compatibility) 5 | if [ ! -d /config/custom-cont-init.d ]; then 6 | mkdir /config/custom-cont-init.d 7 | fi 8 | 9 | if [ -f /config/custom-cont-init.d/mp4-automated-installer.bash ]; then 10 | rm /config/custom-cont-init.d/mp4-automated-installer.bash 11 | else 12 | echo "downloading mp4-automated-installer.bashh from: https://github.com/RandomNinjaAtk/Scripts/blob/master/lso_docker_ubuntu/mp4-automated-installer.bash" && \ 13 | curl -o /config/custom-cont-init.d/mp4-automated-installer.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/lso_docker_ubuntu/mp4-automated-installer.bash && \ 14 | echo "download complete" && \ 15 | echo "running mp4-automated-installer.bash..." && \ 16 | bash /config/custom-cont-init.d/mp4-automated-installer.bash && \ 17 | rm /config/custom-cont-init.d/mp4-automated-installer.bash 18 | fi 19 | 20 | exit 0 21 | -------------------------------------------------------------------------------- /lso_docker_ubuntu/updaters/sabnzbd_scripts_auto_update.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "==========START SABNZBD SCRIPTS AUTOMATED UPDATES===========" 3 | 4 | if [ -f /config/custom-cont-init.d/sabnzbd_script_setup.bash ]; then 5 | echo "Previous version detected..." 6 | echo "removing....sabnzbd_script_setup.bash" 7 | rm /config/custom-cont-init.d/sabnzbd_script_setup.bash 8 | else 9 | echo "begining updated script installation..." 10 | echo "downloading sabnzbd_script_setup.bash from: https://github.com/RandomNinjaAtk/Scripts/blob/master/lso_docker_ubuntu/sabnzbd_script_setup.bash" && \ 11 | curl -o /config/custom-cont-init.d/sabnzbd_script_setup.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/lso_docker_ubuntu/sabnzbd_script_setup.bash && \ 12 | echo "download complete" && \ 13 | echo "running sabnzbd_script_setup.bash..." && \ 14 | bash /config/custom-cont-init.d/sabnzbd_script_setup.bash && \ 15 | rm /config/custom-cont-init.d/sabnzbd_script_setup.bash 16 | fi 17 | echo "==========END SABNZBD SCRIPTS AUTOMATED UPDATES===========" 18 | exit 0 19 | -------------------------------------------------------------------------------- /sabnzbd/AudioPostProcessing.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ####################################### 3 | # Audio Post-Processing # 4 | # Bash Script # 5 | ####################################### 6 | #=============REQUIREMENTS============= 7 | # flac, mp3val, ffmpeg # 8 | #============CONFIGURATION============= 9 | RemoveNonAudioFiles="TRUE" # TURE = ENABLED, Deletes non FLAC/M4A/MP3/OPUS/OGG files 10 | DuplicateFileCleanUp="TRUE" # TRUE = ENABLED, Deletes duplicate files 11 | AudioVerification="TRUE" # TRUE = ENABLED, Verifies FLAC/MP3 files for errors (fixes MP3's, deletes bad FLAC files) 12 | Convert="FALSE" # TRUE = ENABLED, Only converts lossless FLAC files 13 | ConversionFormat="FLAC" # SET TO: OPUS or AAC or MP3 or ALAC or FLAC - converts lossless FLAC files to set format 14 | ConversionBitrate="320" # Set to desired bitrate when converting to OPUS/AAC/MP3 format types 15 | ReplaygainTagging="TRUE" # TRUE = ENABLED, adds replaygain tags for compatible players (FLAC ONLY) 16 | BeetsProcessing="TRUE" # TRUE = ENABLED :: Match with beets 17 | BeetsFallbackToLidarr="TRUE" # TRUE = ENABLED :: If beets cannot match, allow lidarr to attempt match and import, if disabled, download will be marked as failed 18 | DetectNonSplitAlubms="TRUE" # TRUE = ENABLED :: Uses "MaxFileSize" to detect and mark download as failed if detected 19 | MaxFileSize="150M" # M = MB, G = GB :: Set size threshold for detecting single file albums 20 | 21 | #============FUNCTIONS============ 22 | 23 | settings () { 24 | 25 | echo "" 26 | echo "Configuration:" 27 | if [ "${RemoveNonAudioFiles}" = TRUE ]; then 28 | echo "RemoveNonAudioFiles: ENABLED" 29 | else 30 | echo "RemoveNonAudioFiles: DISABLED" 31 | fi 32 | 33 | if [ "${DuplicateFileCleanUp}" = TRUE ]; then 34 | echo "DuplicateFileCleanUp: ENABLED" 35 | else 36 | echo "DuplicateFileCleanUp: DISABLED" 37 | fi 38 | 39 | if [ "${AudioVerification}" = TRUE ]; then 40 | echo "AudioVerification: ENABLED" 41 | else 42 | echo "AudioVerification: DISABLED" 43 | fi 44 | 45 | if [ "${Convert}" = TRUE ]; then 46 | echo "Convert: ENABLED" 47 | echo "Convert Format: $ConversionFormat" 48 | if [ "${ConversionFormat}" = FLAC ]; then 49 | echo "Bitrate: lossless" 50 | elif [ "${ConversionFormat}" = ALAC ]; then 51 | echo "Bitrate: lossless" 52 | else 53 | echo "Conversion Bitrate: ${ConversionBitrate}k" 54 | fi 55 | else 56 | echo "Convert: DISABLED" 57 | fi 58 | 59 | if [ "${Convert}" = TRUE ]; then 60 | if [ "${ConversionFormat}" = FLAC ]; then 61 | if [ "${ReplaygainTagging}" = TRUE ]; then 62 | echo "ReplaygainTagging: ENABLED" 63 | else 64 | echo "ReplaygainTagging: DISABLED" 65 | fi 66 | fi 67 | else 68 | if [ "${ReplaygainTagging}" = TRUE ]; then 69 | echo "ReplaygainTagging: ENABLED" 70 | else 71 | echo "ReplaygainTagging: DISABLED" 72 | fi 73 | fi 74 | 75 | if [ "${BeetsProcessing}" = TRUE ]; then 76 | echo "BeetsProcessing: ENABLED" 77 | if [ "${BeetsFallbackToLidarr}" = TRUE ]; then 78 | echo "BeetsFallbackToLidarr: ENABLED" 79 | else 80 | echo "BeetsFallbackToLidarr: DISABLED" 81 | fi 82 | else 83 | echo "BeetsProcessing: DISABLED" 84 | fi 85 | 86 | if [ "${DetectNonSplitAlubms}" = TRUE ]; then 87 | echo "DetectNonSplitAlubms: ENABLED" 88 | echo "MaxFileSize: $MaxFileSize" 89 | else 90 | echo "DetectNonSplitAlubms: DISABLED" 91 | fi 92 | 93 | echo "" 94 | echo "Processing: $1" 95 | 96 | } 97 | 98 | clean () { 99 | if find "$1" -type f -iregex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" | read; then 100 | if find "$1" -type f -not -iregex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" | read; then 101 | echo "" 102 | echo "REMOVE NON AUDIO FILES" 103 | find "$1" -type f -not -iregex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" -delete 104 | echo "REMOVE NON AUDIO FILES COMPLETE" 105 | fi 106 | if find "$1" -type f -mindepth 2 -iregex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" | read; then 107 | echo "" 108 | echo "MOVE FILES TO DIR" 109 | find "$1" -type f -mindepth 2 -iregex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" -exec mv "{}" "$1"/ \; 110 | echo "MOVE FILES TO DIR COMPLETE" 111 | fi 112 | if find "$1" -type d -mindepth 1 | read; then 113 | echo "" 114 | echo "REMOVE SUB-DIRECTORIES" 115 | find "$1" -type d -mindepth 1 -exec rm -rf "{}" \; 116 | echo "REMOVE SUB-DIRECTORIES COMPLETE" 117 | fi 118 | else 119 | echo "ERROR: NO AUDIO FILES FOUND" && exit 1 120 | fi 121 | } 122 | 123 | duplicatefilecleanup () { 124 | duplicate="FALSE" 125 | if find "$1" -type f -mindepth 1 -iname "*([0-9]).*" | read; then 126 | find "$1" -type f -mindepth 1 -iname "*([0-9]).*" -delete 127 | duplicate="TRUE" 128 | fi 129 | 130 | if find "$1" -type f -mindepth 1 -iname "*.[0-9].*" | read; then 131 | find "$1" -type f -mindepth 1 -iname "*.[0-9].*" -delete 132 | duplicate="TRUE" 133 | fi 134 | 135 | if find "$1" -type f -mindepth 1 -iname "*.flac" | read; then 136 | if find "$1"/* -type f -not -iname "*.flac" | read; then 137 | find "$1"/* -type f -not -iname "*.flac" -delete 138 | duplicate="TRUE" 139 | fi 140 | fi 141 | if [ "${duplicate}" = TRUE ]; then 142 | echo "" 143 | echo "DUPLICATE FILE CLEANUP" 144 | echo "DUPLICATE FILE CLEANUP COMPLETE" 145 | fi 146 | } 147 | 148 | detectsinglefilealbums () { 149 | if find "$1" -type f -iregex ".*/.*\.\(flac\|mp3\|m4a\|alac\|ogg\|opus\)" -size +${MaxFileSize} | read; then 150 | echo "ERROR: Non split album detected" && exit 1 151 | fi 152 | } 153 | 154 | verify () { 155 | if find "$1" -iname "*.flac" | read; then 156 | verifytrackcount=$(find "$1"/ -iname "*.flac" | wc -l) 157 | echo "" 158 | echo "Verifying: $verifytrackcount Tracks" 159 | if ! [ -x "$(command -v flac)" ]; then 160 | echo "ERROR: FLAC verification utility not installed (ubuntu: apt-get install -y flac)" 161 | else 162 | for fname in "$1"/*.flac; do 163 | filename="$(basename "$fname")" 164 | if flac -t --totally-silent "$fname"; then 165 | echo "Verified Track: $filename" 166 | else 167 | echo "ERROR: Track Verification Failed: \"$filename\"" 168 | rm -rf "$1"/* 169 | sleep 0.1 170 | exit 1 171 | fi 172 | done 173 | fi 174 | fi 175 | if find "$1" -iname "*.mp3" | read; then 176 | verifytrackcount=$(find "$1"/ -iname "*.mp3" | wc -l) 177 | echo "" 178 | echo "Verifying: $verifytrackcount Tracks" 179 | if ! [ -x "$(command -v mp3val)" ]; then 180 | echo "MP3VAL verification utility not installed (ubuntu: apt-get install -y mp3val)" 181 | else 182 | for fname in "$1"/*.mp3; do 183 | filename="$(basename "$fname")" 184 | if mp3val -f -nb "$fname" > /dev/null; then 185 | echo "Verified Track: $filename" 186 | fi 187 | done 188 | fi 189 | fi 190 | } 191 | 192 | conversion () { 193 | converttrackcount=$(find "$1"/ -name "*.flac" | wc -l) 194 | targetformat="$ConversionFormat" 195 | bitrate="$ConversionBitrate" 196 | if [ "${ConversionFormat}" = OPUS ]; then 197 | options="-acodec libopus -ab ${bitrate}k -application audio" 198 | extension="opus" 199 | targetbitrate="${bitrate}k" 200 | fi 201 | if [ "${ConversionFormat}" = AAC ]; then 202 | options="-acodec aac -ab ${bitrate}k -movflags faststart" 203 | extension="m4a" 204 | targetbitrate="${bitrate}k" 205 | fi 206 | if [ "${ConversionFormat}" = MP3 ]; then 207 | options="-acodec libmp3lame -ab ${bitrate}k" 208 | extension="mp3" 209 | targetbitrate="${bitrate}k" 210 | fi 211 | if [ "${ConversionFormat}" = ALAC ]; then 212 | options="-acodec alac -movflags faststart" 213 | extension="m4a" 214 | targetbitrate="lossless" 215 | fi 216 | if [ "${ConversionFormat}" = FLAC ]; then 217 | options="-acodec flac" 218 | extension="flac" 219 | targetbitrate="lossless" 220 | fi 221 | if [ -x "$(command -v ffmpeg)" ]; then 222 | if find "$1"/ -name "*.flac" | read; then 223 | echo "" 224 | echo "Converting: $converttrackcount Tracks (Target Format: $targetformat (${targetbitrate}))" 225 | for fname in "$1"/*.flac; do 226 | filename="$(basename "${fname%.flac}")" 227 | if ffmpeg -loglevel warning -hide_banner -nostats -i "$fname" -n -vn $options "${fname%.flac}.temp.$extension"; then 228 | echo "Converted: $filename" 229 | if [ -f "${fname%.flac}.temp.$extension" ]; then 230 | rm "$fname" 231 | sleep 0.1 232 | mv "${fname%.flac}.temp.$extension" "${fname%.flac}.$extension" 233 | fi 234 | else 235 | echo "Conversion failed: $filename, performing cleanup..." 236 | rm -rf "$1"/* 237 | sleep 0.1 238 | exit 1 239 | fi 240 | done 241 | fi 242 | else 243 | echo "ERROR: ffmpeg not installed, please install ffmpeg to use this conversion feature" 244 | sleep 5 245 | fi 246 | } 247 | 248 | replaygain () { 249 | if ! [ -x "$(command -v flac)" ]; then 250 | echo "ERROR: METAFLAC replaygain utility not installed (ubuntu: apt-get install -y flac)" 251 | elif find "$1" -iname "*.flac" | read; then 252 | replaygaintrackcount=$(find "$1"/ -iname "*.flac" | wc -l) 253 | echo "" 254 | find "$1" -iname "*.flac" -exec metaflac --add-replay-gain "{}" + && echo "Replaygain: $replaygaintrackcount Tracks Tagged" 255 | fi 256 | } 257 | 258 | beets () { 259 | echo "" 260 | trackcount=$(find "$1" -type f -iregex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) 261 | echo "Matching $trackcount tracks with Beets" 262 | if [ -f /config/scripts/beets/library.blb ]; then 263 | rm /config/scripts/beets/library.blb 264 | sleep 0.1 265 | fi 266 | if [ -f /config/scripts/beets/beets.log ]; then 267 | rm /config/scripts/beets/beets.log 268 | sleep 0.1 269 | fi 270 | 271 | touch "$1/beets-match" 272 | sleep 0.1 273 | 274 | if find "$1" -type f -iregex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | read; then 275 | beet -c /config/scripts/beets/config.yaml -d "$1" import -q "$1" > /dev/null 276 | if find "$1" -type f -iregex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -newer "$1/beets-match" | read; then 277 | echo "SUCCESS: Matched with beets!" 278 | else 279 | if [ "${BeetsFallbackToLidarr}" = TRUE ]; then 280 | echo "ERROR: Unable to match using beets, fallback to lidarr import matching..." 281 | else 282 | rm -rf "$1"/* 283 | echo "ERROR: Unable to match using beets to a musicbrainz release, marking download as failed..." && exit 1 284 | fi 285 | fi 286 | fi 287 | 288 | if [ -f "$1/beets-match" ]; then 289 | rm "$1/beets-match" 290 | sleep 0.1 291 | fi 292 | } 293 | 294 | #============START SCRIPT============ 295 | 296 | settings "$1" 297 | 298 | if [ "${RemoveNonAudioFiles}" = TRUE ]; then 299 | clean "$1" 300 | else 301 | echo "CLEANING DISABLED" 302 | fi 303 | 304 | if [ "${DuplicateFileCleanUp}" = TRUE ]; then 305 | duplicatefilecleanup "$1" 306 | else 307 | echo "DUPLICATE CLEANUP DISABLED" 308 | fi 309 | 310 | if [ "${DetectNonSplitAlubms}" = TRUE ]; then 311 | detectsinglefilealbums "$1" 312 | else 313 | echo "NON-SPLIT ABLUM DETECTION DISABLED" 314 | fi 315 | 316 | if [ "${AudioVerification}" = TRUE ]; then 317 | verify "$1" 318 | else 319 | echo "AUDIO VERFICATION DISABLED" 320 | fi 321 | 322 | if [ "${BeetsProcessing}" = TRUE ]; then 323 | beets "$1" 324 | else 325 | echo "BEETS PROCESSING DISABLED" 326 | fi 327 | 328 | if [ "${Convert}" = TRUE ]; then 329 | conversion "$1" 330 | else 331 | echo "CONVERSION DISABLED" 332 | fi 333 | 334 | if [ "${ReplaygainTagging}" = TRUE ]; then 335 | replaygain "$1" 336 | else 337 | echo "REPLAYGAIN TAGGING DISABLED" 338 | fi 339 | 340 | echo "" 341 | echo "AUDIO POST-PROCESSING COMPLETE" && exit 0 342 | #============END SCRIPT============ 343 | -------------------------------------------------------------------------------- /sabnzbd/MKV-Cleaner.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ####################################### 3 | # MKV Audio & Subtitle Cleanup # 4 | # Bash Script # 5 | # Version 1.2.0 # 6 | ####################################### 7 | # Description: # 8 | # This script removes unwated audio # 9 | # and subtitles based on configured # 10 | # preferences... # 11 | #=============REQUIREMENTS============= 12 | # mkvtoolsnix (mkvmerge) # 13 | # jq # 14 | #============CONFIGURATION============= 15 | PerferredLanguage="eng" # Keeps only the audio for the language selected, if not found, fall-back to unknown tracks and if also not found, a final fall-back to all other audio tracks 16 | SubtitleLanguage="eng" # Removes all subtitles not matching specified language 17 | SetUnknownAudioLanguage="true" # true = ENABLED, if enabled, sets found unknown (und) audio tracks to the language in the next setting 18 | UnkownAudioLanguage="eng" # Sets unknown language tracks to the language specified 19 | MatchVideoLanguage="true" # Sets video language to match perferred language 20 | #===============FUNCTIONS============== 21 | 22 | set -e 23 | 24 | echo "" 25 | echo "==========================" 26 | if find "$1" -type f -iregex ".*/.*\.\(mkv\|mp4\|avi\)" | read; then 27 | echo "CHECK: Finding video files for processing..." 28 | echo "SUCCESS: Video files found" 29 | else 30 | echo "ERROR: No video files found for processing" 31 | exit 1 32 | fi 33 | echo "==========================" 34 | echo "" 35 | 36 | #cleanup unwanted files 37 | if find "$1" -type f -not -iregex ".*/.*\.\(mkv\|mp4\|avi\)" | read; then 38 | echo "" 39 | echo "==========================" 40 | echo "CHECK: Searching for unwanted files" 41 | echo "SUCCESS: Unwanted files found" 42 | echo "INFO: Deleting unwanted file types" 43 | find "$1"/* -type f -not -iregex ".*/.*\.\(webvtt\|ass\|srt\|mkv\|mp4\|avi\)" -delete 44 | echo "INFO: Complete" 45 | echo "==========================" 46 | echo "" 47 | fi 48 | 49 | #check for required applications 50 | echo "" 51 | echo "==========================" 52 | echo "INFO: Begin checking for required applications" 53 | echo "CHECK: for mkvmerge utility" 54 | if [ ! -x "$(command -v mkvmerge)" ]; then 55 | echo "ERROR: mkvmerge utility not installed" 56 | exit 1 57 | else 58 | echo "SUCCESS: mkvmerge installed" 59 | fi 60 | echo "CHECK: for jq utility" 61 | if [ ! -x "$(command -v jq)" ]; then 62 | echo "ERROR: jq package not installed" 63 | exit 1 64 | else 65 | echo "SUCCESS: mkvmerge installed" 66 | fi 67 | echo "==========================" 68 | echo "" 69 | 70 | #convert mp4 to mkv before language processing 71 | find "$1" -type f -iregex ".*/.*\.\(mp4\)" -print0 | while IFS= read -r -d '' video; do 72 | echo "" 73 | echo "==========================" 74 | echo "INFO: Processing $video" 75 | if timeout 10s mkvmerge -i "$video" > /dev/null; then 76 | echo "INFO: MP4 found, remuxing to mkv before processing audio/subtitles" 77 | mkvmerge -o "$video.merged.mkv" "$video" 78 | # cleanup temp files and rename 79 | mv "$video" "$video.original.mkv" && echo "INFO: Renamed source file" 80 | mv "$video.merged.mkv" "${video/.mp4/.mkv}" && echo "INFO: Renamed temp file" 81 | rm "$video.original.mkv" && echo "INFO: Deleted source file" 82 | else 83 | echo "ERROR: mkvmerge failed" 84 | rm "$video" && echo "INFO: deleted: $video" 85 | exit 1 86 | fi 87 | echo "INFO: Processing complete" 88 | echo "==========================" 89 | echo "" 90 | done 91 | 92 | #convert avi to mkv before language processing 93 | find "$1" -type f -iregex ".*/.*\.\(avi\)" -print0 | while IFS= read -r -d '' video; do 94 | echo "" 95 | echo "==========================" 96 | echo "INFO: Processing $video" 97 | if timeout 10s mkvmerge -i "$video" > /dev/null; then 98 | echo "INFO: AVI found, remuxing to mkv before processing audio/subtitles" 99 | mkvmerge -o "$video.merged.mkv" "$video" 100 | # cleanup temp files and rename 101 | mv "$video" "$video.original.mkv" && echo "INFO: Renamed source file" 102 | mv "$video.merged.mkv" "${video/.avi/.mkv}" && echo "INFO: Renamed temp file" 103 | rm "$video.original.mkv" && echo "INFO: Deleted source file" 104 | else 105 | echo "ERROR: mkvmerge failed" 106 | rm "$video" && echo "INFO: deleted: $video" 107 | exit 1 108 | fi 109 | echo "INFO: Processing complete" 110 | echo "==========================" 111 | echo "" 112 | done 113 | 114 | # Finding Preferred Language 115 | find "$1" -type f -iregex ".*/.*\.\(mkv\)" -print0 | while IFS= read -r -d '' video; do 116 | echo "" 117 | echo "==========================" 118 | echo "INFO: processing $video" 119 | if timeout 10s mkvmerge -i "$video" > /dev/null; then 120 | perfvideo=$(mkvmerge -J "$video" | jq ".tracks[] | select((.type==\"video\") and select(.properties.language==\"${PerferredLanguage}\")) | .id") 121 | allvideo=$(mkvmerge -J "$video" | jq ".tracks[] | select(.type==\"video\") | .id") 122 | nonperfvideo=$(mkvmerge -J "$video" | jq ".tracks[] | select((.type==\"video\") and select(.properties.language!=\"${PerferredLanguage}\")) | .id") 123 | perfaudio=$(mkvmerge -J "$video" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language==\"${PerferredLanguage}\")) | .id") 124 | undaudio=$(mkvmerge -J "$video" | jq '.tracks[] | select((.type=="audio") and select(.properties.language=="und")) | .id') 125 | nonundaudio=$(mkvmerge -J "$video" | jq '.tracks[] | select((.type=="audio") and select(.properties.language!="und")) | .id') 126 | allaudio=$(mkvmerge -J "$video" | jq ".tracks[] | select(.type==\"audio\") | .id") 127 | nonperfaudio=$(mkvmerge -J "$video" | jq ".tracks[] | select((.type==\"audio\") and select(.properties.language!=\"${PerferredLanguage}\")) | .id") 128 | perfsub=$(mkvmerge -J "$video" | jq ".tracks[] | select((.type==\"subtitles\") and select(.properties.language==\"${SubtitleLanguage}\")) | .id") 129 | allsub=$(mkvmerge -J "$video" | jq ".tracks[] | select(.type==\"subtitles\") | .id") 130 | nonperfsub=$(mkvmerge -J "$video" | jq ".tracks[] | select((.type==\"subtitles\") and select(.properties.language!=\"${SubtitleLanguage}\")) | .id") 131 | else 132 | echo "ERROR: mkvmerge failed to read tracks and set values" 133 | rm "$video" && echo "INFO: deleted: $video" 134 | exit 1 135 | fi 136 | 137 | # Checking for video 138 | echo "CHECK: Finding video tracks..." 139 | if test ! -z "$allvideo"; then 140 | echo "SUCCESS: Video tracks found" 141 | else 142 | # no video was found, error and report failed to sabnzbd 143 | echo "ERROR: No video tracks found" 144 | rm "$video" && echo "INFO: deleted: $video" 145 | exit 1 146 | fi 147 | 148 | # Checking for audio 149 | echo "CHECK: Finding audio tracks..." 150 | if test ! -z "$allaudio"; then 151 | echo "SUCCESS: Audio tracks found" 152 | else 153 | # no audio was found, error and report failed to sabnzbd 154 | echo "ERROR: No audio tracks found" 155 | rm "$video" && echo "INFO: deleted: $video" 156 | exit 1 157 | fi 158 | 159 | # Checking for subtitles 160 | echo "CHECK: Finding subtitle tracks..." 161 | if test ! -z "$allsub"; then 162 | echo "SUCCESS: Subtitle tracks found" 163 | subtitles="true" 164 | else 165 | echo "INFO: No subtitles found" 166 | subtitles="false" 167 | fi 168 | 169 | # Checking for preferred audio 170 | if test ! -z "$perfaudio"; then 171 | echo "CHECK: Finding \"${PerferredLanguage}\" audio tracks" 172 | echo "SUCCESS: \"${PerferredLanguage}\" audio tracks found" 173 | echo "CHECK: Finding unwanted audio tracks" 174 | setundaudio="false" 175 | if test ! -z "$nonperfaudio"; then 176 | echo "SUCCESS: Unwanted audio tracks found" 177 | echo "INFO: Marking unwanted audio tracks for deletion" 178 | removeaudio="true" 179 | else 180 | echo "SUCCESS: No unwanted audio tracks found" 181 | removeaudio="false" 182 | fi 183 | 184 | echo "CHECK: Searching for subtitles" 185 | if [ "${subtitles}" = true ]; then 186 | echo "SUCCESS: Subtitle tracks found" 187 | echo "CHECK: Finding \"${SubtitleLanguage}\" subtitle tracks" 188 | if test ! -z "$perfsub"; then 189 | echo "SUCCESS: \"${SubtitleLanguage}\" subtitle tracks found" 190 | echo "CHECK: Finding unwanted subtitle tracks" 191 | if test ! -z "$nonperfsub"; then 192 | echo "SUCCESS: Unwanted subtitle tracks found" 193 | echo "INFO: Marking unwanted subtitle tracks for deletion" 194 | removesubs="true" 195 | else 196 | echo "SUCCESS: No unwanted subtitle tracks found" 197 | removesubs="false" 198 | fi 199 | else 200 | echo "INFO: \"${SubtitleLanguage}\" subtitle tracks not found" 201 | echo "CHECK: Finding unwanted subtitle tracks" 202 | if test ! -z "$nonperfsub"; then 203 | echo "SUCCESS: Unwanted subtitle tracks found" 204 | echo "INFO: Marking unwanted subtitle tracks for deletion" 205 | removesubs="true" 206 | else 207 | echo "SUCCESS: No unwanted subtitle tracks found" 208 | removesubs="false" 209 | fi 210 | fi 211 | else 212 | echo "ERROR: No subtitle tracks found" 213 | echo "INFO: No unwanted subtitle tracks to remove" 214 | removesubs="false" 215 | fi 216 | 217 | if [ "${MatchVideoLanguage}" = true ]; then 218 | echo "CHECK: Analyzing video laguange" 219 | if test ! -z "$nonperfvideo"; then 220 | echo "INFO: Video language does not match \"${PerferredLanguage}\"" 221 | echo "INFO: Updating video language to match \"${PerferredLanguage}\"" 222 | setvideolanguage="true" 223 | else 224 | echo "SUCCESS: Video language matches \"${PerferredLanguage}\"" 225 | setvideolanguage="false" 226 | fi 227 | else 228 | setvideolanguage="false" 229 | fi 230 | elif test ! -z "$undaudio"; then 231 | echo "CHECK: Searching for \"und\" audio" 232 | echo "SUCCESS: \"und\" audio tracks found" 233 | echo "CHECK: Searching for unwanted audio tracks" 234 | setundaudio="true" 235 | if test ! -z "$nonundaudio"; then 236 | echo "SUCCESS: Unwanted audio tracks found" 237 | echo "INFO: Marking unwanted autio tracks for deleteion" 238 | removeaudio="true" 239 | else 240 | echo "SUCCES: No unwanted audio tracks found for removal" 241 | removeaudio="false" 242 | fi 243 | 244 | echo "CHECK: Searching for subtitles" 245 | if [ "${subtitles}" = true ]; then 246 | echo "SUCCESS: Subtitle tracks found" 247 | echo "CHECK: Finding \"${SubtitleLanguage}\" subtitle tracks" 248 | if test ! -z "$perfsub"; then 249 | echo "SUCCESS: \"${SubtitleLanguage}\" subtitle tracks found" 250 | echo "CHECK: Finding unwanted subtitle tracks" 251 | if test ! -z "$nonperfsub"; then 252 | echo "SUCCESS: Unwanted subtitle tracks found" 253 | echo "INFO: Marking unwanted subtitle tracks for deletion" 254 | removesubs="true" 255 | else 256 | echo "SUCCESS: No unwanted subtitle tracks found" 257 | removesubs="false" 258 | fi 259 | else 260 | echo "INFO: \"${SubtitleLanguage}\" subtitle tracks not found" 261 | echo "CHECK: Finding unwanted subtitle tracks" 262 | if test ! -z "$nonperfsub"; then 263 | echo "SUCCESS: Unwanted subtitle tracks found" 264 | echo "INFO: Marking unwanted subtitle tracks for deletion" 265 | removesubs="true" 266 | else 267 | echo "SUCCESS: No unwanted subtitle tracks found" 268 | removesubs="false" 269 | fi 270 | fi 271 | else 272 | echo "ERROR: No subtitle tracks found" 273 | echo "INFO: No unwanted subtitle tracks to remove" 274 | removesubs="false" 275 | fi 276 | 277 | if [ "${MatchVideoLanguage}" = true ]; then 278 | echo "CHECK: Analyzing video laguange" 279 | if test ! -z "$nonperfvideo"; then 280 | echo "INFO: Video language does not match \"${PerferredLanguage}\"" 281 | echo "INFO: Updating video language to match \"${PerferredLanguage}\"" 282 | setvideolanguage="true" 283 | else 284 | echo "SUCCESS: Video language matches \"${PerferredLanguage}\"" 285 | setvideolanguage="false" 286 | fi 287 | else 288 | setvideolanguage="false" 289 | fi 290 | 291 | elif test ! -z "$allaudio"; then 292 | echo "CHECK: Searching for all audio tracks" 293 | echo "SUCCESS: Audio tracks found" 294 | echo "CHECK: Searching for subtitles" 295 | if [ "${subtitles}" = true ]; then 296 | echo "SUCCESS: Subtitle tracks found" 297 | echo "CHECK: Finding \"${SubtitleLanguage}\" subtitle tracks" 298 | if test ! -z "$perfsub"; then 299 | echo "SUCCESS: \"${SubtitleLanguage}\" subtitle tracks found" 300 | echo "CHECK: Finding unwanted subtitle tracks" 301 | if test ! -z "$nonperfsub"; then 302 | echo "SUCCESS: Unwanted subtitle tracks found" 303 | echo "INFO: Marking unwanted subtitle tracks for deletion" 304 | removesubs="true" 305 | else 306 | echo "SUCCESS: No unwanted subtitle tracks found" 307 | removesubs="false" 308 | fi 309 | else 310 | echo "ERROR: No subtitle tracks found, only foreign audio tracks found" 311 | echo "INFO: Deleting video and marking download as failed because no usuable audio/subititles are found in requested langauge" 312 | rm "$video" && echo "INFO: deleted: $video" 313 | exit 1 314 | fi 315 | echo "INFO: Skipping unwanted audo check" 316 | echo "INFO: Skip setting video language" 317 | removeaudio="false" 318 | setundaudio="false" 319 | setvideolanguage="false" 320 | else 321 | echo "ERROR: No subtitle tracks found, only foreign audio tracks found" 322 | echo "INFO: Deleting video and marking download as failed because no usuable audio/subititles are found in requested langauge" 323 | rm "$video" && echo "INFO: deleted: $video" 324 | exit 1 325 | fi 326 | fi 327 | 328 | if [ "${removeaudio}" = false ] && [ "${setundaudio}" = false ] && [ "${removesubs}" = false ] && [ "${setvideolanguage}" = false ]; then 329 | echo "INFO: Video passed all checks, no processing needed" 330 | else 331 | 332 | if [ "${setundaudio}" = true ]; then 333 | if [ "${SetUnknownAudioLanguage}" = true ]; then 334 | 335 | for I in $undaudio 336 | do 337 | OUT=$OUT" -a $I --language $I:${UnkownAudioLanguage}" 338 | done 339 | mkvaudio="$OUT" 340 | 341 | elif [ "${removeaudio}" = true ]; then 342 | mkvaudio=" -a und" 343 | else 344 | mkvaudio="" 345 | fi 346 | else 347 | if [ "${removeaudio}" = true ]; then 348 | mkvaudio=" -a ${PerferredLanguage}" 349 | else 350 | mkvaudio="" 351 | fi 352 | fi 353 | 354 | if [ "${removesubs}" = true ]; then 355 | mkvsubs=" -s ${SubtitleLanguage}" 356 | else 357 | mkvsubs="" 358 | fi 359 | 360 | if [ "${setvideolanguage}" = true ]; then 361 | mkvvideo=" -d ${nonperfvideo} --language ${nonperfvideo}:${PerferredLanguage}" 362 | else 363 | mkvvideo="" 364 | fi 365 | 366 | echo "INFO: Begin processing file with mkvmerge" 367 | if mkvmerge --no-global-tags --title "" -o "$video.merged.mkv"${mkvvideo}${mkvaudio}${mkvsubs} "$video"; then 368 | echo "SUCCESS: mkvmerge complete" 369 | echo "INFO: Options used:${mkvvideo}${mkvaudio}${mkvsubs}" 370 | else 371 | echo "ERROR: mkvmerge failed" 372 | exit 1 373 | fi 374 | # cleanup temp files and rename 375 | mv "$video" "$video.original.mkv" && echo "INFO: Renamed source file" 376 | mv "$video.merged.mkv" "$video" && echo "INFO: Renamed temp file" 377 | rm "$video.original.mkv" && echo "INFO: Deleted source file" 378 | fi 379 | echo "INFO: Processing complete" 380 | echo "==========================" 381 | echo "" 382 | done 383 | 384 | echo "INFO: Video processing complete" 385 | 386 | # script complete, now exiting 387 | exit 0 388 | -------------------------------------------------------------------------------- /sabnzbd/README.md: -------------------------------------------------------------------------------- 1 | # Script Information 2 | These scripts are designed to be used with sabzbd for post-processing on linux based systems 3 | 4 | ## Script Usage 5 | 6 | 1. Download the scripts from this repo 7 | 1. Copy the scripts into the configured "Scripts Folder" directory for sabnzbd, see sabnzbd "folders" configuratino page 8 | 1. Set the permissions on the file to executable (chmod +x ) 9 | 1. Add the post processing script to video download categories 10 | 11 | For additional information, visit the following link: 12 | https://sabnzbd.org/wiki/scripts/post-processing-scripts 13 | 14 | # Script Descriptions 15 | 16 | ## video-processing.bash 17 | This script automtatically downloads **MKV-Cleaner.bash**, **Deobfuscate.py** and then runs both scripts on the intended download. 18 | ###### Important 19 | This script is designed to be used with the following script: https://github.com/RandomNinjaAtk/Scripts/blob/master/lso_docker_ubuntu/sabnzbd_script_setup.bash and only for linuxserver.io sabnzbd docker containers. 20 | 21 | ## MKV-Cleaner.bash 22 | This script removes unwanted audio and subtitle tracks based on configured settings 23 | 24 | ### Configuration Options 25 | Configuration options are found in the top few lines of the script

26 | **RemoveNonVideoFiles** - Deletes non MKV/MP4/AVI files
27 | **Remux** - Remuxes MKV/MP4/AVI into mkv files and removes unwanted audio/subtitles based on the language preference settings
28 | **PerferredLanguage** - Keeps only the audio for the language selected, if not found, fall-back to unknown tracks and if also not found, a final fall-back to all other audio tracks
29 | **SubtitleLanguage** - Removes all subtitles not matching specified language
30 | **SetUnknownAudioLanguage** - If enabled, sets found unknown (und) audio tracks to the language in the next setting
31 | **UnkownAudioLanguage** - Sets unknown language tracks to the language specified

32 | Language Preferences require using "ISO 639-2" language codes, list of codes can be found here: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes 33 | 34 | ### Requirements 35 | * **mkvtoolnix** 36 | 37 | ### Compatibility Testing 38 | * Linuxserver.io Sabnzbd Docker (To install requirements, use the mkvtoolnix_install.bash script found here: https://github.com/RandomNinjaAtk/Scripts/tree/master/lso_docker_ubuntu
39 | 40 |
41 | 42 | ## AudioPostProcessing.bash 43 | This script can verify flac files for corruption, fix errors in mp3 files, transcode flac/alac files to another format, add replaygain tags to flac files 44 | 45 | ### Configuration Options 46 | Configuration options are found in the top few lines of the script

47 | **RemoveNonAudioFiles** - Deletes non FLAC/M4A/MP3/OPUS/OGG files
48 | **DuplicateFileCleanUp** - Deletes duplicate files, sabnzbd sometimes creates duplicates, or if a download contains both lossless and lossy version, it deletes lossy version
49 | **AudioVerification** - Verifies FLAC/MP3 files for errors (fixes MP3's, deletes bad FLAC files)
50 | **Convert** - Only converts lossless FLAC/ALAC files to format in the next setting
51 | **ConversionFormat** - SET TO: OPUS or AAC or MP3 or FLAC - converts lossless FLAC files to set format
52 | **Threads** - SET TO: "0" to use maximum number of threads for multi-threaded operations
53 | **ReplaygainTagging** - adds replaygain tags for compatible players (FLAC ONLY)
54 | 55 | ### Requirements 56 | * **flac** 57 | * **ffmpeg** 58 | * **mp3val** 59 | 60 | ### Compatibility Testing 61 | * Linuxserver.io Sabnzbd Docker (To install requirements, use the ffmpeg_install.bash & audio_tools_install.bash script found here: https://github.com/RandomNinjaAtk/Scripts/tree/master/lso_docker_ubuntu
62 | -------------------------------------------------------------------------------- /sabnzbd/mp4-video-processing.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Download Scripts 4 | 5 | if [ ! -f /config/scripts/sickbeard_mp4_automator/Deobfuscate.py ]; then 6 | echo "downloading Deobfuscate.py from: https://github.com/sabnzbd/sabnzbd/blob/develop/scripts/Deobfuscate.py" 7 | curl -o /config/scripts/sickbeard_mp4_automator/Deobfuscate.py https://raw.githubusercontent.com/sabnzbd/sabnzbd/develop/scripts/Deobfuscate.py 8 | echo "done" 9 | 10 | # Set Permissions 11 | echo "setting permissions..." 12 | chmod +x /config/scripts/sickbeard_mp4_automator/Deobfuscate.py 13 | echo "done" 14 | fi 15 | 16 | if [ ! -f /config/scripts/sickbeard_mp4_automator/MKV-Cleaner.bash ]; then 17 | echo "downloading MKV-Cleaner.bash from: https://github.com/RandomNinjaAtk/Scripts/tree/master/sabnzbd/MKV-Cleaner.bash" 18 | curl -o /config/scripts/sickbeard_mp4_automator/MKV-Cleaner.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/sabnzbd/MKV-Cleaner.bash 19 | echo "done" 20 | 21 | # Set Permissions 22 | echo "setting permissions..." 23 | chmod 777 /config/scripts/MKV-Cleaner.bash 24 | echo "done" 25 | fi 26 | 27 | set -e 28 | 29 | # Execute on new downloads 30 | cd /config/scripts/sickbeard_mp4_automator 31 | 32 | # Run sabnzbd Deobfuscation script 33 | timeout --foreground 1m python Deobfuscate.py 34 | 35 | # Run Cleaner before processing wtih mp4 automator 36 | bash MKV-Cleaner.bash "$1" 37 | 38 | # Manual run of Sickbeard MP4 Automator 39 | python3 manual.py -i "$1" -nt 40 | 41 | 42 | 43 | echo "COMPLETE" 44 | 45 | exit 0 46 | -------------------------------------------------------------------------------- /sabnzbd/video-processing.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Download Scripts 4 | if [ ! -f /config/scripts/MKV-Cleaner.bash ]; then 5 | echo "downloading MKV-Cleaner.bash from: https://github.com/RandomNinjaAtk/Scripts/tree/master/sabnzbd/MKV-Cleaner.bash" 6 | curl -o /config/scripts/MKV-Cleaner.bash https://raw.githubusercontent.com/RandomNinjaAtk/Scripts/master/sabnzbd/MKV-Cleaner.bash 7 | echo "done" 8 | 9 | # Set Permissions 10 | echo "setting permissions..." 11 | chmod 777 /config/scripts/MKV-Cleaner.bash 12 | echo "done" 13 | fi 14 | 15 | if [ ! -f /config/scripts/Deobfuscate.py ]; then 16 | echo "downloading Deobfuscate.py from: https://github.com/sabnzbd/sabnzbd/blob/develop/scripts/Deobfuscate.py" 17 | curl -o /config/scripts/Deobfuscate.py https://raw.githubusercontent.com/sabnzbd/sabnzbd/develop/scripts/Deobfuscate.py 18 | echo "done" 19 | 20 | # Set Permissions 21 | echo "setting permissions..." 22 | chmod 777 /config/scripts/Deobfuscate.py 23 | echo "done" 24 | fi 25 | 26 | # Execute on new downloads 27 | 28 | set -e 29 | 30 | cd /config/scripts 31 | 32 | timeout --foreground 1m python Deobfuscate.py 33 | 34 | bash MKV-Cleaner.bash "$1" 35 | 36 | exit 0 37 | --------------------------------------------------------------------------------