Example #1
0
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]
Example #4
0
    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()
Example #5
0
    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()
Example #6
0
    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
Example #7
0
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")
Example #8
0
    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()
Example #9
0
    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()
Example #10
0
    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()
Example #11
0
 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()
Example #12
0
    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 ---===###")
Example #13
0
    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()
Example #14
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 __enter__(self):
     self.plexconn = kodiSQL('plex')
     return Plex_DB_Functions(self.plexconn.cursor())
Example #16
0
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
Example #18
0
    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
Example #19
0
 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.")
Example #21
0
            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()
Example #22
0
    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])
Example #23
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()
Example #26
0
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)
Example #27
0
 #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,))
Example #28
0
    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()
Example #30
0
    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
Example #31
0
 def __enter__(self):
     self.embyconn = kodiSQL('emby')
     self.emby_db = Embydb_Functions(self.embyconn.cursor())
     return self.emby_db
Example #32
0
 def __enter__(self):
     self.kodiconn = kodiSQL(self.itemType)
     self.emby_db = Kodidb_Functions(self.kodiconn.cursor())
     return self.emby_db
Example #33
0
    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)