From 0c54257de67bb7ae8d57b7f908e73bd48b6b5cba Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Sat, 18 Jul 2015 03:08:05 -0500 Subject: [PATCH] fix for the merge that didn't follow Media path fix, and clean up of writeKodiVideoDB. Fix for library sync for deletes. --- resources/lib/API.py | 521 +++++---- resources/lib/LibrarySync.py | 121 +- resources/lib/PlayUtils.py | 135 +-- resources/lib/WriteKodiVideoDB.py | 1804 ++++++++++++++--------------- 4 files changed, 1281 insertions(+), 1300 deletions(-) diff --git a/resources/lib/API.py b/resources/lib/API.py index cfc7a210..d70da166 100644 --- a/resources/lib/API.py +++ b/resources/lib/API.py @@ -1,3 +1,4 @@ +# -- coding: utf-8 -- # API.py # This class helps translate more complex cases from the MediaBrowser API to the XBMC API @@ -11,142 +12,157 @@ class API(): def getPeople(self, item): # Process People - director=[] - writer=[] - cast=[] - people = item.get("People") - if(people != None): - for person in people: - if(person.get("Type") == "Director"): - director.append(person.get("Name")) - if(person.get("Type") == "Writing"): - writer.append(person.get("Name")) - if(person.get("Type") == "Writer"): - writer.append(person.get("Name")) - if(person.get("Type") == "Actor"): - Name = person.get("Name") - Role = person.get("Role") - if Role == None: - Role = '' - cast.append(Name) - return {'Director' : director, - 'Writer' : writer, - 'Cast' : cast - } - - def getTimeInfo(self, item): - resumeTime = '' - userData = item.get("UserData") - PlaybackPositionTicks = '100' - if userData.get("PlaybackPositionTicks") != None: - PlaybackPositionTicks = str(userData.get("PlaybackPositionTicks")) - reasonableTicks = int(userData.get("PlaybackPositionTicks")) / 1000 - resumeTime = reasonableTicks / 10000 + director = [] + writer = [] + cast = [] try: - tempDuration = str(int(item.get("RunTimeTicks", "0"))/(10000000*60)) - except TypeError: - try: - tempDuration = str(int(item.get("CumulativeRunTimeTicks"))/(10000000*60)) - except TypeError: - tempDuration = "0" - cappedPercentage = None - resume=0 - percentage=0 - if (resumeTime != "" and int(resumeTime) > 0): - duration = float(tempDuration) - if(duration > 0): - resume = float(resumeTime) / 60 - percentage = int((resume / duration) * 100.0) - return {'Duration' : tempDuration, - 'TotalTime' : tempDuration, - 'Percent' : str(percentage), - 'ResumeTime' : str(resume) - } + people = item['People'] + + except: pass + + else: + + for person in people: + + type = person['Type'] + Name = person['Name'] + + if "Director" in type: + director.append(Name) + elif "Writing" in type: + writer.append(Name) + elif "Writer" in type: + writer.append(Name) + elif "Actor" in type: + cast.append(Name) + + return { + + 'Director': director, + 'Writer': writer, + 'Cast': cast + } + + def getTimeInfo(self, item): + # Runtime and Resume point + tempRuntime = 0 + runtime = 0 + resume = 0 + + try: # Get resume point + userdata = item['UserData'] + playbackPosition = userdata['PlaybackPositionTicks'] + resume = playbackPosition / 10000000.0 + except: pass + + try: # Get total runtime + tempRuntime = item['RunTimeTicks'] + + except: + try: tempRuntime = item['CumulativeRunTimeTicks'] + except: pass + + finally: + runtime = tempRuntime / 10000000.0 + + + return { + + 'ResumeTime': resume, + 'TotalTime': runtime + } def getStudios(self, item): # Process Studio - studios = [] - if item.get("SeriesStudio") != None and item.get("SeriesStudio") != '': - studios.append(item.get("SeriesStudio")) - else: - if(item.get("Studios") != []): - for studio_string in item.get("Studios"): - temp=studio_string.get("Name") - studios.append(temp) + studios = [] + + try: + studio = item['SeriesStudio'] + studios.append(studio) + except: + try: + studioArray = item['Studios'] + for studio in studioArray: + studios.append(studio['Name']) + except: pass + return studios - def getMediaStreams(self, item, mediaSources=False): - # Process MediaStreams - channels = '' - videocodec = '' - audiocodec = '' - audiolanguage = '' - subtitlelanguage = '' - height = '' - width = '' - aspectratio = '1:1' - aspectfloat = 1.85 - Video3DFormat = '' + def getGenre(self,item): + genre = "" + genres = item.get("Genres") + if genres != None and genres != []: + for genre_string in genres: + if genre == "": #Just take the first genre + genre = genre_string + else: + genre = genre + " / " + genre_string + elif item.get("SeriesGenres") != None and item.get("SeriesGenres") != '': + genres = item.get("SeriesGenres") + if genres != None and genres != []: + for genre_string in genres: + if genre == "": #Just take the first genre + genre = genre_string + else: + genre = genre + " / " + genre_string + return genre - if mediaSources == True: - mediaSources = item.get("MediaSources") - if(mediaSources != None): - MediaStreams = mediaSources[0].get("MediaStreams") - else: + def getMediaStreams(self, item, mediaSources = False): + + videotracks = [] # Height, Width, Codec, AspectRatio, AspectFloat, 3D + audiotracks = [] # Codec, Channels, language + subtitlelanguages = [] # Language + + if mediaSources: + try: + MediaStreams = item['MediaSources'][0]['MediaStreams'] + except: MediaStreams = None else: - MediaStreams = item.get("MediaStreams") - if(MediaStreams != None): - #mediaStreams = MediaStreams[0].get("MediaStreams") - if(MediaStreams != None): - for mediaStream in MediaStreams: - if(mediaStream.get("Type") == "Video"): - videocodec = mediaStream.get("Codec") - if mediaStream.get("Height"): - height = int(mediaStream.get("Height")) - if mediaStream.get("Width"): - width = int(mediaStream.get("Width")) - aspectratio = mediaStream.get("AspectRatio") - Video3DFormat = item.get("Video3DFormat") - if aspectratio != None and len(aspectratio) >= 3: - try: - aspectwidth,aspectheight = aspectratio.split(':') - aspectfloat = float(aspectwidth) / float(aspectheight) - except: - aspectfloat = 1.85 - if(mediaStream.get("Type") == "Audio"): - isdefault = mediaStream.get("IsDefault") == "true" - if audiocodec == '': - audiocodec = mediaStream.get("Codec") - if channels == '': - channels = mediaStream.get("Channels") - if audiolanguage == '': - audiolanguage = mediaStream.get("Language") - # only overwrite if default - if isdefault: - audiocodec = mediaStream.get("Codec") - channels = mediaStream.get("Channels") - audiolanguage = mediaStream.get("Language") - if(mediaStream.get("Type") == "Subtitle"): - isdefault = mediaStream.get("IsDefault") == "true" - if subtitlelanguage == '': - subtitlelanguage = mediaStream.get("Language") - # only overwrite if default - if isdefault: - subtitlelanguage = mediaStream.get("Language") - - - return {'channels' : str(channels), - 'videocodec' : videocodec, - 'audiocodec' : audiocodec, - 'audiolanguage' : audiolanguage, - 'subtitlelanguage' : subtitlelanguage, - 'height' : height, - 'width' : width, - 'aspectratio' : aspectfloat, - '3dformat' : Video3DFormat - } + MediaStreams = item.get('MediaStreams') + + if MediaStreams: + # Sort through the Video, Audio, Subtitle tracks + for mediaStream in MediaStreams: + + type = mediaStream.get("Type", "") + + if "Video" in type: + videotrack = {} + videotrack['videocodec'] = mediaStream.get('Codec') + videotrack['height'] = mediaStream.get('Height') + videotrack['width'] = mediaStream.get('Width') + videotrack['aspectratio'] = mediaStream.get('AspectRatio') + videotrack['Video3DFormat'] = item.get('Video3DFormat') + if len(videotrack['aspectratio']) >= 3: + try: + aspectwidth, aspectheight = aspectratio.split(':') + videotrack['aspectfloat'] = float(aspectwidth) / float(aspectheight) + except: + videotrack['aspectfloat'] = 1.85 + videotracks.append(videotrack) + + elif "Audio" in type: + audiotrack = {} + audiotrack['audiocodec'] = mediaStream.get('Codec') + audiotrack['channels'] = mediaStream.get('Channels') + audiotrack['audiolanguage'] = mediaStream.get('Language') + audiotracks.append(audiotrack) + + elif "Subtitle" in type: + try: + subtitlelanguages.append(mediaStream['Language']) + except: + subtitlelanguages.append("Unknown") + + return { + + 'videocodec' : videotracks, + 'audiocodec' : audiotracks, + 'subtitlelanguage' : subtitlelanguages + } + def getChecksum(self, item): # use the etags checksum for this if available @@ -169,109 +185,62 @@ class API(): return checksum def getUserData(self, item): - userData = item.get("UserData") - resumeTime = 0 - if(userData != None): - if userData.get("Played") != True: - watched="True" - else: - watched="False" - if userData.get("IsFavorite") == True: - favorite=True - else: - favorite=False - if(userData.get("Played") == True): - # Cover the Emby scenario where item is played but playcount is 0. - playcount = userData.get('PlayCount') + # Default + favorite = False + playcount = None + lastPlayedDate = None + userKey = "" + + try: + userdata = item['UserData'] + + except: # No userdata found. + pass + + else: + favorite = userdata['IsFavorite'] + userKey = userdata.get('Key', "") + + watched = userdata['Played'] + if watched: + # Playcount is tied to the watch status + playcount = userdata['PlayCount'] if playcount == 0: playcount = 1 else: - playcount="0" - if userData.get('UnplayedItemCount') != None: - UnplayedItemCount = userData.get('UnplayedItemCount') - else: - UnplayedItemCount = "0" - if userData.get('LastPlayedDate') != None: - #TODO--> is there some other way to do this ? - datestring = userData.get('LastPlayedDate').split('T')[0] - timestring = userData.get('LastPlayedDate').split('T')[1] - timestring = timestring.split('.')[0] - LastPlayedDate = datestring + " " + timestring - else: - LastPlayedDate = None - if userData.get('PlaybackPositionTicks') != None: - PlaybackPositionTicks = userData.get('PlaybackPositionTicks') - else: - PlaybackPositionTicks = '' - userKey = userData.get("Key", "") - return {'Watched' : watched, - 'Favorite' : favorite, - 'PlayCount': playcount, - 'LastPlayedDate': LastPlayedDate, - 'UnplayedItemCount' : UnplayedItemCount, - 'PlaybackPositionTicks' : str(PlaybackPositionTicks), - 'Key' : userKey - } - - def getGenre(self,item): - genre = "" - genres = item.get("Genres") - if genres != None and genres != []: - for genre_string in genres: - if genre == "": #Just take the first genre - genre = genre_string - else: - genre = genre + " / " + genre_string - elif item.get("SeriesGenres") != None and item.get("SeriesGenres") != '': - genres = item.get("SeriesGenres") - if genres != None and genres != []: - for genre_string in genres: - if genre == "": #Just take the first genre - genre = genre_string - else: - genre = genre + " / " + genre_string - return genre - - def getName(self, item): - Temp = item.get("Name") - if Temp == None: - Temp = "" - Name=Temp.encode('utf-8') - return Name + playcount = None + + lastPlayedDate = userdata.get('LastPlayedDate', None) + if lastPlayedDate: + lastPlayedDate = lastPlayedDate.split('.')[0].replace('T', " ") + + return { + + 'Favorite': favorite, + 'PlayCount': playcount, + 'LastPlayedDate': lastPlayedDate, + 'Key': userKey + } + def getRecursiveItemCount(self, item): if item.get("RecursiveItemCount") != None: return str(item.get("RecursiveItemCount")) else: - return "0" - - def getSeriesName(self, item): - Temp = item.get("SeriesName") - if Temp == None: - Temp = "" - Name=Temp.encode('utf-8') - return Name + return "0" def getOverview(self, item): - Temp = item.get("Overview") - if Temp == None: - Temp='' - Overview1=Temp.encode('utf-8') - Overview=str(Overview1) - Overview=Overview.replace("\"", "\'") - Overview=Overview.replace("\n", " ") - Overview=Overview.replace("\r", " ") - return Overview - - def getPremiereDate(self, item): - if(item.get("PremiereDate") != None): - premieredatelist = (item.get("PremiereDate")).split("T") - premieredate = premieredatelist[0] - else: - premieredate = "" - Temp = premieredate - premieredate = Temp.encode('utf-8') - return premieredate + + overview = "" + + try: + overview = item['Overview'] + overview = overview.replace("\"", "\'") + overview = overview.replace("\n", " ") + overview = overview.replace("\r", " ") + except: pass + + return overview def getTVInfo(self, item, userData): TotalSeasons = 0 if item.get("ChildCount")==None else item.get("ChildCount") @@ -306,15 +275,105 @@ class API(): 'Episode' : tempEpisode, 'SeriesName' : SeriesName } + def getDateCreated(self, item): - tempDate = item.get("DateCreated") - if tempDate != None: - tempDate = tempDate.split("T")[0] - date = tempDate.split("-") - tempDate = date[2] + "." + date[1] + "." +date[0] - else: - tempDate = "01.01.2000" - return tempDate + + dateadded = None + + try: + dateadded = item['DateCreated'] + dateadded = dateadded.split('.')[0].replace('T', " ") + except: pass + + return dateadded + + def getPremiereDate(self, item): + + premiere = None + + try: + premiere = item['PremiereDate'] + premiere = premiere.split('.')[0].replace('T', " ") + except: pass + + return premiere + + def getTagline(self, item): + + tagline = None + + try: + tagline = item['Taglines'][0] + except: pass + + return tagline + + def getProvider(self, item, providername): + # Provider Name: imdb or tvdb + provider = None + + try: + if "imdb" in providername: + provider = item['ProviderIds']['Imdb'] + elif "tvdb" in providername: + provider = item['ProviderIds']['Tvdb'] + except: pass + + return provider + + def getCountry(self, item): + + country = None + + try: + country = item['ProductionLocations'][0] + except: pass + + return country + + def getArtworks(self, data, type, mediaType = "", index = "0", getAll = False): + + """ + Get all artwork, it will return an empty string + for the artwork type not found. + + Index only matters when getAll is False. + + mediaType: movie, boxset, tvshow, episode, season + + Artwork type: Primary, Banner, Logo, Art, Thumb, + Disc Backdrop + """ + id = data['Id'] + + maxHeight = 10000 + maxWidth = 10000 + imageTag = "e3ab56fe27d389446754d0fb04910a34" # Place holder tag + + + if getAll: + + allartworks = { + + 'Primary': "", + 'Banner': "", + 'Logo': "", + 'Art': "", + 'Thumb': "", + 'Disc': "", + 'Backdrop': "" + } + + for keytype in allartworks: + type = keytype + url = "" + + allartworks[keytype] = url + + + return allartworks + + else: pass def getArtwork(self, data, type, mediaType = "", index = "0", userParentInfo = False): @@ -416,6 +475,14 @@ class API(): artwork='' return artwork + + def imageUrl(self, id, type, index, width, height): + + WINDOW = xbmcgui.Window(10000) + username = WINDOW.getProperty('currUser') + server = WINDOW.getProperty('server%s' % username) + # For people image - actors, directors, writers + return "%s/mediabrowser/Items/%s/Images/%s?MaxWidth=%s&MaxHeight=%s&Index=%s" % (server, id, type, width, height, index) def getUserArtwork(self, data, type, index = "0"): diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index bc5482b2..7610558c 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -659,61 +659,67 @@ class LibrarySync(threading.Thread): # Delete from Kodi before Emby # To be able to get mediaType doUtils = DownloadUtils() - - video = [] + video = {} music = [] - - itemIds = ','.join(itemList) - url = "{server}/mediabrowser/Users/{UserId}/Items?Ids=%s&format=json" % itemIds - result = doUtils.downloadUrl(url) - - if result is "": - # Websocket feedback - self.logMsg("Item %s is removed." % itemIds) - return - for item in result[u'Items']: - # Sort by type for database deletion - itemId = item["Id"] - mediaType = item["MediaType"] + # Database connection to myVideosXX.db + connectionvideo = utils.KodiSQL() + cursorvideo = connectionvideo.cursor() + # Database connection to myMusicXX.db + connectionmusic = utils.KodiSQL("music") + cursormusic = connectionmusic.cursor() - if "Video" in mediaType: - video.append(itemId) - elif "Audio" in mediaType: - music.append(itemId) + for item in itemList: + # Sort by type for database deletion + try: # Search video database + self.logMsg("Check video database.", 1) + cursorvideo.execute("SELECT media_type FROM emby WHERE emby_id = ?", (item,)) + mediatype = cursorvideo.fetchone()[0] + video[item] = mediatype + #video.append(itemtype) + except: + self.logMsg("Check music database.", 1) + try: # Search music database + cursormusic.execute("SELECT media_type FROM emby WHERE emby_id = ?", (item,)) + cursormusic.fetchone()[0] + music.append(item) + except: self.logMsg("Item %s is not found in Kodi database." % item, 1) if len(video) > 0: - #Process video library - connection = utils.KodiSQL("video") - cursor = connection.cursor() - + connection = connectionvideo + cursor = cursorvideo + # Process video library for item in video: - type = ReadKodiDB().getTypeByEmbyId(item, connection, cursor) - self.logMsg("Type: %s" % type) - self.logMsg("Message: Doing LibraryChanged: Items Removed: Calling deleteItemFromKodiLibrary: %s" % item, 0) + + type = video[item] + self.logMsg("Doing LibraryChanged: Items Removed: Calling deleteItemFromKodiLibrary: %s" % item, 1) + if "episode" in type: # Get the TV Show Id for reference later showId = ReadKodiDB().getShowIdByEmbyId(item, connection, cursor) - self.logMsg("ShowId: %s" % showId, 0) + self.logMsg("ShowId: %s" % showId, 1) WriteKodiVideoDB().deleteItemFromKodiLibrary(item, connection, cursor) # Verification if "episode" in type: showTotalCount = ReadKodiDB().getShowTotalCount(showId, connection, cursor) - self.logMsg("ShowTotalCount: %s" % showTotalCount, 0) + self.logMsg("ShowTotalCount: %s" % showTotalCount, 1) # If there are no episodes left if showTotalCount == 0 or showTotalCount == None: # Delete show embyId = ReadKodiDB().getEmbyIdByKodiId(showId, "tvshow", connection, cursor) - self.logMsg("Message: Doing LibraryChanged: Deleting show: %s" % embyId, 0) + self.logMsg("Message: Doing LibraryChanged: Deleting show: %s" % embyId, 1) WriteKodiVideoDB().deleteItemFromKodiLibrary(embyId, connection, cursor) connection.commit() - cursor.close() + # Close connection + cursorvideo.close() if len(music) > 0: + connection = connectionmusic + cursor = cursormusic #Process music library - addon = xbmcaddon.Addon(id='plugin.video.emby') - if addon.getSetting("enableMusicSync") is "true": + addon = xbmcaddon.Addon() + if addon.getSetting('enableMusicSync') == "true": connection = utils.KodiSQL("music") cursor = connection.cursor() @@ -722,35 +728,34 @@ class LibrarySync(threading.Thread): WriteKodiMusicDB().deleteItemFromKodiLibrary(item, connection, cursor) connection.commit() - cursor.close() + # Close connection + cursormusic.close() if deleteEmbyItem: for item in itemList: url = "{server}/mediabrowser/Items/%s" % item self.logMsg('Deleting via URL: %s' % url) - doUtils.downloadUrl(url, type="DELETE") + doUtils.downloadUrl(url, type = "DELETE") xbmc.executebuiltin("Container.Refresh") def remove_items(self, itemsRemoved): - + # websocket client self.removeItems.extend(itemsRemoved) def update_items(self, itemsToUpdate): - # doing adds and updates + # websocket client if(len(itemsToUpdate) > 0): - self.logMsg("Message : Doing LibraryChanged : Processing Added and Updated : " + str(itemsToUpdate), 0) + self.logMsg("Doing LibraryChanged : Processing Added and Updated : " + str(itemsToUpdate), 0) self.updateItems.extend(itemsToUpdate) - self.doIncrementalSync = True def user_data_update(self, userDataList): - # do full playcount update for now + # websocket client for userData in userDataList: itemId = userData.get("ItemId") if(itemId != None): self.updateItems.append(itemId) if(len(self.updateItems) > 0): - self.logMsg("Message : Doing UserDataChanged : Processing Updated : " + str(self.updateItems), 0) - self.doIncrementalSync = True + self.logMsg("Doing UserDataChanged : Processing Updated : " + str(self.updateItems), 0) def ShouldStop(self): @@ -770,32 +775,44 @@ class LibrarySync(threading.Thread): while not self.KodiMonitor.abortRequested(): + # In the event the server goes offline after + # the thread has already been started. + while self.suspendClient == True: + # The service.py will change self.suspendClient to False + if self.KodiMonitor.waitForAbort(5): + # Abort was requested while waiting. We should exit + break + # Library sync if not startupComplete: # Run full sync self.logMsg("Doing_Db_Sync: syncDatabase (Started)", 1) + startTime = datetime.now() libSync = self.FullLibrarySync() - self.logMsg("Doing_Db_Sync: syncDatabase (Finished) %s" % libSync, 1) + elapsedTime = datetime.now() - startTime + self.logMsg("Doing_Db_Sync: syncDatabase (Finished in: %s) %s" % (str(elapsedTime).split('.')[0], libSync), 1) if libSync: startupComplete = True - if WINDOW.getProperty("OnWakeSync") == "true": + # Set via Kodi Monitor event + if WINDOW.getProperty("OnWakeSync") == "true" and WINDOW.getProperty('Server_online') == "true": WINDOW.clearProperty("OnWakeSync") if WINDOW.getProperty("SyncDatabaseRunning") != "true": - utils.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Started)",0) + self.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Started)", 0) libSync = self.FullLibrarySync() - utils.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Finished) " + str(libSync),0) + self.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Finished) " + str(libSync), 0) - if self.doIncrementalSync: - # Add or update item to Kodi library + if len(self.updateItems) > 0: + # Add or update items + self.logMsg("Processing items: %s" % (str(self.updateItems)), 1) listItems = self.updateItems self.updateItems = [] - self.doIncrementalSync = False self.IncrementalSync(listItems) if len(self.removeItems) > 0: # Remove item from Kodi library + self.logMsg("Removing items: %s" % self.removeItems, 1) listItems = self.removeItems self.removeItems = [] self.removefromDB(listItems) @@ -805,3 +822,11 @@ class LibrarySync(threading.Thread): break self.logMsg("--- Library Sync Thread stopped ---", 0) + + def suspendClient(self): + self.suspendClient = True + self.logMsg("--- Library Sync Thread paused ---", 0) + + def resumeClient(self): + self.suspendClient = False + self.logMsg("--- Library Sync Thread resumed ---", 0) diff --git a/resources/lib/PlayUtils.py b/resources/lib/PlayUtils.py index 47b167be..fdbe715a 100644 --- a/resources/lib/PlayUtils.py +++ b/resources/lib/PlayUtils.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + ################################################################################################# # utils class ################################################################################################# @@ -19,8 +21,7 @@ class PlayUtils(): clientInfo = ClientInformation() addonName = clientInfo.getAddonName() - addonId = clientInfo.getAddonId() - addon = xbmcaddon.Addon(id=addonId) + addon = xbmcaddon.Addon() audioPref = addon.getSetting('Audiopref') subsPref = addon.getSetting('Subspref') @@ -35,76 +36,36 @@ class PlayUtils(): def getPlayUrl(self, server, id, result): - addon = self.addon WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') server = WINDOW.getProperty('server%s' % username) - if self.isDirectPlay(result): - try: - # Try direct play - playurl = self.directPlay(result) - if not playurl: - # Let user know that direct play failed - resp = xbmcgui.Dialog().select('Warning: Unable to direct play.', ['Play from HTTP', 'Play from HTTP and remember next time.']) - if resp > -1: - # Play from HTTP - playurl = self.directStream(result, server, id) - if resp == 1: - # Remember next time - addon.setSetting('playFromStream', "true") - if not playurl: - # Try transcoding - playurl = self.transcoding(result, server, id) - WINDOW.setProperty("transcoding%s" % id, "true") - self.logMsg("File is transcoding.", 1) - WINDOW.setProperty("%splaymethod" % playurl, "Transcode") - else: - self.logMsg("File is direct streaming.", 1) - WINDOW.setProperty("%splaymethod" % playurl, "DirectStream") - else: - # User decided not to proceed. - self.logMsg("Unable to direct play. Verify the following path is accessible by the device: %s. You might also need to add SMB credentials in the addon settings." % result[u'MediaSources'][0][u'Path']) - return False - else: - self.logMsg("File is direct playing.", 1) - WINDOW.setProperty("%splaymethod" % playurl.encode('utf-8'), "DirectPlay") - except: - return False + if self.isDirectPlay(result,True): + # Try direct play + playurl = self.directPlay(result) + if playurl: + self.logMsg("File is direct playing.", 1) + WINDOW.setProperty("%splaymethod" % playurl.encode('utf-8'), "DirectPlay") elif self.isDirectStream(result): - try: - # Try direct stream - playurl = self.directStream(result, server, id) - if not playurl: - # Try transcoding - playurl = self.transcoding(result, server, id) - WINDOW.setProperty("transcoding%s" % id, "true") - self.logMsg("File is transcoding.", 1) - WINDOW.setProperty("%splaymethod" % playurl, "Transcode") - else: - self.logMsg("File is direct streaming.", 1) - WINDOW.setProperty("%splaymethod" % playurl, "DirectStream") - except: - return False + # Try direct stream + playurl = self.directStream(result, server, id) + if playurl: + self.logMsg("File is direct streaming.", 1) + WINDOW.setProperty("%splaymethod" % playurl, "DirectStream") - elif self.isTranscoding(result): - try: - # Try transcoding - playurl = self.transcoding(result, server, id) - WINDOW.setProperty("transcoding%s" % id, "true") + else:# Try transcoding + playurl = self.transcoding(result, server, id) + if playurl: self.logMsg("File is transcoding.", 1) WINDOW.setProperty("%splaymethod" % playurl, "Transcode") - except: - return False return playurl.encode('utf-8') - - def isDirectPlay(self, result): + def isDirectPlay(self, result, dialog=False): # Requirements for Direct play: # FileSystem, Accessible path - self.addon = xbmcaddon.Addon(id=self.addonId) + self.addon = xbmcaddon.Addon() playhttp = self.addon.getSetting('playFromStream') # User forcing to play via HTTP instead of SMB @@ -126,17 +87,30 @@ class PlayUtils(): return True else: self.logMsg("Can't direct play: Unable to locate the content.", 1) + if dialog: + # Let user know that direct play failed + resp = xbmcgui.Dialog().select('Warning: Unable to direct play.', ['Play from HTTP', 'Play from HTTP and remember next time.']) + if resp == 1: + # Remember next time + addon.setSetting('playFromStream', "true") + else: + # User decided not to proceed. + self.logMsg("Unable to direct play. Verify the following path is accessible by the device: %s. You might also need to add SMB credentials in the addon settings." % result[u'MediaSources'][0][u'Path']) return False def directPlay(self, result): addon = self.addon - try: - # Item can be played directly - playurl = result[u'MediaSources'][0][u'Path'] - + try: + playurl = result[u'MediaSources'][0][u'Path'] + except: + playurl = result[u'Path'] + except: + self.logMsg("Direct play failed. Trying Direct stream.", 1) + return False + else: if u'VideoType' in result: # Specific format modification if u'Dvd' in result[u'VideoType']: @@ -156,19 +130,15 @@ class PlayUtils(): playurl = playurl.replace("\\", "/") if "apple.com" in playurl: - USER_AGENT = 'QuickTime/7.7.4' + USER_AGENT = "QuickTime/7.7.4" playurl += "?|User-Agent=%s" % USER_AGENT if ":" not in playurl: - self.logMsg("Path seems invalid: %s" % playurl) + self.logMsg("Path seems invalid: %s" % playurl, 1) return False return playurl - except: - self.logMsg("Direct play failed. Trying Direct stream.", 1) - return False - def isDirectStream(self, result): # Requirements for Direct stream: # FileSystem or Remote, BitRate, supported encoding @@ -188,23 +158,24 @@ class PlayUtils(): return True - def directStream(self, result, server, id, type="Video"): + def directStream(self, result, server, id, type = "Video"): try: - if type == "Video": - # Play with Direct Stream + if "ThemeVideo" in type: + playurl ="%s/mediabrowser/Videos/%s/stream?static=true" % (server, id) + + elif "Video" in type: playurl = "%s/mediabrowser/Videos/%s/stream?static=true" % (server, id) - elif type == "Audio": + # Verify audio and subtitles + mediaSources = result[u'MediaSources'] + if mediaSources[0].get('DefaultAudioStreamIndex') != None: + playurl = "%s&AudioStreamIndex=%s" % (playurl, mediaSources[0].get('DefaultAudioStreamIndex')) + if mediaSources[0].get('DefaultSubtitleStreamIndex') != None: + playurl = "%s&SubtitleStreamIndex=%s" % (playurl, mediaSources[0].get('DefaultSubtitleStreamIndex')) + + elif "Audio" in type: playurl = "%s/mediabrowser/Audio/%s/stream.mp3" % (server, id) - return playurl - - mediaSources = result[u'MediaSources'] - if mediaSources[0].get('DefaultAudioStreamIndex') != None: - playurl = "%s&AudioStreamIndex=%s" % (playurl, mediaSources[0].get('DefaultAudioStreamIndex')) - if mediaSources[0].get('DefaultSubtitleStreamIndex') != None: - playurl = "%s&SubtitleStreamIndex=%s" % (playurl, mediaSources[0].get('DefaultSubtitleStreamIndex')) - - self.logMsg("Playurl: %s" % playurl) + return playurl except: @@ -329,7 +300,7 @@ class PlayUtils(): # Local or Network path self.logMsg("Path exists.", 2) return True - elif ":\\" not in path: + elif "nfs:" in path.lower(): # Give benefit of the doubt. self.logMsg("Can't verify path. Still try direct play.", 2) return True diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index 26ea1daf..f4327ab9 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -1,223 +1,222 @@ +# -*- coding: utf-8 -*- + ################################################################################################# # WriteKodiVideoDB ################################################################################################# +import sqlite3 +from os.path import basename import xbmc import xbmcgui import xbmcaddon -import xbmcvfs -import json -import urllib -import sqlite3 -import os -from decimal import Decimal - +from ClientInformation import ClientInformation +import Utils as utils +from API import API from DownloadUtils import DownloadUtils from PlayUtils import PlayUtils from ReadKodiDB import ReadKodiDB from ReadEmbyDB import ReadEmbyDB from TextureCache import TextureCache -from API import API -import Utils as utils -from xml.etree.ElementTree import Element, SubElement, Comment, tostring -from xml.etree import ElementTree -from xml.dom import minidom -import xml.etree.cElementTree as ET class WriteKodiVideoDB(): textureCache = TextureCache() + doUtils = DownloadUtils() + kodiversion = int(xbmc.getInfoLabel("System.BuildVersion")[:2]) - def updatePlayCountFromKodi(self, id, type, playcount=0): - #when user marks item watched from kodi interface update this in Emby + addon = xbmcaddon.Addon() + addonName = ClientInformation().getAddonName() + WINDOW = xbmcgui.Window(10000) + + username = WINDOW.getProperty('currUser') + userid = WINDOW.getProperty('userId%s' % username) + server = WINDOW.getProperty('server%s' % username) + + directpath = addon.getSetting('useDirectPaths') == "true" + + def logMsg(self, msg, lvl = 1): + + className = self.__class__.__name__ + utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl)) + + def updatePlayCountFromKodi(self, id, type, playcount = 0): + + # When user marks item watched from kodi interface update this in Emby + # Erase resume point when user marks watched/unwatched to follow Emby behavior + doUtils = self.doUtils + self.logMsg("updatePlayCountFromKodi Called", 2) - utils.logMsg("Emby", "updatePlayCountFromKodi Called") connection = utils.KodiSQL() cursor = connection.cursor() - cursor.execute("SELECT emby_id FROM emby WHERE media_type=? AND kodi_id=?",(type,id)) - - emby_id = cursor.fetchone() + cursor.execute("SELECT emby_id FROM emby WHERE media_type = ? AND kodi_id = ?", (type, id,)) - if(emby_id != None): - emby_id = emby_id[0] - # Erase resume point when user marks watched/unwatched to follow Emby behavior - addon = xbmcaddon.Addon(id='plugin.video.emby') - downloadUtils = DownloadUtils() + try: # Find associated Kodi Id to Emby Id + emby_id = cursor.fetchone()[0] + except: + # Could not find the Emby Id + self.logMsg("Emby Id not found.", 2) + else: + # Found the Emby Id, let Emby server know of new playcount watchedurl = "{server}/mediabrowser/Users/{UserId}/PlayedItems/%s" % emby_id if playcount != 0: - downloadUtils.downloadUrl(watchedurl, type="POST") + doUtils.downloadUtils(watchedurl, type = "POST") else: - downloadUtils.downloadUrl(watchedurl, type="DELETE") - + doUtils.downloadUtils(watchedurl, type = "DELETE") + # Erase any resume point associated self.setKodiResumePoint(id, 0, 0, cursor) - cursor.close + finally: + cursor.close - def addOrUpdateMovieToKodiLibrary( self, embyId ,connection, cursor, viewTag): - - addon = xbmcaddon.Addon(id='plugin.video.emby') - WINDOW = xbmcgui.Window(10000) - username = WINDOW.getProperty('currUser') - userid = WINDOW.getProperty('userId%s' % username) - server = WINDOW.getProperty('server%s' % username) - downloadUtils = DownloadUtils() + def addOrUpdateMovieToKodiLibrary(self, embyId, connection, cursor, viewTag): + addon = self.addon MBitem = ReadEmbyDB().getFullItem(embyId) if not MBitem: - utils.logMsg("ADD movie to Kodi library FAILED", "Item %s not found on server!" %embyId) + self.logMsg("ADD movie to Kodi library FAILED", "Item %s not found on server!" % embyId) return # If the item already exist in the local Kodi DB we'll perform a full item update # If the item doesn't exist, we'll add it to the database - cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) - result = cursor.fetchone() - if result != None: - movieid = result[0] - else: + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (embyId,)) + try: + movieid = cursor.fetchone()[0] + except: movieid = None + self.logMsg("Movie Id: %s not found." % embyId, 2) timeInfo = API().getTimeInfo(MBitem) - userData=API().getUserData(MBitem) + userData = API().getUserData(MBitem) people = API().getPeople(MBitem) - - #### The movie details ######### - runtime = int(timeInfo.get('Duration'))*60 - plot = utils.convertEncoding(API().getOverview(MBitem)) - title = utils.convertEncoding(MBitem["Name"]) - sorttitle = utils.convertEncoding(MBitem["SortName"]) - year = MBitem.get("ProductionYear") - rating = MBitem.get("CommunityRating") - mpaa = MBitem.get("OfficialRating") - genres = MBitem.get("Genres") - genre = " / ".join(genres) + genres = MBitem.get('Genres') studios = API().getStudios(MBitem) - studio = " / ".join(studios) - writer = " / ".join(people.get("Writer")) - director = " / ".join(people.get("Director")) - country = None - if MBitem.get("ProductionLocations") !=None and MBitem.get("ProductionLocations") != []: - country = MBitem.get("ProductionLocations")[0] - - imdb = None - if MBitem.get("ProviderIds"): - if MBitem.get("ProviderIds").get("Imdb"): - imdb = MBitem.get("ProviderIds").get("Imdb") - if MBitem.get("ShortOverview") != None: - shortplot = utils.convertEncoding(MBitem.get("ShortOverview")) - else: - shortplot = None - - trailerUrl = None - if MBitem.get("LocalTrailerCount") != None and MBitem.get("LocalTrailerCount") > 0: - itemTrailerUrl = "%s/mediabrowser/Users/%s/Items/%s/LocalTrailers?format=json" % (server, userid, MBitem.get("Id")) - jsonData = downloadUtils.downloadUrl(itemTrailerUrl) - if(jsonData != ""): - trailerItem = jsonData - trailerUrl = "plugin://plugin.video.emby/trailer/?id=%s&mode=play" % trailerItem[0][u'Id'] - elif MBitem.get("RemoteTrailers"): - try: - trailerUrl = MBitem.get("RemoteTrailers")[0].get("Url") + #### The movie details #### + playcount = userData.get('PlayCount') + dateplayed = userData.get("LastPlayedDate") + dateadded = API().getDateCreated(MBitem) + checksum = API().getChecksum(MBitem) + + title = MBitem['Name'] + plot = API().getOverview(MBitem) + shortplot = MBitem.get('ShortOverview') + tagline = API().getTagline(MBitem) + votecount = MBitem.get('VoteCount') + rating = MBitem.get('CommunityRating') + writer = " / ".join(people.get('Writer')) + year = MBitem.get('ProductionYear') + imdb = API().getProvider(MBitem, "imdb") + sorttitle = MBitem['SortName'] + runtime = timeInfo.get('TotalTime') + mpaa = MBitem.get('OfficialRating') + genre = " / ".join(genres) + director = " / ".join(people.get('Director')) + studio = " / ".join(studios) + country = API().getCountry(MBitem) + + try: # Verify if there's a local trailer + if MBitem.get('LocalTrailerCount'): + itemTrailerUrl = "{server}/mediabrowser/Users/{UserId}/Items/%s/LocalTrailers?format=json" % embyId + result = self.doUtils.downloadUrl(itemTrailerUrl) + trailerUrl = "plugin://plugin.video.emby/trailer/?id=%s&mode=play" % result[0]['Id'] + # Or get youtube trailer + else: + trailerUrl = MBitem['RemoteTrailers'][0]['Url'] trailerId = trailerUrl.split('=')[1] trailerUrl = "plugin://plugin.video.youtube/play/?video_id=%s" % trailerId - except: - trailerUrl = MBitem.get("RemoteTrailers")[0].get("Url") - - if MBitem.get("DateCreated") != None: - dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") - else: - dateadded = None - - if userData.get("PlayCount") != "0": - playcount = int(userData.get('PlayCount')) - else: - playcount = None #playcount must be set to NULL in the db - - votecount = MBitem.get("VoteCount") - - tagline = None - if MBitem.get("Taglines") != None and MBitem.get("Taglines") != []: - tagline = MBitem.get("Taglines")[0] + except: + trailerUrl = None #### ADD OR UPDATE THE FILE AND PATH ########### #### NOTE THAT LASTPLAYED AND PLAYCOUNT ARE STORED AT THE FILE ENTRY - if addon.getSetting('useDirectPaths') == 'true': - playurl = PlayUtils().directPlay(MBitem) - if playurl == False: - return - elif "\\" in playurl: - filename = playurl.rsplit("\\",1)[-1] - path = playurl.replace(filename, "") - elif "/" in playurl: - filename = playurl.rsplit("/",1)[-1] - path = playurl.replace(filename, "") - else: - path = "plugin://plugin.video.emby/movies/%s/" % MBitem["Id"] - filename = "plugin://plugin.video.emby/movies/%s/?id=%s&mode=play" % (MBitem["Id"],MBitem["Id"]) - - #create the path - cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,)) - result = cursor.fetchone() - if result != None: - pathid = result[0] - else: - cursor.execute("select coalesce(max(idPath),0) as pathid from path") - pathid = cursor.fetchone()[0] - pathid = pathid + 1 - pathsql = "insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" - cursor.execute(pathsql, (pathid,path,"movies","metadata.local",1)) - #create the file if not exists - cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ? and idPath = ?",(filename,pathid,)) - result = cursor.fetchone() - if result != None: - fileid = result[0] - if result == None: - cursor.execute("select coalesce(max(idFile),0) as fileid from files") + # Get the real filename for direct path or media flags for plugin path + playurl = PlayUtils().directPlay(MBitem) + try: + fileext = basename(playurl) + except: return # playurl returned False + else: # Set filename and path + + if self.directpath: + # Use direct paths instead of add-on redirect + filename = fileext + path = playurl.replace(filename, "") + + else: # Set plugin path and media flags using real filename + filename = "plugin://plugin.video.emby/movies/%s/?filename=%s&id=%s&mode=play" % (embyId, fileext, embyId) + path = "plugin://plugin.video.emby/movies/%s/" % embyId + + # Remove Kodi bookmark - messes with plugin path bookmark + cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ?", (fileext,)) + try: + result = cursor.fetchone()[0] + self.setKodiResumePoint(result, 0, 0, cursor) + except: pass + + + # Validate the path in database + cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?", (path,)) + try: + pathid = cursor.fetchone()[0] + except: + # Path does not exist yet + cursor.execute("select coalesce(max(idPath),0) as pathid from path") + pathid = cursor.fetchone()[0] + 1 + query = "INSERT into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" + cursor.execute(query, (pathid, path, "movies", "metadata.local", 1)) + + # Validate the file in database + cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ? and idPath = ?", (filename, pathid,)) + try: fileid = cursor.fetchone()[0] - fileid = fileid + 1 - pathsql="insert into files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (fileid,pathid,filename,playcount,userData.get("LastPlayedDate"),dateadded)) + except: + # File does not exist yet + cursor.execute("select coalesce(max(idFile),0) as fileid from files") + fileid = cursor.fetchone()[0] + 1 + query = "INSERT INTO files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)" + cursor.execute(query, (fileid, pathid, filename, playcount, dateplayed, dateadded)) + else: # File exists + query = "UPDATE files SET playCount = ?, lastPlayed = ? WHERE idFile = ?" + cursor.execute(query, (playcount, dateplayed, fileid)) + + + ##### UPDATE THE MOVIE ##### + if movieid: + self.logMsg("UPDATE movie to Kodi Library, Id: %s - Title: %s" % (embyId, title), 1) + + query = "UPDATE movie SET c00 = ?, c01 = ?, c02 = ?, c03 = ?, c04 = ?, c05 = ?, c06 = ?, c07 = ?, c09 = ?, c10 = ?, c11 = ?, c12 = ?, c14 = ?, c15 = ?, c16 = ?, c18 = ?, c19 = ?, c21 = ? WHERE idMovie = ?" + cursor.execute(query, (title, plot, shortplot, tagline, votecount, rating, writer, year, imdb, sorttitle, runtime, mpaa, genre, director, title, studio, trailerUrl, country, movieid)) + + # Update the checksum in emby table + query = "UPDATE emby SET checksum = ? WHERE emby_id = ?" + cursor.execute(query, (checksum, embyId)) + + ##### OR ADD THE MOVIE ##### else: - pathsql="update files SET playCount = ?, lastPlayed = ? WHERE idFile = ?" - cursor.execute(pathsql, (playcount,userData.get("LastPlayedDate"), fileid)) - - ##### ADD THE MOVIE ############ - if movieid == None: - - utils.logMsg("ADD movie to Kodi library","Id: %s - Title: %s" % (embyId, title)) - - #create the movie + self.logMsg("ADD movie to Kodi Library, Id: %s - Title: %s" % (embyId, title), 1) + + # Create the movie cursor.execute("select coalesce(max(idMovie),0) as movieid from movie") - movieid = cursor.fetchone()[0] - movieid = movieid + 1 - pathsql="insert into movie(idMovie, idFile, c00, c01, c02, c03, c04, c05, c06, c07, c09, c10, c11, c12, c14, c15, c16, c18, c19, c21) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (movieid, fileid, title, plot, shortplot, tagline, votecount, rating, writer, year, imdb, sorttitle, runtime, mpaa, genre, director, title, studio, trailerUrl, country)) - - #add the viewtag + movieid = cursor.fetchone()[0] + 1 + query = "INSERT INTO movie(idMovie, idFile, c00, c01, c02, c03, c04, c05, c06, c07, c09, c10, c11, c12, c14, c15, c16, c18, c19, c21) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(query, (movieid, fileid, title, plot, shortplot, tagline, votecount, rating, writer, year, imdb, sorttitle, runtime, mpaa, genre, director, title, studio, trailerUrl, country)) + + # Add the viewtag self.AddTagToMedia(movieid, viewTag, "movie", cursor) - - #create the reference in emby table - pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" - cursor.execute(pathsql, (MBitem["Id"], movieid, "movie", API().getChecksum(MBitem))) - - #### UPDATE THE MOVIE ##### - else: - utils.logMsg("UPDATE movie to Kodi library","Id: %s - Title: %s" % (embyId, title)) - pathsql="update movie SET c00 = ?, c01 = ?, c02 = ?, c03 = ?, c04 = ?, c05 = ?, c06 = ?, c07 = ?, c09 = ?, c10 = ?, c11 = ?, c12 = ?, c14 = ?, c15 = ?, c16 = ?, c18 = ?, c19 = ?, c21 = ?WHERE idMovie = ?" - cursor.execute(pathsql, (title, plot, shortplot, tagline, votecount, rating, writer, year, imdb, sorttitle, runtime, mpaa, genre, director, title, studio, trailerUrl, country, movieid)) - - #update the checksum in emby table - cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem),MBitem["Id"])) + + # Create the reference in emby table + query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" + cursor.execute(query, (embyId, movieid, "movie", checksum)) + + + # Update or insert actors + self.AddPeopleToMedia(movieid ,MBitem.get('People'), "movie", connection, cursor) - #update or insert actors - self.AddPeopleToMedia(movieid,MBitem.get("People"),"movie", connection, cursor) - - #update artwork + # Update artwork self.addOrUpdateArt(API().getArtwork(MBitem, "Primary", mediaType = "movie"), movieid, "movie", "thumb", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary", mediaType = "movie"), movieid, "movie", "poster", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Banner", mediaType = "movie"), movieid, "movie", "banner", cursor) @@ -227,158 +226,145 @@ class WriteKodiVideoDB(): self.addOrUpdateArt(API().getArtwork(MBitem, "Disc", mediaType = "movie"), movieid, "movie", "discart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop", mediaType = "movie"), movieid, "movie", "fanart", cursor) - #update genres + # Update genres self.AddGenresToMedia(movieid, genres, "movie", cursor) - #update countries - self.AddCountriesToMedia(movieid, MBitem.get("ProductionLocations"), "movie", cursor) + # Update countries + self.AddCountriesToMedia(movieid, MBitem.get('ProductionLocations'), "movie", cursor) - #update studios + # Update studios self.AddStudiosToMedia(movieid, studios, "movie", cursor) - #add streamdetails + # Add streamdetails self.AddStreamDetailsToMedia(API().getMediaStreams(MBitem), fileid, cursor) - #add to or remove from favorites tag - if userData.get("Favorite"): + # Add to or remove from favorites tag + if userData.get('Favorite'): self.AddTagToMedia(movieid, "Favorite movies", "movie", cursor) else: self.AddTagToMedia(movieid, "Favorite movies", "movie", cursor, True) - #set resume point - resume = int(round(float(timeInfo.get("ResumeTime"))))*60 - total = int(round(float(timeInfo.get("TotalTime"))))*60 + # Set resume point and round to 6th decimal + resume = round(float(timeInfo.get('ResumeTime')), 6) + total = round(float(timeInfo.get('TotalTime')), 6) + jumpback = int(addon.getSetting('resumeJumpBack')) + if resume > jumpback: + # To avoid negative bookmark + resume = resume - jumpback self.setKodiResumePoint(fileid, resume, total, cursor) - def addOrUpdateMusicVideoToKodiLibrary( self, embyId ,connection, cursor): - - addon = xbmcaddon.Addon(id='plugin.video.emby') - WINDOW = xbmcgui.Window(10000) - username = WINDOW.getProperty('currUser') - userid = WINDOW.getProperty('userId%s' % username) - server = WINDOW.getProperty('server%s' % username) - downloadUtils = DownloadUtils() + def addOrUpdateMusicVideoToKodiLibrary(self, embyId ,connection, cursor): + addon = self.addon MBitem = ReadEmbyDB().getFullItem(embyId) if not MBitem: - utils.logMsg("ADD musicvideo to Kodi library FAILED", "Item %s not found on server!" %embyId) + self.logMsg("ADD musicvideo to Kodi library FAILED", "Item %s not found on server!" % embyId, 1) return - + # If the item already exist in the local Kodi DB we'll perform a full item update # If the item doesn't exist, we'll add it to the database - cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) - result = cursor.fetchone() - if result != None: - idMVideo = result[0] - else: + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (embyId,)) + try: + idMVideo = cursor.fetchone()[0] + except: idMVideo = None timeInfo = API().getTimeInfo(MBitem) - userData=API().getUserData(MBitem) + userData = API().getUserData(MBitem) people = API().getPeople(MBitem) - - #### The video details ######### - runtime = int(timeInfo.get('Duration'))*60 - plot = utils.convertEncoding(API().getOverview(MBitem)) - title = utils.convertEncoding(MBitem["Name"]) - year = MBitem.get("ProductionYear") - genres = MBitem.get("Genres") - genre = " / ".join(genres) + genres = MBitem.get('Genres') studios = API().getStudios(MBitem) + + #### The video details #### + playcount = userData.get('PlayCount') + dateplayed = userData.get('LastPlayedDate') + dateadded = API().getDateCreated(MBitem) + checksum = API().getChecksum(MBitem) + + title = MBitem['Name'] + runtime = timeInfo.get('TotalTime') + director = " / ".join(people.get('Director')) studio = " / ".join(studios) - director = " / ".join(people.get("Director")) - artist = " / ".join(MBitem.get("Artists")) - album = MBitem.get("Album") - track = MBitem.get("Track") - - if MBitem.get("DateCreated") != None: - dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") - else: - dateadded = None - - if userData.get("PlayCount") != "0": - playcount = int(userData.get('PlayCount')) - else: - playcount = None #playcount must be set to NULL in the db + year = MBitem.get('ProductionYear') + plot = API().getOverview(MBitem) + album = MBitem.get('Album') + artist = " / ".join(MBitem.get('Artists')) + genre = " / ".join(genres) + track = MBitem.get('Track') #### ADD OR UPDATE THE FILE AND PATH ########### #### NOTE THAT LASTPLAYED AND PLAYCOUNT ARE STORED AT THE FILE ENTRY - if addon.getSetting('useDirectPaths')=='true': - if PlayUtils().isDirectPlay(MBitem): - playurl = PlayUtils().directPlay(MBitem) - #use the direct file path - if "\\" in playurl: - filename = playurl.rsplit("\\",1)[-1] - path = playurl.replace(filename,"") - elif "/" in playurl: - filename = playurl.rsplit("/",1)[-1] - path = playurl.replace(filename,"") - else: - #for transcoding we just use the server's streaming path because I couldn't figure out how to set the plugin path in the music DB - path = server + "/Video/%s/" %MBitem["Id"] - filename = "stream.mp4" - else: - path = "plugin://plugin.video.emby/musicvideos/%s/" % MBitem["Id"] - filename = "plugin://plugin.video.emby/musicvideos/%s/?id=%s&mode=play" % (MBitem["Id"], MBitem["Id"]) - - #create the path - cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,)) - result = cursor.fetchone() - if result != None: - pathid = result[0] - else: - cursor.execute("select coalesce(max(idPath),0) as pathid from path") - pathid = cursor.fetchone()[0] - pathid = pathid + 1 - pathsql = "insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" - cursor.execute(pathsql, (pathid,path,"musicvideos","metadata.local",1)) - #create the file if not exists - cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ? and idPath = ?",(filename,pathid,)) - result = cursor.fetchone() - if result != None: - fileid = result[0] - if result == None: - cursor.execute("select coalesce(max(idFile),0) as fileid from files") + # Set filename and path + if addon.getSetting('useDirectPaths') == "true": + # playurl can return False + playurl = PlayUtils().directPlay(MBitem) + try: + filename = basename(playurl) + path = playurl.replace(filename, "") + except: return# Should we return instead? - for transcoding we just use the server's streaming path because I couldn't figure out how to set the plugin path in the music DB' + else: # Set plugin path + path = "plugin://plugin.video.emby/musicvideos/%s/" % embyId + filename = "plugin://plugin.video.emby/musicvideos/%s/?id=%s&mode=play" % (embyId, embyId) + + + # Validate the path in database + cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?", (path,)) + try: + pathid = cursor.fetchone()[0] + except: + # Path does not exist yet + cursor.execute("select coalesce(max(idPath),0) as pathid from path") + pathid = cursor.fetchone()[0] + 1 + query = "INSERT INTO path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" + cursor.execute(query, (pathid, path, "musicvideos", "metadata.local", 1)) + + # Validate the file in database + cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ? and idPath = ?", (filename, pathid,)) + try: fileid = cursor.fetchone()[0] - fileid = fileid + 1 - pathsql="insert into files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (fileid,pathid,filename,playcount,userData.get("LastPlayedDate"),dateadded)) - else: - pathsql="update files SET playCount = ?, lastPlayed = ? WHERE idFile = ?" - cursor.execute(pathsql, (playcount,userData.get("LastPlayedDate"), fileid)) + query = "UPDATE files SET playCount = ?, lastPlayed = ? WHERE idFile = ?" + cursor.execute(query, (playcount, dateplayed, fileid)) + except: + # File does not exist yet + cursor.execute("select coalesce(max(idFile),0) as fileid from files") + fileid = cursor.fetchone()[0] + 1 + query = "INSERT INTO files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)" + cursor.execute(query, (fileid, pathid, filename, playcount, dateplayed, dateadded)) + - ##### ADD THE VIDEO ############ - if idMVideo == None: - - utils.logMsg("ADD musicvideo to Kodi library","Id: %s - Title: %s" % (embyId, title)) - - #create the video + ##### UPDATE THE MVIDEO ##### + if idMVideo: + self.logMsg("UPDATE musicvideo to Kodi Library, Id: %s - Title: %s" % (embyId, title), 1) + + query = "UPDATE musicvideo SET c00 = ?, c04 = ?, c05 = ?, c06 = ?, c07 = ?, c08 = ?, c09 = ?, c10 = ?, c11 = ?, c12 = ? WHERE idMVideo = ?" + cursor.execute(query, (title, runtime, director, studio, year, plot, album, artist, genre, track, idMVideo)) + + # Update the checksum in emby table + query = "UPDATE emby SET checksum = ? WHERE emby_id = ?" + cursor.execute(query, (checksum, embyId)) + + ##### OR ADD THE MVIDEO ##### + else: + self.logMsg("ADD musicvideo to Kodi Library, Id: %s - Title: %s" % (embyId, title), 1) + + # Create the video cursor.execute("select coalesce(max(idMVideo),0) as idMVideo from musicvideo") - idMVideo = cursor.fetchone()[0] - idMVideo = idMVideo + 1 - pathsql="insert into musicvideo(idMVideo, idFile, c00, c04, c05, c06, c07, c08, c09, c10, c11, c12) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (idMVideo, fileid, title, runtime, director, studio, year, plot, album, artist, genre, track)) - - #create the reference in emby table - pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" - cursor.execute(pathsql, (MBitem["Id"], idMVideo, "musicvideo", API().getChecksum(MBitem))) - - #### UPDATE THE VIDEO ##### - else: - utils.logMsg("UPDATE musicvideo to Kodi library","Id: %s - Title: %s" % (embyId, title)) - pathsql="update musicvideo SET c00 = ?, c04 = ?, c05 = ?, c06 = ?, c07 = ?, c08 = ?, c09 = ?, c10 = ?, c11 = ?, c12 = ? WHERE idMVideo = ?" - cursor.execute(pathsql, (title, runtime, director, studio, year, plot, album, artist, genre, track, idMVideo)) - - #update the checksum in emby table - cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem),MBitem["Id"])) + idMVideo = cursor.fetchone()[0] + 1 + query = "INSERT INTO musicvideo(idMVideo, idFile, c00, c04, c05, c06, c07, c08, c09, c10, c11, c12) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(query, (idMVideo, fileid, title, runtime, director, studio, year, plot, album, artist, genre, track)) + + # Create the reference in emby table + query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" + cursor.execute(query, (embyId, idMVideo, "musicvideo", checksum)) + - #update or insert actors + # Update or insert actors self.AddPeopleToMedia(idMVideo,MBitem.get("People"),"musicvideo", connection, cursor) - #update artwork + # Update artwork self.addOrUpdateArt(API().getArtwork(MBitem, "Primary", mediaType = "musicvideo"), idMVideo, "musicvideo", "thumb", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary", mediaType = "musicvideo"), idMVideo, "musicvideo", "poster", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Banner", mediaType = "musicvideo"), idMVideo, "musicvideo", "banner", cursor) @@ -388,158 +374,140 @@ class WriteKodiVideoDB(): self.addOrUpdateArt(API().getArtwork(MBitem, "Disc", mediaType = "musicvideo"), idMVideo, "musicvideo", "discart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop", mediaType = "musicvideo"), idMVideo, "musicvideo", "fanart", cursor) - #update genres + # Update genres self.AddGenresToMedia(idMVideo, genres, "musicvideo", cursor) - #update studios + # Update studios self.AddStudiosToMedia(idMVideo, studios, "musicvideo", cursor) - #add streamdetails + # Add streamdetails self.AddStreamDetailsToMedia(API().getMediaStreams(MBitem), fileid, cursor) - - #set resume point - resume = int(round(float(timeInfo.get("ResumeTime"))))*60 - total = int(round(float(timeInfo.get("TotalTime"))))*60 - self.setKodiResumePoint(fileid, resume, total, cursor) - def addOrUpdateTvShowToKodiLibrary( self, embyId, connection, cursor, viewTag ): - - addon = xbmcaddon.Addon(id='plugin.video.emby') - port = addon.getSetting('port') - host = addon.getSetting('ipaddress') - server = host + ":" + port + def addOrUpdateTvShowToKodiLibrary(self, embyId, connection, cursor, viewTag): MBitem = ReadEmbyDB().getFullItem(embyId) if not MBitem: - utils.logMsg("ADD tvshow to Kodi library FAILED", "Item %s not found on server!" %embyId) + self.logMsg("ADD tvshow to Kodi library FAILED", "Item %s not found on server!" % embyId) return - - timeInfo = API().getTimeInfo(MBitem) - userData=API().getUserData(MBitem) - - #thumbPath = API().getArtwork(MBitem, "Primary") - + # If the item already exist in the local Kodi DB we'll perform a full item update # If the item doesn't exist, we'll add it to the database - cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) - result = cursor.fetchone() - if result != None: - showid = result[0] - else: + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?", (embyId,)) + try: + showid = cursor.fetchone()[0] + except: showid = None - - #### TV SHOW DETAILS ######### - - genres = MBitem.get("Genres") - genre = " / ".join(genres) - studios = API().getStudios(MBitem) - studio = " / ".join(studios) - mpaa = MBitem.get("OfficialRating") - runtime = int(timeInfo.get('Duration'))*60 - plot = utils.convertEncoding(API().getOverview(MBitem)) - title = utils.convertEncoding(MBitem["Name"]) - sorttitle = utils.convertEncoding(MBitem["SortName"]) - rating = MBitem.get("CommunityRating") - - tvdb = None - if MBitem.get("ProviderIds"): - if MBitem.get("ProviderIds").get("Tvdb"): - tvdb = MBitem.get("ProviderIds").get("Tvdb") - - if MBitem.get("DateCreated") != None: - dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") - else: - dateadded = None - - if MBitem.get("PremiereDate") != None: - premieredatelist = (MBitem.get("PremiereDate")).split("T") - premieredate = premieredatelist[0] - else: - premieredate = None - #create toplevel path as monitored source - needed for things like actors and stuff to work (no clue why) - if addon.getSetting('useDirectPaths')=='true': - smbuser = addon.getSetting('smbusername') - smbpass = addon.getSetting('smbpassword') - # Network share - if smbuser: - playurl = MBitem["Path"].replace("\\\\", "smb://%s:%s@" % (smbuser, smbpass)).replace("\\", "/") - else: - playurl = MBitem["Path"].replace("\\\\", "smb://").replace("\\", "/") - #make sure that the path always ends with a slash - path = utils.convertEncoding(playurl + "/") - toplevelpathstr = path.rsplit("/",2)[1] - toplevelpath = path.replace(toplevelpathstr + "/","") - else: - path = "plugin://plugin.video.emby/tvshows/" + MBitem["Id"] + "/" + timeInfo = API().getTimeInfo(MBitem) + userData = API().getUserData(MBitem) + people = API().getPeople(MBitem) + genres = MBitem.get('Genres') + studios = API().getStudios(MBitem) + + #### The tv show details #### + playcount = userData.get('PlayCount') + dateplayed = userData.get("LastPlayedDate") + dateadded = API().getDateCreated(MBitem) + checksum = API().getChecksum(MBitem) + + title = MBitem['Name'] + plot = API().getOverview(MBitem) + rating = MBitem.get('CommunityRating') + premieredate = API().getPremiereDate(MBitem) + genre = " / ".join(genres) + tvdb = API().getProvider(MBitem, "tvdb") + mpaa = MBitem.get('OfficialRating') + studio = " / ".join(studios) + sorttitle = MBitem['SortName'] + + #### ADD OR UPDATE THE FILE AND PATH ########### + #### TOP LEVEL PATH AS MONITORED SOURCE IS REQUIRED - for actors, etc. (no clue why) + + # Set filename and path + if self.directpath: + playurl = PlayUtils().directPlay(MBitem) + try: # playurl can return False + filename = basename(playurl) + path = playurl.replace(filename, "") + if "\\" in playurl: + temp = "%s\\" % path.rsplit("\\", 2)[1] + elif "/" in playurl: + temp = "%s/" % path.rsplit("/", 2)[1] + toplevelpath = path.replace(temp,"") + except: pass + else: # Set plugin path + path = "plugin://plugin.video.emby/tvshows/%s/" % embyId toplevelpath = "plugin://plugin.video.emby/" - #### ADD THE TV SHOW TO KODI ############## - if showid == None: + + ##### UPDATE THE TV SHOW ##### + if showid: + self.logMsg("UPDATE tvshow to Kodi library, Id: %s - Title: %s" % (embyId, title)) - utils.logMsg("ADD tvshow to Kodi library","Id: %s - Title: %s" % (embyId, title)) + query = "UPDATE tvshow SET c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?, c12 = ?, c13 = ?, c14 = ?, c15 = ? WHERE idShow = ?" + cursor.execute(query, (title, plot, rating, premieredate, genre, title, tvdb, mpaa, studio, sorttitle, showid)) - #create the tv show path - cursor.execute("select coalesce(max(idPath),0) as pathid from path") - pathid = cursor.fetchone()[0] - pathid = pathid + 1 - pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" - cursor.execute(pathsql, (pathid,path,None,None,1)) - cursor.execute("SELECT idPath as tlpathid FROM path WHERE strPath = ?",(toplevelpath,)) - result = cursor.fetchone() - if result == None: - cursor.execute("select coalesce(max(idPath),0) as tlpathid from path") - tlpathid = cursor.fetchone()[0] - tlpathid = tlpathid + 1 - pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" - cursor.execute(pathsql, (tlpathid,toplevelpath,"tvshows","metadata.local",1)) - - #create the tvshow - cursor.execute("select coalesce(max(idShow),0) as showid from tvshow") - showid = cursor.fetchone()[0] - showid = showid + 1 - pathsql="insert into tvshow(idShow, c00, c01, c04, c05, c08, c09, c12, c13, c14, c15) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (showid, title, plot, rating, premieredate, genre, title, tvdb, mpaa, studio, sorttitle)) - - #create the reference in emby table - pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" - cursor.execute(pathsql, (MBitem["Id"], showid, "tvshow", API().getChecksum(MBitem))) - - #link the path - pathsql="insert into tvshowlinkpath(idShow,idPath) values(?, ?)" - cursor.execute(pathsql, (showid,pathid)) - - #add the viewtag - self.AddTagToMedia(showid, viewTag, "tvshow", cursor) - - #### UPDATE THE TV SHOW ############# + # Update the checksum in emby table + query = "UPDATE emby SET checksum = ? WHERE emby_id = ?" + cursor.execute(query, (checksum, embyId)) + + ##### OR ADD THE TV SHOW ##### else: - utils.logMsg("UPDATE tvshow to Kodi library","Id: %s - Title: %s" % (embyId, title)) + self.logMsg("ADD tvshow to Kodi library, Id: %s - Title: %s" % (embyId, title)) - pathsql="UPDATE tvshow SET c00 = ?, c01 = ?, c04 = ?, c05 = ?, c08 = ?, c09 = ?, c12 = ?, c13 = ?, c14 = ?, c15 = ? WHERE idShow = ?" - cursor.execute(pathsql, (title, plot, rating, premieredate, title, genre, tvdb, mpaa, studio, sorttitle, showid)) + # Create the TV show path + cursor.execute("select coalesce(max(idPath),0) as pathid from path") + pathid = cursor.fetchone()[0] + 1 + query = "INSERT INTO path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" + cursor.execute(query, (pathid, path, None, None, 1)) + + # Validate the top level path in database + cursor.execute("SELECT idPath as tlpathid FROM path WHERE strPath = ?", (toplevelpath,)) + try: + cursor.fetchone()[0] + except: + # Top level path does not exist yet + cursor.execute("select coalesce(max(idPath),0) as tlpathid from path") + tlpathid = cursor.fetchone()[0] + 1 + query = "INSERT INTO path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" + cursor.execute(query, (tlpathid, toplevelpath, "tvshows", "metadata.local", 1)) + + # Create the TV show + cursor.execute("select coalesce(max(idShow),0) as showid from tvshow") + showid = cursor.fetchone()[0] + 1 + query = "INSERT INTO tvshow(idShow, c00, c01, c04, c05, c08, c09, c12, c13, c14, c15) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(query, (showid, title, plot, rating, premieredate, genre, title, tvdb, mpaa, studio, sorttitle)) - #update the checksum in emby table - cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem), MBitem["Id"])) + # Create the reference in emby table + query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" + cursor.execute(query, (embyId, showid, "tvshow", checksum)) - #update or insert people - self.AddPeopleToMedia(showid,MBitem.get("People"),"tvshow", connection, cursor) + # Link the path + query = "INSERT INTO tvshowlinkpath(idShow, idPath) values(?, ?)" + cursor.execute(query, (showid, pathid)) + + # Add the viewtag + self.AddTagToMedia(showid, viewTag, "tvshow", cursor) + + + # Update or insert people + self.AddPeopleToMedia(showid, MBitem.get('People'),"tvshow", connection, cursor) - #update genres + # Update genres self.AddGenresToMedia(showid, genres, "tvshow", cursor) - #update studios + # Update studios self.AddStudiosToMedia(showid, studios, "tvshow", cursor) - #add to or remove from favorites tag - if userData.get("Favorite"): + # Add to or remove from favorites tag + if userData.get('Favorite'): self.AddTagToMedia(showid, "Favorite tvshows", "tvshow", cursor) else: self.AddTagToMedia(showid, "Favorite tvshows", "tvshow", cursor, True) - #update artwork + # Update artwork self.addOrUpdateArt(API().getArtwork(MBitem, "Primary", mediaType = "tvshow"), showid, "tvshow", "thumb", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Primary", mediaType = "tvshow"), showid, "tvshow", "poster", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Banner", mediaType = "tvshow"), showid, "tvshow", "banner", cursor) @@ -549,206 +517,202 @@ class WriteKodiVideoDB(): self.addOrUpdateArt(API().getArtwork(MBitem, "Disc", mediaType = "tvshow"), showid, "tvshow", "discart", cursor) self.addOrUpdateArt(API().getArtwork(MBitem, "Backdrop", mediaType = "tvshow"), showid, "tvshow", "fanart", cursor) - #update season details - self.updateSeasons(MBitem["Id"], showid, connection, cursor) + # Update season details + self.updateSeasons(embyId, showid, connection, cursor) def addOrUpdateEpisodeToKodiLibrary(self, embyId, showid, connection, cursor): + addon = self.addon + MBitem = ReadEmbyDB().getFullItem(embyId) + + if not MBitem: + self.logMsg("ADD episode to Kodi library FAILED, Item %s not found on server!" % embyId, 1) + return + # If the episode already exist in the local Kodi DB we'll perform a full item update # If the item doesn't exist, we'll add it to the database - MBitem = ReadEmbyDB().getFullItem(embyId) - if not MBitem: - utils.logMsg("ADD episode to Kodi library FAILED", "Item %s not found on server!" %embyId) - return - - cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem["Id"],)) - result = cursor.fetchone() - if result != None: - episodeid = result[0] - else: + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(embyId,)) + try: + episodeid = cursor.fetchone()[0] + except: episodeid = None - - addon = xbmcaddon.Addon(id='plugin.video.emby') - port = addon.getSetting('port') - host = addon.getSetting('ipaddress') - server = host + ":" + port - + timeInfo = API().getTimeInfo(MBitem) - userData=API().getUserData(MBitem) + userData = API().getUserData(MBitem) people = API().getPeople(MBitem) - ###### episode properties ################ - episode = 0 - if MBitem.get("IndexNumber") != None: - episode = int(MBitem.get("IndexNumber")) + ##### The episode details ##### + seriesId = MBitem['SeriesId'] + seriesName = MBitem['SeriesName'] + season = MBitem.get('ParentIndexNumber') + episode = MBitem.get('IndexNumber', 0) - runtime = int(timeInfo.get('Duration'))*60 - plot = utils.convertEncoding(API().getOverview(MBitem)) - title = utils.convertEncoding(MBitem["Name"]) - rating = MBitem.get("CommunityRating") + playcount = userData.get('PlayCount') + dateplayed = userData.get("LastPlayedDate") + dateadded = API().getDateCreated(MBitem) + checksum = API().getChecksum(MBitem) + + title = MBitem['Name'] + plot = API().getOverview(MBitem) + rating = MBitem.get('CommunityRating') writer = " / ".join(people.get("Writer")) + premieredate = API().getPremiereDate(MBitem) + runtime = timeInfo.get('TotalTime') director = " / ".join(people.get("Director")) - - if MBitem.get("PremiereDate") != None: - premieredatelist = (MBitem.get("PremiereDate")).split("T") - premieredate = premieredatelist[0] - else: - premieredate = None - - if MBitem.get("DateCreated") != None: - dateadded = MBitem["DateCreated"].replace("T"," ") - dateadded = dateadded.split(".")[0] - else: - dateadded = None - - if userData.get("LastPlayedDate") != None: - lastplayed = userData.get("LastPlayedDate") - else: - lastplayed = None - - if userData.get("PlayCount") != "0": - playcount = int(userData.get('PlayCount')) - else: - playcount = None #playcount must be set to NULL in the db - - #### ADD OR UPDATE THE FILE AND PATH ########### - #### NOTE THAT LASTPLAYED AND PLAYCOUNT ARE STORED AT THE FILE ENTRY - if addon.getSetting('useDirectPaths') == 'true': - playurl = PlayUtils().directPlay(MBitem) - if playurl == False: - return - elif "\\" in playurl: - filename = playurl.rsplit("\\",1)[-1] - path = playurl.replace(filename, "") - elif "/" in playurl: - filename = playurl.rsplit("/",1)[-1] - path = playurl.replace(filename, "") - else: - path = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/" - filename = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/?id=" + MBitem["Id"] + "&mode=play" - - #create the new path - return id if already exists - cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,)) - result = cursor.fetchone() - if result != None: - pathid = result[0] - if result == None: - cursor.execute("select coalesce(max(idPath),0) as pathid from path") - pathid = cursor.fetchone()[0] - pathid = pathid + 1 - pathsql="insert into path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" - cursor.execute(pathsql, (pathid,path,None,None,1)) - #create the file if not exists - cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ? and idPath = ?",(filename,pathid,)) - result = cursor.fetchone() - if result != None: - fileid = result[0] - if result == None: - cursor.execute("select coalesce(max(idFile),0) as fileid from files") - fileid = cursor.fetchone()[0] - fileid = fileid + 1 - sql="INSERT OR REPLACE into files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)" - cursor.execute(sql, (fileid,pathid,filename,playcount,lastplayed,dateadded)) - else: - pathsql="update files SET playCount = ?, lastPlayed = ? WHERE idFile = ?" - cursor.execute(pathsql, (playcount,userData.get("LastPlayedDate"), fileid)) + #### ADD OR UPDATE THE FILE AND PATH ########### + #### NOTE THAT LASTPLAYED AND PLAYCOUNT ARE STORED AT THE FILE ENTRY + #### ORDERING FOR SORTING C15 C16 TO DISPLAY SPECIALS WITHIN REGULAR EPISODES + + # Get the real filename + playurl = PlayUtils().directPlay(MBitem) + try: + fileext = basename(playurl) + except: return # playurl returned False + else: # Set filename and path + + if self.directpath: + filename = fileext + path = playurl.replace(filename, "") + + else: # Set plugin path and media flags - real filename with extension + filename = "plugin://plugin.video.emby/tvshows/%s/?filename=%s&id=%s&mode=play" % (seriesId, fileext, embyId) + path = "plugin://plugin.video.emby/tvshows/%s/" % seriesId + + cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ?", (fileext,)) + try: # Remove Kodi bookmark - messes with plugin path bookmark + result = cursor.fetchone()[0] + self.setKodiResumePoint(result, 0, 0, cursor) + except: pass - # safety check: check season first - season = 0 - if MBitem.get("ParentIndexNumber") != None: - season = int(MBitem.get("ParentIndexNumber")) - else: - utils.logMsg("Emby","SKIP adding episode to Kodi Library, no ParentIndexNumber - ID: " + MBitem["Id"] + " - " + MBitem["Name"]) + # Validate the path in database + cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?", (path,)) + try: + pathid = cursor.fetchone()[0] + except: + # Path does not exist yet + cursor.execute("select coalesce(max(idPath),0) as pathid from path") + pathid = cursor.fetchone()[0] + 1 + query = "INSERT INTO path(idPath, strPath, strContent, strScraper, noUpdate) values(?, ?, ?, ?, ?)" + cursor.execute(query, (pathid, path, None, None, 1)) + + # Validate the file in database + cursor.execute("SELECT idFile as fileid FROM files WHERE strFilename = ? and idPath = ?", (filename, pathid,)) + try: + fileid = cursor.fetchone()[0] + except: + # File does not exist yet + cursor.execute("select coalesce(max(idFile),0) as fileid from files") + fileid = cursor.fetchone()[0] + 1 + query = "INSERT INTO files(idFile, idPath, strFilename, playCount, lastPlayed, dateAdded) values(?, ?, ?, ?, ?, ?)" + cursor.execute(query, (fileid, pathid, filename, playcount, dateplayed, dateadded)) + else: # File exists + query = "UPDATE files SET playCount = ?, lastPlayed = ? WHERE idFile = ?" + cursor.execute(query, (playcount, dateplayed, fileid)) + + # Validate the season exists in Emby and in database + if season is None: + self.logMsg("SKIP adding episode to Kodi Library, no ParentIndexNumber - ID: %s - %s" % (embyId, title)) return False - cursor.execute("SELECT idSeason FROM seasons WHERE idShow = ? and season = ?",(showid, season)) - result = cursor.fetchone() - if(result == None): - #update seasons first - self.updateSeasons(MBitem["SeriesId"], showid, connection, cursor) - - # ADD EPISODE TO KODI - if episodeid == None: - utils.logMsg("ADD episode to Kodi library","Id: %s - Title: %s" % (embyId, title)) - #create the episode - cursor.execute("select coalesce(max(idEpisode),0) as episodeid from episode") - episodeid = cursor.fetchone()[0] - episodeid = episodeid + 1 - pathsql = "INSERT into episode(idEpisode, idFile, c00, c01, c03, c04, c05, c09, c10, c12, c13, c14, idShow, c15, c16) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(pathsql, (episodeid, fileid, title, plot, rating, writer, premieredate, runtime, director, season, episode, title, showid, "-1", "-1")) - - #create the reference in emby table - pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum, parent_id) values(?, ?, ?, ?, ?)" - cursor.execute(pathsql, (MBitem["Id"], episodeid, "episode", API().getChecksum(MBitem), showid)) - - # UPDATE THE EPISODE IN KODI (for now, we just send in all data) - else: - utils.logMsg("UPDATE episode to Kodi library","Id: %s - Title: %s" % (embyId, title)) - - pathsql = "UPDATE episode SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?, c10 = ?, c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ? WHERE idEpisode = ?" - cursor.execute(pathsql, (title, plot, rating, writer, premieredate, runtime, director, season, episode, title, "-1", "-1", episodeid)) + cursor.execute("SELECT idSeason FROM seasons WHERE idShow = ? and season = ?", (showid, season,)) + try: + cursor.fetchone()[0] + except: # Season does not exist, update seasons + self.updateSeasons(seriesId, showid, connection, cursor) + + + ##### UPDATE THE EPISODE ##### + if episodeid: + self.logMsg("UPDATE episode from // %s - S%s // to Kodi library, Id: %s - E%s: %s" % (seriesName, season, embyId, episode, title)) + + query = "UPDATE episode SET c00 = ?, c01 = ?, c03 = ?, c04 = ?, c05 = ?, c09 = ?, c10 = ?, c12 = ?, c13 = ?, c14 = ?, c15 = ?, c16 = ? WHERE idEpisode = ?" + cursor.execute(query, (title, plot, rating, writer, premieredate, runtime, director, season, episode, title, "-1", "-1", episodeid)) #update the checksum in emby table - cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(MBitem), MBitem["Id"])) + query = "UPDATE emby SET checksum = ? WHERE emby_id = ?" + cursor.execute(query, (checksum, embyId)) - #update or insert actors - self.AddPeopleToMedia(episodeid,MBitem.get("People"),"episode", connection, cursor) + ##### OR ADD THE EPISODE ##### + else: + self.logMsg("ADD episode from // %s - S%s // to Kodi library, Id: %s - E%s: %s" % (seriesName, season, embyId, episode, title)) + + # Create the episode + cursor.execute("select coalesce(max(idEpisode),0) as episodeid from episode") + episodeid = cursor.fetchone()[0] + 1 + query = "INSERT INTO episode(idEpisode, idFile, c00, c01, c03, c04, c05, c09, c10, c12, c13, c14, idShow, c15, c16) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(query, (episodeid, fileid, title, plot, rating, writer, premieredate, runtime, director, season, episode, title, showid, "-1", "-1")) + + # Create the reference in emby table + query = "INSERT INTO emby(emby_id, kodi_id, media_type, checksum, parent_id) values(?, ?, ?, ?, ?)" + cursor.execute(query, (embyId, episodeid, "episode", checksum, showid)) + - #set resume point - resume = int(round(float(timeInfo.get("ResumeTime"))))*60 - total = int(round(float(timeInfo.get("TotalTime"))))*60 + # Update or insert actors + self.AddPeopleToMedia(episodeid, MBitem.get('People'), "episode", connection, cursor) + + # Set resume point and round to 6th decimal + resume = round(float(timeInfo.get('ResumeTime')), 6) + total = round(float(timeInfo.get('TotalTime')), 6) + jumpback = int(addon.getSetting('resumeJumpBack')) + if resume > jumpback: + # To avoid negative bookmark + resume = resume - jumpback self.setKodiResumePoint(fileid, resume, total, cursor) - #add streamdetails + # Add streamdetails self.AddStreamDetailsToMedia(API().getMediaStreams(MBitem), fileid, cursor) - #update artwork + # Update artwork self.addOrUpdateArt(API().getArtwork(MBitem, "Primary", mediaType = "episode"), episodeid, "episode", "thumb", cursor) def deleteItemFromKodiLibrary(self, id, connection, cursor ): - cursor.execute("SELECT kodi_id, media_type FROM emby WHERE emby_id=?", (id,)) - result = cursor.fetchone() - if result: + cursor.execute("SELECT kodi_id, media_type FROM emby WHERE emby_id = ?", (id,)) + try: + result = cursor.fetchone() kodi_id = result[0] media_type = result[1] - if media_type == "movie": - utils.logMsg("deleting movie from Kodi library --> ",id) + except: pass + else: # Delete entry from database + if "movie" in media_type: + self.logMsg("Deleting movie from Kodi library, Id: %s" % id, 1) cursor.execute("DELETE FROM movie WHERE idMovie = ?", (kodi_id,)) - if media_type == "episode": - utils.logMsg("deleting episode from Kodi library --> ",id) - cursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodi_id,)) - if media_type == "tvshow": - utils.logMsg("deleting tvshow from Kodi library --> ",id) - cursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodi_id,)) - if media_type == "musicvideo": - utils.logMsg("deleting musicvideo from Kodi library --> ",id) - cursor.execute("DELETE FROM musicvideo WHERE idMVideo = ?", (kodi_id,)) - #delete the record in emby table + elif "episode" in media_type: + cursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodi_id,)) + self.logMsg("Deleting episode from Kodi library, Id: %s" % id, 1) + + elif "tvshow" in media_type: + cursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodi_id,)) + self.logMsg("Deleting tvshow from Kodi library, Id: %s" % id, 1) + + elif "musicvideo" in media_type: + cursor.execute("DELETE FROM musicvideo WHERE idMVideo = ?", (kodi_id,)) + self.logMsg("Deleting musicvideo from Kodi library, Id: %s" % id, 1) + + # Delete the record in emby table cursor.execute("DELETE FROM emby WHERE emby_id = ?", (id,)) def updateSeasons(self,embyTvShowId, kodiTvShowId, connection, cursor): seasonData = ReadEmbyDB().getTVShowSeasons(embyTvShowId) - if seasonData != None: + + if seasonData: # Verify every season for season in seasonData: - seasonNum = season.get("IndexNumber") - if seasonNum != None and seasonNum >= 0: - cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?",(kodiTvShowId, seasonNum)) - result = cursor.fetchone() - if result == None: - #create the season - cursor.execute("select coalesce(max(idSeason),0) as seasonid from seasons") - seasonid = cursor.fetchone()[0] - seasonid = seasonid + 1 - cursor.execute("INSERT into seasons(idSeason, idShow, season) values(?, ?, ?)", (seasonid, kodiTvShowId, seasonNum)) - else: - seasonid = result[0] - - #update artwork + + seasonNum = season.get('IndexNumber') + + cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?", (kodiTvShowId, seasonNum,)) + try: + seasonid = cursor.fetchone()[0] + except: # Create the season + cursor.execute("select coalesce(max(idSeason),0) as seasonid from seasons") + seasonid = cursor.fetchone()[0] + 1 + query = "INSERT INTO seasons(idSeason, idShow, season) values(?, ?, ?)" + cursor.execute(query, (seasonid, kodiTvShowId, seasonNum)) + finally: # Update artwork imageUrl = API().getArtwork(season, "Thumb", mediaType = "season") self.addOrUpdateArt(imageUrl, seasonid, "season", "landscape", cursor) @@ -757,390 +721,387 @@ class WriteKodiVideoDB(): imageUrl = API().getArtwork(season, "Banner", mediaType = "season") self.addOrUpdateArt(imageUrl, seasonid, "season", "banner", cursor) - # Set All season poster + + # All season entry MBitem = ReadEmbyDB().getFullItem(embyTvShowId) seasonNum = -1 - cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?", (kodiTvShowId, seasonNum)) - result = cursor.fetchone() - if result == None: - # Create the all-season - cursor.execute("select coalesce(max(idSeason),0) as seasonid from seasons") + + cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?", (kodiTvShowId, seasonNum,)) + try: seasonid = cursor.fetchone()[0] - seasonid = seasonid + 1 - cursor.execute("INSERT into seasons(idSeason, idShow, season) values(?, ?, ?)", (seasonid, kodiTvShowId, seasonNum)) - else: - seasonid = result[0] - imageUrl = API().getArtwork(MBitem, "Primary", mediaType = "season") - self.addOrUpdateArt(imageUrl, seasonid, "season", "poster", cursor) + except: # Create all season entry + cursor.execute("select coalesce(max(idSeason),0) as seasonid from seasons") + seasonid = cursor.fetchone()[0] + 1 + query = "INSERT INTO seasons(idSeason, idShow, season) values(?, ?, ?)" + cursor.execute(query, (seasonid, kodiTvShowId, seasonNum)) + finally: # Update the artwork + imageUrl = API().getArtwork(MBitem, "Primary", mediaType = "season") + self.addOrUpdateArt(imageUrl, seasonid, "season", "poster", cursor) def addOrUpdateArt(self, imageUrl, kodiId, mediaType, imageType, cursor): - updateDone = False + if imageUrl: - cursor.execute("SELECT url FROM art WHERE media_id = ? AND media_type = ? AND type = ?", (kodiId, mediaType, imageType)) - result = cursor.fetchone() - if(result == None): - utils.logMsg("ArtworkSync", "Adding Art Link for kodiId: " + str(kodiId) + " (" + imageUrl + ")") - cursor.execute("INSERT INTO art(media_id, media_type, type, url) values(?, ?, ?, ?)", (kodiId, mediaType, imageType, imageUrl)) + + cursor.execute("SELECT url FROM art WHERE media_id = ? AND media_type = ? AND type = ?", (kodiId, mediaType, imageType,)) + try: # Update the artwork + url = cursor.fetchone()[0] + except: # Add the artwork + self.logMsg("Adding Art Link for kodiId: %s (%s)" % (kodiId, imageUrl), 1) + query = "INSERT INTO art(media_id, media_type, type, url) values(?, ?, ?, ?)" + cursor.execute(query, (kodiId, mediaType, imageType, imageUrl)) else: - url = result[0]; - if(url != imageUrl): - utils.logMsg("ArtworkSync", "Updating Art Link for kodiId: " + str(kodiId) + " (" + url + ") -> (" + imageUrl + ")") - cursor.execute("UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?", (imageUrl, kodiId, mediaType, imageType)) + if url != imageUrl: + self.logMsg("Updating Art Link for kodiId: %s (%s) -> (%s)" % (kodiId, url, imageUrl), 1) + query = "INSERT INTO art(media_id, media_type, type, url) values(?, ?, ?, ?)" + cursor.execute(query, (kodiId, mediaType, imageType, imageUrl)) - #cache fanart and poster in Kodi texture cache - if "fanart" in imageType or "poster" in imageType: - utils.logMsg("ArtworkSync", "Adding or Updating Fanart: %s" % imageUrl) + # Cache fanart and poster in Kodi texture cache + if imageType in ("fanart", "poster"): self.textureCache.CacheTexture(imageUrl) def setKodiResumePoint(self, fileid, resume_seconds, total_seconds, cursor): - cursor.execute("delete FROM bookmark WHERE idFile = ?", (fileid,)) - if resume_seconds != 0: + cursor.execute("DELETE FROM bookmark WHERE idFile = ?", (fileid,)) + if resume_seconds: cursor.execute("select coalesce(max(idBookmark),0) as bookmarkId from bookmark") - bookmarkId = cursor.fetchone()[0] - bookmarkId = bookmarkId + 1 - bookmarksql="insert into bookmark(idBookmark, idFile, timeInSeconds, totalTimeInSeconds, thumbNailImage, player, playerState, type) values(?, ?, ?, ?, ?, ?, ?, ?)" - cursor.execute(bookmarksql, (bookmarkId,fileid,resume_seconds,total_seconds,None,"DVDPlayer",None,1)) + bookmarkId = cursor.fetchone()[0] + 1 + query = "INSERT INTO bookmark(idBookmark, idFile, timeInSeconds, totalTimeInSeconds, thumbNailImage, player, playerState, type) values(?, ?, ?, ?, ?, ?, ?, ?)" + cursor.execute(query, (bookmarkId, fileid, resume_seconds, total_seconds, None, "DVDPlayer", None, 1)) def AddPeopleToMedia(self, id, people, mediatype, connection, cursor): - downloadUtils = DownloadUtils() - kodiVersion = 14 - if xbmc.getInfoLabel("System.BuildVersion").startswith("15"): - kodiVersion = 15 + kodiVersion = self.kodiversion - if(people != None): + if people: castorder = 1 - for person in people: - Name = person.get("Name") - actorid = None - # Get existing actor - if kodiVersion == 15: - # Kodi Isengard database # - cursor.execute("SELECT actor_id as actorid FROM actor WHERE name = ?",(Name,)) - else: - # Kodi Gotham or Helix database # - cursor.execute("SELECT idActor as actorid FROM actors WHERE strActor = ?",(Name,)) - result = cursor.fetchone() - if result != None: - actorid = result[0] - if actorid == None: - if kodiVersion == 15: - # Kodi Isengard database # - cursor.execute("select coalesce(max(actor_id),0) as actorid from actor") - actorid = cursor.fetchone()[0] - actorid = actorid + 1 - peoplesql="insert into actor(actor_id, name) values(?, ?)" - else: - # Kodi Gotham or Helix database # - cursor.execute("select coalesce(max(idActor),0) as actorid from actors") - actorid = cursor.fetchone()[0] - actorid = actorid + 1 - peoplesql="insert into actors(idActor, strActor) values(?, ?)" - utils.logMsg("AddPeopleToMedia", "Processing : " + person.get("Name")) - cursor.execute(peoplesql, (actorid,Name)) - - ### add people image to art table - Thumb = downloadUtils.imageUrl(person.get("Id"), "Primary", 0, 400, 400) - if Thumb: - if(person.get("Type") == "Director"): - arttype = "director" - elif(person.get("Type") == "Writer" or person.get("Type") == "Writing"): - arttype = "writer" - else: - arttype = "actor" - self.addOrUpdateArt(Thumb, actorid, arttype, "thumb", cursor) - #### ACTORS ###### - if(person.get("Type") == "Actor"): - - Role = person.get("Role") + for person in people: + + name = person['Name'] + type = person['Type'] + + if kodiVersion == 15: + # Kodi Isengard + cursor.execute("SELECT actor_id as actorid FROM actor WHERE name = ?", (name,)) + else: + # Kodi Gotham or Helix + cursor.execute("SELECT idActor as actorid FROM actors WHERE strActor = ?",(name,)) + + try: # Update person in database + actorid = cursor.fetchone()[0] + except: + # Person entry does not exist yet. if kodiVersion == 15: - # Kodi Isengard database # - peoplesql="INSERT OR REPLACE into actor_link(actor_id, media_id, media_type,role, cast_order) values(?, ?, ?, ?, ?)" - cursor.execute(peoplesql, (actorid, id, mediatype, Role, castorder)) - castorder += 1 + # Kodi Isengard + cursor.execute("select coalesce(max(actor_id),0) as actorid from actor") + query = "INSERT INTO actor(actor_id, name) values(?, ?)" else: - # Kodi Gotham or Helix database # - if mediatype == "movie": - peoplesql="INSERT OR REPLACE into actorlinkmovie(idActor, idMovie, strRole, iOrder) values(?, ?, ?, ?)" - cursor.execute(peoplesql, (actorid,id,Role,castorder)) - if mediatype == "tvshow": - peoplesql="INSERT OR REPLACE into actorlinktvshow(idActor, idShow, strRole, iOrder) values(?, ?, ?, ?)" - cursor.execute(peoplesql, (actorid,id,Role,castorder)) - if mediatype == "episode": - peoplesql="INSERT OR REPLACE into actorlinkepisode(idActor, idEpisode, strRole, iOrder) values(?, ?, ?, ?)" - cursor.execute(peoplesql, (actorid,id,Role,castorder)) - castorder += 1 + # Kodi Gotham or Helix + cursor.execute("select coalesce(max(idActor),0) as actorid from actors") + query = "INSERT INTO actors(idActor, strActor) values(?, ?)" + + actorid = cursor.fetchone()[0] + 1 + self.logMsg("Adding people to Media, processing: %s" % name, 2) + + cursor.execute(query, (actorid, name)) + finally: + # Add person image to art table + thumb = API().imageUrl(person['Id'], "Primary", 0, 400, 400) + if thumb: + arttype = type.lower() + + if "writing" in arttype: + arttype = "writer" + + self.addOrUpdateArt(thumb, actorid, arttype, "thumb", cursor) + + # Link person to content in database + if kodiVersion == 15: + # Kodi Isengard + if "Actor" in type: + Role = person.get('Role') + query = "INSERT OR REPLACE INTO actor_link(actor_id, media_id, media_type, role, cast_order) values(?, ?, ?, ?, ?)" + cursor.execute(query, (actorid, id, mediatype, Role, castorder)) + castorder += 1 - #### DIRECTORS ###### - if(person.get("Type") == "Director"): - - if kodiVersion == 15: - # Kodi Isengard database # - peoplesql="INSERT OR REPLACE into director_link(actor_id, media_id, media_type) values(?, ?, ?)" - cursor.execute(peoplesql, (actorid, id, mediatype)) - else: - # Kodi Gotham or Helix database # - if mediatype == "movie": - peoplesql="INSERT OR REPLACE into directorlinkmovie(idDirector, idMovie) values(?, ?)" - if mediatype == "tvshow": - peoplesql="INSERT OR REPLACE into directorlinktvshow(idDirector, idShow) values(?, ?)" - if mediatype == "musicvideo": - peoplesql="INSERT OR REPLACE into directorlinkmusicvideo(idDirector, idMVideo) values(?, ?)" - if mediatype == "episode": - peoplesql="INSERT OR REPLACE into directorlinkepisode(idDirector, idEpisode) values(?, ?)" - cursor.execute(peoplesql, (actorid,id)) + elif "Director" in type: + query = "INSERT OR REPLACE INTO director_link(actor_id, media_id, media_type) values(?, ?, ?)" + cursor.execute(query, (actorid, id, mediatype)) - #### WRITERS ###### - if(person.get("Type") == "Writing" or person.get("Type") == "Writer"): - - if kodiVersion == 15: - # Kodi Isengard database # - peoplesql="INSERT OR REPLACE into writer_link(actor_id, media_id, media_type) values(?, ?, ?)" - cursor.execute(peoplesql, (actorid, id, mediatype)) + elif type in ("Writing", "Writer"): + query = "INSERT OR REPLACE INTO writer_link(actor_id, media_id, media_type) values(?, ?, ?)" + cursor.execute(query, (actorid, id, mediatype)) + else: - # Kodi Gotham or Helix database # - if mediatype == "movie": - peoplesql="INSERT OR REPLACE into writerlinkmovie(idWriter, idMovie) values(?, ?)" - cursor.execute(peoplesql, (actorid,id)) - if mediatype == "episode": - peoplesql="INSERT OR REPLACE into writerlinkepisode(idWriter, idEpisode) values(?, ?)" - cursor.execute(peoplesql, (actorid,id)) + # Kodi Gotham or Helix + if "Actor" in type: + Role = person.get('Role') + + if "movie" in mediatype: + query = "INSERT OR REPLACE INTO actorlinkmovie(idActor, idMovie, strRole, iOrder) values(?, ?, ?, ?)" + elif "tvshow" in mediatype: + query = "INSERT OR REPLACE INTO actorlinktvshow(idActor, idShow, strRole, iOrder) values(?, ?, ?, ?)" + elif "episode" in mediatype: + query = "INSERT OR REPLACE INTO actorlinkepisode(idActor, idEpisode, strRole, iOrder) values(?, ?, ?, ?)" + + cursor.execute(query, (actorid, id, Role, castorder)) + castorder += 1 + + elif "Director" in type: + + if "movie" in mediatype: + query = "INSERT OR REPLACE INTO directorlinkmovie(idDirector, idMovie) values(?, ?)" + elif "tvshow" in mediatype: + query = "INSERT OR REPLACE INTO directorlinktvshow(idDirector, idShow) values(?, ?)" + elif "musicvideo" in mediatype: + query = "INSERT OR REPLACE INTO directorlinkmusicvideo(idDirector, idMVideo) values(?, ?)" + elif "episode" in mediatype: + query = "INSERT OR REPLACE INTO directorlinkepisode(idDirector, idEpisode) values(?, ?)" + + cursor.execute(query, (actorid, id)) + + elif type in ("Writing", "Writer"): + + if "movie" in mediatype: + query = "INSERT OR REPLACE INTO writerlinkmovie(idWriter, idMovie) values(?, ?)" + elif "episode" in mediatype: + query = "INSERT OR REPLACE INTO writerlinkepisode(idWriter, idEpisode) values(?, ?)" + + cursor. execute(query, (actorid, id)) def AddGenresToMedia(self, id, genres, mediatype, cursor): + kodiVersion = self.kodiversion + if genres: - - kodiVersion = 14 - if xbmc.getInfoLabel("System.BuildVersion").startswith("15"): - kodiVersion = 15 - + + # Delete current genres for clean slate + if kodiVersion == 15: + cursor.execute("DELETE FROM genre_link WHERE media_id = ? AND media_type = ?", (id, mediatype,)) + else: + if "movie" in mediatype: + cursor.execute("DELETE FROM genrelinkmovie WHERE idMovie = ?", (id,)) + elif "tvshow" in mediatype: + cursor.execute("DELETE FROM genrelinktvshow WHERE idShow = ?", (id,)) + elif "musicvideo" in mediatype: + cursor.execute("DELETE FROM genrelinkmusicvideo WHERE idMVideo = ?", (id,)) + + # Add Genres for genre in genres: if kodiVersion == 15: - genre_id = None - cursor.execute("SELECT genre_id as genre_id FROM genre WHERE name = ?",(genre,)) - result = cursor.fetchone() - if result != None: - genre_id = result[0] - #create genre - if genre_id == None: - cursor.execute("select coalesce(max(genre_id),0) as genre_id from genre") + # Kodi Isengard + cursor.execute("SELECT genre_id as genre_id FROM genre WHERE name = ?", (genre,)) + try: genre_id = cursor.fetchone()[0] - genre_id = genre_id + 1 - sql="insert into genre(genre_id, name) values(?, ?)" - cursor.execute(sql, (genre_id,genre)) - utils.logMsg("AddGenresToMedia", "Processing : " + genre) - - #assign genre to item - sql="INSERT OR REPLACE into genre_link(genre_id, media_id, media_type) values(?, ?, ?)" - cursor.execute(sql, (genre_id, id, mediatype)) - + except: + # Create genre in database + cursor.execute("select coalesce(max(genre_id),0) as genre_id from genre") + genre_id = cursor.fetchone()[0] + 1 + + query = "INSERT INTO genre(genre_id, name) values(?, ?)" + cursor.execute(query, (genre_id,genre)) + self.logMsg("Add Genres to media, processing: %s" % genre, 1) + finally: + # Assign genre to item + query = "INSERT OR REPLACE INTO genre_link(genre_id, media_id, media_type) values(?, ?, ?)" + cursor.execute(query, (genre_id, id, mediatype)) else: - idGenre = None - cursor.execute("SELECT idGenre as idGenre FROM genre WHERE strGenre = ?",(genre,)) - result = cursor.fetchone() - if result != None: - idGenre = result[0] - #create genre - if idGenre == None: - cursor.execute("select coalesce(max(idGenre),0) as idGenre from genre") + # Kodi Gotham or Helix + cursor.execute("SELECT idGenre as idGenre FROM genre WHERE strGenre = ?", (genre,)) + try: idGenre = cursor.fetchone()[0] - idGenre = idGenre + 1 - sql="insert into genre(idGenre, strGenre) values(?, ?)" - cursor.execute(sql, (idGenre,genre)) + except: + # Create genre in database + cursor.execute("select coalesce(max(idGenre),0) as idGenre from genre") + idGenre = cursor.fetchone()[0] + 1 + + query = "INSERT INTO genre(idGenre, strGenre) values(?, ?)" + cursor.execute(query, (idGenre,genre)) + self.logMsg("Add Genres to media, processing: %s" % genre, 1) + finally: + # Assign genre to item + if "movie" in mediatype: + query = "INSERT OR REPLACE into genrelinkmovie(idGenre, idMovie) values(?, ?)" + elif "tvshow" in mediatype: + query = "INSERT OR REPLACE into genrelinktvshow(idGenre, idShow) values(?, ?)" + elif "musicvideo" in mediatype: + query = "INSERT OR REPLACE into genrelinkmusicvideo(idGenre, idMVideo) values(?, ?)" + cursor.execute(query, (idGenre, id)) - #assign genre to item - if mediatype == "movie": - sql="INSERT OR REPLACE into genrelinkmovie(idGenre, idMovie) values(?, ?)" - if mediatype == "tvshow": - sql="INSERT OR REPLACE into genrelinktvshow(idGenre, idShow) values(?, ?)" - if mediatype == "episode": - return - if mediatype == "musicvideo": - sql="INSERT OR REPLACE into genrelinkmusicvideo(idGenre, idMVideo) values(?, ?)" - cursor.execute(sql, (idGenre,id)) - def AddCountriesToMedia(self, id, countries, mediatype, cursor): + + kodiVersion = self.kodiversion + if countries: - kodiVersion = 14 - if xbmc.getInfoLabel("System.BuildVersion").startswith("15"): - kodiVersion = 15 - for country in countries: if kodiVersion == 15: - country_id = None - cursor.execute("SELECT country_id as country_id FROM country WHERE name = ?",(country,)) - result = cursor.fetchone() - if result != None: - country_id = result[0] - #create country - if country_id == None: - cursor.execute("select coalesce(max(country_id),0) as country_id from country") + # Kodi Isengard + cursor.execute("SELECT country_id as country_id FROM country WHERE name = ?", (country,)) + try: country_id = cursor.fetchone()[0] - country_id = country_id + 1 - sql="insert into country(country_id, name) values(?, ?)" - cursor.execute(sql, (country_id,country)) - utils.logMsg("AddCountriesToMedia", "Processing : " + country) - - #assign country to item - sql="INSERT OR REPLACE into country_link(country_id, media_id, media_type) values(?, ?, ?)" - cursor.execute(sql, (country_id, id, mediatype)) - - else: - idCountry = None - cursor.execute("SELECT idCountry as idCountry FROM country WHERE strCountry = ?",(country,)) - result = cursor.fetchone() - if result != None: - idCountry = result[0] - #create country - if idCountry == None: - cursor.execute("select coalesce(max(idCountry),0) as idCountry from country") - idCountry = cursor.fetchone()[0] - idCountry = idCountry + 1 - sql="insert into country(idCountry, strCountry) values(?, ?)" - cursor.execute(sql, (idCountry,country)) + except: + # Country entry does not exists + cursor.execute("select coalesce(max(country_id),0) as country_id from country") + country_id = cursor.fetchone()[0] + 1 - #assign country to item - if mediatype == "movie": - sql="INSERT OR REPLACE into countrylinkmovie(idCountry, idMovie) values(?, ?)" - cursor.execute(sql, (idCountry,id)) - else: - #only movies have a country field - return + query = "INSERT INTO country(country_id, name) values(?, ?)" + cursor.execute(query, (country_id, country)) + self.logMsg("Add Countries to Media, processing: %s" % country) + finally: + # Assign country to content + query = "INSERT OR REPLACE INTO country_link(country_id, media_id, media_type) values(?, ?, ?)" + cursor.execute(query, (country_id, id, mediatype)) + else: + # Kodi Gotham or Helix + cursor.execute("SELECT idCountry as idCountry FROM country WHERE strCountry = ?", (country,)) + try: + idCountry = cursor.fetchone()[0] + except: + # Country entry does not exists + cursor.execute("select coalesce(max(idCountry),0) as idCountry from country") + idCountry = cursor.fetchone()[0] + 1 + + query = "INSERT INTO country(idCountry, strCountry) values(?, ?)" + cursor.execute(query, (idCountry, country)) + finally: + # Only movies have a country field + if "movie" in mediatype: + query = "INSERT OR REPLACE INTO countrylinkmovie(idCountry, idMovie) values(?, ?)" + cursor.execute(query, (idCountry, id)) def AddStudiosToMedia(self, id, studios, mediatype, cursor): + kodiVersion = self.kodiversion + if studios: - - kodiVersion = 14 - if xbmc.getInfoLabel("System.BuildVersion").startswith("15"): - kodiVersion = 15 - for studio in studios: if kodiVersion == 15: - studio_id = None + # Kodi Isengard cursor.execute("SELECT studio_id as studio_id FROM studio WHERE name = ?",(studio,)) - result = cursor.fetchone() - if result != None: - studio_id = result[0] - #create studio - if studio_id == None: - cursor.execute("select coalesce(max(studio_id),0) as studio_id from studio") + try: studio_id = cursor.fetchone()[0] - studio_id = studio_id + 1 - sql="insert into studio(studio_id, name) values(?, ?)" - cursor.execute(sql, (studio_id,studio)) - utils.logMsg("AddstudiosToMedia", "Processing : " + studio) + except: # Studio does not exists. + cursor.execute("select coalesce(max(studio_id),0) as studio_id from studio") + studio_id = cursor.fetchone()[0] + 1 + + query = "INSERT INTO studio(studio_id, name) values(?, ?)" + cursor.execute(query, (studio_id,studio)) + self.logMsg("Add Studios to media, processing: %s" % studio, 1) - #assign studio to item - sql="INSERT OR REPLACE into studio_link(studio_id, media_id, media_type) values(?, ?, ?)" - cursor.execute(sql, (studio_id, id, mediatype)) - + finally: # Assign studio to item + query = "INSERT OR REPLACE INTO studio_link(studio_id, media_id, media_type) values(?, ?, ?)" + cursor.execute(query, (studio_id, id, mediatype)) else: - idstudio = None + # Kodi Gotham or Helix cursor.execute("SELECT idstudio as idstudio FROM studio WHERE strstudio = ?",(studio,)) - result = cursor.fetchone() - if result != None: - idstudio = result[0] - #create studio - if idstudio == None: - cursor.execute("select coalesce(max(idstudio),0) as idstudio from studio") + try: idstudio = cursor.fetchone()[0] - idstudio = idstudio + 1 - sql="insert into studio(idstudio, strstudio) values(?, ?)" - cursor.execute(sql, (idstudio,studio)) + + except: # Studio does not exists. + cursor.execute("select coalesce(max(idstudio),0) as idstudio from studio") + idstudio = cursor.fetchone()[0] + 1 - #assign studio to item - if mediatype == "movie": - sql="INSERT OR REPLACE into studiolinkmovie(idstudio, idMovie) values(?, ?)" - if mediatype == "musicvideo": - sql="INSERT OR REPLACE into studiolinkmusicvideo(idstudio, idMVideo) values(?, ?)" - if mediatype == "tvshow": - sql="INSERT OR REPLACE into studiolinktvshow(idstudio, idShow) values(?, ?)" - if mediatype == "episode": - sql="INSERT OR REPLACE into studiolinkepisode(idstudio, idEpisode) values(?, ?)" - cursor.execute(sql, (idstudio,id)) + query = "INSERT INTO studio(idstudio, strstudio) values(?, ?)" + cursor.execute(query, (idstudio,studio)) + self.logMsg("Add Studios to media, processing: %s" % studio, 1) + + finally: # Assign studio to item + if "movie" in mediatype: + query = "INSERT OR REPLACE INTO studiolinkmovie(idstudio, idMovie) values(?, ?)" + elif "musicvideo" in mediatype: + query = "INSERT OR REPLACE INTO studiolinkmusicvideo(idstudio, idMVideo) values(?, ?)" + elif "tvshow" in mediatype: + query = "INSERT OR REPLACE INTO studiolinktvshow(idstudio, idShow) values(?, ?)" + elif "episode" in mediatype: + query = "INSERT OR REPLACE INTO studiolinkepisode(idstudio, idEpisode) values(?, ?)" + cursor.execute(query, (idstudio, id)) - def AddTagToMedia(self, id, tag, mediatype, cursor, doRemove=False): + def AddTagToMedia(self, id, tag, mediatype, cursor, doRemove = False): + + kodiVersion = self.kodiversion if tag: - - kodiVersion = 14 - if xbmc.getInfoLabel("System.BuildVersion").startswith("15"): - kodiVersion = 15 - - if kodiVersion == 15: - tag_id = None - cursor.execute("SELECT tag_id as tag_id FROM tag WHERE name = ?",(tag,)) - result = cursor.fetchone() - if result != None: - tag_id = result[0] - #create tag - if tag_id == None: - cursor.execute("select coalesce(max(tag_id),0) as tag_id from tag") - tag_id = cursor.fetchone()[0] - tag_id = tag_id + 1 - sql="insert into tag(tag_id, name) values(?, ?)" - cursor.execute(sql, (tag_id,tag)) - utils.logMsg("AddTagToMedia", "Adding tag: " + tag) - - #assign tag to item - if doRemove: - sql="DELETE FROM tag_link WHERE media_id = ? AND media_type = ? AND tag_id = ?" - cursor.execute(sql, (id, mediatype, tag_id)) - else: - sql="INSERT OR REPLACE into tag_link(tag_id, media_id, media_type) values(?, ?, ?)" - cursor.execute(sql, (tag_id, id, mediatype)) - - else: - idTag = None - cursor.execute("SELECT idTag as idTag FROM tag WHERE strTag = ?",(tag,)) - result = cursor.fetchone() - if result != None: - idTag = result[0] - #create idTag - if idTag == None: - cursor.execute("select coalesce(max(idTag),0) as idTag from tag") - idTag = cursor.fetchone()[0] - idTag = idTag + 1 - sql="insert into tag(idTag, strTag) values(?, ?)" - cursor.execute(sql, (idTag,tag)) - utils.logMsg("AddTagToMedia", "Adding tag: " + tag) - #assign tag to item - if doRemove: - sql="DELETE FROM taglinks WHERE idMedia = ? AND media_type = ? AND idTag = ?" - cursor.execute(sql, (id, mediatype, idTag)) - else: - sql="INSERT OR REPLACE into taglinks(idTag, idMedia, media_type) values(?, ?, ?)" - cursor.execute(sql, (idTag, id, mediatype)) + if kodiVersion == 15: + # Kodi Isengard + cursor.execute("SELECT tag_id as tag_id FROM tag WHERE name = ?", (tag,)) + try: + tag_id = cursor.fetchone()[0] + except: + # Create the tag + cursor.execute("select coalesce(max(tag_id),0) as tag_id from tag") + tag_id = cursor.fetchone()[0] + 1 + + query = "INSERT INTO tag(tag_id, name) values(?, ?)" + cursor.execute(query, (tag_id, tag)) + self.logMsg("Add Tag to media, adding tag: %s" % tag, 1) + finally: + # Assign tag to item + if not doRemove: + query = "INSERT OR REPLACE INTO tag_link(tag_id, media_id, media_type) values(?, ?, ?)" + cursor.execute(query, (tag_id, id, mediatype)) + else: + cursor.execute("DELETE FROM tag_link WHERE media_id = ? AND media_type = ? AND tag_id = ?", (id, mediatype, tag_id,)) + else: + # Kodi Gotham or Helix + cursor.execute("SELECT idTag as idTag FROM tag WHERE strTag = ?", (tag,)) + try: + idTag = cursor.fetchone()[0] + except: + # Create the tag + cursor.execute("select coalesce(max(idTag),0) as idTag from tag") + idTag = cursor.fetchone()[0] + 1 + + query = "INSERT INTO tag(idTag, strTag) values(?, ?)" + cursor.execute(query, (idTag, tag)) + self.logMsg("Add Tag to media, adding tag: %s" % tag, 1) + finally: + # Assign tag to item + if not doRemove: + query = "INSERT OR REPLACE INTO taglinks(idTag, idMedia, media_type) values(?, ?, ?)" + cursor.execute(query, (idTag, id, mediatype)) + else: + cursor.execute("DELETE FROM taglinks WHERE idMedia = ? AND media_type = ? AND idTag = ?", (id, mediatype, idTag,)) def AddStreamDetailsToMedia(self, streamdetails, fileid, cursor): - #first remove any existing entries - cursor.execute("delete FROM streamdetails WHERE idFile = ?", (fileid,)) + # First remove any existing entries + cursor.execute("DELETE FROM streamdetails WHERE idFile = ?", (fileid,)) if streamdetails: - #video details - sql="insert into streamdetails(idFile, iStreamType, strVideoCodec, fVideoAspect, iVideoWidth, iVideoHeight, strStereoMode) values(?, ?, ?, ?, ?, ?, ?)" - cursor.execute(sql, (fileid,0,streamdetails.get("videocodec"),streamdetails.get("aspectratio"),streamdetails.get("width"),streamdetails.get("height"),streamdetails.get("3dformat"))) - #audio details - sql="insert into streamdetails(idFile, iStreamType, strAudioCodec, iAudioChannels, strAudioLanguage, strSubtitleLanguage) values(?, ?, ?, ?, ?, ?)" - cursor.execute(sql, (fileid,1,streamdetails.get("audiocodec"),streamdetails.get("channels"),streamdetails.get("audiolanguage"),streamdetails.get("subtitlelanguage"))) + # Video details + for videotrack in streamdetails['videocodec']: + query = "INSERT INTO streamdetails(idFile, iStreamType, strVideoCodec, fVideoAspect, iVideoWidth, iVideoHeight, strStereoMode) values(?, ?, ?, ?, ?, ?, ?)" + cursor.execute(query, (fileid, 0, videotrack.get('videocodec'), videotrack.get('aspectratio'), videotrack.get('width'), videotrack.get('height'), videotrack.get('Video3DFormat'))) + + # Audio details + for audiotrack in streamdetails['audiocodec']: + query = "INSERT INTO streamdetails(idFile, iStreamType, strAudioCodec, iAudioChannels, strAudioLanguage) values(?, ?, ?, ?, ?)" + cursor.execute(query, (fileid, 1, audiotrack.get('audiocodec'), audiotrack.get('channels'), audiotrack.get('audiolanguage'))) + + # Subtitles details + for subtitletrack in streamdetails['subtitlelanguage']: + query = "INSERT INTO streamdetails(idFile, iStreamType, strSubtitleLanguage) values(?, ?, ?)" + cursor.execute(query, (fileid, 2, subtitletrack)) def addBoxsetToKodiLibrary(self, boxset, connection, cursor): - strSet = boxset["Name"] - # check if exists + strSet = boxset['Name'] cursor.execute("SELECT idSet FROM sets WHERE strSet = ?", (strSet,)) - result = cursor.fetchone() - setid = None - if result != None: - setid = result[0] - currentsetartsql = "SELECT type, url FROM art where media_type = ? and media_id = ? and url != ''" + try: + setid = cursor.fetchone()[0] + except: + # Boxset does not exists + query = "INSERT INTO sets(idSet, strSet) values(?, ?)" + cursor.execute(query, (None, strSet)) + # Get the setid of the new boxset + cursor.execute("SELECT idSet FROM sets WHERE strSet = ?", (strSet,)) + setid = cursor.fetchone()[0] + finally: + # Assign artwork + currentsetartsql = 'SELECT type, url FROM art where media_type = ? and media_id = ? and url != ""' cursor.execute(currentsetartsql, ("set", setid)) existing_type_map = {} rows = cursor.fetchall() @@ -1148,13 +1109,13 @@ class WriteKodiVideoDB(): existing_type_map[row[0] ] = row[1] artwork = {} - artwork["poster"] = API().getArtwork(boxset, "Primary", mediaType = "boxset") - artwork["banner"] = API().getArtwork(boxset, "Banner", mediaType = "boxset") - artwork["clearlogo"] = API().getArtwork(boxset, "Logo", mediaType = "boxset") - artwork["clearart"] = API().getArtwork(boxset, "Art", mediaType = "boxset") - artwork["landscape"] = API().getArtwork(boxset, "Thumb", mediaType = "boxset") - artwork["discart"] = API().getArtwork(boxset, "Disc", mediaType = "boxset") - artwork["fanart"] = API().getArtwork(boxset, "Backdrop", mediaType = "boxset") + artwork['poster'] = API().getArtwork(boxset, "Primary", mediaType = "boxset") + artwork['banner'] = API().getArtwork(boxset, "Banner", mediaType = "boxset") + artwork['clearlogo'] = API().getArtwork(boxset, "Logo", mediaType = "boxset") + artwork['clearart'] = API().getArtwork(boxset, "Art", mediaType = "boxset") + artwork['landscape'] = API().getArtwork(boxset, "Thumb", mediaType = "boxset") + artwork['discart'] = API().getArtwork(boxset, "Disc", mediaType = "boxset") + artwork['fanart'] = API().getArtwork(boxset, "Backdrop", mediaType = "boxset") art_types = ['poster','fanart','landscape','clearlogo','clearart','banner','discart'] for update_type in art_types: @@ -1163,68 +1124,25 @@ class WriteKodiVideoDB(): setupdateartsql = "UPDATE art SET url = ? where media_type = ? and media_id = ? and type = ?" cursor.execute(setupdateartsql,(artwork[update_type],"set",setid,update_type)) elif artwork[update_type] != '': - setartsql = "INSERT INTO art(media_id, media_type, type, url) VALUES(?,?,?,?)" + setartsql = "INSERT INTO art(media_id, media_type, type, url) VALUES(?, ?, ?, ?)" cursor.execute(setartsql,(setid,"set",update_type,artwork[update_type])) - - if setid == None: - # insert not exists - setssql="INSERT INTO sets (idSet, strSet) values(?, ?)" - cursor.execute(setssql, (None,strSet)) - #if OK: - cursor.execute("SELECT idSet FROM sets WHERE strSet = ?", (strSet,)) - - result = cursor.fetchone() - if result != None: - setid = result[0] - - currentsetartsql = "SELECT type, url FROM art where media_type = ? and media_id = ? and url != ''" - cursor.execute(currentsetartsql, ("set", setid)) - existing_type_map = {} - rows = cursor.fetchall() - for row in rows: - existing_type_map[row[0] ] = row[1] - - artwork = {} - artwork["poster"] = API().getArtwork(boxset, "Primary", mediaType = "boxset") - artwork["banner"] = API().getArtwork(boxset, "Banner", mediaType = "boxset") - artwork["clearlogo"] = API().getArtwork(boxset, "Logo", mediaType = "boxset") - artwork["clearart"] = API().getArtwork(boxset, "Art", mediaType = "boxset") - artwork["landscape"] = API().getArtwork(boxset, "Thumb", mediaType = "boxset") - artwork["discart"] = API().getArtwork(boxset, "Disc", mediaType = "boxset") - artwork["fanart"] = API().getArtwork(boxset, "Backdrop", mediaType = "boxset") - - art_types = ['poster','fanart','landscape','clearlogo','clearart','banner','discart'] - for update_type in art_types: - if ( update_type in existing_type_map ): - if ( existing_type_map[update_type] != artwork[update_type] ) and artwork[update_type] != '': - setupdateartsql = "UPDATE art SET url = ? where media_type = ? and media_id = ? and type = ?" - cursor.execute(setupdateartsql,(artwork[update_type],"set",setid,update_type)) - elif artwork[update_type] != '': - setartsql = "INSERT INTO art(media_id, media_type, type, url) VALUES(?,?,?,?)" - cursor.execute(setartsql,(setid,"set",update_type,artwork[update_type])) - + return True def updateBoxsetToKodiLibrary(self, boxsetmovie, boxset, connection, cursor): - strSet = boxset["Name"] - cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(boxsetmovie["Id"],)) - result = cursor.fetchone() - if result != None: - movieid = result[0] - else: - movieid = None - if movieid != None: - # check if exists + + strSet = boxset['Name'] + boxsetmovieid = boxsetmovie['Id'] + cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(boxsetmovieid,)) + try: + movieid = cursor.fetchone()[0] cursor.execute("SELECT idSet FROM sets WHERE strSet = ?", (strSet,)) - result = cursor.fetchone() - setid = None - if result != None: - setid = result[0] - - pathsql="update movie SET idSet = ? WHERE idMovie = ?" - cursor.execute(pathsql, (setid, movieid)) - - #update the checksum in emby table - cursor.execute("UPDATE emby SET checksum = ? WHERE emby_id = ?", (API().getChecksum(boxsetmovie),boxsetmovie["Id"])) - - \ No newline at end of file + setid = cursor.fetchone()[0] + except: pass + else: + query = "UPDATE movie SET idSet = ? WHERE idMovie = ?" + cursor.execute(query, (setid, movieid)) + + # Update the checksum in emby table + query = "UPDATE emby SET checksum = ? WHERE emby_id = ?" + cursor.execute(query, (API().getChecksum(boxsetmovie), boxsetmovieid)) \ No newline at end of file