mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-04-08 11:42:08 +00:00
Merge pull request #38 from oddstr13/pr-logging-1
Greatly increase the amount of logging information.
This commit is contained in:
commit
e72a124e31
33 changed files with 723 additions and 636 deletions
25
.editorconfig
Normal file
25
.editorconfig
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# With more recent updates Visual Studio 2017 supports EditorConfig files out of the box
|
||||||
|
# Visual Studio Code needs an extension: https://github.com/editorconfig/editorconfig-vscode
|
||||||
|
# For emacs, vim, np++ and other editors, see here: https://github.com/editorconfig
|
||||||
|
###############################
|
||||||
|
# Core EditorConfig Options #
|
||||||
|
###############################
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# All files
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
end_of_line = lf
|
||||||
|
max_line_length = null
|
||||||
|
|
||||||
|
# YAML indentation
|
||||||
|
[*.{yml,yaml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# XML indentation
|
||||||
|
[*.xml]
|
||||||
|
indent_size = 2
|
|
@ -138,6 +138,7 @@ class Database(object):
|
||||||
try:
|
try:
|
||||||
loaded = self._get_database(databases[file]) if file in databases else file
|
loaded = self._get_database(databases[file]) if file in databases else file
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
for i in range(1, 10):
|
for i in range(1, 10):
|
||||||
alt_file = "%s-%s" % (file, i)
|
alt_file = "%s-%s" % (file, i)
|
||||||
|
@ -150,8 +151,8 @@ class Database(object):
|
||||||
loaded = None
|
loaded = None
|
||||||
|
|
||||||
break
|
break
|
||||||
except Exception:
|
except Exception as error:
|
||||||
pass
|
LOG.exception(error)
|
||||||
|
|
||||||
if discovered and discovered != loaded:
|
if discovered and discovered != loaded:
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||||
|
|
||||||
class JellyfinDatabase():
|
class JellyfinDatabase():
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, cursor):
|
def __init__(self, cursor):
|
||||||
self.cursor = cursor
|
self.cursor = cursor
|
||||||
|
|
||||||
|
@ -105,7 +104,6 @@ class JellyfinDatabase():
|
||||||
def remove_wild_item(self, item_id):
|
def remove_wild_item(self, item_id):
|
||||||
self.cursor.execute(QU.delete_item_by_wild, (item_id + "%",))
|
self.cursor.execute(QU.delete_item_by_wild, (item_id + "%",))
|
||||||
|
|
||||||
|
|
||||||
def get_view_name(self, item_id):
|
def get_view_name(self, item_id):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -113,6 +111,7 @@ class JellyfinDatabase():
|
||||||
|
|
||||||
return self.cursor.fetchone()[0]
|
return self.cursor.fetchone()[0]
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_view(self, *args):
|
def get_view(self, *args):
|
||||||
|
@ -159,7 +158,6 @@ class JellyfinDatabase():
|
||||||
self.cursor.execute(QU.get_version)
|
self.cursor.execute(QU.get_version)
|
||||||
version = self.cursor.fetchone()[0]
|
version = self.cursor.fetchone()[0]
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
pass
|
LOG.exception(error)
|
||||||
|
|
||||||
return version
|
return version
|
||||||
|
|
|
@ -73,7 +73,8 @@ def validate_view(library_id, item_id):
|
||||||
'Recursive': True,
|
'Recursive': True,
|
||||||
'Ids': item_id
|
'Ids': item_id
|
||||||
})
|
})
|
||||||
except Exception:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True if len(result['Items']) else False
|
return True if len(result['Items']) else False
|
||||||
|
@ -257,7 +258,7 @@ def _get_items(query, server_id=None):
|
||||||
items['TotalRecordCount'] = _get(url, test_params, server_id=server_id)['TotalRecordCount']
|
items['TotalRecordCount'] = _get(url, test_params, server_id=server_id)['TotalRecordCount']
|
||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error("Failed to retrieve the server response %s: %s params:%s", url, error, params)
|
LOG.exception("Failed to retrieve the server response %s: %s params:%s", url, error, params)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
index = params.get('StartIndex', 0)
|
index = params.get('StartIndex', 0)
|
||||||
|
@ -397,8 +398,6 @@ def get_objects(src, filename):
|
||||||
|
|
||||||
LOG.error(error)
|
LOG.error(error)
|
||||||
response = requests.get(src, stream=True, verify=False)
|
response = requests.get(src, stream=True, verify=False)
|
||||||
except Exception:
|
|
||||||
raise
|
|
||||||
|
|
||||||
dl = xbmcvfs.File(path, 'w')
|
dl = xbmcvfs.File(path, 'w')
|
||||||
dl.write(response.content)
|
dl.write(response.content)
|
||||||
|
|
|
@ -76,7 +76,7 @@ class Service(xbmc.Monitor):
|
||||||
try:
|
try:
|
||||||
Views().get_nodes()
|
Views().get_nodes()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
window('jellyfin.connected.bool', True)
|
window('jellyfin.connected.bool', True)
|
||||||
settings('groupedSets.bool', objects.utils.get_grouped_set())
|
settings('groupedSets.bool', objects.utils.get_grouped_set())
|
||||||
|
@ -137,7 +137,7 @@ class Service(xbmc.Monitor):
|
||||||
self.connect.register()
|
self.connect.register()
|
||||||
setup.Setup()
|
setup.Setup()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
def stop_default(self):
|
def stop_default(self):
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ class Service(xbmc.Monitor):
|
||||||
try:
|
try:
|
||||||
self.connect.register()
|
self.connect.register()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
elif method == 'GUI.OnScreensaverDeactivated':
|
elif method == 'GUI.OnScreensaverDeactivated':
|
||||||
|
|
||||||
|
|
|
@ -248,8 +248,9 @@ class FullSync(object):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
if not 'Failed to validate path' in error:
|
if 'Failed to validate path' not in error:
|
||||||
|
|
||||||
dialog("ok", heading="{jellyfin}", line1=_(33119))
|
dialog("ok", heading="{jellyfin}", line1=_(33119))
|
||||||
LOG.error("full sync exited unexpectedly")
|
LOG.error("full sync exited unexpectedly")
|
||||||
|
|
|
@ -1,16 +1,27 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
##################################################################################################
|
##################################################################################################
|
||||||
|
|
||||||
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
import traceback
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
|
import xbmcaddon
|
||||||
import database
|
import database
|
||||||
|
|
||||||
from . import window, settings
|
from . import window, settings
|
||||||
|
|
||||||
##################################################################################################
|
##################################################################################################
|
||||||
|
|
||||||
|
__addon__ = xbmcaddon.Addon(id='plugin.video.jellyfin')
|
||||||
|
__pluginpath__ = xbmc.translatePath(__addon__.getAddonInfo('path').decode('utf-8'))
|
||||||
|
|
||||||
|
##################################################################################################
|
||||||
|
|
||||||
|
|
||||||
def config():
|
def config():
|
||||||
|
|
||||||
|
@ -18,6 +29,7 @@ def config():
|
||||||
logger.addHandler(LogHandler())
|
logger.addHandler(LogHandler())
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
def reset():
|
def reset():
|
||||||
|
|
||||||
for handler in logging.getLogger('JELLYFIN').handlers:
|
for handler in logging.getLogger('JELLYFIN').handlers:
|
||||||
|
@ -59,7 +71,7 @@ class LogHandler(logging.StreamHandler):
|
||||||
string = string.replace(server.encode('utf-8') or "{server}", "{jellyfin-server}")
|
string = string.replace(server.encode('utf-8') or "{server}", "{jellyfin-server}")
|
||||||
|
|
||||||
for token in self.sensitive['Token']:
|
for token in self.sensitive['Token']:
|
||||||
string = string.replace(token.encode('utf-8') or "{token}", "{jellyfin-token}")
|
string = string.replace(token.encode('utf-8') or "{token}", "{jellyfin-token}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xbmc.log(string, level=xbmc.LOGNOTICE)
|
xbmc.log(string, level=xbmc.LOGNOTICE)
|
||||||
|
@ -95,9 +107,10 @@ class MyFormatter(logging.Formatter):
|
||||||
# when the logger formatter was instantiated
|
# when the logger formatter was instantiated
|
||||||
format_orig = self._fmt
|
format_orig = self._fmt
|
||||||
|
|
||||||
|
self._gen_rel_path(record)
|
||||||
|
|
||||||
# Replace the original format with one customized by logging level
|
# Replace the original format with one customized by logging level
|
||||||
if record.levelno in (logging.DEBUG, logging.ERROR):
|
self._fmt = '%(name)s -> %(levelname)s::%(relpath)s:%(lineno)s %(message)s'
|
||||||
self._fmt = '%(name)s -> %(levelname)s:: %(message)s'
|
|
||||||
|
|
||||||
# Call the original formatter class to do the grunt work
|
# Call the original formatter class to do the grunt work
|
||||||
result = logging.Formatter.format(self, record)
|
result = logging.Formatter.format(self, record)
|
||||||
|
@ -106,3 +119,23 @@ class MyFormatter(logging.Formatter):
|
||||||
self._fmt = format_orig
|
self._fmt = format_orig
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def formatException(self, exc_info):
|
||||||
|
_pluginpath_real = os.path.realpath(__pluginpath__)
|
||||||
|
res = []
|
||||||
|
|
||||||
|
for o in traceback.format_exception(*exc_info):
|
||||||
|
if o.startswith(' File "'):
|
||||||
|
# If this split can't handle your file names, you should seriously consider renaming your files.
|
||||||
|
fn = o.split(' File "', 2)[1].split('", line ', 1)[0]
|
||||||
|
rfn = os.path.realpath(fn)
|
||||||
|
if rfn.startswith(_pluginpath_real):
|
||||||
|
o = o.replace(fn, os.path.relpath(rfn, _pluginpath_real))
|
||||||
|
|
||||||
|
res.append(o)
|
||||||
|
|
||||||
|
return ''.join(res)
|
||||||
|
|
||||||
|
def _gen_rel_path(self, record):
|
||||||
|
if record.pathname:
|
||||||
|
record.relpath = os.path.relpath(record.pathname, __pluginpath__)
|
||||||
|
|
|
@ -484,7 +484,7 @@ class PlayUtils(object):
|
||||||
try:
|
try:
|
||||||
subs.append(self.download_external_subs(url, filename))
|
subs.append(self.download_external_subs(url, filename))
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
subs.append(url)
|
subs.append(url)
|
||||||
else:
|
else:
|
||||||
subs.append(url)
|
subs.append(url)
|
||||||
|
@ -512,7 +512,8 @@ class PlayUtils(object):
|
||||||
try:
|
try:
|
||||||
response = requests.get(src, stream=True, verify=False)
|
response = requests.get(src, stream=True, verify=False)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except Exception as e:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
response.encoding = 'utf-8'
|
response.encoding = 'utf-8'
|
||||||
|
|
|
@ -266,7 +266,8 @@ def indent(elem, level=0):
|
||||||
else:
|
else:
|
||||||
if level and (not elem.tail or not elem.tail.strip()):
|
if level and (not elem.tail or not elem.tail.strip()):
|
||||||
elem.tail = i
|
elem.tail = i
|
||||||
except Exception:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
return
|
return
|
||||||
|
|
||||||
def write_xml(content, file):
|
def write_xml(content, file):
|
||||||
|
@ -447,6 +448,6 @@ def convert_to_local(date):
|
||||||
|
|
||||||
return date.strftime('%Y-%m-%dT%H:%M:%S')
|
return date.strftime('%Y-%m-%dT%H:%M:%S')
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
return str(date)
|
return str(date)
|
||||||
|
|
|
@ -84,10 +84,11 @@ def stop(default=None):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if should_stop():
|
if should_stop(): # ??? TODO: Fixme
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
if default is not None:
|
if default is not None:
|
||||||
return default
|
return default
|
||||||
|
@ -142,7 +143,8 @@ def library_check():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
views = self.jellyfin_db.get_views_by_media('music')[0]
|
views = self.jellyfin_db.get_views_by_media('music')[0]
|
||||||
except Exception:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
return
|
return
|
||||||
|
|
||||||
view = {'Id': views[0], 'Name': views[1]}
|
view = {'Id': views[0], 'Name': views[1]}
|
||||||
|
|
|
@ -112,6 +112,7 @@ class Jellyfin(object):
|
||||||
|
|
||||||
@ensure_client()
|
@ensure_client()
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
LOG.debug("__getitem__(%r)", key)
|
||||||
return self.client[self.server_id][key]
|
return self.client[self.server_id][key]
|
||||||
|
|
||||||
def construct(self):
|
def construct(self):
|
||||||
|
@ -123,4 +124,5 @@ class Jellyfin(object):
|
||||||
else:
|
else:
|
||||||
LOG.info("---[ START JELLYFINCLIENT: %s ]---", self.server_id)
|
LOG.info("---[ START JELLYFINCLIENT: %s ]---", self.server_id)
|
||||||
|
|
||||||
|
|
||||||
config()
|
config()
|
|
@ -83,6 +83,7 @@ class JellyfinClient(object):
|
||||||
self.http.stop_session()
|
self.http.stop_session()
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
LOG.debug("__getitem__(%r)", key)
|
||||||
|
|
||||||
if key.startswith('config'):
|
if key.startswith('config'):
|
||||||
return self.config[key.replace('config/', "", 1)] if "/" in key else self.config
|
return self.config[key.replace('config/', "", 1)] if "/" in key else self.config
|
||||||
|
|
|
@ -334,6 +334,3 @@ class API(object):
|
||||||
return self._delete("Videos/ActiveEncodings", params={
|
return self._delete("Videos/ActiveEncodings", params={
|
||||||
'DeviceId': device_id
|
'DeviceId': device_id
|
||||||
})
|
})
|
||||||
|
|
||||||
def delete_item(self, item_id):
|
|
||||||
return self.items("/%s" % item_id, "DELETE")
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ LOG = logging.getLogger('JELLYFIN.'+__name__)
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -25,6 +26,7 @@ class Config(object):
|
||||||
self.http()
|
self.http()
|
||||||
|
|
||||||
def __shortcuts__(self, key):
|
def __shortcuts__(self, key):
|
||||||
|
LOG.debug("__shortcuts__(%r)", key)
|
||||||
|
|
||||||
if key == "auth":
|
if key == "auth":
|
||||||
return self.auth
|
return self.auth
|
||||||
|
@ -38,13 +40,13 @@ class Config(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
LOG.debug("__getitem__(%r)", key)
|
||||||
return self.data.get(key, self.__shortcuts__(key))
|
return self.data.get(key, self.__shortcuts__(key))
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
self.data[key] = value
|
self.data[key] = value
|
||||||
|
|
||||||
def app(self, name, version, device_name, device_id, capabilities=None, device_pixel_ratio=None):
|
def app(self, name, version, device_name, device_id, capabilities=None, device_pixel_ratio=None):
|
||||||
|
|
||||||
LOG.info("Begin app constructor.")
|
LOG.info("Begin app constructor.")
|
||||||
|
|
||||||
self.data['app.name'] = name
|
self.data['app.name'] = name
|
||||||
|
|
|
@ -60,6 +60,7 @@ class ConnectionManager(object):
|
||||||
self.http = HTTP(client)
|
self.http = HTTP(client)
|
||||||
|
|
||||||
def __shortcuts__(self, key):
|
def __shortcuts__(self, key):
|
||||||
|
LOG.debug("__shortcuts__(%r)", key)
|
||||||
|
|
||||||
if key == "clear":
|
if key == "clear":
|
||||||
return self.clear_data
|
return self.clear_data
|
||||||
|
@ -97,6 +98,7 @@ class ConnectionManager(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
LOG.debug("__getitem__(%r)", key)
|
||||||
return self.__shortcuts__(key)
|
return self.__shortcuts__(key)
|
||||||
|
|
||||||
def clear_data(self):
|
def clear_data(self):
|
||||||
|
@ -163,8 +165,8 @@ class ConnectionManager(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
result = self._request_url(request, False)
|
result = self._request_url(request, False)
|
||||||
except Exception as error: # Failed to login
|
except Exception as error: # Failed to login
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self._on_authenticated(result, options)
|
self._on_authenticated(result, options)
|
||||||
|
@ -184,7 +186,8 @@ class ConnectionManager(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
public_info = self._try_connect(address, options=options)
|
public_info = self._try_connect(address, options=options)
|
||||||
except Exception:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
return _on_fail()
|
return _on_fail()
|
||||||
else:
|
else:
|
||||||
LOG.info("connectToAddress %s succeeded", address)
|
LOG.info("connectToAddress %s succeeded", address)
|
||||||
|
@ -258,7 +261,7 @@ class ConnectionManager(object):
|
||||||
try:
|
try:
|
||||||
return self.http.request(request)
|
return self.http.request(request)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def _add_app_info(self):
|
def _add_app_info(self):
|
||||||
|
@ -352,7 +355,7 @@ class ConnectionManager(object):
|
||||||
result = self._try_connect(address, timeout, options)
|
result = self._try_connect(address, timeout, options)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.error("test failed for connection mode %s with server %s", mode, server.get('Name'))
|
LOG.exception("test failed for connection mode %s with server %s", mode, server.get('Name'))
|
||||||
|
|
||||||
if enable_retry:
|
if enable_retry:
|
||||||
# TODO: wake on lan and retry
|
# TODO: wake on lan and retry
|
||||||
|
@ -428,7 +431,7 @@ class ConnectionManager(object):
|
||||||
try:
|
try:
|
||||||
sock.sendto(MESSAGE, MULTI_GROUP)
|
sock.sendto(MESSAGE, MULTI_GROUP)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
return servers
|
return servers
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -441,7 +444,7 @@ class ConnectionManager(object):
|
||||||
return servers
|
return servers
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error("Error trying to find servers: %s", e)
|
LOG.exception("Error trying to find servers: %s", e)
|
||||||
return servers
|
return servers
|
||||||
|
|
||||||
def _get_last_used_server(self):
|
def _get_last_used_server(self):
|
||||||
|
@ -579,6 +582,7 @@ class ConnectionManager(object):
|
||||||
})
|
})
|
||||||
self._update_server_info(server, system_info)
|
self._update_server_info(server, system_info)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
server['UserId'] = None
|
server['UserId'] = None
|
||||||
server['AccessToken'] = None
|
server['AccessToken'] = None
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Credentials(object):
|
||||||
if not isinstance(self.credentials, dict):
|
if not isinstance(self.credentials, dict):
|
||||||
raise ValueError("invalid credentials format")
|
raise ValueError("invalid credentials format")
|
||||||
|
|
||||||
except Exception as e: # File is either empty or missing
|
except Exception as e: # File is either empty or missing
|
||||||
LOG.warn(e)
|
LOG.warn(e)
|
||||||
self.credentials = {}
|
self.credentials = {}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ LOG = logging.getLogger('Jellyfin.'+__name__)
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
|
||||||
class HTTP(object):
|
class HTTP(object):
|
||||||
|
|
||||||
session = None
|
session = None
|
||||||
|
@ -26,6 +27,7 @@ class HTTP(object):
|
||||||
self.config = client['config']
|
self.config = client['config']
|
||||||
|
|
||||||
def __shortcuts__(self, key):
|
def __shortcuts__(self, key):
|
||||||
|
LOG.debug("__shortcuts__(%r)", key)
|
||||||
|
|
||||||
if key == "request":
|
if key == "request":
|
||||||
return self.request
|
return self.request
|
||||||
|
@ -90,7 +92,7 @@ class HTTP(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = self._requests(session or self.session or requests, data.pop('type', "GET"), **data)
|
r = self._requests(session or self.session or requests, data.pop('type', "GET"), **data)
|
||||||
r.content # release the connection
|
r.content # release the connection
|
||||||
|
|
||||||
if not self.keep_alive and self.session is not None:
|
if not self.keep_alive and self.session is not None:
|
||||||
self.stop_session()
|
self.stop_session()
|
||||||
|
@ -137,7 +139,7 @@ class HTTP(object):
|
||||||
|
|
||||||
raise HTTPException("Unauthorized", error)
|
raise HTTPException("Unauthorized", error)
|
||||||
|
|
||||||
elif r.status_code == 500: # log and ignore.
|
elif r.status_code == 500: # log and ignore.
|
||||||
LOG.error("--[ 500 response ] %s", error)
|
LOG.error("--[ 500 response ] %s", error)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -214,7 +216,7 @@ class HTTP(object):
|
||||||
|
|
||||||
def _authorization(self, data):
|
def _authorization(self, data):
|
||||||
|
|
||||||
auth = "MediaBrowser "
|
auth = "MediaBrowser "
|
||||||
auth += "Client=%s, " % self.config['app.name'].encode('utf-8')
|
auth += "Client=%s, " % self.config['app.name'].encode('utf-8')
|
||||||
auth += "Device=%s, " % self.config['app.device_name'].encode('utf-8')
|
auth += "Device=%s, " % self.config['app.device_name'].encode('utf-8')
|
||||||
auth += "DeviceId=%s, " % self.config['app.device_id'].encode('utf-8')
|
auth += "DeviceId=%s, " % self.config['app.device_id'].encode('utf-8')
|
||||||
|
|
|
@ -31,6 +31,7 @@ class WSClient(threading.Thread):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
def __shortcuts__(self, key):
|
def __shortcuts__(self, key):
|
||||||
|
LOG.debug("__shortcuts__(%r)", key)
|
||||||
|
|
||||||
if key == "send":
|
if key == "send":
|
||||||
return self.send
|
return self.send
|
||||||
|
|
|
@ -746,6 +746,7 @@ class WebSocket(object):
|
||||||
except socket.timeout as e:
|
except socket.timeout as e:
|
||||||
raise WebSocketTimeoutException(e.args[0])
|
raise WebSocketTimeoutException(e.args[0])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logger.exception(e)
|
||||||
if "timed out" in e.args[0]:
|
if "timed out" in e.args[0]:
|
||||||
raise WebSocketTimeoutException(e.args[0])
|
raise WebSocketTimeoutException(e.args[0])
|
||||||
else:
|
else:
|
||||||
|
@ -893,12 +894,13 @@ class WebSocketApp(object):
|
||||||
break
|
break
|
||||||
self._callback(self.on_message, data)
|
self._callback(self.on_message, data)
|
||||||
|
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
#print str(e.args[0])
|
|
||||||
if "timed out" not in e.args[0]:
|
if "timed out" not in e.args[0]:
|
||||||
|
logger.exception(e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
|
logger.exception(e)
|
||||||
self._callback(self.on_error, e)
|
self._callback(self.on_error, e)
|
||||||
finally:
|
finally:
|
||||||
if thread:
|
if thread:
|
||||||
|
@ -911,11 +913,8 @@ class WebSocketApp(object):
|
||||||
if callback:
|
if callback:
|
||||||
try:
|
try:
|
||||||
callback(self, *args)
|
callback(self, *args)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
logger.error(e)
|
logger.exception(e)
|
||||||
if True:#logger.isEnabledFor(logging.DEBUG):
|
|
||||||
_, _, tb = sys.exc_info()
|
|
||||||
traceback.print_tb(tb)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -334,7 +334,7 @@ class Library(threading.Thread):
|
||||||
|
|
||||||
Views().get_nodes()
|
Views().get_nodes()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
elif not settings('SyncInstallRunDone.bool'):
|
elif not settings('SyncInstallRunDone.bool'):
|
||||||
|
|
||||||
|
@ -459,7 +459,7 @@ class Library(threading.Thread):
|
||||||
time_now = datetime.strptime(self.server['config/server-time'].split(', ', 1)[1], '%d %b %Y %H:%M:%S GMT') - timedelta(minutes=2)
|
time_now = datetime.strptime(self.server['config/server-time'].split(', ', 1)[1], '%d %b %Y %H:%M:%S GMT') - timedelta(minutes=2)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
time_now = datetime.utcnow() - timedelta(minutes=2)
|
time_now = datetime.utcnow() - timedelta(minutes=2)
|
||||||
|
|
||||||
last_sync = time_now.strftime('%Y-%m-%dT%H:%M:%Sz')
|
last_sync = time_now.strftime('%Y-%m-%dT%H:%M:%Sz')
|
||||||
|
@ -703,7 +703,9 @@ class SortWorker(threading.Thread):
|
||||||
try:
|
try:
|
||||||
media = database.get_media_by_id(item_id)
|
media = database.get_media_by_id(item_id)
|
||||||
self.output[media].put({'Id': item_id, 'Type': media})
|
self.output[media].put({'Id': item_id, 'Type': media})
|
||||||
except Exception:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
items = database.get_media_by_parent_id(item_id)
|
items = database.get_media_by_parent_id(item_id)
|
||||||
|
|
||||||
if not items:
|
if not items:
|
||||||
|
|
|
@ -113,13 +113,14 @@ class Monitor(xbmc.Monitor):
|
||||||
self.server_instance(data['ServerId'])
|
self.server_instance(data['ServerId'])
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
dialog("ok", heading="{jellyfin}", line1=_(33142))
|
dialog("ok", heading="{jellyfin}", line1=_(33142))
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
server = Jellyfin(data['ServerId'])
|
server = Jellyfin(data['ServerId'])
|
||||||
except Exception:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
server = Jellyfin()
|
server = Jellyfin()
|
||||||
|
|
||||||
if method == 'GetItem':
|
if method == 'GetItem':
|
||||||
|
@ -328,7 +329,7 @@ class Monitor(xbmc.Monitor):
|
||||||
try:
|
try:
|
||||||
session = server['api'].get_device(self.device_id)
|
session = server['api'].get_device(self.device_id)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -765,7 +765,7 @@ def on_play(data, server):
|
||||||
try:
|
try:
|
||||||
file = player.getPlayingFile()
|
file = player.getPlayingFile()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -211,8 +211,8 @@ class GetArtworkWorker(threading.Thread):
|
||||||
prep.url = "http://%s:%s/image/image://%s" % (self.kodi['host'], self.kodi['port'], url)
|
prep.url = "http://%s:%s/image/image://%s" % (self.kodi['host'], self.kodi['port'], url)
|
||||||
s.send(prep, timeout=(0.01, 0.01))
|
s.send(prep, timeout=(0.01, 0.01))
|
||||||
s.content # release the connection
|
s.content # release the connection
|
||||||
except Exception:
|
except Exception as error:
|
||||||
pass
|
LOG.exception(error)
|
||||||
|
|
||||||
self.queue.task_done()
|
self.queue.task_done()
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ class Movies(KodiDb):
|
||||||
KodiDb.__init__(self, videodb.cursor)
|
KodiDb.__init__(self, videodb.cursor)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
LOG.debug("__getitem__(%r)", key)
|
||||||
|
|
||||||
if key == 'Movie':
|
if key == 'Movie':
|
||||||
return self.movie
|
return self.movie
|
||||||
|
@ -175,7 +176,7 @@ class Movies(KodiDb):
|
||||||
obj['Trailer'] = "plugin://plugin.video.youtube/play/?video_id=%s" % obj['Trailer'].rsplit('=', 1)[1]
|
obj['Trailer'] = "plugin://plugin.video.youtube/play/?video_id=%s" % obj['Trailer'].rsplit('=', 1)[1]
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
|
||||||
LOG.error("Failed to get trailer: %s", error)
|
LOG.exception("Failed to get trailer: %s", error)
|
||||||
obj['Trailer'] = None
|
obj['Trailer'] = None
|
||||||
|
|
||||||
def get_path_filename(self, obj):
|
def get_path_filename(self, obj):
|
||||||
|
|
|
@ -35,6 +35,7 @@ class Music(KodiDb):
|
||||||
KodiDb.__init__(self, musicdb.cursor)
|
KodiDb.__init__(self, musicdb.cursor)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
LOG.debug("__getitem__(%r)", key)
|
||||||
|
|
||||||
if key in ('MusicArtist', 'AlbumArtist'):
|
if key in ('MusicArtist', 'AlbumArtist'):
|
||||||
return self.artist
|
return self.artist
|
||||||
|
@ -219,7 +220,7 @@ class Music(KodiDb):
|
||||||
self.artist(self.server['api'].get_item(temp_obj['Id']), library=None)
|
self.artist(self.server['api'].get_item(temp_obj['Id']), library=None)
|
||||||
temp_obj['ArtistId'] = self.jellyfin_db.get_item_by_id(*values(temp_obj, QUEM.get_item_obj))[0]
|
temp_obj['ArtistId'] = self.jellyfin_db.get_item_by_id(*values(temp_obj, QUEM.get_item_obj))[0]
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.update_artist_name(*values(temp_obj, QU.update_artist_name_obj))
|
self.update_artist_name(*values(temp_obj, QU.update_artist_name_obj))
|
||||||
|
@ -375,7 +376,7 @@ class Music(KodiDb):
|
||||||
self.artist(self.server['api'].get_item(temp_obj['Id']), library=None)
|
self.artist(self.server['api'].get_item(temp_obj['Id']), library=None)
|
||||||
temp_obj['ArtistId'] = self.jellyfin_db.get_item_by_id(*values(temp_obj, QUEM.get_item_obj))[0]
|
temp_obj['ArtistId'] = self.jellyfin_db.get_item_by_id(*values(temp_obj, QUEM.get_item_obj))[0]
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.link(*values(temp_obj, QU.update_link_obj))
|
self.link(*values(temp_obj, QU.update_link_obj))
|
||||||
|
@ -409,7 +410,7 @@ class Music(KodiDb):
|
||||||
self.artist(self.server['api'].get_item(temp_obj['Id']), library=None)
|
self.artist(self.server['api'].get_item(temp_obj['Id']), library=None)
|
||||||
temp_obj['ArtistId'] = self.jellyfin_db.get_item_by_id(*values(temp_obj, QUEM.get_item_obj))[0]
|
temp_obj['ArtistId'] = self.jellyfin_db.get_item_by_id(*values(temp_obj, QUEM.get_item_obj))[0]
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.link_song_artist(*values(temp_obj, QU.update_song_artist_obj))
|
self.link_song_artist(*values(temp_obj, QU.update_song_artist_obj))
|
||||||
|
|
|
@ -35,6 +35,7 @@ class MusicVideos(KodiDb):
|
||||||
KodiDb.__init__(self, videodb.cursor)
|
KodiDb.__init__(self, videodb.cursor)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
LOG.debug("__getitem__(%r)", key)
|
||||||
|
|
||||||
if key == 'MusicVideo':
|
if key == 'MusicVideo':
|
||||||
return self.musicvideo
|
return self.musicvideo
|
||||||
|
|
|
@ -38,6 +38,7 @@ class TVShows(KodiDb):
|
||||||
KodiDb.__init__(self, videodb.cursor)
|
KodiDb.__init__(self, videodb.cursor)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
|
LOG.debug("__getitem__(%r)", key)
|
||||||
|
|
||||||
if key == 'Series':
|
if key == 'Series':
|
||||||
return self.tvshow
|
return self.tvshow
|
||||||
|
|
|
@ -12,6 +12,7 @@ LOG = logging.getLogger("JELLYFIN."+__name__)
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
|
||||||
def get_play_action():
|
def get_play_action():
|
||||||
|
|
||||||
''' I could not figure out a way to listen to kodi setting changes?
|
''' I could not figure out a way to listen to kodi setting changes?
|
||||||
|
@ -22,16 +23,14 @@ def get_play_action():
|
||||||
try:
|
try:
|
||||||
return options[result['result']['value']]
|
return options[result['result']['value']]
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
log.error("Returning play action due to error: %s", error)
|
LOG.exception("Returning play action due to error: %s", error)
|
||||||
|
|
||||||
return options[1]
|
return options[1]
|
||||||
|
|
||||||
|
|
||||||
def get_grouped_set():
|
def get_grouped_set():
|
||||||
|
|
||||||
''' Get if boxsets should be grouped
|
''' Get if boxsets should be grouped
|
||||||
'''
|
'''
|
||||||
result = JSONRPC('Settings.GetSettingValue').execute({'setting': "videolibrary.groupmoviesets"})
|
result = JSONRPC('Settings.GetSettingValue').execute({'setting': "videolibrary.groupmoviesets"})
|
||||||
try:
|
return result.get('result', {}).get('value', False)
|
||||||
return result['result']['value']
|
|
||||||
except Exception as error:
|
|
||||||
return False
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
seektime = self.getTime()
|
seektime = self.getTime()
|
||||||
except Exception: # at this point we should be playing and if not then bail out
|
except Exception: # at this point we should be playing and if not then bail out
|
||||||
return
|
return
|
||||||
|
|
||||||
result = JSONRPC('Application.GetProperties').execute({'properties': ["volume", "muted"]})
|
result = JSONRPC('Application.GetProperties').execute({'properties': ["volume", "muted"]})
|
||||||
|
@ -193,22 +193,22 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
'playerid': 1,
|
'playerid': 1,
|
||||||
'properties': ["currentsubtitle","currentaudiostream","subtitleenabled"]
|
'properties': ["currentsubtitle", "currentaudiostream", "subtitleenabled"]
|
||||||
}
|
}
|
||||||
result = JSONRPC('Player.GetProperties').execute(params)
|
result = JSONRPC('Player.GetProperties').execute(params)
|
||||||
result = result.get('result')
|
result = result.get('result')
|
||||||
|
|
||||||
try: # Audio tracks
|
try: # Audio tracks
|
||||||
audio = result['currentaudiostream']['index']
|
audio = result['currentaudiostream']['index']
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
audio = 0
|
audio = 0
|
||||||
|
|
||||||
try: # Subtitles tracks
|
try: # Subtitles tracks
|
||||||
subs = result['currentsubtitle']['index']
|
subs = result['currentsubtitle']['index']
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
subs = 0
|
subs = 0
|
||||||
|
|
||||||
try: # If subtitles are enabled
|
try: # If subtitles are enabled
|
||||||
subs_enabled = result['subtitleenabled']
|
subs_enabled = result['subtitleenabled']
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
subs_enabled = False
|
subs_enabled = False
|
||||||
|
|
|
@ -118,6 +118,7 @@ def verify_kodi_defaults():
|
||||||
src=xbmc.translatePath("special://xbmc/system/library/video").decode('utf-8'),
|
src=xbmc.translatePath("special://xbmc/system/library/video").decode('utf-8'),
|
||||||
dst=xbmc.translatePath("special://profile/library/video").decode('utf-8'))
|
dst=xbmc.translatePath("special://profile/library/video").decode('utf-8'))
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.warning(error)
|
||||||
xbmcvfs.mkdir(node_path)
|
xbmcvfs.mkdir(node_path)
|
||||||
|
|
||||||
for index, node in enumerate(['movies', 'tvshows', 'musicvideos']):
|
for index, node in enumerate(['movies', 'tvshows', 'musicvideos']):
|
||||||
|
@ -169,6 +170,7 @@ class Views(object):
|
||||||
libraries = self.server['api'].get_media_folders()['Items']
|
libraries = self.server['api'].get_media_folders()['Items']
|
||||||
views = self.server['api'].get_views()['Items']
|
views = self.server['api'].get_views()['Items']
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
raise IndexError("Unable to retrieve libraries: %s" % error)
|
raise IndexError("Unable to retrieve libraries: %s" % error)
|
||||||
|
|
||||||
libraries.extend([x for x in views if x['Id'] not in [y['Id'] for y in libraries]])
|
libraries.extend([x for x in views if x['Id'] not in [y['Id'] for y in libraries]])
|
||||||
|
@ -188,7 +190,7 @@ class Views(object):
|
||||||
try:
|
try:
|
||||||
libraries = self.get_libraries()
|
libraries = self.get_libraries()
|
||||||
except IndexError as error:
|
except IndexError as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -273,6 +275,7 @@ class Views(object):
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
xml = etree.parse(file).getroot()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
LOG.warning("Unable to parse file '%s'", file)
|
||||||
xml = etree.Element('smartplaylist', {'type': view['Media']})
|
xml = etree.Element('smartplaylist', {'type': view['Media']})
|
||||||
etree.SubElement(xml, 'name')
|
etree.SubElement(xml, 'name')
|
||||||
etree.SubElement(xml, 'match')
|
etree.SubElement(xml, 'match')
|
||||||
|
@ -316,6 +319,7 @@ class Views(object):
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
xml = etree.parse(file).getroot()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
LOG.warning("Unable to parse file '%s'", file)
|
||||||
xml = self.node_root('folder' if item_type == 'favorites' and view['Media'] == 'episodes' else 'filter', index)
|
xml = self.node_root('folder' if item_type == 'favorites' and view['Media'] == 'episodes' else 'filter', index)
|
||||||
etree.SubElement(xml, 'label')
|
etree.SubElement(xml, 'label')
|
||||||
etree.SubElement(xml, 'match')
|
etree.SubElement(xml, 'match')
|
||||||
|
@ -371,7 +375,8 @@ class Views(object):
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
xml = etree.parse(file).getroot()
|
||||||
xml.set('order', str(index))
|
xml.set('order', str(index))
|
||||||
except Exception:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
xml = self.node_root('main', index)
|
xml = self.node_root('main', index)
|
||||||
etree.SubElement(xml, 'label')
|
etree.SubElement(xml, 'label')
|
||||||
|
|
||||||
|
@ -410,6 +415,7 @@ class Views(object):
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
xml = etree.parse(file).getroot()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
LOG.warning("Unable to parse file '%s'", file)
|
||||||
xml = self.node_root('filter', index)
|
xml = self.node_root('filter', index)
|
||||||
etree.SubElement(xml, 'label')
|
etree.SubElement(xml, 'label')
|
||||||
etree.SubElement(xml, 'match')
|
etree.SubElement(xml, 'match')
|
||||||
|
@ -441,6 +447,7 @@ class Views(object):
|
||||||
try:
|
try:
|
||||||
xml = etree.parse(file).getroot()
|
xml = etree.parse(file).getroot()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
LOG.warning("Unable to parse file '%s'", file)
|
||||||
xml = self.node_root('folder', index)
|
xml = self.node_root('folder', index)
|
||||||
etree.SubElement(xml, 'label')
|
etree.SubElement(xml, 'label')
|
||||||
etree.SubElement(xml, 'content')
|
etree.SubElement(xml, 'content')
|
||||||
|
@ -692,7 +699,7 @@ class Views(object):
|
||||||
try:
|
try:
|
||||||
self.media_folders = self.get_libraries()
|
self.media_folders = self.get_libraries()
|
||||||
except IndexError as error:
|
except IndexError as error:
|
||||||
LOG.error(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
for library in (libraries or []):
|
for library in (libraries or []):
|
||||||
view = {'Id': library[0], 'Name': library[1], 'Tag': library[1], 'Media': library[2]}
|
view = {'Id': library[0], 'Name': library[1], 'Tag': library[1], 'Media': library[2]}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class WebService(threading.Thread):
|
||||||
conn.request("QUIT", "/")
|
conn.request("QUIT", "/")
|
||||||
conn.getresponse()
|
conn.getresponse()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
pass
|
LOG.exception(error)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class WebService(threading.Thread):
|
||||||
server.serve_forever()
|
server.serve_forever()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
|
||||||
if '10053' not in error: # ignore host diconnected errors
|
if '10053' not in error: # ignore host diconnected errors
|
||||||
LOG.exception(error)
|
LOG.exception(error)
|
||||||
|
|
||||||
LOG.info("---<[ webservice ]")
|
LOG.info("---<[ webservice ]")
|
||||||
|
@ -132,13 +132,13 @@ class requestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||||
self.wfile.write(path)
|
self.wfile.write(path)
|
||||||
|
|
||||||
except IndexError as error:
|
except IndexError as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
xbmc.log(str(error), xbmc.LOGWARNING)
|
|
||||||
self.send_error(404, "Exception occurred: %s" % error)
|
self.send_error(404, "Exception occurred: %s" % error)
|
||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
xbmc.log(str(error), xbmc.LOGWARNING)
|
|
||||||
self.send_error(500, "Exception occurred: %s" % error)
|
self.send_error(500, "Exception occurred: %s" % error)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -64,10 +64,11 @@ class ServiceManager(threading.Thread):
|
||||||
|
|
||||||
service.service()
|
service.service()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
if service is not None:
|
if service is not None:
|
||||||
|
|
||||||
if not 'ExitService' in error:
|
if 'ExitService' not in error:
|
||||||
service.shutdown()
|
service.shutdown()
|
||||||
|
|
||||||
if 'RestartService' in error:
|
if 'RestartService' in error:
|
||||||
|
@ -91,7 +92,7 @@ if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
session = ServiceManager()
|
session = ServiceManager()
|
||||||
session.start()
|
session.start()
|
||||||
session.join() # Block until the thread exits.
|
session.join() # Block until the thread exits.
|
||||||
|
|
||||||
if 'RestartService' in session.exception:
|
if 'RestartService' in session.exception:
|
||||||
continue
|
continue
|
||||||
|
|
4
tox.ini
Normal file
4
tox.ini
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[flake8]
|
||||||
|
max-line-length = 9999
|
||||||
|
import-order-style = pep8
|
||||||
|
exclude = ./.git,./.vscode,./libraries
|
Loading…
Add table
Reference in a new issue