diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml deleted file mode 100644 index 574f9b33..00000000 --- a/.github/codeql-config.yml +++ /dev/null @@ -1,4 +0,0 @@ -name: CodeQL Config - -paths-ignore: - - lib diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index e9c8e05d..00000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: CodeQL - -on: - push: - branches: [nightly] - pull_request: - branches: [nightly] - schedule: - - cron: '05 10 * * 1' - -jobs: - codeql-analysis: - name: CodeQL Analysis - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: ['javascript', 'python'] - - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - config-file: ./.github/codeql-config.yml - languages: ${{ matrix.language }} - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/issues-stale.yml b/.github/workflows/issues-stale.yml index b805e266..4605bcec 100644 --- a/.github/workflows/issues-stale.yml +++ b/.github/workflows/issues-stale.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Stale - uses: actions/stale@v9 + uses: actions/stale@v5 with: stale-issue-message: > This issue is stale because it has been open for 30 days with no activity. @@ -30,7 +30,7 @@ jobs: days-before-close: 5 - name: Invalid Template - uses: actions/stale@v9 + uses: actions/stale@v5 with: stale-issue-message: > Invalid issues template. diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml index a60987f5..728cd8c9 100644 --- a/.github/workflows/issues.yml +++ b/.github/workflows/issues.yml @@ -10,6 +10,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Label Issues - uses: dessant/label-actions@v4 + uses: dessant/label-actions@v2 with: github-token: ${{ github.token }} diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 62c3f86c..64747d4c 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -1,7 +1,6 @@ name: Publish Docker on: - workflow_dispatch: ~ push: branches: [master, beta, nightly] tags: [v*] @@ -13,40 +12,41 @@ jobs: if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v3.0.2 - name: Prepare id: prepare run: | if [[ $GITHUB_REF == refs/tags/* ]]; then - echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + echo ::set-output name=tag::${GITHUB_REF#refs/tags/} elif [[ $GITHUB_REF == refs/heads/master ]]; then - echo "tag=latest" >> $GITHUB_OUTPUT + echo ::set-output name=tag::latest else - echo "tag=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + echo ::set-output name=tag::${GITHUB_REF#refs/heads/} fi if [[ $GITHUB_REF == refs/tags/*-beta ]]; then - echo "branch=beta" >> $GITHUB_OUTPUT + echo ::set-output name=branch::beta elif [[ $GITHUB_REF == refs/tags/* ]]; then - echo "branch=master" >> $GITHUB_OUTPUT + echo ::set-output name=branch::master else - echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + echo ::set-output name=branch::${GITHUB_REF#refs/heads/} fi - echo "commit=${GITHUB_SHA}" >> $GITHUB_OUTPUT - echo "docker_platforms=linux/amd64,linux/arm64/v8,linux/arm/v7,linux/arm/v6" >> $GITHUB_OUTPUT - echo "docker_image=${{ secrets.DOCKER_REPO }}/tautulli" >> $GITHUB_OUTPUT + echo ::set-output name=commit::${GITHUB_SHA} + echo ::set-output name=build_date::$(date -u +'%Y-%m-%dT%H:%M:%SZ') + echo ::set-output name=docker_platforms::linux/amd64,linux/arm64/v8,linux/arm/v7,linux/arm/v6 + echo ::set-output name=docker_image::${{ secrets.DOCKER_REPO }}/tautulli - name: Set Up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v2 id: buildx with: version: latest - name: Cache Docker Layers - uses: actions/cache@v4 + uses: actions/cache@v3.0.3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} @@ -54,28 +54,22 @@ jobs: ${{ runner.os }}-buildx- - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@v2 if: success() with: username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v2 if: success() with: registry: ghcr.io username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.GHCR_TOKEN }} - - name: Extract Docker Metadata - id: metadata - uses: docker/metadata-action@v5 - with: - images: ${{ steps.prepare.outputs.docker_image }} - - name: Docker Build and Push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v3 if: success() with: context: . @@ -86,10 +80,10 @@ jobs: TAG=${{ steps.prepare.outputs.tag }} BRANCH=${{ steps.prepare.outputs.branch }} COMMIT=${{ steps.prepare.outputs.commit }} + BUILD_DATE=${{ steps.prepare.outputs.build_date }} tags: | ${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.tag }} ghcr.io/${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.tag }} - labels: ${{ steps.metadata.outputs.labels }} cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache @@ -99,10 +93,23 @@ jobs: if: always() && !contains(github.event.head_commit.message, '[skip ci]') runs-on: ubuntu-latest steps: + - name: Get Build Job Status + uses: technote-space/workflow-conclusion-action@v2.2 + + - name: Combine Job Status + id: status + run: | + failures=(neutral, skipped, timed_out, action_required) + if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then + echo ::set-output name=status::failure + else + echo ::set-output name=status::$WORKFLOW_CONCLUSION + fi + - name: Post Status to Discord uses: sarisia/actions-status-discord@v1 with: webhook: ${{ secrets.DISCORD_WEBHOOK }} - status: ${{ needs.build-docker.result == 'success' && 'success' || contains(needs.*.result, 'failure') && 'failure' || 'cancelled' }} + status: ${{ steps.status.outputs.status }} title: ${{ github.workflow }} nofail: true diff --git a/.github/workflows/publish-installers.yml b/.github/workflows/publish-installers.yml index b4a66960..bb100a2e 100644 --- a/.github/workflows/publish-installers.yml +++ b/.github/workflows/publish-installers.yml @@ -1,18 +1,14 @@ name: Publish Installers on: - workflow_dispatch: ~ push: branches: [master, beta, nightly] tags: [v*] -env: - PYTHON_VERSION: '3.11' - jobs: build-installer: name: Build ${{ matrix.os_upper }} Installer - runs-on: ${{ matrix.os }}-${{ matrix.os_version }} + runs-on: ${{ matrix.os }}-latest if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} strategy: fail-fast: false @@ -20,18 +16,14 @@ jobs: include: - os: 'windows' os_upper: 'Windows' - os_version: 'latest' - arch: 'x64' ext: 'exe' - os: 'macos' os_upper: 'MacOS' - os_version: '14' - arch: 'universal' ext: 'pkg' steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v3.0.2 - name: Set Release Version id: get_version @@ -40,14 +32,14 @@ jobs: if [[ $GITHUB_REF == refs/tags/* ]]; then echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV VERSION_NSIS=${GITHUB_REF#refs/tags/v}.1 - echo "VERSION_NSIS=${VERSION_NSIS/%-beta.1/.0}" >> $GITHUB_OUTPUT - echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT - echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + echo ::set-output name=VERSION_NSIS::${VERSION_NSIS/%-beta.1/.0} + echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/v} + echo ::set-output name=RELEASE_VERSION::${GITHUB_REF#refs/tags/} else echo "VERSION=0.0.0" >> $GITHUB_ENV - echo "VERSION_NSIS=0.0.0.0" >> $GITHUB_OUTPUT - echo "VERSION=0.0.0" >> $GITHUB_OUTPUT - echo "RELEASE_VERSION=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + echo ::set-output name=VERSION_NSIS::0.0.0.0 + echo ::set-output name=VERSION::0.0.0 + echo ::set-output name=RELEASE_VERSION::${GITHUB_SHA::7} fi if [[ $GITHUB_REF == refs/tags/*-beta ]]; then echo "beta" > branch.txt @@ -59,29 +51,34 @@ jobs: echo $GITHUB_SHA > version.txt - name: Set Up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v3.1.2 with: - python-version: ${{ env.PYTHON_VERSION }} - cache: pip - cache-dependency-path: '**/requirements*.txt' + python-version: 3.9 + + - name: Cache Dependencies + uses: actions/cache@v3.0.3 + with: + path: ~\AppData\Local\pip\Cache + key: ${{ runner.os }}-pip-${{ hashFiles('package/requirements-package.txt') }} + restore-keys: ${{ runner.os }}-pip- - name: Install Dependencies run: | python -m pip install --upgrade pip - pip install -r package/requirements-package.txt --no-binary cffi + pip install -r package/requirements-package.txt - name: Build Package run: | pyinstaller -y ./package/Tautulli-${{ matrix.os }}.spec - name: Create Windows Installer - uses: joncloud/makensis-action@v4.1 + uses: joncloud/makensis-action@v3.6 if: matrix.os == 'windows' with: script-file: ./package/Tautulli.nsi arguments: > /DVERSION=${{ steps.get_version.outputs.VERSION_NSIS }} - /DINSTALLER_NAME=..\Tautulli-${{ matrix.os }}-${{ steps.get_version.outputs.RELEASE_VERSION }}-${{ matrix.arch }}.${{ matrix.ext }} + /DINSTALLER_NAME=..\Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.exe additional-plugin-paths: package/nsis-plugins - name: Create MacOS Installer @@ -92,31 +89,13 @@ jobs: --version ${{ steps.get_version.outputs.VERSION }} \ --component ./dist/Tautulli.app \ --scripts ./package/macos-scripts \ - Tautulli-${{ matrix.os }}-${{ steps.get_version.outputs.RELEASE_VERSION }}-${{ matrix.arch }}.${{ matrix.ext }} + Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.pkg - name: Upload Installer - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3 with: name: Tautulli-${{ matrix.os }}-installer - path: Tautulli-${{ matrix.os }}-${{ steps.get_version.outputs.RELEASE_VERSION }}-${{ matrix.arch }}.${{ matrix.ext }} - - virus-total: - name: VirusTotal Scan - needs: build-installer - if: needs.build-installer.result == 'success' && !contains(github.event.head_commit.message, '[skip ci]') - runs-on: ubuntu-latest - steps: - - name: Download Installers - if: needs.build-installer.result == 'success' - uses: actions/download-artifact@v4 - - - name: Upload to VirusTotal - uses: crazy-max/ghaction-virustotal@v4 - with: - vt_api_key: ${{ secrets.VT_API_KEY }} - files: | - Tautulli-windows-installer/Tautulli-windows-*-x64.exe - Tautulli-macos-installer/Tautulli-macos-*-universal.pkg + path: Tautulli-${{ matrix.os }}-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.${{ matrix.ext }} release: name: Release Installers @@ -124,44 +103,63 @@ jobs: if: always() && startsWith(github.ref, 'refs/tags/') && !contains(github.event.head_commit.message, '[skip ci]') runs-on: ubuntu-latest steps: + - name: Get Build Job Status + uses: technote-space/workflow-conclusion-action@v2.2 + - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v3.0.2 - name: Set Release Version id: get_version run: | - echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + echo ::set-output name=RELEASE_VERSION::${GITHUB_REF#refs/tags/} - name: Download Installers - if: needs.build-installer.result == 'success' - uses: actions/download-artifact@v4 + if: env.WORKFLOW_CONCLUSION == 'success' + uses: actions/download-artifact@v3 - name: Get Changelog id: get_changelog run: | - CHANGELOG="$( sed -n '/^## /{p; :loop n; p; /^## /q; b loop}' CHANGELOG.md \ - | sed '$d' | sed '$d' | sed '$d' )" - EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) - echo "CHANGELOG<<$EOF" >> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "$EOF" >> $GITHUB_OUTPUT + echo ::set-output name=CHANGELOG::"$( sed -n '/^## /{p; :loop n; p; /^## /q; b loop}' CHANGELOG.md \ + | sed '$d' | sed '$d' | sed '$d' | sed ':a;N;$!ba;s/\n/%0A/g' )" - name: Create Release - uses: softprops/action-gh-release@v2 + uses: actions/create-release@v1 id: create_release env: - GITHUB_TOKEN: ${{ secrets.GHACTIONS_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ steps.get_version.outputs.RELEASE_VERSION }} - name: Tautulli ${{ steps.get_version.outputs.RELEASE_VERSION }} + release_name: Tautulli ${{ steps.get_version.outputs.RELEASE_VERSION }} body: | ## Changelog ##${{ steps.get_changelog.outputs.CHANGELOG }} + draft: false prerelease: ${{ endsWith(steps.get_version.outputs.RELEASE_VERSION, '-beta') }} - files: | - Tautulli-windows-installer/Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.exe - Tautulli-macos-installer/Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}-universal.pkg + + - name: Upload Windows Installer + uses: actions/upload-release-asset@v1 + if: env.WORKFLOW_CONCLUSION == 'success' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: Tautulli-windows-installer/Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.exe + asset_name: Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.exe + asset_content_type: application/vnd.microsoft.portable-executable + + - name: Upload MacOS Installer + uses: actions/upload-release-asset@v1 + if: env.WORKFLOW_CONCLUSION == 'success' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: Tautulli-macos-installer/Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.pkg + asset_name: Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.pkg + asset_content_type: application/vnd.apple.installer+xml discord: name: Discord Notification @@ -169,10 +167,23 @@ jobs: if: always() && !contains(github.event.head_commit.message, '[skip ci]') runs-on: ubuntu-latest steps: + - name: Get Build Job Status + uses: technote-space/workflow-conclusion-action@v2.2 + + - name: Combine Job Status + id: status + run: | + failures=(neutral, skipped, timed_out, action_required) + if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then + echo ::set-output name=status::failure + else + echo ::set-output name=status::$WORKFLOW_CONCLUSION + fi + - name: Post Status to Discord uses: sarisia/actions-status-discord@v1 with: webhook: ${{ secrets.DISCORD_WEBHOOK }} - status: ${{ needs.build-installer.result == 'success' && 'success' || contains(needs.*.result, 'failure') && 'failure' || 'cancelled' }} + status: ${{ steps.status.outputs.status }} title: ${{ github.workflow }} nofail: true diff --git a/.github/workflows/publish-snap.yml b/.github/workflows/publish-snap.yml index b3898a38..1d365996 100644 --- a/.github/workflows/publish-snap.yml +++ b/.github/workflows/publish-snap.yml @@ -1,7 +1,6 @@ name: Publish Snap on: - workflow_dispatch: ~ push: branches: [master, beta, nightly] tags: [v*] @@ -15,51 +14,55 @@ jobs: fail-fast: false matrix: architecture: + - i386 - amd64 - arm64 - armhf + - ppc64el + #- s390x # broken at the moment steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v3.0.2 - name: Prepare id: prepare run: | git fetch --prune --unshallow --tags if [[ $GITHUB_REF == refs/tags/*-beta || $GITHUB_REF == refs/heads/beta ]]; then - echo "RELEASE=beta" >> $GITHUB_OUTPUT + echo ::set-output name=RELEASE::beta elif [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then - echo "RELEASE=stable" >> $GITHUB_OUTPUT + echo ::set-output name=RELEASE::stable else - echo "RELEASE=edge" >> $GITHUB_OUTPUT + echo ::set-output name=RELEASE::edge fi - name: Set Up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v2 + with: + image: tonistiigi/binfmt@sha256:df15403e06a03c2f461c1f7938b171fda34a5849eb63a70e2a2109ed5a778bde - name: Build Snap Package - uses: diddlesnaps/snapcraft-multiarch-action@master + uses: diddlesnaps/snapcraft-multiarch-action@v1 id: build with: architecture: ${{ matrix.architecture }} - name: Upload Snap Package - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3 with: name: Tautulli-snap-package-${{ matrix.architecture }} path: ${{ steps.build.outputs.snap }} - name: Review Snap Package - uses: diddlesnaps/snapcraft-review-tools-action@master + uses: diddlesnaps/snapcraft-review-tools-action@v1 with: snap: ${{ steps.build.outputs.snap }} - name: Publish Snap Package uses: snapcore/action-publish@v1 if: startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/nightly' - env: - SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }} with: + store_login: ${{ secrets.SNAP_LOGIN }} snap: ${{ steps.build.outputs.snap }} release: ${{ steps.prepare.outputs.RELEASE }} @@ -69,10 +72,23 @@ jobs: if: always() && !contains(github.event.head_commit.message, '[skip ci]') runs-on: ubuntu-latest steps: + - name: Get Build Job Status + uses: technote-space/workflow-conclusion-action@v2.2 + + - name: Combine Job Status + id: status + run: | + failures=(neutral, skipped, timed_out, action_required) + if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then + echo ::set-output name=status::failure + else + echo ::set-output name=status::$WORKFLOW_CONCLUSION + fi + - name: Post Status to Discord uses: sarisia/actions-status-discord@v1 with: webhook: ${{ secrets.DISCORD_WEBHOOK }} - status: ${{ needs.build-snap.result == 'success' && 'success' || contains(needs.*.result, 'failure') && 'failure' || 'cancelled' }} + status: ${{ steps.status.outputs.status }} title: ${{ github.workflow }} nofail: true diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml index ac550fe2..08f92507 100644 --- a/.github/workflows/pull-requests.yml +++ b/.github/workflows/pull-requests.yml @@ -10,14 +10,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v3.0.2 - name: Comment on Pull Request - uses: mshick/add-pr-comment@v2 + uses: mshick/add-pr-comment@v1 if: github.base_ref != 'nightly' with: message: Pull requests must be made to the `nightly` branch. Thanks. repo-token: ${{ secrets.GITHUB_TOKEN }} + repo-token-user-login: 'github-actions[bot]' - name: Fail Workflow if: github.base_ref != 'nightly' diff --git a/.github/workflows/submit-winget.yml b/.github/workflows/submit-winget.yml deleted file mode 100644 index efa6cee7..00000000 --- a/.github/workflows/submit-winget.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Submit winget - -on: - workflow_dispatch: ~ - release: - types: [published] - -jobs: - winget: - name: Submit Winget Package - runs-on: windows-latest - if: ${{ !github.event.release.prerelease }} - steps: - - name: Sync Winget Fork - run: gh repo sync ${{ secrets.WINGET_USERNAME }}/winget-pkgs -b master - env: - GH_TOKEN: ${{ secrets.WINGET_TOKEN }} - - - name: Submit package to Windows Package Manager Community Repository - run: | - $wingetPackage = "Tautulli.Tautulli" - $gitToken = "${{ secrets.WINGET_TOKEN }}" - - $github = Invoke-RestMethod -uri "https://api.github.com/repos/Tautulli/Tautulli/releases/latest" - $installerUrl = $github | Select -ExpandProperty assets -First 1 | Where-Object -Property name -match "Tautulli-windows-.*-x64.exe" | Select -ExpandProperty browser_download_url - $version = "$($github.tag_name.Trim('v')).1" - - # getting latest wingetcreate file - iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe - .\wingetcreate.exe update $wingetPackage -s -v $version -u $installerUrl -t $gitToken - - virus-total: - name: VirusTotal Scan - runs-on: ubuntu-latest - steps: - - name: Upload to VirusTotal - uses: crazy-max/ghaction-virustotal@v4 - with: - vt_api_key: ${{ secrets.VT_API_KEY }} - github_token: ${{ secrets.GHACTIONS_TOKEN }} - update_release_body: true - files: | - .exe$ - .pkg$ diff --git a/.gitignore b/.gitignore index 1e54132b..68d5abaf 100644 --- a/.gitignore +++ b/.gitignore @@ -53,9 +53,6 @@ Thumbs.db #Ignore files generated by PyCharm *.idea/* -#Ignore files generated by VSCode -*.vscode/* - #Ignore files generated by vi *.swp diff --git a/CHANGELOG.md b/CHANGELOG.md index b349b355..54ed38b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,409 +1,5 @@ # Changelog -## v2.15.3 (2025-08-03) - -* Exporter: - * New: Added hearingImpaired for subtitles and visualImpaired for audio attributes to exporter fields. -* Graphs: - * Fix: Remove duplicate "Total" entry in graph tooltips. (Thanks @zdimension) (#2534) -* UI: - * Fix: Failing to retrieve collections / playlists with over 1000 items. - * Fix: Scrollbar not showing on macosx and webkit browsers. (#2221) - * Fix: Incorrect rounding of minutes in global stats play duration. - * Fix: Disable browser autocomplete for notification agent and newsletter agent configurations. (#2557) -* API: - * New: Added ability to return svg files using pms_image_proxy API command. -* Other: - * New: Added ability to set config values using environment variables. (Thanks @komuw) (#2309, #2543) - - -## v2.15.2 (2025-04-12) - -* Activity: - * New: Added link to library by clicking media type icon. - * New: Added stream count to tab title on homepage. (#2517) -* History: - * Fix: Check stream watched status before stream stopped status. (#2506) -* Notifications: - * Fix: ntfy notifications failing to send if provider link is blank. - * Fix: Check Pushover notification attachment is under 5MB limit. (#2396) - * Fix: Track URLs redirecting to the correct media page. (#2513) - * New: Added audio profile notification parameters. - * New: Added PATCH method for Webhook notifications. -* Graphs: - * New: Added Total line to daily streams graph. (Thanks @zdimension) (#2497) -* UI: - * Fix: Do not redirect API requests to the login page. (#2490) - * Change: Swap source and stream columns in stream info modal. -* Other: - * Fix: Various typos. (Thanks @luzpaz) (#2520) - * Fix: CherryPy CORS response header not being set correctly. (#2279) - - -## v2.15.1 (2025-01-11) - -* Activity: - * Fix: Detection of HDR transcodes. (Thanks @cdecker08) (#2412, #2466) -* Newsletters: - * Fix: Disable basic authentication for /newsletter and /image endpoints. (#2472) -* Exporter: - * New: Added logos to season and episode exports. -* Other: - * Fix: Docker container https health check. - - -## v2.15.0 (2024-11-24) - -* Notes: - * Support for Python 3.8 has been dropped. The minimum Python version is now 3.9. -* Notifications: - * New: Allow Telegram blockquote and tg-emoji HTML tags. (Thanks @MythodeaLoL) (#2427) - * New: Added Plex slug and Plex Watch URL notification parameters. (#2420) - * Change: Update OneSignal API calls to use the new API endpoint for Tautulli Remote App notifications. -* Newsletters: - * Fix: Dumping custom dates in raw newsletter json. -* History: - * Fix: Unable to fix match for artists. (#2429) -* Exporter: - * New: Added movie and episode hasVoiceActivity attribute to exporter fields. - * New: Added subtitle canAutoSync attribute to exporter fields. - * New: Added logos to the exporter fields. -* UI: - * New: Add friendly name to the top bar of config modals. (Thanks @peagravel) (#2432) -* API: - * New: Added plex slugs to metadata in the get_metadata API command. -* Other: - * Fix: Tautulli failing to start with Python 3.13. (#2426) - - -## v2.14.6 (2024-10-12) - -* Newsletters: - * Fix: Allow formatting newsletter date parameters. - * Change: Support apscheduler compatible cron expressions. -* UI: - * Fix: Round runtime before converting to human duration. - * Fix: Make recently added/watched rows touch scrollable. -* Other: - * Fix: Auto-updater not running. - - -## v2.14.5 (2024-09-20) - -* Activity: - * Fix: Display of 2k resolution on activity card. -* Notifications: - * Fix: ntfy notifications with special characters failing to send. -* Other: - * Fix: Memory leak with database closing. (#2404) - - -## v2.14.4 (2024-08-10) - -* Notifications: - * Fix: Update Slack notification info card. - * New: Added ntfy notification agent. (Thanks @nwithan8) (#2356, #2000) -* UI: - * Fix: macOS platform capitalization. -* Other: - * Fix: Remove deprecated getdefaultlocale. (Thanks @teodorstelian) (#2364, #2345) - - -## v2.14.3 (2024-06-19) - -* Graphs: - * Fix: History table not loading when clicking on the graphs in some instances. -* UI: - * Fix: Scheduled tasks table not loading when certain tasks are disabled. - * Removed: Unnecessary Remote Server checkbox from the settings page. -* Other: - * Fix: Webserver not restarting after the setup wizard. - * Fix: Workaround webserver crashing in some instances. - - -## v2.14.2 (2024-05-18) - -* History: - * Fix: Live TV activity not logging to history. - * Fix: Incorrect grouping of live TV history. -* Notifications: - * Fix: Pushover configuration settings refreshing after entering a token. - * Fix: Plex remote access down notifications not triggering. - * Fix: Deleting all images from Cloudinary only deleting 1000 images. - * New: Added platform version and product version notification parameters. (#2244) - * New: Added LAN streams and WAN streams notification parameters. (#2276) - * New: Added Dolby Vision notification parameters. (#2240) - * New: Added live TV channel notification parameters. - * Change: Improved Tautulli Remote App notification encryption method. - * Note: Requires Tautulli Remote App version 3.2.4. -* Exporter: - * New: Added slug attribute to exporter fields. - * New: Added track genres to exporter fields. - * New: Added playlist source URI to exporter fields. - * New: Added artProvider and thumbProvider to exporter fields. -* UI: - * Fix: Mask deleted usernames in the logs. - * Fix: Live TV watch stats not showing on the media info page. - * Fix: Users without access to Plex server not showing as inactive. - * Removed: Deprecated synced item pages. - * Removed: Anonymous redirect settings. Links now use browser no-referrer policy instead. -* API: - * New: Added Dolby Vision info to the get_metadata API command. - * New: Added before and after parameters to the get_home_stats API command. (#2231) -* Packages: - * New: Universal binary for macOS for Apple silicon. - * New: Bump Snap package to core22. -* Other: - * Change: Login cookie expires changed to max-age. - * Change: Improved key generation for login password. It is recommended to reenter your HTTP Password in the settings after upgrading. - * Removed: Python 2 compatibility code. (#2098, #2226) (Thanks @zdimension) - - -## v2.13.4 (2023-12-07) - -* UI: - * Fix: Tautulli configuration settings page not loading when system language is None. - * Fix: Login cookie expiring too quickly. - - -## v2.13.3 (2023-12-03) - -* Notifications: - * New: Added duration_time notification parameter. - * New: Added file_size_bytes notification parameter. - * New: Added time formats notification text modifiers. - * New: Added support for thetvdb_url for movies. -* UI: - * Fix: Activity card overflowing due to screen scaling. (#2033) - * Fix: Stream duration on activity card not being updated on track changes in some cases. (#2206) - - -## v2.13.2 (2023-10-26) - -* History: - * New: Added quarter values icons for history watch status. (#2179, #2156) (Thanks @herby2212) -* Graphs: - * New: Added concurrent streams per day graph. (#2046) (Thanks @herby2212) -* Exporter: - * New: Added metadata directory to exporter fields. - * Removed: Banner exporter fields for tv shows. -* UI: - * New: Added last triggered time to notification agents and newsletter agent lists. -* Other: - * New: Added X-Plex-Language header override to config file. - - -## v2.13.1 (2023-08-25) - -* Notes: - * Support for Python 3.7 has been dropped. The minimum Python version is now 3.8. -* Other: - * Fix: Tautulli failing to start on some systems. - - -## v2.13.0 (2023-08-25) - -* Notes: - * Support for Python 3.7 has been dropped. The minimum Python version is now 3.8. -* Notifications: - * Fix: Improved watched notification trigger description. (#2104) - * New: Added notification image option for iOS Tautulli Remote app. -* Exporter: - * New: Added track chapter export fields. - * New: Added on-demand subtitle export fields. - - -## v2.12.5 (2023-07-13) - -* Activity: - * New: Added d3d11va to list of hardware decoders. -* History: - * Fix: Incorrect grouping of play history. - * New: Added button in settings to regroup play history. -* Notifications: - * Fix: Incorrect concurrent streams notifications by IP addresss for IPv6 addresses (#2096) (Thanks @pooley182) -* UI: - * Fix: Occasional UI crashing on Python 3.11. - * New: Added multiselect user filters to History and Graphs pages. (#2090) (Thanks @zdimension) -* API: - * New: Added regroup_history API command. - * Change: Updated graph API commands to accept a comma separated list of user IDs. - - -## v2.12.4 (2023-05-23) - -* History: - * Fix: Set view offset equal to duration if a stream is stopped within the last 10 sec. -* Other: - * Fix: Database import may fail for some older databases. - * Fix: Double-quoted strings for newer versions of SQLite. (#2015, #2057) -* API: - * Change: Return the ID for async API calls (export_metadata, notify, notify_newsletter). - - -## v2.12.3 (2023-04-14) - -* Activity: - * Fix: Incorrect subtitle decision shown when subtitles are transcoded. -* History: - * Fix: Incorrect order when sorting by the duration column in the history tables. -* Notifications: - * Fix: Logging error when running scripts that use PlexAPI. -* UI: - * Fix: Calculate file sizes setting causing the media info table to fail to load. - * Fix: Incorrect artwork and thumbnail shown for Live TV on the Most Active Libraries statistics card. -* API: - * Change: Renamed duration to play_duration in the get_history API response. (Note: duration kept for backwards compatibility.) - - -## v2.12.2 (2023-03-16) - -* Other: - * Fix: Tautulli not starting on FreeBSD jails. - - -## v2.12.1 (2023-03-14) - -* Activity: - * Fix: Stop checking for deprecated sync items sessions. - * Change: Do not show audio language on activity cards for music. -* Other: - * Fix: Tautulli not starting on macOS. - - -## v2.12.0 (2023-03-13) - -* Notifications: - * New: Added support for Telegram group topics. (#1980) - * New: Added anidb_id and anidb_url notification parameters. (#1973) - * New: Added notification triggers for Intro Marker, Commercial Marker, and Credits Marker. - * New: Added various intro, commercial, and credits marker notification parameters. - * New: Allow setting a custom Pushover notification sound. (#2005) - * Change: Notification images are now uploaded directly to Discord without the need for a 3rd party image hosting service. - * Change: Automatically strip whitespace from notification condition values. - * Change: Trigger watched notifications based on the video watched completion behaviour setting. -* Exporter: - * Fix: Unable to run exporter when using the Snap package. (#2007) - * New: Added credits marker, and audio/subtitle settings to export fields. -* UI: - * Fix: Incorrect styling and missing content for collection media info pages. - * New: Added edition details field on movie media info pages. (#1957) (Thanks @herby2212) - * New: Added setting to change the video watched completion behaviour. - * New: Added watch time and user statistics to collection and playlist media info pages. (#1982, #2012) (Thanks @herby2212) - * New: Added history table to collection and playlist media info pages. - * New: Dynamically change watched status in the UI based on video watched completion behaviour setting. - * New: Added hidden setting to override server name. - * Change: Move track artist to a details field instead of in the title on track media info pages. -* API: - * New: Added section_id and user_id parameters to get_home_stats API command. (#1944) - * New: Added marker info to get_metadata API command results. - * New: Added media_type parameter to get_item_watch_time_stats and get_item_user_stats API commands. (#1982) (Thanks @herby2212) - * New: Added last_refreshed timestamp to get_library_media_info API command response. -* Other: - * Change: Migrate analytics to Google Analytics 4. - - -## v2.11.1 (2022-12-22) - -* Activity: - * Fix: Use source language instead of stream language on activity cards. -* Notifications: - * Fix: Blank start time notification parameters causing recently added notifications to fail. (#1940) -* Other: - * Fix: Tautulli failing to start when using python 3.7. - * Fix: Snap install failing to start. (#1941) - * Fix: Update check crashing when git is missing. (#1943) (Thanks @Minituff) - - -## v2.11.0 (2022-12-22) - -* Activity: - * New: Added audio and subtitle language to activity cards. (#1831, #1900) (Thanks @fscorrupt) -* History: - * New: Log subtitle language and subtitle forced to database. (#1826) -* Notifications: - * Fix: Validating condition operators would fail with a blank parameter. - * New: Added start time and stop time notification parameters. (#1931) - * New: Added session_key to LunaSea notification payload. (#1929) (Thanks @JagandeepBrar) -* Newsletters: - * Fix: Allow CSS to support light and dark themes. -* Exporter: - * New: Added editionTitle to movie exporter fields. - * Change: m3u8 export changed to .m3u file extension. File is still encoded using UTF-8. -* UI: - * Fix: Link watch statistics to media page using metadata from history. (#1882) - * New: Show subtitle language and subtitle forced flag in stream data modal. -* Other: - * Fix: Mask more user and metadata fields for guest access. (#1913) - * Change: Disable TLS 1.0 and 1.1 for the webserver. Minimum TLS version is 1.2. (#1870) - * Change: Use system language for requests to Plex Media Server. - - -## v2.10.5 (2022-11-07) - -* Notifications: - * New: Added edition_title notification parameter. (#1838) - * Change: Track notifications link to MusicBrainz track instead of album. -* Newsletters: - * New: Added months time frame for newsletters. (#1876) -* UI: - * Fix: Broken link on library statistic cards. (#1852) - * Fix: Check for IPv6 host when generating QR code for app registration. - * Fix: Missing padding on condition operator dropdown on small screens. -* Other: - * Fix: Launching browser when webserver is bound to IPv6. - * New: Tautulli can be installed via the Windows Package Manager (winget). - * Change: Separate stdout and stderr console logging. (#1874) -* API: - * Fix: API not returning 400 response code. - * New: Added edition_title to get_metadata API response. - * New: Added collections to get_children_metadata API response. - * New: Added user_thumb to get_history API response. - * New: Validate custom notification conditions before saving notification agents. (#1846) - * Change: Fallback to parent_thumb for seasons in get_metadata API response. - - -## v2.10.4 (2022-09-05) - -* Activity: - * New: Added tooltip for quality profile on activity cards. -* Notifications: - * New: Added "does not begin with" and "does not end with" condition operators. -* UI: - * Fix: Album count showing 0 on library statistics. - * Fix: Library statistics not showing up for libraries without any history. - - -## v2.10.3 (2022-08-09) - -* Notifications: - * New: Added JSON support for MQTT notifications. (#1763) - * New: Added show year notification parameter. -* Exporter: - * New: Added guids to artist, album, and track metadata export fields. - * New: Added languageTag to stream media info export fields. -* UI: - * Fix: Long channel identifier overflowing activity card. (#1802) - * Change: Use the last played item's artwork for library statistics cards. -* Other: - * Fix: Username log filter causing database to lock up. (#1705) - * Change: Username log filter only applies to usernames longer than 3 characters. (#1806) -* API: - * New: Added parent_year and grandparent_year to get_metadata_details API command. - * New: Added last played metadata to top_libraries and top_users in get_home_stats API command. - * New: Allow fallback to another PMS image in pms_image_proxy API command. - - -## v2.10.2 (2022-07-03) - -* Activity: - * Fix: Incorrect audio stream info shown on the activity card when playing a secondary audio track. -* UI: - * Fix: Usernames not showing on the home statistics cards. - * Fix: Do not save a user's friendly name if it is the same as the username. - * Change: Update library icons to the latest Plex style. - - ## v2.10.1 (2022-06-01) * Notifications: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 46a644e5..a415fb54 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,12 +9,12 @@ All pull requests should be based on the `nightly` branch, to minimize cross mer ### Python Code #### Compatibility -The code should work with Python 3.8+. Note that Tautulli runs on many different platforms. +The code should work with Python 3.6+. Note that Tautulli runs on many different platforms. Re-use existing code. Do not hesitate to add logging in your code. You can the logger module `plexpy.logger.*` for this. Web requests are invoked via `plexpy.request.*` and derived ones. Use these methods to automatically add proper and meaningful error handling. #### Code conventions -Although Tautulli did not adopt a code convention in the past, we try to follow [PEP8](http://legacy.python.org/dev/peps/pep-0008/) conventions for future code. A short summary to remind you (copied from http://wiki.ros.org/PyStyleGuide): +Although Tautulli did not adapt a code convention in the past, we try to follow the [PEP8](http://legacy.python.org/dev/peps/pep-0008/) conventions for future code. A short summary to remind you (copied from http://wiki.ros.org/PyStyleGuide): * 4 space indentation * 80 characters per line diff --git a/Dockerfile b/Dockerfile index 8d8c324b..7a52841f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,4 +25,4 @@ CMD [ "python", "Tautulli.py", "--datadir", "/config" ] ENTRYPOINT [ "./start.sh" ] EXPOSE 8181 -HEALTHCHECK --start-period=90s CMD curl -ILfks https://localhost:8181/status > /dev/null || curl -ILfs http://localhost:8181/status > /dev/null || exit 1 +HEALTHCHECK --start-period=90s CMD curl -ILfSs http://localhost:8181/status > /dev/null || curl -ILfkSs https://localhost:8181/status > /dev/null || exit 1 diff --git a/README.md b/README.md index 37829290..93301401 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ and [PlexWatchWeb](https://github.com/ecleese/plexWatchWeb). [![Docker Stars][badge-docker-stars]][DockerHub] [![Downloads][badge-downloads]][Releases Latest] -[badge-python]: https://img.shields.io/badge/python->=3.9-blue?style=flat-square +[badge-python]: https://img.shields.io/badge/python->=3.6-blue?style=flat-square [badge-docker-pulls]: https://img.shields.io/docker/pulls/tautulli/tautulli?style=flat-square [badge-docker-stars]: https://img.shields.io/docker/stars/tautulli/tautulli?style=flat-square [badge-downloads]: https://img.shields.io/github/downloads/Tautulli/Tautulli/total?style=flat-square @@ -57,24 +57,24 @@ Read the [Installation Guides][Installation] for instructions on how to install [badge-release-nightly-last-commit]: https://img.shields.io/github/last-commit/Tautulli/Tautulli/nightly?style=flat-square&color=blue [badge-release-nightly-commits]: https://img.shields.io/github/commits-since/Tautulli/Tautulli/latest/nightly?style=flat-square&color=blue [badge-docker-master]: https://img.shields.io/badge/docker-latest-blue?style=flat-square -[badge-docker-master-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-docker.yml?style=flat-square&branch=master +[badge-docker-master-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Docker/master?style=flat-square [badge-docker-beta]: https://img.shields.io/badge/docker-beta-blue?style=flat-square -[badge-docker-beta-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-docker.yml?style=flat-square&branch=beta +[badge-docker-beta-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Docker/beta?style=flat-square [badge-docker-nightly]: https://img.shields.io/badge/docker-nightly-blue?style=flat-square -[badge-docker-nightly-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-docker.yml?style=flat-square&branch=nightly +[badge-docker-nightly-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Docker/nightly?style=flat-square [badge-snap-master]: https://img.shields.io/badge/snap-stable-blue?style=flat-square -[badge-snap-master-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-snap.yml?style=flat-square&branch=master +[badge-snap-master-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Snap/master?style=flat-square [badge-snap-beta]: https://img.shields.io/badge/snap-beta-blue?style=flat-square -[badge-snap-beta-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-snap.yml?style=flat-square&branch=beta +[badge-snap-beta-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Snap/beta?style=flat-square [badge-snap-nightly]: https://img.shields.io/badge/snap-edge-blue?style=flat-square -[badge-snap-nightly-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-snap.yml?style=flat-square&branch=nightly +[badge-snap-nightly-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Snap/nightly?style=flat-square [badge-installer-master-win]: https://img.shields.io/github/v/release/Tautulli/Tautulli?label=windows&style=flat-square [badge-installer-master-macos]: https://img.shields.io/github/v/release/Tautulli/Tautulli?label=macos&style=flat-square -[badge-installer-master-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-installers.yml?style=flat-square&branch=master +[badge-installer-master-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Installers/master?style=flat-square [badge-installer-beta-win]: https://img.shields.io/github/v/release/Tautulli/Tautulli?label=windows&include_prereleases&style=flat-square [badge-installer-beta-macos]: https://img.shields.io/github/v/release/Tautulli/Tautulli?label=macos&include_prereleases&style=flat-square -[badge-installer-beta-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-installers.yml?style=flat-square&branch=beta -[badge-installer-nightly-ci]: https://img.shields.io/github/actions/workflow/status/Tautulli/Tautulli/.github/workflows/publish-installers.yml?style=flat-square&branch=nightly +[badge-installer-beta-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Installers/beta?style=flat-square +[badge-installer-nightly-ci]: https://img.shields.io/github/workflow/status/Tautulli/Tautulli/Publish%20Installers/nightly?style=flat-square ## Support @@ -129,7 +129,7 @@ This is free software under the GPL v3 open source license. Feel free to do with but any modification must be open sourced. A copy of the license is included. This software includes Highsoft software libraries which you may freely distribute for -non-commercial use. Commercial users must licence this software, for more information visit +non-commercial use. Commerical users must licence this software, for more information visit https://shop.highsoft.com/faq/non-commercial#non-commercial-redistribution. diff --git a/Tautulli.py b/Tautulli.py index b3cf4736..85e30c04 100755 --- a/Tautulli.py +++ b/Tautulli.py @@ -23,18 +23,18 @@ import sys # Ensure lib added to path, before any other imports sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'lib')) +from future.builtins import str +import appdirs import argparse import datetime import locale -import platformdirs import pytz import signal import shutil import time import threading import tzlocal -import ctypes import plexpy from plexpy import common, config, database, helpers, logger, webstart @@ -70,26 +70,8 @@ def main(): plexpy.SYS_ENCODING = None try: - - # Attempt to get the system's locale settings - language_code, encoding = locale.getlocale() - - # Special handling for Windows platform - if sys.platform == 'win32': - # Get the user's current language settings on Windows - windll = ctypes.windll.kernel32 - lang_id = windll.GetUserDefaultLCID() - - # Map Windows language ID to locale identifier - language_code = locale.windows_locale.get(lang_id, '') - - # Get the preferred encoding - encoding = locale.getpreferredencoding() - - # Assign values to application-specific variable - plexpy.SYS_LANGUAGE = language_code - plexpy.SYS_ENCODING = encoding - + locale.setlocale(locale.LC_ALL, "") + plexpy.SYS_LANGUAGE, plexpy.SYS_ENCODING = locale.getdefaultlocale() except (locale.Error, IOError): pass @@ -129,7 +111,7 @@ def main(): if args.quiet: plexpy.QUIET = True - # Do an initial setup of the logger. + # Do an intial setup of the logger. # Require verbose for pre-initilization to see critical errors logger.initLogger(console=not plexpy.QUIET, log_dir=False, verbose=True) @@ -204,7 +186,7 @@ def main(): if args.datadir: plexpy.DATA_DIR = args.datadir elif plexpy.FROZEN: - plexpy.DATA_DIR = platformdirs.user_data_dir("Tautulli", False) + plexpy.DATA_DIR = appdirs.user_data_dir("Tautulli", False) else: plexpy.DATA_DIR = plexpy.PROG_DIR @@ -264,13 +246,23 @@ def main(): # Start the background threads plexpy.start() - # Force the http port if necessary + # Force the http port if neccessary if args.port: plexpy.HTTP_PORT = args.port logger.info('Using forced web server port: %i', plexpy.HTTP_PORT) else: plexpy.HTTP_PORT = int(plexpy.CONFIG.HTTP_PORT) + # Check if pyOpenSSL is installed. It is required for certificate generation + # and for CherryPy. + if plexpy.CONFIG.ENABLE_HTTPS: + try: + import OpenSSL + except ImportError: + logger.warn("The pyOpenSSL module is missing. Install this " + "module to enable HTTPS. HTTPS will be disabled.") + plexpy.CONFIG.ENABLE_HTTPS = False + # Try to start the server. Will exit here is address is already in use. webstart.start() diff --git a/data/interfaces/default/base.html b/data/interfaces/default/base.html index d6c9f859..5e8d4447 100644 --- a/data/interfaces/default/base.html +++ b/data/interfaces/default/base.html @@ -13,7 +13,6 @@ - @@ -124,6 +123,11 @@ % else:
  • Graphs
  • % endif + % if title == "Synced Items": +
  • Synced Items
  • + % else: +
  • Synced Items
  • + % endif % if title == "Settings": @@ -60,7 +58,7 @@ DOCUMENTATION :: END getPlexPyURL = function () { var deferred = $.Deferred(); - if (location.hostname !== "localhost" && location.hostname !== "127.0.0.1" && location.hostname !== "[::1]") { + if (location.hostname !== "localhost" && location.hostname !== "127.0.0.1") { deferred.resolve(location.href.split('/settings')[0]); } else { $.get('get_plexpy_url').then(function (url) { @@ -72,11 +70,11 @@ DOCUMENTATION :: END function checkQRAddress(url) { var parser = document.createElement('a'); - parser.setAttribute('href', url); + parser.href = url; var hostname = parser.hostname; var protocol = parser.protocol; - if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]') { + if (hostname === '127.0.0.1' || hostname === 'localhost') { $('#api_qr_localhost').toggle(true); $('#api_qr_private').toggle(false); } else { diff --git a/data/interfaces/default/newsletter_config.html b/data/interfaces/default/newsletter_config.html index f6ae70c3..003594a7 100644 --- a/data/interfaces/default/newsletter_config.html +++ b/data/interfaces/default/newsletter_config.html @@ -13,7 +13,7 @@