Compare commits

...

28 Commits

Author SHA1 Message Date
JonnyWong16
1698622d63 v2.5.3 2020-07-10 17:07:18 -07:00
JonnyWong16
fa27271647 Change shebang on contrib scripts 2020-07-10 17:02:23 -07:00
JonnyWong16
d837811c68 Improve start script 2020-07-09 17:13:16 -07:00
JonnyWong16
ad195f0969 Fix deleteing more than 1000 history entries at the same time 2020-07-08 12:27:20 -07:00
JonnyWong16
4a8748e322 Live TV library not being recreated after server identifier is changed
* Fixes Tautulli/Tautulli-Issues#261
2020-07-07 18:14:00 -07:00
JonnyWong16
0f016c83ea Fix ipwhois data location for macOS package
* Fixes Tautulli/Tautulli-Issues#260
2020-07-07 17:25:46 -07:00
JonnyWong16
061ae44da4 Fix indentation in macOS postinstall script 2020-07-07 17:05:15 -07:00
JonnyWong16
a8b90bf100 Reduce macOS build requirement to pyobjc-framework-Cocoa 2020-07-07 17:05:10 -07:00
JonnyWong16
eb3cd49bc4 Add hidden import pkg_resources.py2_warn to macos.spec
* Fixes build on macOS 10.13 (High Sierra)
2020-07-06 20:57:37 -07:00
JonnyWong16
416d869288 Add python version to Google Analytics 2020-07-06 18:13:33 -07:00
JonnyWong16
a116c26c25 Run python scripts with the same sys.executable as Tautulli 2020-07-06 11:32:16 -07:00
JonnyWong16
cc4ec53dac Full path to python3 interpreter in FreeBSD startup script 2020-07-06 10:08:36 -07:00
JonnyWong16
63164c7ff5 Quote command in systemd script 2020-07-06 09:37:37 -07:00
JonnyWong16
9815c014e8 Add python interpreter to init-scripts 2020-07-06 09:30:35 -07:00
JonnyWong16
41843dc573 Rename some column headers 2020-07-04 12:22:40 -07:00
JonnyWong16
cc6bd528a5 Add architecture to release assets 2020-07-04 11:28:22 -07:00
JonnyWong16
2625ef5fb9 Use Popen to restart on macOS 2020-07-03 19:48:27 -07:00
JonnyWong16
dbd2d28877 Set macOS menu bar icon thread to daemon 2020-07-03 19:47:57 -07:00
JonnyWong16
f70f814c70 Shutdown tray icons last 2020-07-03 19:47:11 -07:00
JonnyWong16
6710e42134 Hide macOS dock icon for pkg install 2020-07-03 19:46:27 -07:00
JonnyWong16
78c5b45e43 Also fix e562ec9 for Python 2 2020-07-03 11:24:47 -07:00
JonnyWong16
e562ec96fa Fix encoding when reading a newsletter file 2020-07-02 20:46:42 -07:00
JonnyWong16
9b5e01c319 Fix logger for email notification exception 2020-07-02 12:45:45 -07:00
JonnyWong16
0097532f4a Fix startup script 2020-07-02 12:33:32 -07:00
JonnyWong16
91935c9018 Add hidden import cheroot.ssl.builtin for pyinstaller 2020-07-02 09:20:58 -07:00
JonnyWong16
83df807f7e Fix typo in eb3db20 2020-07-02 09:15:13 -07:00
JonnyWong16
eb3db20340 Add hidden import chroot.ssl for pyinstaller 2020-07-02 09:11:15 -07:00
JonnyWong16
6dab6194ea Replace which with command -v in startup script 2020-07-01 22:44:05 -07:00
24 changed files with 108 additions and 74 deletions

View File

@@ -53,7 +53,7 @@ jobs:
uses: joncloud/makensis-action@v1.2
with:
script-file: ./package/Tautulli.nsi
arguments: /DVERSION=${{ steps.get_version.outputs.VERSION_NSIS }} /DINSTALLER_NAME=..\Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}.exe
arguments: /DVERSION=${{ steps.get_version.outputs.VERSION_NSIS }} /DINSTALLER_NAME=..\Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.exe
include-more-plugins: true
include-custom-plugins-path: package/nsis-plugins
@@ -61,7 +61,7 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: Tautulli-windows-installer
path: Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}.exe
path: Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.exe
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1
@@ -117,13 +117,13 @@ jobs:
- name: Create Installer
run: |
sudo pkgbuild --install-location /Applications --version ${{ steps.get_version.outputs.VERSION }} --component ./dist/Tautulli.app --scripts ./package/macos-scripts Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}.pkg
sudo pkgbuild --install-location /Applications --version ${{ steps.get_version.outputs.VERSION }} --component ./dist/Tautulli.app --scripts ./package/macos-scripts Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.pkg
- name: Upload Installer
uses: actions/upload-artifact@v2
with:
name: Tautulli-macos-installer
path: Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}.pkg
path: Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}-x64.pkg
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1
@@ -188,8 +188,8 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}.exe
asset_name: Tautulli-windows-${{ steps.get_version.outputs.RELEASE_VERSION }}.exe
asset_path: ./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
@@ -199,6 +199,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}.pkg
asset_name: Tautulli-macos-${{ steps.get_version.outputs.RELEASE_VERSION }}.pkg
asset_path: ./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

