diff --git a/contextmenu.py b/contextmenu.py index 15663fe6..08efa137 100644 --- a/contextmenu.py +++ b/contextmenu.py @@ -109,7 +109,7 @@ class ContextMenu(object): def _select_menu(self): # Display select dialog - userdata = self.api.getUserData() + userdata = self.api.get_userdata() options = [] if userdata['Favorite']: @@ -178,7 +178,7 @@ class ContextMenu(object): new_value = 5 if settings('enableUpdateSongRating') == "true": - musicutils.updateRatingToFile(new_value, self.api.getFilePath()) + musicutils.updateRatingToFile(new_value, self.api.get_file_path()) query = "UPDATE song SET rating = ? WHERE idSong = ?" cursor.execute(query, (new_value, self.kodi_id,)) diff --git a/default.py b/default.py index 44a818e0..ba611fe6 100644 --- a/default.py +++ b/default.py @@ -70,7 +70,7 @@ class Main(object): elif mode == 'texturecache': import artwork - artwork.Artwork().fullTextureCacheSync() + artwork.Artwork().texture_cache_sync() else: entrypoint.doMainListing() @@ -136,7 +136,7 @@ class Main(object): dialog(type_="ok", heading="{emby}", line1=lang(33034)) - log.warn("Not connected to the emby server.") + log.warn("Not connected to the emby server") elif window('emby_dbScan') != "true": import librarysync @@ -149,7 +149,7 @@ class Main(object): else: library_sync.fullSync(repair=True) else: - log.warn("Database scan is already running.") + log.warn("Database scan is already running") if __name__ == "__main__": diff --git a/resources/lib/api.py b/resources/lib/api.py index 0d7332b5..1c5a1ca1 100644 --- a/resources/lib/api.py +++ b/resources/lib/api.py @@ -14,45 +14,42 @@ log = logging.getLogger("EMBY."+__name__) ################################################################################################## -class API(): +class API(object): def __init__(self, item): - # item is the api response self.item = item - def getUserData(self): + def get_userdata(self): # Default favorite = False likes = None playcount = None played = False - lastPlayedDate = None + last_played = None resume = 0 - userrating = 0 + user_rating = 0 try: userdata = self.item['UserData'] - except KeyError: # No userdata found. pass - else: favorite = userdata['IsFavorite'] likes = userdata.get('Likes') # Userrating is based on likes and favourite if favorite: - userrating = 5 + user_rating = 5 elif likes: - userrating = 3 - elif likes == False: - userrating = 0 + user_rating = 3 + elif likes is False: + user_rating = 0 else: - userrating = 1 + user_rating = 1 - lastPlayedDate = userdata.get('LastPlayedDate') - if lastPlayedDate: - lastPlayedDate = lastPlayedDate.split('.')[0].replace('T', " ") + last_played = userdata.get('LastPlayedDate') + if last_played: + last_played = last_played.split('.')[0].replace('T', " ") if userdata['Played']: # Playcount is tied to the watch status @@ -61,12 +58,12 @@ class API(): if playcount == 0: playcount = 1 - if lastPlayedDate is None: - lastPlayedDate = self.getDateCreated() + if last_played is None: + last_played = self.get_date_created() - playbackPosition = userdata.get('PlaybackPositionTicks') - if playbackPosition: - resume = playbackPosition / 10000000.0 + playback_position = userdata.get('PlaybackPositionTicks') + if playback_position: + resume = playback_position / 10000000.0 return { @@ -74,12 +71,12 @@ class API(): 'Likes': likes, 'PlayCount': playcount, 'Played': played, - 'LastPlayedDate': lastPlayedDate, + 'LastPlayedDate': last_played, 'Resume': resume, - 'UserRating': userrating + 'UserRating': user_rating } - def getPeople(self): + def get_people(self): # Process People director = [] writer = [] @@ -87,21 +84,19 @@ class API(): try: people = self.item['People'] - except KeyError: pass - else: for person in people: - type = person['Type'] + type_ = person['Type'] name = person['Name'] - if "Director" in type: + if type_ == 'Director': director.append(name) - elif "Actor" in type: + elif type_ == 'Actor': cast.append(name) - elif type in ("Writing", "Writer"): + elif type_ in ('Writing', 'Writer'): writer.append(name) return { @@ -111,101 +106,115 @@ class API(): 'Cast': cast } - def getMediaStreams(self): - videotracks = [] - audiotracks = [] - subtitlelanguages = [] + def get_media_streams(self): + + video_tracks = [] + audio_tracks = [] + subtitle_languages = [] try: media_streams = self.item['MediaSources'][0]['MediaStreams'] except KeyError: - if not self.item.get("MediaStreams"): return None + if not self.item.get("MediaStreams"): + return None media_streams = self.item['MediaStreams'] for media_stream in media_streams: # Sort through Video, Audio, Subtitle stream_type = media_stream['Type'] - codec = media_stream.get('Codec', "").lower() - profile = media_stream.get('Profile', "").lower() if stream_type == "Video": - # Height, Width, Codec, AspectRatio, AspectFloat, 3D - track = { - - 'codec': codec, - 'height': media_stream.get('Height'), - 'width': media_stream.get('Width'), - 'video3DFormat': self.item.get('Video3DFormat'), - 'aspect': 1.85 - } - - try: - container = self.item['MediaSources'][0]['Container'].lower() - except: - container = "" - - # Sort codec vs container/profile - if "msmpeg4" in codec: - track['codec'] = "divx" - elif "mpeg4" in codec: - if "simple profile" in profile or not profile: - track['codec'] = "xvid" - elif "h264" in codec: - if container in ("mp4", "mov", "m4v"): - track['codec'] = "avc1" - - # Aspect ratio - if self.item.get('AspectRatio'): - # Metadata AR - aspect = self.item['AspectRatio'] - else: # File AR - aspect = media_stream.get('AspectRatio', "0") - - try: - aspectwidth, aspectheight = aspect.split(':') - track['aspect'] = round(float(aspectwidth) / float(aspectheight), 6) - - except (ValueError, ZeroDivisionError): - width = track.get('width') - height = track.get('height') - - if width and height: - track['aspect'] = round(float(width / height), 6) - else: - track['aspect'] = 1.85 - - if self.item.get("RunTimeTicks"): - track['duration'] = self.item.get("RunTimeTicks") / 10000000.0 - - videotracks.append(track) + self._video_stream(video_tracks, media_stream) elif stream_type == "Audio": - # Codec, Channels, language - track = { - - 'codec': codec, - 'channels': media_stream.get('Channels'), - 'language': media_stream.get('Language') - } - - if "dca" in codec and "dts-hd ma" in profile: - track['codec'] = "dtshd_ma" - - audiotracks.append(track) + self._audio_stream(audio_tracks, media_stream) elif stream_type == "Subtitle": - # Language - subtitlelanguages.append(media_stream.get('Language', "Unknown")) + subtitle_languages.append(media_stream.get('Language', "Unknown")) return { - 'video': videotracks, - 'audio': audiotracks, - 'subtitle': subtitlelanguages + 'video': video_tracks, + 'audio': audio_tracks, + 'subtitle': subtitle_languages } - def getRuntime(self): + def _video_stream(self, video_tracks, stream): + + codec = stream.get('Codec', "").lower() + profile = stream.get('Profile', "").lower() + + # Height, Width, Codec, AspectRatio, AspectFloat, 3D + track = { + + 'codec': codec, + 'height': stream.get('Height'), + 'width': stream.get('Width'), + 'video3DFormat': self.item.get('Video3DFormat'), + 'aspect': 1.85 + } + + try: + container = self.item['MediaSources'][0]['Container'].lower() + except Exception: + container = "" + + # Sort codec vs container/profile + if "msmpeg4" in codec: + track['codec'] = "divx" + elif "mpeg4" in codec: + if "simple profile" in profile or not profile: + track['codec'] = "xvid" + elif "h264" in codec: + if container in ("mp4", "mov", "m4v"): + track['codec'] = "avc1" + + # Aspect ratio + if 'AspectRatio' in self.item: + # Metadata AR + aspect = self.item['AspectRatio'] + else: # File AR + aspect = stream.get('AspectRatio', "0") + + try: + aspect_width, aspect_height = aspect.split(':') + track['aspect'] = round(float(aspect_width) / float(aspect_height), 6) + + except (ValueError, ZeroDivisionError): + + width = track.get('width') + height = track.get('height') + + if width and height: + track['aspect'] = round(float(width / height), 6) + else: + track['aspect'] = 1.85 + + if 'RunTimeTicks' in self.item: + track['duration'] = self.get_runtime() + + video_tracks.append(track) + + def _audio_stream(self, audio_tracks, stream): + + codec = stream.get('Codec', "").lower() + profile = stream.get('Profile', "").lower() + # Codec, Channels, language + track = { + + 'codec': codec, + 'channels': stream.get('Channels'), + 'language': stream.get('Language') + } + + if "dca" in codec and "dts-hd ma" in profile: + track['codec'] = "dtshd_ma" + + audio_tracks.append(track) + + def get_runtime(self): + try: runtime = self.item['RunTimeTicks'] / 10000000.0 @@ -214,7 +223,8 @@ class API(): return runtime - def adjustResume(self, resume_seconds): + @classmethod + def adjust_resume(cls, resume_seconds): resume = 0 if resume_seconds: @@ -226,24 +236,23 @@ class API(): return resume - def getStudios(self): + def get_studios(self): # Process Studios studios = [] - try: studio = self.item['SeriesStudio'] - studios.append(self.verifyStudio(studio)) + studios.append(self.verify_studio(studio)) except KeyError: - studioList = self.item['Studios'] - for studio in studioList: + for studio in self.item['Studios']: name = studio['Name'] - studios.append(self.verifyStudio(name)) + studios.append(self.verify_studio(name)) return studios - def verifyStudio(self, studioName): + @classmethod + def verify_studio(cls, studio_name): # Convert studio for Kodi to properly detect them studios = { @@ -254,9 +263,9 @@ class API(): 'wgn america': "WGN" } - return studios.get(studioName.lower(), studioName) + return studios.get(studio_name.lower(), studio_name) - def getChecksum(self): + def get_checksum(self): # Use the etags checksum and userdata userdata = self.item['UserData'] @@ -265,7 +274,7 @@ class API(): self.item['Etag'], userdata['Played'], userdata['IsFavorite'], - userdata.get('Likes',''), + userdata.get('Likes', ""), userdata['PlaybackPositionTicks'], userdata.get('UnplayedItemCount', ""), userdata.get('LastPlayedDate', "") @@ -273,7 +282,7 @@ class API(): return checksum - def getGenres(self): + def get_genres(self): all_genres = "" genres = self.item.get('Genres', self.item.get('SeriesGenres')) @@ -282,17 +291,17 @@ class API(): return all_genres - def getDateCreated(self): + def get_date_created(self): try: - dateadded = self.item['DateCreated'] - dateadded = dateadded.split('.')[0].replace('T', " ") + date_added = self.item['DateCreated'] + date_added = date_added.split('.')[0].replace('T', " ") except KeyError: - dateadded = None + date_added = None - return dateadded + return date_added - def getPremiereDate(self): + def get_premiere_date(self): try: premiere = self.item['PremiereDate'] @@ -302,7 +311,7 @@ class API(): return premiere - def getOverview(self): + def get_overview(self): try: overview = self.item['Overview'] @@ -314,7 +323,7 @@ class API(): return overview - def getTagline(self): + def get_tagline(self): try: tagline = self.item['Taglines'][0] @@ -323,16 +332,16 @@ class API(): return tagline - def getProvider(self, providername): + def get_provider(self, name): try: - provider = self.item['ProviderIds'][providername] + provider = self.item['ProviderIds'][name] except KeyError: provider = None return provider - def getMpaa(self): + def get_mpaa(self): # Convert more complex cases mpaa = self.item.get('OfficialRating', "") @@ -342,7 +351,7 @@ class API(): return mpaa - def getCountry(self): + def get_country(self): try: country = self.item['ProductionLocations'][0] @@ -351,7 +360,7 @@ class API(): return country - def getFilePath(self): + def get_file_path(self): try: filepath = self.item['Path'] diff --git a/resources/lib/artwork.py b/resources/lib/artwork.py index 28ace1fa..146425d9 100644 --- a/resources/lib/artwork.py +++ b/resources/lib/artwork.py @@ -2,9 +2,7 @@ ################################################################################################# -import json import logging -import requests import os import urllib from sqlite3 import OperationalError @@ -12,9 +10,10 @@ from sqlite3 import OperationalError import xbmc import xbmcgui import xbmcvfs +import requests import image_cache_thread -from utils import window, settings, language as lang, kodiSQL +from utils import window, settings, dialog, language as lang, kodiSQL, JSONRPC ################################################################################################## @@ -23,58 +22,54 @@ log = logging.getLogger("EMBY."+__name__) ################################################################################################## -class Artwork(): +class Artwork(object): xbmc_host = 'localhost' xbmc_port = None xbmc_username = None xbmc_password = None - imageCacheThreads = [] - imageCacheLimitThreads = 0 + image_cache_threads = [] + image_cache_limit = 0 def __init__(self): - self.enableTextureCache = settings('enableTextureCache') == "true" - self.imageCacheLimitThreads = int(settings('imageCacheLimit')) - self.imageCacheLimitThreads = int(self.imageCacheLimitThreads * 5) - log.info("Using Image Cache Thread Count: %s" % self.imageCacheLimitThreads) + self.enable_texture_cache = settings('enableTextureCache') == "true" + self.image_cache_limit = int(settings('imageCacheLimit')) * 5 + log.info("image cache thread count: %s", self.image_cache_limit) - if not self.xbmc_port and self.enableTextureCache: - self.setKodiWebServerDetails() + if not self.xbmc_port and self.enable_texture_cache: + self._set_webserver_details() - self.userId = window('emby_currUser') - self.server = window('emby_server%s' % self.userId) + self.user_id = window('emby_currUser') + self.server = window('emby_server%s' % self.user_id) - def double_urlencode(self, text): - text = self.single_urlencode(text) - text = self.single_urlencode(text) + def _double_urlencode(self, text): + + text = self._single_urlencode(text) + text = self._single_urlencode(text) return text - def single_urlencode(self, text): + @classmethod + def _single_urlencode(cls, text): # urlencode needs a utf- string - text = urllib.urlencode({'blahblahblah':text.encode("utf-8")}) + text = urllib.urlencode({'blahblahblah': text.encode('utf-8')}) text = text[13:] - return text.decode("utf-8") #return the result again as unicode + return text.decode('utf-8') #return the result again as unicode - def setKodiWebServerDetails(self): + def _set_webserver_details(self): # Get the Kodi webserver details - used to set the texture cache + get_setting_value = JSONRPC('Settings.GetSettingValue') + web_query = { - "jsonrpc": "2.0", - "id": 1, - "method": "Settings.GetSettingValue", - "params": { - - "setting": "services.webserver" - } + "setting": "services.webserver" } - result = xbmc.executeJSONRPC(json.dumps(web_query)) - result = json.loads(result) + result = get_setting_value.execute(web_query) try: xbmc_webserver_enabled = result['result']['value'] except (KeyError, TypeError): @@ -82,48 +77,30 @@ class Artwork(): if not xbmc_webserver_enabled: # Enable the webserver, it is disabled + set_setting_value = JSONRPC('Settings.SetSettingValue') + web_port = { - "jsonrpc": "2.0", - "id": 1, - "method": "Settings.SetSettingValue", - "params": { - - "setting": "services.webserverport", - "value": 8080 - } + "setting": "services.webserverport", + "value": 8080 } - result = xbmc.executeJSONRPC(json.dumps(web_port)) + set_setting_value.execute(web_port) self.xbmc_port = 8080 web_user = { - "jsonrpc": "2.0", - "id": 1, - "method": "Settings.SetSettingValue", - "params": { - - "setting": "services.webserver", - "value": True - } + "setting": "services.webserver", + "value": True } - result = xbmc.executeJSONRPC(json.dumps(web_user)) + set_setting_value.execute(web_user) self.xbmc_username = "kodi" - # Webserver already enabled web_port = { - "jsonrpc": "2.0", - "id": 1, - "method": "Settings.GetSettingValue", - "params": { - - "setting": "services.webserverport" - } + "setting": "services.webserverport" } - result = xbmc.executeJSONRPC(json.dumps(web_port)) - result = json.loads(result) + result = get_setting_value.execute(web_port) try: self.xbmc_port = result['result']['value'] except (TypeError, KeyError): @@ -131,16 +108,9 @@ class Artwork(): web_user = { - "jsonrpc": "2.0", - "id": 1, - "method": "Settings.GetSettingValue", - "params": { - - "setting": "services.webserverusername" - } + "setting": "services.webserverusername" } - result = xbmc.executeJSONRPC(json.dumps(web_user)) - result = json.loads(result) + result = get_setting_value.execute(web_user) try: self.xbmc_username = result['result']['value'] except TypeError: @@ -148,29 +118,20 @@ class Artwork(): web_pass = { - "jsonrpc": "2.0", - "id": 1, - "method": "Settings.GetSettingValue", - "params": { - - "setting": "services.webserverpassword" - } + "setting": "services.webserverpassword" } - result = xbmc.executeJSONRPC(json.dumps(web_pass)) - result = json.loads(result) + result = get_setting_value.execute(web_pass) try: self.xbmc_password = result['result']['value'] except TypeError: pass - def fullTextureCacheSync(self): + def texture_cache_sync(self): # This method will sync all Kodi artwork to textures13.db # and cache them locally. This takes diskspace! - dialog = xbmcgui.Dialog() - - if not dialog.yesno( - heading=lang(29999), - line1=lang(33042)): + if not dialog(type_="yesno", + heading="{emby}", + line1=lang(33042)): return log.info("Doing Image Cache Sync") @@ -179,135 +140,147 @@ class Artwork(): pdialog.create(lang(29999), lang(33043)) # ask to rest all existing or not - if dialog.yesno(lang(29999), lang(33044)): - log.info("Resetting all cache data first.") - - # Remove all existing textures first - path = xbmc.translatePath('special://thumbnails/').decode('utf-8') - if xbmcvfs.exists(path): - allDirs, allFiles = xbmcvfs.listdir(path) - for dir in allDirs: - allDirs, allFiles = xbmcvfs.listdir(path+dir) - for file in allFiles: - if os.path.supports_unicode_filenames: - path = os.path.join(path+dir.decode('utf-8'),file.decode('utf-8')) - xbmcvfs.delete(path) - else: - xbmcvfs.delete(os.path.join(path.encode('utf-8')+dir,file)) - - # remove all existing data from texture DB - connection = kodiSQL('texture') - cursor = connection.cursor() - cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') - rows = cursor.fetchall() - for row in rows: - tableName = row[0] - if tableName != "version": - cursor.execute("DELETE FROM " + tableName) - connection.commit() - cursor.close() + if dialog(type_="yesno", heading="{emby}", line1=lang(33044)): + log.info("Resetting all cache data first") + self._delete_cache() # Cache all entries in video DB - connection = kodiSQL('video') - cursor = connection.cursor() + self._cache_all_video_entries(pdialog) + # Cache all entries in music DB + self._cache_all_music_entries(pdialog) + + pdialog.update(100, "%s %s" % (lang(33046), len(self.image_cache_threads))) + log.info("Waiting for all threads to exit") + + while len(self.image_cache_threads): + for thread in self.image_cache_threads: + if thread.is_finished: + self.image_cache_threads.remove(thread) + pdialog.update(100, "%s %s" % (lang(33046), len(self.image_cache_threads))) + log.info("Waiting for all threads to exit: %s", len(self.image_cache_threads)) + xbmc.sleep(500) + + pdialog.close() + + def _cache_all_video_entries(self, pdialog): + + conn = kodiSQL('video') + cursor = conn.cursor() cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") # dont include actors result = cursor.fetchall() total = len(result) - log.info("Image cache sync about to process %s images" % total) + log.info("Image cache sync about to process %s images", total) cursor.close() count = 0 for url in result: - + if pdialog.iscanceled(): break percentage = int((float(count) / float(total))*100) - message = "%s of %s (%s)" % (count, total, self.imageCacheThreads) + message = "%s of %s (%s)" % (count, total, len(self.image_cache_threads)) pdialog.update(percentage, "%s %s" % (lang(33045), message)) - self.cacheTexture(url[0]) + self.cache_texture(url[0]) count += 1 - - # Cache all entries in music DB - connection = kodiSQL('music') - cursor = connection.cursor() + + def _cache_all_music_entries(self, pdialog): + + conn = kodiSQL('music') + cursor = conn.cursor() cursor.execute("SELECT url FROM art") result = cursor.fetchall() total = len(result) - log.info("Image cache sync about to process %s images" % total) + log.info("Image cache sync about to process %s images", total) cursor.close() count = 0 for url in result: - + if pdialog.iscanceled(): break percentage = int((float(count) / float(total))*100) message = "%s of %s" % (count, total) pdialog.update(percentage, "%s %s" % (lang(33045), message)) - self.cacheTexture(url[0]) + self.cache_texture(url[0]) count += 1 - - pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads))) - log.info("Waiting for all threads to exit") - - while len(self.imageCacheThreads): - for thread in self.imageCacheThreads: - if thread.is_finished: - self.imageCacheThreads.remove(thread) - pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads))) - log.info("Waiting for all threads to exit: %s" % len(self.imageCacheThreads)) - xbmc.sleep(500) - pdialog.close() + @classmethod + def _delete_cache(cls): + # Remove all existing textures first + path = xbmc.translatePath('special://thumbnails/').decode('utf-8') + if xbmcvfs.exists(path): + dirs, ignore_files = xbmcvfs.listdir(path) + for directory in dirs: + ignore_dirs, files = xbmcvfs.listdir(path + directory) + for file_ in files: - def addWorkerImageCacheThread(self, url): + if os.path.supports_unicode_filenames: + filename = os.path.join(path + directory.decode('utf-8'), + file_.decode('utf-8')) + else: + filename = os.path.join(path.encode('utf-8') + directory, file_) + + xbmcvfs.delete(filename) + log.info("deleted: %s", filename) + + # remove all existing data from texture DB + conn = kodiSQL('texture') + cursor = conn.cursor() + cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') + rows = cursor.fetchall() + for row in rows: + table_name = row[0] + if table_name != "version": + cursor.execute("DELETE FROM " + table_name) + conn.commit() + cursor.close() + + def _add_worker_image_thread(self, url): while True: # removed finished - for thread in self.imageCacheThreads: + for thread in self.image_cache_threads: if thread.is_finished: - self.imageCacheThreads.remove(thread) + self.image_cache_threads.remove(thread) # add a new thread or wait and retry if we hit our limit - if len(self.imageCacheThreads) < self.imageCacheLimitThreads: - newThread = image_cache_thread.ImageCacheThread() - newThread.set_url(self.double_urlencode(url)) - newThread.set_host(self.xbmc_host, self.xbmc_port) - newThread.set_auth(self.xbmc_username, self.xbmc_password) - newThread.start() - self.imageCacheThreads.append(newThread) + if len(self.image_cache_threads) < self.image_cache_limit: + + new_thread = image_cache_thread.ImageCacheThread() + new_thread.set_url(self._double_urlencode(url)) + new_thread.set_host(self.xbmc_host, self.xbmc_port) + new_thread.set_auth(self.xbmc_username, self.xbmc_password) + + new_thread.start() + self.image_cache_threads.append(new_thread) return else: - log.info("Waiting for empty queue spot: %s" % len(self.imageCacheThreads)) + log.info("Waiting for empty queue spot: %s", len(self.image_cache_threads)) xbmc.sleep(50) - def cacheTexture(self, url): + def cache_texture(self, url): # Cache a single image url to the texture cache - if url and self.enableTextureCache: - log.debug("Processing: %s" % url) + if url and self.enable_texture_cache: + log.debug("Processing: %s", url) - if not self.imageCacheLimitThreads: - # Add image to texture cache by simply calling it at the http endpoint - - url = self.double_urlencode(url) - try: # Extreme short timeouts so we will have a exception. - response = requests.head( - url=("http://%s:%s/image/image://%s" - % (self.xbmc_host, self.xbmc_port, url)), - auth=(self.xbmc_username, self.xbmc_password), - timeout=(0.01, 0.01)) - # We don't need the result - except: pass + if not self.image_cache_limit: + url = self._double_urlencode(url) + try: # Add image to texture cache by simply calling it at the http endpoint + requests.head(url=("http://%s:%s/image/image://%s" + % (self.xbmc_host, self.xbmc_port, url)), + auth=(self.xbmc_username, self.xbmc_password), + timeout=(0.01, 0.01)) + except Exception: # We don't need the result + pass else: - self.addWorkerImageCacheThread(url) + self._add_worker_image_thread(url) - - def addArtwork(self, artwork, kodiId, mediaType, cursor): + def add_artwork(self, artwork, kodi_id, media_type, cursor): # Kodi conversion table - kodiart = { + kodi_artwork = { 'Primary': ["thumb", "poster"], 'Banner': "banner", @@ -318,15 +291,14 @@ class Artwork(): 'Backdrop': "fanart", 'BoxRear': "poster" } - # Artwork is a dictionary - for art in artwork: + for artwork_type in artwork: - if art == "Backdrop": + if artwork_type == 'Backdrop': # Backdrop entry is a list # Process extra fanart for artwork downloader (fanart, fanart1, fanart2...) - backdrops = artwork[art] - backdropsNumber = len(backdrops) + backdrops = artwork[artwork_type] + backdrops_number = len(backdrops) query = ' '.join(( @@ -336,10 +308,10 @@ class Artwork(): "AND media_type = ?", "AND type LIKE ?" )) - cursor.execute(query, (kodiId, mediaType, "fanart%",)) + cursor.execute(query, (kodi_id, media_type, "fanart%",)) rows = cursor.fetchall() - if len(rows) > backdropsNumber: + if len(rows) > backdrops_number: # More backdrops in database. Delete extra fanart. query = ' '.join(( @@ -348,47 +320,40 @@ class Artwork(): "AND media_type = ?", "AND type LIKE ?" )) - cursor.execute(query, (kodiId, mediaType, "fanart_",)) + cursor.execute(query, (kodi_id, media_type, "fanart_",)) # Process backdrops and extra fanart - index = "" - for backdrop in backdrops: - self.addOrUpdateArt( - imageUrl=backdrop, - kodiId=kodiId, - mediaType=mediaType, - imageType="%s%s" % ("fanart", index), - cursor=cursor) + for index, backdrop in enumerate(backdrops): - if backdropsNumber > 1: - try: # Will only fail on the first try, str to int. - index += 1 - except TypeError: - index = 1 + self.add_update_art(image_url=backdrop, + kodi_id=kodi_id, + media_type=media_type, + image_type=("fanart" if not index else "%s%s" + % ("fanart", index)), + cursor=cursor) - elif art == "Primary": + elif artwork_type == 'Primary': # Primary art is processed as thumb and poster for Kodi. - for artType in kodiart[art]: - self.addOrUpdateArt( - imageUrl=artwork[art], - kodiId=kodiId, - mediaType=mediaType, - imageType=artType, - cursor=cursor) + for art_type in kodi_artwork[artwork_type]: + self.add_update_art(image_url=artwork[artwork_type], + kodi_id=kodi_id, + media_type=media_type, + image_type=art_type, + cursor=cursor) - elif kodiart.get(art): + elif artwork_type in kodi_artwork: # Process the rest artwork type that Kodi can use - self.addOrUpdateArt( - imageUrl=artwork[art], - kodiId=kodiId, - mediaType=mediaType, - imageType=kodiart[art], - cursor=cursor) + self.add_update_art(image_url=artwork[artwork_type], + kodi_id=kodi_id, + media_type=media_type, + image_type=kodi_artwork[artwork_type], + cursor=cursor) - def addOrUpdateArt(self, imageUrl, kodiId, mediaType, imageType, cursor): + def add_update_art(self, image_url, kodi_id, media_type, image_type, cursor): # Possible that the imageurl is an empty string - if imageUrl: - cacheimage = False + if image_url: + + cache_image = False query = ' '.join(( @@ -398,13 +363,13 @@ class Artwork(): "AND media_type = ?", "AND type = ?" )) - cursor.execute(query, (kodiId, mediaType, imageType,)) + cursor.execute(query, (kodi_id, media_type, image_type,)) try: # Update the artwork url = cursor.fetchone()[0] except TypeError: # Add the artwork - cacheimage = True - log.debug("Adding Art Link for kodiId: %s (%s)" % (kodiId, imageUrl)) + cache_image = True + log.debug("Adding Art Link for kodiId: %s (%s)", kodi_id, image_url) query = ( ''' @@ -413,20 +378,21 @@ class Artwork(): VALUES (?, ?, ?, ?) ''' ) - cursor.execute(query, (kodiId, mediaType, imageType, imageUrl)) + cursor.execute(query, (kodi_id, media_type, image_type, image_url)) else: # Only cache artwork if it changed - if url != imageUrl: - cacheimage = True + if url != image_url: + + cache_image = True # Only for the main backdrop, poster if (window('emby_initialScan') != "true" and - imageType in ("fanart", "poster")): + image_type in ("fanart", "poster")): # Delete current entry before updating with the new one - self.deleteCachedArtwork(url) + self.delete_cached_artwork(url) - log.info("Updating Art url for %s kodiId: %s (%s) -> (%s)" - % (imageType, kodiId, url, imageUrl)) + log.info("Updating Art url for %s kodiId: %s (%s) -> (%s)", + image_type, kodi_id, url, image_url) query = ' '.join(( @@ -436,13 +402,13 @@ class Artwork(): "AND media_type = ?", "AND type = ?" )) - cursor.execute(query, (imageUrl, kodiId, mediaType, imageType)) + cursor.execute(query, (image_url, kodi_id, media_type, image_type)) # Cache fanart and poster in Kodi texture cache - if cacheimage and imageType in ("fanart", "poster"): - self.cacheTexture(imageUrl) + if cache_image and image_type in ("fanart", "poster"): + self.cache_texture(image_url) - def deleteArtwork(self, kodiId, mediaType, cursor): + def delete_artwork(self, kodi_id, media_type, cursor): query = ' '.join(( @@ -451,85 +417,83 @@ class Artwork(): "WHERE media_id = ?", "AND media_type = ?" )) - cursor.execute(query, (kodiId, mediaType,)) + cursor.execute(query, (kodi_id, media_type,)) rows = cursor.fetchall() for row in rows: url = row[0] - imageType = row[1] - if imageType in ("poster", "fanart"): - self.deleteCachedArtwork(url) + image_type = row[1] + if image_type in ("poster", "fanart"): + self.delete_cached_artwork(url) - def deleteCachedArtwork(self, url): + @classmethod + def delete_cached_artwork(cls, url): # Only necessary to remove and apply a new backdrop or poster - connection = kodiSQL('texture') - cursor = connection.cursor() + conn = kodiSQL('texture') + cursor = conn.cursor() try: cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,)) - cachedurl = cursor.fetchone()[0] + cached_url = cursor.fetchone()[0] except TypeError: - log.info("Could not find cached url.") + log.info("Could not find cached url") except OperationalError: log.info("Database is locked. Skip deletion process.") else: # Delete thumbnail as well as the entry - thumbnails = xbmc.translatePath("special://thumbnails/%s" % cachedurl).decode('utf-8') - log.info("Deleting cached thumbnail: %s" % thumbnails) + thumbnails = xbmc.translatePath("special://thumbnails/%s", cached_url).decode('utf-8') + log.info("Deleting cached thumbnail: %s", thumbnails) xbmcvfs.delete(thumbnails) try: cursor.execute("DELETE FROM texture WHERE url = ?", (url,)) - connection.commit() + conn.commit() except OperationalError: log.debug("Issue deleting url from cache. Skipping.") finally: cursor.close() - def getPeopleArtwork(self, people): + def get_people_artwork(self, people): # append imageurl if existing for person in people: - personId = person['Id'] - tag = person.get('PrimaryImageTag') - image = "" - if tag: + person_id = person['Id'] + + if "PrimaryImageTag" in person: image = ( "%s/emby/Items/%s/Images/Primary?" "MaxWidth=400&MaxHeight=400&Index=0&Tag=%s" - % (self.server, personId, tag)) + % (self.server, person_id, person['PrimaryImageTag'])) person['imageurl'] = image return people - def getUserArtwork(self, itemId, itemType): + def get_user_artwork(self, item_id, item_type): # Load user information set by UserClient - image = ("%s/emby/Users/%s/Images/%s?Format=original" - % (self.server, itemId, itemType)) - return image + return "%s/emby/Users/%s/Images/%s?Format=original" % (self.server, item_id, item_type) - def getAllArtwork(self, item, parentInfo=False): + def get_all_artwork(self, item, parent_info=False): - itemid = item['Id'] + item_id = item['Id'] artworks = item['ImageTags'] backdrops = item.get('BackdropImageTags', []) - maxHeight = 10000 - maxWidth = 10000 - customquery = "" + max_height = 10000 + max_width = 10000 + custom_query = "" if settings('compressArt') == "true": - customquery = "&Quality=90" + custom_query = "&Quality=90" if settings('enableCoverArt') == "false": - customquery += "&EnableImageEnhancers=false" + custom_query += "&EnableImageEnhancers=false" - allartworks = { + all_artwork = { 'Primary': "", 'Art': "", @@ -540,71 +504,52 @@ class Artwork(): 'Backdrop': [] } + def get_backdrops(backdrops): + + for index, tag in enumerate(backdrops): + artwork = ("%s/emby/Items/%s/Images/Backdrop/%s?" + "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" + % (self.server, item_id, index, max_width, max_height, + tag, custom_query)) + all_artwork['Backdrop'].append(artwork) + + def get_artwork(type_, tag): + + artwork = ("%s/emby/Items/%s/Images/%s/0?" + "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" + % (self.server, item_id, type_, max_width, max_height, tag, custom_query)) + all_artwork[type_] = artwork + # Process backdrops - for index, tag in enumerate(backdrops): - artwork = ( - "%s/emby/Items/%s/Images/Backdrop/%s?" - "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" - % (self.server, itemid, index, maxWidth, maxHeight, tag, customquery)) - allartworks['Backdrop'].append(artwork) + get_backdrops(backdrops) # Process the rest of the artwork - for art in artworks: + for artwork in artworks: # Filter backcover - if art != "BoxRear": - tag = artworks[art] - artwork = ( - "%s/emby/Items/%s/Images/%s/0?" - "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" - % (self.server, itemid, art, maxWidth, maxHeight, tag, customquery)) - allartworks[art] = artwork + if artwork != "BoxRear": + get_artwork(artwork, artworks[artwork]) # Process parent items if the main item is missing artwork - if parentInfo: - + if parent_info: # Process parent backdrops - if not allartworks['Backdrop']: + if not all_artwork['Backdrop']: - parentId = item.get('ParentBackdropItemId') - if parentId: - # If there is a parentId, go through the parent backdrop list - parentbackdrops = item['ParentBackdropImageTags'] - - for index, tag in enumerate(parentbackdrops): - artwork = ( - "%s/emby/Items/%s/Images/Backdrop/%s?" - "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" - % (self.server, parentId, index, maxWidth, maxHeight, tag, customquery)) - allartworks['Backdrop'].append(artwork) + if 'ParentBackdropItemId' in item: + # If there is a parent_id, go through the parent backdrop list + get_backdrops(item['ParentBackdropImageTags']) # Process the rest of the artwork - parentartwork = ['Logo', 'Art', 'Thumb'] - for parentart in parentartwork: + for parent_artwork in ('Logo', 'Art', 'Thumb'): - if not allartworks[parentart]: + if not all_artwork[parent_artwork]: - parentId = item.get('Parent%sItemId' % parentart) - if parentId: - - parentTag = item['Parent%sImageTag' % parentart] - artwork = ( - "%s/emby/Items/%s/Images/%s/0?" - "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" - % (self.server, parentId, parentart, - maxWidth, maxHeight, parentTag, customquery)) - allartworks[parentart] = artwork + if 'Parent%sItemId' % parent_artwork in item: + get_artwork(parent_artwork, item['Parent%sImageTag' % parent_artwork]) # Parent album works a bit differently - if not allartworks['Primary']: + if not all_artwork['Primary']: - parentId = item.get('AlbumId') - if parentId and item.get('AlbumPrimaryImageTag'): + if 'AlbumId' in item and 'AlbumPrimaryImageTag' in item: + get_artwork('Primary', item['AlbumPrimaryImageTag']) - parentTag = item['AlbumPrimaryImageTag'] - artwork = ( - "%s/emby/Items/%s/Images/Primary/0?" - "MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" - % (self.server, parentId, maxWidth, maxHeight, parentTag, customquery)) - allartworks['Primary'] = artwork - - return allartworks \ No newline at end of file + return all_artwork diff --git a/resources/lib/embydb_functions.py b/resources/lib/embydb_functions.py index 9220fa5d..4a1090f0 100644 --- a/resources/lib/embydb_functions.py +++ b/resources/lib/embydb_functions.py @@ -191,7 +191,7 @@ class Embydb_Functions(): self.embycursor.execute(query, (parentid, mediatype,)) return self.embycursor.fetchall() - def getChecksum(self, mediatype): + def get_checksum(self, mediatype): query = ' '.join(( diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index f79af63a..fa14471f 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -319,7 +319,7 @@ def addUser(): url = "{server}/emby/Users/%s?format=json" % userid result = doUtils.downloadUrl(url) window('EmbyAdditionalUserImage.%s' % count, - value=art.getUserArtwork(result['Id'], 'Primary')) + value=art.get_user_artwork(result['Id'], 'Primary')) window('EmbyAdditionalUserPosition.%s' % userid, value=str(count)) count +=1 @@ -608,7 +608,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils. li.setProperty("embyid",itemid) - allart = art.getAllArtwork(item) + allart = art.get_all_artwork(item) if item["Type"] == "Photo": #listitem setup for pictures... @@ -621,16 +621,16 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils. li.setArt( {"fanart": img_path}) #add image as fanart for use with skinhelper auto thumb/backgrund creation li.setInfo('pictures', infoLabels={ "picturepath": img_path, "date": premieredate, "size": picture.get("Size"), "exif:width": str(picture.get("Width")), "exif:height": str(picture.get("Height")), "title": title}) li.setThumbnailImage(img_path) - li.setProperty("plot",API.getOverview()) + li.setProperty("plot",API.get_overview()) li.setIconImage('DefaultPicture.png') else: #normal video items li.setProperty('IsPlayable', 'true') path = "%s?id=%s&mode=play" % (sys.argv[0], item.get("Id")) li.setProperty("path",path) - genre = API.getGenres() + genre = API.get_genres() overlay = 0 - userdata = API.getUserData() + userdata = API.get_userdata() runtime = item.get("RunTimeTicks",0)/ 10000000.0 seektime = userdata['Resume'] if seektime: @@ -655,7 +655,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils. 'genre': genre, 'playcount': str(playcount), 'title': title, - 'plot': API.getOverview(), + 'plot': API.get_overview(), 'Overlay': str(overlay), 'duration': runtime } @@ -672,7 +672,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils. else: pbutils.PlaybackUtils(item).setArtwork(li) - mediastreams = API.getMediaStreams() + mediastreams = API.get_media_streams() videostreamFound = False if mediastreams: for key, value in mediastreams.iteritems(): @@ -1084,7 +1084,7 @@ def getExtraFanArt(embyId,embyPath): xbmcvfs.mkdirs(fanartDir) item = emby.getItem(embyId) if item: - backdrops = art.getAllArtwork(item)['Backdrop'] + backdrops = art.get_all_artwork(item)['Backdrop'] tags = item['BackdropImageTags'] count = 0 for backdrop in backdrops: diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index 12a3ddeb..9be93f0a 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -307,31 +307,31 @@ class Movies(Items): log.debug("View tag found: %s" % viewtag) # fileId information - checksum = API.getChecksum() - dateadded = API.getDateCreated() - userdata = API.getUserData() + checksum = API.get_checksum() + dateadded = API.get_date_created() + userdata = API.get_userdata() playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] # item details - people = API.getPeople() + people = API.get_people() writer = " / ".join(people['Writer']) director = " / ".join(people['Director']) genres = item['Genres'] title = item['Name'] - plot = API.getOverview() + plot = API.get_overview() shortplot = item.get('ShortOverview') - tagline = API.getTagline() + tagline = API.get_tagline() votecount = item.get('VoteCount') rating = item.get('CommunityRating') year = item.get('ProductionYear') - imdb = API.getProvider('Imdb') + imdb = API.get_provider('Imdb') sorttitle = item['SortName'] - runtime = API.getRuntime() - mpaa = API.getMpaa() + runtime = API.get_runtime() + mpaa = API.get_mpaa() genre = " / ".join(genres) - country = API.getCountry() - studios = API.getStudios() + country = API.get_country() + studios = API.get_studios() try: studio = studios[0] except IndexError: @@ -366,7 +366,7 @@ class Movies(Items): ##### GET THE FILE AND PATH ##### - playurl = API.getFilePath() + playurl = API.get_file_path() if "\\" in playurl: # Local path @@ -461,14 +461,14 @@ class Movies(Items): # Process countries self.kodi_db.addCountries(movieid, item['ProductionLocations'], "movie") # Process cast - people = artwork.getPeopleArtwork(item['People']) + people = artwork.get_people_artwork(item['People']) self.kodi_db.addPeople(movieid, people, "movie") # Process genres self.kodi_db.addGenres(movieid, genres, "movie") # Process artwork - artwork.addArtwork(artwork.getAllArtwork(item), movieid, "movie", kodicursor) + artwork.add_artwork(artwork.get_all_artwork(item), movieid, "movie", kodicursor) # Process stream details - streams = API.getMediaStreams() + streams = API.get_media_streams() self.kodi_db.addStreams(fileid, streams, runtime) # Process studios self.kodi_db.addStudios(movieid, studios, "movie") @@ -479,7 +479,7 @@ class Movies(Items): tags.append("Favorite movies") self.kodi_db.addTags(movieid, tags, "movie") # Process playstates - resume = API.adjustResume(userdata['Resume']) + resume = API.adjust_resume(userdata['Resume']) total = round(float(runtime), 6) self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed) @@ -500,7 +500,7 @@ class Movies(Items): setid = self.kodi_db.createBoxset(title) # Process artwork - artwork.addArtwork(artwork.getAllArtwork(boxset), setid, "set", self.kodicursor) + artwork.add_artwork(artwork.get_all_artwork(boxset), setid, "set", self.kodicursor) # Process movies inside boxset current_movies = emby_db.getItemId_byParentId(setid, "movie") @@ -556,9 +556,9 @@ class Movies(Items): # Get emby information itemid = item['Id'] - checksum = API.getChecksum() - userdata = API.getUserData() - runtime = API.getRuntime() + checksum = API.get_checksum() + userdata = API.get_userdata() + runtime = API.get_runtime() # Get Kodi information emby_dbitem = emby_db.getItem_byId(itemid) @@ -578,7 +578,7 @@ class Movies(Items): # Process playstates playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] - resume = API.adjustResume(userdata['Resume']) + resume = API.adjust_resume(userdata['Resume']) total = round(float(runtime), 6) log.debug("%s New resume point: %s" % (itemid, resume)) @@ -604,7 +604,7 @@ class Movies(Items): # Remove the emby reference emby_db.removeItem(itemid) # Remove artwork - artwork.deleteArtwork(kodiid, mediatype, kodicursor) + artwork.delete_artwork(kodiid, mediatype, kodicursor) if mediatype == "movie": # Delete kodi movie and file @@ -693,30 +693,30 @@ class MusicVideos(Items): log.debug("View tag found: %s" % viewtag) # fileId information - checksum = API.getChecksum() - dateadded = API.getDateCreated() - userdata = API.getUserData() + checksum = API.get_checksum() + dateadded = API.get_date_created() + userdata = API.get_userdata() playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] # item details - runtime = API.getRuntime() - plot = API.getOverview() + runtime = API.get_runtime() + plot = API.get_overview() title = item['Name'] year = item.get('ProductionYear') genres = item['Genres'] genre = " / ".join(genres) - studios = API.getStudios() + studios = API.get_studios() studio = " / ".join(studios) artist = " / ".join(item.get('Artists')) album = item.get('Album') track = item.get('Track') - people = API.getPeople() + people = API.get_people() director = " / ".join(people['Director']) ##### GET THE FILE AND PATH ##### - playurl = API.getFilePath() + playurl = API.get_file_path() if "\\" in playurl: # Local path @@ -833,14 +833,14 @@ class MusicVideos(Items): for artist in artists: artist['Type'] = "Artist" people.extend(artists) - people = artwork.getPeopleArtwork(people) + people = artwork.get_people_artwork(people) self.kodi_db.addPeople(mvideoid, people, "musicvideo") # Process genres self.kodi_db.addGenres(mvideoid, genres, "musicvideo") # Process artwork - artwork.addArtwork(artwork.getAllArtwork(item), mvideoid, "musicvideo", kodicursor) + artwork.add_artwork(artwork.get_all_artwork(item), mvideoid, "musicvideo", kodicursor) # Process stream details - streams = API.getMediaStreams() + streams = API.get_media_streams() self.kodi_db.addStreams(fileid, streams, runtime) # Process studios self.kodi_db.addStudios(mvideoid, studios, "musicvideo") @@ -851,7 +851,7 @@ class MusicVideos(Items): tags.append("Favorite musicvideos") self.kodi_db.addTags(mvideoid, tags, "musicvideo") # Process playstates - resume = API.adjustResume(userdata['Resume']) + resume = API.adjust_resume(userdata['Resume']) total = round(float(runtime), 6) self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed) @@ -863,9 +863,9 @@ class MusicVideos(Items): # Get emby information itemid = item['Id'] - checksum = API.getChecksum() - userdata = API.getUserData() - runtime = API.getRuntime() + checksum = API.get_checksum() + userdata = API.get_userdata() + runtime = API.get_runtime() # Get Kodi information emby_dbitem = emby_db.getItem_byId(itemid) @@ -887,7 +887,7 @@ class MusicVideos(Items): # Process playstates playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] - resume = API.adjustResume(userdata['Resume']) + resume = API.adjust_resume(userdata['Resume']) total = round(float(runtime), 6) self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed) @@ -922,7 +922,7 @@ class MusicVideos(Items): url = row[0] imagetype = row[1] if imagetype in ("poster", "fanart"): - artwork.deleteCachedArtwork(url) + artwork.delete_cached_artwork(url) kodicursor.execute("DELETE FROM musicvideo WHERE idMVideo = ?", (mvideoid,)) kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,)) @@ -1033,28 +1033,28 @@ class TVShows(Items): log.debug("View tag found: %s" % viewtag) # fileId information - checksum = API.getChecksum() - dateadded = API.getDateCreated() - userdata = API.getUserData() + checksum = API.get_checksum() + dateadded = API.get_date_created() + userdata = API.get_userdata() playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] # item details genres = item['Genres'] title = item['Name'] - plot = API.getOverview() + plot = API.get_overview() rating = item.get('CommunityRating') - premieredate = API.getPremiereDate() - tvdb = API.getProvider('Tvdb') + premieredate = API.get_premiere_date() + tvdb = API.get_provider('Tvdb') sorttitle = item['SortName'] - mpaa = API.getMpaa() + mpaa = API.get_mpaa() genre = " / ".join(genres) - studios = API.getStudios() + studios = API.get_studios() studio = " / ".join(studios) ##### GET THE FILE AND PATH ##### - playurl = API.getFilePath() + playurl = API.get_file_path() if self.directpath: # Direct paths is set the Kodi way @@ -1142,12 +1142,12 @@ class TVShows(Items): kodicursor.execute(query, (path, None, None, 1, pathid)) # Process cast - people = artwork.getPeopleArtwork(item['People']) + people = artwork.get_people_artwork(item['People']) self.kodi_db.addPeople(showid, people, "tvshow") # Process genres self.kodi_db.addGenres(showid, genres, "tvshow") # Process artwork - artwork.addArtwork(artwork.getAllArtwork(item), showid, "tvshow", kodicursor) + artwork.add_artwork(artwork.get_all_artwork(item), showid, "tvshow", kodicursor) # Process studios self.kodi_db.addStudios(showid, studios, "tvshow") # Process tags: view, emby tags @@ -1164,7 +1164,7 @@ class TVShows(Items): # Finally, refresh the all season entry seasonid = self.kodi_db.addSeason(showid, -1) # Process artwork - artwork.addArtwork(artwork.getAllArtwork(item), seasonid, "season", kodicursor) + artwork.add_artwork(artwork.get_all_artwork(item), seasonid, "season", kodicursor) if force_episodes: # We needed to recreate the show entry. Re-add episodes now. @@ -1199,7 +1199,7 @@ class TVShows(Items): emby_db.addReference(item['Id'], seasonid, "Season", "season", parentid=showid) # Process artwork - artwork.addArtwork(artwork.getAllArtwork(item), seasonid, "season", kodicursor) + artwork.add_artwork(artwork.get_all_artwork(item), seasonid, "season", kodicursor) def add_updateEpisode(self, item): # Process single episode @@ -1225,7 +1225,7 @@ class TVShows(Items): except TypeError: update_item = False - log.info("episodeid: %s not found." % itemid) + log.debug("episodeid: %s not found." % itemid) # episodeid kodicursor.execute("select coalesce(max(idEpisode),0) from episode") episodeid = kodicursor.fetchone()[0] + 1 @@ -1242,21 +1242,21 @@ class TVShows(Items): log.info("episodeid: %s missing from Kodi, repairing the entry." % episodeid) # fileId information - checksum = API.getChecksum() - dateadded = API.getDateCreated() - userdata = API.getUserData() + checksum = API.get_checksum() + dateadded = API.get_date_created() + userdata = API.get_userdata() playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] # item details - people = API.getPeople() + people = API.get_people() writer = " / ".join(people['Writer']) director = " / ".join(people['Director']) title = item['Name'] - plot = API.getOverview() + plot = API.get_overview() rating = item.get('CommunityRating') - runtime = API.getRuntime() - premieredate = API.getPremiereDate() + runtime = API.get_runtime() + premieredate = API.get_premiere_date() # episode details try: @@ -1308,7 +1308,7 @@ class TVShows(Items): ##### GET THE FILE AND PATH ##### - playurl = API.getFilePath() + playurl = API.get_file_path() if "\\" in playurl: # Local path @@ -1431,16 +1431,16 @@ class TVShows(Items): kodicursor.execute(query, (pathid, filename, dateadded, fileid)) # Process cast - people = artwork.getPeopleArtwork(item['People']) + people = artwork.get_people_artwork(item['People']) self.kodi_db.addPeople(episodeid, people, "episode") # Process artwork - artworks = artwork.getAllArtwork(item) - artwork.addOrUpdateArt(artworks['Primary'], episodeid, "episode", "thumb", kodicursor) + artworks = artwork.get_all_artwork(item) + artwork.add_update_art(artworks['Primary'], episodeid, "episode", "thumb", kodicursor) # Process stream details - streams = API.getMediaStreams() + streams = API.get_media_streams() self.kodi_db.addStreams(fileid, streams, runtime) # Process playstates - resume = API.adjustResume(userdata['Resume']) + resume = API.adjust_resume(userdata['Resume']) total = round(float(runtime), 6) self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed) if not self.directpath and resume: @@ -1464,10 +1464,10 @@ class TVShows(Items): # Get emby information itemid = item['Id'] - checksum = API.getChecksum() - userdata = API.getUserData() - runtime = API.getRuntime() - dateadded = API.getDateCreated() + checksum = API.get_checksum() + userdata = API.get_userdata() + runtime = API.get_runtime() + dateadded = API.get_date_created() # Get Kodi information emby_dbitem = emby_db.getItem_byId(itemid) @@ -1491,7 +1491,7 @@ class TVShows(Items): # Process playstates playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] - resume = API.adjustResume(userdata['Resume']) + resume = API.adjust_resume(userdata['Resume']) total = round(float(runtime), 6) log.debug("%s New resume point: %s" % (itemid, resume)) @@ -1627,7 +1627,7 @@ class TVShows(Items): def removeShow(self, kodiid): kodicursor = self.kodicursor - self.artwork.deleteArtwork(kodiid, "tvshow", kodicursor) + self.artwork.delete_artwork(kodiid, "tvshow", kodicursor) kodicursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodiid,)) log.debug("Removed tvshow: %s." % kodiid) @@ -1635,7 +1635,7 @@ class TVShows(Items): kodicursor = self.kodicursor - self.artwork.deleteArtwork(kodiid, "season", kodicursor) + self.artwork.delete_artwork(kodiid, "season", kodicursor) kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodiid,)) log.debug("Removed season: %s." % kodiid) @@ -1643,7 +1643,7 @@ class TVShows(Items): kodicursor = self.kodicursor - self.artwork.deleteArtwork(kodiid, "episode", kodicursor) + self.artwork.delete_artwork(kodiid, "episode", kodicursor) kodicursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodiid,)) kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,)) log.debug("Removed episode: %s." % kodiid) @@ -1724,16 +1724,16 @@ class Music(Items): ##### The artist details ##### lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - dateadded = API.getDateCreated() - checksum = API.getChecksum() + dateadded = API.get_date_created() + checksum = API.get_checksum() name = item['Name'] - musicBrainzId = API.getProvider('MusicBrainzArtist') + musicBrainzId = API.get_provider('MusicBrainzArtist') genres = " / ".join(item.get('Genres')) - bio = API.getOverview() + bio = API.get_overview() # Associate artwork - artworks = artwork.getAllArtwork(item, parentInfo=True) + artworks = artwork.get_all_artwork(item, parent_info=True) thumb = artworks['Primary'] backdrops = artworks['Backdrop'] # List @@ -1784,7 +1784,7 @@ class Music(Items): # Update artwork - artwork.addArtwork(artworks, artistid, "artist", kodicursor) + artwork.add_artwork(artworks, artistid, "artist", kodicursor) def add_updateAlbum(self, item): # Process a single artist @@ -1805,16 +1805,16 @@ class Music(Items): ##### The album details ##### lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - dateadded = API.getDateCreated() - userdata = API.getUserData() - checksum = API.getChecksum() + dateadded = API.get_date_created() + userdata = API.get_userdata() + checksum = API.get_checksum() name = item['Name'] - musicBrainzId = API.getProvider('MusicBrainzAlbum') + musicBrainzId = API.get_provider('MusicBrainzAlbum') year = item.get('ProductionYear') genres = item.get('Genres') genre = " / ".join(genres) - bio = API.getOverview() + bio = API.get_overview() rating = userdata['UserRating'] artists = item['AlbumArtists'] if not artists: @@ -1825,7 +1825,7 @@ class Music(Items): artistname = " / ".join(artistname) # Associate artwork - artworks = artwork.getAllArtwork(item, parentInfo=True) + artworks = artwork.get_all_artwork(item, parent_info=True) thumb = artworks['Primary'] if thumb: thumb = "%s" % thumb @@ -1952,7 +1952,7 @@ class Music(Items): # Add genres self.kodi_db.addMusicGenres(albumid, genres, "album") # Update artwork - artwork.addArtwork(artworks, albumid, "album", kodicursor) + artwork.add_artwork(artworks, albumid, "album", kodicursor) def add_updateSong(self, item): # Process single song @@ -1974,15 +1974,15 @@ class Music(Items): log.debug("songid: %s not found." % itemid) ##### The song details ##### - checksum = API.getChecksum() - dateadded = API.getDateCreated() - userdata = API.getUserData() + checksum = API.get_checksum() + dateadded = API.get_date_created() + userdata = API.get_userdata() playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] # item details title = item['Name'] - musicBrainzId = API.getProvider('MusicBrainzTrackId') + musicBrainzId = API.get_provider('MusicBrainzTrackId') genres = item.get('Genres') genre = " / ".join(genres) artists = " / ".join(item['Artists']) @@ -1993,7 +1993,7 @@ class Music(Items): else: track = disc*2**16 + tracknumber year = item.get('ProductionYear') - duration = API.getRuntime() + duration = API.get_runtime() rating = userdata['UserRating'] #if enabled, try to get the rating from file and/or emby @@ -2001,7 +2001,7 @@ class Music(Items): rating, comment, hasEmbeddedCover = musicutils.getAdditionalSongTags(itemid, rating, API, kodicursor, emby_db, self.enableimportsongrating, self.enableexportsongrating, self.enableupdatesongrating) else: hasEmbeddedCover = False - comment = API.getOverview() + comment = API.get_overview() ##### GET THE FILE AND PATH ##### @@ -2009,7 +2009,7 @@ class Music(Items): path = "%s/emby/Audio/%s/" % (self.server, itemid) filename = "stream.mp3" else: - playurl = API.getFilePath() + playurl = API.get_file_path() if "\\" in playurl: # Local path @@ -2063,7 +2063,7 @@ class Music(Items): album_name = item.get('Album') if album_name: log.info("Creating virtual music album for song: %s." % itemid) - albumid = self.kodi_db.addAlbum(album_name, API.getProvider('MusicBrainzAlbum')) + albumid = self.kodi_db.addAlbum(album_name, API.get_provider('MusicBrainzAlbum')) emby_db.addReference("%salbum%s" % (itemid, albumid), albumid, "MusicAlbum_", "album") else: # No album Id associated to the song. @@ -2257,14 +2257,14 @@ class Music(Items): self.kodi_db.addMusicGenres(songid, genres, "song") # Update artwork - allart = artwork.getAllArtwork(item, parentInfo=True) + allart = artwork.get_all_artwork(item, parent_info=True) if hasEmbeddedCover: allart["Primary"] = "image://music@" + artwork.single_urlencode( playurl ) - artwork.addArtwork(allart, songid, "song", kodicursor) + artwork.add_artwork(allart, songid, "song", kodicursor) if item.get('AlbumId') is None: # Update album artwork - artwork.addArtwork(allart, albumid, "album", kodicursor) + artwork.add_artwork(allart, albumid, "album", kodicursor) def updateUserdata(self, item): # This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks @@ -2275,9 +2275,9 @@ class Music(Items): # Get emby information itemid = item['Id'] - checksum = API.getChecksum() - userdata = API.getUserData() - runtime = API.getRuntime() + checksum = API.get_checksum() + userdata = API.get_userdata() + runtime = API.get_runtime() rating = userdata['UserRating'] # Get Kodi information @@ -2401,15 +2401,15 @@ class Music(Items): kodicursor = self.kodicursor - self.artwork.deleteArtwork(kodiId, "song", self.kodicursor) + self.artwork.delete_artwork(kodiId, "song", self.kodicursor) self.kodicursor.execute("DELETE FROM song WHERE idSong = ?", (kodiId,)) def removeAlbum(self, kodiId): - self.artwork.deleteArtwork(kodiId, "album", self.kodicursor) + self.artwork.delete_artwork(kodiId, "album", self.kodicursor) self.kodicursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodiId,)) def removeArtist(self, kodiId): - self.artwork.deleteArtwork(kodiId, "artist", self.kodicursor) + self.artwork.delete_artwork(kodiId, "artist", self.kodicursor) self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodiId,)) \ No newline at end of file diff --git a/resources/lib/kodidb_functions.py b/resources/lib/kodidb_functions.py index 5f36f60f..fe76b5e2 100644 --- a/resources/lib/kodidb_functions.py +++ b/resources/lib/kodidb_functions.py @@ -420,7 +420,7 @@ class Kodidb_Functions(): if "writing" in arttype: arttype = "writer" - self.artwork.addOrUpdateArt(thumb, actorid, arttype, "thumb", self.cursor) + self.artwork.add_update_art(thumb, actorid, arttype, "thumb", self.cursor) def addGenres(self, kodiid, genres, mediatype): diff --git a/resources/lib/kodimonitor.py b/resources/lib/kodimonitor.py index 89668b3f..35efa40f 100644 --- a/resources/lib/kodimonitor.py +++ b/resources/lib/kodimonitor.py @@ -25,192 +25,146 @@ class KodiMonitor(xbmc.Monitor): def __init__(self): - self.doUtils = downloadutils.DownloadUtils() - - log.info("Kodi monitor started.") + self.download = downloadutils.DownloadUtils().downloadUrl + log.info("Kodi monitor started") def onScanStarted(self, library): - log.debug("Kodi library scan %s running." % library) + + log.debug("Kodi library scan %s running", library) if library == "video": window('emby_kodiScan', value="true") - + def onScanFinished(self, library): - log.debug("Kodi library scan %s finished." % library) + + log.debug("Kodi library scan %s finished", library) if library == "video": window('emby_kodiScan', clear=True) def onSettingsChanged(self): # Monitor emby settings - # Review reset setting at a later time, need to be adjusted to account for initial setup - # changes. - '''currentPath = utils.settings('useDirectPaths') - if utils.window('emby_pluginpath') != currentPath: - # Plugin path value changed. Offer to reset - log("Changed to playback mode detected", 1) - utils.window('emby_pluginpath', value=currentPath) - resp = xbmcgui.Dialog().yesno( - heading="Playback mode change detected", - line1=( - "Detected the playback mode has changed. The database " - "needs to be recreated for the change to be applied. " - "Proceed?")) - if resp: - utils.reset()''' - - currentLog = settings('logLevel') - if window('emby_logLevel') != currentLog: + current_log_level = settings('logLevel') + if window('emby_logLevel') != current_log_level: # The log level changed, set new prop - log.info("New log level: %s" % currentLog) - window('emby_logLevel', value=currentLog) + log.info("New log level: %s", current_log_level) + window('emby_logLevel', value=current_log_level) def onNotification(self, sender, method, data): - doUtils = self.doUtils - if method not in ("Playlist.OnAdd"): - log.info("Method: %s Data: %s" % (method, data)) - + if method not in ('Playlist.OnAdd', 'Player.OnStop', 'Player.OnClear'): + log.info("Method: %s Data: %s", method, data) + if data: - data = json.loads(data,'utf-8') + data = json.loads(data, 'utf-8') + if method == 'Player.OnPlay': + self._on_play_(data) - if method == "Player.OnPlay": - # Set up report progress for emby playback - item = data.get('item') - try: - kodiid = item['id'] - item_type = item['type'] - except (KeyError, TypeError): - log.info("Item is invalid for playstate update.") - else: - if ((settings('useDirectPaths') == "1" and not item_type == "song") or - (item_type == "song" and settings('enableMusic') == "true")): - # Set up properties for player - embyconn = kodiSQL('emby') - embycursor = embyconn.cursor() - emby_db = embydb.Embydb_Functions(embycursor) - emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type) - try: - itemid = emby_dbitem[0] - except TypeError: - log.info("No kodiId returned.") - else: - url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % itemid - result = doUtils.downloadUrl(url) - log.debug("Item: %s" % result) + elif method == 'VideoLibrary.OnUpdate': + self._video_update(data) - playurl = None - count = 0 - while not playurl and count < 2: - try: - playurl = xbmc.Player().getPlayingFile() - except RuntimeError: - count += 1 - xbmc.sleep(200) - else: - listItem = xbmcgui.ListItem() - playback = pbutils.PlaybackUtils(result) - - if item_type == "song" and settings('streamMusic') == "true": - window('emby_%s.playmethod' % playurl, value="DirectStream") - else: - window('emby_%s.playmethod' % playurl, value="DirectPlay") - # Set properties for player.py - playback.setProperties(playurl, listItem) - finally: - embycursor.close() - - - elif method == "VideoLibrary.OnUpdate": - # Manually marking as watched/unwatched - playcount = data.get('playcount') - item = data.get('item') - try: - kodiid = item['id'] - item_type = item['type'] - except (KeyError, TypeError): - log.info("Item is invalid for playstate update.") - else: - # Send notification to the server. - embyconn = kodiSQL('emby') - embycursor = embyconn.cursor() - emby_db = embydb.Embydb_Functions(embycursor) - emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type) - try: - itemid = emby_dbitem[0] - except TypeError: - log.info("Could not find itemid in emby database.") - else: - # Stop from manually marking as watched unwatched, with actual playback. - if window('emby_skipWatched%s' % itemid) == "true": - # property is set in player.py - window('emby_skipWatched%s' % itemid, clear=True) - else: - # notify the server - url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % itemid - if playcount != 0: - doUtils.downloadUrl(url, action_type="POST") - log.info("Mark as watched for itemid: %s" % itemid) - else: - doUtils.downloadUrl(url, action_type="DELETE") - log.info("Mark as unwatched for itemid: %s" % itemid) - finally: - embycursor.close() - - - elif method == "VideoLibrary.OnRemove": - # Removed function, because with plugin paths + clean library, it will wipe - # entire library if user has permissions. Instead, use the emby context menu available - # in Isengard and higher version - pass - '''try: - kodiid = data['id'] - type = data['type'] - except (KeyError, TypeError): - log("Item is invalid for emby deletion.", 1) - else: - # Send the delete action to the server. - embyconn = utils.kodiSQL('emby') - embycursor = embyconn.cursor() - emby_db = embydb.Embydb_Functions(embycursor) - emby_dbitem = emby_db.getItem_byKodiId(kodiid, type) - try: - itemid = emby_dbitem[0] - except TypeError: - log("Could not find itemid in emby database.", 1) - else: - if utils.settings('skipContextMenu') != "true": - resp = xbmcgui.Dialog().yesno( - heading="Confirm delete", - line1="Delete file on Emby Server?") - if not resp: - log("User skipped deletion.", 1) - embycursor.close() - return - - url = "{server}/emby/Items/%s?format=json" % itemid - log("Deleting request: %s" % itemid) - doUtils.downloadUrl(url, action_type="DELETE") - finally: - embycursor.close()''' - - elif method == "System.OnSleep": + elif method == 'System.OnSleep': # Connection is going to sleep log.info("Marking the server as offline. System.OnSleep activated.") window('emby_online', value="sleep") - elif method == "System.OnWake": - # Allow network to wake up - xbmc.sleep(10000) - window('emby_online', value="false") + elif method == 'System.OnWake': + self._system_wake() + + elif method == 'GUI.OnScreensaverDeactivated': + self._screensaver_deactivated() + + def _on_play_(self, data): + # Set up report progress for emby playback + try: + item = data['item'] + kodi_id = item['id'] + item_type = item['type'] + except (KeyError, TypeError): + log.info("Item is invalid for playstate update") + else: + if ((settings('useDirectPaths') == "1" and not item_type == "song") or + (item_type == "song" and settings('enableMusic') == "true")): + # Set up properties for player + item_id = self._get_item_id(kodi_id, item_type) + if item_id: + url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % item_id + result = self.download(url) + log.debug("Item: %s", result) + + playurl = None + count = 0 + while not playurl and count < 2: + try: + playurl = xbmc.Player().getPlayingFile() + except RuntimeError: + count += 1 + xbmc.sleep(200) + else: + listitem = xbmcgui.ListItem() + playback = pbutils.PlaybackUtils(result) + + if item_type == "song" and settings('streamMusic') == "true": + window('emby_%s.playmethod' % playurl, value="DirectStream") + else: + window('emby_%s.playmethod' % playurl, value="DirectPlay") + # Set properties for player.py + playback.setProperties(playurl, listitem) + + def _video_update(self, data): + # Manually marking as watched/unwatched + try: + item = data['item'] + kodi_id = item['id'] + item_type = item['type'] + except (KeyError, TypeError): + log.info("Item is invalid for playstate update") + else: + # Send notification to the server. + item_id = self._get_item_id(kodi_id, item_type) + if item_id: + # Stop from manually marking as watched unwatched, with actual playback. + if window('emby_skipWatched%s' % item_id) == "true": + # property is set in player.py + window('emby_skipWatched%s' % item_id, clear=True) + else: + # notify the server + url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % item_id + if data.get('playcount') != 0: + self.download(url, action_type="POST") + log.info("Mark as watched for itemid: %s", item_id) + else: + self.download(url, action_type="DELETE") + log.info("Mark as unwatched for itemid: %s", item_id) + + @classmethod + def _system_wake(cls): + # Allow network to wake up + xbmc.sleep(10000) + window('emby_online', value="false") + window('emby_onWake', value="true") + + @classmethod + def _screensaver_deactivated(cls): + + if settings('dbSyncScreensaver') == "true": + xbmc.sleep(5000) window('emby_onWake', value="true") + @classmethod + def _get_item_id(cls, kodi_id, item_type): - elif method == "GUI.OnScreensaverDeactivated": - if settings('dbSyncScreensaver') == "true": - xbmc.sleep(5000); - window('emby_onWake', value="true") + item_id = None + conn = kodiSQL('emby') + cursor = conn.cursor() + emby_db = embydb.Embydb_Functions(cursor) + db_item = emby_db.getItem_byKodiId(kodi_id, item_type) + cursor.close() - elif method == "Playlist.OnClear": - pass \ No newline at end of file + try: + item_id = db_item[0] + except TypeError: + log.info("Could not retrieve item Id") + + return item_id diff --git a/resources/lib/librarysync.py b/resources/lib/librarysync.py index 85f66474..9d0e6ce9 100644 --- a/resources/lib/librarysync.py +++ b/resources/lib/librarysync.py @@ -1049,12 +1049,12 @@ class ManualSync(LibrarySync): # Pull the list of movies and boxsets in Kodi try: - all_kodimovies = dict(emby_db.getChecksum('Movie')) + all_kodimovies = dict(emby_db.get_checksum('Movie')) except ValueError: all_kodimovies = {} try: - all_kodisets = dict(emby_db.getChecksum('BoxSet')) + all_kodisets = dict(emby_db.get_checksum('BoxSet')) except ValueError: all_kodisets = {} @@ -1088,7 +1088,7 @@ class ManualSync(LibrarySync): all_embymoviesIds.add(itemid) - if all_kodimovies.get(itemid) != API.getChecksum(): + if all_kodimovies.get(itemid) != API.get_checksum(): # Only update if movie is not in Kodi or checksum is different updatelist.append(itemid) @@ -1179,7 +1179,7 @@ class ManualSync(LibrarySync): # Pull the list of musicvideos in Kodi try: - all_kodimvideos = dict(emby_db.getChecksum('MusicVideo')) + all_kodimvideos = dict(emby_db.get_checksum('MusicVideo')) except ValueError: all_kodimvideos = {} @@ -1211,7 +1211,7 @@ class ManualSync(LibrarySync): all_embymvideosIds.add(itemid) - if all_kodimvideos.get(itemid) != API.getChecksum(): + if all_kodimvideos.get(itemid) != API.get_checksum(): # Only update if musicvideo is not in Kodi or checksum is different updatelist.append(itemid) @@ -1258,12 +1258,12 @@ class ManualSync(LibrarySync): # Pull the list of tvshows and episodes in Kodi try: - all_koditvshows = dict(emby_db.getChecksum('Series')) + all_koditvshows = dict(emby_db.get_checksum('Series')) except ValueError: all_koditvshows = {} try: - all_kodiepisodes = dict(emby_db.getChecksum('Episode')) + all_kodiepisodes = dict(emby_db.get_checksum('Episode')) except ValueError: all_kodiepisodes = {} @@ -1297,7 +1297,7 @@ class ManualSync(LibrarySync): all_embytvshowsIds.add(itemid) - if all_koditvshows.get(itemid) != API.getChecksum(): + if all_koditvshows.get(itemid) != API.get_checksum(): # Only update if movie is not in Kodi or checksum is different updatelist.append(itemid) @@ -1341,7 +1341,7 @@ class ManualSync(LibrarySync): itemid = embyepisode['Id'] all_embyepisodesIds.add(itemid) - if all_kodiepisodes.get(itemid) != API.getChecksum(): + if all_kodiepisodes.get(itemid) != API.get_checksum(): # Only update if movie is not in Kodi or checksum is different updatelist.append(itemid) @@ -1388,17 +1388,17 @@ class ManualSync(LibrarySync): # Pull the list of artists, albums, songs try: - all_kodiartists = dict(emby_db.getChecksum('MusicArtist')) + all_kodiartists = dict(emby_db.get_checksum('MusicArtist')) except ValueError: all_kodiartists = {} try: - all_kodialbums = dict(emby_db.getChecksum('MusicAlbum')) + all_kodialbums = dict(emby_db.get_checksum('MusicAlbum')) except ValueError: all_kodialbums = {} try: - all_kodisongs = dict(emby_db.getChecksum('Audio')) + all_kodisongs = dict(emby_db.get_checksum('Audio')) except ValueError: all_kodisongs = {} @@ -1429,17 +1429,17 @@ class ManualSync(LibrarySync): itemid = embyitem['Id'] if data_type == "artists": all_embyartistsIds.add(itemid) - if all_kodiartists.get(itemid) != API.getChecksum(): + if all_kodiartists.get(itemid) != API.get_checksum(): # Only update if artist is not in Kodi or checksum is different updatelist.append(itemid) elif data_type == "albums": all_embyalbumsIds.add(itemid) - if all_kodialbums.get(itemid) != API.getChecksum(): + if all_kodialbums.get(itemid) != API.get_checksum(): # Only update if album is not in Kodi or checksum is different updatelist.append(itemid) else: all_embysongsIds.add(itemid) - if all_kodisongs.get(itemid) != API.getChecksum(): + if all_kodisongs.get(itemid) != API.get_checksum(): # Only update if songs is not in Kodi or checksum is different updatelist.append(itemid) log.info("%s to update: %s" % (data_type, updatelist)) diff --git a/resources/lib/musicutils.py b/resources/lib/musicutils.py index 1f5bd9e9..2a02638d 100644 --- a/resources/lib/musicutils.py +++ b/resources/lib/musicutils.py @@ -74,7 +74,7 @@ def getAdditionalSongTags(embyid, emby_rating, API, kodicursor, emby_db, enablei emby = embyserver.Read_EmbyServer() previous_values = None - filename = API.getFilePath() + filename = API.get_file_path() rating = 0 emby_rating = int(round(emby_rating, 0)) diff --git a/resources/lib/playbackutils.py b/resources/lib/playbackutils.py index d36b4b33..2fa703a2 100644 --- a/resources/lib/playbackutils.py +++ b/resources/lib/playbackutils.py @@ -82,8 +82,8 @@ class PlaybackUtils(): ############### RESUME POINT ################ - userdata = self.API.getUserData() - seektime = self.API.adjustResume(userdata['Resume']) + userdata = self.API.get_userdata() + seektime = self.API.adjust_resume(userdata['Resume']) # We need to ensure we add the intro and additional parts only once. # Otherwise we get a loop. @@ -309,7 +309,7 @@ class PlaybackUtils(): def setArtwork(self, listItem): # Set up item and item info - allartwork = self.artwork.getAllArtwork(self.item, parentInfo=True) + allartwork = self.artwork.get_all_artwork(self.item, parent_info=True) # Set artwork for listitem arttypes = { @@ -346,20 +346,20 @@ class PlaybackUtils(): def setListItem(self, listItem): - people = self.API.getPeople() - studios = self.API.getStudios() + people = self.API.get_people() + studios = self.API.get_studios() metadata = { 'title': self.item.get('Name', "Missing name"), 'year': self.item.get('ProductionYear'), - 'plot': self.API.getOverview(), + 'plot': self.API.get_overview(), 'director': people.get('Director'), 'writer': people.get('Writer'), - 'mpaa': self.API.getMpaa(), + 'mpaa': self.API.get_mpaa(), 'genre': " / ".join(self.item['Genres']), 'studio': " / ".join(studios), - 'aired': self.API.getPremiereDate(), + 'aired': self.API.get_premiere_date(), 'rating': self.item.get('CommunityRating'), 'votes': self.item.get('VoteCount') } diff --git a/resources/lib/userclient.py b/resources/lib/userclient.py index 40e7be54..f2f44c96 100644 --- a/resources/lib/userclient.py +++ b/resources/lib/userclient.py @@ -147,7 +147,7 @@ class UserClient(threading.Thread): settings('username', value=self._user['Name']) if "PrimaryImageTag" in self._user: window('EmbyUserImage', - value=artwork.Artwork().getUserArtwork(self._user['Id'], 'Primary')) + value=artwork.Artwork().get_user_artwork(self._user['Id'], 'Primary')) self._server = self.download("{server}/emby/System/Configuration?format=json") settings('markPlayed', value=str(self._server['MaxResumePct']))