예제 #1
0
    def movies(self, embycursor, kodicursor, pdialog):

        # Get movies from emby
        emby_db = embydb.Embydb_Functions(embycursor)
        movies = Movies(embycursor, kodicursor, pdialog)

        views = emby_db.getView_byType('movies')
        views += emby_db.getView_byType('mixed')
        log.info("Media folders: %s" % views)

        ##### PROCESS MOVIES #####
        for view in views:

            log.info("Processing: %s", view)
            view_name = view['name']

            # Get items per view
            if pdialog:
                pdialog.update(heading=lang(29999),
                               message="%s %s..." % (lang(33017), view_name))

            all_movies = self.emby.getMovies(view['id'], dialog=pdialog)
            movies.add_all("Movie", all_movies, view)

        log.debug("Movies finished.")

        ##### PROCESS BOXSETS #####
        if pdialog:
            pdialog.update(heading=lang(29999), message=lang(33018))

        boxsets = self.emby.getBoxset(dialog=pdialog)
        movies.add_all("BoxSet", boxsets)
        log.debug("Boxsets finished.")

        return True
예제 #2
0
    def modify_playlist(self, item_ids):

        conn = kodiSQL('emby')
        cursor = conn.cursor()
        emby_db = embydb.Embydb_Functions(cursor)

        log.info("---*** ADD TO PLAYLIST ***---")
        log.info("Items: %s", item_ids)

        playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)

        for item_id in item_ids:

            log.info("Adding %s to playlist", item_id)
            item = emby_db.getItem_byId(item_id)
            try:
                db_id = item[0]
                media_type = item[4]

            except TypeError:
                # Item is not found in our database, add item manually
                item = self.emby.getItem(item_id)
                self.add_to_xbmc_playlist(playlist, item)

            else:  # Add to playlist
                self.add_to_playlist(db_id, media_type)

        self.verify_playlist()
        cursor.close()
        return playlist
예제 #3
0
    def modifyPlaylist(self, itemids):

        log = self.logMsg

        embyconn = utils.kodiSQL('emby')
        embycursor = embyconn.cursor()
        emby_db = embydb.Embydb_Functions(embycursor)

        log("---*** ADD TO PLAYLIST ***---", 1)
        log("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)

            log("Adding %s to playlist." % itemid, 1)

        self.verifyPlaylist()
        embycursor.close()
        return playlist
예제 #4
0
    def tvshows(self, embycursor, kodicursor, pdialog):

        # Get shows from emby
        emby_db = embydb.Embydb_Functions(embycursor)
        tvshows = TVShows(embycursor, kodicursor, pdialog)

        views = emby_db.getView_byType('tvshows')
        views += emby_db.getView_byType('mixed')
        log.info("Media folders: %s" % views)

        for view in views:

            # Get items per view
            if pdialog:
                pdialog.update(
                        heading=lang(29999),
                        message="%s %s..." % (lang(33020), view['name']))

            all_tvshows = self.emby.getShows(view['id'], dialog=pdialog)
            tvshows.add_all("Series", all_tvshows, view)

        else:
            log.debug("TVShows finished.")

        return True
예제 #5
0
    def musicvideos(self, embycursor, kodicursor, pdialog):

        # Get musicvideos from emby
        emby_db = embydb.Embydb_Functions(embycursor)
        mvideos = MusicVideos(embycursor, kodicursor, pdialog)

        views = emby_db.getView_byType('musicvideos')
        log.info("Media folders: %s" % views)

        for view in views:
            log.info("Processing: %s", view)

            # Get items per view
            viewId = view['id']
            viewName = view['name']

            if pdialog:
                pdialog.update(
                        heading=lang(29999),
                        message="%s %s..." % (lang(33019), viewName))

            # Initial or repair sync
            all_mvideos = self.emby.getMusicVideos(viewId, dialog=pdialog)
            mvideos.add_all("MusicVideo", all_mvideos, view)

        else:
            log.debug("MusicVideos finished.")

        return True
예제 #6
0
    def __init__(self, embycursor, kodicursor, pdialog=None):

        self.embycursor = embycursor
        self.emby_db = embydb.Embydb_Functions(self.embycursor)
        self.kodicursor = kodicursor
        self.kodi_db = _kodi_movies.KodiMovies(self.kodicursor)
        self.pdialog = pdialog

        self.new_time = int(settings('newvideotime')) * 1000

        Items.__init__(self)
예제 #7
0
    def _get_item_id(cls, kodi_id, item_type):

        item_id = None

        with DatabaseConn('emby') as cursor:
            emby_db = embydb.Embydb_Functions(cursor)
            db_item = emby_db.getItem_byKodiId(kodi_id, item_type)

        try:
            item_id = db_item[0]
        except TypeError:
            log.info("Could not retrieve item Id")

        return item_id
예제 #8
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))

        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
                    log(
                        "Item was not found in the database, manually adding item.",
                        1)
                    item = PlexFunctions.GetPlexMetadata(itemid)
                    if item is None or item == 401:
                        log('Could not download itemid %s' % itemid, -1)
                    else:
                        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()
