Compare commits
7 Commits
v2.1.30-be
...
v2.1.32
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6d35bd7947 | ||
![]() |
d27356bbba | ||
![]() |
3054a824ce | ||
![]() |
3b22b6a3f7 | ||
![]() |
e4be5a716f | ||
![]() |
13579b8140 | ||
![]() |
b11437b86b |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -1,5 +1,25 @@
|
||||
# Changelog
|
||||
|
||||
## v2.1.32 (2019-06-26)
|
||||
|
||||
* Newsletters:
|
||||
* Fix: Newsletter scheduler issue for QNAP devices using an invalid "local" timezone preventing Tautulli from starting.
|
||||
|
||||
|
||||
## v2.1.31 (2019-06-24)
|
||||
|
||||
* No additional changes from v2.1.31-beta.
|
||||
|
||||
|
||||
## v2.1.31-beta (2019-06-13)
|
||||
|
||||
* Monitoring:
|
||||
* Fix: Synced content showing incorrect stream info.
|
||||
* Other:
|
||||
* Fix: Unable to view database status when authentication is enabled.
|
||||
* Change: Default database synchronous mode changed to prevent database corruption. Database response may be slower.
|
||||
|
||||
|
||||
## v2.1.30-beta (2019-05-11)
|
||||
|
||||
* Monitoring:
|
||||
@@ -14,6 +34,7 @@
|
||||
|
||||
|
||||
## v2.1.29 (2019-05-11)
|
||||
|
||||
* No additional changes from v2.1.29-beta.
|
||||
|
||||
|
||||
@@ -158,6 +179,7 @@
|
||||
|
||||
|
||||
## v2.1.20 (2018-09-05)
|
||||
|
||||
* No additional changes from v2.1.20-beta.
|
||||
|
||||
|
||||
|
@@ -218,7 +218,7 @@ DOCUMENTATION :: END
|
||||
% if data['stream_container_decision'] == 'transcode':
|
||||
Transcode (${data['container'].upper()} <i class="fa fa-long-arrow-right"></i> ${data['stream_container'].upper()})
|
||||
% else:
|
||||
Direct Play (${data['container'].upper()})
|
||||
Direct Play (${data['stream_container'].upper()})
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
@@ -236,7 +236,7 @@ DOCUMENTATION :: END
|
||||
% elif data['stream_video_decision'] == 'copy':
|
||||
Direct Stream (${data['stream_video_codec'].upper()} ${VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])})
|
||||
% else:
|
||||
Direct Play (${data['video_codec'].upper()} ${VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])})
|
||||
Direct Play (${data['stream_video_codec'].upper()} ${VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])})
|
||||
% endif
|
||||
% elif data['media_type'] == 'photo':
|
||||
Direct Play (${data['width']}x${data['height']})
|
||||
@@ -253,7 +253,7 @@ DOCUMENTATION :: END
|
||||
% elif data['stream_audio_decision'] == 'copy':
|
||||
Direct Stream (${AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
|
||||
% else:
|
||||
Direct Play (${AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0].capitalize()})
|
||||
Direct Play (${AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
@@ -270,7 +270,7 @@ DOCUMENTATION :: END
|
||||
% elif data['stream_subtitle_decision'] == 'burn':
|
||||
Burn (${data['subtitle_codec'].upper()})
|
||||
% else:
|
||||
Direct Play (${data['stream_subtitle_codec'].upper() if data['synced_version'] else data['subtitle_codec'].upper()})
|
||||
Direct Play (${data['subtitle_codec'].upper() if data['synced_version'] else data['stream_subtitle_codec'].upper()})
|
||||
% endif
|
||||
% else:
|
||||
None
|
||||
|
@@ -430,7 +430,7 @@
|
||||
if (s.stream_container_decision === 'transcode') {
|
||||
transcode_container = 'Transcode (' + s.container.toUpperCase() + ' <i class="fa fa-long-arrow-right"></i> ' + s.stream_container.toUpperCase() + ')';
|
||||
} else {
|
||||
transcode_container = 'Direct Play (' + s.container.toUpperCase() + ')';
|
||||
transcode_container = 'Direct Play (' + s.stream_container.toUpperCase() + ')';
|
||||
}
|
||||
$('#transcode_container-' + key).html(transcode_container);
|
||||
|
||||
@@ -465,7 +465,7 @@
|
||||
} else if (s.stream_video_decision === 'copy') {
|
||||
video_decision = 'Direct Stream (' + s.stream_video_codec.toUpperCase() + ' ' + sv_res + ')';
|
||||
} else {
|
||||
video_decision = 'Direct Play (' + s.video_codec.toUpperCase() + ' ' + v_res + ')';
|
||||
video_decision = 'Direct Play (' + s.stream_video_codec.toUpperCase() + ' ' + sv_res + ')';
|
||||
}
|
||||
} else if (s.media_type === 'photo') {
|
||||
video_decision = 'Direct Play (' + s.width + 'x' + s.height + ')';
|
||||
@@ -481,7 +481,7 @@
|
||||
} else if (s.stream_audio_decision === 'copy') {
|
||||
audio_decision = 'Direct Stream (' + sa_codec + ' ' + capitalizeFirstLetter(s.stream_audio_channel_layout.split('(')[0]) + ')';
|
||||
} else {
|
||||
audio_decision = 'Direct Play (' + a_codec + ' ' + capitalizeFirstLetter(s.audio_channel_layout.split('(')[0]) + ')';
|
||||
audio_decision = 'Direct Play (' + sa_codec + ' ' + capitalizeFirstLetter(s.stream_audio_channel_layout.split('(')[0]) + ')';
|
||||
}
|
||||
}
|
||||
$('#audio_decision-' + key).html(audio_decision);
|
||||
@@ -495,7 +495,7 @@
|
||||
} else if (s.stream_subtitle_decision === 'burn') {
|
||||
subtitle_decision = 'Burn (' + s.subtitle_codec.toUpperCase() + ')';
|
||||
} else {
|
||||
subtitle_decision = 'Direct Play (' + ((s.synced_version === '1') ? s.stream_subtitle_codec.toUpperCase() : s.subtitle_codec.toUpperCase()) + ')';
|
||||
subtitle_decision = 'Direct Play (' + ((s.synced_version === '1') ? s.subtitle_codec.toUpperCase() : s.stream_subtitle_codec.toUpperCase()) + ')';
|
||||
}
|
||||
}
|
||||
$('#subtitle_decision-' + key).html(subtitle_decision);
|
||||
|
@@ -100,6 +100,7 @@ UMASK = None
|
||||
|
||||
HTTP_PORT = None
|
||||
HTTP_ROOT = None
|
||||
AUTH_ENABLED = None
|
||||
|
||||
DEV = False
|
||||
|
||||
@@ -114,6 +115,7 @@ WIN_SYS_TRAY_ICON = None
|
||||
SYS_TIMEZONE = None
|
||||
SYS_UTC_OFFSET = None
|
||||
|
||||
|
||||
def initialize(config_file):
|
||||
with INIT_LOCK:
|
||||
|
||||
|
@@ -284,7 +284,7 @@ _CONFIG_DEFINITIONS = {
|
||||
'JOIN_ON_PMSUPDATE': (int, 'Join', 0),
|
||||
'JOIN_ON_CONCURRENT': (int, 'Join', 0),
|
||||
'JOIN_ON_NEWDEVICE': (int, 'Join', 0),
|
||||
'JOURNAL_MODE': (str, 'Advanced', 'wal'),
|
||||
'JOURNAL_MODE': (str, 'Advanced', 'WAL'),
|
||||
'LAUNCH_BROWSER': (int, 'General', 1),
|
||||
'LOG_BLACKLIST': (int, 'General', 1),
|
||||
'LOG_DIR': (str, 'General', ''),
|
||||
@@ -541,6 +541,7 @@ _CONFIG_DEFINITIONS = {
|
||||
'SCRIPTS_ON_PMSUPDATE_SCRIPT': (unicode, 'Scripts', ''),
|
||||
'SCRIPTS_ON_CONCURRENT_SCRIPT': (unicode, 'Scripts', ''),
|
||||
'SCRIPTS_ON_NEWDEVICE_SCRIPT': (unicode, 'Scripts', ''),
|
||||
'SYNCHRONOUS_MODE': (str, 'Advanced', 'NORMAL'),
|
||||
'TELEGRAM_BOT_TOKEN': (str, 'Telegram', ''),
|
||||
'TELEGRAM_ENABLED': (int, 'Telegram', 0),
|
||||
'TELEGRAM_CHAT_ID': (str, 'Telegram', ''),
|
||||
|
@@ -126,12 +126,12 @@ class MonitorDatabase(object):
|
||||
def __init__(self, filename=FILENAME):
|
||||
self.filename = filename
|
||||
self.connection = sqlite3.connect(db_filename(filename), timeout=20)
|
||||
# Don't wait for the disk to finish writing
|
||||
self.connection.execute("PRAGMA synchronous = OFF")
|
||||
# Journal disabled since we never do rollbacks
|
||||
# Set database synchronous mode (default NORMAL)
|
||||
self.connection.execute("PRAGMA synchronous = %s" % plexpy.CONFIG.SYNCHRONOUS_MODE)
|
||||
# Set database journal mode (default WAL)
|
||||
self.connection.execute("PRAGMA journal_mode = %s" % plexpy.CONFIG.JOURNAL_MODE)
|
||||
# 64mb of cache memory, probably need to make it user configurable
|
||||
self.connection.execute("PRAGMA cache_size=-%s" % (get_cache_size() * 1024))
|
||||
# Set database cache size (default 32MB)
|
||||
self.connection.execute("PRAGMA cache_size = -%s" % (get_cache_size() * 1024))
|
||||
self.connection.row_factory = dict_factory
|
||||
|
||||
def action(self, query, args=None, return_last_id=False):
|
||||
|
@@ -61,13 +61,11 @@ def schedule_newsletter_job(newsletter_job_id, name='', func=None, remove_job=Fa
|
||||
logger.info(u"Tautulli NewsletterHandler :: Removed scheduled newsletter: %s" % name)
|
||||
else:
|
||||
NEWSLETTER_SCHED.reschedule_job(
|
||||
newsletter_job_id, args=args, trigger=CronTrigger().from_crontab(
|
||||
cron, timezone=plexpy.SYS_TIMEZONE))
|
||||
newsletter_job_id, args=args, trigger=CronTrigger.from_crontab(cron))
|
||||
logger.info(u"Tautulli NewsletterHandler :: Re-scheduled newsletter: %s" % name)
|
||||
elif not remove_job:
|
||||
NEWSLETTER_SCHED.add_job(
|
||||
func, args=args, id=newsletter_job_id, trigger=CronTrigger().from_crontab(
|
||||
cron, timezone=plexpy.SYS_TIMEZONE))
|
||||
func, args=args, id=newsletter_job_id, trigger=CronTrigger.from_crontab(cron))
|
||||
logger.info(u"Tautulli NewsletterHandler :: Scheduled newsletter: %s" % name)
|
||||
|
||||
|
||||
|
@@ -1646,10 +1646,10 @@ class PmsConnect(object):
|
||||
if helpers.get_xml_attr(stream, 'streamType') == '1':
|
||||
video_stream_info = stream
|
||||
|
||||
elif helpers.get_xml_attr(stream, 'streamType') == '2':
|
||||
elif helpers.get_xml_attr(stream, 'streamType') == '2' and helpers.get_xml_attr(stream, 'selected') == '1':
|
||||
audio_stream_info = stream
|
||||
|
||||
elif helpers.get_xml_attr(stream, 'streamType') == '3':
|
||||
elif helpers.get_xml_attr(stream, 'streamType') == '3' and helpers.get_xml_attr(stream, 'selected') == '1':
|
||||
subtitle_stream_info = stream
|
||||
|
||||
video_id = audio_id = subtitle_id = None
|
||||
|
@@ -1,2 +1,2 @@
|
||||
PLEXPY_BRANCH = "beta"
|
||||
PLEXPY_RELEASE_VERSION = "v2.1.30-beta"
|
||||
PLEXPY_BRANCH = "master"
|
||||
PLEXPY_RELEASE_VERSION = "v2.1.32"
|
||||
|
@@ -5884,7 +5884,7 @@ class WebInterface(object):
|
||||
status = {'result': 'success', 'message': 'Ok'}
|
||||
|
||||
if args or kwargs:
|
||||
if not cherrypy.request.path_info == '/api/v2':
|
||||
if not cherrypy.request.path_info == '/api/v2' and plexpy.AUTH_ENABLED:
|
||||
cherrypy.request.config['auth.require'] = []
|
||||
check_auth()
|
||||
|
||||
|
@@ -80,14 +80,15 @@ def initialize(options):
|
||||
logger.info(u"Tautulli WebStart :: Web server authentication is enabled: %s.", ' and '.join(login_allowed))
|
||||
|
||||
if options['http_basic_auth']:
|
||||
auth_enabled = False
|
||||
plexpy.AUTH_ENABLED = False
|
||||
basic_auth_enabled = True
|
||||
else:
|
||||
auth_enabled = True
|
||||
plexpy.AUTH_ENABLED = True
|
||||
basic_auth_enabled = False
|
||||
cherrypy.tools.auth = cherrypy.Tool('before_handler', webauth.check_auth, priority=2)
|
||||
else:
|
||||
auth_enabled = basic_auth_enabled = False
|
||||
plexpy.AUTH_ENABLED = False
|
||||
basic_auth_enabled = False
|
||||
|
||||
if options['http_root'].strip('/'):
|
||||
plexpy.HTTP_ROOT = options['http_root'] = '/' + options['http_root'].strip('/') + '/'
|
||||
@@ -104,7 +105,7 @@ def initialize(options):
|
||||
'tools.gzip.mime_types': ['text/html', 'text/plain', 'text/css',
|
||||
'text/javascript', 'application/json',
|
||||
'application/javascript'],
|
||||
'tools.auth.on': auth_enabled,
|
||||
'tools.auth.on': plexpy.AUTH_ENABLED,
|
||||
'tools.auth_basic.on': basic_auth_enabled,
|
||||
'tools.auth_basic.realm': 'Tautulli web server',
|
||||
'tools.auth_basic.checkpassword': cherrypy.lib.auth_basic.checkpassword_dict({
|
||||
|
Reference in New Issue
Block a user