Prettify
This commit is contained in:
parent
ca8ad96a05
commit
ca11528593
6 changed files with 82 additions and 58 deletions
|
@ -12,7 +12,7 @@ from xbmc import sleep, executebuiltin, translatePath
|
||||||
from xbmcgui import ListItem
|
from xbmcgui import ListItem
|
||||||
|
|
||||||
from utils import window, settings, language as lang, dialog, try_encode, \
|
from utils import window, settings, language as lang, dialog, try_encode, \
|
||||||
CatchExceptions, exists_dir, plex_command, try_decode
|
catch_exceptions, exists_dir, plex_command, try_decode
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
|
||||||
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
|
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
|
||||||
|
@ -473,7 +473,7 @@ def getVideoFiles(plexId, params):
|
||||||
xbmcplugin.endOfDirectory(HANDLE)
|
xbmcplugin.endOfDirectory(HANDLE)
|
||||||
|
|
||||||
|
|
||||||
@CatchExceptions(warnuser=False)
|
@catch_exceptions(warnuser=False)
|
||||||
def getExtraFanArt(plexid, plexPath):
|
def getExtraFanArt(plexid, plexPath):
|
||||||
"""
|
"""
|
||||||
Get extrafanart for listitem
|
Get extrafanart for listitem
|
||||||
|
|
|
@ -6,7 +6,7 @@ from ntpath import dirname
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from artwork import Artwork
|
from artwork import Artwork
|
||||||
from utils import window, kodi_sql, CatchExceptions
|
from utils import window, kodi_sql, catch_exceptions
|
||||||
import plexdb_functions as plexdb
|
import plexdb_functions as plexdb
|
||||||
import kodidb_functions as kodidb
|
import kodidb_functions as kodidb
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ class Items(object):
|
||||||
self.kodiconn.close()
|
self.kodiconn.close()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@CatchExceptions(warnuser=True)
|
@catch_exceptions(warnuser=True)
|
||||||
def getfanart(self, plex_id, refresh=False):
|
def getfanart(self, plex_id, refresh=False):
|
||||||
"""
|
"""
|
||||||
Tries to get additional fanart for movies (+sets) and TV shows.
|
Tries to get additional fanart for movies (+sets) and TV shows.
|
||||||
|
@ -177,7 +177,7 @@ class Movies(Items):
|
||||||
"""
|
"""
|
||||||
Used for plex library-type movies
|
Used for plex library-type movies
|
||||||
"""
|
"""
|
||||||
@CatchExceptions(warnuser=True)
|
@catch_exceptions(warnuser=True)
|
||||||
def add_update(self, item, viewtag=None, viewid=None):
|
def add_update(self, item, viewtag=None, viewid=None):
|
||||||
"""
|
"""
|
||||||
Process single movie
|
Process single movie
|
||||||
|
@ -509,7 +509,7 @@ class TVShows(Items):
|
||||||
"""
|
"""
|
||||||
For Plex library-type TV shows
|
For Plex library-type TV shows
|
||||||
"""
|
"""
|
||||||
@CatchExceptions(warnuser=True)
|
@catch_exceptions(warnuser=True)
|
||||||
def add_update(self, item, viewtag=None, viewid=None):
|
def add_update(self, item, viewtag=None, viewid=None):
|
||||||
"""
|
"""
|
||||||
Process a single show
|
Process a single show
|
||||||
|
@ -742,7 +742,7 @@ class TVShows(Items):
|
||||||
tags.extend(collections)
|
tags.extend(collections)
|
||||||
self.kodi_db.addTags(showid, tags, "tvshow")
|
self.kodi_db.addTags(showid, tags, "tvshow")
|
||||||
|
|
||||||
@CatchExceptions(warnuser=True)
|
@catch_exceptions(warnuser=True)
|
||||||
def add_updateSeason(self, item, viewtag=None, viewid=None):
|
def add_updateSeason(self, item, viewtag=None, viewid=None):
|
||||||
"""
|
"""
|
||||||
Process a single season of a certain tv show
|
Process a single season of a certain tv show
|
||||||
|
@ -790,7 +790,7 @@ class TVShows(Items):
|
||||||
view_id=viewid,
|
view_id=viewid,
|
||||||
checksum=checksum)
|
checksum=checksum)
|
||||||
|
|
||||||
@CatchExceptions(warnuser=True)
|
@catch_exceptions(warnuser=True)
|
||||||
def add_updateEpisode(self, item, viewtag=None, viewid=None):
|
def add_updateEpisode(self, item, viewtag=None, viewid=None):
|
||||||
"""
|
"""
|
||||||
Process single episode
|
Process single episode
|
||||||
|
@ -1282,7 +1282,7 @@ class Music(Items):
|
||||||
self.kodi_db = kodidb.Kodidb_Functions(self.kodicursor)
|
self.kodi_db = kodidb.Kodidb_Functions(self.kodicursor)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@CatchExceptions(warnuser=True)
|
@catch_exceptions(warnuser=True)
|
||||||
def add_updateArtist(self, item, viewtag=None, viewid=None):
|
def add_updateArtist(self, item, viewtag=None, viewid=None):
|
||||||
"""
|
"""
|
||||||
Adds a single artist
|
Adds a single artist
|
||||||
|
@ -1368,7 +1368,7 @@ class Music(Items):
|
||||||
# Update artwork
|
# Update artwork
|
||||||
artwork.addArtwork(artworks, artistid, v.KODI_TYPE_ARTIST, kodicursor)
|
artwork.addArtwork(artworks, artistid, v.KODI_TYPE_ARTIST, kodicursor)
|
||||||
|
|
||||||
@CatchExceptions(warnuser=True)
|
@catch_exceptions(warnuser=True)
|
||||||
def add_updateAlbum(self, item, viewtag=None, viewid=None, children=None,
|
def add_updateAlbum(self, item, viewtag=None, viewid=None, children=None,
|
||||||
scan_children=True):
|
scan_children=True):
|
||||||
"""
|
"""
|
||||||
|
@ -1565,7 +1565,7 @@ class Music(Items):
|
||||||
for child in children:
|
for child in children:
|
||||||
self.add_updateSong(child, viewtag, viewid)
|
self.add_updateSong(child, viewtag, viewid)
|
||||||
|
|
||||||
@CatchExceptions(warnuser=True)
|
@catch_exceptions(warnuser=True)
|
||||||
def add_updateSong(self, item, viewtag=None, viewid=None):
|
def add_updateSong(self, item, viewtag=None, viewid=None):
|
||||||
"""
|
"""
|
||||||
Process single song
|
Process single song
|
||||||
|
|
|
@ -9,7 +9,7 @@ import xbmc
|
||||||
from xbmcvfs import exists
|
from xbmcvfs import exists
|
||||||
|
|
||||||
from utils import window, settings, unix_timestamp, thread_methods, \
|
from utils import window, settings, unix_timestamp, thread_methods, \
|
||||||
create_actor_db_index, dialog, LogTime, playlist_xsp, language as lang, \
|
create_actor_db_index, dialog, log_time, playlist_xsp, language as lang, \
|
||||||
unix_date_to_kodi, reset, try_decode, delete_playlists, delete_nodes, \
|
unix_date_to_kodi, reset, try_decode, delete_playlists, delete_nodes, \
|
||||||
try_encode, compare_version
|
try_encode, compare_version
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
@ -218,7 +218,7 @@ class LibrarySync(Thread):
|
||||||
# Create an index for actors to speed up sync
|
# Create an index for actors to speed up sync
|
||||||
create_actor_db_index()
|
create_actor_db_index()
|
||||||
|
|
||||||
@LogTime
|
@log_time
|
||||||
def fullSync(self, repair=False):
|
def fullSync(self, repair=False):
|
||||||
"""
|
"""
|
||||||
repair=True: force sync EVERY item
|
repair=True: force sync EVERY item
|
||||||
|
@ -727,7 +727,7 @@ class LibrarySync(Thread):
|
||||||
})
|
})
|
||||||
self.updatelist = []
|
self.updatelist = []
|
||||||
|
|
||||||
@LogTime
|
@log_time
|
||||||
def PlexMovies(self):
|
def PlexMovies(self):
|
||||||
# Initialize
|
# Initialize
|
||||||
self.allPlexElementsId = {}
|
self.allPlexElementsId = {}
|
||||||
|
@ -819,7 +819,7 @@ class LibrarySync(Thread):
|
||||||
with itemMth() as method:
|
with itemMth() as method:
|
||||||
method.updateUserdata(xml)
|
method.updateUserdata(xml)
|
||||||
|
|
||||||
@LogTime
|
@log_time
|
||||||
def PlexTVShows(self):
|
def PlexTVShows(self):
|
||||||
# Initialize
|
# Initialize
|
||||||
self.allPlexElementsId = {}
|
self.allPlexElementsId = {}
|
||||||
|
@ -949,7 +949,7 @@ class LibrarySync(Thread):
|
||||||
log.info("%s sync is finished." % itemType)
|
log.info("%s sync is finished." % itemType)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@LogTime
|
@log_time
|
||||||
def PlexMusic(self):
|
def PlexMusic(self):
|
||||||
itemType = 'Music'
|
itemType = 'Music'
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ from logging import getLogger
|
||||||
from threading import Thread, RLock
|
from threading import Thread, RLock
|
||||||
|
|
||||||
from downloadutils import DownloadUtils as DU
|
from downloadutils import DownloadUtils as DU
|
||||||
from utils import window, kodi_time_to_millis, Lock_Function
|
from utils import window, kodi_time_to_millis, LockFunction
|
||||||
import state
|
import state
|
||||||
import variables as v
|
import variables as v
|
||||||
import json_rpc as js
|
import json_rpc as js
|
||||||
|
@ -17,7 +17,7 @@ import playqueue as PQ
|
||||||
LOG = getLogger("PLEX." + __name__)
|
LOG = getLogger("PLEX." + __name__)
|
||||||
# Need to lock all methods and functions messing with subscribers or state
|
# Need to lock all methods and functions messing with subscribers or state
|
||||||
LOCK = RLock()
|
LOCK = RLock()
|
||||||
LOCKER = Lock_Function(LOCK)
|
LOCKER = LockFunction(LOCK)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
|
@ -242,20 +242,20 @@ def kodi_time_to_millis(time):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def try_encode(uniString, encoding='utf-8'):
|
def try_encode(input_str, encoding='utf-8'):
|
||||||
"""
|
"""
|
||||||
Will try to encode uniString (in unicode) to encoding. This possibly
|
Will try to encode input_str (in unicode) to encoding. This possibly
|
||||||
fails with e.g. Android TV's Python, which does not accept arguments for
|
fails with e.g. Android TV's Python, which does not accept arguments for
|
||||||
string.encode()
|
string.encode()
|
||||||
"""
|
"""
|
||||||
if isinstance(uniString, str):
|
if isinstance(input_str, str):
|
||||||
# already encoded
|
# already encoded
|
||||||
return uniString
|
return input_str
|
||||||
try:
|
try:
|
||||||
uniString = uniString.encode(encoding, "ignore")
|
input_str = input_str.encode(encoding, "ignore")
|
||||||
except TypeError:
|
except TypeError:
|
||||||
uniString = uniString.encode()
|
input_str = input_str.encode()
|
||||||
return uniString
|
return input_str
|
||||||
|
|
||||||
|
|
||||||
def try_decode(string, encoding='utf-8'):
|
def try_decode(string, encoding='utf-8'):
|
||||||
|
@ -878,10 +878,7 @@ def passwords_xml():
|
||||||
settings('networkCreds', value="%s" % server)
|
settings('networkCreds', value="%s" % server)
|
||||||
LOG.info("Added server: %s to passwords.xml", server)
|
LOG.info("Added server: %s to passwords.xml", server)
|
||||||
# Prettify and write to file
|
# Prettify and write to file
|
||||||
try:
|
indent(root)
|
||||||
indent(root)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
etree.ElementTree(root).write(xmlpath, encoding="UTF-8")
|
etree.ElementTree(root).write(xmlpath, encoding="UTF-8")
|
||||||
|
|
||||||
|
|
||||||
|
@ -957,7 +954,7 @@ def delete_nodes():
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# WRAPPERS
|
# WRAPPERS
|
||||||
|
|
||||||
def CatchExceptions(warnuser=False):
|
def catch_exceptions(warnuser=False):
|
||||||
"""
|
"""
|
||||||
Decorator for methods to catch exceptions and log them. Useful for e.g.
|
Decorator for methods to catch exceptions and log them. Useful for e.g.
|
||||||
librarysync threads using itemtypes.py, because otherwise we would not
|
librarysync threads using itemtypes.py, because otherwise we would not
|
||||||
|
@ -967,12 +964,18 @@ def CatchExceptions(warnuser=False):
|
||||||
which will trigger a Kodi infobox to inform user
|
which will trigger a Kodi infobox to inform user
|
||||||
"""
|
"""
|
||||||
def decorate(func):
|
def decorate(func):
|
||||||
|
"""
|
||||||
|
Decorator construct
|
||||||
|
"""
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
|
"""
|
||||||
|
Wrapper construct
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
except Exception as e:
|
except Exception as err:
|
||||||
LOG.error('%s has crashed. Error: %s', func.__name__, e)
|
LOG.error('%s has crashed. Error: %s', func.__name__, err)
|
||||||
import traceback
|
import traceback
|
||||||
LOG.error("Traceback:\n%s", traceback.format_exc())
|
LOG.error("Traceback:\n%s", traceback.format_exc())
|
||||||
if warnuser:
|
if warnuser:
|
||||||
|
@ -982,7 +985,7 @@ def CatchExceptions(warnuser=False):
|
||||||
return decorate
|
return decorate
|
||||||
|
|
||||||
|
|
||||||
def LogTime(func):
|
def log_time(func):
|
||||||
"""
|
"""
|
||||||
Decorator for functions and methods to log the time it took to run the code
|
Decorator for functions and methods to log the time it took to run the code
|
||||||
"""
|
"""
|
||||||
|
@ -1010,10 +1013,10 @@ def thread_methods(cls=None, add_stops=None, add_suspends=None):
|
||||||
ALSO returns True if PKC should exit
|
ALSO returns True if PKC should exit
|
||||||
|
|
||||||
Also adds the following class attributes:
|
Also adds the following class attributes:
|
||||||
__thread_stopped
|
thread_stopped
|
||||||
__thread_suspended
|
thread_suspended
|
||||||
__stops
|
stops
|
||||||
__suspends
|
suspends
|
||||||
|
|
||||||
invoke with either
|
invoke with either
|
||||||
@Newthread_methods
|
@Newthread_methods
|
||||||
|
@ -1030,41 +1033,56 @@ def thread_methods(cls=None, add_stops=None, add_suspends=None):
|
||||||
add_suspends=add_suspends)
|
add_suspends=add_suspends)
|
||||||
# Because we need a reference, not a copy of the immutable objects in
|
# Because we need a reference, not a copy of the immutable objects in
|
||||||
# state, we need to look up state every time explicitly
|
# state, we need to look up state every time explicitly
|
||||||
cls.__stops = ['STOP_PKC']
|
cls.stops = ['STOP_PKC']
|
||||||
if add_stops is not None:
|
if add_stops is not None:
|
||||||
cls.__stops.extend(add_stops)
|
cls.stops.extend(add_stops)
|
||||||
cls.__suspends = add_suspends or []
|
cls.suspends = add_suspends or []
|
||||||
|
|
||||||
# Attach new attributes to class
|
# Attach new attributes to class
|
||||||
cls.__thread_stopped = False
|
cls.thread_stopped = False
|
||||||
cls.__thread_suspended = False
|
cls.thread_suspended = False
|
||||||
|
|
||||||
# Define new class methods and attach them to class
|
# Define new class methods and attach them to class
|
||||||
def stop_thread(self):
|
def stop_thread(self):
|
||||||
self.__thread_stopped = True
|
"""
|
||||||
|
Call to stop this thread
|
||||||
|
"""
|
||||||
|
self.thread_stopped = True
|
||||||
cls.stop_thread = stop_thread
|
cls.stop_thread = stop_thread
|
||||||
|
|
||||||
def suspend_thread(self):
|
def suspend_thread(self):
|
||||||
self.__thread_suspended = True
|
"""
|
||||||
|
Call to suspend this thread
|
||||||
|
"""
|
||||||
|
self.thread_suspended = True
|
||||||
cls.suspend_thread = suspend_thread
|
cls.suspend_thread = suspend_thread
|
||||||
|
|
||||||
def resume_thread(self):
|
def resume_thread(self):
|
||||||
self.__thread_suspended = False
|
"""
|
||||||
|
Call to revive a suspended thread back to life
|
||||||
|
"""
|
||||||
|
self.thread_suspended = False
|
||||||
cls.resume_thread = resume_thread
|
cls.resume_thread = resume_thread
|
||||||
|
|
||||||
def thread_suspended(self):
|
def thread_suspended(self):
|
||||||
if self.__thread_suspended is True:
|
"""
|
||||||
|
Returns True if the thread is suspended
|
||||||
|
"""
|
||||||
|
if self.thread_suspended is True:
|
||||||
return True
|
return True
|
||||||
for suspend in self.__suspends:
|
for suspend in self.suspends:
|
||||||
if getattr(state, suspend):
|
if getattr(state, suspend):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
cls.thread_suspended = thread_suspended
|
cls.thread_suspended = thread_suspended
|
||||||
|
|
||||||
def thread_stopped(self):
|
def thread_stopped(self):
|
||||||
if self.__thread_stopped is True:
|
"""
|
||||||
|
Returns True if the thread is stopped
|
||||||
|
"""
|
||||||
|
if self.thread_stopped is True:
|
||||||
return True
|
return True
|
||||||
for stop in self.__stops:
|
for stop in self.stops:
|
||||||
if getattr(state, stop):
|
if getattr(state, stop):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -1074,12 +1092,12 @@ def thread_methods(cls=None, add_stops=None, add_suspends=None):
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
class Lock_Function(object):
|
class LockFunction(object):
|
||||||
"""
|
"""
|
||||||
Decorator for class methods and functions to lock them with lock.
|
Decorator for class methods and functions to lock them with lock.
|
||||||
|
|
||||||
Initialize this class first
|
Initialize this class first
|
||||||
lockfunction = Lock_Function(lock), where lock is a threading.Lock() object
|
lockfunction = LockFunction(lock), where lock is a threading.Lock() object
|
||||||
|
|
||||||
To then lock a function or method:
|
To then lock a function or method:
|
||||||
|
|
||||||
|
@ -1090,8 +1108,14 @@ class Lock_Function(object):
|
||||||
self.lock = lock
|
self.lock = lock
|
||||||
|
|
||||||
def lockthis(self, func):
|
def lockthis(self, func):
|
||||||
|
"""
|
||||||
|
Use this method to actually lock a function or method
|
||||||
|
"""
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
|
"""
|
||||||
|
Wrapper construct
|
||||||
|
"""
|
||||||
with self.lock:
|
with self.lock:
|
||||||
result = func(*args, **kwargs)
|
result = func(*args, **kwargs)
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -213,8 +213,8 @@ class Alexa_Websocket(WebSocket):
|
||||||
|
|
||||||
Can't use thread_methods!
|
Can't use thread_methods!
|
||||||
"""
|
"""
|
||||||
__thread_stopped = False
|
thread_stopped = False
|
||||||
__thread_suspended = False
|
thread_suspended = False
|
||||||
|
|
||||||
def getUri(self):
|
def getUri(self):
|
||||||
uri = ('wss://pubsub.plex.tv/sub/websockets/%s/%s?X-Plex-Token=%s'
|
uri = ('wss://pubsub.plex.tv/sub/websockets/%s/%s?X-Plex-Token=%s'
|
||||||
|
@ -256,16 +256,16 @@ class Alexa_Websocket(WebSocket):
|
||||||
|
|
||||||
# Path in thread_methods
|
# Path in thread_methods
|
||||||
def stop_thread(self):
|
def stop_thread(self):
|
||||||
self.__thread_stopped = True
|
self.thread_stopped = True
|
||||||
|
|
||||||
def suspend_thread(self):
|
def suspend_thread(self):
|
||||||
self.__thread_suspended = True
|
self.thread_suspended = True
|
||||||
|
|
||||||
def resume_thread(self):
|
def resume_thread(self):
|
||||||
self.__thread_suspended = False
|
self.thread_suspended = False
|
||||||
|
|
||||||
def thread_stopped(self):
|
def thread_stopped(self):
|
||||||
if self.__thread_stopped is True:
|
if self.thread_stopped is True:
|
||||||
return True
|
return True
|
||||||
if state.STOP_PKC:
|
if state.STOP_PKC:
|
||||||
return True
|
return True
|
||||||
|
@ -276,7 +276,7 @@ class Alexa_Websocket(WebSocket):
|
||||||
"""
|
"""
|
||||||
Overwrite method since we need to check for plex token
|
Overwrite method since we need to check for plex token
|
||||||
"""
|
"""
|
||||||
if self.__thread_suspended is True:
|
if self.thread_suspended is True:
|
||||||
return True
|
return True
|
||||||
if not state.PLEX_TOKEN:
|
if not state.PLEX_TOKEN:
|
||||||
return True
|
return True
|
||||||
|
|
Loading…
Add table
Reference in a new issue