예제 #9
0
    def __init__(self, emby_cursor, kodi_cursor):
        self.emby_cursor = emby_cursor
        self.kodi_cursor = kodi_cursor

        self.total_nodes = 0
        self.nodes = list()
        self.playlists = list()
        self.views = list()
        self.sorted_views = list()
        self.grouped_views = list()

        self.video_nodes = VideoNodes()
        self.playlist = Playlist()
        self.emby = embyserver.Read_EmbyServer()
        self.emby_db = embydb.Embydb_Functions(emby_cursor)
예제 #10
0
    def _get_item_id(cls, kodi_id, item_type):

        item_id = xbmc.getInfoLabel('ListItem.Property(embyid)')

        if not item_id and kodi_id and item_type:

            with DatabaseConn('emby') as cursor:
                emby_db = embydb.Embydb_Functions(cursor)
                item = emby_db.getItem_byKodiId(kodi_id, item_type)
                try:
                    item_id = item[0]
                except TypeError:
                    pass

        return item_id
예제 #11
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")
예제 #12
0
    def _get_item_id(cls, kodi_id, item_type):

        item_id = None

        conn = kodiSQL('emby')
        cursor = conn.cursor()
        emby_db = embydb.Embydb_Functions(cursor)
        db_item = emby_db.getItem_byKodiId(kodi_id, item_type)
        cursor.close()

        try:
            item_id = db_item[0]
        except TypeError:
            log.info("Could not retrieve item Id")

        return item_id
예제 #13
0
    def _get_item_id(cls, kodi_id, item_type):

        item_id = xbmc.getInfoLabel('ListItem.Property(embyid)')

        if not item_id and kodi_id and item_type:

            conn = kodiSQL('emby')
            cursor = conn.cursor()
            emby_db = embydb.Embydb_Functions(cursor)
            item = emby_db.getItem_byKodiId(kodi_id, item_type)
            cursor.close()
            try:
                item_id = item[0]
            except TypeError:
                pass

        return item_id
예제 #14
0
    def playAll(self, itemids, startat):

        embyconn = 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()
예제 #15
0
    def play_all(self, item_ids, start_at):

        conn = kodiSQL('emby')
        cursor = conn.cursor()
        emby_db = embydb.Embydb_Functions(cursor)

        player = xbmc.Player()
        playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
        playlist.clear()

        log.info("---*** PLAY ALL ***---")
        log.info("Items: %s and start at: %s", item_ids, start_at)

        started = False
        window('emby_customplaylist', value="true")

        if start_at:
            # Seek to the starting position
            window('emby_customplaylist.seektime', str(start_at))

        for item_id in item_ids:

            log.info("Adding %s to playlist", item_id)
            item = emby_db.getItem_byId(item_id)
            try:
                db_id = item[0]
                media_type = item[4]

            except TypeError:
                # Item is not found in our database, add item manually
                log.info(
                    "Item was not found in the database, manually adding item")
                item = self.emby.getItem(item_id)
                self.add_to_xbmc_playlist(playlist, item)

            else:  # Add to playlist
                self.add_to_playlist(db_id, media_type)

            if not started:
                started = True
                player.play(playlist)

        self.verify_playlist()
        cursor.close()
