예제 #1
0
def refreshPlaylist():

    lib = librarysync.LibrarySync()
    dialog = xbmcgui.Dialog()
    try:
        # First remove playlists
        utils.deletePlaylists()
        # Remove video nodes
        utils.deleteNodes()
        # Refresh views
        lib.refreshViews()
        dialog.notification(
            heading=lang(29999),
            message=lang(33069),
            icon="special://home/addons/plugin.video.emby/icon.png",
            time=1000,
            sound=False)

    except Exception as e:
        log("Refresh playlists/nodes failed: %s" % e, 1)
        dialog.notification(heading=lang(29999),
                            message=lang(33070),
                            icon=xbmcgui.NOTIFICATION_ERROR,
                            time=1000,
                            sound=False)
예제 #2
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
예제 #3
0
def refreshPlaylist():

    if window('emby_online') != "true":
        log.info("server is offline")
        return

    lib = librarysync.LibrarySync()
    dialog = xbmcgui.Dialog()
    try:
        # First remove playlists
        Playlist().delete_playlists()
        # Remove video nodes
        VideoNodes().deleteNodes()
        # Refresh views
        lib.refreshViews()
        dialog.notification(
                heading=lang(29999),
                message=lang(33069),
                icon="special://home/addons/emby.for.kodi/icon.png",
                time=1000,
                sound=False)

    except Exception as e:
        log.exception("Refresh playlists/nodes failed: %s" % e)
        dialog.notification(
            heading=lang(29999),
            message=lang(33070),
            icon=xbmcgui.NOTIFICATION_ERROR,
            time=1000,
            sound=False)
    def update_library(self, path=False):
        if debug.get():
            log('remove_video setting set to %s' % (setting('remove_video')))
        if path and setting('remove_video') == 'true':
            if debug.get():
                log('removing video from video library %s' % (path))
            videolibrary.remove_video(path)

        if debug.get():
            log('update_library setting set to %s' %
                (setting('update_library')))
        if setting('update_library') == 'true':
            if debug.get():
                log('updating whole video library %s' % (path))
            xbmc.executebuiltin('UpdateLibrary(video)')
            while not xbmc.getCondVisibility('Library.IsScanningVideo'):
                pass
            while xbmc.getCondVisibility('Library.IsScanningVideo'):
                xbmc.sleep(20)
            percent = (self.current - 1) * 100 / self.steps
            if self.enable:
                self.bar.update(percent, info('name'),
                                lang(30531) % (self.module_title, lang(30513)))
            self.current += 1
            self.module_current += 1
            log('Progress.update_library: self.current=%s, self.module_current=%s'
                % (self.current, self.module_current))
예제 #5
0
    def __run(self):
        """
        Do the work
        """
        log.debug('Show sync info thread started')
        # cache local variables because it's faster
        total = self.total
        dialog = self.dialog
        thread_stopped = self.thread_stopped
        dialog.create("%s %s: %s %s" %
                      (lang(39714), self.item_type, str(total), lang(39715)))

        total = 2 * total
        totalProgress = 0
        while thread_stopped() is False:
            with LOCK:
                get_progress = GET_METADATA_COUNT
                process_progress = PROCESS_METADATA_COUNT
                viewName = PROCESSING_VIEW_NAME
            totalProgress = get_progress + process_progress
            try:
                percentage = int(float(totalProgress) / float(total) * 100.0)
            except ZeroDivisionError:
                percentage = 0
            dialog.update(percentage,
                          message="%s %s. %s %s: %s" %
                          (get_progress, lang(39712), process_progress,
                           lang(39713), viewName))
            # Sleep for x milliseconds
            sleep(200)
        dialog.close()
        log.debug('Show sync info thread terminated')
예제 #6
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
예제 #7
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
예제 #8
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
예제 #9
0
    def _play(cls, data):

        item_ids = data['ItemIds']
        command = data['PlayCommand']

        playlist_ = playlist.Playlist()

        if command == 'PlayNow':
            startat = data.get('StartPositionTicks', 0)
            playlist_.play_all(item_ids, startat)
            dialog(type_="notification",
                   heading="{emby}",
                   message="%s %s" % (len(item_ids), lang(33004)),
                   icon="{emby}",
                   sound=False)

        elif command == 'PlayNext':
            new_playlist = playlist_.modify_playlist(item_ids)
            dialog(type_="notification",
                   heading="{emby}",
                   message="%s %s" % (len(item_ids), lang(33005)),
                   icon="{emby}",
                   sound=False)
            player = xbmc.Player()
            if not player.isPlaying():
                # Only start the playlist if nothing is playing
                player.play(new_playlist)
예제 #10
0
    def onInit(self):

        self.message = self.getControl(MESSAGE)
        self.message_box = self.getControl(MESSAGE_BOX)
        self.busy = self.getControl(BUSY)
        self.list_ = self.getControl(LIST)

        for server in self.servers:
            server_type = "wifi" if server.get('ExchangeToken') else "network"
            self.list_.addItem(
                self._add_listitem(server['Name'], server['Id'], server_type))

        self.getControl(USER_NAME).setLabel(
            "%s %s" % (lang(33000), self.username.decode('utf-8')))

        if self.user_image is not None:
            self.getControl(USER_IMAGE).setImage(self.user_image)

        if not self.emby_connect:  # Change connect user
            self.getControl(EMBY_CONNECT).setLabel("[UPPERCASE][B]" +
                                                   lang(30618) +
                                                   "[/B][/UPPERCASE]")

        if self.servers:
            self.setFocus(self.list_)
