diff --git a/.dockerignore b/.dockerignore index 58df2a2c..03a45ec9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,6 +3,7 @@ .gitignore .github .gitattributes +.vscode .assets READMETEMPLATE.md README.md diff --git a/.github/workflows/BuildImage.yml b/.github/workflows/BuildImage.yml index 5dc31a53..4de4566b 100644 --- a/.github/workflows/BuildImage.yml +++ b/.github/workflows/BuildImage.yml @@ -22,7 +22,7 @@ jobs: echo "MODNAME=${{ env.MODNAME }}" >> $GITHUB_OUTPUT echo "MULTI_ARCH=${{ env.MULTI_ARCH }}" >> $GITHUB_OUTPUT # **** If the mod needs to be versioned, set the versioning logic below. Otherwise leave as is. **** - MOD_VERSION=${GITHUB_SHA:0:7} + MOD_VERSION="2.7.1" echo "MOD_VERSION=${MOD_VERSION}" >> $GITHUB_OUTPUT outputs: GITHUB_REPO: ${{ steps.outputs.outputs.GITHUB_REPO }} diff --git a/Dockerfile b/Dockerfile index e1176038..b05466f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,7 @@ # syntax=docker/dockerfile:1 ## Buildstage ## -FROM ghcr.io/linuxserver/baseimage-alpine:3.19 as buildstage - +FROM ghcr.io/linuxserver/baseimage-alpine:3.20 as buildstage ARG MOD_VERSION # copy local files @@ -17,11 +16,14 @@ RUN \ ## Single layer deployed image ## FROM scratch +ARG MOD_VERSION -LABEL org.opencontainers.image.source=https://github.com/TheCaptain989/radarr-striptracks +LABEL org.opencontainers.image.title=radarr-striptracks LABEL org.opencontainers.image.description="A Docker Mod to Radarr/Sonarr to automatically strip out unwanted audio and subtitle streams" +LABEL org.opencontainers.image.version="${MOD_VERSION}" +LABEL org.opencontainers.image.source="https://github.com/TheCaptain989/radarr-striptracks" +LABEL org.opencontainers.image.authors="TheCaptain989 " LABEL org.opencontainers.image.licenses=GPL-3.0-only -LABEL org.opencontainers.image.authors="TheCaptain989" # Add files from buildstage COPY --from=buildstage /root-layer/ / diff --git a/README.md b/README.md index 922fdcc9..907ee4a3 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ # About -A [Docker Mod](https://github.com/linuxserver/docker-mods) for the LinuxServer.io Radarr/Sonarr v3 Docker container that adds a script to automatically strip out unwanted audio and subtitle tracks, keeping only the desired languages. - -**Beginning with version 2.0 of this mod, it only supports v3 or later of Radarr/Sonarr. For legacy Radarr/Sonarr v2 please use mod release 1.3 or earlier** +A [Docker Mod](https://github.com/linuxserver/docker-mods) for the LinuxServer.io Radarr/Sonarr v3 or higher Docker containers that adds a script to automatically strip out unwanted audio and subtitle tracks, keeping only the desired languages. **This unified script works in both Radarr and Sonarr. Use this mod in either container!** >**NOTE:** This mod supports Linux OSes only. - -Production Container info: ![Docker Image Size](https://img.shields.io/docker/image-size/linuxserver/mods/radarr-striptracks "Container Size") + +Production Container info: ![Docker Image Size](https://img.shields.io/docker/image-size/linuxserver/mods/radarr-striptracks "Container Size") +[![linuxserver/docker-mods/mods/radarr-striptracks](https://img.shields.io/badge/dynamic/json?logo=github&url=https%3A%2F%2Fraw.githubusercontent.com%2Fthecaptain989%2Fghcr-pulls%2Fmaster%2Findex.json&query=%24%5B%3F(%40.owner%3D%3D%22linuxserver%22%20%26%26%20%40.repo%3D%3D%22docker-mods%22%20%26%26%20%40.image%3D%3D%22mods%22%20%26%26%20%40.tag%3D%3D%22radarr-striptracks%22)%5D.pulls&label=ghcr%20pulls&color=1572A4)](https://github.com/linuxserver/docker-mods/pkgs/container/mods) Development Container info: ![Docker Image Size](https://img.shields.io/docker/image-size/thecaptain989/radarr-striptracks "Container Size") -![Docker Pulls](https://img.shields.io/docker/pulls/thecaptain989/radarr-striptracks "Container Pulls") +![Docker Pulls](https://img.shields.io/docker/pulls/thecaptain989/radarr-striptracks?logo=docker "Container Pulls") [![GitHub Super-Linter](https://github.com/TheCaptain989/radarr-striptracks/actions/workflows/linter.yml/badge.svg)](https://github.com/TheCaptain989/radarr-striptracks/actions/workflows/linter.yml "Linter Job") + # Installation 1. Pull your selected container ([linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr "LinuxServer.io's Radarr container") or [linuxserver/sonarr](https://hub.docker.com/r/linuxserver/sonarr "LinuxServer.io's Sonarr container")) from GitHub Container Registry or Docker Hub: @@ -101,7 +101,7 @@ The language selection **'Unknown'** will match tracks with **no configured lang The Radarr language selection **'Any'** has two purposes: 1) It will trigger a search of languages in ***Custom Formats*** - 2) If none are found, it will will preserve **all languages** in the video file. This is functionally equivalent to calling the script with `--audio :any --subs :any` command-line options. See [Any language code](./README.md#any-language-code) below for more details. + 2) If none are found, it will preserve **all languages** in the video file. This is functionally equivalent to calling the script with `--audio :any --subs :any` command-line options. See [Any language code](./README.md#any-language-code) below for more details. >**Note:** When using the *Custom Format* conditions and scoring to select languages you may not get the results you expect. >This can be non-intuitive configuration, especially when using negative scoring and the 'Negate' option. @@ -154,15 +154,15 @@ Where: Option|Argument|Description ---|---|--- --a, --audio||Audio languages to keep
ISO639-2 code(s) prefixed with a colon (`:`) --s, --subs||Subtitle languages to keep
IISO639-2 code(s) prefixed with a colon (`:`) +-a, --audio||Audio languages to keep
ISO 639-2 code(s) prefixed with a colon (`:`) +-s, --subs||Subtitle languages to keep
ISO 639-2 code(s) prefixed with a colon (`:`) -f, --file||If included, the script enters **[Batch Mode](./README.md#batch-mode)** and converts the specified video file.
Requires the `-a` option.
![danger] **WARNING:** Do not use this argument when called from Radarr or Sonarr! -l, --log|\|The log filename
Default of /config/log/striptracks.txt -d, --debug|\[\\]|Enables debug logging. Level is optional.
Default of 1 (low)
2 includes JSON output
3 contains even more JSON output --help| |Display help and exit. --version| |Display version and exit. -The `` and `` are optional arguments that are colon (`:`) prepended language codes in [ISO639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes "List of ISO 639-2 codes") format. +The `` and `` are optional arguments that are colon (`:`) prepended language codes in [ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes "List of ISO 639-2 codes") format. For example: * `:eng` @@ -188,7 +188,7 @@ Several [Included Wrapper Scripts](./README.md#included-wrapper-scripts) use thi ### Unknown language code The `:und` language code is a special code. When used, the script will match on any track that has a null or blank language attribute. If not included, tracks with no language attribute will be removed. ->![danger] **NOTE:** It is common for M2TS and AVI containers to have tracks with unknown languages! It is strongly recommended to include `:und` in most instances unless you know exactly what you're doing. +>![danger] **NOTE:** It is common for M2TS and AVI files to have tracks with unknown languages! It is strongly recommended to include `:und` in most instances unless you know exactly what you're doing. ## Special Handling of Audio The script is smart enough to not remove the last audio track. There is in fact no way to force the script to remove all audio. This way you don't have to specify every possible language if you are importing a foreign film, for example. @@ -336,5 +336,8 @@ This would not be possible without the following: The AWK script parsing mkvmerge output is adapted from Endoro's post on [VideoHelp](https://forum.videohelp.com/threads/343271-BULK-remove-non-English-tracks-from-MKV-container#post2292889). Icons made by [Freepik](https://www.freepik.com) from [Flaticon](https://www.flaticon.com/) +## Legacy Change Notes +Beginning with version 2.0 of this mod, it only supports v3 or later of Radarr/Sonarr. For legacy Radarr/Sonarr v2 please use mod release 1.3 or earlier. + [warning]: .assets/warning.png "Warning" [danger]: .assets/danger.png "Danger" diff --git a/SECURITY.md b/SECURITY.md index 46cfa041..1c28230c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,8 +6,8 @@ Only the latest major and minor version are supported. | Version | Supported | | ------- | ------------------ | -| 2.6.x | :heavy_check_mark: | -| < 2.6 | :x: | +| 2.7.x | :heavy_check_mark: | +| < 2.7 | :x: | ## Reporting a Vulnerability diff --git a/root/usr/local/bin/striptracks.sh b/root/usr/local/bin/striptracks.sh index f257c129..08314b4e 100755 --- a/root/usr/local/bin/striptracks.sh +++ b/root/usr/local/bin/striptracks.sh @@ -809,6 +809,63 @@ function check_compat { [ $striptracks_debug -ge 1 ] && echo "Debug|Feature $1 is $([ $striptracks_return -eq 1 ] && echo "not ")compatible with ${striptracks_type^} v${striptracks_arr_version}." | log return $striptracks_return } +# Get media management configuration +function get_media_config { + local url="$striptracks_api_url/config/mediamanagement" + [ $striptracks_debug -ge 1 ] && echo "Debug|Getting ${striptracks_type^} configuration. Calling ${striptracks_type^} API using GET and URL '$url'" | log + unset striptracks_result + striptracks_result=$(curl -s --fail-with-body -H "X-Api-Key: $striptracks_apikey" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + --get "$url") + local striptracks_curlret=$?; [ $striptracks_curlret -ne 0 ] && { + local striptracks_message=$(echo -e "[$striptracks_curlret] curl error when calling: \"$url\"\nWeb server returned: $(echo $striptracks_result | jq -jcrM .message?)" | awk '{print "Error|"$0}') + echo "$striptracks_message" | log + echo "$striptracks_message" >&2 + } + [ $striptracks_debug -ge 2 ] && echo "API returned: $striptracks_result" | awk '{print "Debug|"$0}' | log + if [ "$(echo $striptracks_result | jq -crM '.id?')" != "null" ] && [ "$(echo $striptracks_result | jq -crM '.id?')" != "" ]; then + local striptracks_return=0 + else + local striptracks_return=1 + fi + return $striptracks_return +} +# Update file metadata in Radarr/Sonarr +function set_video_info { + local url="$striptracks_api_url/$striptracks_video_api/$striptracks_video_id" + local data="$(echo $striptracks_videoinfo | jq -crM .monitored='true')" + local i=0 + for ((i=1; i <= 5; i++)); do + [ $striptracks_debug -ge 1 ] && echo "Debug|Updating monitored to 'true'. Calling ${striptracks_type^} API using PUT and URL '$url' with data $data" | log + unset striptracks_result + striptracks_result=$(curl -s --fail-with-body -H "X-Api-Key: $striptracks_apikey" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -d "$data" \ + -X PUT "$url") + local striptracks_curlret=$?; [ $striptracks_curlret -ne 0 ] && { + local striptracks_message=$(echo -e "[$striptracks_curlret] curl error when calling: \"$url\" with data $data\nWeb server returned: $(echo $striptracks_result | jq -jcrM .message?)" | awk '{print "Error|"$0}') + echo "$striptracks_message" | log + echo "$striptracks_message" >&2 + } + [ $striptracks_debug -ge 2 ] && echo "Debug|API returned ${#striptracks_result} bytes." | log + [ $striptracks_debug -ge 3 ] && echo "API returned: $striptracks_result" | awk '{print "Debug|"$0}' | log + # Exit loop if database is not locked, else wait 1 minute + if [[ ! "$(echo $striptracks_result | jq -jcrM .message?)" =~ database\ is\ locked ]]; then + break + else + echo "Warn|Database is locked; system is likely overloaded. Sleeping 1 minute." | log + sleep 60 + fi + done + if [ $striptracks_curlret -eq 0 -a "${#striptracks_result}" != 0 ]; then + local striptracks_return=0 + else + local striptracks_return=1 + fi + return $striptracks_return +} # Exit program function end_script { # Cool bash feature @@ -1140,6 +1197,20 @@ elif [ -n "$striptracks_api_url" ]; then echo "$striptracks_message" >&2 striptracks_exitstatus=17 fi + # Check if Radarr/Sonarr are configured to unmonitor deleted videos + get_media_config + striptracks_return=$?; [ $striptracks_return -ne 0 ] && { + # No '.id' in returned JSON + striptracks_message="Warn|The Media Management Config API returned no id." + echo "$striptracks_message" | log + echo "$striptracks_message" >&2 + striptracks_exitstatus=17 + } + if [ "$(echo "$striptracks_result" | jq -crM ".autoUnmonitorPreviouslyDownloaded${striptracks_video_api^}s")" = "true" ]; then + striptracks_conf_unmonitor=1 + striptracks_message="Warn|Will compensate for ${striptracks_type^} configuration to unmonitor deleted ${striptracks_video_api}s." + echo "$striptracks_message" | log + fi else # No URL means we can't call the API striptracks_message="Warn|Unable to determine ${striptracks_type^} API URL." @@ -1518,8 +1589,18 @@ elif [ -n "$striptracks_api_url" ]; then # Get new video file id if get_video_info; then - striptracks_videofile_id="$(echo $striptracks_result | jq -crM .${striptracks_json_quality_root}.id)" + striptracks_videoinfo="$striptracks_result" + striptracks_videofile_id="$(echo $striptracks_videoinfo | jq -crM .${striptracks_json_quality_root}.id)" [ $striptracks_debug -ge 1 ] && echo "Debug|Using new video file id '$striptracks_videofile_id'" | log + + # Check if video is unmonitored after the delete/import + if [ $striptracks_conf_unmonitor -eq 1 -a "$(echo "$striptracks_videoinfo" | jq -crM ".monitored")" = "false" ]; then + striptracks_message="Warn|'$striptracks_title' is unmonitored after deleting the original video. Compensating for ${striptracks_type^} configuration." + echo "$striptracks_message" | log + # Set video to monitored again + set_video_info + fi + # Get new video file info if get_videofile_info; then striptracks_videofile_info="$striptracks_result"