예제 #16
0
def deleteItem():

    # Serves as a keymap action
    if xbmc.getInfoLabel(
            'ListItem.Property(embyid)'):  # If we already have the embyid
        itemId = 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:
                log("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:
            log("Unknown embyId, unable to proceed.", 1)
            return

    if settings('skipContextMenu') != "true":
        resp = xbmcgui.Dialog().yesno(heading=lang(29999), line1=lang(33041))
        if not resp:
            log("User skipped deletion for: %s." % itemId, 1)
            return

    embyserver.Read_EmbyServer().deleteItem(itemId)
예제 #17
0
    def __init__(self, embycursor, kodicursor, pdialog=None):

        self.embycursor = embycursor
        self.emby_db = embydb.Embydb_Functions(self.embycursor)
        self.kodicursor = kodicursor
        self.kodi_db = _kodi_music.KodiMusic(self.kodicursor)
        self.pdialog = pdialog

        self.new_time = int(settings('newmusictime')) * 1000
        self.directstream = settings('streamMusic') == "true"
        self.enableimportsongrating = settings(
            'enableImportSongRating') == "true"
        self.enableexportsongrating = settings(
            'enableExportSongRating') == "true"
        self.enableupdatesongrating = settings(
            'enableUpdateSongRating') == "true"
        self.userid = window('emby_currUser')
        self.server = window('emby_server%s' % self.userid)

        Items.__init__(self)
예제 #18
0
    def music(self, embycursor, kodicursor, pdialog):
        # Get music from emby
        emby_db = embydb.Embydb_Functions(embycursor)
        music = Music(embycursor, kodicursor, pdialog)

        views = emby_db.getView_byType('music')
        log.info("Media folders: %s", views)

        # Add music artists and everything will fall into place
        if pdialog:
            pdialog.update(heading=lang(29999),
                           message="%s Music..." % lang(33021))

        for view in views:
            all_artists = self.emby.getArtists(view['id'], dialog=pdialog)
            music.add_all("MusicArtist", all_artists)

        log.debug("Finished syncing music")

        return True
예제 #19
0
    def incrementalSync(self):

        update_embydb = False
        pDialog = None

        # do a view update if needed
        if self.refresh_views:
            self.refreshViews()
            self.refresh_views = False
            self.forceLibraryUpdate = True

        # do a lib update if any items in list
        totalUpdates = len(self.addedItems) + len(self.updateItems) + len(self.userdataItems) + len(self.removeItems)
        if totalUpdates > 0:
            with database.DatabaseConn('emby') as cursor_emby:
                with database.DatabaseConn('video') as cursor_video:

                    emby_db = embydb.Embydb_Functions(cursor_emby)

                    incSyncIndicator = int(settings('incSyncIndicator') or 10)
                    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(cursor_emby, cursor_video)
                            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 stuff happened then do some stuff
        if update_embydb:
            update_embydb = False
            log.info("Updating emby database.")
            self.saveLastSync()

        if self.forceLibraryUpdate:
            # Force update the Kodi library
            self.forceLibraryUpdate = False

            log.info("Updating video library.")
            window('emby_kodiScan', value="true")
            xbmc.executebuiltin('UpdateLibrary(video)')

        if pDialog:
            pDialog.close()
예제 #20
0
    def run_internal(self):

        dialog = xbmcgui.Dialog()

        startupComplete = False

        log.warn("---===### Starting LibrarySync ###===---")

        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
                log.info("Doing DB Version Check")
                with database.DatabaseConn('emby') as cursor:
                    emby_db = embydb.Embydb_Functions(cursor)
                    currentVersion = emby_db.get_version()
                    ###$ Begin migration $###
                    if not currentVersion:
                        currentVersion = emby_db.get_version(settings('dbCreatedWithVersion') or self.clientInfo.get_version())
                        log.info("Migration of database version completed")
                    ###$ End migration $###

                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:
                        database.db_reset()

                    break

                window('emby_dbCheck', value="true")


            if not startupComplete:
                # Verify the video database can be found
                videoDb = database.video_database()
                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 ---===###")
예제 #21
0
    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']

        options = []
예제 #22
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)
예제 #23
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()
예제 #24
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
예제 #25
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()

        # use emby and video DBs
        with database.DatabaseConn('emby') as cursor_emby:
            with database.DatabaseConn('video') as cursor_video:    
                # content sync: movies, tvshows, musicvideos, music

                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
                views.Views(cursor_emby, cursor_video).maintain()
                cursor_emby.connection.commit()
                #self.maintainViews(cursor_emby, cursor_video)

                # 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](cursor_emby, cursor_video, pDialog)
                    if not completed:
                        xbmc.executebuiltin('InhibitIdleShutdown(false)')
                        utils.setScreensaver(value=screensaver)
                        window('emby_dbScan', clear=True)
                        if pDialog:
                            pDialog.close()

                        return False
                    else:
                        elapsedTime = datetime.now() - startTime
                        log.info("SyncDatabase (finished %s in: %s)"
                            % (itemtype, str(elapsedTime).split('.')[0]))

                         
        # sync music
        # use emby and music
        if music_enabled:                   
            if repair and 'music' not in repair_list:
                pass
            else:
                with database.DatabaseConn('emby') as cursor_emby:
                    with database.DatabaseConn('music') as cursor_music:
                        startTime = datetime.now()
                        completed = self.music(cursor_emby, cursor_music, pDialog)
                        if not completed:
                            xbmc.executebuiltin('InhibitIdleShutdown(false)')
                            utils.setScreensaver(value=screensaver)
                            window('emby_dbScan', clear=True)
                            if pDialog:
                                pDialog.close()

                            return False
                        else:
                            elapsedTime = datetime.now() - startTime
                            log.info("SyncDatabase (finished music in: %s)"
                                % (str(elapsedTime).split('.')[0]))

        if pDialog:
            pDialog.close()

        with database.DatabaseConn('emby') as cursor_emby:
            emby_db = embydb.Embydb_Functions(cursor_emby)
            current_version = emby_db.get_version(self.clientInfo.get_version())
                
        window('emby_version', current_version)

        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
