def get_uncached_artwork(): """ Returns a list of URLs that haven't been cached yet """ all_urls = [] cached_urls = [] result = [] connection = kodiSQL('video') cursor = connection.cursor() # Get all artwork urls cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") for url in cursor.fetchall(): all_urls.append(url[0]) connection.close() connection = kodiSQL('music') cursor = connection.cursor() cursor.execute("SELECT url FROM art") for url in cursor.fetchall(): all_urls.append(url[0]) connection.close() # Get the cached urls connection = kodiSQL('texture') cursor = connection.cursor() cursor.execute("SELECT url FROM texture") for url in cursor.fetchall(): cached_urls.append(url[0]) connection.close() for url in all_urls: if url not in cached_urls: result.append(url) log.info('%s artwork urls have not been cached yet' % len(result)) return result
def refreshViews(self): embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() kodiconn = utils.kodiSQL('video') kodicursor = kodiconn.cursor() # Compare views, assign correct tags to items self.maintainViews(embycursor, kodicursor) self.dbCommit(kodiconn) kodicursor.close() embyconn.commit() embycursor.close()
def getView_embyId(self, itemid): # Returns ancestors using embyId viewId = None url = "{server}/emby/Items/%s/Ancestors?UserId={UserId}&format=json" % itemid result = self.doUtils(url) for view in result: viewtype = view['Type'] if viewtype == "CollectionFolder": # Found view viewId = view['Id'] # Compare to view table in emby database emby = utils.kodiSQL('emby') cursor_emby = emby.cursor() query = ' '.join(( "SELECT view_name, media_type", "FROM view", "WHERE view_id = ?" )) cursor_emby.execute(query, (viewId,)) result = cursor_emby.fetchone() try: viewName = result[0] mediatype = result[1] except TypeError: viewName = None mediatype = None cursor_emby.close() return [viewName, viewId, mediatype]
def deleteCachedArtwork(self, url): # Only necessary to remove and apply a new backdrop or poster connection = utils.kodiSQL('texture') cursor = connection.cursor() try: cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,)) cachedurl = cursor.fetchone()[0] except TypeError: self.logMsg("Could not find cached url.", 1) except OperationalError: self.logMsg("Database is locked. Skip deletion process.", 1) else: # Delete thumbnail as well as the entry thumbnails = xbmc.translatePath("special://thumbnails/%s" % cachedurl).decode('utf-8') self.logMsg("Deleting cached thumbnail: %s" % thumbnails, 1) xbmcvfs.delete(thumbnails) try: cursor.execute("DELETE FROM texture WHERE url = ?", (url,)) connection.commit() except OperationalError: self.logMsg("Issue deleting url from cache. Skipping.", 2) finally: cursor.close()
def _rate_song(self): conn = kodiSQL('music') cursor = conn.cursor() query = "SELECT rating FROM song WHERE idSong = ?" cursor.execute(query, (self.kodi_id,)) try: value = cursor.fetchone()[0] current_value = int(round(float(value), 0)) except TypeError: pass else: new_value = dialog("numeric", 0, lang(30411), str(current_value)) if new_value > -1: new_value = int(new_value) if new_value > 5: new_value = 5 if settings('enableUpdateSongRating') == "true": musicutils.updateRatingToFile(new_value, self.api.get_file_path()) query = "UPDATE song SET rating = ? WHERE idSong = ?" cursor.execute(query, (new_value, self.kodi_id,)) conn.commit() finally: cursor.close()
def modifyPlaylist(self, itemids): embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) self.logMsg("---*** ADD TO PLAYLIST ***---", 1) self.logMsg("Items: %s" % itemids, 1) player = xbmc.Player() playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) for itemid in itemids: embydb_item = emby_db.getItem_byId(itemid) try: dbid = embydb_item[0] mediatype = embydb_item[4] except TypeError: # Item is not found in our database, add item manually item = self.emby.getItem(itemid) self.addtoPlaylist_xbmc(playlist, item) else: # Add to playlist self.addtoPlaylist(dbid, mediatype) self.logMsg("Adding %s to playlist." % itemid, 1) self.verifyPlaylist() embycursor.close() return playlist
def deleteItem(): # Serves as a keymap action if xbmc.getInfoLabel('ListItem.Property(embyid)'): # If we already have the embyid embyid = xbmc.getInfoLabel('ListItem.Property(embyid)') else: dbid = xbmc.getInfoLabel('ListItem.DBID') itemtype = xbmc.getInfoLabel('ListItem.DBTYPE') if not itemtype: if xbmc.getCondVisibility('Container.Content(albums)'): itemtype = "album" elif xbmc.getCondVisibility('Container.Content(artists)'): itemtype = "artist" elif xbmc.getCondVisibility('Container.Content(songs)'): itemtype = "song" elif xbmc.getCondVisibility('Container.Content(pictures)'): itemtype = "picture" else: utils.logMsg("EMBY delete", "Unknown type, unable to proceed.", 1) return embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) item = emby_db.getItem_byKodiId(dbid, itemtype) embycursor.close() try: embyid = item[0] except TypeError: utils.logMsg("EMBY delete", "Unknown embyId, unable to proceed.", 1) return if utils.settings('skipContextMenu') != "true": resp = xbmcgui.Dialog().yesno( heading="Confirm delete", line1=("Delete file from Emby Server? This will " "also delete the file(s) from disk!")) if not resp: utils.logMsg("EMBY delete", "User skipped deletion for: %s." % embyid, 1) return doUtils = downloadutils.DownloadUtils() url = "{server}/emby/Items/%s?format=json" % embyid utils.logMsg("EMBY delete", "Deleting request: %s" % embyid, 0) doUtils.downloadUrl(url, type="DELETE")
def playAll(self, itemids, startat): window = utils.window embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) player = xbmc.Player() playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() self.logMsg("---*** PLAY ALL ***---", 1) self.logMsg("Items: %s and start at: %s" % (itemids, startat), 1) started = False window('plex_customplaylist', value="true") if startat != 0: # Seek to the starting position window('plex_customplaylist.seektime', str(startat)) with embydb.GetEmbyDB() as emby_db: for itemid in itemids: embydb_item = emby_db.getItem_byId(itemid) try: dbid = embydb_item[0] mediatype = embydb_item[4] except TypeError: # Item is not found in our database, add item manually self.logMsg("Item was not found in the database, manually " "adding item.", 1) item = PlexFunctions.GetPlexMetadata(itemid) if item is None or item == 401: self.logMsg('Could not download itemid %s' % itemid, -1) else: self.addtoPlaylist_xbmc(playlist, item) else: # Add to playlist self.addtoPlaylist(dbid, mediatype) self.logMsg("Adding %s to playlist." % itemid, 1) if not started: started = True player.play(playlist) self.verifyPlaylist()
def playAll(self, itemids, startat): log = self.logMsg window = utils.window embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) player = xbmc.Player() playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() log("---*** PLAY ALL ***---", 1) log("Items: %s and start at: %s" % (itemids, startat), 1) started = False window('emby_customplaylist', value="true") if startat != 0: # Seek to the starting position window('emby_customplaylist.seektime', str(startat)) for itemid in itemids: embydb_item = emby_db.getItem_byId(itemid) try: dbid = embydb_item[0] mediatype = embydb_item[4] except TypeError: # Item is not found in our database, add item manually log("Item was not found in the database, manually adding item.", 1) item = self.emby.getItem(itemid) self.addtoPlaylist_xbmc(playlist, item) else: # Add to playlist self.addtoPlaylist(dbid, mediatype) log("Adding %s to playlist." % itemid, 1) if not started: started = True player.play(playlist) self.verifyPlaylist() embycursor.close()
def playAll(self, itemids, startat): embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) self.logMsg("---*** PLAY ALL ***---", 1) self.logMsg("Items: %s" % itemids) player = xbmc.Player() playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() started = False utils.window('emby_customplaylist', value="true", windowid=10101) position = 0 for itemid in itemids: embydb_item = emby_db.getItem_byId(itemid) try: dbid = embydb_item[0] mediatype = embydb_item[4] except TypeError: # Item is not found in our database, add item manually item = self.emby.getItem(itemid) self.addtoPlaylist_xbmc(playlist, item) else: # Add to playlist self.addtoPlaylist(dbid, mediatype) self.logMsg("Adding %s to playlist." % itemid, 1) if not started: started = True player.play(playlist) if startat: # Seek to the starting position seektime = startat / 10000000.0 player.seekTime(seektime) self.verifyPlaylist() embycursor.close()
def deleteCachedArtwork(self, url): # Only necessary to remove and apply a new backdrop or poster connection = kodiSQL('texture') cursor = connection.cursor() try: cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,)) cachedurl = cursor.fetchone()[0] except TypeError: log.info("Could not find cached url.") else: # Delete thumbnail as well as the entry thumbnails = tryDecode( translatePath("special://thumbnails/%s" % cachedurl)) log.debug("Deleting cached thumbnail: %s" % thumbnails) try: delete(thumbnails) except Exception as e: log.error('Could not delete cached artwork %s. Error: %s' % (thumbnails, e)) cursor.execute("DELETE FROM texture WHERE url = ?", (url,)) connection.commit() finally: connection.close()
def run_internal(self): dialog = xbmcgui.Dialog() startupComplete = False log.warn("---===### Starting LibrarySync ###===---") # Verify database structure, otherwise create it. self._verify_emby_database() while not self.monitor.abortRequested(): # In the event the server goes offline while self.suspend_thread: # Set in service.py if self.monitor.waitForAbort(5): # Abort was requested while waiting. We should exit break if (window('emby_dbCheck') != "true" and settings('SyncInstallRunDone') == "true"): # Verify the validity of the database embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) currentVersion = emby_db.get_version() ###$ Begin migration $### if not currentVersion: currentVersion = emby_db.get_version( settings('dbCreatedWithVersion') or self.clientInfo.get_version()) embyconn.commit() log.info("Migration of database version completed") ###$ End migration $### embycursor.close() window('emby_version', value=currentVersion) minVersion = window('emby_minDBVersion') uptoDate = self.compareDBVersion(currentVersion, minVersion) if not uptoDate: log.warn( "Database version out of date: %s minimum version required: %s" % (currentVersion, minVersion)) resp = dialog.yesno(lang(29999), lang(33022)) if not resp: log.warn( "Database version is out of date! USER IGNORED!") dialog.ok(lang(29999), lang(33023)) else: utils.reset() break window('emby_dbCheck', value="true") if not startupComplete: # Verify the video database can be found videoDb = utils.getKodiVideoDBPath() if not xbmcvfs.exists(videoDb): # Database does not exists log.error("The current Kodi version is incompatible " "with the Emby for Kodi add-on. Please visit " "https://github.com/MediaBrowser/Emby.Kodi/wiki " "to know which Kodi versions are supported.") dialog.ok(heading=lang(29999), line1=lang(33024)) break # Run start up sync log.warn("Database version: %s", window('emby_version')) log.info("SyncDatabase (started)") startTime = datetime.now() librarySync = self.startSync() elapsedTime = datetime.now() - startTime log.info("SyncDatabase (finished in: %s) %s" % (str(elapsedTime).split('.')[0], librarySync)) # Add other servers at this point # TODO: re-add once plugin listing is created # self.user.load_connect_servers() # Only try the initial sync once per kodi session regardless # This will prevent an infinite loop in case something goes wrong. startupComplete = True # Process updates if window('emby_dbScan') != "true" and window( 'emby_shouldStop') != "true": self.incrementalSync() if window('emby_onWake') == "true" and window( 'emby_online') == "true": # Kodi is waking up # Set in kodimonitor.py window('emby_onWake', clear=True) if window('emby_syncRunning') != "true": log.info("SyncDatabase onWake (started)") librarySync = self.startSync() log.info("SyncDatabase onWake (finished) %s" % librarySync) if self.stop_thread: # Set in service.py log.debug("Service terminated thread.") break if self.monitor.waitForAbort(1): # Abort was requested while waiting. We should exit break log.warn("###===--- LibrarySync Stopped ---===###")
def FullTextureCacheSync(self): # This method will sync all Kodi artwork to textures13.db # and cache them locally. This takes diskspace! if not xbmcgui.Dialog().yesno("Image Texture Cache", "Running the image cache process can take some time.", "Are you sure you want continue?"): return self.logMsg("Doing Image Cache Sync", 1) dialog = xbmcgui.DialogProgress() dialog.create("Emby for Kodi", "Image Cache Sync") # ask to rest all existing or not if xbmcgui.Dialog().yesno("Image Texture Cache", "Reset all existing cache data first?", ""): self.logMsg("Resetting all cache data first", 1) # Remove all existing textures first path = xbmc.translatePath("special://thumbnails/").decode('utf-8') if xbmcvfs.exists(path): allDirs, allFiles = xbmcvfs.listdir(path) for dir in allDirs: allDirs, allFiles = xbmcvfs.listdir(path+dir) for file in allFiles: if os.path.supports_unicode_filenames: xbmcvfs.delete(os.path.join(path+dir.decode('utf-8'),file.decode('utf-8'))) else: xbmcvfs.delete(os.path.join(path.encode('utf-8')+dir,file)) # remove all existing data from texture DB textureconnection = utils.kodiSQL('texture') texturecursor = textureconnection.cursor() texturecursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = texturecursor.fetchall() for row in rows: tableName = row[0] if(tableName != "version"): texturecursor.execute("DELETE FROM " + tableName) textureconnection.commit() texturecursor.close() # Cache all entries in video DB connection = utils.kodiSQL('video') cursor = connection.cursor() cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") # dont include actors result = cursor.fetchall() total = len(result) count = 1 percentage = 0 self.logMsg("Image cache sync about to process " + str(total) + " images", 1) for url in result: if dialog.iscanceled(): break percentage = int((float(count) / float(total))*100) textMessage = str(count) + " of " + str(total) + " (" + str(len(self.imageCacheThreads)) + ")" dialog.update(percentage, "Updating Image Cache: " + textMessage) self.CacheTexture(url[0]) count += 1 cursor.close() # Cache all entries in music DB connection = utils.kodiSQL('music') cursor = connection.cursor() cursor.execute("SELECT url FROM art") result = cursor.fetchall() total = len(result) count = 1 percentage = 0 self.logMsg("Image cache sync about to process " + str(total) + " images", 1) for url in result: if dialog.iscanceled(): break percentage = int((float(count) / float(total))*100) textMessage = str(count) + " of " + str(total) dialog.update(percentage, "Updating Image Cache: " + textMessage) self.CacheTexture(url[0]) count += 1 cursor.close() dialog.update(100, "Waiting for all threads to exit: " + str(len(self.imageCacheThreads))) self.logMsg("Waiting for all threads to exit", 1) while len(self.imageCacheThreads) > 0: for thread in self.imageCacheThreads: if thread.isFinished: self.imageCacheThreads.remove(thread) dialog.update(100, "Waiting for all threads to exit: " + str(len(self.imageCacheThreads))) self.logMsg("Waiting for all threads to exit: " + str(len(self.imageCacheThreads)), 1) xbmc.sleep(500) dialog.close()
def fullTextureCacheSync(self): # This method will sync all Kodi artwork to textures13.db # and cache them locally. This takes diskspace! dialog = xbmcgui.Dialog() if not dialog.yesno(heading=lang(29999), line1=lang(33042)): return log("Doing Image Cache Sync", 1) pdialog = xbmcgui.DialogProgress() pdialog.create(lang(29999), lang(33043)) # ask to rest all existing or not if dialog.yesno(lang(29999), lang(33044)): log("Resetting all cache data first.", 1) # Remove all existing textures first path = xbmc.translatePath('special://thumbnails/').decode('utf-8') if xbmcvfs.exists(path): allDirs, allFiles = xbmcvfs.listdir(path) for dir in allDirs: allDirs, allFiles = xbmcvfs.listdir(path + dir) for file in allFiles: if os.path.supports_unicode_filenames: path = os.path.join(path + dir.decode('utf-8'), file.decode('utf-8')) xbmcvfs.delete(path) else: xbmcvfs.delete( os.path.join(path.encode('utf-8') + dir, file)) # remove all existing data from texture DB connection = kodiSQL('texture') cursor = connection.cursor() cursor.execute( 'SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tableName = row[0] if tableName != "version": cursor.execute("DELETE FROM " + tableName) connection.commit() cursor.close() # Cache all entries in video DB connection = kodiSQL('video') cursor = connection.cursor() cursor.execute("SELECT url FROM art WHERE media_type != 'actor'" ) # dont include actors result = cursor.fetchall() total = len(result) log("Image cache sync about to process %s images" % total, 1) cursor.close() count = 0 for url in result: if pdialog.iscanceled(): break percentage = int((float(count) / float(total)) * 100) message = "%s of %s (%s)" % (count, total, self.imageCacheThreads) pdialog.update(percentage, "%s %s" % (lang(33045), message)) self.cacheTexture(url[0]) count += 1 # Cache all entries in music DB connection = kodiSQL('music') cursor = connection.cursor() cursor.execute("SELECT url FROM art") result = cursor.fetchall() total = len(result) log("Image cache sync about to process %s images" % total, 1) cursor.close() count = 0 for url in result: if pdialog.iscanceled(): break percentage = int((float(count) / float(total)) * 100) message = "%s of %s" % (count, total) pdialog.update(percentage, "%s %s" % (lang(33045), message)) self.cacheTexture(url[0]) count += 1 pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads))) log("Waiting for all threads to exit", 1) while len(self.imageCacheThreads): for thread in self.imageCacheThreads: if thread.isFinished: self.imageCacheThreads.remove(thread) pdialog.update( 100, "%s %s" % (lang(33046), len(self.imageCacheThreads))) log( "Waiting for all threads to exit: %s" % len(self.imageCacheThreads), 1) xbmc.sleep(500) pdialog.close()
def __enter__(self): self.plexconn = kodiSQL('plex') return Plex_DB_Functions(self.plexconn.cursor())
if __name__ == '__main__': itemid = xbmc.getInfoLabel("ListItem.DBID").decode("utf-8") itemtype = xbmc.getInfoLabel("ListItem.DBTYPE").decode("utf-8") emby = embyserver.Read_EmbyServer() embyid = "" if not itemtype and xbmc.getCondVisibility("Container.Content(albums)"): itemtype = "album" if not itemtype and xbmc.getCondVisibility("Container.Content(artists)"): itemtype = "artist" if not itemtype and xbmc.getCondVisibility("Container.Content(songs)"): itemtype = "song" if not itemtype and xbmc.getCondVisibility("Container.Content(pictures)"): itemtype = "picture" if (not itemid or itemid == "-1") and xbmc.getInfoLabel("ListItem.Property(embyid)"): embyid = xbmc.getInfoLabel("ListItem.Property(embyid)") else: embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) item = emby_db.getItem_byKodiId(itemid, itemtype) embycursor.close() if item: embyid = item[0] logMsg("Contextmenu opened for embyid: %s - itemtype: %s" %(embyid,itemtype)) if embyid: item = emby.getItem(embyid) API = api.API(item) userdata = API.getUserData() likes = userdata['Likes'] favourite = userdata['Favorite']
def __enter__(self): self.kodiconn = kodiSQL(self.itemType) self.emby_db = Kodidb_Functions(self.kodiconn.cursor()) return self.emby_db
def onNotification(self, sender, method, data): doUtils = self.doUtils if method not in ("Playlist.OnAdd"): log("Method: %s Data: %s" % (method, data), 1) if data: data = json.loads(data,'utf-8') if method == "Player.OnPlay": # Set up report progress for emby playback item = data.get('item') try: kodiid = item['id'] item_type = item['type'] except (KeyError, TypeError): log("Item is invalid for playstate update.", 1) else: if ((settings('useDirectPaths') == "1" and not item_type == "song") or (item_type == "song" and settings('enableMusic') == "true")): # Set up properties for player embyconn = kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type) try: itemid = emby_dbitem[0] except TypeError: log("No kodiId returned.", 1) else: url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % itemid result = doUtils.downloadUrl(url) log("Item: %s" % result, 2) playurl = None count = 0 while not playurl and count < 2: try: playurl = xbmc.Player().getPlayingFile() except RuntimeError: count += 1 xbmc.sleep(200) else: listItem = xbmcgui.ListItem() playback = pbutils.PlaybackUtils(result) if item_type == "song" and settings('streamMusic') == "true": window('emby_%s.playmethod' % playurl, value="DirectStream") else: window('emby_%s.playmethod' % playurl, value="DirectPlay") # Set properties for player.py playback.setProperties(playurl, listItem) finally: embycursor.close() elif method == "VideoLibrary.OnUpdate": # Manually marking as watched/unwatched playcount = data.get('playcount') item = data.get('item') try: kodiid = item['id'] item_type = item['type'] except (KeyError, TypeError): log("Item is invalid for playstate update.", 1) else: # Send notification to the server. embyconn = kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type) try: itemid = emby_dbitem[0] except TypeError: log("Could not find itemid in emby database.", 1) else: # Stop from manually marking as watched unwatched, with actual playback. if window('emby_skipWatched%s' % itemid) == "true": # property is set in player.py window('emby_skipWatched%s' % itemid, clear=True) else: # notify the server url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % itemid if playcount != 0: doUtils.downloadUrl(url, action_type="POST") log("Mark as watched for itemid: %s" % itemid, 1) else: doUtils.downloadUrl(url, action_type="DELETE") log("Mark as unwatched for itemid: %s" % itemid, 1) finally: embycursor.close() elif method == "VideoLibrary.OnRemove": # Removed function, because with plugin paths + clean library, it will wipe # entire library if user has permissions. Instead, use the emby context menu available # in Isengard and higher version pass '''try: kodiid = data['id'] type = data['type'] except (KeyError, TypeError): log("Item is invalid for emby deletion.", 1) else: # Send the delete action to the server. embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) emby_dbitem = emby_db.getItem_byKodiId(kodiid, type) try: itemid = emby_dbitem[0] except TypeError: log("Could not find itemid in emby database.", 1) else: if utils.settings('skipContextMenu') != "true": resp = xbmcgui.Dialog().yesno( heading="Confirm delete", line1="Delete file on Emby Server?") if not resp: log("User skipped deletion.", 1) embycursor.close() return url = "{server}/emby/Items/%s?format=json" % itemid log("Deleting request: %s" % itemid) doUtils.downloadUrl(url, action_type="DELETE") finally: embycursor.close()''' elif method == "System.OnWake": # Allow network to wake up xbmc.sleep(10000) window('emby_onWake', value="true") elif method == "GUI.OnScreensaverDeactivated": if settings('dbSyncScreensaver') == "true": xbmc.sleep(5000); window('emby_onWake', value="true") elif method == "Playlist.OnClear": pass
def __enter__(self): self.embyconn = kodiSQL('emby') self.emby_db = Embydb_Functions(self.embyconn.cursor()) return self.emby_db
def onNotification(self, sender, method, data): doUtils = self.doUtils if method not in ("Playlist.OnAdd"): self.logMsg("Method: %s Data: %s" % (method, data), 1) if data: data = json.loads(data) if method == "Player.OnPlay": # Set up report progress for emby playback item = data.get('item') try: kodiid = item['id'] type = item['type'] except (KeyError, TypeError): self.logMsg("Properties already set for item.", 1) else: if ((utils.settings('useDirectPaths') == "1" and not type == "song") or (type == "song" and utils.settings('disableMusic') == "false")): # Set up properties for player embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) emby_dbitem = emby_db.getItem_byKodiId(kodiid, type) try: itemid = emby_dbitem[0] except TypeError: self.logMsg("No kodiid returned.", 1) else: url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % itemid result = doUtils.downloadUrl(url) self.logMsg("Item: %s" % result, 2) playurl = None count = 0 while not playurl and count < 2: try: playurl = xbmc.Player().getPlayingFile() except RuntimeError: count += 1 xbmc.sleep(200) else: listItem = xbmcgui.ListItem() playback = pbutils.PlaybackUtils(result) if type == "song" and utils.settings('streamMusic') == "true": utils.window('emby_%s.playmethod' % playurl, value="DirectStream") else: utils.window('emby_%s.playmethod' % playurl, value="DirectPlay") # Set properties for player.py playback.setProperties(playurl, listItem) finally: embycursor.close() elif method == "VideoLibrary.OnUpdate": # Manually marking as watched/unwatched playcount = data.get('playcount') item = data.get('item') try: kodiid = item['id'] type = item['type'] except (KeyError, TypeError): self.logMsg("Item is invalid for playstate update.", 1) else: # Send notification to the server. embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) emby_dbitem = emby_db.getItem_byKodiId(kodiid, type) try: itemid = emby_dbitem[0] except TypeError: self.logMsg("Could not find itemid in emby database.", 1) else: # Stop from manually marking as watched unwatched, with actual playback. if utils.window('emby_skipWatched%s' % itemid) == "true": # property is set in player.py utils.window('emby_skipWatched%s' % itemid, clear=True) else: # notify the server url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % itemid if playcount != 0: doUtils.downloadUrl(url, type="POST") self.logMsg("Mark as watched for itemid: %s" % itemid, 1) else: doUtils.downloadUrl(url, type="DELETE") self.logMsg("Mark as unwatched for itemid: %s" % itemid, 1) finally: embycursor.close() elif method == "VideoLibrary.OnRemove": try: kodiid = data['id'] type = data['type'] except (KeyError, TypeError): self.logMsg("Item is invalid for emby deletion.", 1) else: # Send the delete action to the server. offerDelete = False if type == "episode" and utils.settings('deleteTV') == "true": offerDelete = True elif type == "movie" and utils.settings('deleteMovies') == "true": offerDelete = True if utils.settings('offerDelete') != "true": # Delete could be disabled, even if the subsetting is enabled. offerDelete = False if offerDelete: embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) emby_dbitem = emby_db.getItem_byKodiId(kodiid, type) try: itemid = emby_dbitem[0] except TypeError: self.logMsg("Could not find itemid in emby database.", 1) else: if utils.settings('skipConfirmDelete') != "true": resp = xbmcgui.Dialog().yesno( heading="Confirm delete", line1="Delete file on Emby Server?") if not resp: self.logMsg("User skipped deletion.", 1) embycursor.close() return url = "{server}/emby/Items/%s?format=json" % itemid self.logMsg("Deleting request: %s" % itemid) doUtils.downloadUrl(url, type="DELETE") finally: embycursor.close() elif method == "System.OnWake": # Allow network to wake up xbmc.sleep(10000) utils.window('emby_onWake', value="true") elif method == "Playlist.OnClear": utils.window('emby_customPlaylist', clear=True, windowid=10101) #xbmcgui.Window(10101).clearProperties() self.logMsg("Clear playlist properties.")
itemType = "album" elif xbmc.getCondVisibility("Container.Content(artists)"): itemType = "artist" elif xbmc.getCondVisibility("Container.Content(songs)"): itemType = "song" elif xbmc.getCondVisibility("Container.Content(pictures)"): itemType = "picture" else: log("ItemType is unknown.") if (not kodiId or kodiId == "-1") and xbmc.getInfoLabel("ListItem.Property(embyid)"): itemId = xbmc.getInfoLabel("ListItem.Property(embyid)") elif kodiId and itemType: embyconn = kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) item = emby_db.getItem_byKodiId(kodiId, itemType) embycursor.close() try: itemId = item[0] except TypeError: pass log("Found ItemId: %s ItemType: %s" % (itemId, itemType), 1) if itemId: dialog = xbmcgui.Dialog() emby = embyserver.Read_EmbyServer()
def fullTextureCacheSync(self): """ This method will sync all Kodi artwork to textures13.db and cache them locally. This takes diskspace! """ if not dialog('yesno', "Image Texture Cache", lang(39250)): return log.info("Doing Image Cache Sync") # ask to rest all existing or not if dialog('yesno', "Image Texture Cache", lang(39251)): log.info("Resetting all cache data first") # Remove all existing textures first path = tryDecode(translatePath("special://thumbnails/")) if IfExists(path): allDirs, allFiles = listdir(path) for dir in allDirs: allDirs, allFiles = listdir(path+dir) for file in allFiles: if os_path.supports_unicode_filenames: delete(os_path.join( path + tryDecode(dir), tryDecode(file))) else: delete(os_path.join( tryEncode(path) + dir, file)) # remove all existing data from texture DB connection = kodiSQL('texture') cursor = connection.cursor() cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tableName = row[0] if tableName != "version": cursor.execute("DELETE FROM " + tableName) connection.commit() connection.close() # Cache all entries in video DB connection = kodiSQL('video') cursor = connection.cursor() # dont include actors cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") result = cursor.fetchall() total = len(result) log.info("Image cache sync about to process %s video images" % total) connection.close() for url in result: self.cacheTexture(url[0]) # Cache all entries in music DB connection = kodiSQL('music') cursor = connection.cursor() cursor.execute("SELECT url FROM art") result = cursor.fetchall() total = len(result) log.info("Image cache sync about to process %s music images" % total) connection.close() for url in result: self.cacheTexture(url[0])
def fullTextureCacheSync(self): # This method will sync all Kodi artwork to textures13.db # and cache them locally. This takes diskspace! dialog = xbmcgui.Dialog() if not dialog.yesno( heading=lang(29999), line1=lang(33042)): return log("Doing Image Cache Sync", 1) pdialog = xbmcgui.DialogProgress() pdialog.create(lang(29999), lang(33043)) # ask to rest all existing or not if dialog.yesno(lang(29999), lang(33044)): log("Resetting all cache data first.", 1) # Remove all existing textures first path = xbmc.translatePath('special://thumbnails/').decode('utf-8') if xbmcvfs.exists(path): allDirs, allFiles = xbmcvfs.listdir(path) for dir in allDirs: allDirs, allFiles = xbmcvfs.listdir(path+dir) for file in allFiles: if os.path.supports_unicode_filenames: path = os.path.join(path+dir.decode('utf-8'),file.decode('utf-8')) xbmcvfs.delete(path) else: xbmcvfs.delete(os.path.join(path.encode('utf-8')+dir,file)) # remove all existing data from texture DB connection = kodiSQL('texture') cursor = connection.cursor() cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tableName = row[0] if tableName != "version": cursor.execute("DELETE FROM " + tableName) connection.commit() cursor.close() # Cache all entries in video DB connection = kodiSQL('video') cursor = connection.cursor() cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") # dont include actors result = cursor.fetchall() total = len(result) log("Image cache sync about to process %s images" % total, 1) cursor.close() count = 0 for url in result: if pdialog.iscanceled(): break percentage = int((float(count) / float(total))*100) message = "%s of %s (%s)" % (count, total, self.imageCacheThreads) pdialog.update(percentage, "%s %s" % (lang(33045), message)) self.cacheTexture(url[0]) count += 1 # Cache all entries in music DB connection = kodiSQL('music') cursor = connection.cursor() cursor.execute("SELECT url FROM art") result = cursor.fetchall() total = len(result) log("Image cache sync about to process %s images" % total, 1) cursor.close() count = 0 for url in result: if pdialog.iscanceled(): break percentage = int((float(count) / float(total))*100) message = "%s of %s" % (count, total) pdialog.update(percentage, "%s %s" % (lang(33045), message)) self.cacheTexture(url[0]) count += 1 pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads))) log("Waiting for all threads to exit", 1) while len(self.imageCacheThreads): for thread in self.imageCacheThreads: if thread.isFinished: self.imageCacheThreads.remove(thread) pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads))) log("Waiting for all threads to exit: %s" % len(self.imageCacheThreads), 1) xbmc.sleep(500) pdialog.close()
def fullSync(self, manualrun=False, repair=False): # Only run once when first setting up. Can be run manually. emby = self.emby music_enabled = utils.settings('enableMusic') == "true" utils.window('emby_dbScan', value="true") # Add sources utils.sourcesXML() embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() # Create the tables for the emby database # emby, view, version embycursor.execute( """CREATE TABLE IF NOT EXISTS emby( emby_id TEXT UNIQUE, media_folder TEXT, emby_type TEXT, media_type TEXT, kodi_id INTEGER, kodi_fileid INTEGER, kodi_pathid INTEGER, parent_id INTEGER, checksum INTEGER)""") embycursor.execute( """CREATE TABLE IF NOT EXISTS view( view_id TEXT UNIQUE, view_name TEXT, media_type TEXT, kodi_tagid INTEGER)""") embycursor.execute("CREATE TABLE IF NOT EXISTS version(idVersion TEXT)") embyconn.commit() # content sync: movies, tvshows, musicvideos, music kodiconn = utils.kodiSQL('video') kodicursor = kodiconn.cursor() if manualrun: message = "Manual sync" elif repair: message = "Repair sync" else: message = "Initial sync" pDialog = self.progressDialog("%s" % message, forced=True) starttotal = datetime.now() # Set views self.maintainViews(embycursor, kodicursor) embyconn.commit() # Sync video library process = { 'movies': self.movies, 'musicvideos': self.musicvideos, 'tvshows': self.tvshows, 'homevideos': self.homevideos } for itemtype in process: startTime = datetime.now() completed = process[itemtype](embycursor, kodicursor, pDialog, compare=manualrun) if not completed: utils.window('emby_dbScan', clear=True) if pDialog: pDialog.close() embycursor.close() kodicursor.close() return False else: self.dbCommit(kodiconn) embyconn.commit() elapsedTime = datetime.now() - startTime self.logMsg( "SyncDatabase (finished %s in: %s)" % (itemtype, str(elapsedTime).split('.')[0]), 1) # sync music if music_enabled: musicconn = utils.kodiSQL('music') musiccursor = musicconn.cursor() startTime = datetime.now() completed = self.music(embycursor, musiccursor, pDialog, compare=manualrun) if not completed: utils.window('emby_dbScan', clear=True) if pDialog: pDialog.close() embycursor.close() musiccursor.close() return False else: musicconn.commit() embyconn.commit() elapsedTime = datetime.now() - startTime self.logMsg( "SyncDatabase (finished music in: %s)" % (str(elapsedTime).split('.')[0]), 1) musiccursor.close() if pDialog: pDialog.close() embycursor.close() kodicursor.close() utils.settings('SyncInstallRunDone', value="true") utils.settings("dbCreatedWithVersion", self.clientInfo.getVersion()) self.saveLastSync() # tell any widgets to refresh because the content has changed utils.window('widgetreload', value=datetime.now().strftime('%Y-%m-%d %H:%M:%S')) xbmc.executebuiltin('UpdateLibrary(video)') elapsedtotal = datetime.now() - starttotal utils.window('emby_dbScan', clear=True) xbmcgui.Dialog().notification( heading="Emby for Kodi", message="%s completed in: %s!" % (message, str(elapsedtotal).split('.')[0]), icon="special://home/addons/plugin.video.emby/icon.png", sound=False) return True
def incrementalSync(self): embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() kodiconn = utils.kodiSQL('video') kodicursor = kodiconn.cursor() emby = self.emby emby_db = embydb.Embydb_Functions(embycursor) pDialog = None if self.refresh_views: # Received userconfig update self.refresh_views = False self.maintainViews(embycursor, kodicursor) self.forceLibraryUpdate = True if self.addedItems or self.updateItems or self.userdataItems or self.removeItems: # Only present dialog if we are going to process items pDialog = self.progressDialog('Incremental sync') process = { 'added': self.addedItems, 'update': self.updateItems, 'userdata': self.userdataItems, 'remove': self.removeItems } types = ['added', 'update', 'userdata', 'remove'] for type in types: if process[type] and utils.window('emby_kodiScan') != "true": listItems = list(process[type]) del process[type][:] # Reset class list items_process = itemtypes.Items(embycursor, kodicursor) update = False # Prepare items according to process type if type == "added": items = emby.sortby_mediatype(listItems) elif type in ("userdata", "remove"): items = emby_db.sortby_mediaType(listItems, unsorted=False) else: items = emby_db.sortby_mediaType(listItems) if items.get('Unsorted'): sorted_items = emby.sortby_mediatype(items['Unsorted']) doupdate = items_process.itemsbyId(sorted_items, "added", pDialog) if doupdate: update = True del items['Unsorted'] doupdate = items_process.itemsbyId(items, type, pDialog) if doupdate: update = True if update: self.forceLibraryUpdate = True if self.forceLibraryUpdate: # Force update the Kodi library self.forceLibraryUpdate = False self.dbCommit(kodiconn) embyconn.commit() self.saveLastSync() # tell any widgets to refresh because the content has changed utils.window('widgetreload', value=datetime.now().strftime('%Y-%m-%d %H:%M:%S')) self.logMsg("Updating video library.", 1) utils.window('emby_kodiScan', value="true") xbmc.executebuiltin('UpdateLibrary(video)') if pDialog: pDialog.close() kodicursor.close() embycursor.close()
def getThemeMedia(): doUtils = downloadutils.DownloadUtils() dialog = xbmcgui.Dialog() playback = None # Choose playback method resp = dialog.select("Playback method for your themes", ["Direct Play", "Direct Stream"]) if resp == 0: playback = "DirectPlay" elif resp == 1: playback = "DirectStream" else: return library = xbmc.translatePath( "special://profile/addon_data/plugin.video.emby/library/").decode('utf-8') # Create library directory if not xbmcvfs.exists(library): xbmcvfs.mkdir(library) # Set custom path for user tvtunes_path = xbmc.translatePath( "special://profile/addon_data/script.tvtunes/").decode('utf-8') if xbmcvfs.exists(tvtunes_path): tvtunes = xbmcaddon.Addon(id="script.tvtunes") tvtunes.setSetting('custom_path_enable', "true") tvtunes.setSetting('custom_path', library) utils.logMsg("EMBY", "TV Tunes custom path is enabled and set.", 1) else: # if it does not exist this will not work so warn user # often they need to edit the settings first for it to be created. dialog.ok( heading="Warning", line1=( "The settings file does not exist in tvtunes. ", "Go to the tvtunes addon and change a setting, then come back and re-run.")) xbmc.executebuiltin('Addon.OpenSettings(script.tvtunes)') return # Get every user view Id embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) viewids = emby_db.getViews() embycursor.close() # Get Ids with Theme Videos itemIds = {} for view in viewids: url = "{server}/emby/Users/{UserId}/Items?HasThemeVideo=True&ParentId=%s&format=json" % view result = doUtils.downloadUrl(url) if result['TotalRecordCount'] != 0: for item in result['Items']: itemId = item['Id'] folderName = item['Name'] folderName = utils.normalize_string(folderName.encode('utf-8')) itemIds[itemId] = folderName # Get paths for theme videos for itemId in itemIds: nfo_path = xbmc.translatePath( "special://profile/addon_data/plugin.video.emby/library/%s/" % itemIds[itemId]) # Create folders for each content if not xbmcvfs.exists(nfo_path): xbmcvfs.mkdir(nfo_path) # Where to put the nfos nfo_path = "%s%s" % (nfo_path, "tvtunes.nfo") url = "{server}/emby/Items/%s/ThemeVideos?format=json" % itemId result = doUtils.downloadUrl(url) # Create nfo and write themes to it nfo_file = xbmcvfs.File(nfo_path, 'w') pathstowrite = "" # May be more than one theme for theme in result['Items']: putils = playutils.PlayUtils(theme) if playback == "DirectPlay": playurl = putils.directPlay() else: playurl = putils.directStream() pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8')) # Check if the item has theme songs and add them url = "{server}/emby/Items/%s/ThemeSongs?format=json" % itemId result = doUtils.downloadUrl(url) # May be more than one theme for theme in result['Items']: putils = playutils.PlayUtils(theme) if playback == "DirectPlay": playurl = putils.directPlay() else: playurl = putils.directStream() pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8')) nfo_file.write( '<tvtunes>%s</tvtunes>' % pathstowrite ) # Close nfo file nfo_file.close() # Get Ids with Theme songs musicitemIds = {} for view in viewids: url = "{server}/emby/Users/{UserId}/Items?HasThemeSong=True&ParentId=%s&format=json" % view result = doUtils.downloadUrl(url) if result['TotalRecordCount'] != 0: for item in result['Items']: itemId = item['Id'] folderName = item['Name'] folderName = utils.normalize_string(folderName.encode('utf-8')) musicitemIds[itemId] = folderName # Get paths for itemId in musicitemIds: # if the item was already processed with video themes back out if itemId in itemIds: continue nfo_path = xbmc.translatePath( "special://profile/addon_data/plugin.video.emby/library/%s/" % musicitemIds[itemId]) # Create folders for each content if not xbmcvfs.exists(nfo_path): xbmcvfs.mkdir(nfo_path) # Where to put the nfos nfo_path = "%s%s" % (nfo_path, "tvtunes.nfo") url = "{server}/emby/Items/%s/ThemeSongs?format=json" % itemId result = doUtils.downloadUrl(url) # Create nfo and write themes to it nfo_file = xbmcvfs.File(nfo_path, 'w') pathstowrite = "" # May be more than one theme for theme in result['Items']: putils = playutils.PlayUtils(theme) if playback == "DirectPlay": playurl = putils.directPlay() else: playurl = putils.directStream() pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8')) nfo_file.write( '<tvtunes>%s</tvtunes>' % pathstowrite ) # Close nfo file nfo_file.close() dialog.notification( heading="Emby for Kodi", message="Themes added!", icon="special://home/addons/plugin.video.emby/icon.png", time=1000, sound=False)
#display select dialog and process results header = utils.language(30401) ret = xbmcgui.Dialog().select(header, options) if ret != -1: if options[ret] == utils.language(30402): emby.updateUserRating(plexid, deletelike=True) if options[ret] == utils.language(30403): emby.updateUserRating(plexid, like=True) if options[ret] == utils.language(30404): emby.updateUserRating(plexid, like=False) if options[ret] == utils.language(30405): emby.updateUserRating(plexid, favourite=True) if options[ret] == utils.language(30406): emby.updateUserRating(plexid, favourite=False) if options[ret] == utils.language(30407): kodiconn = utils.kodiSQL('music') kodicursor = kodiconn.cursor() query = ' '.join(("SELECT rating", "FROM song", "WHERE idSong = ?" )) kodicursor.execute(query, (itemid,)) currentvalue = int(round(float(kodicursor.fetchone()[0]),0)) newvalue = xbmcgui.Dialog().numeric(0, "Set custom song rating (0-5)", str(currentvalue)) if newvalue: newvalue = int(newvalue) if newvalue > 5: newvalue = "5" if utils.settings('enableUpdateSongRating') == "true": musicutils.updateRatingToFile(newvalue, API.getFilePath()) if utils.settings('enableExportSongRating') == "true": like, favourite, deletelike = musicutils.getEmbyRatingFromKodiRating(newvalue) emby.updateUserRating(plexid, like, favourite, deletelike) query = ' '.join(( "UPDATE song","SET rating = ?", "WHERE idSong = ?" )) kodicursor.execute(query, (newvalue,itemid,))
def incrementalSync(self): embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() kodiconn = utils.kodiSQL('video') kodicursor = kodiconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) pDialog = None update_embydb = False if self.refresh_views: # Received userconfig update self.refresh_views = False self.maintainViews(embycursor, kodicursor) self.forceLibraryUpdate = True update_embydb = True incSyncIndicator = int(settings('incSyncIndicator') or 10) totalUpdates = len(self.addedItems) + len(self.updateItems) + len( self.userdataItems) + len(self.removeItems) if incSyncIndicator != -1 and totalUpdates > incSyncIndicator: # Only present dialog if we are going to process items pDialog = self.progressDialog('Incremental sync') log.info("incSyncIndicator=" + str(incSyncIndicator) + " totalUpdates=" + str(totalUpdates)) process = { 'added': self.addedItems, 'update': self.updateItems, 'userdata': self.userdataItems, 'remove': self.removeItems } for process_type in ['added', 'update', 'userdata', 'remove']: if process[process_type] and window('emby_kodiScan') != "true": listItems = list(process[process_type]) del process[process_type][:] # Reset class list items_process = itemtypes.Items(embycursor, kodicursor) update = False # Prepare items according to process process_type if process_type == "added": items = self.emby.sortby_mediatype(listItems) elif process_type in ("userdata", "remove"): items = emby_db.sortby_mediaType(listItems, unsorted=False) else: items = emby_db.sortby_mediaType(listItems) if items.get('Unsorted'): sorted_items = self.emby.sortby_mediatype( items['Unsorted']) doupdate = items_process.itemsbyId( sorted_items, "added", pDialog) if doupdate: embyupdate, kodiupdate_video = doupdate if embyupdate: update_embydb = True if kodiupdate_video: self.forceLibraryUpdate = True del items['Unsorted'] doupdate = items_process.itemsbyId(items, process_type, pDialog) if doupdate: embyupdate, kodiupdate_video = doupdate if embyupdate: update_embydb = True if kodiupdate_video: self.forceLibraryUpdate = True if update_embydb: update_embydb = False log.info("Updating emby database.") embyconn.commit() self.saveLastSync() if self.forceLibraryUpdate: # Force update the Kodi library self.forceLibraryUpdate = False self.dbCommit(kodiconn) log.info("Updating video library.") window('emby_kodiScan', value="true") xbmc.executebuiltin('UpdateLibrary(video)') if pDialog: pDialog.close() kodicursor.close() embycursor.close()
if xbmc.getCondVisibility("Container.Content(albums)"): itemType = "album" elif xbmc.getCondVisibility("Container.Content(artists)"): itemType = "artist" elif xbmc.getCondVisibility("Container.Content(songs)"): itemType = "song" elif xbmc.getCondVisibility("Container.Content(pictures)"): itemType = "picture" else: log.info("ItemType is unknown.") if (not kodiId or kodiId == "-1") and xbmc.getInfoLabel("ListItem.Property(embyid)"): itemId = xbmc.getInfoLabel("ListItem.Property(embyid)") elif kodiId and itemType: embyconn = kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) item = emby_db.getItem_byKodiId(kodiId, itemType) embycursor.close() try: itemId = item[0] except TypeError: pass log.info("Found ItemId: %s ItemType: %s" % (itemId, itemType)) if itemId: dialog = xbmcgui.Dialog()
def fullSync(self, manualrun=False, repair=False): # Only run once when first setting up. Can be run manually. music_enabled = settings('enableMusic') == "true" xbmc.executebuiltin('InhibitIdleShutdown(true)') screensaver = utils.getScreensaver() utils.setScreensaver(value="") window('emby_dbScan', value="true") # Add sources utils.sourcesXML() embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() # content sync: movies, tvshows, musicvideos, music kodiconn = utils.kodiSQL('video') kodicursor = kodiconn.cursor() if manualrun: message = "Manual sync" elif repair: message = "Repair sync" repair_list = [] choices = ['all', 'movies', 'musicvideos', 'tvshows'] if music_enabled: choices.append('music') if self.kodi_version > 15: # Jarvis or higher types = xbmcgui.Dialog().multiselect(lang(33094), choices) if types is None: pass elif 0 in types: # all choices.pop(0) repair_list.extend(choices) else: for index in types: repair_list.append(choices[index]) else: resp = xbmcgui.Dialog().select(lang(33094), choices) if resp == 0: # all choices.pop(resp) repair_list.extend(choices) else: repair_list.append(choices[resp]) log.info("Repair queued for: %s", repair_list) else: message = "Initial sync" window('emby_initialScan', value="true") pDialog = self.progressDialog("%s" % message) starttotal = datetime.now() # Set views self.maintainViews(embycursor, kodicursor) embyconn.commit() # Sync video library process = { 'movies': self.movies, 'musicvideos': self.musicvideos, 'tvshows': self.tvshows } for itemtype in process: if repair and itemtype not in repair_list: continue startTime = datetime.now() completed = process[itemtype](embycursor, kodicursor, pDialog) if not completed: xbmc.executebuiltin('InhibitIdleShutdown(false)') utils.setScreensaver(value=screensaver) window('emby_dbScan', clear=True) if pDialog: pDialog.close() embycursor.close() kodicursor.close() return False else: self.dbCommit(kodiconn) embyconn.commit() elapsedTime = datetime.now() - startTime log.info("SyncDatabase (finished %s in: %s)" % (itemtype, str(elapsedTime).split('.')[0])) else: # Close the Kodi cursor kodicursor.close() # sync music if music_enabled: if repair and 'music' not in repair_list: pass else: musicconn = utils.kodiSQL('music') musiccursor = musicconn.cursor() startTime = datetime.now() completed = self.music(embycursor, musiccursor, pDialog) if not completed: xbmc.executebuiltin('InhibitIdleShutdown(false)') utils.setScreensaver(value=screensaver) window('emby_dbScan', clear=True) if pDialog: pDialog.close() embycursor.close() musiccursor.close() return False else: musicconn.commit() embyconn.commit() elapsedTime = datetime.now() - startTime log.info("SyncDatabase (finished music in: %s)" % (str(elapsedTime).split('.')[0])) musiccursor.close() if pDialog: pDialog.close() emby_db = embydb.Embydb_Functions(embycursor) current_version = emby_db.get_version(self.clientInfo.get_version()) window('emby_version', current_version) embyconn.commit() embycursor.close() settings('SyncInstallRunDone', value="true") self.saveLastSync() xbmc.executebuiltin('UpdateLibrary(video)') elapsedtotal = datetime.now() - starttotal xbmc.executebuiltin('InhibitIdleShutdown(false)') utils.setScreensaver(value=screensaver) window('emby_dbScan', clear=True) window('emby_initialScan', clear=True) xbmcgui.Dialog().notification( heading=lang(29999), message="%s %s %s" % (message, lang(33025), str(elapsedtotal).split('.')[0]), icon="special://home/addons/plugin.video.emby/icon.png", sound=False) return True
def itemsbyId(self, items, process, pdialog=None): # Process items by itemid. Process can be added, update, userdata, remove embycursor = self.embycursor kodicursor = self.kodicursor itemtypes = { 'Movie': Movies, 'BoxSet': Movies, 'MusicVideo': MusicVideos, 'Series': TVShows, 'Season': TVShows, 'Episode': TVShows, 'MusicAlbum': Music, 'MusicArtist': Music, 'AlbumArtist': Music, 'Audio': Music } update_videolibrary = False total = 0 for item in items: total += len(items[item]) if total == 0: return False #log.info("Processing %s: %s", process, items) if pdialog: pdialog.update(heading="Processing %s: %s items" % (process, total)) for itemtype in items: # Safety check if not itemtypes.get(itemtype): # We don't process this type of item continue itemlist = items[itemtype] if not itemlist: # The list to process is empty continue musicconn = None if itemtype in ('MusicAlbum', 'MusicArtist', 'AlbumArtist', 'Audio'): if self.music_enabled: musicconn = kodiSQL('music') musiccursor = musicconn.cursor() items_process = itemtypes[itemtype](embycursor, musiccursor, pdialog) else: # Music is not enabled, do not proceed with itemtype continue else: update_videolibrary = True items_process = itemtypes[itemtype](embycursor, kodicursor, pdialog) if process == "added": items_process.add_all(itemtype, itemlist) elif process == "remove": items_process.remove_all(itemtype, itemlist) else: process_items = self.emby.getFullItems(itemlist) items_process.process_all(itemtype, process, process_items, total) if musicconn is not None: # close connection for special types log.info("updating music database") musicconn.commit() musiccursor.close() return (True, update_videolibrary)