View File

@@ -1,5 +1,21 @@
# Changelog
## v2.5.3 (2020-07-10)
* History:
* Fix: Unable to delete more than 1000 history entries at the same time.
* Notifications:
* Change: Python script notifications to run using the same Python interpreter as Tautulli.
* Newsletters:
* Fix: Unable to view newsletters with special characters.
* Other:
* Fix: Tautulli failing to start after enabling HTTPS when installed using the Windows / macOS installers.
* Fix: Startup script not working on macOS.
* Fix: Unable to hide dock icon on macOS with the pkg install. Refer to the FAQ regarding the Python rocket dock icon.
* Change: Added path to Python interpreter in system startup (daemon) scripts.
* Change: Added Python version to Google analytics.
## v2.5.2 (2020-07-01)
* Announcements:

View File

@@ -265,7 +265,10 @@ def main():
if plexpy.CONFIG.SYS_TRAY_ICON:
# MacOS menu bar icon must be run on the main thread and is blocking
# Start the rest of Tautulli on a new thread
threading.Thread(target=wait).start()
thread = threading.Thread(target=wait)
thread.daemon = True
thread.start()
plexpy.MAC_SYS_TRAY_ICON = macos.MacOSSystemTray()
plexpy.MAC_SYS_TRAY_ICON.start()
else:

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Display information
echo "This script will remove *.pyc files. These files are generated by Python, but they can cause conflicts after an upgrade. It's safe to remove them, because they will be regenerated."

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Parameter check
if [ -z "$1" ]; then

View File

@@ -38,7 +38,7 @@
<th align="left" id="count">Total Movies / TV Shows / Artists</th>
<th align="left" id="parent_count">Total Seasons / Albums</th>
<th align="left" id="child_count">Total Episodes / Tracks</th>
<th align="left" id="last_accessed">Last Accessed</th>
<th align="left" id="last_accessed">Last Streamed</th>
<th align="left" id="last_played">Last Played</th>
<th align="left" id="total_plays">Total Plays</th>
<th align="left" id="total_duration">Total Played Duration</th>

View File

@@ -284,7 +284,7 @@ DOCUMENTATION :: END
<table class="display user_ip_table" id="user_ip_table-UID-${data['user_id']}" width="100%">
<thead>
<tr>
<th align="left" id="last_seen">Last Seen</th>
<th align="left" id="last_seen">Last Streamed</th>
<th align="left" id="ip_address">IP Address</th>
<th align="left" id="platform">Last Platform</th>
<th align="left" id="player">Last Player</th>

View File

@@ -34,7 +34,7 @@
<th align="left" id="edit_row">Edit</th>
<th align="right" id="avatar"></th>
<th align="left" id="friendly_name">User</th>
<th align="left" id="last_seen">Last Seen</th>
<th align="left" id="last_seen">Last Streamed</th>
<th align="left" id="last_known_ip">Last Known IP</th>
<th align="left" id="last_platform">Last Platform</th>
<th align="left" id="last_player">Last Player</th>

View File

@@ -38,6 +38,7 @@ load_rc_config ${name}
status_cmd="${name}_status"
stop_cmd="${name}_stop"
command_interpreter="/usr/local/bin/python3"
command="${tautulli_dir}/Tautulli.py"
command_args="--daemon --pidfile ${tautulli_pid} --quiet --nolaunch ${tautulli_flags}"

View File