예제 #26
0
def getThemeMedia():

    doUtils = downloadutils.DownloadUtils()
    dialog = xbmcgui.Dialog()
    playback = None

    # Choose playback method
    resp = dialog.select(lang(33072), [lang(30165), lang(33071)])
    if resp == 0:
        playback = "DirectPlay"
    elif resp == 1:
        playback = "DirectStream"
    else:
        return

    library = xbmc.translatePath(
                "special://profile/addon_data/emby.for.kodi/library/").decode('utf-8')
    # Create library directory
    if not xbmcvfs.exists(library):
        xbmcvfs.mkdir(library)

    # Set custom path for user
    if xbmc.getCondVisibility('System.HasAddon(script.tvtunes)'):
        tvtunes = xbmcaddon.Addon(id="script.tvtunes")
        tvtunes.setSetting('custom_path_enable', "true")
        tvtunes.setSetting('custom_path', library)
        log.info("TV Tunes custom path is enabled and set.")
    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=lang(29999), line1=lang(33073))
        xbmc.executebuiltin('Addon.OpenSettings(script.tvtunes)')
        return
        
    # Get every user view Id
    with database.DatabaseConn('emby') as cursor:
        emby_db = embydb.Embydb_Functions(cursor)
        viewids = emby_db.getViews()

    # 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/emby.for.kodi/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']: 
            if playback == "DirectPlay":
                playurl = api.API(theme).get_file_path()
            else:
                playurl = playutils.PlayUtils(theme).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/emby.for.kodi/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']: 
            if playback == "DirectPlay":
                playurl = api.API(theme).get_file_path()
            else:
                playurl = playutils.PlayUtils(theme).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=lang(29999),
            message=lang(33069),
            icon="special://home/addons/emby.for.kodi/icon.png",
            time=1000,
            sound=False)