예제 #11
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
예제 #12
0
    def _AutoPickPMS(self):
        """
        Will try to pick PMS based on machineIdentifier saved in file settings
        but only once

        Returns server or None if unsuccessful
        """
        httpsUpdated = False
        checkedPlexTV = False
        server = None
        while True:
            if httpsUpdated is False:
                serverlist = self._getServerList()
                for item in serverlist:
                    if item.get('machineIdentifier') == self.serverid:
                        server = item
                if server is None:
                    name = settings('plex_servername')
                    log.warn('The PMS you have used before with a unique '
                             'machineIdentifier of %s and name %s is '
                             'offline' % (self.serverid, name))
                    # "PMS xyz offline"
                    self.dialog.notification(addonName,
                                             '%s %s'
                                             % (name, lang(39213)),
                                             xbmcgui.NOTIFICATION_ERROR,
                                             7000,
                                             False)
                    return
            chk = self._checkServerCon(server)
            if chk == 504 and httpsUpdated is False:
                # Not able to use HTTP, try HTTPs for now
                server['scheme'] = 'https'
                httpsUpdated = True
                continue
            if chk == 401:
                log.warn('Not yet authorized for Plex server %s'
                         % server['name'])
                if self.CheckPlexTVSignIn() is True:
                    if checkedPlexTV is False:
                        # Try again
                        checkedPlexTV = True
                        httpsUpdated = False
                        continue
                    else:
                        log.warn('Not authorized even though we are signed '
                                 ' in to plex.tv correctly')
                        self.dialog.ok(addonName, '%s %s'
                                       % lang(39214) + server['name'])
                        return
                else:
                    return
            # Problems connecting
            elif chk >= 400 or chk is False:
                log.warn('Problems connecting to server %s. chk is %s'
                         % (server['name'], chk))
                return
            log.info('We found a server to automatically connect to: %s'
                     % server['name'])
            return server
예제 #13
0
def chooseServer():
    """
    Lets user choose from list of PMS
    """
    log.info("Choosing PMS server requested, starting")

    import initialsetup
    setup = initialsetup.InitialSetup()
    server = setup.pick_pms(showDialog=True)
    if server is None:
        log.error('We did not connect to a new PMS, aborting')
        plex_command('SUSPEND_USER_CLIENT', 'False')
        plex_command('SUSPEND_LIBRARY_THREAD', 'False')
        return

    log.info("User chose server %s" % server['name'])
    setup.write_pms_to_settings(server)

    if not __LogOut():
        return

    from utils import wipe_database
    # Wipe Kodi and Plex database as well as playlists and video nodes
    wipe_database()

    # Log in again
    __LogIn()
    log.info("Choosing new PMS complete")
    # '<PMS> connected'
    dialog('notification',
           lang(29999),
           '%s %s' % (server['name'], lang(39220)),
           icon='{plex}',
           time=3000,
           sound=False)
예제 #14
0
    def _AutoPickPMS(self):
        """
        Will try to pick PMS based on machineIdentifier saved in file settings
        but only once

        Returns server or None if unsuccessful
        """
        httpsUpdated = False
        checkedPlexTV = False
        server = None
        while True:
            if httpsUpdated is False:
                serverlist = self._getServerList()
                for item in serverlist:
                    if item.get('machineIdentifier') == self.serverid:
                        server = item
                if server is None:
                    name = settings('plex_servername')
                    log.warn('The PMS you have used before with a unique '
                             'machineIdentifier of %s and name %s is '
                             'offline' % (self.serverid, name))
                    # "PMS xyz offline"
                    if settings('show_pms_offline') == 'true':
                        self.dialog.notification(addonName,
                                                 '%s %s' % (name, lang(39213)),
                                                 xbmcgui.NOTIFICATION_ERROR,
                                                 7000, False)
                    return
            chk = self._checkServerCon(server)
            if chk == 504 and httpsUpdated is False:
                # Not able to use HTTP, try HTTPs for now
                server['scheme'] = 'https'
                httpsUpdated = True
                continue
            if chk == 401:
                log.warn('Not yet authorized for Plex server %s' %
                         server['name'])
                if self.CheckPlexTVSignIn() is True:
                    if checkedPlexTV is False:
                        # Try again
                        checkedPlexTV = True
                        httpsUpdated = False
                        continue
                    else:
                        log.warn('Not authorized even though we are signed '
                                 ' in to plex.tv correctly')
                        self.dialog.ok(addonName,
                                       '%s %s' % lang(39214) + server['name'])
                        return
                else:
                    return
            # Problems connecting
            elif chk >= 400 or chk is False:
                log.warn('Problems connecting to server %s. chk is %s' %
                         (server['name'], chk))
                return
            log.info('We found a server to automatically connect to: %s' %
                     server['name'])
            return server