@@ -31,11 +31,13 @@
# sudo chown tautulli:tautulli -R /opt/Tautulli
#
# - Adjust ExecStart= to point to:
# 1. Your Tautulli executable
# 1. Your Python interpreter (get the path with "command -v python3")
# - Default: /usr/bin/python3
# 2. Your Tautulli executable
# - Default: /opt/Tautulli/Tautulli.py
# 2. Your config file (recommended is to put it somewhere in /etc)
# 3. Your config file (recommended is to put it somewhere in /etc)
# - Default: --config /opt/Tautulli/config.ini
# 3. Your datadir (recommended is to NOT put it in your Tautulli exec dir)
# 4. Your datadir (recommended is to NOT put it in your Tautulli exec dir)
# - Default: --datadir /opt/Tautulli
#
# - Adjust User= and Group= to the user/group you want Tautulli to run as.
@@ -50,7 +52,7 @@ Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/opt/Tautulli/Tautulli.py --config /opt/Tautulli/config.ini --datadir /opt/Tautulli --quiet --daemon --nolaunch
ExecStart=/usr/bin/python3 /opt/Tautulli/Tautulli.py --config /opt/Tautulli/config.ini --datadir /opt/Tautulli --quiet --daemon --nolaunch
GuessMainPID=no
Type=forking
User=tautulli

View File

