def updatePlayCount(self, itemID): #update playcount of the itemID from MB3 to Kodi library addon = xbmcaddon.Addon(id='plugin.video.emby') WINDOW = xbmcgui.Window( 10000 ) embyItem = ReadEmbyDB().getItem(itemID) if(embyItem == None): return False type = embyItem.get("Type") #process movie if type == 'Movie': kodiItem = ReadKodiDB().getKodiMovie(itemID) if(kodiItem == None): return False if(self.ShouldStop(None)): return False userData = API().getUserData(embyItem) timeInfo = API().getTimeInfo(embyItem) kodiresume = int(round(kodiItem['resume'].get("position"))) resume = int(round(float(timeInfo.get("ResumeTime"))))*60 total = int(round(float(timeInfo.get("TotalTime"))))*60 if kodiresume != resume: WriteKodiDB().setKodiResumePoint(kodiItem['movieid'],resume,total,"movie") #write property forced will refresh the item in the list so playcount change is immediately visible WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")),"movie",True) WriteKodiDB().updateProperty(kodiItem,"lastplayed",userData.get("LastPlayedDate"), "movie") if(self.ShouldStop(None)): return False #process episode elif type == 'Episode': if(self.ShouldStop(None)): return False kodiItem = ReadKodiDB().getKodiEpisodeByMbItem(embyItem["Id"], embyItem["SeriesId"]) userData = API().getUserData(embyItem) timeInfo = API().getTimeInfo(embyItem) if kodiItem != None: kodiresume = int(round(kodiItem['resume'].get("position"))) resume = int(round(float(timeInfo.get("ResumeTime"))))*60 total = int(round(float(timeInfo.get("TotalTime"))))*60 if kodiresume != resume: WriteKodiDB().setKodiResumePoint(kodiItem['episodeid'],resume,total,"episode") #write property forced will refresh the item in the list so playcount change is immediately visible WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")),"episode",True) WriteKodiDB().updateProperty(kodiItem,"lastplayed",userData.get("LastPlayedDate"), "episode") return True
def getExtraFanArt(): itemPath = "" embyId = "" #get extrafanart for listitem - this will only be used for skins that actually call the listitem's path + fanart dir... try: #only do this if the listitem has actually changed itemPath = xbmc.getInfoLabel("ListItem.FileNameAndPath") if not itemPath: itemPath = xbmc.getInfoLabel("ListItem.Path") if ("/tvshows/" in itemPath or "/musicvideos/" in itemPath or "/movies/" in itemPath): embyId = itemPath.split("/")[-2] utils.logMsg("%s %s" % ("Emby addon", "getExtraFanArt"), "requesting extraFanArt for Id: " + embyId, 1) #we need to store the images locally for this to work because of the caching system in xbmc fanartDir = xbmc.translatePath("special://thumbnails/emby/" + embyId + "/") if not xbmcvfs.exists(fanartDir): #download the images to the cache directory xbmcvfs.mkdir(fanartDir) item = ReadEmbyDB().getFullItem(embyId) if item != None: if item.has_key("BackdropImageTags"): if(len(item["BackdropImageTags"]) > 0): WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') server = WINDOW.getProperty('server%s' % username) totalbackdrops = len(item["BackdropImageTags"]) count = 0 for backdrop in item["BackdropImageTags"]: backgroundUrl = "%s/mediabrowser/Items/%s/Images/Backdrop/%s/?MaxWidth=10000&MaxHeight=10000&Format=original&Tag=%s&EnableImageEnhancers=false" % (server, embyId, str(count), backdrop) count += 1 fanartFile = os.path.join(fanartDir,"fanart" + backdrop + ".jpg") li = xbmcgui.ListItem(backdrop, path=fanartFile) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=fanartFile, listitem=li) xbmcvfs.copy(backgroundUrl,fanartFile) else: #use existing cached images dirs, files = xbmcvfs.listdir(fanartDir) count = 1 for file in files: count +=1 li = xbmcgui.ListItem(file, path=os.path.join(fanartDir,file)) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=os.path.join(fanartDir,file), listitem=li) except Exception as e: utils.logMsg("%s %s" % ("Emby addon", "Error in getExtraFanArt"), str(e), 1) pass #always do endofdirectory to prevent errors in the logs xbmcplugin.endOfDirectory(int(sys.argv[1]))
def updateUserdata(self, userdata, connection, cursor): # This updates: LastPlayedDate, Playcount embyId = userdata['ItemId'] MBitem = ReadEmbyDB().getItem(embyId) if not MBitem: self.logMsg("UPDATE userdata to Kodi library FAILED, Item %s not found on server!" % embyId, 1) return # Get details checksum = API().getChecksum(MBitem) userdata = API().getUserData(MBitem) # Find the Kodi Id cursor.execute("SELECT kodi_id, media_type FROM emby WHERE emby_id = ?", (embyId,)) try: result = cursor.fetchone() kodiid = result[0] mediatype = result[1] self.logMsg("Found embyId: %s in database - kodiId: %s type: %s" % (embyId, kodiid, mediatype), 1) except: self.logMsg("Id: %s not found in the emby database table." % embyId, 1) else: if mediatype in ("song"): playcount = userdata['PlayCount'] dateplayed = userdata['LastPlayedDate'] query = "UPDATE song SET iTimesPlayed = ?, lastplayed = ? WHERE idSong = ?" cursor.execute(query, (playcount, dateplayed, kodiid)) #update the checksum in emby table query = "UPDATE emby SET checksum = ? WHERE emby_id = ?" cursor.execute(query, (checksum, embyId))
def getExtraFanArt(): itemPath = "" embyId = "" #get extrafanart for listitem - this will only be used for skins that actually call the listitem's path + fanart dir... try: #only do this if the listitem has actually changed itemPath = xbmc.getInfoLabel("ListItem.FileNameAndPath") if not itemPath: itemPath = xbmc.getInfoLabel("ListItem.Path") if ("/tvshows/" in itemPath or "/musicvideos/" in itemPath or "/movies/" in itemPath): embyId = itemPath.split("/")[-2] #we need to store the images locally for this to work because of the caching system in xbmc fanartDir = xbmc.translatePath("special://thumbnails/emby/" + embyId + "/") if not xbmcvfs.exists(fanartDir): #download the images to the cache directory xbmcvfs.mkdir(fanartDir) item = ReadEmbyDB().getFullItem(embyId) if item != None: if item.has_key("BackdropImageTags"): if(len(item["BackdropImageTags"]) > 0): totalbackdrops = len(item["BackdropImageTags"]) for index in range(0,totalbackdrops): backgroundUrl = API().getArtwork(item, "Backdrop",str(index)) fanartFile = os.path.join(fanartDir,"fanart" + str(index) + ".jpg") li = xbmcgui.ListItem(str(index), path=fanartFile) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=fanartFile, listitem=li) xbmcvfs.copy(backgroundUrl,fanartFile) else: #use existing cached images dirs, files = xbmcvfs.listdir(fanartDir) count = 1 for file in files: count +=1 li = xbmcgui.ListItem(file, path=os.path.join(fanartDir,file)) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=os.path.join(fanartDir,file), listitem=li) except: pass #always do endofdirectory to prevent errors in the logs xbmcplugin.endOfDirectory(int(sys.argv[1]))
def autoPlayPlayback(self): currentFile = xbmc.Player().getPlayingFile() data = self.played_information.get(currentFile) # only report playback if emby has initiated the playback (item_id has value) if(data != None and data.get("item_id") != None): addonSettings = xbmcaddon.Addon(id='plugin.video.emby') item_id = data.get("item_id") type = data.get("Type") # if its an episode see if autoplay is enabled if addonSettings.getSetting("autoPlaySeason")=="true" and type=="Episode": WINDOW = xbmcgui.Window( 10000 ) username = WINDOW.getProperty('currUser') userid = WINDOW.getProperty('userId%s' % username) server = WINDOW.getProperty('server%s' % username) # add remaining unplayed episodes if applicable MB3Episode = ReadEmbyDB().getItem(item_id) userData = MB3Episode["UserData"] if userData!=None and userData["Played"]==True: pDialog = xbmcgui.DialogProgress() seasonId = MB3Episode["SeasonId"] url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&ImageTypeLimit=1&Limit=1&SortBy=SortName&SortOrder=Ascending&Filters=IsUnPlayed&IncludeItemTypes=Episode&IsVirtualUnaired=false&Recursive=true&IsMissing=False&format=json" % seasonId jsonData = self.doUtils.downloadUrl(url) if(jsonData != ""): seasonData = json.loads(jsonData) if seasonData.get("Items") != None: item = seasonData.get("Items")[0] pDialog.create("Auto Play next episode", str(item.get("ParentIndexNumber")) + "x" + str(item.get("IndexNumber")) + ". " + item["Name"] + " found","Cancel to stop automatic play") count = 0 while(pDialog.iscanceled()==False and count < 10): xbmc.sleep(1000) count += 1 progress = count * 10 remainingsecs = 10 - count pDialog.update(progress, str(item.get("ParentIndexNumber")) + "x" + str(item.get("IndexNumber")) + ". " + item["Name"] + " found","Cancel to stop automatic play", str(remainingsecs) + " second(s) until auto dismiss") pDialog.close() if pDialog.iscanceled()==False: playTime = xbmc.Player().getTime() totalTime = xbmc.Player().getTotalTime() while xbmc.Player().isPlaying() and (totalTime-playTime > 2): xbmc.sleep(500) playTime = xbmc.Player().getTime() totalTime = xbmc.Player().getTotalTime() PlaybackUtils().PLAYAllEpisodes(seasonData.get("Items"))
def IncrementalSync(self, itemList): startupDone = WINDOW.getProperty("startup") == "done" #only perform incremental scan when full scan is completed if startupDone: #this will only perform sync for items received by the websocket addon = xbmcaddon.Addon(id='plugin.video.emby') dbSyncIndication = addon.getSetting("dbSyncIndication") == "true" performMusicSync = addon.getSetting("enableMusicSync") == "true" WINDOW.setProperty("SyncDatabaseRunning", "true") #show the progress dialog if (dbSyncIndication and xbmc.Player().isPlaying() == False): xbmcgui.Dialog().notification('Emby for Kodi', 'Performing incremental sync...', "special://home/addons/plugin.video.emby/icon.png") connection = utils.KodiSQL("video") cursor = connection.cursor() try: #### PROCESS MOVIES #### views = ReadEmbyDB().getCollections("movies") for view in views: allEmbyMovies = ReadEmbyDB().getMovies(view.get('id'), itemList) for item in allEmbyMovies: if not item.get('IsFolder'): WriteKodiVideoDB().addOrUpdateMovieToKodiLibrary(item["Id"],connection, cursor, view.get('title')) #### PROCESS BOX SETS ##### boxsets = ReadEmbyDB().getBoxSets() for boxset in boxsets: boxsetMovies = ReadEmbyDB().getMoviesInBoxSet(boxset["Id"]) WriteKodiVideoDB().addBoxsetToKodiLibrary(boxset,connection, cursor) for boxsetMovie in boxsetMovies: WriteKodiVideoDB().updateBoxsetToKodiLibrary(boxsetMovie,boxset, connection, cursor) #### PROCESS TV SHOWS #### views = ReadEmbyDB().getCollections("tvshows") for view in views: allEmbyTvShows = ReadEmbyDB().getTvShows(view.get('id'),itemList) for item in allEmbyTvShows: if item.get('IsFolder') and item.get('RecursiveItemCount') != 0: kodiId = WriteKodiVideoDB().addOrUpdateTvShowToKodiLibrary(item["Id"],connection, cursor, view.get('title')) #### PROCESS OTHERS BY THE ITEMLIST ###### for item in itemList: MBitem = ReadEmbyDB().getItem(item) itemType = MBitem.get('Type', "") #### PROCESS EPISODES ###### if "Episode" in itemType: #get the tv show cursor.execute("SELECT kodi_id FROM emby WHERE media_type='tvshow' AND emby_id=?", (MBitem["SeriesId"],)) result = cursor.fetchone() if result: kodi_show_id = result[0] else: kodi_show_id = None if kodi_show_id: WriteKodiVideoDB().addOrUpdateEpisodeToKodiLibrary(MBitem["Id"], kodi_show_id, connection, cursor) else: #tv show doesn't exist #perform full tvshow sync instead so both the show and episodes get added self.TvShowsFullSync(connection,cursor,None) elif "Season" in itemType: #get the tv show cursor.execute("SELECT kodi_id FROM emby WHERE media_type='tvshow' AND emby_id=?", (MBitem["SeriesId"],)) result = cursor.fetchone() if result: kodi_show_id = result[0] # update season WriteKodiVideoDB().updateSeasons(MBitem["SeriesId"], kodi_show_id, connection, cursor) #### PROCESS BOXSETS ###### elif "BoxSet" in itemType: boxsetMovies = ReadEmbyDB().getMoviesInBoxSet(boxset["Id"]) WriteKodiVideoDB().addBoxsetToKodiLibrary(boxset,connection, cursor) for boxsetMovie in boxsetMovies: WriteKodiVideoDB().updateBoxsetToKodiLibrary(boxsetMovie,boxset, connection, cursor) #### PROCESS MUSICVIDEOS #### elif "MusicVideo" in itemType: if not MBitem.get('IsFolder'): WriteKodiVideoDB().addOrUpdateMusicVideoToKodiLibrary(MBitem["Id"],connection, cursor) ### commit all changes to database ### connection.commit() cursor.close() ### PROCESS MUSIC LIBRARY ### if performMusicSync: connection = utils.KodiSQL("music") cursor = connection.cursor() for item in itemList: MBitem = ReadEmbyDB().getItem(item) itemType = MBitem.get('Type', "") if "MusicArtist" in itemType: WriteKodiMusicDB().addOrUpdateArtistToKodiLibrary(MBitem["Id"],connection, cursor) if "MusicAlbum" in itemType: WriteKodiMusicDB().addOrUpdateAlbumToKodiLibrary(MBitem["Id"],connection, cursor) if "Audio" in itemType: WriteKodiMusicDB().addOrUpdateSongToKodiLibrary(MBitem["Id"],connection, cursor) connection.commit() cursor.close() finally: xbmc.executebuiltin("UpdateLibrary(video)") WINDOW.setProperty("SyncDatabaseRunning", "false") # tell any widgets to refresh because the content has changed WINDOW.setProperty("widgetreload", datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
def TvShowsSync(self, connection, cursor ,fullsync, installFirstRun, itemList = []): addon = xbmcaddon.Addon(id='plugin.video.emby') WINDOW = xbmcgui.Window( 10000 ) pDialog = None startedSync = datetime.today() try: dbSyncIndication = addon.getSetting("dbSyncIndication") if(installFirstRun or dbSyncIndication == "Dialog Progress"): pDialog = xbmcgui.DialogProgress() elif(dbSyncIndication == "BG Progress"): pDialog = xbmcgui.DialogProgressBG() if(pDialog != None): pDialog.create('Sync DB', 'Sync DB') totalItemsAdded = 0 totalItemsUpdated = 0 totalItemsDeleted = 0 allTVShows = list() allMB3EpisodeIds = list() #for use with deletions allKodiEpisodeIds = [] # for use with deletions views = ReadEmbyDB().getCollections("tvshows") viewCount = len(views) viewCurrent = 1 progressTitle = "" for view in views: progressTitle = "Sync DB : Processing " + view.get('title') + " " + str(viewCurrent) + " of " + str(viewCount) # incremental sync --> new episodes only if fullsync == False: latestMBEpisodes = ReadEmbyDB().getLatestEpisodes(fullinfo = True, itemList = itemList) utils.logMsg("Sync TV", "Inc Sync Started on : " + str(len(latestMBEpisodes)) + " : " + str(itemList), 1) if latestMBEpisodes != None: allKodiTvShowsIds = set(ReadKodiDB().getKodiTvShowsIds(True)) # get included TV Shows showList = [] for episode in latestMBEpisodes: if(episode["SeriesId"] not in showList): showList.append(episode["SeriesId"]) utils.logMsg("Incremental TV Sync", "Included TV Show List : " + str(showList), 0) if(pDialog != None): pDialog.update(0, progressTitle) total = len(showList) + 1 count = 1 # process included TV Shows for showID in showList: embyTvShow = ReadEmbyDB().getFullItem(showID) if(showID not in allKodiTvShowsIds): utils.logMsg("Incremental TV Sync", "Adding TV Show : " + embyTvShow.get("Name"), 1) WriteKodiDB().addTVShowToKodiLibrary(embyTvShow, connection, cursor) kodiTvShow = ReadKodiDB().getKodiTVShow(showID) utils.logMsg("Incremental TV Sync", "Updating TV Show : " + embyTvShow.get("Name"), 1) WriteKodiDB().updateTVShowToKodiLibrary(embyTvShow, kodiTvShow, connection, cursor) # update progress bar if(pDialog != None): percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, progressTitle, "Processing TV Shows : " + str(count)) count += 1 if(pDialog != None): pDialog.update(0, progressTitle) total = len(latestMBEpisodes) + 1 count = 1 # process new episodes for episode in latestMBEpisodes: if(self.ShouldStop(pDialog)): return False WriteKodiDB().addEpisodeToKodiLibrary(episode, connection, cursor) progressAction = "Adding" totalItemsAdded += 1 # update progress bar if(pDialog != None): percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, progressTitle, progressAction + " Episode: " + str(count)) count += 1 #process updates if(pDialog != None): progressTitle = "Sync DB : Processing Episodes" pDialog.update(0, progressTitle) total = len(latestMBEpisodes) + 1 count = 1 for episode in latestMBEpisodes: if(self.ShouldStop(pDialog)): return False allKodiTVShows = ReadKodiDB().getKodiTvShows(False) kodishow = allKodiTVShows.get(episode["SeriesId"],None) kodiEpisodes = ReadKodiDB().getKodiEpisodes(kodishow["tvshowid"],True,True) if(self.ShouldStop(pDialog)): return False userData = API().getUserData(episode) if kodiEpisodes != None: KodiItem = kodiEpisodes.get(episode.get("Id"), None) if(KodiItem != None): WriteKodiDB().updateEpisodeToKodiLibrary(episode, KodiItem, connection, cursor) if(self.ShouldStop(pDialog)): return False # update progress bar if(pDialog != None): percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, progressTitle, "Updating Episode: " + str(count)) count += 1 # full sync --> Tv shows and Episodes if fullsync: viewTVShows = list() tvShowData = ReadEmbyDB().getTVShows(id = view.get('id') , fullinfo = True, fullSync = True) allKodiIds = set(ReadKodiDB().getKodiTvShowsIds(True)) if(self.ShouldStop(pDialog)): return False if (tvShowData == None): return False if(pDialog != None): progressTitle = "Sync DB : Processing TV Shows" pDialog.update(0, progressTitle) total = len(tvShowData) + 1 count = 1 # add TV Shows for item in tvShowData: if item.get('IsFolder') and item.get('RecursiveItemCount') != 0: allTVShows.append(item["Id"]) viewTVShows.append(item["Id"]) item['Tag'] = [] item['Tag'].append(view.get('title')) progMessage = "Processing" if item["Id"] not in allKodiIds: WriteKodiDB().addTVShowToKodiLibrary(item,connection, cursor) totalItemsAdded += 1 if(self.ShouldStop(pDialog)): return False # update progress bar if(pDialog != None): percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, progressTitle, "Adding Tv Show: " + str(count)) count += 1 if(pDialog != None): progressTitle = "Sync DB : Processing TV Shows" pDialog.update(0, progressTitle, "") total = len(viewTVShows) + 1 count = 1 # update TV Shows allKodiTVShows = ReadKodiDB().getKodiTvShows(True) for item in tvShowData: if item.get('IsFolder'): item['Tag'] = [] item['Tag'].append(view.get('title')) if allKodiTVShows != None: kodishow = allKodiTVShows.get(item["Id"],None) else: kodishow = None if(kodishow != None): updated = WriteKodiDB().updateTVShowToKodiLibrary(item,kodishow,connection, cursor) if(updated): totalItemsUpdated += 1 if(self.ShouldStop(pDialog)): return False # update progress bar if(pDialog != None): percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, progressTitle, "Updating Tv Show: " + str(count)) count += 1 # do episode adds allEpisodes = list() showTotal = len(viewTVShows) showCurrent = 1 for tvshow in viewTVShows: episodeData = ReadEmbyDB().getEpisodes(tvshow,True) if episodeData != None: if(self.ShouldStop(pDialog)): return False if(pDialog != None): progressTitle = "Sync DB : Processing Tv Show " + str(showCurrent) + " of " + str(showTotal) pDialog.update(0, progressTitle) total = len(episodeData) + 1 count = 0 for item in episodeData: if(self.ShouldStop(pDialog)): return False progressAction = "Adding" WriteKodiDB().addEpisodeToKodiLibrary(item, connection, cursor) # update progress bar if(pDialog != None): percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, progressTitle, progressAction + " Episode: " + str(count)) count += 1 showCurrent += 1 # do episode updates showCurrent = 1 for tvshow in viewTVShows: episodeData = ReadEmbyDB().getEpisodes(tvshow,True) kodiEpisodes = None allKodiTVShows = ReadKodiDB().getKodiTvShows(False) if allKodiTVShows != None: kodishow = allKodiTVShows.get(tvshow,None) if kodishow != None: kodiEpisodes = ReadKodiDB().getKodiEpisodes(kodishow["tvshowid"],True,True) if(self.ShouldStop(pDialog)): return False if(pDialog != None): progressTitle = "Sync DB : Processing Tv Show " + str(showCurrent) + " of " + str(showTotal) pDialog.update(0, progressTitle) total = len(episodeData) + 1 count = 0 #we have to compare the lists somehow for item in episodeData: #add episodeId to the list of all episodes for use later on the deletes allMB3EpisodeIds.append(item["Id"]) matchFound = False userData = API().getUserData(item) if kodiEpisodes != None: KodiItem = kodiEpisodes.get(item.get("Id"), None) if(KodiItem != None): updated = WriteKodiDB().updateEpisodeToKodiLibrary(item, KodiItem, connection, cursor) if(updated): totalItemsUpdated += 1 if(self.ShouldStop(pDialog)): return False # update progress bar if(pDialog != None): percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, progressTitle, "Updating Episode: " + str(count)) count += 1 #add all kodi episodes to a list with episodes for use later on to delete episodes #the mediabrowser ID is set as uniqueID in the NFO... for some reason this has key 'unknown' in the json response if kodishow != None: show = ReadKodiDB().getKodiEpisodes(kodishow["tvshowid"],False,False) if show != None: for episode in show: dict = {'episodeid': str(episode["uniqueid"]["unknown"]),'tvshowid': tvshow} allKodiEpisodeIds.append(dict) showCurrent += 1 if(pDialog != None): progressTitle = "Removing Deleted Items" pDialog.update(0, progressTitle) if(self.ShouldStop(pDialog)): return False # DELETES -- EPISODES # process any deletes only at fullsync allMB3EpisodeIdsSet = set(allMB3EpisodeIds) for episode in allKodiEpisodeIds: if episode.get('episodeid') not in allMB3EpisodeIdsSet: WINDOW.setProperty("embyid" + str(episode.get('episodeid')),"deleted") WriteKodiDB().deleteEpisodeFromKodiLibrary(episode.get('episodeid'),episode.get('tvshowid')) totalItemsDeleted += 1 # DELETES -- TV SHOWS if fullsync: allKodiShows = ReadKodiDB().getKodiTvShowsIds(True) allMB3TVShows = set(allTVShows) for show in allKodiShows: if not show in allMB3TVShows: WriteKodiDB().deleteTVShowFromKodiLibrary(show) totalItemsDeleted += 1 if(self.ShouldStop(pDialog)): return False # display notification if set up notificationString = "" if(totalItemsAdded > 0): notificationString += "Added:" + str(totalItemsAdded) + " " if(totalItemsUpdated > 0): notificationString += "Updated:" + str(totalItemsUpdated) + " " if(totalItemsDeleted > 0): notificationString += "Deleted:" + str(totalItemsDeleted) + " " timeTaken = datetime.today() - startedSync timeTakenString = str(int(timeTaken.seconds / 60)) + ":" + str(timeTaken.seconds % 60) utils.logMsg("Sync Episodes", "Finished " + timeTakenString + " " + notificationString, 0) if(dbSyncIndication == "Notify OnChange" and notificationString != ""): notificationString = "(" + timeTakenString + ") " + notificationString xbmc.executebuiltin("XBMC.Notification(Episode Sync: " + notificationString + ",)") elif(dbSyncIndication == "Notify OnFinish"): if(notificationString == ""): notificationString = "Done" notificationString = "(" + timeTakenString + ") " + notificationString xbmc.executebuiltin("XBMC.Notification(Episode Sync: " + notificationString + ",)") finally: if(pDialog != None): pDialog.close() return True
def PLAY(self, id): xbmc.log("PLAY Called") WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') userid = WINDOW.getProperty('userId%s' % username) server = WINDOW.getProperty('server%s' % username) url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&ImageTypeLimit=1" % id result = self.downloadUtils.downloadUrl(url) userData = result[u'UserData'] resume_result = 0 seekTime = 0 #get the resume point from Kodi DB for a Movie kodiItem = ReadKodiDB().getKodiMovie(id) if kodiItem != None: seekTime = int(round(kodiItem['resume'].get("position"))) else: #get the resume point from Kodi DB for an episode episodeItem = ReadEmbyDB().getItem(id) if episodeItem != None and str(episodeItem["Type"]) == "Episode": kodiItem = ReadKodiDB().getKodiEpisodeByMbItem(id,episodeItem["SeriesId"]) if kodiItem != None: seekTime = int(round(kodiItem['resume'].get("position"))) playurl = PlayUtils().getPlayUrl(server, id, result) isStrmFile = False thumbPath = API().getArtwork(result, "Primary") #workaround for when the file to play is a strm file itself if playurl.endswith(".strm"): isStrmFile = True tempPath = os.path.join(addondir,"library","temp.strm") xbmcvfs.copy(playurl, tempPath) sfile = open(tempPath, 'r') playurl = sfile.readline() sfile.close() xbmcvfs.delete(tempPath) WINDOW.setProperty("virtualstrm", id) WINDOW.setProperty("virtualstrmtype", result.get("Type")) listItem = xbmcgui.ListItem(path=playurl, iconImage=thumbPath, thumbnailImage=thumbPath) self.setListItemProps(server, id, listItem, result) # Can not play virtual items if (result.get("LocationType") == "Virtual"): xbmcgui.Dialog().ok(self.language(30128), self.language(30129)) watchedurl = "%s/mediabrowser/Users/%s/PlayedItems/%s" % (server, userid, id) positionurl = "%s/mediabrowser/Users/%s/PlayingItems/%s" % (server, userid, id) deleteurl = "%s/mediabrowser/Items/%s" % (server, id) # set the current playing info WINDOW.setProperty(playurl+"watchedurl", watchedurl) WINDOW.setProperty(playurl+"positionurl", positionurl) WINDOW.setProperty(playurl+"deleteurl", "") WINDOW.setProperty(playurl+"deleteurl", deleteurl) if seekTime != 0: displayTime = str(datetime.timedelta(seconds=seekTime)) display_list = [ self.language(30106) + ' ' + displayTime, self.language(30107)] resumeScreen = xbmcgui.Dialog() resume_result = resumeScreen.select(self.language(30105), display_list) if resume_result == 0: WINDOW.setProperty(playurl+"seektime", str(seekTime)) else: WINDOW.clearProperty(playurl+"seektime") else: WINDOW.clearProperty(playurl+"seektime") if result.get("Type")=="Episode": WINDOW.setProperty(playurl+"refresh_id", result.get("SeriesId")) else: WINDOW.setProperty(playurl+"refresh_id", id) WINDOW.setProperty(playurl+"runtimeticks", str(result.get("RunTimeTicks"))) WINDOW.setProperty(playurl+"type", result.get("Type")) WINDOW.setProperty(playurl+"item_id", id) if PlayUtils().isDirectPlay(result) == True: playMethod = "DirectPlay" else: playMethod = "Transcode" WINDOW.setProperty(playurl+"playmethod", playMethod) mediaSources = result.get("MediaSources") if(mediaSources != None): if mediaSources[0].get('DefaultAudioStreamIndex') != None: WINDOW.setProperty(playurl+"AudioStreamIndex", str(mediaSources[0].get('DefaultAudioStreamIndex'))) if mediaSources[0].get('DefaultSubtitleStreamIndex') != None: WINDOW.setProperty(playurl+"SubtitleStreamIndex", str(mediaSources[0].get('DefaultSubtitleStreamIndex'))) #this launches the playback #artwork only works with both resolvedurl and player command if isStrmFile: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) else: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) if(addon.getSetting("addExtraPlaybackArt") == "true"): utils.logMsg("PLAY", "Doing second xbmc.Player().play to add extra art") xbmc.Player().play(playurl,listItem)
def IncrementalSync(self, itemList): startupDone = WINDOW.getProperty("startup") == "done" #only perform incremental scan when full scan is completed if startupDone: #this will only perform sync for items received by the websocket dbSyncIndication = utils.settings("dbSyncIndication") == "true" performMusicSync = utils.settings("enableMusicSync") == "true" WINDOW.setProperty("SyncDatabaseRunning", "true") #show the progress dialog pDialog = None if (dbSyncIndication and xbmc.Player().isPlaying() == False): pDialog = xbmcgui.DialogProgressBG() pDialog.create('Emby for Kodi', 'Incremental Sync') self.logMsg("Doing LibraryChanged : Show Progress IncrementalSync()", 0); connection = utils.KodiSQL("video") cursor = connection.cursor() try: #### PROCESS MOVIES #### views = ReadEmbyDB().getCollections("movies") for view in views: allEmbyMovies = ReadEmbyDB().getMovies(view.get('id'), itemList) count = 1 total = len(allEmbyMovies) + 1 for item in allEmbyMovies: if(pDialog != None): progressTitle = "Incremental Sync "+ " (" + str(count) + " of " + str(total) + ")" percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, "Emby for Kodi - Incremental Sync Movies", progressTitle) count = count + 1 if not item.get('IsFolder'): WriteKodiVideoDB().addOrUpdateMovieToKodiLibrary(item["Id"],connection, cursor, view.get('title')) #### PROCESS BOX SETS ##### boxsets = ReadEmbyDB().getBoxSets() count = 1 total = len(boxsets) + 1 for boxset in boxsets: if(boxset["Id"] in itemList): utils.logMsg("IncrementalSync", "Updating box Set : " + str(boxset["Name"]), 1) boxsetMovies = ReadEmbyDB().getMoviesInBoxSet(boxset["Id"]) WriteKodiVideoDB().addBoxsetToKodiLibrary(boxset, connection, cursor) if(pDialog != None): progressTitle = "Incremental Sync "+ " (" + str(count) + " of " + str(total) + ")" percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, "Emby for Kodi - Incremental Sync BoxSet", progressTitle) count = count + 1 WriteKodiVideoDB().removeMoviesFromBoxset(boxset, connection, cursor) for boxsetMovie in boxsetMovies: WriteKodiVideoDB().updateBoxsetToKodiLibrary(boxsetMovie, boxset, connection, cursor) else: utils.logMsg("IncrementalSync", "Skipping Box Set : " + boxset["Name"], 1) #### PROCESS TV SHOWS #### views = ReadEmbyDB().getCollections("tvshows") for view in views: allEmbyTvShows = ReadEmbyDB().getTvShows(view.get('id'),itemList) count = 1 total = len(allEmbyTvShows) + 1 for item in allEmbyTvShows: if(pDialog != None): progressTitle = "Incremental Sync "+ " (" + str(count) + " of " + str(total) + ")" percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, "Emby for Kodi - Incremental Sync Tv", progressTitle) count = count + 1 if utils.settings('syncEmptyShows') == "true" or (item.get('IsFolder') and item.get('RecursiveItemCount') != 0): kodiId = WriteKodiVideoDB().addOrUpdateTvShowToKodiLibrary(item["Id"],connection, cursor, view.get('title')) #### PROCESS OTHERS BY THE ITEMLIST ###### count = 1 total = len(itemList) + 1 for item in itemList: if(pDialog != None): progressTitle = "Incremental Sync "+ " (" + str(count) + " of " + str(total) + ")" percentage = int(((float(count) / float(total)) * 100)) pDialog.update(percentage, "Emby for Kodi - Incremental Sync Items", progressTitle) count = count + 1 MBitem = ReadEmbyDB().getItem(item) itemType = MBitem.get('Type', "") #### PROCESS EPISODES ###### if "Episode" in itemType: #get the tv show cursor.execute("SELECT kodi_id FROM emby WHERE media_type='tvshow' AND emby_id=?", (MBitem["SeriesId"],)) result = cursor.fetchone() if result: kodi_show_id = result[0] else: kodi_show_id = None if kodi_show_id: WriteKodiVideoDB().addOrUpdateEpisodeToKodiLibrary(MBitem["Id"], kodi_show_id, connection, cursor) else: #tv show doesn't exist #perform full tvshow sync instead so both the show and episodes get added self.TvShowsFullSync(connection,cursor,None) elif "Season" in itemType: #get the tv show cursor.execute("SELECT kodi_id FROM emby WHERE media_type='tvshow' AND emby_id=?", (MBitem["SeriesId"],)) result = cursor.fetchone() if result: kodi_show_id = result[0] # update season WriteKodiVideoDB().updateSeasons(MBitem["SeriesId"], kodi_show_id, connection, cursor) #### PROCESS BOXSETS ###### elif "BoxSet" in itemType: boxsetMovies = ReadEmbyDB().getMoviesInBoxSet(boxset["Id"]) WriteKodiVideoDB().addBoxsetToKodiLibrary(boxset,connection, cursor) for boxsetMovie in boxsetMovies: WriteKodiVideoDB().updateBoxsetToKodiLibrary(boxsetMovie,boxset, connection, cursor) #### PROCESS MUSICVIDEOS #### elif "MusicVideo" in itemType: if not MBitem.get('IsFolder'): WriteKodiVideoDB().addOrUpdateMusicVideoToKodiLibrary(MBitem["Id"],connection, cursor) ### commit all changes to database ### connection.commit() cursor.close() ### PROCESS MUSIC LIBRARY ### if performMusicSync: connection = utils.KodiSQL("music") cursor = connection.cursor() for item in itemList: MBitem = ReadEmbyDB().getItem(item) itemType = MBitem.get('Type', "") if "MusicArtist" in itemType: WriteKodiMusicDB().addOrUpdateArtistToKodiLibrary(MBitem, connection, cursor) if "MusicAlbum" in itemType: WriteKodiMusicDB().addOrUpdateAlbumToKodiLibrary(MBitem, connection, cursor) if "Audio" in itemType: WriteKodiMusicDB().addOrUpdateSongToKodiLibrary(MBitem, connection, cursor) connection.commit() cursor.close() finally: if(pDialog != None): pDialog.close() self.SaveLastSync() xbmc.executebuiltin("UpdateLibrary(video)") WINDOW.setProperty("SyncDatabaseRunning", "false") # tell any widgets to refresh because the content has changed WINDOW.setProperty("widgetreload", datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
def buildVideoNodesListing(self): try: # the library path doesn't exist on all systems if not xbmcvfs.exists("special://profile/library/"): xbmcvfs.mkdir("special://profile/library") if not xbmcvfs.exists("special://profile/library/video/"): #we need to copy over the default items shutil.copytree(xbmc.translatePath("special://xbmc/system/library/video"), xbmc.translatePath("special://profile/library/video")) #always cleanup existing Emby video nodes first because we don't want old stuff to stay in there path = "special://profile/library/video/" if xbmcvfs.exists(path): allDirs, allFiles = xbmcvfs.listdir(path) for dir in allDirs: if dir.startswith("Emby "): shutil.rmtree(xbmc.translatePath("special://profile/library/video/" + dir)) for file in allFiles: if file.startswith("emby"): xbmcvfs.delete(path + file) #we build up a listing and set window props for all nodes we created #the window props will be used by the main entry point to quickly build up the listing and can be used in skins (like titan) too for quick reference #comment marcelveldt: please leave the window props as-is because I will be referencing them in titan skin... totalNodesCount = 0 #build the listing for all views views_movies = ReadEmbyDB().getCollections("movies") if views_movies: for view in views_movies: title = view.get('title') content = view.get('content') if content == "mixed": title = "%s - Movies" % title self.buildVideoNodeForView(title, "movies", totalNodesCount) totalNodesCount +=1 views_shows = ReadEmbyDB().getCollections("tvshows") if views_shows: for view in views_shows: title = view.get('title') content = view.get('content') if content == "mixed": title = "%s - TV Shows" % title self.buildVideoNodeForView(title, "tvshows", totalNodesCount) totalNodesCount +=1 #create tag node for emby channels nodefile = os.path.join(xbmc.translatePath("special://profile/library/video"), "emby_channels.xml") root = etree.Element("node", {"order":"1", "type":"folder"}) label = language(30173) etree.SubElement(root, "label").text = label etree.SubElement(root, "content").text = "movies" etree.SubElement(root, "path").text = "plugin://plugin.video.emby/?id=0&mode=channels" etree.SubElement(root, "icon").text = "special://home/addons/plugin.video.emby/icon.png" WINDOW.setProperty("Emby.nodes.%s.title" %str(totalNodesCount),label) WINDOW.setProperty("Emby.nodes.%s.type" %str(totalNodesCount),"channels") path = "library://video/emby_channels.xml" WINDOW.setProperty("Emby.nodes.%s.path" %str(totalNodesCount),"ActivateWindow(Video,%s,return)"%path) WINDOW.setProperty("Emby.nodes.%s.content" %str(totalNodesCount),path) totalNodesCount +=1 try: etree.ElementTree(root).write(nodefile, xml_declaration=True) except: etree.ElementTree(root).write(nodefile) #create tag node - favorite shows nodefile = os.path.join(xbmc.translatePath("special://profile/library/video"),"emby_favorite_shows.xml") root = etree.Element("node", {"order":"1", "type":"filter"}) label = language(30181) etree.SubElement(root, "label").text = label etree.SubElement(root, "match").text = "all" etree.SubElement(root, "content").text = "tvshows" etree.SubElement(root, "icon").text = "special://home/addons/plugin.video.emby/icon.png" etree.SubElement(root, "order", {"direction":"ascending"}).text = "sorttitle" Rule = etree.SubElement(root, "rule", {"field":"tag","operator":"is"}) etree.SubElement(Rule, "value").text = "Favorite tvshows" #do not localize the tagname itself WINDOW.setProperty("Emby.nodes.%s.title" %str(totalNodesCount),label) WINDOW.setProperty("Emby.nodes.%s.type" %str(totalNodesCount),"favourites") path = "library://video/emby_favorite_shows.xml" WINDOW.setProperty("Emby.nodes.%s.path" %str(totalNodesCount),"ActivateWindow(Video,%s,return)"%path) WINDOW.setProperty("Emby.nodes.%s.content" %str(totalNodesCount),path) totalNodesCount +=1 try: etree.ElementTree(root).write(nodefile, xml_declaration=True) except: etree.ElementTree(root).write(nodefile) #create tag node - favorite movies nodefile = os.path.join(xbmc.translatePath("special://profile/library/video"),"emby_favorite_movies.xml") root = etree.Element("node", {"order":"1", "type":"filter"}) label = language(30180) etree.SubElement(root, "label").text = label etree.SubElement(root, "match").text = "all" etree.SubElement(root, "content").text = "movies" etree.SubElement(root, "icon").text = "special://home/addons/plugin.video.emby/icon.png" etree.SubElement(root, "order", {"direction":"ascending"}).text = "sorttitle" Rule = etree.SubElement(root, "rule", {"field":"tag","operator":"is"}) etree.SubElement(Rule, "value").text = "Favorite movies" #do not localize the tagname itself WINDOW.setProperty("Emby.nodes.%s.title" %str(totalNodesCount),label) WINDOW.setProperty("Emby.nodes.%s.type" %str(totalNodesCount),"favourites") path = "library://video/emby_favorite_movies.xml" WINDOW.setProperty("Emby.nodes.%s.path" %str(totalNodesCount),"ActivateWindow(Video,%s,return)"%path) WINDOW.setProperty("Emby.nodes.%s.content" %str(totalNodesCount),path) totalNodesCount +=1 try: etree.ElementTree(root).write(nodefile, xml_declaration=True) except: etree.ElementTree(root).write(nodefile) WINDOW.setProperty("Emby.nodes.total", str(totalNodesCount)) except Exception as e: utils.logMsg("Emby addon","Error while creating videonodes listings, restart required ?") print e
def getExtraFanArt(): itemPath = "" embyId = "" #get extrafanart for listitem - this will only be used for skins that actually call the listitem's path + fanart dir... try: #only do this if the listitem has actually changed itemPath = xbmc.getInfoLabel("ListItem.FileNameAndPath") if not itemPath: itemPath = xbmc.getInfoLabel("ListItem.Path") if ("/tvshows/" in itemPath or "/musicvideos/" in itemPath or "/movies/" in itemPath): embyId = itemPath.split("/")[-2] utils.logMsg("%s %s" % ("Emby addon", "getExtraFanArt"), "requesting extraFanArt for Id: " + embyId, 1) #we need to store the images locally for this to work because of the caching system in xbmc fanartDir = xbmc.translatePath("special://thumbnails/emby/" + embyId + "/") if not xbmcvfs.exists(fanartDir): #download the images to the cache directory xbmcvfs.mkdir(fanartDir) item = ReadEmbyDB().getFullItem(embyId) if item != None: if item.has_key("BackdropImageTags"): if (len(item["BackdropImageTags"]) > 0): WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') server = WINDOW.getProperty('server%s' % username) totalbackdrops = len(item["BackdropImageTags"]) count = 0 for backdrop in item["BackdropImageTags"]: backgroundUrl = "%s/mediabrowser/Items/%s/Images/Backdrop/%s/?MaxWidth=10000&MaxHeight=10000&Format=original&Tag=%s&EnableImageEnhancers=false" % ( server, embyId, str(count), backdrop) count += 1 fanartFile = os.path.join( fanartDir, "fanart" + backdrop + ".jpg") li = xbmcgui.ListItem(backdrop, path=fanartFile) xbmcplugin.addDirectoryItem(handle=int( sys.argv[1]), url=fanartFile, listitem=li) xbmcvfs.copy(backgroundUrl, fanartFile) else: #use existing cached images dirs, files = xbmcvfs.listdir(fanartDir) count = 1 for file in files: count += 1 li = xbmcgui.ListItem(file, path=os.path.join(fanartDir, file)) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=os.path.join( fanartDir, file), listitem=li) except Exception as e: utils.logMsg("%s %s" % ("Emby addon", "Error in getExtraFanArt"), str(e), 1) pass #always do endofdirectory to prevent errors in the logs xbmcplugin.endOfDirectory(int(sys.argv[1]))
def addOrUpdateArtistToKodiLibrary( 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() MBitem = ReadEmbyDB().getFullItem(embyId) # 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: artistid = result[0] else: artistid = None #### The artist details ######### name = utils.convertEncoding(MBitem["Name"]) musicBrainsId = None if MBitem.get("ProviderIds"): if MBitem.get("ProviderIds").get("MusicBrainzArtist"): musicBrainsId = MBitem.get("ProviderIds").get("MusicBrainzArtist") genres = " / ".join(MBitem.get("Genres")) bio = utils.convertEncoding(API().getOverview(MBitem)) dateadded = None if MBitem.get("DateCreated"): dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") thumb = API().getArtwork(MBitem, "Primary") if thumb: thumb = "<thumb>" + thumb + "</thumb>" fanart = API().getArtwork(MBitem, "Backdrop") if fanart: fanart = "<fanart>" + fanart + "</fanart>" lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S') #safety check 1: does the artist already exist? cursor.execute("SELECT idArtist FROM artist WHERE strArtist = ?",(name,)) result = cursor.fetchone() if result != None: artistid = result[0] #safety check 2: does the musicbrainzartistId already exist? cursor.execute("SELECT idArtist FROM artist WHERE strMusicBrainzArtistID = ?",(musicBrainsId,)) result = cursor.fetchone() if result != None: artistid = result[0] ##### ADD THE ARTIST ############ if artistid == None: utils.logMsg("ADD artist to Kodi library","Id: %s - Title: %s" % (embyId, name)) try: #create the artist cursor.execute("select coalesce(max(idArtist),0) as artistid from artist") artistid = cursor.fetchone()[0] artistid = artistid + 1 pathsql="insert into artist(idArtist, strArtist, strMusicBrainzArtistID, strGenres, strBiography, strImage, strFanart, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?)" cursor.execute(pathsql, (artistid, name, musicBrainsId, genres, bio, thumb, fanart, lastScraped, dateadded)) #create the reference in emby table pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" cursor.execute(pathsql, (MBitem["Id"], artistid, "artist", API().getChecksum(MBitem))) except Exception, e: utils.logMsg("Error while adding artist to Kodi library: ", e) return
def addOrUpdateSongToKodiLibrary( 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() MBitem = ReadEmbyDB().getFullItem(embyId) timeInfo = API().getTimeInfo(MBitem) userData=API().getUserData(MBitem) kodiVersion = 14 if xbmc.getInfoLabel("System.BuildVersion").startswith("15"): kodiVersion = 15 # 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: songid = result[0] else: songid = None #### The song details ######### name = utils.convertEncoding(MBitem["Name"]) musicBrainzId = None if MBitem.get("ProviderIds"): if MBitem.get("ProviderIds").get("MusicBrainzTrackId"): musicBrainzId = MBitem.get("ProviderIds").get("MusicBrainzTrackId") genres = " / ".join(MBitem.get("Genres")) artists = " / ".join(MBitem.get("Artists")) track = MBitem.get("IndexNumber") duration = MBitem.get("RunTimeTicks", 0) / 10000000 year = MBitem.get("ProductionYear") bio = utils.convertEncoding(API().getOverview(MBitem)) dateadded = None if MBitem.get("DateCreated"): dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") if userData.get("LastPlayedDate") != None: lastplayed = userData.get("LastPlayedDate") else: lastplayed = None playcount = None if userData.get("PlayCount"): playcount = int(userData.get("PlayCount")) #get the album albumid = None if MBitem.get("AlbumId"): cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(MBitem.get("AlbumId"),)) result = cursor.fetchone() if result: albumid = result[0] if albumid == None: #no album = single in kodi, we need to create a single album for that cursor.execute("select coalesce(max(idAlbum),0) as albumid from album") albumid = cursor.fetchone()[0] albumid = albumid + 1 if kodiVersion == 15: pathsql="insert into album(idAlbum, strArtists, strGenres, iYear, dateAdded, strReleaseType) values(?, ?, ?, ?, ?, ?)" cursor.execute(pathsql, (albumid, artists, genres, year, dateadded, "single")) else: pathsql="insert into album(idAlbum, strArtists, strGenres, iYear, dateAdded) values(?, ?, ?, ?, ?)" cursor.execute(pathsql, (albumid, artists, genres, year, dateadded)) #some stuff here to get the album linked to artists for artist in MBitem.get("ArtistItems"): cursor.execute("SELECT kodi_id FROM emby WHERE emby_id = ?",(artist["Id"],)) result = cursor.fetchone() if result: artistid = result[0] sql="INSERT OR REPLACE into album_artist(idArtist, idAlbum, strArtist) values(?, ?, ?)" cursor.execute(sql, (artistid, albumid, artist["Name"])) 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 + "/Audio/%s/" %MBitem["Id"] filename = "stream.mp3" #get 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) values(?, ?)" cursor.execute(pathsql, (pathid,path)) ##### ADD THE SONG ############ if songid == None: utils.logMsg("ADD song to Kodi library","Id: %s - Title: %s" % (embyId, name)) try: #create the song cursor.execute("select coalesce(max(idSong),0) as songid from song") songid = cursor.fetchone()[0] songid = songid + 1 pathsql="insert into song(idSong, idAlbum, idPath, strArtists, strGenres, strTitle, iTrack, iDuration, iYear, strFileName, strMusicBrainzTrackID, iTimesPlayed, lastplayed) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" cursor.execute(pathsql, (songid, albumid, pathid, artists, genres, name, track, duration, year, filename, musicBrainzId, playcount, lastplayed)) #create the reference in emby table pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" cursor.execute(pathsql, (MBitem["Id"], songid, "song", API().getChecksum(MBitem))) except Exception, e: utils.logMsg("Error while adding song to Kodi library: ", e) return
def addOrUpdateAlbumToKodiLibrary( 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() kodiVersion = 14 if xbmc.getInfoLabel("System.BuildVersion").startswith("15"): kodiVersion = 15 MBitem = ReadEmbyDB().getFullItem(embyId) # 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: albumid = result[0] else: albumid = None #### The album details ######### name = utils.convertEncoding(MBitem["Name"]) MBartists = [] for item in MBitem.get("AlbumArtists"): MBartists.append(item["Name"]) artists = " / ".join(MBartists) year = MBitem.get("ProductionYear") musicBrainsId = None if MBitem.get("ProviderIds"): if MBitem.get("ProviderIds").get("MusicBrainzAlbum"): musicBrainsId = MBitem.get("ProviderIds").get("MusicBrainzAlbum") genres = " / ".join(MBitem.get("Genres")) bio = utils.convertEncoding(API().getOverview(MBitem)) dateadded = None if MBitem.get("DateCreated"): dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") thumb = API().getArtwork(MBitem, "Primary") if thumb: thumb = "<thumb>" + thumb + "</thumb>" lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S') ##### ADD THE ALBUM ############ if albumid == None: utils.logMsg("ADD album to Kodi library","Id: %s - Title: %s" % (embyId, name)) #safety check: does the strMusicBrainzAlbumID already exist? cursor.execute("SELECT idAlbum FROM album WHERE strMusicBrainzAlbumID = ?",(musicBrainsId,)) result = cursor.fetchone() if result != None: albumid = result[0] else: #create the album try: cursor.execute("select coalesce(max(idAlbum),0) as albumid from album") albumid = cursor.fetchone()[0] albumid = albumid + 1 if kodiVersion == 15: pathsql="insert into album(idAlbum, strAlbum, strMusicBrainzAlbumID, strArtists, iYear, strGenres, strReview, strImage, lastScraped, dateAdded, strReleaseType) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" cursor.execute(pathsql, (albumid, name, musicBrainsId, artists, year, genres, bio, thumb, lastScraped, dateadded, "album")) else: pathsql="insert into album(idAlbum, strAlbum, strMusicBrainzAlbumID, strArtists, iYear, strGenres, strReview, strImage, lastScraped, dateAdded) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" cursor.execute(pathsql, (albumid, name, musicBrainsId, artists, year, genres, bio, thumb, lastScraped, dateadded)) #create the reference in emby table pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" cursor.execute(pathsql, (MBitem["Id"], albumid, "album", API().getChecksum(MBitem))) except Exception, e: utils.logMsg("Error while adding album to Kodi library: ", e) return #create the reference in emby table pathsql = "INSERT into emby(emby_id, kodi_id, media_type, checksum) values(?, ?, ?, ?)" cursor.execute(pathsql, (MBitem["Id"], albumid, "album", API().getChecksum(MBitem)))