예제 #15
0
def emby_backup():
    # Create a backup at specified location
    path = settings('backupPath')

    # filename
    default_value = "Kodi%s.%s" % (xbmc.getInfoLabel('System.BuildVersion')[:2],
                                   xbmc.getInfoLabel('System.Date(dd-mm-yy)'))
    folder_name = dialog(type_="input",
                         heading=lang(33089),
                         defaultt=default_value)
    if not folder_name:
        return

    backup = os.path.join(path, folder_name)
    log.info("Backup: %s", backup)

    # Create directory
    if xbmcvfs.exists(backup+"\\"):
        log.info("Existing directory!")
        if not dialog(type_="yesno",
                      heading="{emby}",
                      line1=lang(33090)):
            return emby_backup()
        shutil.rmtree(backup)

    # Addon_data
    addon_data = xbmc.translatePath("special://profile/addon_data/emby.for.kodi").decode('utf-8')
    try:
        shutil.copytree(src=addon_data,
                        dst=os.path.join(backup, "addon_data", "emby.for.kodi"))
    except shutil.Error as error:
        log.error(error)

    # Database files
    database_folder = os.path.join(backup, "Database")
    if not xbmcvfs.mkdir(database_folder):
        try:
            os.makedirs(database_folder)
        except OSError as error:
            log.error(error)
            dialog(type_="ok",
                   heading="{emby}",
                   line1="Failed to create backup")
        return

    # Emby database
    emby_path = database.emby_database()
    xbmcvfs.copy(emby_path, os.path.join(database_folder, ntpath.basename(emby_path)))
    # Videos database
    video_path = database.video_database()
    xbmcvfs.copy(video_path, os.path.join(database_folder, ntpath.basename(video_path)))
    # Music database
    if settings('enableMusic') == "true":
        music_path = database.music_database()
        xbmcvfs.copy(music_path, os.path.join(database_folder, ntpath.basename(music_path)))

    dialog(type_="ok",
           heading="{emby}",
           line1="%s: %s" % (lang(33091), backup))
예제 #16
0
def resetAuth():
    # User tried login and failed too many times
    resp = xbmcgui.Dialog().yesno(heading=lang(30132), line1=lang(33050))
    if resp:
        log("Reset login attempts.", 1)
        window('emby_serverStatus', value="Auth")
    else:
        xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)')
예제 #17
0
    def _auto_pick_pms(self):
        """
        Will try to pick PMS based on machineIdentifier saved in file settings
        but only once

        Returns server or None if unsuccessful
        """
        https_updated = False
        checked_plex_tv = False
        server = None
        while True:
            if https_updated is False:
                serverlist = PF.discover_pms(self.plex_token)
                for item in serverlist:
                    if item.get('machineIdentifier') == self.serverid:
                        server = item
                if server is None:
                    name = settings('plex_servername')
                    LOG.warn(
                        'The PMS you have used before with a unique '
                        'machineIdentifier of %s and name %s is '
                        'offline', self.serverid, name)
                    return
            chk = self._check_pms_connectivity(server)
            if chk == 504 and https_updated is False:
                # switch HTTPS to HTTP or vice-versa
                if server['scheme'] == 'https':
                    server['scheme'] = 'http'
                else:
                    server['scheme'] = 'https'
                https_updated = True
                continue
            if chk == 401:
                LOG.warn('Not yet authorized for Plex server %s',
                         server['name'])
                if self.check_plex_tv_sign_in() is True:
                    if checked_plex_tv is False:
                        # Try again
                        checked_plex_tv = True
                        https_updated = False
                        continue
                    else:
                        LOG.warn('Not authorized even though we are signed '
                                 ' in to plex.tv correctly')
                        dialog(
                            'ok', lang(29999), '%s %s' %
                            (lang(39214), try_encode(server['name'])))
                        return
                else:
                    return
            # Problems connecting
            elif chk >= 400 or chk is False:
                LOG.warn('Problems connecting to server %s. chk is %s',
                         server['name'], chk)
                return
            LOG.info('We found a server to automatically connect to: %s',
                     server['name'])
            return server
예제 #18
0
    def compare_boxsets(self):

        if self.pdialog:
            self.pdialog.update(heading=lang(29999), message=lang(33027))

        boxsets = dict(self.emby_db.get_checksum('BoxSet'))
        emby_boxsets = self.emby.getBoxset(dialog=self.pdialog)

        return self.compare("BoxSet", emby_boxsets['Items'], boxsets)
	def __rate_lib(self, progress):
		progress.start_module(lang(30204), self.RATE_LIB_STEPS)
		try:
			if not self.episodeid:
				raise Exception(lang(30601))
			progress.update(lang(30522)) # updating rating
			utilxbmc.set_episode_rating(self.episodeid, self.rating)
		except Exception, e:
			dialog.error(e.message)
