Merge pull request #345 from oddstr13/pr-cleanup-1

A tiny bit of code cleanup
This commit is contained in:
mcarlton00 2020-08-02 09:31:32 -04:00 committed by GitHub
commit da21f49928
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 155 additions and 182 deletions

View file

@ -11,7 +11,7 @@ from dialogs import ServerConnect, UsersConnect, LoginManual, ServerManual
from helper import settings, addon_id, event, api, window
from jellyfin import Jellyfin
from jellyfin.connection_manager import CONNECTION_STATE
from jellyfin.exceptions import HTTPException
from helper.exceptions import HTTPException
from helper import LazyLogger
##################################################################################################

View file

@ -14,7 +14,7 @@ import requests
from helper import settings, stop, event, window, create_id
from jellyfin import Jellyfin
from jellyfin import api
from jellyfin.exceptions import HTTPException
from helper.exceptions import HTTPException
from helper import LazyLogger
#################################################################################################
@ -235,7 +235,7 @@ def get_songs_by_artist(artist_id, basic=False):
yield items
@stop()
@stop
def _get_items(query, server_id=None):
''' query = {

View file

@ -12,9 +12,10 @@ import downloader as server
import helper.xmls as xmls
from objects import Movies, TVShows, MusicVideos, Music
from database import Database, get_sync, save_sync, jellyfin_db
from helper import translate, settings, window, progress, dialog, LibraryException
from helper import translate, settings, window, progress, dialog
from helper.utils import get_screensaver, set_screensaver
from helper import LazyLogger
from helper.exceptions import LibraryException, PathValidationException
##################################################################################################
@ -239,14 +240,16 @@ class FullSync(object):
raise
except PathValidationException:
raise
except Exception as error:
dialog("ok", "{jellyfin}", translate(33119))
LOG.error("full sync exited unexpectedly")
LOG.exception(error)
if 'Failed to validate path' not in error:
dialog("ok", "{jellyfin}", translate(33119))
LOG.error("full sync exited unexpectedly")
save_sync(self.sync)
save_sync(self.sync)
raise

View file

@ -3,7 +3,6 @@ from __future__ import division, absolute_import, print_function, unicode_litera
from .lazylogger import LazyLogger
from .translate import translate
from .exceptions import LibraryException
from .utils import addon_id
from .utils import window
@ -26,8 +25,6 @@ from .utils import set_addon_mode
from .utils import get_filesystem_encoding
from .wrapper import progress
from .wrapper import catch
from .wrapper import silent_catch
from .wrapper import stop
from .wrapper import jellyfin_item
from .wrapper import library_check

View file

@ -4,7 +4,23 @@ from __future__ import division, absolute_import, print_function, unicode_litera
#################################################################################################
class HTTPException(Exception):
# Jellyfin HTTP exception
def __init__(self, status, message):
self.status = status
self.message = message
class LibraryException(Exception):
# Jellyfin library sync exception
def __init__(self, status):
self.status = status
class PathValidationException(Exception):
"""
Replacing generic `Exception`
TODO: Investigate the usage of this to see if it can be done better.
"""
pass

View file

@ -47,133 +47,90 @@ def progress(message=None):
return decorator
def catch(errors=(Exception,)):
def stop(func):
''' Wrapper to catch exceptions and return using catch
'''
def decorator(func):
def wrapper(*args, **kwargs):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except errors as error:
LOG.exception(error)
try:
if should_stop(): # ??? TODO: Fixme
raise Exception
raise Exception("Caught exception")
except Exception as error:
LOG.exception(error)
return wrapper
return decorator
raise LibraryException("StopCalled")
return func(*args, **kwargs)
return wrapper
def silent_catch(errors=(Exception,)):
''' Wrapper to catch exceptions and ignore them
'''
def decorator(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except errors as error:
LOG.error(error)
return wrapper
return decorator
def stop(default=None):
''' Wrapper to catch exceptions and return using catch
'''
def decorator(func):
def wrapper(*args, **kwargs):
try:
if should_stop(): # ??? TODO: Fixme
raise Exception
except Exception as error:
LOG.exception(error)
if default is not None:
return default
raise LibraryException("StopCalled")
return func(*args, **kwargs)
return wrapper
return decorator
def jellyfin_item():
def jellyfin_item(func):
''' Wrapper to retrieve the jellyfin_db item.
'''
def decorator(func):
def wrapper(self, item, *args, **kwargs):
e_item = self.jellyfin_db.get_item_by_id(item['Id'] if type(item) == dict else item)
def wrapper(self, item, *args, **kwargs):
e_item = self.jellyfin_db.get_item_by_id(item['Id'] if type(item) == dict else item)
return func(self, item, e_item=e_item, *args, **kwargs)
return func(self, item, e_item=e_item, *args, **kwargs)
return wrapper
return decorator
return wrapper
def library_check():
def library_check(func):
''' Wrapper to retrieve the library
'''
def decorator(func):
def wrapper(self, item, *args, **kwargs):
def wrapper(self, item, *args, **kwargs):
''' TODO: Rethink this one... songs and albums cannot be found by library. expensive.
'''
from database import get_sync
''' TODO: Rethink this one... songs and albums cannot be found by library. expensive.
'''
from database import get_sync
if kwargs.get('library') is None:
sync = get_sync()
if kwargs.get('library') is None:
sync = get_sync()
if 'e_item' in kwargs:
try:
view_id = kwargs['e_item'][6]
view_name = self.jellyfin_db.get_view_name(view_id)
view = {'Name': view_name, 'Id': view_id}
except Exception:
view = None
if 'e_item' in kwargs:
try:
view_id = kwargs['e_item'][6]
view_name = self.jellyfin_db.get_view_name(view_id)
view = {'Name': view_name, 'Id': view_id}
except Exception:
view = None
if view is None:
ancestors = self.server.jellyfin.get_ancestors(item['Id'])
if view is None:
ancestors = self.server.jellyfin.get_ancestors(item['Id'])
if not ancestors:
if item['Type'] == 'MusicArtist':
if not ancestors:
if item['Type'] == 'MusicArtist':
try:
views = self.jellyfin_db.get_views_by_media('music')[0]
except Exception as error:
LOG.exception(error)
return
view = {'Id': views[0], 'Name': views[1]}
else: # Grab the first music library
try:
views = self.jellyfin_db.get_views_by_media('music')[0]
except Exception as error:
LOG.exception(error)
return
else:
for ancestor in ancestors:
if ancestor['Type'] == 'CollectionFolder':
view = self.jellyfin_db.get_view_name(ancestor['Id'])
view = {'Id': None, 'Name': None} if view is None else {'Name': ancestor['Name'], 'Id': ancestor['Id']}
break
if view['Id'] not in [x.replace('Mixed:', "") for x in sync['Whitelist'] + sync['Libraries']]:
LOG.info("Library %s is not synced. Skip update.", view['Id'])
view = {'Id': views[0], 'Name': views[1]}
else: # Grab the first music library
return
else:
for ancestor in ancestors:
if ancestor['Type'] == 'CollectionFolder':
kwargs['library'] = view
view = self.jellyfin_db.get_view_name(ancestor['Id'])
view = {'Id': None, 'Name': None} if view is None else {'Name': ancestor['Name'], 'Id': ancestor['Id']}
return func(self, item, *args, **kwargs)
break
return wrapper
return decorator
if view['Id'] not in [x.replace('Mixed:', "") for x in sync['Whitelist'] + sync['Libraries']]:
LOG.info("Library %s is not synced. Skip update.", view['Id'])
return
kwargs['library'] = view
return func(self, item, *args, **kwargs)
return wrapper

View file

@ -1,11 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import division, absolute_import, print_function, unicode_literals
#################################################################################################
class HTTPException(Exception):
# Jellyfin HTTP exception
def __init__(self, status, message):
self.status = status
self.message = message

View file

@ -10,8 +10,7 @@ from six import string_types, ensure_str
from helper.utils import JsonDebugPrinter
from helper import LazyLogger
from .exceptions import HTTPException
from helper.exceptions import HTTPException
#################################################################################################

View file

@ -15,8 +15,9 @@ from database import Database, jellyfin_db, get_sync, save_sync
from full_sync import FullSync
from views import Views
from downloader import GetItemWorker
from helper import translate, api, stop, settings, window, dialog, event, LibraryException
from helper import translate, api, stop, settings, window, dialog, event
from helper.utils import split_list, set_screensaver, get_screensaver
from helper.exceptions import LibraryException
from jellyfin import Jellyfin
from helper import LazyLogger
@ -109,7 +110,7 @@ class Library(threading.Thread):
with Database('video'), Database('music'):
pass
@stop()
@stop
def service(self):
''' If error is encountered, it will rerun this function.

