From 3852275b7451df3527d96e162b0354678b358843 Mon Sep 17 00:00:00 2001
From: Giovanni Harting <539@idlegandalf.com>
Date: Sat, 6 Feb 2021 18:41:24 +0100
Subject: [PATCH] =?UTF-8?q?Jellyfin=20Login=20=E2=9C=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 8 +-
data/interfaces/default/welcome.html | 43 ++++------
jellypy/helpers.py | 13 ---
jellypy/jellyfin.py | 23 +++---
jellypy/webserve.py | 115 ++++++++++++---------------
5 files changed, 85 insertions(+), 117 deletions(-)
diff --git a/README.md b/README.md
index 0c0a064c..bc001f25 100644
--- a/README.md
+++ b/README.md
@@ -19,10 +19,10 @@ not well documented (read as: not documented at all).
## Major Differences compared to Tautulli
-* No Plex/PMS Support
-* Removed Google Analytics
-* Removed Python2 support
-* Removed import feature from varius abondonded projects
+* Dropped Plex/PMS Support
+* Dropped Google Analytics
+* Dropped Python2 support
+* Dropped import from varius abondonded projects
## Installation & Support
diff --git a/data/interfaces/default/welcome.html b/data/interfaces/default/welcome.html
index 158570ad..ddfb6eeb 100644
--- a/data/interfaces/default/welcome.html
+++ b/data/interfaces/default/welcome.html
@@ -176,8 +176,7 @@ from jellypy import common, helpers
-
- Verify
+ Verify
@@ -185,7 +184,7 @@ from jellypy import common, helpers
Activity Logging
- Tautulli will keep a history of all streaming activity on your Plex server.
+ JellyPy will keep a history of all streaming activity on your Jellyfin server.
@@ -216,7 +215,7 @@ from jellypy import common, helpers
Notifications
- Tautulli can send a wide variety of notifications to alert you of activity on your Plex
+ JellyPy can send a wide variety of notifications to alert you of activity on your Jellyfin
server.
@@ -225,20 +224,6 @@ from jellypy import common, helpers
wizard.
-
-
-
-
Database Import
-
-
- If you have an existing Tautulli, PlexWatch, or Plexivity database, you can import the data
- into Tautulli.
-
-
- To import a database, navigate to the Settings page
- and to the Import & Backups tab after you have completed this setup wizard.
-
-
@@ -266,7 +251,6 @@ from jellypy import common, helpers
-
@@ -308,7 +292,7 @@ from jellypy import common, helpers
return retValue;
}
- function validatejellyfinip(el) {
+ function validateJellyfinIp(el) {
var valid_jellyfin_ip = el.val();
var retValue = {};
@@ -324,7 +308,7 @@ from jellypy import common, helpers
return retValue;
}
- function validatejellyfintoken(el) {
+ function validateJellyfinToken(el) {
var valid_jellyfin_token = el.val();
var retValue = {};
@@ -518,24 +502,27 @@ from jellypy import common, helpers
var jellyfin_verified = false;
var authenticated = false;
- $("#verify-plex-server").click(function () {
+ $("#verify-jellyfin-server").click(function () {
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();
+ var jellyfin_user = $("#jellyfin_user").val().trim();
+ var jellyfin_password = $("#jellyfin_password").val();
+
if ((jellyfin_ip !== '') || (jellyfin_port !== '')) {
$("#jellyfin-verify-status").html(' Verifying server...');
$('#jellyfin-verify-status').fadeIn('fast');
$.ajax({
- url: 'get_server_id',
+ url: 'check_login',
data: {
hostname: jellyfin_ip,
port: jellyfin_port,
- identifier: jellyfin_identifier,
ssl: jellyfin_ssl,
- remote: jellyfin_is_remote
+ remote: jellyfin_is_remote,
+ user: jellyfin_user,
+ password: jellyfin_password
},
cache: true,
async: true,
@@ -549,12 +536,12 @@ from jellypy import common, helpers
var identifier = result.identifier;
if (identifier) {
$("#jellyfin_identifier").val(identifier);
- $("#jellyfin-verify-status").html(' Server found!');
+ $("#jellyfin-verify-status").html(' Login successfull!');
$('#jellyfin-verify-status').fadeIn('fast');
jellyfin_verified = true;
$("#jellyfin_valid").val("valid");
} else {
- $("#jellyfin-verify-status").html(' This is not a Plex Server!');
+ $("#jellyfin-verify-status").html(' This is not a Jellyfin Server!');
$('#jellyfin-verify-status').fadeIn('fast');
}
}
diff --git a/jellypy/helpers.py b/jellypy/helpers.py
index 1522cc5c..f432dc9c 100644
--- a/jellypy/helpers.py
+++ b/jellypy/helpers.py
@@ -653,19 +653,6 @@ def is_public_ip(host):
return False
-def get_ip(host):
- ip_address = ''
- if is_valid_ip(host):
- return host
- elif not re.match(r'^[0-9]+(?:\.[0-9]+){3}(?!\d*-[a-z0-9]{6})$', host):
- try:
- ip_address = socket.getaddrinfo(host, None)[0][4][0]
- logger.debug("IP Checker :: Resolved %s to %s." % (host, ip_address))
- except:
- logger.error("IP Checker :: Bad IP or hostname provided: %s." % host)
- return ip_address
-
-
def is_valid_ip(address):
try:
return IP(address)
diff --git a/jellypy/jellyfin.py b/jellypy/jellyfin.py
index 04a45636..ab543b26 100644
--- a/jellypy/jellyfin.py
+++ b/jellypy/jellyfin.py
@@ -35,11 +35,13 @@ class Jellyfin(object):
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.jf.config.data["auth.ssl"] = jellypy.CONFIG.JELLYFIN_SSL
self.url = url
+ self.id = None
+ self.token = token
- if token:
- self.login(token=token)
+ if self.token:
+ self.login()
def get_library(self, section_id):
return self.jf.library.sectionByID(str(section_id))
@@ -50,22 +52,23 @@ class Jellyfin(object):
def get_item(self, rating_key):
return self.jf.fetchItem(rating_key)
- def login(self, user=None, password=None, token=None) -> bool:
- if user and password:
+ def login(self, user=None, password=None) -> bool:
+ if user and password and self.url:
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
-
+ self.id = credentials["Servers"][0]["Id"]
# jellypy.CONFIG.JELLYFIN_TOKEN =
#
# self._connect_client(server)
# self.credentials.append(server)
# self.save_credentials()
return True
- return False
+ if self.token and self.url:
+ # TODO: Add token auth
+ pass
+
+ return False
diff --git a/jellypy/webserve.py b/jellypy/webserve.py
index a232d516..96d602e8 100644
--- a/jellypy/webserve.py
+++ b/jellypy/webserve.py
@@ -20,6 +20,7 @@ import csv
import json
import linecache
import os
+import re
import shutil
import sys
import threading
@@ -30,7 +31,6 @@ from urllib.parse import urlencode
import cherrypy
import mako.exceptions
import mako.template
-import websocket
from cherrypy import NotFound
from cherrypy.lib.static import serve_file, serve_fileobj, serve_download
from mako.lookup import TemplateLookup
@@ -57,6 +57,7 @@ from jellypy import versioncheck
from jellypy import webstart
from jellypy.api2 import API2
from jellypy.helpers import checked, addtoapi, create_https_certificates, build_datatables_json, sanitize_out
+from jellypy.jellyfin import Jellyfin
from jellypy.password import make_hash
from jellypy.session import get_session_info, get_session_user_id, allow_session_user, allow_session_library
from jellypy.webauth import AuthController, requireAuth, member_of, check_auth
@@ -4035,14 +4036,16 @@ class WebInterface(object):
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
@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 JELLYFIN server identifier.
+ def check_login(self, hostname=None, port=None, ssl=0, remote=0, manual=0, user=None, password=None,
+ get_url=False, test_websocket=False, **kwargs):
+ """ Try Jellyfin Login.
```
Required parameters:
hostname (str): 'localhost' or '192.160.0.10'
- port (int): 32400
+ port (int): 8096
+ user (str): Jellyfin user
+ password (str): Jellyfin password
Optional parameters:
ssl (int): 0 or 1
@@ -4054,66 +4057,54 @@ class WebInterface(object):
```
"""
# Attempt to get the pms_identifier from plex.tv if the server is published
- # Works for all JELLYFIN SSL settings
- if not identifier and hostname and port:
- pass
- # TODO: Jellyfin
- # plex_tv = plextv.PlexTV()
- # servers = plex_tv.discover()
- # ip_address = get_ip(hostname)
+ # Works for all Jellyfin SSL settings
+ result = {"identifier": None}
+ if hostname and port and user and password:
+ path_regex = re.compile("^(https?://)?([^/:]+)(:[0-9]+)?(/.*)?$")
+
+ protocol, host, port, path = path_regex.match(hostname + ":" + port).groups()
+
+ if not protocol:
+ protocol = "http://"
+
+ if protocol == "http://" and not port:
+ port = "8096"
+
+ server = "".join(filter(bool, (protocol, host, port, path)))
+
+ jf = Jellyfin(server)
+ if jf.login(user, password):
+ result = {'identifier': jf.id}
+
+ # if identifier:
+ # if helpers.bool_true(get_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
#
- # for server in servers:
- # if (server['ip'] == hostname or server['ip'] == ip_address) and server['port'] == port:
- # identifier = server['clientIdentifier']
- # break
+ # 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.JELLYFIN_TOKEN]
#
- # # Fallback to checking /identity endpoint if the server is unpublished
- # # 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)
- # uri = '/identity'
- #
- # request_handler = http_handler.HTTPHandler(urls=url,
- # ssl_verify=False)
- # request = request_handler.make_request(uri=uri,
- # request_type='GET',
- # output_format='xml')
- # if request:
- # xml_head = request.getElementsByTagName('MediaContainer')[0]
- # identifier = xml_head.getAttribute('machineIdentifier')
-
- result = {'identifier': identifier}
-
- if identifier:
- if helpers.bool_true(get_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.JELLYFIN_TOKEN]
-
- logger.debug("Testing websocket connection...")
- try:
- test_ws = websocket.create_connection(ws_url, header=header)
- test_ws.close()
- logger.debug("Websocket connection test successful.")
- result['ws'] = True
- except (websocket.WebSocketException, IOError, Exception) as e:
- logger.error("Websocket connection test failed: %s" % e)
- result['ws'] = False
+ # logger.debug("Testing websocket connection...")
+ # try:
+ # test_ws = websocket.create_connection(ws_url, header=header)
+ # test_ws.close()
+ # logger.debug("Websocket connection test successful.")
+ # result['ws'] = True
+ # except (websocket.WebSocketException, IOError, Exception) as e:
+ # logger.error("Websocket connection test failed: %s" % e)
+ # result['ws'] = False
return result
else:
- logger.warn('Unable to retrieve the JELLYFIN identifier.')
+ logger.warn('Unable to retrieve the Jellyfin identifier.')
return result
@cherrypy.expose
@@ -4480,8 +4471,8 @@ class WebInterface(object):
@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):
+ opacity=100, background='000000', blur=0, img_format='png',
+ fallback=None, refresh=False, clip=False, **kwargs):
""" Gets an image from the JELLYFIN and saves it to the image cache directory.
```