예제 #20
0
    def compare_songs(self):

        if self.pdialog:
            self.pdialog.update(heading=lang(29999), message="%s Songs..." % lang(33031))

        songs = dict(self.emby_db.get_checksum('Audio'))
        emby_songs = self.emby.getSongs(basic=True, dialog=self.pdialog)

        return self.compare("Audio", emby_songs['Items'], songs)
 def __preserve_playcount(self, progress):
     progress.start_module(lang(30701), self.PRESERVE_PLAYCOUNT_STEPS)
     try:
         if not self.movieid:
             raise Exception(lang(30604))
         progress.update(lang(30598))  # setting old playcount
         utilxbmc.set_movie_playcount(self.movieid, self.playcount)
     except Exception, e:
         dialog.error(e.message)
 def __set_tag(self, progress):
     progress.start_module(lang(30702), self.SET_TAG_STEPS)
     try:
         if not self.movieid:
             raise Exception(lang(30604))
         progress.update(lang(30597))  # setting tag
         utilxbmc.set_movie_tag(self.movieid, self.tag)
     except Exception, e:
         dialog.error(e.message)
예제 #23
0
    def compare_albums(self):

        if self.pdialog:
            self.pdialog.update(heading=lang(29999), message="%s Albums..." % lang(33031))

        albums = dict(self.emby_db.get_checksum('MusicAlbum'))
        emby_albums = self.emby.getAlbums(basic=True, dialog=self.pdialog)

        return self.compare("MusicAlbum", emby_albums['Items'], albums)
예제 #24
0
    def compare_albums(self):

        if self.pdialog:
            self.pdialog.update(heading=lang(29999),
                                message="%s Albums..." % lang(33031))

        albums = dict(self.emby_db.get_checksum('MusicAlbum'))
        emby_albums = self.emby.getAlbums(basic=True, dialog=self.pdialog)

        return self.compare("MusicAlbum", emby_albums['Items'], albums)
 def __rate_lib(self, progress):
     progress.start_module(lang(30204), self.RATE_LIB_STEPS)
     try:
         if not self.movieid:
             raise Exception(lang(30604))
         progress.update(lang(30522))  # updating rating
         log("Movie ID is %d" % self.movieid)
         utilxbmc.set_movie_rating(self.movieid, self.rating)
     except Exception, e:
         dialog.error(e.message)
예제 #26
0
    def compare_songs(self):

        if self.pdialog:
            self.pdialog.update(heading=lang(29999),
                                message="%s Songs..." % lang(33031))

        songs = dict(self.emby_db.get_checksum('Audio'))
        emby_songs = self.emby.getSongs(basic=True, dialog=self.pdialog)

        return self.compare("Audio", emby_songs['Items'], songs)
예제 #27
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 = translatePath("special://thumbnails/")
            if exists(path):
                rmtree(path, ignore_errors=True)

            # remove all existing data from texture DB
            connection = kodiSQL('texture')
            cursor = connection.cursor()
            query = 'SELECT tbl_name FROM sqlite_master WHERE type=?'
            cursor.execute(query, ('table', ))
            rows = cursor.fetchall()
            for row in rows:
                tableName = row[0]
                if tableName != "version":
                    query = "DELETE FROM ?"
                    cursor.execute(query, (tableName, ))
            connection.commit()
            connection.close()

        # Cache all entries in video DB
        connection = kodiSQL('video')
        cursor = connection.cursor()
        # dont include actors
        query = "SELECT url FROM art WHERE media_type != ?"
        cursor.execute(query, ('actor', ))
        result = cursor.fetchall()
        total = len(result)
        log.info("Image cache sync about to process %s video images" % total)
        connection.close()

        for url in result:
            self.cacheTexture(url[0])
        # Cache all entries in music DB
        connection = kodiSQL('music')
        cursor = connection.cursor()
        cursor.execute("SELECT url FROM art")
        result = cursor.fetchall()
        total = len(result)
        log.info("Image cache sync about to process %s music images" % total)
        connection.close()
        for url in result:
            self.cacheTexture(url[0])
	def __move(self, progress):
		progress.start_module(lang(30132), self.MOVE_STEPS)
		try:
			progress.update(lang(30590)) # detecting library place
	 		lib_source = os.path.dirname(os.path.dirname(os.path.dirname(self.path)))
		 	if self.destination == lib_source:
		 		raise Exception(lang(30602))
			progress.update(lang(30506)) # moving files
			source = os.path.dirname(self.path)
			match = os.path.splitext(os.path.basename(self.path))[0]
			count = utilfile.count_manage_files(self.alt_method, source, match)
			if not dialog.warning(lang(30132), count):
				raise Exception(lang(30609))
			log("Episode: move source path: %s" % source)
			if setting('fm_episodes_structure') == '0': # multiple folders
				destination = os.path.join(self.destination, self.path.split(os.sep)[-3], self.path.split(os.sep)[-2])
				log("Episode: move destination (multiple) |alt_method=%s|: %s" % (self.alt_method, destination))
			else: # single folder
				destination = os.path.join(self.destination, self.path.split(os.sep)[-2])
				log("Episode: move destination (single) |alt_method=%s|: %s" % (self.alt_method, destination))
			utilfile.move_files(self.alt_method, source, destination, match, True)
			progress.update(lang(30513)) # updating library
			progress.update_library(self.path)
			self.path = os.path.join(destination, os.path.basename(self.path))
			self.episodeid = utilxbmc.get_episodeid_by_path(self.path)
			if self.episodeid: # if still in lib source folders
				progress.update(lang(30514)) # setting watched
				utilxbmc.set_episode_playcount(self.episodeid, self.playcount+1)
		except OSError:
			dialog.error(lang(30610))
		except ValueError as err:
			ValueErrorHandler(err)
		except Exception, e:
			dialog.error(e.message)