View file

@ -10,6 +10,7 @@ import downloader as server
from database import jellyfin_db, queries as QUEM
from helper import api, stop, validate, validate_bluray_dir, validate_dvd_dir, jellyfin_item, library_check, values, Local
from helper import LazyLogger
from helper.exceptions import PathValidationException
from .obj import Objects
from .kodi import Movies as KodiDb, queries as QU
@ -36,9 +37,9 @@ class Movies(KodiDb):
KodiDb.__init__(self, videodb.cursor)
@stop()
@jellyfin_item()
@library_check()
@stop
@jellyfin_item
@library_check
def movie(self, item, e_item, library):
''' If item does not exist, entry will be added.
@ -173,7 +174,7 @@ class Movies(KodiDb):
if self.direct_path:
if not validate(obj['Path']):
raise Exception("Failed to validate path. User stopped.")
raise PathValidationException("Failed to validate path. User stopped.")
obj['Path'] = obj['Path'].replace(obj['Filename'], "")
@ -199,8 +200,8 @@ class Movies(KodiDb):
}
obj['Filename'] = "%s?%s" % (obj['Path'], urlencode(params))
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def boxset(self, item, e_item):
''' If item does not exist, entry will be added.
@ -280,8 +281,8 @@ class Movies(KodiDb):
for boxset in boxsets:
self.remove(boxset[0])
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def userdata(self, item, e_item):
''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
@ -314,8 +315,8 @@ class Movies(KodiDb):
self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj))
LOG.debug("USERDATA movie [%s/%s] %s: %s", obj['FileId'], obj['MovieId'], obj['Id'], obj['Title'])
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def remove(self, item_id, e_item):
''' Remove movieid, fileid, jellyfin reference.

View file

@ -8,9 +8,11 @@ import datetime
from database import jellyfin_db, queries as QUEM
from helper import api, stop, validate, jellyfin_item, values, library_check, Local
from helper import LazyLogger
from helper.exceptions import PathValidationException
from .obj import Objects
from .kodi import Music as KodiDb, queries_music as QU
##################################################################################################
LOG = LazyLogger(__name__)
@ -33,9 +35,9 @@ class Music(KodiDb):
KodiDb.__init__(self, musicdb.cursor)
@stop()
@jellyfin_item()
@library_check()
@stop
@jellyfin_item
@library_check
def artist(self, item, e_item, library):
''' If item does not exist, entry will be added.
@ -101,8 +103,8 @@ class Music(KodiDb):
self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj))
LOG.debug("UPDATE artist [%s] %s: %s", obj['ArtistId'], obj['Name'], obj['Id'])
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def album(self, item, e_item):
''' Update object to kodi.
@ -207,9 +209,9 @@ class Music(KodiDb):
self.link(*values(temp_obj, QU.update_link_obj))
self.item_ids.append(temp_obj['Id'])
@stop()
@jellyfin_item()
@library_check()
@stop
@jellyfin_item
@library_check
def song(self, item, e_item, library):
''' Update object to kodi.
@ -325,7 +327,7 @@ class Music(KodiDb):
if self.direct_path:
if not validate(obj['Path']):
raise Exception("Failed to validate path. User stopped.")
raise PathValidationException("Failed to validate path. User stopped.")
obj['Path'] = obj['Path'].replace(obj['Filename'], "")
@ -400,8 +402,8 @@ class Music(KodiDb):
obj['AlbumId'] = self.create_entry_album()
self.add_single(*values(obj, QU.add_single_obj))
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def userdata(self, item, e_item):
''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
@ -429,8 +431,8 @@ class Music(KodiDb):
self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj))
LOG.debug("USERDATA %s [%s] %s: %s", obj['Media'], obj['KodiId'], obj['Id'], obj['Title'])
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def remove(self, item_id, e_item):
''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
@ -510,7 +512,7 @@ class Music(KodiDb):
self.delete_song(kodi_id)
LOG.debug("DELETE song [%s] %s", kodi_id, item_id)
@jellyfin_item()
@jellyfin_item
def get_child(self, item_id, e_item):
''' Get all child elements from tv show jellyfin id.

View file

@ -12,6 +12,7 @@ from kodi_six.utils import py2_encode
from database import jellyfin_db, queries as QUEM
from helper import api, stop, validate, library_check, jellyfin_item, values, Local
from helper import LazyLogger
from helper.exceptions import PathValidationException
from .obj import Objects
from .kodi import MusicVideos as KodiDb, queries as QU
@ -38,9 +39,9 @@ class MusicVideos(KodiDb):
KodiDb.__init__(self, videodb.cursor)
@stop()
@jellyfin_item()
@library_check()
@stop
@jellyfin_item
@library_check
def musicvideo(self, item, e_item, library):
''' If item does not exist, entry will be added.
@ -162,7 +163,7 @@ class MusicVideos(KodiDb):
if self.direct_path:
if not validate(obj['Path']):
raise Exception("Failed to validate path. User stopped.")
raise PathValidationException("Failed to validate path. User stopped.")
obj['Path'] = obj['Path'].replace(obj['Filename'], "")
@ -176,8 +177,8 @@ class MusicVideos(KodiDb):
}
obj['Filename'] = "%s?%s" % (obj['Path'], urlencode(params))
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def userdata(self, item, e_item):
''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
@ -209,8 +210,8 @@ class MusicVideos(KodiDb):
self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj))
LOG.debug("USERDATA mvideo [%s/%s] %s: %s", obj['FileId'], obj['MvideoId'], obj['Id'], obj['Title'])
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def remove(self, item_id, e_item):
''' Remove mvideoid, fileid, pathid, jellyfin reference.

View file

@ -13,6 +13,7 @@ import downloader as server
from database import jellyfin_db, queries as QUEM
from helper import api, stop, validate, jellyfin_item, library_check, values, Local
from helper import LazyLogger
from helper.exceptions import PathValidationException
from .obj import Objects
from .kodi import TVShows as KodiDb, queries as QU
@ -40,9 +41,9 @@ class TVShows(KodiDb):
KodiDb.__init__(self, videodb.cursor)
@stop()
@jellyfin_item()
@library_check()
@stop
@jellyfin_item
@library_check
def tvshow(self, item, e_item, library):
''' If item does not exist, entry will be added.
@ -195,12 +196,12 @@ class TVShows(KodiDb):
obj['TopLevel'] = "plugin://plugin.video.jellyfin/"
if not validate(obj['Path']):
raise Exception("Failed to validate path. User stopped.")
raise PathValidationException("Failed to validate path. User stopped.")
else:
obj['TopLevel'] = "plugin://plugin.video.jellyfin/%s/" % obj['LibraryId']
obj['Path'] = "%s%s/" % (obj['TopLevel'], obj['Id'])
@stop()
@stop
def season(self, item, show_id=None):
''' If item does not exist, entry will be added.
@ -218,8 +219,9 @@ class TVShows(KodiDb):
try:
obj['ShowId'] = self.jellyfin_db.get_item_by_id(*values(obj, QUEM.get_item_series_obj))[0]
except (KeyError, TypeError):
except (KeyError, TypeError) as error:
LOG.error("Unable to add series %s", obj['SeriesId'])
LOG.exception(error)
return False
@ -233,8 +235,8 @@ class TVShows(KodiDb):
self.artwork.add(obj['Artwork'], obj['SeasonId'], "season")
LOG.debug("UPDATE season [%s/%s] %s: %s", obj['ShowId'], obj['SeasonId'], obj['Title'] or obj['Index'], obj['Id'])
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def episode(self, item, e_item):
''' If item does not exist, entry will be added.
@ -390,7 +392,7 @@ class TVShows(KodiDb):
if self.direct_path:
if not validate(obj['Path']):
raise Exception("Failed to validate path. User stopped.")
raise PathValidationException("Failed to validate path. User stopped.")
obj['Path'] = obj['Path'].replace(obj['Filename'], "")
else:
@ -411,8 +413,9 @@ class TVShows(KodiDb):
try:
self.tvshow(self.server.jellyfin.get_item(obj['SeriesId']), library=None)
obj['ShowId'] = self.jellyfin_db.get_item_by_id(*values(obj, QUEM.get_item_series_obj))[0]
except (TypeError, KeyError):
except (TypeError, KeyError) as error:
LOG.error("Unable to add series %s", obj['SeriesId'])
LOG.exception(error)
return False
else:
@ -422,8 +425,8 @@ class TVShows(KodiDb):
return True
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def userdata(self, item, e_item):
''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
@ -483,8 +486,8 @@ class TVShows(KodiDb):
self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj))
LOG.debug("USERDATA %s [%s/%s] %s: %s", obj['Media'], obj['FileId'], obj['KodiId'], obj['Id'], obj['Title'])
@stop()
@jellyfin_item()
@stop
@jellyfin_item
def remove(self, item_id, e_item):
''' Remove showid, fileid, pathid, jellyfin reference.
@ -586,7 +589,7 @@ class TVShows(KodiDb):
self.delete_episode(kodi_id, file_id)
LOG.debug("DELETE episode [%s/%s] %s", file_id, kodi_id, item_id)
@jellyfin_item()
@jellyfin_item
def get_child(self, item_id, e_item):
''' Get all child elements from tv show jellyfin id.

View file

@ -8,7 +8,7 @@ import os
from kodi_six import xbmc, xbmcvfs
from objects.obj import Objects
from helper import translate, api, window, settings, dialog, event, silent_catch, JSONRPC
from helper import translate, api, window, settings, dialog, event, JSONRPC
from jellyfin import Jellyfin
from helper import LazyLogger
@ -27,13 +27,17 @@ class Player(xbmc.Player):
def __init__(self):
xbmc.Player.__init__(self)
@silent_catch()
def get_playing_file(self):
return self.getPlayingFile()
try:
return self.getPlayingFile()
except Exception as error:
LOG.exception(error)
@silent_catch()
def get_file_info(self, file):
return self.played[file]
try:
return self.played[file]
except Exception as error:
LOG.exception(error)
def is_playing_file(self, file):
return file in self.played