├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md ├── build.sh └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── README.md ├── extras └── auto-restart-plex.sh ├── package.json ├── test ├── get_arch.bats └── process_args.bats ├── update-plex.sh └── yarn.lock /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Script output 11 | ``` 12 | Add update-plex.sh script output here, between the ``` lines. 13 | ``` 14 | 15 | ### NAS Model 16 | Add Synology NAS Model here. 17 | 18 | ### DSM Version 19 | Add DSM version here. 20 | 21 | ### Additional context 22 | Add any other context about the problem here. 23 | -------------------------------------------------------------------------------- /.github/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | set -o pipefail 5 | set -o nounset 6 | # set -o xtrace 7 | 8 | VERSION=$(jq --raw-output '.release.tag_name' "$GITHUB_EVENT_PATH") 9 | 10 | mkdir build 11 | sed "s/(in-development)/$VERSION/" update-plex.sh > build/update-plex.sh 12 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | release: 4 | types: [created] 5 | jobs: 6 | generate: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - run: .github/build.sh 11 | - uses: skx/github-action-publish-binaries@master 12 | env: 13 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 14 | with: 15 | args: 'build/update-plex.sh' 16 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [push, pull_request] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - run: yarn 9 | - run: yarn test 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /build/ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # synology-update-plex 2 | > Script to Auto Update Plex Media Server on Synology NAS 3 | 4 | [![Latest Release](https://img.shields.io/github/v/release/cowboy/synology-update-plex)][release] 5 | [![Test](https://github.com/cowboy/synology-update-plex/workflows/Test/badge.svg)][test-master] 6 | [![Donate](https://img.shields.io/badge/Support%20this%20project!-$5-success)][donate] 7 | 8 | ## Goals 9 | 10 | - Make the echoed messages super clear 11 | - Make the version checking logic as smart as possible 12 | - Ensure the script fails if there are any errors 13 | - Ensure temp files are cleaned up properly 14 | - Write bash code as idiomatically as possible 15 | - Attempt to find the "Plex Media Server" directory that contains Preferences.xml efficiently 16 | - Attempt to support all Synology NAS architectures 17 | 18 | ## Usage 19 | 20 | First, SSH into your NAS, save the [latest release][release] update-plex.sh script somewhere and set it as executable: 21 | 22 | ```sh 23 | $ ssh you@IP_OF_YOUR_NAS 24 | you@yournas:~$ wget "https://github.com/cowboy/synology-update-plex/releases/latest/download/update-plex.sh" 25 | you@yournas:~$ chmod a+x update-plex.sh 26 | ``` 27 | 28 | Then, create a Scheduled Task with a User-defined script in the Synology DSM Control Panel: 29 | - Ensure the User is `root` 30 | - Ensure the Run command is `/path/to/update-plex.sh` 31 | - Add the `--plex-pass` option (eg. `/path/to/update-plex.sh --plex-pass`) if you have Plex Pass and want to enable early access / beta releases 32 | 33 | ## Caveats 34 | 35 | [donate]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RRUNYDUYBAH58&source=url 36 | [test-master]: https://github.com/cowboy/synology-update-plex/actions?query=workflow%3ATest+branch%3Amaster 37 | [release]: https://github.com/cowboy/synology-update-plex/releases/latest 38 | [issue]: https://github.com/cowboy/synology-update-plex/issues 39 | [pr]: https://github.com/cowboy/synology-update-plex/pulls 40 | 41 | - Be careful when SSHing into your NAS. I'm not responsible if you break anything! 42 | - This script may contain bugs. I'm not responsible if it breaks anything! 43 | - This script has been tested on a Synology DS918+ NAS running DSM 7. It should work with other Synology NAS models. 44 | - This script assumes Plex was installed manually from https://www.plex.tv/media-server-downloads/. 45 | - This script sends "Plex Media Server" notifications as "Package Center" because it's simpler than doing it any other way. 46 | 47 | ## Common Issues 48 | 49 | - If the script is trying to download the wrong release file for your NAS, please see the comments at the top of the [get_arch](/test/get_arch.bats) test suite. 50 | - If the script fails with `Unable to find "Plex Media Server" directory` when `--plex-pass` is specified, you may need to manually change `/volume*` in the script to your volume's root path. 51 | - If the script fails with `error = [289]` while installing package, [add Plex as a trusted publisher for package installations](https://support.plex.tv/hc/en-us/articles/205165858). 52 | 53 | If you find a bug or an issue not listed here, please [file an issue][issue] or [create a pull request][pr]. Explain the situation and include all script output. 54 | 55 | 56 | ## References 57 | 58 | Adapted from work first published at: 59 | - https://forums.plex.tv/t/script-to-auto-update-plex-on-synology-nas-rev4/479748 60 | 61 | Including other update scripts such as: 62 | - https://github.com/martinorob/plexupdate 63 | - https://github.com/nitantsoni/plexupdate 64 | - https://gist.github.com/seanhamlin/dcde16a164377dca87a798a4c2ea051c 65 | - https://forums.plex.tv/t/script-to-auto-update-plex-on-synology-nas-rev4/479748/67 66 | 67 | ## License 68 | 69 | [![CC0](http://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg)](https://creativecommons.org/publicdomain/zero/1.0/) 70 | 71 | To the extent possible under law, Ben Alman has waived all copyright and related or neighboring rights to this work. 72 | -------------------------------------------------------------------------------- /extras/auto-restart-plex.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Plex service auto-restart script 4 | # 5 | # Based on 6 | # https://www.reddit.com/r/synology/comments/op7smc/comment/iq4096i/ 7 | # 8 | # Tested in DSM 7.1.1, YMMV 9 | 10 | set -o errexit 11 | set -o pipefail 12 | set -o nounset 13 | # set -o xtrace 14 | 15 | port=32400 16 | 17 | echo "Checking if Plex is running on port $port." 18 | 19 | if netstat -tnlp | grep :$port >/dev/null; then 20 | echo "Plex is running." 21 | exit 0 22 | fi 23 | 24 | echo 'Plex is not running, attempting to restart.' 25 | echo 26 | echo 'Last 20 log entries:' 27 | echo '--------------------' 28 | tail -20 '/volume1/PlexMediaServer/AppData/Plex Media Server/Logs/Plex Media Server.log' 29 | echo '--------------------' 30 | echo 31 | echo 'Ensuring Plex service is stopped...' 32 | synopkg stop PlexMediaServer 33 | echo 34 | echo 'Starting Plex service...' 35 | synopkg start PlexMediaServer 36 | echo 37 | echo 'Done.' 38 | exit 1 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "synology-update-plex", 3 | "description": "Script to Auto Update Plex Media Server on Synology NAS", 4 | "repository": "git@github.com:cowboy/synology-update-plex.git", 5 | "author": "Ben Alman ", 6 | "private": true, 7 | "scripts": { 8 | "test": "bats test", 9 | "watch": "chokidar \"**/*.{sh,bats}\" -c \"bats test\"" 10 | }, 11 | "devDependencies": { 12 | "bats": "^1.1.0", 13 | "chokidar-cli": "^2.1.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/get_arch.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | setup() { 4 | load "${BATS_TEST_DIRNAME}"/../update-plex.sh 5 | } 6 | 7 | # The following armv7 logic was derived from the labels here: 8 | # curl -s "https://plex.tv/api/downloads/5.json" | jq -r '.nas.Synology.releases[] | select(.label | contains("ARMv7"))' 9 | # 10 | # linux-armv7hf 11 | # ARMv7 (x13 Series, x14 Series (excluding DS414j), DS115j, RS815, and DS216se) 12 | # linux-armv7hf_neon 13 | # ARMv7 (x15 Series (excluding DS115j and RS815), x16 Series (excluding DS216se), x17 Series, x18 Series, and DS414j) 14 | # 15 | # Full model list from: 16 | # https://www.synology.com/en-us/knowledgebase/DSM/tutorial/Compatibility_Peripherals/What_kind_of_CPU_does_my_NAS_have 17 | # 18 | # If you're running into problems with the script trying to download the wrong 19 | # release file for your NAS, please note the output of the `uname -m` command 20 | # and the contents of the /proc/sys/kernel/syno_hw_version file and compare them 21 | # to the table below. If anything is missing or incorrect, please file an issue 22 | # with your uname and syno_hw_version values or open a PR like this one: 23 | # https://github.com/cowboy/synology-update-plex/pull/44/files 24 | 25 | @test "get_arch :: should return the correct arch for the x18 series" { 26 | run get_arch armv7 RS3618xs; [[ "$output" == "armv7hf_neon" ]] 27 | run get_arch armv7 RS2818RP+; [[ "$output" == "armv7hf_neon" ]] 28 | run get_arch armv7 RS2418+; [[ "$output" == "armv7hf_neon" ]] 29 | run get_arch armv7 RS2418RP+; [[ "$output" == "armv7hf_neon" ]] 30 | run get_arch armv7 RS818+; [[ "$output" == "armv7hf_neon" ]] 31 | run get_arch armv7 RS818RP+; [[ "$output" == "armv7hf_neon" ]] 32 | run get_arch armv7 DS3018xs; [[ "$output" == "armv7hf_neon" ]] 33 | run get_arch armv7 DS1618+; [[ "$output" == "armv7hf_neon" ]] 34 | run get_arch armv7 DS918+; [[ "$output" == "armv7hf_neon" ]] 35 | run get_arch armv7 DS718+; [[ "$output" == "armv7hf_neon" ]] 36 | run get_arch armv7 DS418; [[ "$output" == "armv7hf_neon" ]] 37 | run get_arch armv7 DS418play; [[ "$output" == "armv7hf_neon" ]] 38 | run get_arch armv7 DS418j; [[ "$output" == "armv7hf_neon" ]] 39 | run get_arch armv7 DS218+; [[ "$output" == "armv7hf_neon" ]] 40 | run get_arch armv7 DS218; [[ "$output" == "armv7hf_neon" ]] 41 | run get_arch armv7 DS218play; [[ "$output" == "armv7hf_neon" ]] 42 | run get_arch armv7 DS218j; [[ "$output" == "armv7hf_neon" ]] 43 | run get_arch armv7 DS118; [[ "$output" == "armv7hf_neon" ]] 44 | } 45 | 46 | @test "get_arch :: should return the correct arch for the x17 series" { 47 | run get_arch armv7 RS18017xs+; [[ "$output" == "armv7hf_neon" ]] 48 | run get_arch armv7 RS4017xs+; [[ "$output" == "armv7hf_neon" ]] 49 | run get_arch armv7 RS3617xs+; [[ "$output" == "armv7hf_neon" ]] 50 | run get_arch armv7 RS3617RPxs; [[ "$output" == "armv7hf_neon" ]] 51 | run get_arch armv7 RS3617xs; [[ "$output" == "armv7hf_neon" ]] 52 | run get_arch armv7 RS217; [[ "$output" == "armv7hf_neon" ]] 53 | run get_arch armv7 DS3617xs; [[ "$output" == "armv7hf_neon" ]] 54 | run get_arch armv7 DS1817+; [[ "$output" == "armv7hf_neon" ]] 55 | run get_arch armv7 DS1817; [[ "$output" == "armv7hf_neon" ]] 56 | run get_arch armv7 DS1517+; [[ "$output" == "armv7hf_neon" ]] 57 | run get_arch armv7 DS1517; [[ "$output" == "armv7hf_neon" ]] 58 | } 59 | 60 | @test "get_arch :: should return the correct arch for the x16 series" { 61 | run get_arch armv7 RS18016xs+; [[ "$output" == "armv7hf_neon" ]] 62 | run get_arch armv7 RS2416+; [[ "$output" == "armv7hf_neon" ]] 63 | run get_arch armv7 RS2416RP+; [[ "$output" == "armv7hf_neon" ]] 64 | run get_arch armv7 RS816; [[ "$output" == "armv7hf_neon" ]] 65 | run get_arch armv7 DS916+; [[ "$output" == "armv7hf_neon" ]] 66 | run get_arch armv7 DS716+II; [[ "$output" == "armv7hf_neon" ]] 67 | run get_arch armv7 DS716+; [[ "$output" == "armv7hf_neon" ]] 68 | run get_arch armv7 DS416; [[ "$output" == "armv7hf_neon" ]] 69 | run get_arch armv7 DS416play; [[ "$output" == "armv7hf_neon" ]] 70 | run get_arch armv7 DS416j; [[ "$output" == "armv7hf_neon" ]] 71 | run get_arch armv7 DS416slim; [[ "$output" == "armv7hf_neon" ]] 72 | run get_arch armv7 DS216+II; [[ "$output" == "armv7hf_neon" ]] 73 | run get_arch armv7 DS216+; [[ "$output" == "armv7hf_neon" ]] 74 | run get_arch armv7 DS216; [[ "$output" == "armv7hf_neon" ]] 75 | run get_arch armv7 DS216play; [[ "$output" == "armv7hf_neon" ]] 76 | run get_arch armv7 DS216play-j; [[ "$output" == "armv7hf_neon" ]] 77 | run get_arch armv7 DS216j; [[ "$output" == "armv7hf_neon" ]] 78 | run get_arch armv7 DS216j-j; [[ "$output" == "armv7neon" ]] 79 | run get_arch armv7 DS216se; [[ "$output" == "armv7hf" ]] 80 | run get_arch armv7 DS116; [[ "$output" == "armv7hf_neon" ]] 81 | } 82 | 83 | @test "get_arch :: should return the correct arch for the x15 series" { 84 | run get_arch armv7 RS815+; [[ "$output" == "armv7hf_neon" ]] 85 | run get_arch armv7 RS815RP+; [[ "$output" == "armv7hf_neon" ]] 86 | run get_arch armv7 RS815; [[ "$output" == "armv7hf" ]] 87 | run get_arch armv7 RC18015xs+; [[ "$output" == "armv7hf_neon" ]] 88 | run get_arch armv7 DS3615xs; [[ "$output" == "armv7hf_neon" ]] 89 | run get_arch armv7 DS2415+; [[ "$output" == "armv7hf_neon" ]] 90 | run get_arch armv7 DS2015xs; [[ "$output" == "armv7hf_neon" ]] 91 | run get_arch armv7 DS1815+; [[ "$output" == "armv7hf_neon" ]] 92 | run get_arch armv7 DS1515+; [[ "$output" == "armv7hf_neon" ]] 93 | run get_arch armv7 DS1515; [[ "$output" == "armv7hf_neon" ]] 94 | run get_arch armv7 DS715; [[ "$output" == "armv7hf_neon" ]] 95 | run get_arch armv7 DS415+; [[ "$output" == "armv7hf_neon" ]] 96 | run get_arch armv7 DS415play; [[ "$output" == "armv7hf_neon" ]] 97 | run get_arch armv7 DS215+; [[ "$output" == "armv7hf_neon" ]] 98 | run get_arch armv7 DS215j; [[ "$output" == "armv7hf_neon" ]] 99 | run get_arch armv7 DS215jv10-j; [[ "$output" == "armv7hf_neon" ]] 100 | run get_arch armv7 DS115; [[ "$output" == "armv7hf_neon" ]] 101 | run get_arch armv7 DS115j; [[ "$output" == "armv7hf" ]] 102 | } 103 | 104 | @test "get_arch :: should return the correct arch for the x14 series" { 105 | run get_arch armv7 RS3614xs+; [[ "$output" == "armv7hf" ]] 106 | run get_arch armv7 RS3614xs; [[ "$output" == "armv7hf" ]] 107 | run get_arch armv7 RS3614RPxs; [[ "$output" == "armv7hf" ]] 108 | run get_arch armv7 RS2414+; [[ "$output" == "armv7hf" ]] 109 | run get_arch armv7 RS2414RP+; [[ "$output" == "armv7hf" ]] 110 | run get_arch armv7 RS814+; [[ "$output" == "armv7hf" ]] 111 | run get_arch armv7 RS814RP+; [[ "$output" == "armv7hf" ]] 112 | run get_arch armv7 RS814; [[ "$output" == "armv7hf" ]] 113 | run get_arch armv7 RS214; [[ "$output" == "armv7hf" ]] 114 | run get_arch armv7 DS414; [[ "$output" == "armv7hf" ]] 115 | run get_arch armv7 DS414j; [[ "$output" == "armv7hf_neon" ]] 116 | run get_arch armv7 DS414slim; [[ "$output" == "armv7hf" ]] 117 | run get_arch armv7 DS214+; [[ "$output" == "armv7hf" ]] 118 | run get_arch armv7 DS214; [[ "$output" == "armv7hf" ]] 119 | run get_arch armv7 DS214play; [[ "$output" == "armv7hf" ]] 120 | run get_arch armv7 DS214se; [[ "$output" == "armv7hf" ]] 121 | run get_arch armv7 DS114; [[ "$output" == "armv7hf" ]] 122 | } 123 | 124 | @test "get_arch :: should return the correct arch for the x13 series" { 125 | run get_arch armv7 RS10613xs+; [[ "$output" == "armv7hf" ]] 126 | run get_arch armv7 RS3413xs+; [[ "$output" == "armv7hf" ]] 127 | run get_arch armv7 DS2413+; [[ "$output" == "armv7hf" ]] 128 | run get_arch armv7 DS1813+; [[ "$output" == "armv7hf" ]] 129 | run get_arch armv7 DS1513+; [[ "$output" == "armv7hf" ]] 130 | run get_arch armv7 DS713+; [[ "$output" == "armv7hf" ]] 131 | run get_arch armv7 DS413; [[ "$output" == "armv7hf" ]] 132 | run get_arch armv7 DS413j; [[ "$output" == "armv7hf" ]] 133 | run get_arch armv7 DS213+; [[ "$output" == "armv7hf" ]] 134 | run get_arch armv7 DS213; [[ "$output" == "armv7hf" ]] 135 | run get_arch armv7 DS213air; [[ "$output" == "armv7hf" ]] 136 | run get_arch armv7 DS213j; [[ "$output" == "armv7hf" ]] 137 | } 138 | 139 | @test "get_arch :: should return x86 if passed-in arch is i686" { 140 | run get_arch i686 DS9001; [[ "$output" == "x86" ]] 141 | } 142 | 143 | @test "get_arch :: should return the passed-in arch if not one of: armv7, i686" { 144 | run get_arch other_arch DS9001; [[ "$output" == "other_arch" ]] 145 | } 146 | -------------------------------------------------------------------------------- /test/process_args.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | setup() { 4 | load "${BATS_TEST_DIRNAME}"/../update-plex.sh 5 | } 6 | 7 | @test 'process_args :: should print nothing by default' { 8 | run process_args 9 | [[ ! "$output" ]] 10 | } 11 | 12 | @test 'process_args :: should print help when --help/-h/-? is specified' { 13 | run process_args --help; [[ "$output" =~ Usage ]] 14 | run process_args -h; [[ "$output" =~ Usage ]] 15 | run process_args -?; [[ "$output" =~ Usage ]] 16 | } 17 | 18 | @test 'process_args :: should print version when --version/-v is specified' { 19 | run process_args --version; [[ "$output" == '(in-development)' ]] 20 | run process_args -v; [[ "$output" == '(in-development)' ]] 21 | } 22 | 23 | @test 'process_args :: should not set plex_pass by default' { 24 | process_args 25 | [[ ! "$plex_pass" ]] 26 | } 27 | 28 | @test 'process_args :: should set plex_pass when --plex-pass is specified' { 29 | process_args --plex-pass 30 | [[ "$plex_pass" ]] 31 | } 32 | 33 | @test 'process_args :: should warn on unknown options' { 34 | run process_args --foo bar --baz >/dev/null 2>&1 35 | [[ "${lines[0]}" == "WARN: Unknown option (ignored): --foo" ]] 36 | [[ "${lines[1]}" == "WARN: Unknown option (ignored): bar" ]] 37 | [[ "${lines[2]}" == "WARN: Unknown option (ignored): --baz" ]] 38 | } 39 | -------------------------------------------------------------------------------- /update-plex.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | script_args=("$@") 4 | script_version='(in-development)' # auto-generated during release 5 | 6 | function help() { cat <&2; } 27 | function fail() { fail_reason="$@"; echo "FAIL: $@"; exit 1; } 28 | 29 | function process_args() { 30 | while [[ "${1-}" ]]; do 31 | case $1 in 32 | -h|-\?|--help) 33 | help 34 | exit 35 | ;; 36 | -v|--version) 37 | echo "$script_version" 38 | exit 39 | ;; 40 | --plex-pass) 41 | plex_pass=1 42 | ;; 43 | *) 44 | warn "Unknown option (ignored): $1" 45 | ;; 46 | esac 47 | shift 48 | done 49 | } 50 | 51 | function dump_vars() { 52 | vars=( 53 | script_args 54 | script_version 55 | plex_pass 56 | pms_dir 57 | dsm_major_version 58 | dsm_minor_version 59 | dsm_micro_version 60 | available_version 61 | installed_version 62 | tmp_dir 63 | package_file 64 | debug_json 65 | ) 66 | header 'Debugging info' 67 | for var in "${vars[@]}"; do 68 | (set -o posix ; set | grep ${var}= || true) 69 | done 70 | echo 71 | } 72 | 73 | function cleanup() { 74 | code=$? 75 | if [[ -d "${tmp_dir-}" ]]; then 76 | header 'Cleaning up' 77 | echo "Removing $tmp_dir" 78 | rm -rf $tmp_dir 79 | fi 80 | if [[ $code == 0 ]]; then 81 | echo 82 | echo 'Done!' 83 | else 84 | notify_failure 85 | dump_vars 86 | echo 'Done, with errors!' 87 | echo 88 | echo 'If this problem persists, please file an issue here, and include the output from this script:' 89 | echo 'https://github.com/cowboy/synology-update-plex/issues' 90 | fi 91 | } 92 | 93 | function notify() { 94 | local json= tag_event=PkgMgr_$1 95 | set -- PKG_NAME "Plex Media Server" "${@:2}" 96 | while [[ "${1-}" ]]; do 97 | [[ -n "$json" ]] && json="$json," 98 | json="$json\"%$1%\":\"${2//\"/\\\"}\"" 99 | shift 2 100 | done 101 | synonotify $tag_event "{$json}" 102 | } 103 | 104 | function notify_success() { 105 | notify UpgradedPkg PKG_VERSION "${available_version:-(unknown)}" 106 | } 107 | 108 | function notify_failure() { 109 | notify UpgradePkgFail FAILED_REASON "${fail_reason-}" 110 | } 111 | 112 | function retrieve_dsm_version() { 113 | header "Retrieving DSM version" 114 | dsm_major_version=$(awk -F "=" '/majorversion/ {print $2}' /etc.defaults/VERSION | tr -d '"') 115 | dsm_minor_version=$(awk -F "=" '/minorversion/ {print $2}' /etc.defaults/VERSION | tr -d '"') 116 | dsm_micro_version=$(awk -F "=" '/micro/ {print $2}' /etc.defaults/VERSION | tr -d '"') 117 | 118 | if [[ "$dsm_major_version" -eq "7" ]]; then 119 | if [[ "$dsm_minor_version" -eq "2" && "$dsm_micro_version" -ge "2" ]] || [[ "$dsm_minor_version" -gt "2" ]]; then 120 | json_dsm_pattern="Synology (DSM 7.2.2+)" 121 | pms_package_name="PlexMediaServer" 122 | echo "Found DSM version 7.2.2+" 123 | else 124 | json_dsm_pattern="Synology (DSM 7)" 125 | pms_package_name="PlexMediaServer" 126 | echo "Found DSM version 7 (before 7.2.2)" 127 | fi 128 | else 129 | json_dsm_pattern="Synology (DSM 6)" 130 | pms_package_name="Plex Media Server" 131 | echo "Found DSM version 6" 132 | fi 133 | } 134 | 135 | function build_downloads_url() { 136 | downloads_url='https://plex.tv/api/downloads/5.json' 137 | 138 | if [[ "${plex_pass-}" ]]; then 139 | header "Enabling Plex Pass releases" 140 | 141 | if [ "$pms_package_name" = "PlexMediaServer" ]; then 142 | pms_dir='/var/packages/PlexMediaServer/home/Plex Media Server' 143 | else 144 | pms_dir="$(echo /volume*"/Plex/Library/Application Support/Plex Media Server")" 145 | fi 146 | if [[ ! -d "$pms_dir" ]]; then 147 | pms_dir="$(find /volume* -type d -name 'Plex Media Server' -execdir test -e "{}/Preferences.xml" \; -print -quit)" 148 | fi 149 | 150 | if [[ ! -d "$pms_dir" ]]; then 151 | fail 'Unable to find "Plex Media Server" directory' 152 | fi 153 | 154 | local prefs_file="$pms_dir/Preferences.xml" 155 | if [[ ! -e "$prefs_file" ]]; then 156 | fail 'Unable to find Preferences.xml file' 157 | fi 158 | 159 | local token=$(grep -oP 'PlexOnlineToken="\K[^"]+' "$prefs_file" || true) 160 | if [[ -z "$token" ]]; then 161 | fail 'Unable to find Plex Token' 162 | fi 163 | 164 | echo "Found Plex Token" 165 | downloads_url="$downloads_url?channel=plexpass&X-Plex-Token=$token" 166 | fi 167 | } 168 | 169 | function retrieve_version_data() { 170 | header 'Retrieving version data' 171 | downloads_json="$(curl -s "$downloads_url")" 172 | if [[ -z "$downloads_json" ]]; then 173 | fail 'Unable to retrieve version data' 174 | fi 175 | } 176 | 177 | function set_available_version() { 178 | available_version=$(jq -r '.nas["'"$json_dsm_pattern"'"].version' <<< "$downloads_json") 179 | if [[ "$available_version" == null ]]; then 180 | debug_json="$downloads_json" 181 | fail 'Unable to retrieve version data' 182 | fi 183 | echo "Available version: $available_version" 184 | } 185 | 186 | function set_installed_version() { 187 | installed_version=$(synopkg version "$pms_package_name") 188 | echo "Installed version: $installed_version" 189 | } 190 | 191 | # https://stackoverflow.com/a/4024263 192 | function version_lte() { 193 | [[ "$1" == "$(echo -e "$1\n$2" | sort -V | head -n1)" ]] 194 | } 195 | 196 | function check_up_to_date() { 197 | set_available_version 198 | set_installed_version 199 | 200 | local available_version_no_build=${available_version/%-*} 201 | local installed_version_no_build=${installed_version/%-*} 202 | 203 | echo 204 | if version_lte "$available_version_no_build" "$installed_version_no_build"; then 205 | if [[ "$installed_version_no_build" != "$available_version_no_build" ]]; then 206 | echo 'The installed version of Plex is newer than the available version. If' \ 207 | 'you have Plex Pass, be sure to run this script with the --plex-pass option.' 208 | fi 209 | echo 'Plex is up-to-date.' 210 | exit 211 | fi 212 | 213 | echo 'New version available!' 214 | } 215 | 216 | function get_arch() { 217 | local arch machine=$1 hw_version=$2 218 | if [[ "$machine" =~ armv7 ]]; then 219 | declare -A model_machine_map 220 | model_machine_map[DS414j]=armv7hf_neon 221 | model_machine_map[DS115j]=armv7hf 222 | model_machine_map[RS815]=armv7hf 223 | model_machine_map[DS216se]=armv7hf 224 | model_machine_map[DS216j-j]=armv7neon 225 | model_machine_map[DS215jv10-j]=armv7hf_neon 226 | if [[ "${model_machine_map[$hw_version]+_}" ]]; then 227 | arch=${model_machine_map[$hw_version]} 228 | elif [[ "${hw_version//[^0-9]/}" =~ 1[5-8]$ ]]; then 229 | arch=armv7hf_neon 230 | else 231 | arch=armv7hf 232 | fi 233 | elif [[ "$machine" =~ i686 ]]; then 234 | arch=x86 235 | else 236 | arch=$machine 237 | fi 238 | echo $arch 239 | } 240 | 241 | function find_release() { 242 | header 'Finding release' 243 | local hw_version=$(