예제 #29
0
    def fastSync(self):

        lastSync = settings('LastIncrementalSync')
        if not lastSync:
            lastSync = "2010-01-01T00:00:00Z"

        lastSyncTime = utils.convertDate(lastSync)
        log.info("Last sync run: %s" % lastSyncTime)

        # get server RetentionDateTime
        try:
            result = self.doUtils(
                "{server}/emby/Emby.Kodi.SyncQueue/GetServerDateTime?format=json"
            )
            retention_time = result['RetentionDateTime']
        except Exception as error:
            log.error(error)
            retention_time = "2010-01-01T00:00:00Z"

        retention_time = utils.convertDate(retention_time)
        log.info("RetentionDateTime: %s" % retention_time)

        # if last sync before retention time do a full sync
        if retention_time > lastSyncTime:
            log.info(
                "Fast sync server retention insufficient, fall back to full sync"
            )
            return False

        params = {'LastUpdateDT': lastSync}
        if settings('enableMusic') != "true":
            params['filter'] = "music"
        url = "{server}/emby/Emby.Kodi.SyncQueue/{UserId}/GetItems?format=json"

        try:
            result = self.doUtils(url, parameters=params)
            processlist = {
                'added': result['ItemsAdded'],
                'update': result['ItemsUpdated'],
                'userdata': result['UserDataChanged'],
                'remove': result['ItemsRemoved']
            }

        except Exception as error:  # To be reviewed to only catch specific errors.
            log.error(error)
            log.error("Failed to retrieve latest updates using fast sync.")
            xbmcgui.Dialog().ok(lang(29999), lang(33095))
            return False

        else:
            log.info("Fast sync changes: %s" % result)
            for action in processlist:
                self.triage_items(action, processlist[action])
            return True
예제 #30
0
    def _connect_to_server(self, server, port):

        server_address = "%s:%s" % (server, port)
        self._message("%s %s..." % (lang(30610), server_address))
        result = self.connect_manager.connectToAddress(server_address)

        if result['State'] == CONN_STATE['Unavailable']:
            self._message(lang(30609))
            return False
        else:
            self._server = result['Servers'][0]
            return True
 def __rate_tag(self, progress):
     progress.start_module(lang(30205), self.RATE_TAG_STEPS)
     try:
         if not self.movieid:
             raise Exception(lang(30604))
         progress.update(lang(30524))  # setting tag
         tag = setting("rt_movies_tag_text")
         if "%s" in tag:
             tag = tag % self.rating
         utilxbmc.set_movie_tag(self.movieid, tag)
     except Exception, e:
         dialog.error(e.message)
예제 #32
0
    def compare_mvideos(self, view):

        view_id = view['id']
        view_name = view['name']

        if self.pdialog:
            self.pdialog.update(heading=lang(29999), message="%s %s..." % (lang(33028), view_name))

        mvideos = dict(self.emby_db.get_checksum_by_view('MusicVideo', view_id))
        emby_mvideos = self.emby.getMusicVideos(view_id, basic=True, dialog=self.pdialog)

        return self.compare("MusicVideo", emby_mvideos['Items'], mvideos, view)
예제 #33
0
    def compare_mvideos(self, view):

        view_id = view['id']
        view_name = view['name']

        if self.pdialog:
            self.pdialog.update(heading=lang(29999), message="%s %s..." % (lang(33028), view_name))

        mvideos = dict(self.emby_db.get_checksum_by_view('MusicVideo', view_id))
        emby_mvideos = self.emby.getMusicVideos(view_id, basic=True, dialog=self.pdialog)

        return self.compare("MusicVideo", emby_mvideos['Items'], mvideos, view)
예제 #34
0
    def _connect_to_server(self, server, port):

        server_address = "%s:%s" % (server, port)
        self._message("%s %s..." % (lang(30610), server_address))
        result = self.connect_manager.connectToAddress(server_address)

        if result['State'] == CONN_STATE['Unavailable']:
            self._message(lang(30609))
            return False
        else:
            self._server = result['Servers'][0]
            return True
 def __rate_lib(self, progress):
     progress.start_module(lang(30204), self.RATE_LIB_STEPS)
     try:
         if not self.episodeid:
             raise Exception(lang(30601))
         progress.update(lang(30522)) # updating rating
         utilxbmc.set_episode_rating(self.episodeid, self.rating)
     except Exception as e:
         if debug.get():
             log(debug.traceback.print_exc(), xbmc.LOGERROR)
         debug.exception_dialog(e)
     finally:
         progress.finish_module()
예제 #36
0
 def __set_tag(self, progress):
     progress.start_module(lang(30702), self.SET_TAG_STEPS)
     try:
         if not self.movieid:
             raise Exception(lang(30604))
         progress.update(lang(30597)) # setting tag
         utilxbmc.set_movie_tag(self.movieid, self.tag)
     except Exception as e:
         if debug.get():
             log(debug.traceback.print_exc(), xbmc.LOGERROR)
         debug.exception_dialog(e)
     finally:
         progress.finish_module()
