From 6e1067e43e8f1e52167f40020e1fdfe2fb843e1e Mon Sep 17 00:00:00 2001 From: Giovanni Harting <539@idlegandalf.com> Date: Sat, 6 Feb 2021 16:36:15 +0100 Subject: [PATCH] remodel config to match jellyfin purpose --- API.md | 3 - CONTRIBUTING.md | 41 ----- data/interfaces/default/css/tautulli.css | 12 +- data/interfaces/default/js/script.js | 195 +++++++++++++---------- data/interfaces/default/welcome.html | 190 +++++++++++----------- jellypy/__init__.py | 28 ++-- jellypy/common.py | 4 +- jellypy/config.py | 157 +++--------------- jellypy/jellyfin.py | 40 ++++- jellypy/version.py | 4 +- jellypy/webserve.py | 187 +++++++++++----------- 11 files changed, 390 insertions(+), 471 deletions(-) delete mode 100644 API.md delete mode 100644 CONTRIBUTING.md diff --git a/API.md b/API.md deleted file mode 100644 index 009a9024..00000000 --- a/API.md +++ /dev/null @@ -1,3 +0,0 @@ -# API Reference - -Tautulli API documentation has been moved to the [wiki page](https://github.com/Tautulli/Tautulli-Wiki/wiki/Tautulli-API-Reference). \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index e687432e..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,41 +0,0 @@ -# Contributing to Tautulli - -## Pull Requests -If you think you can contribute code to the Tautulli repository, do not hesitate to submit a pull request. - -### Branches -All pull requests should be based on the `nightly` branch, to minimize cross merges. When you want to develop a new feature, clone the repository with `git clone origin/nightly -b FEATURE_NAME`. Use meaningful commit messages. - -### Python Code - -#### Compatibility -The code should work with Python 2.7.17 or 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 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 - * `package_name` - * `ClassName` - * `method_name` - * `field_name` - * `_private_something` - * `self.__really_private_field` - * `_global` - -#### Documentation -Document your code. Use docstrings See [PEP-257](https://www.python.org/dev/peps/pep-0257/) for more information. - -### HTML/Template code - -#### Compatibility -HTML5 compatible browsers are targeted. - -#### Conventions -* 4 space indentation -* `methodName` -* `variableName` -* `ClassName` diff --git a/data/interfaces/default/css/tautulli.css b/data/interfaces/default/css/tautulli.css index 59442840..54e79b1b 100644 --- a/data/interfaces/default/css/tautulli.css +++ b/data/interfaces/default/css/tautulli.css @@ -89,14 +89,14 @@ select.form-control { margin-bottom: 4px; padding-left: 5px; } -.selectize-control.form-control.selectize-pms-ip .selectize-input { +.selectize-control.form-control.selectize-jellyfin-ip .selectize-input { padding-left: 12px !important; border-top-left-radius: 3px; border-bottom-left-radius: 3px; min-height: 32px !important; height: 32px !important; } -.input-group .selectize-control.form-control.selectize-pms-ip .selectize-input > div { +.input-group .selectize-control.form-control.selectize-jellyfin-ip .selectize-input > div { max-width: 450px; overflow: hidden; text-overflow: ellipsis; @@ -104,18 +104,18 @@ select.form-control { .wizard-input-section p.welcome-message { margin: 20px 0; } -.wizard-input-section .selectize-control.form-control.selectize-pms-ip .selectize-input > div { +.wizard-input-section .selectize-control.form-control.selectize-jellyfin-ip .selectize-input > div { max-width: 360px; overflow: hidden; text-overflow: ellipsis; } -#selectize-pms-ip-container .selectize-dropdown.form-control.selectize-pms-ip { +#selectize-jellyfin-ip-container .selectize-dropdown.form-control.selectize-jellyfin-ip { margin-left: 15px; } -.wizard-input-section .selectize-control.form-control.selectize-pms-ip .selectize-dropdown .selectize-dropdown-content { +.wizard-input-section .selectize-control.form-control.selectize-jellyfin-ip .selectize-dropdown .selectize-dropdown-content { max-height: 150px; } -.wizard-input-section .selectize-dropdown.form-control.selectize-pms-ip { +.wizard-input-section .selectize-dropdown.form-control.selectize-jellyfin-ip { margin-top: 0 !important; } #condition-widget .fa-plus, diff --git a/data/interfaces/default/js/script.js b/data/interfaces/default/js/script.js index 4cb6f5e9..cd6af786 100644 --- a/data/interfaces/default/js/script.js +++ b/data/interfaces/default/js/script.js @@ -145,7 +145,7 @@ function doAjaxCall(url, elem, reload, form, showMsg, callback) { dataString = $(formID).serialize(); } // Loader Image - var loader = $("
  Saving...
"); + var loader = $("
  Saving...