@@ -16,10 +16,10 @@ analysis = Analysis(
('../CHANGELOG.md', '.'),
('../LICENSE', '.'),
('../version.txt', '.'),
('../lib/ipwhois/data', 'data')
('../lib/ipwhois/data', 'ipwhois/data')
],
excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter'],
hiddenimports=['Foundation', 'AppKit'],
hiddenimports=['pkg_resources.py2_warn', 'Foundation', 'AppKit', 'cheroot.ssl', 'cheroot.ssl.builtin'],
cipher=block_cipher
)
pyz = PYZ(
@@ -47,5 +47,9 @@ app = BUNDLE(
name='Tautulli.app',
icon='../data/interfaces/default/images/logo-circle.icns',
bundle_identifier='com.Tautulli.Tautulli',
version=VERSION
version=VERSION,
info_plist={
'LSBackgroundOnly': True,
'LSUIElement': True
}
)

View File

@@ -16,6 +16,7 @@ analysis = Analysis(
('..\\lib\\ipwhois\\data', 'data')
],
excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter'],
hiddenimports=['cheroot.ssl', 'cheroot.ssl.builtin'],
cipher=block_cipher,
)
pyz = PYZ(

View File

@@ -3,7 +3,7 @@
dialogText=`osascript -e 'set dialogText to button returned of (display dialog "Installation complete. Start Tautulli?" buttons {"Start", "Close"})'`;
if [[ $dialogText == 'Start' ]]
then
open /Applications/Tautulli.app
open /Applications/Tautulli.app
else
exit 0;
fi

View File

@@ -1,4 +1,4 @@
pyinstaller
pyopenssl
pycryptodomex
pyobjc
pyobjc-framework-Cocoa

View File

@@ -37,8 +37,7 @@ from apscheduler.triggers.interval import IntervalTrigger
from UniversalAnalytics import Tracker
import pytz
PYTHON_VERSION = sys.version_info[:3]
PYTHON2 = PYTHON_VERSION[0] == 2
PYTHON2 = sys.version_info[0] == 2
if PYTHON2:
import activity_handler
@@ -2211,11 +2210,6 @@ def shutdown(restart=False, update=False, checkout=False, reset=False):
logger.info("Removing pidfile %s", PIDFILE)
os.remove(PIDFILE)
if WIN_SYS_TRAY_ICON:
WIN_SYS_TRAY_ICON.shutdown()
elif MAC_SYS_TRAY_ICON:
MAC_SYS_TRAY_ICON.shutdown()
if restart:
logger.info("Tautulli is restarting...")
@@ -2238,7 +2232,7 @@ def shutdown(restart=False, update=False, checkout=False, reset=False):
# https://bugs.python.org/issue19066
if NOFORK:
pass
elif common.PLATFORM == 'Windows':
elif common.PLATFORM in ('Windows', 'Darwin'):
subprocess.Popen(args, cwd=os.getcwd())
else:
os.execv(exe, args)
@@ -2248,6 +2242,11 @@ def shutdown(restart=False, update=False, checkout=False, reset=False):
logger.shutdown()
if WIN_SYS_TRAY_ICON:
WIN_SYS_TRAY_ICON.shutdown()
elif MAC_SYS_TRAY_ICON:
MAC_SYS_TRAY_ICON.shutdown()
os._exit(0)
@@ -2264,6 +2263,7 @@ def initialize_tracker():
'appInstallerId': CONFIG.GIT_BRANCH,
'dimension1': '{} {}'.format(common.PLATFORM, common.PLATFORM_RELEASE), # App Platform
'dimension2': common.PLATFORM_LINUX_DISTRO, # Linux Distro
'dimension3': common.PYTHON_VERSION,
'userLanguage': SYS_LANGUAGE,
'documentEncoding': SYS_ENCODING,
'noninteractive': True

View File

@@ -35,6 +35,7 @@ PLATFORM_RELEASE = platform.release()
PLATFORM_VERSION = platform.version()
PLATFORM_LINUX_DISTRO = ' '.join(x for x in distro.linux_distribution() if x)
PLATFORM_DEVICE_NAME = platform.node()
PYTHON_VERSION = platform.python_version()
BRANCH = version.PLEXPY_BRANCH
RELEASE = version.PLEXPY_RELEASE_VERSION

View File

@@ -75,7 +75,6 @@ _CONFIG_DEFINITIONS = {
'PMS_UPDATE_CHECK_INTERVAL': (int, 'Advanced', 24),
'PMS_WEB_URL': (str, 'PMS', 'https://app.plex.tv/desktop'),
'TIME_FORMAT': (str, 'General', 'HH:mm'),
'ADD_LIVE_TV_LIBRARY': (int, 'Advanced', 1),
'ANON_REDIRECT': (str, 'General', 'http://www.nullrefer.com/?'),
'API_ENABLED': (int, 'General', 1),
'API_KEY': (str, 'General', ''),

View File

@@ -27,10 +27,10 @@ import time
import plexpy
if plexpy.PYTHON2:
import logger
from helpers import cast_to_int, bool_true
from helpers import cast_to_int, bool_true, chunk
else:
from plexpy import logger
from plexpy.helpers import cast_to_int, bool_true
from plexpy.helpers import cast_to_int, bool_true, chunk
FILENAME = "tautulli.db"
@@ -218,12 +218,16 @@ def delete_rows_from_table(table, row_ids):
if row_ids:
logger.info("Tautulli Database :: Deleting row ids %s from %s database table", row_ids, table)
query = "DELETE FROM " + table + " WHERE id IN (%s) " % ','.join(['?'] * len(row_ids))
monitor_db = MonitorDatabase()
# SQlite verions prior to 3.32.0 (2020-05-22) have maximum variable limit of 999
# https://sqlite.org/limits.html
sqlite_max_variable_number = 999
monitor_db = MonitorDatabase()
try:
monitor_db.action(query, row_ids)
return True
for row_ids_group in chunk(row_ids, sqlite_max_variable_number):
query = "DELETE FROM " + table + " WHERE id IN (%s) " % ','.join(['?'] * len(row_ids_group))
monitor_db.action(query, row_ids_group)
except Exception as e:
logger.error("Tautulli Database :: Failed to delete rows from %s database table: %s" % (table, e))
return False

View File

@@ -31,7 +31,7 @@ import datetime
from functools import wraps
import hashlib
import imghdr
from future.moves.itertools import zip_longest
from future.moves.itertools import islice, zip_longest
import ipwhois
import ipwhois.exceptions
import ipwhois.utils
@@ -1068,6 +1068,11 @@ def grouper(iterable, n, fillvalue=None):
return zip_longest(fillvalue=fillvalue, *args)
def chunk(it, size):
it = iter(it)
return iter(lambda: tuple(islice(it, size)), ())
def traverse_map(obj, func):
if isinstance(obj, list):
new_obj = []

View File

@@ -88,6 +88,8 @@ def refresh_libraries():
if result == 'insert':
new_keys.append(section['section_id'])
add_live_tv_library(refresh=True)
query = 'UPDATE library_sections SET is_active = 0 WHERE server_id != ? OR ' \
'section_id NOT IN ({})'.format(', '.join(['?'] * len(section_ids)))
monitor_db.action(query=query, args=[plexpy.CONFIG.PMS_IDENTIFIER] + section_ids)
@@ -115,28 +117,28 @@ def refresh_libraries():
return False
def add_live_tv_library():
if not plexpy.CONFIG.ADD_LIVE_TV_LIBRARY:
def add_live_tv_library(refresh=False):
monitor_db = database.MonitorDatabase()
result = monitor_db.select_single('SELECT * FROM library_sections '
'WHERE section_id = ? and server_id = ?',
[common.LIVE_TV_SECTION_ID, plexpy.CONFIG.PMS_IDENTIFIER])
if result and not refresh or not result and refresh:
return
logger.info("Tautulli Libraries :: Adding Live TV library to the database.")
monitor_db = database.MonitorDatabase()
section_keys = {'server_id': plexpy.CONFIG.PMS_IDENTIFIER,
'section_id': common.LIVE_TV_SECTION_ID}
section_values = {'server_id': plexpy.CONFIG.PMS_IDENTIFIER,
'section_id': common.LIVE_TV_SECTION_ID,
'section_name': common.LIVE_TV_SECTION_NAME,
'section_type': 'live'
'section_type': 'live',
'is_active': 1
}
result = monitor_db.upsert('library_sections', key_dict=section_keys, value_dict=section_values)
if result == 'insert':
plexpy.CONFIG.__setattr__('ADD_LIVE_TV_LIBRARY', 0)
plexpy.CONFIG.write()
def has_library_type(section_type):
monitor_db = database.MonitorDatabase()

View File

@@ -17,6 +17,7 @@
from __future__ import unicode_literals
from io import open
import os
from apscheduler.triggers.cron import CronTrigger
@@ -214,7 +215,7 @@ def get_newsletter(newsletter_uuid=None, newsletter_id_name=None):
if newsletter_file in os.listdir(newsletter_folder):
try:
with open(newsletter_file_fp, 'r') as n_file:
with open(newsletter_file_fp, 'r', encoding='utf-8') as n_file:
newsletter = n_file.read()
return newsletter
except OSError as e:

View File

@@ -1399,8 +1399,7 @@ class EMAIL(Notifier):
success = True
except Exception as e:
logger.error("Tautulli Notifiers :: {name} notification failed: {e}".format(
name=self.NAME, e=str(e).decode('utf-8')))
logger.error("Tautulli Notifiers :: %s notification failed: %s", self.NAME, e)
finally:
if mailserver:
@@ -2970,7 +2969,7 @@ class SCRIPTS(Notifier):
'.php': 'php',
'.pl': 'perl',
'.ps1': 'powershell -executionPolicy bypass -file',
'.py': 'python',
'.py': 'python' if plexpy.FROZEN else sys.executable,
'.pyw': 'pythonw',
'.rb': 'ruby',
'.sh': ''
@@ -3008,7 +3007,7 @@ class SCRIPTS(Notifier):
'TAUTULLI_PUBLIC_URL': plexpy.CONFIG.HTTP_BASE_URL + plexpy.HTTP_ROOT,
'TAUTULLI_APIKEY': plexpy.CONFIG.API_KEY,
'TAUTULLI_ENCODING': plexpy.SYS_ENCODING,
'TAUTULLI_PYTHON_VERSION': '.'.join(map(str, plexpy.PYTHON_VERSION))
'TAUTULLI_PYTHON_VERSION': common.PYTHON_VERSION
}
if user_id:

View File

@@ -18,4 +18,4 @@
from __future__ import unicode_literals
PLEXPY_BRANCH = "master"
PLEXPY_RELEASE_VERSION = "v2.5.2"
PLEXPY_RELEASE_VERSION = "v2.5.3"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
if [[ "$TAUTULLI_DOCKER" = "True" ]]; then
if [[ -v PUID && -v PGID ]]; then
if [[ "$TAUTULLI_DOCKER" == "True" ]]; then
if [[ -n $PUID && -n $PGID ]]; then
getent group "$PGID" 2>&1 > /dev/null || groupadd -g "$PGID" tautulli
getent passwd "$PUID" 2>&1 > /dev/null || useradd -r -u "$PUID" -g "$PGID" tautulli
@@ -14,24 +14,20 @@ if [[ "$TAUTULLI_DOCKER" = "True" ]]; then
echo "Running Tautulli using user $user (uid=$PUID) and group $group (gid=$PGID)"
su "$user" -g "$group" -c "python /app/Tautulli.py --datadir /config"
else
python Tautulli.py --datadir /config
python Tautulli.py --datadir /config
fi
else
if which python3 >/dev/null; then
python3 Tautulli.py &> /dev/null &
elif which python3.8 >/dev/null; then
python3.8 Tautulli.py &> /dev/null &
elif which python3.7 >/dev/null; then
python3.7 Tautulli.py &> /dev/null &
elif which python3.6 >/dev/null; then
python3.6 Tautulli.py &> /dev/null &
elif which python >/dev/null; then
python Tautulli.py &> /dev/null &
elif which python2 >/dev/null; then
python2 Tautulli.py &> /dev/null &
elif which python2.7 >/dev/null; then
python2.7 Tautulli.py &> /dev/null &
else
echo "Cannot start Tautulli: python not found."
fi
python_versions=("python3" "python3.8" "python3.7" "python3.6" "python" "python2" "python2.7")
for cmd in "${python_versions[@]}"; do
if command -v "$cmd" >/dev/null; then
echo "Starting Tautulli with $cmd."
if [[ "$(uname -s)" == "Darwin" ]]; then
$cmd Tautulli.py &> /dev/null &
else
$cmd Tautulli.py --quiet --daemon
fi
exit
fi
done
echo "Unable to start Tautulli. No Python interpreter was found in the following options:" "${python_versions[@]}"
fi