예제 #37
0
    def _delete_item(self):

        delete = True
        if settings('skipContextMenu') != "true":

            if not dialog(type_="yesno", heading=addonName, line1=lang(33041)):
                log.info("User skipped deletion for: %s", self.item_id)
                delete = False

        if delete:
            log.info("Deleting Plex item with id %s", self.item_id)
            if delete_item_from_pms(self.item_id) is False:
                dialog(type_="ok", heading="{plex}", line1=lang(30414))
예제 #38
0
 def __preserve_playcount(self, progress):
     progress.start_module(lang(30701), self.PRESERVE_PLAYCOUNT_STEPS)
     try:
         if not self.movieid:
             raise Exception(lang(30604))
         progress.update(lang(30598)) # setting old playcount
         utilxbmc.set_movie_playcount(self.movieid, self.playcount)
     except Exception as e:
         if debug.get():
             log(debug.traceback.print_exc(), xbmc.LOGERROR)
         debug.exception_dialog(e)
     finally:
         progress.finish_module()
예제 #39
0
    def _delete_item(self):

        delete = True
        if settings('skipContextMenu') != "true":

            if not dialog("yesno", heading=lang(29999), line1=lang(33041)):
                log.info("User skipped deletion for: %s", self.item_id)
                delete = False

        if delete:
            log.info("Deleting Plex item with id %s", self.item_id)
            if delete_item_from_pms(self.item_id) is False:
                dialog("ok", heading="{plex}", line1=lang(30414))
 def _delete_item(self):
     """
     Delete item on PMS
     """
     delete = True
     if settings('skipContextMenu') != "true":
         if not dialog("yesno", heading="{plex}", line1=lang(33041)):
             LOG.info("User skipped deletion for: %s", self.plex_id)
             delete = False
     if delete:
         LOG.info("Deleting Plex item with id %s", self.plex_id)
         if delete_item_from_pms(self.plex_id) is False:
             dialog("ok", heading="{plex}", line1=lang(30414))
예제 #41
0
    def fastSync(self):

        lastSync = settings('LastIncrementalSync')
        if not lastSync:
            lastSync = "2010-01-01T00:00:00Z"

        lastSyncTime = utils.convertDate(lastSync)
        log.info("Last sync run: %s" % lastSyncTime)

        # get server RetentionDateTime
        try:
            result = self.doUtils("{server}/emby/Emby.Kodi.SyncQueue/GetServerDateTime?format=json")
            retention_time = result['RetentionDateTime']
        except Exception as error:
            log.error(error)
            retention_time = "2010-01-01T00:00:00Z"

        retention_time = utils.convertDate(retention_time)
        log.info("RetentionDateTime: %s" % retention_time)

        # if last sync before retention time do a full sync
        if retention_time > lastSyncTime:
            log.info("Fast sync server retention insufficient, fall back to full sync")
            return False

        params = {'LastUpdateDT': lastSync}
        if settings('enableMusic') != "true":
            params['filter'] = "music"
        url = "{server}/emby/Emby.Kodi.SyncQueue/{UserId}/GetItems?format=json"

        try:
            result = self.doUtils(url, parameters=params)
            processlist = {

                'added': result['ItemsAdded'],
                'update': result['ItemsUpdated'],
                'userdata': result['UserDataChanged'],
                'remove': result['ItemsRemoved']
            }

        except Exception as error: # To be reviewed to only catch specific errors.
            log.error(error)
            log.error("Failed to retrieve latest updates using fast sync.")
            xbmcgui.Dialog().ok(lang(29999), lang(33095))
            return False

        else:
            log.info("Fast sync changes: %s" % result)
            for action in processlist:
                self.triage_items(action, processlist[action])
            return True
예제 #42
0
 def deviceid(self):
     deviceId_old = window('plex_client_Id')
     from clientinfo import getDeviceId
     try:
         deviceId = getDeviceId(reset=True)
     except Exception as e:
         log.error('Failed to generate a new device Id: %s' % e)
         dialog('ok', lang(29999), lang(33032))
     else:
         log.info('Successfully removed old device ID: %s New deviceId:'
                  '%s' % (deviceId_old, deviceId))
         # 'Kodi will now restart to apply the changes'
         dialog('ok', lang(29999), lang(33033))
         executebuiltin('RestartApp')
예제 #43
0
    def _set_access(self):

        try:
            self.doutils.downloadUrl("{server}/emby/Users?format=json")
        except Exception as error:
            if self._has_access and "restricted" in error:
                self._has_access = False
                log.info("access is restricted")
        else:
            if not self._has_access:
                self._has_access = True
                window('emby_serverStatus', clear=True)
                log.info("access is granted")
                xbmcgui.Dialog().notification(lang(29999), lang(33007))
예제 #44
0
 def deviceid(self):
     deviceId_old = window('plex_client_Id')
     from clientinfo import getDeviceId
     try:
         deviceId = getDeviceId(reset=True)
     except Exception as e:
         log.error('Failed to generate a new device Id: %s' % e)
         dialog('ok', lang(29999), lang(33032))
     else:
         log.info('Successfully removed old device ID: %s New deviceId:'
                  '%s' % (deviceId_old, deviceId))
         # 'Kodi will now restart to apply the changes'
         dialog('ok', lang(29999), lang(33033))
         executebuiltin('RestartApp')
