Compare commits

...

2 Commits

Author SHA1 Message Date
ee2bb22dc9 README: Jellyfin Login ✓ 2021-02-06 18:42:24 +01:00
3852275b74 Jellyfin Login ✓ 2021-02-06 18:41:24 +01:00
5 changed files with 86 additions and 118 deletions

View File

@@ -11,7 +11,7 @@ JellyPy only supports Jellyfin. If you are running run Plex, head over to Tautul
Working on getting basic functionality up. It's going to take some time, based on that Jellyfin's API is
not well documented (read as: not documented at all).
- [ ] Login to Jellyfin
- [x] Login to Jellyfin
- [ ] Libraries/Media
- [ ] Activity
- [ ] History
@@ -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

View File

@@ -176,8 +176,7 @@ from jellypy import common, helpers
</div>
</div>
</div>
<input type="hidden" id="jellyfin_identifier" name="jellyfin_identifier" value="${config['jellyfin_identifier']}">
<a class="btn btn-dark" id="verify-plex-server" href="#" role="button">Verify</a>
<a class="btn btn-dark" id="verify-jellyfin-server" href="#" role="button">Verify</a>
<span style="margin-left: 10px; display: none;" id="jellyfin-verify-status"></span>
</div>
@@ -185,7 +184,7 @@ from jellypy import common, helpers
<h3>Activity Logging</h3>
<div class="wizard-input-section">
<p class="help-block">
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.
</p>
</div>
<div class="wizard-input-section">
@@ -216,7 +215,7 @@ from jellypy import common, helpers
<h3>Notifications</h3>
<div class="wizard-input-section">
<p class="help-block">
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.
</p>
<p class="help-block">
@@ -225,20 +224,6 @@ from jellypy import common, helpers
wizard.
</p>
</div>
</div>
<div class="wizard-card" data-cardname="card7">
<h3>Database Import</h3>
<div class="wizard-input-section">
<p class="help-block">
If you have an existing Tautulli, PlexWatch, or Plexivity database, you can import the data
into Tautulli.
</p>
<p class="help-block">
To import a database, navigate to the <strong>Settings</strong> page
and to the <strong>Import & Backups</strong> tab after you have completed this setup wizard.
</p>
</div>
<!-- Required fields but hidden -->
<div style="display: none;">
@@ -266,7 +251,6 @@ from jellypy import common, helpers
<input type="text" name="home_stats_cards" id="home_stats_cards" value="first_run_wizard">
<input type="text" name="home_library_cards" id="home_library_cards" value="first_run_wizard">
</div>
</div>
</form>
@@ -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('<i class="fa fa-refresh fa-spin"></i>&nbsp; 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('<i class="fa fa-check"></i>&nbsp; Server found!');
$("#jellyfin-verify-status").html('<i class="fa fa-check"></i>&nbsp; Login successfull!');
$('#jellyfin-verify-status').fadeIn('fast');
jellyfin_verified = true;
$("#jellyfin_valid").val("valid");
} else {
$("#jellyfin-verify-status").html('<i class="fa fa-exclamation-circle"></i>&nbsp; This is not a Plex Server!');
$("#jellyfin-verify-status").html('<i class="fa fa-exclamation-circle"></i>&nbsp; This is not a Jellyfin Server!');
$('#jellyfin-verify-status').fadeIn('fast');
}
}

View File

@@ -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)

View File

@@ -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
if self.token and self.url:
# TODO: Add token auth
pass
return False

View File

@@ -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,
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):
""" Get the JELLYFIN server identifier.
""" 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