"); // Data Success Message var dataSucces = $(elem).data('success'); if (typeof dataSucces === "undefined") { @@ -248,10 +248,10 @@ getBrowsePath = function (key, path, filter_ext) { path: path, filter_ext: filter_ext }, - success: function(data) { + success: function (data) { deferred.resolve(data); }, - error: function() { + error: function () { deferred.reject(); } }); @@ -350,13 +350,13 @@ function getPercent(value1, value2) { function millisecondsToMinutes(ms, roundToMinute) { if (ms > 0) { - var minutes = Math.floor(ms / 60000); - var seconds = ((ms % 60000) / 1000).toFixed(0); - if (roundToMinute) { - return (seconds >= 30 ? (minutes + 1) : minutes); - } else { - return (seconds == 60 ? (minutes + 1) + ":00" : minutes + ":" + (seconds < 10 ? "0" : "") + seconds); - } + var minutes = Math.floor(ms / 60000); + var seconds = ((ms % 60000) / 1000).toFixed(0); + if (roundToMinute) { + return (seconds >= 30 ? (minutes + 1) : minutes); + } else { + return (seconds == 60 ? (minutes + 1) + ":00" : minutes + ":" + (seconds < 10 ? "0" : "") + seconds); + } } else { if (roundToMinute) { return '0'; @@ -366,7 +366,7 @@ function millisecondsToMinutes(ms, roundToMinute) { } } -function humanDuration(ms, sig='dhm', units='ms', return_seconds=300000) { +function humanDuration(ms, sig = 'dhm', units = 'ms', return_seconds = 300000) { var factors = { d: 86400000, h: 3600000, @@ -385,7 +385,7 @@ function humanDuration(ms, sig='dhm', units='ms', return_seconds=300000) { ms = ms * factors[units]; - h = ms % factors['d']; + h = ms % factors['d']; d = Math.trunc(ms / factors['d']); m = h % factors['h']; @@ -460,6 +460,7 @@ function getCookie(cname) { } return ""; } + var Accordion = function (el, multiple, close) { this.el = el || {}; this.multiple = multiple || false; @@ -496,6 +497,7 @@ function clearSearchButton(tableName, table) { table.search('').draw(); }); } + // Taken from https://github.com/Hellowlol/HTPC-Manager window.onerror = function (message, file, line) { var e = { @@ -504,7 +506,8 @@ window.onerror = function (message, file, line) { 'file': file, 'line': line }; - $.post("log_js_errors", e, function (data) { }); + $.post("log_js_errors", e, function (data) { + }); }; $('*').on('click', '.refresh_pms_image', function (e) { @@ -554,14 +557,11 @@ function forceMinMax(elem) { var default_val = parseInt(elem.data('default')); if (isNaN(val)) { elem.val(default_val); - } - else if (min !== undefined && val < min) { + } else if (min !== undefined && val < min) { elem.val(min); - } - else if (max !== undefined && val > max) { + } else if (max !== undefined && val > max) { elem.val(max); - } - else { + } else { elem.val(val); } } @@ -570,14 +570,14 @@ function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } -$.fn.slideToggleBool = function(bool, options) { - return bool ? $(this).slideDown(options) : $(this).slideUp(options); +$.fn.slideToggleBool = function (bool, options) { + return bool ? $(this).slideDown(options) : $(this).slideUp(options); }; function openPlexXML(endpoint, plextv, params) { var data = $.extend({endpoint: endpoint, plextv: plextv}, params); - $.getJSON('return_plex_xml_url', data, function(xml_url) { - window.open(xml_url, '_blank'); + $.getJSON('return_plex_xml_url', data, function (xml_url) { + window.open(xml_url, '_blank'); }); } @@ -609,6 +609,7 @@ function setLocalStorage(key, value, path) { } localStorage.setItem(key_path, value); } + function getLocalStorage(key, default_value, path) { var key_path = key; if (path !== false) { @@ -624,7 +625,7 @@ function getLocalStorage(key, default_value, path) { } function uuidv4() { - return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, function(c) { + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) { var cryptoObj = window.crypto || window.msCrypto; // for IE 11 return (c ^ cryptoObj.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) }); @@ -648,44 +649,44 @@ function getPlexHeaders() { var plex_oauth_window = null; const plex_oauth_loader = '' + '
' + - '
' + - '' + - '
' + - 'Redirecting to the Plex login page...' + - '
' + + '
' + + '' + + '
' + + 'Redirecting to the Plex login page...' + + '
' + '
'; function closePlexOAuthWindow() { @@ -702,10 +703,10 @@ getPlexOAuthPin = function () { url: 'https://plex.tv/api/v2/pins?strong=true', type: 'POST', headers: x_plex_headers, - success: function(data) { + success: function (data) { deferred.resolve({pin: data.id, code: data.code}); }, - error: function() { + error: function () { closePlexOAuthWindow(); deferred.reject(); } @@ -751,7 +752,7 @@ function PlexOAuth(success, error, pre) { type: 'GET', headers: x_plex_headers, success: function (data) { - if (data.authToken){ + if (data.authToken) { closePlexOAuthWindow(); if (typeof success === "function") { success(data.authToken) @@ -767,8 +768,10 @@ function PlexOAuth(success, error, pre) { } }, complete: function () { - if (!plex_oauth_window.closed && polling === pin){ - setTimeout(function() {poll()}, 1000); + if (!plex_oauth_window.closed && polling === pin) { + setTimeout(function () { + poll() + }, 1000); } }, timeout: 10000 @@ -783,7 +786,7 @@ function PlexOAuth(success, error, pre) { } function encodeData(data) { - return Object.keys(data).map(function(key) { + return Object.keys(data).map(function (key) { return [key, data[key]].map(encodeURIComponent).join("="); }).join("&"); } @@ -808,17 +811,39 @@ function page(endpoint, ...args) { function pms_image_proxy(img, rating_key, width, height, opacity, background, blur, fallback, refresh, clip, img_format) { var params = {}; - if (img != null) { params.img = img; } - if (rating_key != null) { params.rating_key = rating_key; } - if (width != null) { params.width = width; } - if (height != null) { params.height = height; } - if (opacity != null) { params.opacity = opacity; } - if (background != null) { params.background = background; } - if (blur != null) { params.blur = blur; } - if (fallback != null) { params.fallback = fallback; } - if (refresh != null) { params.refresh = true; } - if (clip != null) { params.clip = true; } - if (img_format != null) { params.img_format = img_format; } + if (img != null) { + params.img = img; + } + if (rating_key != null) { + params.rating_key = rating_key; + } + if (width != null) { + params.width = width; + } + if (height != null) { + params.height = height; + } + if (opacity != null) { + params.opacity = opacity; + } + if (background != null) { + params.background = background; + } + if (blur != null) { + params.blur = blur; + } + if (fallback != null) { + params.fallback = fallback; + } + if (refresh != null) { + params.refresh = true; + } + if (clip != null) { + params.clip = true; + } + if (img_format != null) { + params.img_format = img_format; + } return params; } @@ -832,7 +857,9 @@ function info_page(rating_key, guid, history, live) { params.rating_key = rating_key; } - if (history) { params.source = 'history'; } + if (history) { + params.source = 'history'; + } return params; } @@ -840,7 +867,9 @@ function info_page(rating_key, guid, history, live) { function library_page(section_id) { var params = {}; - if (section_id != null) { params.section_id = section_id; } + if (section_id != null) { + params.section_id = section_id; + } return params; } @@ -848,8 +877,12 @@ function library_page(section_id) { function user_page(user_id, user) { var params = {}; - if (user_id != null) { params.user_id = user_id; } - if (user != null) { params.user = user; } + if (user_id != null) { + params.user_id = user_id; + } + if (user != null) { + params.user = user; + } return params; } diff --git a/data/interfaces/default/welcome.html b/data/interfaces/default/welcome.html index 8fbaed02..158570ad 100644 --- a/data/interfaces/default/welcome.html +++ b/data/interfaces/default/welcome.html @@ -98,20 +98,20 @@ from jellypy import common, helpers