예제 #45
0
 def __delete(self, progress):
     progress.start_module(lang(30132), self.DELETE_STEPS)
     try:
         progress.update(lang(30516)) # deleting files
         source = os.path.dirname(self.path)
         remove_empty = setting('fm_movies_remove_empty') == 'true'
         if setting('fm_movies_structure') == '0': # multiple folders
             count = utilfile.count_manage_directory(self.alt_method, source)
             if not dialog.warning(lang(30132), count):
                 raise Exception(lang(30609))
             utilfile.delete_directory(self.alt_method, source)
         else: # single folder
             match = os.path.splitext(os.path.basename(self.path))[0]
             count = utilfile.count_manage_files(self.alt_method, source, match)
             log("Movie.__delete: match=%s" % match)
             if not dialog.warning(lang(30132), count):
                 raise Exception(lang(30609))
             utilfile.delete_files(self.alt_method, source, match, remove_empty)
         progress.update(lang(30513)) # updating library
         progress.update_library(self.path)
         self.movieid = None
         self.path = None
     except OSError:
         dialog.error(lang(30610))
     except ValueError as err:
         ValueErrorHandler(err)
     except Exception as e:
         if debug.get():
             log(debug.traceback.print_exc(), xbmc.LOGERROR)
         debug.exception_dialog(e)
     finally:
         progress.finish_module()
예제 #46
0
    def _set_access(self):

        try:
            self.doutils.downloadUrl("{server}/emby/Users?format=json")
        except Exception as error:
            if self._has_access and "restricted" in error:
                self._has_access = False
                log.info("access is restricted")
        else:
            if not self._has_access:
                self._has_access = True
                window('emby_serverStatus', clear=True)
                log.info("access is granted")
                xbmcgui.Dialog().notification(lang(29999), lang(33007))
 def __delete(self, progress):
     progress.start_module(lang(30133), self.DELETE_STEPS)
     try:
         progress.update(lang(30516))  # deleting files
         source = os.path.dirname(self.path)
         remove_empty = setting("fm_movie_remove_empty") == "true"
         if setting("fm_movies_structure") == "0":  # multiple folders
             count = utilfile.count_manage_directory(self.alt_method, source)
             if not dialog.warning(lang(30133), count):
                 raise Exception(lang(30609))
             utilfile.delete_directory(self.alt_method, source)
         else:  # single folder
             match = os.path.splitext(os.path.basename(self.path))[0]
             count = utilfile.count_manage_files(self.alt_method, source, match)
             log("Movie: delete match: %s" % match)
             if not dialog.warning(lang(30133), count):
                 raise Exception(lang(30609))
             utilfile.delete_files(self.alt_method, source, match, remove_empty)
         progress.update(lang(30513))  # updating library
         progress.update_library(self.path)
         self.movieid = None
         self.path = None
     except OSError:
         dialog.error(lang(30610))
     except ValueError as err:
         ValueErrorHandler(err)
     except Exception, e:
         dialog.error(e.message)
예제 #48
0
    def isDirectPlay(self):

        # Requirement: Filesystem, Accessible path
        if settings('playFromStream') == "true":
            # User forcing to play via HTTP
            log.info("Can't direct play, play from HTTP enabled.")
            return False

        videotrack = self.item['MediaSources'][0]['Name']
        transcodeH265 = settings('transcodeH265')
        videoprofiles = [x['Profile'] for x in self.item['MediaSources'][0]['MediaStreams'] if 'Profile' in x]
        transcodeHi10P = settings('transcodeHi10P')        

        if transcodeHi10P == "true" and "H264" in videotrack and "High 10" in videoprofiles:
            return False   

        if transcodeH265 in ("1", "2", "3") and ("HEVC" in videotrack or "H265" in videotrack):
            # Avoid H265/HEVC depending on the resolution
            resolution = int(videotrack.split("P", 1)[0])
            res = {

                '1': 480,
                '2': 720,
                '3': 1080
            }
            log.info("Resolution is: %sP, transcode for resolution: %sP+"
                % (resolution, res[transcodeH265]))
            if res[transcodeH265] <= resolution:
                return False

        canDirectPlay = self.item['MediaSources'][0]['SupportsDirectPlay']
        # Make sure direct play is supported by the server
        if not canDirectPlay:
            log.info("Can't direct play, server doesn't allow/support it.")
            return False

        location = self.item['LocationType']
        if location == "FileSystem":
            # Verify the path
            if not self.fileExists():
                log.info("Unable to direct play.")
                log.info(self.directPlay())
                xbmcgui.Dialog().ok(
                            heading=lang(29999),
                            line1=lang(33011),
                            line2=(self.directPlay()))                            
                sys.exit()

        return True
예제 #49
0
    def path_validation(cls, path):
        # Verify if direct path is accessible or not
        verify_path = path
        if not os.path.supports_unicode_filenames:
            verify_path = path.encode('utf-8')

        if window('emby_pathverified') != "true" and not xbmcvfs.exists(verify_path):
            if dialog(type_="yesno",
                      heading="{emby}",
                      line1="%s %s. %s" % (lang(33047), path, lang(33048))):

                window('emby_shouldStop', value="true")
                return False

        return True