예제 #27
0
    def maintainViews(self, embycursor, kodicursor):

        # Compare the views to emby
        emby = self.emby
        emby_db = embydb.Embydb_Functions(embycursor)
        kodi_db = kodidb.Kodidb_Functions(kodicursor)

        # Get views
        result = self.doUtils("{server}/emby/Users/{UserId}/Views?format=json")
        grouped_views = result['Items'] if 'Items' in result else []
        ordered_views = self.emby.getViews(sortedlist=True)
        all_views = []
        sorted_views = []
        for view in ordered_views:
            all_views.append(view['name'])
            if view['type'] == "music":
                continue

            if view['type'] == "mixed":
                sorted_views.append(view['name'])
            sorted_views.append(view['name'])
        log.info("Sorted views: %s" % sorted_views)

        # total nodes for window properties
        self.vnodes.clearProperties()
        totalnodes = len(sorted_views) + 0

        current_views = emby_db.getViews()
        # Set views for supported media type
        emby_mediatypes = {
            'movies': "Movie",
            'tvshows': "Series",
            'musicvideos': "MusicVideo",
            'homevideos': "Video",
            'music': "Audio",
            'photos': "Photo"
        }
        for mediatype in [
                'movies', 'tvshows', 'musicvideos', 'homevideos', 'music',
                'photos'
        ]:

            nodes = []  # Prevent duplicate for nodes of the same type
            playlists = []  # Prevent duplicate for playlists of the same type
            # Get media folders from server
            folders = self.emby.getViews(mediatype, root=True)
            for folder in folders:

                folderid = folder['id']
                foldername = folder['name']
                viewtype = folder['type']

                if foldername not in all_views:
                    # Media folders are grouped into userview
                    params = {
                        'ParentId': folderid,
                        'Recursive': True,
                        'Limit': 1,
                        'IncludeItemTypes': emby_mediatypes[mediatype]
                    }  # Get one item from server using the folderid
                    url = "{server}/emby/Users/{UserId}/Items?format=json"
                    result = self.doUtils(url, parameters=params)
                    try:
                        verifyitem = result['Items'][0]['Id']
                    except (TypeError, IndexError):
                        # Something is wrong. Keep the same folder name.
                        # Could be the view is empty or the connection
                        pass
                    else:
                        for grouped_view in grouped_views:
                            # This is only reserved for the detection of grouped views
                            if (grouped_view['Type'] == "UserView"
                                    and grouped_view.get('CollectionType')
                                    == mediatype):
                                # Take the userview, and validate the item belong to the view
                                if self.emby.verifyView(
                                        grouped_view['Id'], verifyitem):
                                    # Take the name of the userview
                                    log.info(
                                        "Found corresponding view: %s %s" %
                                        (grouped_view['Name'],
                                         grouped_view['Id']))
                                    foldername = grouped_view['Name']
                                    break
                        else:
                            # Unable to find a match, add the name to our sorted_view list
                            sorted_views.append(foldername)
                            log.info(
                                "Couldn't find corresponding grouped view: %s"
                                % sorted_views)

                # Failsafe
                try:
                    sorted_views.index(foldername)
                except ValueError:
                    sorted_views.append(foldername)

                # Get current media folders from emby database
                view = emby_db.getView_byId(folderid)
                try:
                    current_viewname = view[0]
                    current_viewtype = view[1]
                    current_tagid = view[2]

                except TypeError:
                    log.info("Creating viewid: %s in Emby database." %
                             folderid)
                    tagid = kodi_db.createTag(foldername)
                    # Create playlist for the video library
                    if (foldername not in playlists and mediatype
                            in ('movies', 'tvshows', 'musicvideos')):
                        utils.playlistXSP(mediatype, foldername, folderid,
                                          viewtype)
                        playlists.append(foldername)
                    # Create the video node
                    if foldername not in nodes and mediatype not in (
                            "musicvideos", "music"):
                        self.vnodes.viewNode(sorted_views.index(foldername),
                                             foldername, mediatype, viewtype,
                                             folderid)
                        if viewtype == "mixed":  # Change the value
                            sorted_views[sorted_views.index(
                                foldername)] = "%ss" % foldername
                        nodes.append(foldername)
                        totalnodes += 1
                    # Add view to emby database
                    emby_db.addView(folderid, foldername, viewtype, tagid)

                else:
                    log.debug(' '.join(("Found viewid: %s" % folderid,
                                        "viewname: %s" % current_viewname,
                                        "viewtype: %s" % current_viewtype,
                                        "tagid: %s" % current_tagid)))

                    # View is still valid
                    try:
                        current_views.remove(folderid)
                    except ValueError:
                        # View was just created, nothing to remove
                        pass

                    # View was modified, update with latest info
                    if current_viewname != foldername:
                        log.info("viewid: %s new viewname: %s" %
                                 (folderid, foldername))
                        tagid = kodi_db.createTag(foldername)

                        # Update view with new info
                        emby_db.updateView(foldername, tagid, folderid)

                        if mediatype != "music":
                            if emby_db.getView_byName(
                                    current_viewname) is None:
                                # The tag could be a combined view. Ensure there's no other tags
                                # with the same name before deleting playlist.
                                utils.playlistXSP(mediatype, current_viewname,
                                                  folderid, current_viewtype,
                                                  True)
                                # Delete video node
                                if mediatype != "musicvideos":
                                    self.vnodes.viewNode(
                                        indexnumber=None,
                                        tagname=current_viewname,
                                        mediatype=mediatype,
                                        viewtype=current_viewtype,
                                        viewid=folderid,
                                        delete=True)
                            # Added new playlist
                            if (foldername not in playlists and mediatype
                                    in ('movies', 'tvshows', 'musicvideos')):
                                utils.playlistXSP(mediatype, foldername,
                                                  folderid, viewtype)
                                playlists.append(foldername)
                            # Add new video node
                            if foldername not in nodes and mediatype != "musicvideos":
                                self.vnodes.viewNode(
                                    sorted_views.index(foldername), foldername,
                                    mediatype, viewtype, folderid)
                                if viewtype == "mixed":  # Change the value
                                    sorted_views[sorted_views.index(
                                        foldername)] = "%ss" % foldername
                                nodes.append(foldername)
                                totalnodes += 1

                        # Update items with new tag
                        items = emby_db.getItem_byView(folderid)
                        for item in items:
                            # Remove the "s" from viewtype for tags
                            kodi_db.updateTag(current_tagid, tagid, item[0],
                                              current_viewtype[:-1])
                    else:
                        # Validate the playlist exists or recreate it
                        if mediatype != "music":
                            if (foldername not in playlists and mediatype
                                    in ('movies', 'tvshows', 'musicvideos')):
                                utils.playlistXSP(mediatype, foldername,
                                                  folderid, viewtype)
                                playlists.append(foldername)
                            # Create the video node if not already exists
                            if foldername not in nodes and mediatype != "musicvideos":
                                self.vnodes.viewNode(
                                    sorted_views.index(foldername), foldername,
                                    mediatype, viewtype, folderid)
                                if viewtype == "mixed":  # Change the value
                                    sorted_views[sorted_views.index(
                                        foldername)] = "%ss" % foldername
                                nodes.append(foldername)
                                totalnodes += 1
        else:
            # Add video nodes listings
            self.vnodes.singleNode(totalnodes, "Favorite movies", "movies",
                                   "favourites")
            totalnodes += 1
            self.vnodes.singleNode(totalnodes, "Favorite tvshows", "tvshows",
                                   "favourites")
            totalnodes += 1
            self.vnodes.singleNode(totalnodes, "Favorite episodes", "episodes",
                                   "favourites")
            totalnodes += 1
            self.vnodes.singleNode(totalnodes, "channels", "movies",
                                   "channels")
            totalnodes += 1
            # Save total
            window('Emby.nodes.total', str(totalnodes))

            # Remove any old referenced views
            log.info("Removing views: %s" % current_views)
            for view in current_views:
                emby_db.removeView(view)
                # Remove any items that belongs to the old view
                items = emby_db.get_item_by_view(view)
                items = [i[0] for i in items]  # Convert list of tuple to list
                self.triage_items("remove", items)