- +
- + % if config['jellyfin_identifier']: + % endif @@ -119,36 +119,36 @@ from jellypy import common, helpers
- +
- +
- +
@@ -162,7 +162,7 @@ from jellypy import common, helpers
-
@@ -171,14 +171,14 @@ from jellypy import common, helpers
-
- + Verify - +
@@ -192,7 +192,7 @@ from jellypy import common, helpers
- @@ -308,15 +308,15 @@ from jellypy import common, helpers return retValue; } - function validatePMSip(el) { - var valid_pms_ip = el.val(); + function validatejellyfinip(el) { + var valid_jellyfin_ip = el.val(); var retValue = {}; - if (valid_pms_ip === "") { + if (valid_jellyfin_ip === "") { retValue.status = false; retValue.msg = "Please verify your server."; - $("#pms-verify-status").html(' Please verify your server.'); - $('#pms-verify-status').fadeIn('fast').delay(2000).fadeOut('fast'); + $("#jellyfin-verify-status").html(' Please verify your server.'); + $('#jellyfin-verify-status').fadeIn('fast').delay(2000).fadeOut('fast'); } else { retValue.status = true; } @@ -324,15 +324,15 @@ from jellypy import common, helpers return retValue; } - function validatePMStoken(el) { - var valid_pms_token = el.val(); + function validatejellyfintoken(el) { + var valid_jellyfin_token = el.val(); var retValue = {}; - if (valid_pms_token === "") { + if (valid_jellyfin_token === "") { retValue.status = false; retValue.msg = "Please authenticate."; - $("#pms-token-status").html(' Please authenticate.'); - $('#pms-token-status').fadeIn('fast').delay(2000).fadeOut('fast'); + $("#jellyfin-token-status").html(' Please authenticate.'); + $('#jellyfin-token-status').fadeIn('fast').delay(2000).fadeOut('fast'); } else { retValue.status = true; } @@ -408,7 +408,7 @@ from jellypy import common, helpers } }); - var $select_pms = $('#pms_ip_selectize').selectize({ + var $select_jellyfin = $('#jellyfin_ip_selectize').selectize({ createOnBlur: true, openOnFocus: true, maxItems: 1, @@ -462,35 +462,35 @@ from jellypy import common, helpers }); }, onChange: function (item) { - var pms_ip_selected = this.getItem(item)[0]; - var identifier = $(pms_ip_selected).data('identifier'); - var ip = $(pms_ip_selected).data('ip'); - var port = $(pms_ip_selected).data('port'); - var local = $(pms_ip_selected).data('local'); - var ssl = $(pms_ip_selected).data('ssl'); - var value = $(pms_ip_selected).data('value'); + var jellyfin_ip_selected = this.getItem(item)[0]; + var identifier = $(jellyfin_ip_selected).data('identifier'); + var ip = $(jellyfin_ip_selected).data('ip'); + var port = $(jellyfin_ip_selected).data('port'); + var local = $(jellyfin_ip_selected).data('local'); + var ssl = $(jellyfin_ip_selected).data('ssl'); + var value = $(jellyfin_ip_selected).data('value'); - $("#pms_valid").val(identifier !== 'undefined' ? 'valid' : ''); - $("#pms-verify-status").html(identifier !== 'undefined' ? '  Server found!' : '').fadeIn('fast'); + $("#jellyfin_valid").val(identifier !== 'undefined' ? 'valid' : ''); + $("#jellyfin-verify-status").html(identifier !== 'undefined' ? '  Server found!' : '').fadeIn('fast'); - $("#pms_identifier").val(identifier !== 'undefined' ? identifier : ''); - $('#pms_ip').val(ip !== 'undefined' ? ip : value); - $('#pms_port').val(port !== 'undefined' ? port : 8096); - $('#pms_is_remote_checkbox').prop('checked', (local !== 'undefined' && local === 0)); - $('#pms_is_remote').val(local !== 'undefined' && local === 0 ? 1 : 0); - $('#pms_ssl_checkbox').prop('checked', (ssl !== 'undefined' && ssl === 1)); - $('#pms_ssl').val(ssl !== 'undefined' && ssl === 1 ? 1 : 0); + $("#jellyfin_identifier").val(identifier !== 'undefined' ? identifier : ''); + $('#jellyfin_ip').val(ip !== 'undefined' ? ip : value); + $('#jellyfin_port').val(port !== 'undefined' ? port : 8096); + $('#jellyfin_is_remote_checkbox').prop('checked', (local !== 'undefined' && local === 0)); + $('#jellyfin_is_remote').val(local !== 'undefined' && local === 0 ? 1 : 0); + $('#jellyfin_ssl_checkbox').prop('checked', (ssl !== 'undefined' && ssl === 1)); + $('#jellyfin_ssl').val(ssl !== 'undefined' && ssl === 1 ? 1 : 0); - $('#pms_port').prop('readonly', false); - $('#pms_is_remote_checkbox').prop('disabled', false); - $('#pms_ssl_checkbox').prop('disabled', false); + $('#jellyfin_port').prop('readonly', false); + $('#jellyfin_is_remote_checkbox').prop('disabled', false); + $('#jellyfin_ssl_checkbox').prop('disabled', false); }, onDropdownOpen: function () { this.clear(); } }); - var select_pms = $select_pms[0].selectize; + var select_jellyfin = $select_jellyfin[0].selectize; function getServerOptions(token) { /* Set token and returns server options */ @@ -501,13 +501,13 @@ from jellypy import common, helpers }, success: function (result) { if (result) { - var existing_ip = $('#pms_ip').val(); - var existing_port = $('#pms_port').val(); + var existing_ip = $('#jellyfin_ip').val(); + var existing_port = $('#jellyfin_port').val(); result.forEach(function (item) { if (item.ip === existing_ip && item.port === existing_port) { - select_pms.updateOption(item.value, item); + select_jellyfin.updateOption(item.value, item); } else { - select_pms.addOption(item); + select_jellyfin.addOption(item); } }); } @@ -515,61 +515,61 @@ from jellypy import common, helpers }) } - var pms_verified = false; + var jellyfin_verified = false; var authenticated = false; $("#verify-plex-server").click(function () { - if (!(pms_verified)) { - var pms_ip = $("#pms_ip").val().trim(); - var pms_port = $("#pms_port").val().trim(); - var pms_identifier = $("#pms_identifier").val(); - var pms_ssl = $("#pms_ssl").val(); - var pms_is_remote = $("#pms_is_remote").val(); - if ((pms_ip !== '') || (pms_port !== '')) { - $("#pms-verify-status").html('  Verifying server...'); - $('#pms-verify-status').fadeIn('fast'); + if (!(jellyfin_verified)) { + var jellyfin_ip = $("#jellyfin_ip").val().trim(); + var jellyfin_port = $("#jellyfin_port").val().trim(); + var jellyfin_identifier = $("#jellyfin_identifier").val(); + var jellyfin_ssl = $("#jellyfin_ssl").val(); + var jellyfin_is_remote = $("#jellyfin_is_remote").val(); + if ((jellyfin_ip !== '') || (jellyfin_port !== '')) { + $("#jellyfin-verify-status").html('  Verifying server...'); + $('#jellyfin-verify-status').fadeIn('fast'); $.ajax({ url: 'get_server_id', data: { - hostname: pms_ip, - port: pms_port, - identifier: pms_identifier, - ssl: pms_ssl, - remote: pms_is_remote + hostname: jellyfin_ip, + port: jellyfin_port, + identifier: jellyfin_identifier, + ssl: jellyfin_ssl, + remote: jellyfin_is_remote }, cache: true, async: true, timeout: 5000, error: function (jqXHR, textStatus, errorThrown) { - $("#pms-verify-status").html('  Error verifying server: ' + textStatus); - $('#pms-verify-status').fadeIn('fast'); + $("#jellyfin-verify-status").html('  Error verifying server: ' + textStatus); + $('#jellyfin-verify-status').fadeIn('fast'); }, success: function (xhr, status) { var result = xhr; var identifier = result.identifier; if (identifier) { - $("#pms_identifier").val(identifier); - $("#pms-verify-status").html('  Server found!'); - $('#pms-verify-status').fadeIn('fast'); - pms_verified = true; - $("#pms_valid").val("valid"); + $("#jellyfin_identifier").val(identifier); + $("#jellyfin-verify-status").html('  Server found!'); + $('#jellyfin-verify-status').fadeIn('fast'); + jellyfin_verified = true; + $("#jellyfin_valid").val("valid"); } else { - $("#pms-verify-status").html('  This is not a Plex Server!'); - $('#pms-verify-status').fadeIn('fast'); + $("#jellyfin-verify-status").html('  This is not a Plex Server!'); + $('#jellyfin-verify-status').fadeIn('fast'); } } }); } else { - $("#pms-verify-status").html('  Please enter both fields.'); - $('#pms-verify-status').fadeIn('fast'); + $("#jellyfin-verify-status").html('  Please enter both fields.'); + $('#jellyfin-verify-status').fadeIn('fast'); } } }); - $(".pms-settings").change(function () { - pms_verified = false; - $("#pms_valid").val(""); - $("#pms-verify-status").html(""); + $(".jellyfin-settings").change(function () { + jellyfin_verified = false; + $("#jellyfin_valid").val(""); + $("#jellyfin-verify-status").html(""); }); }); diff --git a/jellypy/__init__.py b/jellypy/__init__.py index 85b68764..985d1110 100644 --- a/jellypy/__init__.py +++ b/jellypy/__init__.py @@ -239,9 +239,9 @@ def initialize(config_file): mobile_app.blacklist_logger() # Check if Tautulli has a uuid - if CONFIG.PMS_UUID == '' or not CONFIG.PMS_UUID: + if CONFIG.JELLYFIN_UUID == '' or not CONFIG.JELLYFIN_UUID: logger.debug("Generating UUID...") - CONFIG.PMS_UUID = generate_uuid() + CONFIG.JELLYFIN_UUID = generate_uuid() CONFIG.write() # Check if Tautulli has an API key @@ -410,7 +410,7 @@ def initialize_scheduler(): # Update check github_minutes = CONFIG.CHECK_GITHUB_INTERVAL if CONFIG.CHECK_GITHUB_INTERVAL and CONFIG.CHECK_GITHUB else 0 - pms_update_check_hours = CONFIG.PMS_UPDATE_CHECK_INTERVAL if 1 <= CONFIG.PMS_UPDATE_CHECK_INTERVAL else 24 + JELLYFIN_update_check_hours = CONFIG.JELLYFIN_UPDATE_CHECK_INTERVAL if 1 <= CONFIG.JELLYFIN_UPDATE_CHECK_INTERVAL else 24 schedule_job(versioncheck.check_update, 'Check GitHub for updates', hours=0, minutes=github_minutes, seconds=0, args=(True, True)) @@ -424,13 +424,13 @@ def initialize_scheduler(): schedule_job(config.make_backup, 'Backup Tautulli config', hours=backup_hours, minutes=0, seconds=0, args=(True, True)) - if WS_CONNECTED and CONFIG.PMS_IP and CONFIG.PMS_TOKEN: + if WS_CONNECTED and CONFIG.JELLYFIN_IP and CONFIG.JELLYFIN_TOKEN: # TODO: Jellyfin # schedule_job(plextv.get_server_resources, 'Refresh Plex server URLs', - # hours=12 * (not bool(CONFIG.PMS_URL_MANUAL)), minutes=0, seconds=0) + # hours=12 * (not bool(CONFIG.JELLYFIN_URL_MANUAL)), minutes=0, seconds=0) schedule_job(activity_pinger.check_server_updates, 'Check for Plex updates', - hours=pms_update_check_hours * bool(CONFIG.MONITOR_PMS_UPDATES), minutes=0, seconds=0) + hours=JELLYFIN_update_check_hours * bool(CONFIG.MONITOR_JELLYFIN_UPDATES), minutes=0, seconds=0) # Refresh the users list and libraries list user_hours = CONFIG.REFRESH_USERS_INTERVAL if 1 <= CONFIG.REFRESH_USERS_INTERVAL <= 24 else 12 @@ -531,8 +531,8 @@ def start(): def startup_refresh(): - # Get the real PMS urls for SSL and remote access - if CONFIG.PMS_TOKEN and CONFIG.PMS_IP and CONFIG.PMS_PORT: + # Get the real JELLYFIN urls for SSL and remote access + if CONFIG.JELLYFIN_TOKEN and CONFIG.JELLYFIN_IP and CONFIG.JELLYFIN_PORT: pass # TODO: Jellyfin # plextv.get_server_resources() @@ -542,11 +542,11 @@ def startup_refresh(): activity_pinger.connect_server(log=True, startup=True) # Refresh the users list on startup - if CONFIG.PMS_TOKEN and CONFIG.REFRESH_USERS_ON_STARTUP: + if CONFIG.JELLYFIN_TOKEN and CONFIG.REFRESH_USERS_ON_STARTUP: users.refresh_users() # Refresh the libraries list on startup - if CONFIG.PMS_IP and CONFIG.PMS_TOKEN and CONFIG.REFRESH_LIBRARIES_ON_STARTUP: + if CONFIG.JELLYFIN_IP and CONFIG.JELLYFIN_TOKEN and CONFIG.REFRESH_LIBRARIES_ON_STARTUP: libraries.refresh_libraries() @@ -684,19 +684,19 @@ def dbcheck(): 'on_resume INTEGER DEFAULT 0, on_change INTEGER DEFAULT 0, on_buffer INTEGER DEFAULT 0, ' 'on_error INTEGER DEFAULT 0, on_watched INTEGER DEFAULT 0, on_created INTEGER DEFAULT 0, ' 'on_extdown INTEGER DEFAULT 0, on_intdown INTEGER DEFAULT 0, ' - 'on_extup INTEGER DEFAULT 0, on_intup INTEGER DEFAULT 0, on_pmsupdate INTEGER DEFAULT 0, ' + 'on_extup INTEGER DEFAULT 0, on_intup INTEGER DEFAULT 0, on_JELLYFINupdate INTEGER DEFAULT 0, ' 'on_concurrent INTEGER DEFAULT 0, on_newdevice INTEGER DEFAULT 0, on_plexpyupdate INTEGER DEFAULT 0, ' 'on_plexpydbcorrupt INTEGER DEFAULT 0, ' 'on_play_subject TEXT, on_stop_subject TEXT, on_pause_subject TEXT, ' 'on_resume_subject TEXT, on_change_subject TEXT, on_buffer_subject TEXT, on_error_subject TEXT, ' 'on_watched_subject TEXT, on_created_subject TEXT, on_extdown_subject TEXT, on_intdown_subject TEXT, ' - 'on_extup_subject TEXT, on_intup_subject TEXT, on_pmsupdate_subject TEXT, ' + 'on_extup_subject TEXT, on_intup_subject TEXT, on_JELLYFINupdate_subject TEXT, ' 'on_concurrent_subject TEXT, on_newdevice_subject TEXT, on_plexpyupdate_subject TEXT, ' 'on_plexpydbcorrupt_subject TEXT, ' 'on_play_body TEXT, on_stop_body TEXT, on_pause_body TEXT, ' 'on_resume_body TEXT, on_change_body TEXT, on_buffer_body TEXT, on_error_body TEXT, ' 'on_watched_body TEXT, on_created_body TEXT, on_extdown_body TEXT, on_intdown_body TEXT, ' - 'on_extup_body TEXT, on_intup_body TEXT, on_pmsupdate_body TEXT, ' + 'on_extup_body TEXT, on_intup_body TEXT, on_JELLYFINupdate_body TEXT, ' 'on_concurrent_body TEXT, on_newdevice_body TEXT, on_plexpyupdate_body TEXT, ' 'on_plexpydbcorrupt_body TEXT, ' 'custom_conditions TEXT, custom_conditions_logic TEXT)' @@ -731,7 +731,7 @@ def dbcheck(): # recently_added table :: This table keeps record of recently added items c_db.execute( 'CREATE TABLE IF NOT EXISTS recently_added (id INTEGER PRIMARY KEY AUTOINCREMENT, ' - 'added_at INTEGER, pms_identifier TEXT, section_id INTEGER, ' + 'added_at INTEGER, JELLYFIN_identifier TEXT, section_id INTEGER, ' 'rating_key INTEGER, parent_rating_key INTEGER, grandparent_rating_key INTEGER, media_type TEXT, ' 'media_info TEXT)' ) diff --git a/jellypy/common.py b/jellypy/common.py index ba2c7d14..4b05fef7 100644 --- a/jellypy/common.py +++ b/jellypy/common.py @@ -31,8 +31,8 @@ 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 +BRANCH = version.JELLYPY_BRANCH +RELEASE = version.JELLYPY_VERSION USER_AGENT = '{}/{} ({} {})'.format(PRODUCT, RELEASE, PLATFORM, PLATFORM_RELEASE) diff --git a/jellypy/config.py b/jellypy/config.py index 0ceb6ceb..bf432766 100644 --- a/jellypy/config.py +++ b/jellypy/config.py @@ -41,30 +41,28 @@ FILENAME = "config.ini" _CONFIG_DEFINITIONS = { 'ALLOW_GUEST_ACCESS': (int, 'General', 0), 'DATE_FORMAT': (str, 'General', 'YYYY-MM-DD'), - 'PMS_IDENTIFIER': (str, 'PMS', ''), - 'PMS_IP': (str, 'PMS', '127.0.0.1'), - 'PMS_IS_CLOUD': (int, 'PMS', 0), - 'PMS_IS_REMOTE': (int, 'PMS', 0), - 'PMS_LOGS_FOLDER': (str, 'PMS', ''), - 'PMS_LOGS_LINE_CAP': (int, 'PMS', 1000), - 'PMS_NAME': (str, 'PMS', ''), - 'PMS_PORT': (int, 'PMS', 32400), - 'PMS_TOKEN': (str, 'PMS', ''), - 'PMS_SSL': (int, 'PMS', 0), - 'PMS_URL': (str, 'PMS', ''), - 'PMS_URL_OVERRIDE': (str, 'PMS', ''), - 'PMS_URL_MANUAL': (int, 'PMS', 0), - 'PMS_USE_BIF': (int, 'PMS', 0), - 'PMS_UUID': (str, 'PMS', ''), - 'PMS_TIMEOUT': (int, 'Advanced', 15), - 'PMS_PLEXPASS': (int, 'PMS', 0), - 'PMS_PLATFORM': (str, 'PMS', ''), - 'PMS_VERSION': (str, 'PMS', ''), - 'PMS_UPDATE_CHANNEL': (str, 'PMS', 'plex'), - 'PMS_UPDATE_DISTRO': (str, 'PMS', ''), - 'PMS_UPDATE_DISTRO_BUILD': (str, 'PMS', ''), - 'PMS_UPDATE_CHECK_INTERVAL': (int, 'Advanced', 24), - 'PMS_WEB_URL': (str, 'PMS', 'https://app.plex.tv/desktop'), + 'JELLYFIN_IDENTIFIER': (str, 'JELLYFIN', ''), + 'JELLYFIN_IP': (str, 'JELLYFIN', '127.0.0.1'), + 'JELLYFIN_IS_REMOTE': (int, 'JELLYFIN', 0), + 'JELLYFIN_LOGS_FOLDER': (str, 'JELLYFIN', ''), + 'JELLYFIN_LOGS_LINE_CAP': (int, 'JELLYFIN', 1000), + 'JELLYFIN_NAME': (str, 'JELLYFIN', ''), + 'JELLYFIN_PORT': (int, 'JELLYFIN', 8096), + 'JELLYFIN_TOKEN': (str, 'JELLYFIN', ''), + 'JELLYFIN_SSL': (int, 'JELLYFIN', 0), + 'JELLYFIN_URL': (str, 'JELLYFIN', ''), + 'JELLYFIN_URL_OVERRIDE': (str, 'JELLYFIN', ''), + 'JELLYFIN_URL_MANUAL': (int, 'JELLYFIN', 0), + 'JELLYFIN_USE_BIF': (int, 'JELLYFIN', 0), + 'JELLYFIN_UUID': (str, 'JELLYFIN', ''), + 'JELLYFIN_TIMEOUT': (int, 'Advanced', 15), + 'JELLYFIN_PLEXPASS': (int, 'JELLYFIN', 0), + 'JELLYFIN_PLATFORM': (str, 'JELLYFIN', ''), + 'JELLYFIN_VERSION': (str, 'JELLYFIN', ''), + 'JELLYFIN_UPDATE_DISTRO': (str, 'JELLYFIN', ''), + 'JELLYFIN_UPDATE_DISTRO_BUILD': (str, 'JELLYFIN', ''), + 'JELLYFIN_UPDATE_CHECK_INTERVAL': (int, 'Advanced', 24), + 'JELLYFIN_CLIENT_UUID': (str, 'JELLYFIN', ''), 'TIME_FORMAT': (str, 'General', 'HH:mm'), 'ANON_REDIRECT': (str, 'General', 'https://www.nullrefer.com/?'), 'API_ENABLED': (int, 'General', 1), @@ -78,7 +76,7 @@ _CONFIG_DEFINITIONS = { 'CACHE_DIR': (str, 'General', ''), 'CACHE_IMAGES': (int, 'General', 1), 'CACHE_SIZEMB': (int, 'Advanced', 32), - 'CHECK_GITHUB': (int, 'General', 1), + 'CHECK_GITHUB': (int, 'General', 0), 'CHECK_GITHUB_INTERVAL': (int, 'General', 360), 'CHECK_GITHUB_ON_STARTUP': (int, 'General', 1), 'CHECK_GITHUB_CACHE_SECONDS': (int, 'Advanced', 3600), @@ -142,7 +140,7 @@ _CONFIG_DEFINITIONS = { 'MOVIE_WATCHED_PERCENT': (int, 'Monitoring', 85), 'MUSIC_WATCHED_PERCENT': (int, 'Monitoring', 85), 'MUSICBRAINZ_LOOKUP': (int, 'General', 0), - 'MONITOR_PMS_UPDATES': (int, 'Monitoring', 0), + 'MONITOR_JELLYFIN_UPDATES': (int, 'Monitoring', 0), 'MONITORING_INTERVAL': (int, 'Monitoring', 60), 'NEWSLETTER_AUTH': (int, 'Newsletter', 0), 'NEWSLETTER_PASSWORD': (str, 'Newsletter', ''), @@ -164,7 +162,7 @@ _CONFIG_DEFINITIONS = { 'NOTIFY_CONCURRENT_BY_IP': (int, 'Monitoring', 0), 'NOTIFY_CONCURRENT_THRESHOLD': (int, 'Monitoring', 2), 'NOTIFY_NEW_DEVICE_INITIAL_ONLY': (int, 'Monitoring', 1), - 'PLEXPY_AUTO_UPDATE': (int, 'General', 0), + 'JELLYPY_AUTO_UPDATE': (int, 'General', 0), 'REFRESH_LIBRARIES_INTERVAL': (int, 'Monitoring', 12), 'REFRESH_LIBRARIES_ON_STARTUP': (int, 'Monitoring', 1), 'REFRESH_USERS_INTERVAL': (int, 'Monitoring', 12), @@ -194,15 +192,12 @@ _BLACKLIST_KEYS = ['_APITOKEN', '_TOKEN', '_KEY', '_SECRET', '_PASSWORD', '_APIK _WHITELIST_KEYS = ['HTTPS_KEY'] _DO_NOT_IMPORT_KEYS = [ - 'FIRST_RUN_COMPLETE', 'GET_FILE_SIZES_HOLD', 'GIT_PATH', 'PMS_LOGS_FOLDER', + 'FIRST_RUN_COMPLETE', 'GET_FILE_SIZES_HOLD', 'GIT_PATH', 'JELLYFIN_LOGS_FOLDER', 'BACKUP_DIR', 'CACHE_DIR', 'EXPORT_DIR', 'LOG_DIR', 'NEWSLETTER_DIR', 'NEWSLETTER_CUSTOM_DIR', 'HTTP_HOST', 'HTTP_PORT', 'HTTP_ROOT', 'HTTP_USERNAME', 'HTTP_PASSWORD', 'HTTP_HASH_PASSWORD', 'HTTP_HASHED_PASSWORD', 'ENABLE_HTTPS', 'HTTPS_CREATE_CERT', 'HTTPS_CERT', 'HTTPS_CERT_CHAIN', 'HTTPS_KEY' ] -_DO_NOT_IMPORT_KEYS_DOCKER = [ - 'PLEXPY_AUTO_UPDATE', 'GIT_REMOTE', 'GIT_BRANCH' -] IS_IMPORTING = False IMPORT_THREAD = None @@ -250,9 +245,6 @@ def import_tautulli_config(config=None, backup=False): # Remove keys that should not be imported for key in _DO_NOT_IMPORT_KEYS: delattr(imported_config, key) - if jellypy.DOCKER or jellypy.SNAP: - for key in _DO_NOT_IMPORT_KEYS_DOCKER: - delattr(imported_config, key) # Merge the imported config file into the current config file jellypy.CONFIG._config.merge(imported_config._config) @@ -442,100 +434,3 @@ class Config(object): """ if self.CONFIG_VERSION == 0: self.CONFIG_VERSION = 1 - - if self.CONFIG_VERSION == 1: - # Change home_stats_cards to list - if self.HOME_STATS_CARDS: - home_stats_cards = ''.join(self.HOME_STATS_CARDS).split(', ') - if 'watch_statistics' in home_stats_cards: - home_stats_cards.remove('watch_statistics') - self.HOME_STATS_CARDS = home_stats_cards - # Change home_library_cards to list - if self.HOME_LIBRARY_CARDS: - home_library_cards = ''.join(self.HOME_LIBRARY_CARDS).split(', ') - if 'library_statistics' in home_library_cards: - home_library_cards.remove('library_statistics') - self.HOME_LIBRARY_CARDS = home_library_cards - - self.CONFIG_VERSION = 2 - - if self.CONFIG_VERSION == 2: - self.CONFIG_VERSION = 3 - - if self.CONFIG_VERSION == 3: - if self.HTTP_ROOT == '/': - self.HTTP_ROOT = '' - - self.CONFIG_VERSION = 4 - - if self.CONFIG_VERSION == 4: - if not len(self.HOME_STATS_CARDS) and 'watch_stats' in self.HOME_SECTIONS: - home_sections = self.HOME_SECTIONS - home_sections.remove('watch_stats') - self.HOME_SECTIONS = home_sections - if not len(self.HOME_LIBRARY_CARDS) and 'library_stats' in self.HOME_SECTIONS: - home_sections = self.HOME_SECTIONS - home_sections.remove('library_stats') - self.HOME_SECTIONS = home_sections - - self.CONFIG_VERSION = 5 - - if self.CONFIG_VERSION == 5: - self.MONITOR_PMS_UPDATES = 0 - - self.CONFIG_VERSION = 6 - - if self.CONFIG_VERSION == 6: - if self.GIT_USER.lower() == 'drzoidberg33': - self.GIT_USER = 'JonnyWong16' - - self.CONFIG_VERSION = 7 - - if self.CONFIG_VERSION == 7: - self.CONFIG_VERSION = 8 - - if self.CONFIG_VERSION == 8: - self.CONFIG_VERSION = 9 - - if self.CONFIG_VERSION == 9: - if self.PMS_UPDATE_CHANNEL == 'plexpass': - self.PMS_UPDATE_CHANNEL = 'beta' - - self.CONFIG_VERSION = 10 - - if self.CONFIG_VERSION == 10: - self.GIT_USER = 'Tautulli' - self.GIT_REPO = 'Tautulli' - - self.CONFIG_VERSION = 11 - - if self.CONFIG_VERSION == 11: - self.ANON_REDIRECT = self.ANON_REDIRECT.replace('http://www.nullrefer.com/?', - 'https://www.nullrefer.com/?') - self.CONFIG_VERSION = 12 - - if self.CONFIG_VERSION == 12: - self.BUFFER_THRESHOLD = max(self.BUFFER_THRESHOLD, 10) - - self.CONFIG_VERSION = 13 - - if self.CONFIG_VERSION == 13: - self.CONFIG_VERSION = 14 - - if self.CONFIG_VERSION == 14: - if jellypy.DOCKER: - self.PLEXPY_AUTO_UPDATE = 0 - - self.CONFIG_VERSION = 15 - - if self.CONFIG_VERSION == 15: - if self.HTTP_ROOT and self.HTTP_ROOT != '/': - self.JWT_UPDATE_SECRET = True - - self.CONFIG_VERSION = 16 - - if self.CONFIG_VERSION == 16: - if jellypy.SNAP: - self.PLEXPY_AUTO_UPDATE = 0 - - self.CONFIG_VERSION = 17 diff --git a/jellypy/jellyfin.py b/jellypy/jellyfin.py index 5ade0b4d..04a45636 100644 --- a/jellypy/jellyfin.py +++ b/jellypy/jellyfin.py @@ -14,13 +14,32 @@ # # You should have received a copy of the GNU General Public License # along with Tautulli. If not, see . +import pprint +import uuid from jellyfin_apiclient_python import JellyfinClient +import jellypy +from jellypy.common import PRODUCT, RELEASE + class Jellyfin(object): def __init__(self, url, token=None): + if not jellypy.CONFIG.JELLYFIN_CLIENT_UUID: + jellypy.CONFIG.JELLYFIN_CLIENT_UUID = uuid.uuid4() + jellypy.CONFIG.write() + self.jf = JellyfinClient() + self.jf.config.data["app.default"] = True + self.jf.config.app( + PRODUCT, RELEASE, PRODUCT, jellypy.CONFIG.JELLYFIN_CLIENT_UUID + ) + self.jf.config.data["http.user_agent"] = PRODUCT + self.jf.config.data["auth.ssl"] = not jellypy.CONFIG.JELLYFIN_SSL + self.url = url + + if token: + self.login(token=token) def get_library(self, section_id): return self.jf.library.sectionByID(str(section_id)) @@ -31,5 +50,22 @@ class Jellyfin(object): def get_item(self, rating_key): return self.jf.fetchItem(rating_key) - def login(self, user, password): - pass + def login(self, user=None, password=None, token=None) -> bool: + if user and password: + self.jf.auth.connect_to_address(self.url) + result = self.jf.auth.login(self.url, user, password) + + if "AccessToken" in result: + credentials = self.jf.auth.credentials.get_credentials() + pprint.pprint(credentials) + server = credentials["Servers"][0] + server["uuid"] = server["Id"] + server["username"] = user + + # jellypy.CONFIG.JELLYFIN_TOKEN = + # + # self._connect_client(server) + # self.credentials.append(server) + # self.save_credentials() + return True + return False diff --git a/jellypy/version.py b/jellypy/version.py index f3cddd1c..8cb03665 100644 --- a/jellypy/version.py +++ b/jellypy/version.py @@ -15,5 +15,5 @@ # You should have received a copy of the GNU General Public License # along with Tautulli. If not, see . -PLEXPY_BRANCH = "master" -PLEXPY_RELEASE_VERSION = "v2.6.5" +JELLYPY_BRANCH = "master" +JELLYPY_VERSION = "1.0.0-alpha" diff --git a/jellypy/webserve.py b/jellypy/webserve.py index ca121895..a232d516 100644 --- a/jellypy/webserve.py +++ b/jellypy/webserve.py @@ -75,7 +75,7 @@ def serve_template(templatename, **kwargs): error_handler=mako_error_handler) http_root = jellypy.HTTP_ROOT - server_name = jellypy.CONFIG.PMS_NAME + server_name = jellypy.CONFIG.JELLYFIN_NAME cache_param = '?' + (jellypy.CURRENT_VERSION or common.RELEASE) _session = get_session_info() @@ -153,15 +153,14 @@ class WebInterface(object): @requireAuth(member_of("admin")) def welcome(self, **kwargs): config = { - "pms_identifier": jellypy.CONFIG.PMS_IDENTIFIER, - "pms_ip": jellypy.CONFIG.PMS_IP, - "pms_port": jellypy.CONFIG.PMS_PORT, - "pms_is_remote": jellypy.CONFIG.PMS_IS_REMOTE, - "pms_ssl": jellypy.CONFIG.PMS_SSL, - "pms_is_cloud": jellypy.CONFIG.PMS_IS_CLOUD, - "pms_token": jellypy.CONFIG.PMS_TOKEN, - "pms_uuid": jellypy.CONFIG.PMS_UUID, - "pms_name": jellypy.CONFIG.PMS_NAME, + "jellyfin_identifier": jellypy.CONFIG.JELLYFIN_IDENTIFIER, + "jellyfin_ip": jellypy.CONFIG.JELLYFIN_IP, + "jellyfin_port": jellypy.CONFIG.JELLYFIN_PORT, + "jellyfin_is_remote": jellypy.CONFIG.JELLYFIN_IS_REMOTE, + "jellyfin_ssl": jellypy.CONFIG.JELLYFIN_SSL, + "jellyfin_token": jellypy.CONFIG.JELLYFIN_TOKEN, + "jellyfin_uuid": jellypy.CONFIG.JELLYFIN_UUID, + "jellyfin_name": jellypy.CONFIG.JELLYFIN_NAME, "logging_ignore_interval": jellypy.CONFIG.LOGGING_IGNORE_INTERVAL } @@ -203,7 +202,7 @@ class WebInterface(object): """ if token: # Need to set token so result doesn't return http 401 - jellypy.CONFIG.__setattr__('PMS_TOKEN', token) + jellypy.CONFIG.__setattr__('JELLYFIN_TOKEN', token) jellypy.CONFIG.write() include_cloud = not (include_cloud == 'false') @@ -226,8 +225,8 @@ class WebInterface(object): config = { "home_sections": jellypy.CONFIG.HOME_SECTIONS, "home_refresh_interval": jellypy.CONFIG.HOME_REFRESH_INTERVAL, - "pms_name": jellypy.CONFIG.PMS_NAME, - "pms_is_cloud": jellypy.CONFIG.PMS_IS_CLOUD, + "jellyfin_name": jellypy.CONFIG.JELLYFIN_NAME, + "jellyfin_is_cloud": jellypy.CONFIG.JELLYFIN_IS_CLOUD, "update_show_changelog": jellypy.CONFIG.UPDATE_SHOW_CHANGELOG, "first_run_complete": jellypy.CONFIG.FIRST_RUN_COMPLETE } @@ -273,7 +272,7 @@ class WebInterface(object): def get_current_activity(self, **kwargs): pass # TODO: Jellyfin - # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN) + # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.JELLYFIN_TOKEN) # result = pms_connect.get_current_activity() # # if result: @@ -287,7 +286,7 @@ class WebInterface(object): def get_current_activity_instance(self, session_key=None, **kwargs): pass # TODO: Jellyfin - # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN) + # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.JELLYFIN_TOKEN) # result = pms_connect.get_current_activity() # # if result: @@ -330,18 +329,18 @@ class WebInterface(object): @cherrypy.tools.json_out() @requireAuth(member_of("admin")) def return_plex_xml_url(self, endpoint='', plextv=False, **kwargs): - kwargs['X-Plex-Token'] = jellypy.CONFIG.PMS_TOKEN + kwargs['X-Plex-Token'] = jellypy.CONFIG.JELLYFIN_TOKEN if helpers.bool_true(plextv): base_url = 'https://plex.tv' else: - if jellypy.CONFIG.PMS_URL_OVERRIDE: - base_url = jellypy.CONFIG.PMS_URL_OVERRIDE + if jellypy.CONFIG.JELLYFIN_URL_OVERRIDE: + base_url = jellypy.CONFIG.JELLYFIN_URL_OVERRIDE else: - base_url = jellypy.CONFIG.PMS_URL + base_url = jellypy.CONFIG.JELLYFIN_URL if '{machine_id}' in endpoint: - endpoint = endpoint.format(machine_id=jellypy.CONFIG.PMS_IDENTIFIER) + endpoint = endpoint.format(machine_id=jellypy.CONFIG.JELLYFIN_IDENTIFIER) return base_url + endpoint + '?' + urlencode(kwargs) @@ -512,7 +511,7 @@ class WebInterface(object): @sanitize_out() @addtoapi("get_library_names") def get_library_sections(self, **kwargs): - """ Get a list of library sections and ids on the PMS. + """ Get a list of library sections and ids on the JELLYFIN. ``` Required parameters: @@ -588,7 +587,7 @@ class WebInterface(object): status_message = 'An error occured.' return serve_template(templatename="edit_library.html", title="Edit Library", - data=result, server_id=jellypy.CONFIG.PMS_IDENTIFIER, status_message=status_message) + data=result, server_id=jellypy.CONFIG.JELLYFIN_IDENTIFIER, status_message=status_message) @cherrypy.expose @requireAuth(member_of("admin")) @@ -2594,7 +2593,7 @@ class WebInterface(object): user_id = get_session_user_id() # TODO: Jellyfin - # plex_tv = plextv.PlexTV(token=jellypy.CONFIG.PMS_TOKEN) + # plex_tv = plextv.PlexTV(token=jellypy.CONFIG.JELLYFIN_TOKEN) # result = plex_tv.get_synced_items(machine_id=machine_id, user_id_filter=user_id) result = None @@ -2711,7 +2710,7 @@ class WebInterface(object): @requireAuth(member_of("admin")) @addtoapi() def get_plex_log(self, **kwargs): - """ Get the PMS logs. + """ Get the JELLYFIN logs. ``` Required parameters: @@ -2732,7 +2731,7 @@ class WebInterface(object): ] ``` """ - window = int(kwargs.get('window', jellypy.CONFIG.PMS_LOGS_LINE_CAP)) + window = int(kwargs.get('window', jellypy.CONFIG.JELLYFIN_LOGS_LINE_CAP)) log_lines = [] log_type = kwargs.get('log_type', 'server') @@ -3060,25 +3059,25 @@ class WebInterface(object): "check_github": checked(jellypy.CONFIG.CHECK_GITHUB), "interface_list": interface_list, "cache_sizemb": jellypy.CONFIG.CACHE_SIZEMB, - "pms_identifier": jellypy.CONFIG.PMS_IDENTIFIER, - "pms_ip": jellypy.CONFIG.PMS_IP, - "pms_logs_folder": jellypy.CONFIG.PMS_LOGS_FOLDER, - "pms_port": jellypy.CONFIG.PMS_PORT, - "pms_token": jellypy.CONFIG.PMS_TOKEN, - "pms_ssl": jellypy.CONFIG.PMS_SSL, - "pms_is_remote": jellypy.CONFIG.PMS_IS_REMOTE, - "pms_is_cloud": jellypy.CONFIG.PMS_IS_CLOUD, - "pms_url": jellypy.CONFIG.PMS_URL, - "pms_url_manual": checked(jellypy.CONFIG.PMS_URL_MANUAL), - "pms_uuid": jellypy.CONFIG.PMS_UUID, - "pms_web_url": jellypy.CONFIG.PMS_WEB_URL, - "pms_name": jellypy.CONFIG.PMS_NAME, - "pms_update_check_interval": jellypy.CONFIG.PMS_UPDATE_CHECK_INTERVAL, + "jellyfin_identifier": jellypy.CONFIG.JELLYFIN_IDENTIFIER, + "jellyfin_ip": jellypy.CONFIG.JELLYFIN_IP, + "jellyfin_logs_folder": jellypy.CONFIG.JELLYFIN_LOGS_FOLDER, + "jellyfin_port": jellypy.CONFIG.JELLYFIN_PORT, + "jellyfin_token": jellypy.CONFIG.JELLYFIN_TOKEN, + "jellyfin_ssl": jellypy.CONFIG.JELLYFIN_SSL, + "jellyfin_is_remote": jellypy.CONFIG.JELLYFIN_IS_REMOTE, + "jellyfin_is_cloud": jellypy.CONFIG.JELLYFIN_IS_CLOUD, + "jellyfin_url": jellypy.CONFIG.JELLYFIN_URL, + "jellyfin_url_manual": checked(jellypy.CONFIG.JELLYFIN_URL_MANUAL), + "jellyfin_uuid": jellypy.CONFIG.JELLYFIN_UUID, + "jellyfin_web_url": jellypy.CONFIG.JELLYFIN_WEB_URL, + "jellyfin_name": jellypy.CONFIG.JELLYFIN_NAME, + "jellyfin_update_check_interval": jellypy.CONFIG.JELLYFIN_UPDATE_CHECK_INTERVAL, "date_format": jellypy.CONFIG.DATE_FORMAT, "time_format": jellypy.CONFIG.TIME_FORMAT, "week_start_monday": checked(jellypy.CONFIG.WEEK_START_MONDAY), "get_file_sizes": checked(jellypy.CONFIG.GET_FILE_SIZES), - "monitor_pms_updates": checked(jellypy.CONFIG.MONITOR_PMS_UPDATES), + "monitor_jellyfin_updates": checked(jellypy.CONFIG.MONITOR_JELLYFIN_UPDATES), "refresh_libraries_interval": jellypy.CONFIG.REFRESH_LIBRARIES_INTERVAL, "refresh_libraries_on_startup": checked(jellypy.CONFIG.REFRESH_LIBRARIES_ON_STARTUP), "refresh_users_interval": jellypy.CONFIG.REFRESH_USERS_INTERVAL, @@ -3108,7 +3107,7 @@ class WebInterface(object): "cloudinary_api_key": jellypy.CONFIG.CLOUDINARY_API_KEY, "cloudinary_api_secret": jellypy.CONFIG.CLOUDINARY_API_SECRET, "cache_images": checked(jellypy.CONFIG.CACHE_IMAGES), - "pms_version": jellypy.CONFIG.PMS_VERSION, + "jellyfin_version": jellypy.CONFIG.JELLYFIN_VERSION, "plexpy_auto_update": checked(jellypy.CONFIG.PLEXPY_AUTO_UPDATE), "git_branch": jellypy.CONFIG.GIT_BRANCH, "git_path": jellypy.CONFIG.GIT_PATH, @@ -3154,12 +3153,12 @@ class WebInterface(object): "launch_browser", "launch_startup", "enable_https", "https_create_cert", "api_enabled", "freeze_db", "check_github", "group_history_tables", - "pms_url_manual", "week_start_monday", + "jellyfin_url_manual", "week_start_monday", "refresh_libraries_on_startup", "refresh_users_on_startup", "notify_consecutive", "notify_recently_added_upgrade", "notify_group_recently_added_grandparent", "notify_group_recently_added_parent", "notify_new_device_initial_only", - "monitor_pms_updates", "get_file_sizes", "log_blacklist", "http_hash_password", + "monitor_jellyfin_updates", "get_file_sizes", "log_blacklist", "http_hash_password", "allow_guest_access", "cache_images", "http_proxy", "http_basic_auth", "notify_concurrent_by_ip", "history_table_activity", "plexpy_auto_update", "themoviedb_lookup", "tvmaze_lookup", "musicbrainz_lookup", "http_plex_admin", @@ -3210,15 +3209,15 @@ class WebInterface(object): if kwargs.get('check_github') != jellypy.CONFIG.CHECK_GITHUB or \ kwargs.get('refresh_libraries_interval') != str(jellypy.CONFIG.REFRESH_LIBRARIES_INTERVAL) or \ kwargs.get('refresh_users_interval') != str(jellypy.CONFIG.REFRESH_USERS_INTERVAL) or \ - kwargs.get('pms_update_check_interval') != str(jellypy.CONFIG.PMS_UPDATE_CHECK_INTERVAL) or \ - kwargs.get('monitor_pms_updates') != jellypy.CONFIG.MONITOR_PMS_UPDATES or \ - kwargs.get('pms_url_manual') != jellypy.CONFIG.PMS_URL_MANUAL: + kwargs.get('jellyfin_update_check_interval') != str(jellypy.CONFIG.JELLYFIN_UPDATE_CHECK_INTERVAL) or \ + kwargs.get('monitor_jellyfin_updates') != jellypy.CONFIG.MONITOR_JELLYFIN_UPDATES or \ + kwargs.get('jellyfin_url_manual') != jellypy.CONFIG.JELLYFIN_URL_MANUAL: reschedule = True - # If we change the SSL setting for PMS or PMS remote setting, make sure we grab the new url. - if kwargs.get('pms_ssl') != str(jellypy.CONFIG.PMS_SSL) or \ - kwargs.get('pms_is_remote') != str(jellypy.CONFIG.PMS_IS_REMOTE) or \ - kwargs.get('pms_url_manual') != jellypy.CONFIG.PMS_URL_MANUAL: + # If we change the SSL setting for JELLYFIN or JELLYFIN remote setting, make sure we grab the new url. + if kwargs.get('jellyfin_ssl') != str(jellypy.CONFIG.JELLYFIN_SSL) or \ + kwargs.get('jellyfin_is_remote') != str(jellypy.CONFIG.JELLYFIN_IS_REMOTE) or \ + kwargs.get('jellyfin_url_manual') != jellypy.CONFIG.JELLYFIN_URL_MANUAL: server_changed = True # If we change the HTTPS setting, make sure we generate a new certificate. @@ -3357,11 +3356,11 @@ class WebInterface(object): # update_channel = pmsconnect.PmsConnect().get_server_update_channel() # # return {'plexpass': plexpass, - # 'pms_platform': common.PMS_PLATFORM_NAME_OVERRIDES.get( - # jellypy.CONFIG.PMS_PLATFORM, jellypy.CONFIG.PMS_PLATFORM), - # 'pms_update_channel': jellypy.CONFIG.PMS_UPDATE_CHANNEL, - # 'pms_update_distro': jellypy.CONFIG.PMS_UPDATE_DISTRO, - # 'pms_update_distro_build': jellypy.CONFIG.PMS_UPDATE_DISTRO_BUILD, + # 'pms_platform': common.JELLYFIN_PLATFORM_NAME_OVERRIDES.get( + # jellypy.CONFIG.JELLYFIN_PLATFORM, jellypy.CONFIG.JELLYFIN_PLATFORM), + # 'pms_update_channel': jellypy.CONFIG.JELLYFIN_UPDATE_CHANNEL, + # 'pms_update_distro': jellypy.CONFIG.JELLYFIN_UPDATE_DISTRO, + # 'pms_update_distro_build': jellypy.CONFIG.JELLYFIN_UPDATE_DISTRO_BUILD, # 'plex_update_channel': 'plexpass' if update_channel == 'beta' else 'public'} @cherrypy.expose @@ -3983,7 +3982,7 @@ class WebInterface(object): @cherrypy.tools.json_out() @requireAuth(member_of("admin")) @addtoapi() - def get_pms_token(self, username=None, password=None, **kwargs): + def get_jellyfin_token(self, username=None, password=None, **kwargs): """ Get the user's Plex token used for Tautulli. ``` @@ -4015,7 +4014,7 @@ class WebInterface(object): @cherrypy.expose @cherrypy.tools.json_out() @requireAuth(member_of("admin")) - def get_plexpy_pms_token(self, username=None, password=None, force=False, **kwargs): + def get_plexpy_jellyfin_token(self, username=None, password=None, force=False, **kwargs): """ Fetch a new Plex.tv token for Tautulli """ if not username and not password: return None @@ -4038,7 +4037,7 @@ class WebInterface(object): @addtoapi() def get_server_id(self, hostname=None, port=None, identifier=None, ssl=0, remote=0, manual=0, get_url=False, test_websocket=False, **kwargs): - """ Get the PMS server identifier. + """ Get the JELLYFIN server identifier. ``` Required parameters: @@ -4055,7 +4054,7 @@ class WebInterface(object): ``` """ # Attempt to get the pms_identifier from plex.tv if the server is published - # Works for all PMS SSL settings + # Works for all JELLYFIN SSL settings if not identifier and hostname and port: pass # TODO: Jellyfin @@ -4069,7 +4068,7 @@ class WebInterface(object): # break # # # Fallback to checking /identity endpoint if the server is unpublished - # # Cannot set SSL settings on the PMS if unpublished so 'http' is okay + # # Cannot set SSL settings on the JELLYFIN if unpublished so 'http' is okay # if not identifier: # scheme = 'https' if helpers.cast_to_int(ssl) else 'http' # url = '{scheme}://{hostname}:{port}'.format(scheme=scheme, hostname=hostname, port=port) @@ -4088,19 +4087,19 @@ class WebInterface(object): if identifier: if helpers.bool_true(get_url): - server = self.get_server_resources(pms_ip=hostname, - pms_port=port, - pms_ssl=ssl, - pms_is_remote=remote, - pms_url_manual=manual, - pms_identifier=identifier) - result['url'] = server['pms_url'] + server = self.get_server_resources(jellyfin_ip=hostname, + jellyfin_port=port, + jellyfin_ssl=ssl, + jellyfin_is_remote=remote, + jellyfin_url_manual=manual, + jellyfin_identifier=identifier) + result['url'] = server['jellyfin_url'] result['ws'] = None if helpers.bool_true(test_websocket): # Quick test websocket connection ws_url = result['url'].replace('http', 'ws', 1) + '/:/websockets/notifications' - header = ['X-Plex-Token: %s' % jellypy.CONFIG.PMS_TOKEN] + header = ['X-Plex-Token: %s' % jellypy.CONFIG.JELLYFIN_TOKEN] logger.debug("Testing websocket connection...") try: @@ -4114,7 +4113,7 @@ class WebInterface(object): return result else: - logger.warn('Unable to retrieve the PMS identifier.') + logger.warn('Unable to retrieve the JELLYFIN identifier.') return result @cherrypy.expose @@ -4122,7 +4121,7 @@ class WebInterface(object): @requireAuth(member_of("admin")) @addtoapi() def get_server_info(self, **kwargs): - """ Get the PMS server information. + """ Get the JELLYFIN server information. ``` Required parameters: @@ -4156,7 +4155,7 @@ class WebInterface(object): @requireAuth(member_of("admin")) @addtoapi() def get_server_pref(self, pref=None, **kwargs): - """ Get a specified PMS server preference. + """ Get a specified JELLYFIN server preference. ``` Required parameters: @@ -4357,8 +4356,8 @@ class WebInterface(object): metadata = None config = { - "pms_identifier": jellypy.CONFIG.PMS_IDENTIFIER, - "pms_web_url": jellypy.CONFIG.PMS_WEB_URL + "jellyfin_identifier": jellypy.CONFIG.JELLYFIN_IDENTIFIER, + "jellyfin_web_url": jellypy.CONFIG.JELLYFIN_WEB_URL } if user_id: @@ -4468,7 +4467,7 @@ class WebInterface(object): # return {'result': 'error', 'message': 'Notification failed.'} @cherrypy.expose - def pms_image_proxy(self, **kwargs): + def jellyfin_image_proxy(self, **kwargs): """ See real_pms_image_proxy docs string""" refresh = False @@ -4477,13 +4476,13 @@ class WebInterface(object): kwargs['refresh'] = refresh - return self.real_pms_image_proxy(**kwargs) + return self.real_jellyfin_image_proxy(**kwargs) - @addtoapi('pms_image_proxy') - def real_pms_image_proxy(self, img=None, rating_key=None, width=750, height=1000, + @addtoapi('jellyfin_image_proxy') + def real_jellyfin_image_proxy(self, img=None, rating_key=None, width=750, height=1000, opacity=100, background='000000', blur=0, img_format='png', fallback=None, refresh=False, clip=False, **kwargs): - """ Gets an image from the PMS and saves it to the image cache directory. + """ Gets an image from the JELLYFIN and saves it to the image cache directory. ``` Required parameters: @@ -4581,7 +4580,7 @@ class WebInterface(object): return result[0] else: - raise Exception('PMS image request failed') + raise Exception('JELLYFIN image request failed') except Exception as e: logger.warn("Failed to get image %s, falling back to %s." % (img, fallback)) @@ -4613,7 +4612,7 @@ class WebInterface(object): if img_info: kwargs.update(img_info) - return self.real_pms_image_proxy(refresh=True, **kwargs) + return self.real_jellyfin_image_proxy(refresh=True, **kwargs) return @@ -4678,13 +4677,13 @@ class WebInterface(object): log_type = kwargs.get('log_type', 'server') log_file = "" - if jellypy.CONFIG.PMS_LOGS_FOLDER: + if jellypy.CONFIG.JELLYFIN_LOGS_FOLDER: if log_type == "server": log_file = 'Plex Media Server.log' - log_file_path = os.path.join(jellypy.CONFIG.PMS_LOGS_FOLDER, log_file) + log_file_path = os.path.join(jellypy.CONFIG.JELLYFIN_LOGS_FOLDER, log_file) elif log_type == "scanner": log_file = 'Plex Media Scanner.log' - log_file_path = os.path.join(jellypy.CONFIG.PMS_LOGS_FOLDER, log_file) + log_file_path = os.path.join(jellypy.CONFIG.JELLYFIN_LOGS_FOLDER, log_file) else: return "Plex log folder not set in the settings." @@ -4807,7 +4806,7 @@ class WebInterface(object): @requireAuth(member_of("admin")) @addtoapi('search') def search_results(self, query='', limit='', **kwargs): - """ Get search results from the PMS. + """ Get search results from the JELLYFIN. ``` Required parameters: @@ -4928,7 +4927,7 @@ class WebInterface(object): @requireAuth(member_of("admin")) @addtoapi() def get_new_rating_keys(self, rating_key='', media_type='', **kwargs): - """ Get a list of new rating keys for the PMS of all of the item's parent/children. + """ Get a list of new rating keys for the JELLYFIN of all of the item's parent/children. ``` Required parameters: @@ -4986,7 +4985,7 @@ class WebInterface(object): @cherrypy.expose @cherrypy.tools.json_out() @requireAuth(member_of("admin")) - def get_pms_sessions_json(self, **kwargs): + def get_jellyfin_sessions_json(self, **kwargs): """ Get all the current sessions. """ # TODO: Jellyfin # pms_connect = pmsconnect.PmsConnect() @@ -5311,7 +5310,7 @@ class WebInterface(object): @cherrypy.tools.json_out() @requireAuth(member_of("admin")) def get_sync_lists(self, machine_id='', **kwargs): - """ Get all items that are currently synced from the PMS. """ + """ Get all items that are currently synced from the JELLYFIN. """ # TODO: Jellyfin # plex_tv = plextv.PlexTV() # result = plex_tv.get_plextv_sync_lists(machine_id=machine_id, output_format='json') @@ -5340,7 +5339,7 @@ class WebInterface(object): @requireAuth(member_of("admin")) @addtoapi() def get_servers_info(self, **kwargs): - """ Get info about the PMS. + """ Get info about the JELLYFIN. ``` Required parameters: @@ -5407,7 +5406,7 @@ class WebInterface(object): @requireAuth(member_of("admin")) @addtoapi() def get_server_friendly_name(self, **kwargs): - """ Get the name of the PMS. + """ Get the name of the JELLYFIN. ``` Required parameters: @@ -5434,7 +5433,7 @@ class WebInterface(object): @requireAuth() @addtoapi() def get_activity(self, session_key=None, session_id=None, **kwargs): - """ Get the current activity on the PMS. + """ Get the current activity on the JELLYFIN. ``` Required parameters: @@ -5694,7 +5693,7 @@ class WebInterface(object): """ # TODO: Jellyfin # try: - # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN) + # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.JELLYFIN_TOKEN) # result = pms_connect.get_current_activity() # # if result: @@ -5831,11 +5830,11 @@ class WebInterface(object): @sanitize_out() @addtoapi() def get_synced_items(self, machine_id='', user_id='', **kwargs): - """ Get a list of synced items on the PMS. + """ Get a list of synced items on the JELLYFIN. ``` Required parameters: - machine_id (str): The PMS identifier + machine_id (str): The JELLYFIN identifier Optional parameters: user_id (str): The id of the Plex user @@ -6062,7 +6061,7 @@ class WebInterface(object): @cherrypy.tools.json_out() @requireAuth(member_of("admin")) @addtoapi() - def get_pms_update(self, **kwargs): + def get_jellyfin_update(self, **kwargs): """ Check for updates to the Plex Media Server. ```