예제 #50
0
    def _startup(self):
        
        serverId = settings('serverId')
        if(serverId != None):
            serverId = hashlib.md5(serverId).hexdigest()
        
        ga = GoogleAnalytics()
        ga.sendEventData("Application", "Startup", serverId)
        try:
            ga.sendEventData("Version", "OS", platform.platform())
            ga.sendEventData("Version", "Python", platform.python_version())
        except Exception:
            pass

        # Start up events
        self.warn_auth = True

        username = self.userclient_thread.get_username()
        if settings('connectMsg') == "true" and username:
            # Get additional users
            add_users = settings('additionalUsers')
            if add_users:
                add_users = ", "+", ".join(add_users.split(','))

            dialog(type_="notification",
                   heading="{emby}",
                   message=("%s %s%s"
                            % (lang(33000), username.decode('utf-8'),
                               add_users.decode('utf-8'))),
                   icon="{emby}",
                   time=2000,
                   sound=False)
        return True
	def update(self, msg):
		percent = self.current * 100 / self.steps
		if self.enable:
			self.bar.update(percent, info('name'), lang(30531) % (self.module_title, msg))
		self.current += 1
		self.module_current += 1
		log('update: self.current=%s, self.module_current=%s' % (self.current, self.module_current))
예제 #52
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()
	def update_library(self, path=False):
		if path and setting('remove_video') == 'true':
			videolibrary.remove_video(path)
		if setting('update_library') == 'true':
			xbmc.executebuiltin('UpdateLibrary(video)')
			while not xbmc.getCondVisibility('Library.IsScanningVideo'):
				pass
			while xbmc.getCondVisibility('Library.IsScanningVideo'):
				xbmc.sleep(20)
			percent = (self.current-1) * 100 / self.steps
			if self.enable:
				if utilxbmc.version() >= 13:
					self.bar = xbmcgui.DialogProgressBG()
				else:
					self.bar = xbmcgui.DialogProgress()
				self.bar.create(info('name'))
				self.bar.update(percent, info('name'),  lang(30531) % (self.module_title, lang(30513)))
예제 #54
0
    def _server_restarting(cls):

        if settings('supressRestartMsg') == "true":
            dialog(type_="notification",
                   heading="{emby}",
                   message=lang(33006),
                   icon="{emby}")
        window('emby_online', value="false")
예제 #55
0
def resetAuth():
    # User tried login and failed too many times
    resp = dialog('yesno', heading="{plex}", line1=lang(39206))
    if resp == 1:
        log.info("Reset login attempts.")
        window('plex_serverStatus', value="Auth")
    else:
        executebuiltin('Addon.OpenSettings(plugin.video.plexkodiconnect)')
예제 #56
0
    def compare_artists(self, view):

        all_embyartistsIds = set()
        update_list = list()

        if self.pdialog:
            self.pdialog.update(heading=lang(29999), message="%s Artists..." % lang(33031))

        artists = dict(self.emby_db.get_checksum('MusicArtist'))
        album_artists = dict(self.emby_db.get_checksum('AlbumArtist'))
        emby_artists = self.emby.getArtists(view['id'], dialog=self.pdialog)

        for item in emby_artists['Items']:

            if self.should_stop():
                    return False

            item_id = item['Id']
            API = api.API(item)

            all_embyartistsIds.add(item_id)
            if item_id in artists:
                if artists[item_id] != API.get_checksum():
                    # Only update if artist is not in Kodi or checksum is different
                    update_list.append(item_id)
            elif album_artists.get(item_id) != API.get_checksum():
                # Only update if artist is not in Kodi or checksum is different
                update_list.append(item_id)

            #compare_to.pop(item_id, None)

        log.info("Update for Artist: %s", update_list)

        emby_items = self.emby.getFullItems(update_list)
        total = len(update_list)

        if self.pdialog:
            self.pdialog.update(heading="Processing Artists / %s items" % total)

        # Process additions and updates
        if emby_items:
            self.process_all("MusicArtist", "update", emby_items, total)
        # Process removals
        for artist in artists:
            if artist not in all_embyartistsIds and artists[artist] is not None:
                self.remove(artist)
예제 #57
0
 def content_pop(self, name):
     # It's possible for the time to be 0. It should be considered disabled in this case.
     if not self.pdialog and self.content_msg and self.new_time:
         dialog(type_="notification",
                heading="{emby}",
                message="%s %s" % (lang(33049), name),
                icon="{emby}",
                time=self.new_time,
                sound=False)
예제 #58
0
    def hasAccess(self):
        # hasAccess is verified in service.py
        result = self.doUtils.downloadUrl("{server}/emby/Users?format=json")

        if result == False:
            # Access is restricted, set in downloadutils.py via exception
            log("Access is restricted.", 1)
            self.HasAccess = False

        elif window('emby_online') != "true":
            # Server connection failed
            pass

        elif window('emby_serverStatus') == "restricted":
            log("Access is granted.", 1)
            self.HasAccess = True
            window('emby_serverStatus', clear=True)
            xbmcgui.Dialog().notification(lang(29999), lang(33007))