diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..f535c9c7
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,5 @@
+.git
+.github
+.gitignore
+*.md
+!CHANGELOG*.md
diff --git a/.github/workflows/publishdocker-branch.yml b/.github/workflows/publishdocker-branch.yml
new file mode 100644
index 00000000..b8a6b336
--- /dev/null
+++ b/.github/workflows/publishdocker-branch.yml
@@ -0,0 +1,30 @@
+name: Publish Docker Branch
+on:
+ push:
+ branches: [master, beta, nightly]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@master
+ - name: Get Branch
+ run: echo ::set-env name=BRANCH::${GITHUB_REF#refs/heads/}
+ - name: Publish to Registry
+ uses: elgohr/Publish-Docker-Github-Action@master
+ env:
+ VERSION: ${{ github.sha }}
+ with:
+ name: tautulli/tautulli
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+ dockerfile: Dockerfile
+ buildargs: VERSION, BRANCH
+ - name: Post Status to Discord
+ uses: sarisia/actions-status-discord@v1
+ if: always()
+ with:
+ webhook: ${{ secrets.DISCORD_WEBHOOK }}
+ status: ${{ job.status }}
+ job: ${{ github.workflow }}
+ nofail: true
diff --git a/.github/workflows/publishdocker-release.yml b/.github/workflows/publishdocker-release.yml
new file mode 100644
index 00000000..96f5bb66
--- /dev/null
+++ b/.github/workflows/publishdocker-release.yml
@@ -0,0 +1,32 @@
+name: Publish Docker Release
+on:
+ push:
+ tags:
+ - 'v*'
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@master
+ - name: Get Branch
+ run: echo ::set-env name=BRANCH::${GITHUB_REF/refs\/tags\//}
+ - name: Publish to Registry
+ uses: elgohr/Publish-Docker-Github-Action@master
+ env:
+ VERSION: ${{ github.sha }}
+ with:
+ name: tautulli/tautulli
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+ dockerfile: Dockerfile
+ buildargs: VERSION, BRANCH
+ tags: ${{ env.BRANCH }}
+ - name: Post Status to Discord
+ uses: sarisia/actions-status-discord@v1
+ if: always()
+ with:
+ webhook: ${{ secrets.DISCORD_WEBHOOK }}
+ status: ${{ job.status }}
+ job: ${{ github.workflow }}
+ nofail: true
diff --git a/.github/workflows/publishrelease-beta.yml b/.github/workflows/publishrelease-beta.yml
new file mode 100644
index 00000000..28183600
--- /dev/null
+++ b/.github/workflows/publishrelease-beta.yml
@@ -0,0 +1,29 @@
+name: Create Pre-Release
+on:
+ push:
+ tags:
+ - 'v*-beta'
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@master
+ - name: Get Release Version
+ run: echo ::set-env name=RELEASE_VERSION::${GITHUB_REF/refs\/tags\//}
+ - name: Get Changelog
+ run: echo ::set-env 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
+ id: create_release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ env.RELEASE_VERSION }}
+ release_name: Tautulli ${{ env.RELEASE_VERSION }}
+ body: |
+ ## Changelog
+
+ ##${{ env.CHANGELOG }}
+ draft: false
+ prerelease: true
diff --git a/.github/workflows/publishrelease-master.yml b/.github/workflows/publishrelease-master.yml
new file mode 100644
index 00000000..e7795681
--- /dev/null
+++ b/.github/workflows/publishrelease-master.yml
@@ -0,0 +1,30 @@
+name: Create Release
+on:
+ push:
+ tags:
+ - 'v*'
+ - '!v*-beta'
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@master
+ - name: Get Release Version
+ run: echo ::set-env name=RELEASE_VERSION::${GITHUB_REF/refs\/tags\//}
+ - name: Get Changelog
+ run: echo ::set-env 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
+ id: create_release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ env.RELEASE_VERSION }}
+ release_name: Tautulli ${{ env.RELEASE_VERSION }}
+ body: |
+ ## Changelog
+
+ ##${{ env.CHANGELOG }}
+ draft: false
+ prerelease: false
diff --git a/API.md b/API.md
index 20825dd7..09e471e0 100644
--- a/API.md
+++ b/API.md
@@ -395,7 +395,11 @@ Returns:
"banner": "/library/metadata/1219/banner/1503306930",
"bif_thumb": "/library/parts/274169/indexes/sd/1000",
"bitrate": "10617",
+ "channel_call_sign": "",
+ "channel_identifier": "",
"channel_stream": 0,
+ "channel_thumb": "",
+ "children_count": "",
"collections": [],
"container": "mkv",
"content_rating": "TV-MA",
@@ -427,13 +431,15 @@ Returns:
"ip_address": "10.10.10.1",
"ip_address_public": "64.123.23.111",
"is_admin": 1,
- "is_allow_sync": null,
+ "is_allow_sync": 1,
"is_home_user": 1,
"is_restricted": 0,
"keep_history": 1,
"labels": [],
"last_viewed_at": "1462165717",
"library_name": "TV Shows",
+ "live": 0,
+ "live_uuid": "",
"local": "1",
"location": "lan",
"machine_id": "lmd93nkn12k29j2lnm",
@@ -442,8 +448,8 @@ Returns:
"optimized_version": 0,
"optimized_version_profile": "",
"optimized_version_title": "",
- "originally_available_at": "2016-04-24",
"original_title": "",
+ "originally_available_at": "2016-04-24",
"parent_guid": "com.plexapp.agents.thetvdb://121361/6?lang=en",
"parent_media_index": "6",
"parent_rating_key": "153036",
@@ -463,6 +469,7 @@ Returns:
"rating_key": "153037",
"relay": 0,
"section_id": "2",
+ "secure": 1,
"session_id": "helf15l3rxgw01xxe0jf3l3d",
"session_key": "27",
"shared_libraries": [
@@ -501,15 +508,21 @@ Returns:
"stream_subtitle_location": "",
"stream_video_bit_depth": "8",
"stream_video_bitrate": "10233",
+ "stream_video_chroma_subsampling": "4:2:0",
"stream_video_codec": "h264",
"stream_video_codec_level": "41",
+ "stream_video_color_primaries": "",
+ "stream_video_color_range": "tv",
+ "stream_video_color_space": "bt709",
+ "stream_video_color_trc": "",
"stream_video_decision": "direct play",
+ "stream_video_dynamic_range": "SDR",
"stream_video_framerate": "24p",
+ "stream_video_full_resolution": "1080p",
"stream_video_height": "1078",
"stream_video_language": "",
"stream_video_language_code": "",
"stream_video_ref_frames": "4",
- "stream_video_full_resolution": "1080p",
"stream_video_resolution": "1080",
"stream_video_scan_type": "progressive",
"stream_video_width": "1920",
@@ -559,9 +572,15 @@ Returns:
"username": "LordCommanderSnow",
"video_bit_depth": "8",
"video_bitrate": "10233",
+ "video_chroma_subsampling": "4:2:0",
"video_codec": "h264",
"video_codec_level": "41",
+ "video_color_primaries": "",
+ "video_color_range": "tv",
+ "video_color_space": "bt709",
+ "video_color_trc": ",
"video_decision": "direct play",
+ "video_dynamic_range": "SDR",
"video_frame_rate": "23.976",
"video_framerate": "24p",
"video_full_resolution": "1080p",
@@ -671,8 +690,9 @@ Optional parameters:
grandparent_rating_key (int): 351
start_date (str): "YYYY-MM-DD"
section_id (int): 2
- media_type (str): "movie", "episode", "track"
+ media_type (str): "movie", "episode", "track", "live"
transcode_decision (str): "direct play", "copy", "transcode",
+ guid (str): Plex guid for an item, e.g. "com.plexapp.agents.thetvdb://121361/6/1"
order_column (str): "date", "friendly_name", "ip_address", "platform", "player",
"full_title", "started", "paused_counter", "stopped", "duration"
order_dir (str): "desc" or "asc"
@@ -697,10 +717,13 @@ Returns:
"original_title": "",
"group_count": 1,
"group_ids": "1124",
+ "guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
"id": 1124,
"ip_address": "xxx.xxx.xxx.xxx",
+ "live": 0,
"media_index": 17,
"media_type": "episode",
+ "originally_available_at": "2016-04-24",
"parent_media_index": 7,
"parent_rating_key": 544,
"parent_title": "",
@@ -758,8 +781,10 @@ Returns:
[{"content_rating": "TV-MA",
"friendly_name": "",
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
+ "guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
"labels": [],
"last_play": 1462380698,
+ "live": 0,
"media_type": "episode",
"platform": "",
"platform_type": "",
@@ -860,15 +885,18 @@ Returns:
"do_notify": "Checked",
"do_notify_created": "Checked",
"duration": 1578037,
+ "guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
"id": 1128,
"keep_history": "Checked",
"labels": [],
"last_accessed": 1462693216,
"last_played": "Game of Thrones - The Red Woman",
"library_art": "/:/resources/show-fanart.jpg",
- "library_thumb": "",
+ "library_thumb": "/:/resources/show.png",
+ "live": 0,
"media_index": 1,
"media_type": "episode",
+ "originally_available_at": "2016-04-24",
"parent_count": 240,
"parent_media_index": 6,
"parent_title": "",
@@ -958,6 +986,7 @@ Returns:
"rating_key": "1219",
"section_id": 2,
"section_type": "show",
+ "sort_title": "Game of Thrones",
"thumb": "/library/metadata/1219/thumb/1436265995",
"title": "Game of Thrones",
"video_codec": "",
@@ -1124,6 +1153,7 @@ Returns:
"labels": [],
"last_viewed_at": "1462165717",
"library_name": "TV Shows",
+ "live": 0,
"media_index": "1",
"media_info": [
{
@@ -1133,6 +1163,9 @@ Returns:
"audio_codec": "ac3",
"audio_profile": "",
"bitrate": "10617",
+ "channel_call_sign": "",
+ "channel_identifier": "",
+ "channel_thumb": "",
"container": "mkv",
"height": "1078",
"id": "257925",
@@ -1151,6 +1184,10 @@ Returns:
"video_bitrate": "10233",
"video_codec": "h264",
"video_codec_level": "41",
+ "video_color_primaries": "",
+ "video_color_range": "tv",
+ "video_color_space": "bt709",
+ "video_color_trc": "",
"video_frame_rate": "23.976",
"video_height": "1078",
"video_language": "",
@@ -1210,7 +1247,7 @@ Returns:
"rating_image": "rottentomatoes://image.rating.ripe",
"rating_key": "153037",
"section_id": "2",
- "sort_title": "Game of Thrones",
+ "sort_title": "Red Woman",
"studio": "HBO",
"summary": "Jon Snow is dead. Daenerys meets a strong man. Cersei sees her daughter again.",
"tagline": "",
@@ -1506,7 +1543,8 @@ Returns:
"series":
[{"name": "Movies", "data": [...]}
{"name": "TV", "data": [...]},
- {"name": "Music", "data": [...]}
+ {"name": "Music", "data": [...]},
+ {"name": "Live TV", "data": [...]}
]
}
```
@@ -1532,7 +1570,8 @@ Returns:
"series":
[{"name": "Movies", "data": [...]}
{"name": "TV", "data": [...]},
- {"name": "Music", "data": [...]}
+ {"name": "Music", "data": [...]},
+ {"name": "Live TV", "data": [...]}
]
}
```
@@ -1558,7 +1597,8 @@ Returns:
"series":
[{"name": "Movies", "data": [...]}
{"name": "TV", "data": [...]},
- {"name": "Music", "data": [...]}
+ {"name": "Music", "data": [...]},
+ {"name": "Live TV", "data": [...]}
]
}
```
@@ -1662,7 +1702,8 @@ Returns:
"series":
[{"name": "Movies", "data": [...]}
{"name": "TV", "data": [...]},
- {"name": "Music", "data": [...]}
+ {"name": "Music", "data": [...]},
+ {"name": "Live TV", "data": [...]}
]
}
```
@@ -1688,7 +1729,8 @@ Returns:
"series":
[{"name": "Movies", "data": [...]}
{"name": "TV", "data": [...]},
- {"name": "Music", "data": [...]}
+ {"name": "Music", "data": [...]},
+ {"name": "Live TV", "data": [...]}
]
}
```
@@ -1714,7 +1756,8 @@ Returns:
"series":
[{"name": "Movies", "data": [...]}
{"name": "TV", "data": [...]},
- {"name": "Music", "data": [...]}
+ {"name": "Music", "data": [...]},
+ {"name": "Live TV", "data": [...]}
]
}
```
@@ -1802,22 +1845,59 @@ Optional parameters:
Returns:
json:
{"recently_added":
- [{"added_at": "1461572396",
+ [{"actors": [
+ "Kit Harington",
+ "Emilia Clarke",
+ "Isaac Hempstead-Wright",
+ "Maisie Williams",
+ "Liam Cunningham",
+ ],
+ "added_at": "1461572396",
+ "art": "/library/metadata/1219/art/1462175063",
+ "audience_rating": "8",
+ "audience_rating_image": "rottentomatoes://image.rating.upright",
+ "banner": "/library/metadata/1219/banner/1462175063",
+ "directors": [
+ "Jeremy Podeswa"
+ ],
+ "duration": "2998290",
+ "full_title": "Game of Thrones - The Red Woman",
+ "genres": [
+ "Adventure",
+ "Drama",
+ "Fantasy"
+ ],
"grandparent_rating_key": "1219",
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
"grandparent_title": "Game of Thrones",
- "library_name": "",
+ "guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
+ "labels": [],
+ "last_viewed_at": "1462165717",
+ "library_name": "TV Shows",
"media_index": "1",
"media_type": "episode",
"original_title": "",
+ "originally_available_at": "2016-04-24",
"parent_media_index": "6",
"parent_rating_key": "153036",
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
"parent_title": "",
+ "rating": "7.8",
+ "rating_image": "rottentomatoes://image.rating.ripe",
"rating_key": "153037",
"section_id": "2",
+ "sort_title": "Red Woman",
+ "studio": "HBO",
+ "summary": "Jon Snow is dead. Daenerys meets a strong man. Cersei sees her daughter again.",
+ "tagline": "",
"thumb": "/library/metadata/153037/thumb/1462175060",
"title": "The Red Woman",
+ "user_rating": "9.0",
+ "updated_at": "1462175060",
+ "writers": [
+ "David Benioff",
+ "D. B. Weiss"
+ ],
"year": "2016"
},
{...},
@@ -1999,6 +2079,7 @@ Returns:
"stream_video_bitrate": 527,
"stream_video_codec": "h264",
"stream_video_decision": "transcode",
+ "stream_video_dynamic_range": "SDR",
"stream_video_framerate": "24p",
"stream_video_height": 306,
"stream_video_resolution": "SD",
@@ -2013,6 +2094,7 @@ Returns:
"video_bitrate": 2500,
"video_codec": "h264",
"video_decision": "transcode",
+ "video_dynamic_range": "SDR",
"video_framerate": "24p",
"video_height": 816,
"video_resolution": "1080",
@@ -2166,12 +2248,15 @@ Returns:
"recordsFiltered": 10,
"data":
[{"friendly_name": "Jon Snow",
+ "guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
"id": 1121,
"ip_address": "xxx.xxx.xxx.xxx",
"last_played": "Game of Thrones - The Red Woman",
"last_seen": 1462591869,
+ "live": 0,
"media_index": 1,
"media_type": "episode",
+ "originally_available_at": "2016-04-24",
"parent_media_index": 6,
"parent_title": "",
"platform": "Chrome",
@@ -2371,13 +2456,16 @@ Returns:
"do_notify": "Checked",
"duration": 2998290,
"friendly_name": "Jon Snow",
+ "guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
"id": 1121,
"ip_address": "xxx.xxx.xxx.xxx",
"keep_history": "Checked",
"last_played": "Game of Thrones - The Red Woman",
"last_seen": 1462591869,
+ "live": 0,
"media_index": 1,
"media_type": "episode",
+ "originally_available_at": "2016-04-24",
"parent_media_index": 6,
"parent_title": "",
"platform": "Chrome",
@@ -2516,10 +2604,10 @@ Optional parameters:
width (str): 300
height (str): 450
opacity (str): 25
- background (str): 282828
+ background (str): Hex color, e.g. 282828
blur (str): 3
img_format (str): png
- fallback (str): "poster", "cover", "art"
+ fallback (str): "poster", "cover", "art", "poster-live", "art-live", "art-live-full"
refresh (bool): True or False whether to refresh the image cache
return_hash (bool): True or False to return the self-hosted image hash instead of the image
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 41f2eeed..831d94e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,61 @@
# Changelog
+## v2.2.0-beta (2020-02-27)
+
+* Important Note!
+ * All Live TV changes requires Plex Media Server 1.18.7 or higher.
+* Monitoring:
+ * New: Added Live TV metadata and posters to the activity cards.
+ * Change: Show bandwidth in Gbps when greater than 1000 Mbps.
+* History:
+ * New: Added history logging for Live TV sessions.
+ * New: Added a fake "Live TV" library to collect Live TV history.
+ * Note: This library will show up the first time that Live TV is played.
+ * New: Added the ability to filter history by Live TV.
+* Graphs:
+ * New: Added Live TV series to the "Plays by Period" and "Play Totals" graphs.
+ * Change: Media type series on the graphs are only shown if the corresponding library type is present.
+* Notifications:
+ * Fix: Race condition causing stream count to be incorrect for playback stop notifications.
+ * New: Added Live TV channel notification parameters.
+* API:
+ * New: Added ability to filter history using a "live" media type and by guid for the get_history API command.
+* Other:
+ * Change: Add crossorigin use-credentials attribute to manifest tags. (Thanks @pkoenig10)
+ * Change: Disable automatic updates for Docker containers. Updates are now handled by updating the Docker container.
+ * Note: If you are using an old Docker container created before v2.2.0, then you may need to completely remove and recreate the container to update for the first time.
+ * Note: Use the ":latest" Docker tag for the newest stable release, or the ":beta" or ":nightly" tags to access the beta or nightly branches.
+
+
+## v2.1.44 (2020-02-05)
+
+* Monitoring:
+ * Fix: SDR source video being identified as HDR stream video.
+* Notifications:
+ * Fix: Unable to select condition operator for video color parameters.
+* UI:
+ * Fix: Capitalization for platforms on history tables.
+
+
+## v2.1.43 (2020-02-03)
+
+* Monitoring:
+ * New: Added HDR indicator on activity card.
+ * New: Added dynamic range to history steam info modal.
+* Notifications:
+ * Fix: Webhook notification body sent as incorrect data type when Content-Type header is overridden.
+ * Fix: Telegram notification character limit incorrect for unicode characters.
+ * New: Added color and dynamic range notification parameters.
+* Newsletters:
+ * Fix: Episodes and Albums plural spelling on recently added newsletter section headers.
+* UI:
+ * Fix: Windows and macOS platform capitalization.
+ * Fix: Season number 0 not shown for episodes on history tables.
+* Other:
+ * Change: Mask email addresses in logs.
+ * Change: Update deprecated GitHub access token URL parameter to Authorization header.
+
+
## v2.1.42 (2020-01-04)
* Other:
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..5efa135a
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,31 @@
+FROM python:2.7.17-slim
+
+LABEL maintainer="TheMeanCanEHdian"
+
+ARG VERSION
+ARG BRANCH
+
+ENV TAUTULLI_DOCKER=True
+ENV TZ=UTC
+
+WORKDIR /app
+
+RUN \
+apt-get -q -y update --no-install-recommends && \
+apt-get install -q -y --no-install-recommends \
+ curl && \
+rm -rf /var/lib/apt/lists/* && \
+pip install --no-cache-dir --upgrade pip && \
+pip install --no-cache-dir --upgrade \
+ pycryptodomex \
+ pyopenssl && \
+echo ${VERSION} > /app/version.txt && \
+echo ${BRANCH} > /app/branch.txt
+
+COPY . /app
+
+CMD [ "python", "Tautulli.py", "--datadir", "/config" ]
+
+VOLUME /config /plex_logs
+EXPOSE 8181
+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 fd2f1dca..c74386ec 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,5 @@
# Tautulli
-[](https://tautulli.com/discord)
-[](https://www.reddit.com/r/Tautulli/)
-[](https://forums.plex.tv/t/tautulli-monitor-your-plex-media-server/225242)
-
A python based web application for monitoring, analytics and notifications for [Plex Media Server](https://plex.tv).
This project is based on code from [Headphones](https://github.com/rembo10/headphones) and [PlexWatchWeb](https://github.com/ecleese/plexWatchWeb).
@@ -31,7 +27,21 @@ This project is based on code from [Headphones](https://github.com/rembo10/headp

-## Installation and Support
+## Installation & Support
+
+[](https://python.org/downloads/release/python-2717/)
+[](https://hub.docker.com/r/tautulli/tautulli)
+[](https://hub.docker.com/r/tautulli/tautulli)
+
+| Status | Branch: `master` | Branch: `beta` | Branch: `nightly` |
+| --- | --- | --- | --- |
+| Release | [](https://github.com/Tautulli/Tautulli/releases/latest)
[](https://github.com/Tautulli/Tautulli/releases/latest) | [](https://github.com/Tautulli/Tautulli/releases)
[](https://github.com/Tautulli/Tautulli/commits/beta) | [](https://github.com/Tautulli/Tautulli/commits/nightly)
[](https://github.com/Tautulli/Tautulli/commits/nightly) |
+| Docker | [](https://hub.docker.com/r/tautulli/tautulli)
[](https://github.com/Tautulli/Tautulli/actions?query=branch%3Amaster) | [](https://hub.docker.com/r/tautulli/tautulli)
[](https://github.com/Tautulli/Tautulli/actions?query=branch%3Abeta) | [](https://hub.docker.com/r/tautulli/tautulli)
[](https://github.com/Tautulli/Tautulli/actions?query=branch%3Anightly) |
+
+[](https://github.com/Tautulli/Tautulli-Wiki/wiki)
+[](https://tautulli.com/discord)
+[](https://www.reddit.com/r/Tautulli/)
+[](https://forums.plex.tv/t/tautulli-monitor-your-plex-media-server/225242)
* Read the [Installation Guides](https://github.com/Tautulli/Tautulli-Wiki/wiki/Installation) for instructions to install Tautulli.
* The [Frequently Asked Questions](https://github.com/Tautulli/Tautulli-Wiki/wiki/Frequently-Asked-Questions) in the wiki can help you with common problems.
@@ -39,10 +49,15 @@ This project is based on code from [Headphones](https://github.com/rembo10/headp
## Issues & Feature Requests
+[](https://github.com/Tautulli/Tautulli-Issues)
+[](https://feathub.com/Tautulli/Tautulli)
+
* Please see the [Issues Repository](https://github.com/Tautulli/Tautulli-Issues).
## License
+[](https://github.com/Tautulli/Tautulli/blob/master/LICENSE)
+
This is free software under the GPL v3 open source license. Feel free to do with it what you wish, 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. Commerical users must licence this software, for more information visit https://shop.highsoft.com/faq/non-commercial#non-commercial-redistribution.
\ No newline at end of file
diff --git a/Tautulli.py b/Tautulli.py
index 2517b8dc..d6e290a9 100755
--- a/Tautulli.py
+++ b/Tautulli.py
@@ -34,7 +34,7 @@ import time
import tzlocal
import plexpy
-from plexpy import config, database, logger, webstart
+from plexpy import config, database, helpers, logger, webstart
# Register signals, such as CTRL + C
@@ -115,7 +115,7 @@ def main():
plexpy.SYS_UTC_OFFSET = datetime.datetime.now(plexpy.SYS_TIMEZONE).strftime('%z')
- if os.getenv('TAUTULLI_DOCKER', False) == 'True':
+ if helpers.bool_true(os.getenv('TAUTULLI_DOCKER', False)):
plexpy.DOCKER = True
if args.dev:
diff --git a/data/interfaces/default/base.html b/data/interfaces/default/base.html
index 38b7cc10..c32dcd08 100644
--- a/data/interfaces/default/base.html
+++ b/data/interfaces/default/base.html
@@ -28,7 +28,7 @@
-
+
@@ -43,23 +43,23 @@