コード例 #1
0
def add_user():

    ''' Add or remove users from the default server session.
    '''
    if not window('jellyfin_online.bool'):
        return

    session = TheVoid('GetSession', {}).get()
    users = TheVoid('GetUsers', {'IsDisabled': False, 'IsHidden': False}).get()
    current = session[0]['AdditionalUsers']

    result = dialog("select", translate(33061), [translate(33062), translate(33063)] if current else [translate(33062)])

    if result < 0:
        return

    if not result:  # Add user
        eligible = [x for x in users if x['Id'] not in [current_user['UserId'] for current_user in current]]
        resp = dialog("select", translate(33064), [x['Name'] for x in eligible])

        if resp < 0:
            return

        user = eligible[resp]
        event('AddUser', {'Id': user['Id'], 'Add': True})
    else:  # Remove user
        resp = dialog("select", translate(33064), [x['UserName'] for x in current])

        if resp < 0:
            return

        user = current[resp]
        event('AddUser', {'Id': user['UserId'], 'Add': False})
コード例 #2
0
    def mapping(self):

        ''' Load the mapping of the full sync.
            This allows us to restore a previous sync.
        '''
        if self.sync['Libraries']:

            if not dialog("yesno", heading="{jellyfin}", line1=translate(33102)):

                if not dialog("yesno", heading="{jellyfin}", line1=translate(33173)):
                    dialog("ok", heading="{jellyfin}", line1=translate(33122))

                    raise LibraryException("ProgressStopped")
                else:
                    self.sync['Libraries'] = []
                    self.sync['RestorePoint'] = {}
        else:
            LOG.info("generate full sync")
            libraries = []

            for library in self.get_libraries():

                if library[2] in ('movies', 'tvshows', 'musicvideos', 'music', 'mixed'):
                    libraries.append({'Id': library[0], 'Name': library[1], 'Media': library[2]})

            libraries = self.select_libraries(libraries)

            if [x['Media'] for x in libraries if x['Media'] in ('movies', 'mixed')]:
                self.sync['Libraries'].append("Boxsets:")

        save_sync(self.sync)
コード例 #3
0
    def _get_server(self, method, data):

        ''' Retrieve the Emby server.
        '''
        try:
            if not data.get('ServerId'):
                raise Exception("ServerId undefined.")

            if method != 'LoadServer' and data['ServerId'] not in self.servers:

                try:
                    connect.Connect().register(data['ServerId'])
                    self.server_instance(data['ServerId'])
                except Exception as error:

                    LOG.error(error)
                    dialog("ok", heading="{emby}", line1=_(33142))

                    return

            server = Emby(data['ServerId']).get_client()
        except Exception:
            server = Emby().get_client()

        return server
コード例 #4
0
def changelog():
    
    version = client.get_version()
    resp = dialog("select", heading="{emby}", list=[version, _(33212)])

    if resp < 0:
        return

    if resp:
        src = "https://api.github.com/repos/MediaBrowser/plugin.video.emby/releases/latest"
    else:
        src = "https://api.github.com/repos/MediaBrowser/plugin.video.emby/releases/tags/%s" % version

    try:
        response = requests.get(src)
        response.raise_for_status()
        response.encoding = 'utf-8'
        response = response.json()
        response['body'] = "[B]%s[/B]\n\n%s" % (response['name'], response['body'])
        response['body'] = response['body'].replace('**:', '[/B]').replace('**', '[B]').replace('*', '-')
        dialog("textviewer", heading="{emby}", text=response['body'])
    except Exception as error:

        LOG.error(error)
        dialog("notification", heading="{emby}", message=_(33204), icon="{emby}", time=1000, sound=False)

    return
コード例 #5
0
    def cache_textures(self):
        ''' This method will sync all Kodi artwork to textures13.db
            and cache them locally. This takes diskspace!
        '''
        if not dialog("yesno", heading="{emby}", line1=_(33042)):
            LOG.info("<[ cache textures ]")

            return

        pdialog = xbmcgui.DialogProgress()
        pdialog.create(_('addon_name'), _(33045))

        if dialog("yesno", heading="{emby}", line1=_(33044)):
            self.delete_all_cache()

        self._cache_all_video_entries(pdialog)
        self._cache_all_music_entries(pdialog)
        pdialog.update(100, "%s: %s" % (_(33046), len(self.queue.queue)))

        while len(self.threads):

            if pdialog.iscanceled():
                break

            remaining = len(self.queue.queue)
            pdialog.update(100, "%s: %s" % (_(33046), remaining))
            LOG.info("Waiting for all threads to exit: %s (%s)",
                     len(self.threads), remaining)
            xbmc.sleep(500)

        pdialog.close()
コード例 #6
0
ファイル: setup.py プロジェクト: Astate/jellyfin-kodi
    def set_web_server(self):

        ''' Enable the webserver if not enabled. This is used to cache artwork.
            Will only test once, if it fails, user will be notified only once.
        '''
        if settings('enableTextureCache.bool'):

            get_setting = JSONRPC('Settings.GetSettingValue')

            if not self.get_web_server():

                set_setting = JSONRPC('Settings.SetSetingValue')
                set_setting.execute({'setting': "services.webserverport", 'value': 8080})
                set_setting.execute({'setting': "services.webserver", 'value': True})

                if not self.get_web_server():

                    settings('enableTextureCache.bool', False)
                    dialog("ok", heading="{emby}", line1=_(33103))
                    
                    return

            result = get_setting.execute({'setting': "services.webserverport"})
            settings('webServerPort', str(result['result']['value'] or ""))
            result = get_setting.execute({'setting': "services.webserverusername"})
            settings('webServerUser', str(result['result']['value'] or ""))
            result = get_setting.execute({'setting': "services.webserverpassword"})
            settings('webServerPass', str(result['result']['value'] or ""))
            settings('useWebServer.bool', True)
コード例 #7
0
    def run(self):

        while True:

            try:
                item = self.queue.get(timeout=3)
            except Queue.Empty:
                break

            time = self.music_time if item[0] == 'Audio' else self.video_time

            if time and (
                    not self.player.isPlayingVideo()
                    or xbmc.getCondVisibility('VideoPlayer.Content(livetv)')):
                dialog("notification",
                       heading="%s %s" % (_(33049), item[0]),
                       message=item[1],
                       icon="{emby}",
                       time=time,
                       sound=False)

            self.queue.task_done()

            if window('emby_should_stop.bool'):
                break

        LOG.info("--<[ q:notify/%s ]", id(self))
        self.is_done = True
コード例 #8
0
    def start(self):
        ''' Main sync process.
        '''
        LOG.info("starting sync with %s", self.sync['Libraries'])
        save_sync(self.sync)
        start_time = datetime.datetime.now()

        for library in list(self.sync['Libraries']):

            self.process_library(library)

            if not library.startswith(
                    'Boxsets:') and library not in self.sync['Whitelist']:
                self.sync['Whitelist'].append(library)

            self.sync['Libraries'].pop(self.sync['Libraries'].index(library))
            self._restore_point({})

        elapsed = datetime.datetime.now() - start_time
        settings('SyncInstallRunDone.bool', True)
        self.library.save_last_sync()
        save_sync(self.sync)

        xbmc.executebuiltin('UpdateLibrary(video)')
        dialog("notification",
               heading="{emby}",
               message="%s %s" % (_(33025), str(elapsed).split('.')[0]),
               icon="{emby}",
               sound=False)
        LOG.info("Full sync completed in: %s", str(elapsed).split('.')[0])
コード例 #9
0
    def get_fast_sync(self):

        new_fast_sync = compare_version(self.server['auth/server-version'],
                                        "4.2.0.23")
        enable_fast_sync = False

        if settings('SyncInstallRunDone.bool'):

            if settings('kodiCompanion.bool'):
                for plugin in self.server['api'].get_plugins():

                    if plugin['Name'] in ("Emby.Kodi Sync Queue",
                                          "Kodi companion"):
                        enable_fast_sync = True

                        break

                if new_fast_sync > 0:
                    self.fast_sync(enable_fast_sync)

                elif enable_fast_sync:

                    if not self.fast_sync_plugin():
                        dialog("ok", heading="{emby}", line1=_(33128))

                        raise Exception("Failed to retrieve latest updates")
                else:
                    raise LibraryException('CompanionMissing')

                LOG.info("--<[ retrieve changes ]")
コード例 #10
0
    def service(self):
        ''' Keeps the service monitor going.
            Exit on Kodi shutdown or profile switch.

            if profile switch happens more than once, 
            Threads depending on abortRequest will not trigger.
        '''
        self.monitor = objects.monitor.Monitor()
        self.monitor.service = self
        self.connect = connect.Connect()
        self.player = self['monitor'].player

        self._server()

        while self.running:
            if window('emby_online.bool'):

                if self['profile'] != window('emby_kodiProfile'):
                    LOG.info("[ profile switch ] %s", self['profile'])

                    break

                if self['player'].isPlaying(
                ) and self['player'].is_playing_file(
                        self['player'].get_playing_file()):
                    difference = datetime.today() - self['last_progress']

                    if difference.seconds > 4:
                        self['last_progress'] = datetime.today()

                        update = (datetime.today() -
                                  self['last_progress_report']).seconds > 40
                        event('ReportProgressRequested', {'Report': update})

                        if update:
                            self['last_progress_report'] = datetime.today()

            if not WEBSERVICE.is_alive():

                LOG.info("[ restarting due to socket disconnect ]")
                window('emby.restart.bool', True)

            if window('emby.restart.bool'):
                dialog("notification",
                       heading="{emby}",
                       message=_(33193),
                       icon="{emby}",
                       time=1000,
                       sound=False)

                raise Exception('RestartService')

            if self.waitForAbort(1):
                break

        self.shutdown()

        raise Exception("ExitService")
コード例 #11
0
ファイル: service.py プロジェクト: molandtoxx/jellyfin-kodi
    def service(self):
        ''' Keeps the service monitor going.
            Exit on Kodi shutdown or profile switch.

            if profile switch happens more than once,
            Threads depending on abortRequest will not trigger.
        '''
        self.monitor = monitor.Monitor()
        player = self.monitor.player
        self.connect = connect.Connect()
        self.start_default()

        self.settings['mode'] = settings('useDirectPaths')

        while self.running:
            if window('jellyfin_online.bool'):

                if self.settings['profile'] != window('jellyfin_kodiProfile'):
                    LOG.info("[ profile switch ] %s", self.settings['profile'])

                    break

                if player.isPlaying() and player.is_playing_file(
                        player.get_playing_file()):
                    difference = datetime.today(
                    ) - self.settings['last_progress']

                    if difference.seconds > 10:
                        self.settings['last_progress'] = datetime.today()

                        update = (datetime.today() -
                                  self.settings['last_progress_report']
                                  ).seconds > 250
                        event('ReportProgressRequested', {'Report': update})

                        if update:
                            self.settings[
                                'last_progress_report'] = datetime.today()

            if window('jellyfin.restart.bool'):

                window('jellyfin.restart', clear=True)
                dialog("notification",
                       heading="{jellyfin}",
                       message=translate(33193),
                       icon="{jellyfin}",
                       time=1000,
                       sound=False)

                raise Exception('RestartService')

            if self.waitForAbort(1):
                break

        self.shutdown()

        raise Exception("ExitService")
コード例 #12
0
    def startup(self):
        ''' Run at startup. 
            Check databases. 
            Check for the server plugin.
        '''
        self.started = True
        Views().get_views()
        Views().get_nodes()

        try:
            if get_sync()['Libraries']:
                self.sync_libraries()

            elif not settings('SyncInstallRunDone.bool'):

                with self.sync(self, self.server) as sync:
                    sync.libraries()

                Views().get_nodes()
                xbmc.executebuiltin('ReloadSkin()')

                return True

            self.get_fast_sync()

            return True
        except LibraryException as error:
            LOG.error(error.status)

            if error.status in 'SyncLibraryLater':

                dialog("ok", heading="{emby}", line1=_(33129))
                settings('SyncInstallRunDone.bool', True)
                sync = get_sync()
                sync['Libraries'] = []
                save_sync(sync)

                return True

            elif error.status == 'CompanionMissing':

                dialog("ok", heading="{emby}", line1=_(33099))
                settings('kodiCompanion.bool', False)

                return True

            elif error.status == 'StopWriteCalled':
                self.verify_libs = True

            raise

        except Exception as error:
            LOG.exception(error)

        return False
コード例 #13
0
ファイル: setup.py プロジェクト: nvllsvm/jellyfin-kodi
    def _is_mode(self):
        ''' Setup playback mode. If native mode selected, check network credentials.
        '''
        value = dialog("yesno",
                       heading=_('playback_mode'),
                       line1=_(33035),
                       nolabel=_('addon_mode'),
                       yeslabel=_('native_mode'))

        settings('useDirectPaths', value="1" if value else "0")

        if value:
            dialog("ok", heading="{jellyfin}", line1=_(33145))
コード例 #14
0
    def __init__(self, library, server):
        ''' You can call all big syncing methods here. 
            Initial, update, repair, remove.
        '''
        self.__dict__ = self._shared_state

        if self.running:
            dialog("ok", heading="{emby}", line1=_(33197))

            raise Exception("Sync is already running.")

        self.library = library
        self.server = server
コード例 #15
0
    def process_library(self, library_id):
        ''' Add a library by it's id. Create a node and a playlist whenever appropriate.
        '''
        media = {
            'movies': self.movies,
            'musicvideos': self.musicvideos,
            'tvshows': self.tvshows,
            'music': self.music
        }
        try:
            if library_id.startswith('Boxsets:'):

                if library_id.endswith('Refresh'):
                    self.refresh_boxsets()
                else:
                    self.boxsets(
                        library_id.split('Boxsets:')[1]
                        if len(library_id) > len('Boxsets:') else None)

                return

            library = self.server.jellyfin.get_item(
                library_id.replace('Mixed:', ""))

            if library_id.startswith('Mixed:'):
                for mixed in ('movies', 'tvshows'):

                    media[mixed](library)
                    self.sync['RestorePoint'] = {}
            else:
                if library['CollectionType']:
                    settings('enableMusic.bool', True)

                media[library['CollectionType']](library)
        except LibraryException as error:

            if error.status == 'StopCalled':
                save_sync(self.sync)

                raise

        except Exception as error:
            LOG.exception(error)

            if 'Failed to validate path' not in error:

                dialog("ok", heading="{jellyfin}", line1=translate(33119))
                LOG.error("full sync exited unexpectedly")
                save_sync(self.sync)

            raise
コード例 #16
0
ファイル: full_sync.py プロジェクト: libanp/plugin.video.emby
    def __init__(self, library, library_id=None, update=False):

        ''' Map the syncing process and start the sync. Ensure only one sync is running.
        '''
        self.__dict__ = self._shared_state
        window('emby_sync.bool', True)

        if not settings('dbSyncScreensaver.bool'):

            xbmc.executebuiltin('InhibitIdleShutdown(true)')
            self.screensaver = get_screensaver()
            set_screensaver(value="")

        if not self.running:

            self.running = True
            self.library = library
            self.direct_path = settings('useDirectPaths') == "1"
            self.update_library = update
            self.server = Emby()
            self.sync = get_sync()

            if library_id:
                libraries = library_id.split(',')

                for selected in libraries:

                    if selected not in [x.replace('Mixed:', "") for x in self.sync['Libraries']]:
                        library = self.get_libraries(selected)

                        if library:

                            self.sync['Libraries'].append("Mixed:%s" % selected if library[1] == 'mixed' else selected)

                            if library[1] in ('mixed', 'movies'):
                                self.sync['Libraries'].append('Boxsets:%s' % selected)
                        else:
                            self.sync['Libraries'].append(selected)
            else:
                self.mapping()

            xmls.sources()

            if not xmls.advanced_settings() and self.sync['Libraries']:
                self.start()
            else:
                self.running = False
        else:
            dialog("ok", heading="{emby}", line1=_(33197))

            raise Exception("Sync is already running.")
コード例 #17
0
    def check_update(self, forced=False):
        ''' Check for objects build version and compare.
            This pulls a dict that contains all the information for the build needed.
        '''
        LOG.info("--[ check updates/%s ]", objects.version)
        kodi = "DEV" if settings('devMode.bool') else xbmc.getInfoLabel(
            'System.BuildVersion')

        try:
            versions = requests.get(
                'http://kodi.emby.media/Public%20testing/Dependencies/databases.json'
            ).json()
            build = find(versions, kodi)

            if not build:
                raise Exception("build %s incompatible?!" % kodi)

            label, zipfile = build.split('-', 1)

            if label == 'DEV' and forced:
                LOG.info("--[ force/objects/%s ]", label)

            elif label == objects.version:
                LOG.info("--[ objects/%s ]", objects.version)

                return False

            get_objects(zipfile, label + '.zip')
            self.reload_objects()

            dialog("notification",
                   heading="{emby}",
                   message=_(33156),
                   icon="{emby}")
            LOG.info("--[ new objects/%s ]", objects.version)

            try:
                if compare_version(self.settings['addon_version'],
                                   objects.embyversion) < 0:
                    dialog("ok",
                           heading="{emby}",
                           line1="%s %s" % (_(33160), objects.embyversion))
            except Exception:
                pass

        except Exception as error:
            LOG.exception(error)

        return True
コード例 #18
0
ファイル: __init__.py プロジェクト: scottwedge/jellyfin-kodi
def reset_kodi():

    with Database() as videodb:
        videodb.cursor.execute(
            "SELECT tbl_name FROM sqlite_master WHERE type='table'")

        for table in videodb.cursor.fetchall():
            name = table[0]

            if name != 'version':
                videodb.cursor.execute("DELETE FROM " + name)

    if settings('enableMusic.bool') or dialog(
            "yesno", heading="{jellyfin}", line1=translate(33162)):

        with Database('music') as musicdb:
            musicdb.cursor.execute(
                "SELECT tbl_name FROM sqlite_master WHERE type='table'")

            for table in musicdb.cursor.fetchall():
                name = table[0]

                if name != 'version':
                    musicdb.cursor.execute("DELETE FROM " + name)

    LOG.info("[ reset kodi ]")
コード例 #19
0
    def _set_intros(self, item):

        ''' if we have any play them when the movie/show is not being resumed.
        '''
        intros = TheVoid('GetIntros', {'ServerId': self.server_id, 'Id': item['Id']}).get()

        if intros['Items']:
            enabled = True

            if settings('askCinema') == "true":

                resp = dialog("yesno", heading="{emby}", line1=_(33016))
                if not resp:

                    enabled = False
                    LOG.info("Skip trailers.")

            if enabled:
                for intro in intros['Items']:

                    listitem = xbmcgui.ListItem()
                    LOG.info("[ intro/%s ] %s", intro['Id'], intro['Name'])

                    play = playutils.PlayUtils(intro, False, self.server_id, self.server)
                    source = play.select_source(play.get_sources())
                    self.set_listitem(intro, listitem, intro=True)
                    listitem.setPath(intro['PlaybackInfo']['Path'])
                    playutils.set_properties(intro, intro['PlaybackInfo']['Method'], self.server_id)

                    self.stack.append([intro['PlaybackInfo']['Path'], listitem])

                window('emby.skip.%s' % intro['Id'], value="true")
コード例 #20
0
    def _set_intros(self, item):

        ''' if we have any play them when the movie/show is not being resumed.
        '''
        intros = self.api_client.get_intros(item['Id'])

        if intros['Items']:
            enabled = True

            if settings('askCinema') == "true":

                resp = dialog("yesno", "{jellyfin}", translate(33016))
                if not resp:

                    enabled = False
                    LOG.info("Skip trailers.")

            if enabled:
                for intro in intros['Items']:

                    listitem = xbmcgui.ListItem()
                    LOG.info("[ intro/%s ] %s", intro['Id'], intro['Name'])

                    play = playutils.PlayUtils(intro, False, self.server_id, self.server, self.api_client)
                    play.select_source(play.get_sources())
                    self.set_listitem(intro, listitem, intro=True)
                    listitem.setPath(intro['PlaybackInfo']['Path'])
                    playutils.set_properties(intro, intro['PlaybackInfo']['Method'], self.server_id)

                    self.stack.append([intro['PlaybackInfo']['Path'], listitem])

                window('jellyfin.skip.%s' % intro['Id'], value="true")
コード例 #21
0
ファイル: library.py プロジェクト: Lumenol/jellyfin-kodi
    def fast_sync(self):
        ''' Movie and userdata not provided by server yet.
        '''
        last_sync = settings('LastIncrementalSync')
        include = []
        filters = ["tvshows", "boxsets", "musicvideos", "music", "movies"]
        sync = get_sync()
        LOG.info("--[ retrieve changes ] %s", last_sync)

        # Get the item type of each synced library and build list of types to request
        for item_id in sync['Whitelist']:
            library = self.server.jellyfin.get_item(item_id)
            library_type = library.get('CollectionType')
            if library_type in filters:
                include.append(library_type)

        # Include boxsets if movies are synced
        if 'movies' in include:
            include.append('boxsets')

        # Filter down to the list of library types we want to exclude
        query_filter = list(set(filters) - set(include))

        try:
            updated = []
            userdata = []
            removed = []

            # Get list of updates from server for synced library types and populate work queues
            result = self.server.jellyfin.get_sync_queue(
                last_sync, ",".join([x for x in query_filter]))
            updated.extend(result['ItemsAdded'])
            updated.extend(result['ItemsUpdated'])
            userdata.extend(result['UserDataChanged'])
            removed.extend(result['ItemsRemoved'])

            total = len(updated) + len(userdata)

            if total > int(settings('syncIndicator') or 99):
                ''' Inverse yes no, in case the dialog is forced closed by Kodi.
                '''
                if dialog("yesno",
                          "{jellyfin}",
                          translate(33172).replace('{number}', str(total)),
                          nolabel=translate(107),
                          yeslabel=translate(106)):
                    LOG.warning("Large updates skipped.")

                    return True

            self.updated(updated)
            self.userdata(userdata)
            self.removed(removed)

        except Exception as error:
            LOG.exception(error)

            return False

        return True
コード例 #22
0
    def select_libraries(self, libraries):
        ''' Select all or certain libraries to be whitelisted.
        '''

        choices = [x['Name'] for x in libraries]
        choices.insert(0, translate(33121))
        selection = dialog("multi", translate(33120), choices)

        if selection is None:
            raise LibraryException('LibrarySelection')
        elif not selection:
            LOG.info("Nothing was selected.")

            raise LibraryException('SyncLibraryLater')

        if 0 in selection:
            selection = list(range(1, len(libraries) + 1))

        selected_libraries = []

        for x in selection:
            library = libraries[x - 1]

            if library['Media'] != 'mixed':
                selected_libraries.append(library['Id'])
            else:
                selected_libraries.append("Mixed:%s" % library['Id'])

        self.sync['Libraries'] = selected_libraries

        return [libraries[x - 1] for x in selection]
コード例 #23
0
    def run(self):
        import objects
        ''' Workaround for playing folders only (context menu on a series/season folder > play)
            Due to plugin paths being returned within the strm, the entries are mislabelled.
            Queue items after the first item was setup and started playing via plugin above.
        '''
        xbmc.sleep(200)  # Let Kodi catch up
        LOG.info("-->[ folder play ]")
        play = None
        position = 1  # play folder should always create a new playlist.

        while True:
            if not window('emby.playlist.plugin.bool'
                          ):  # default.py wait for initial item to start up
                try:
                    try:
                        params = self.server.queue.get(timeout=0.01)
                    except Queue.Empty:
                        break

                    server = params.get('server')

                    if not server and not window('emby_online.bool'):
                        dialog("notification",
                               heading="{emby}",
                               message=_(33146),
                               icon=xbmcgui.NOTIFICATION_ERROR)

                        raise Exception("NotConnected")

                    play = objects.PlayStrm(params, server)
                    position = play.play_folder(position)

                except Exception as error:
                    LOG.exception(error)

                    xbmc.Player().stop()  # mute failed playback pop up
                    xbmc.PlayList(xbmc.PLAYLIST_VIDEO).clear()
                    self.server.queue.queue.clear()

                    break

                self.server.queue.task_done()

        self.server.threads.remove(self)
        self.server.pending = []
        LOG.info("--<[ folder play ]")
コード例 #24
0
    def onSettingsChanged(self):
        ''' React to setting changes that impact window values.
        '''
        if window('emby_should_stop.bool'):
            return

        if settings('logLevel') != self['log_level']:

            log_level = settings('logLevel')
            window('emby_logLevel', str(log_level))
            self['logLevel'] = log_level
            LOG.warn("New log level: %s", log_level)

        if settings('enableContext.bool') != self['enable_context']:

            window('emby_context', settings('enableContext'))
            self['enable_context'] = settings('enableContext.bool')
            LOG.warn("New context setting: %s", self['enable_context'])

        if settings('enableContextTranscode.bool'
                    ) != self['enable_context_transcode']:

            window('emby_context_transcode',
                   settings('enableContextTranscode'))
            self['enable_context_transcode'] = settings(
                'enableContextTranscode.bool')
            LOG.warn("New context transcode setting: %s",
                     self['enable_context_transcode'])

        if settings('useDirectPaths') != self['mode'] and self[
                'library'] and self['library'].started:

            self['mode'] = settings('useDirectPaths')
            LOG.warn("New playback mode setting: %s", self['mode'])

            if not self['mode_warn']:

                self['mode_warn'] = True
                if dialog("yesno", heading="{emby}", line1=_(33118)):
                    xbmc.executebuiltin(
                        'RunPlugin(plugin://plugin.video.emby/?mode=reset)')

        if settings('kodiCompanion.bool') != self['kodi_companion']:
            self['kodi_companion'] = settings('kodiCompanion.bool')

            if not self['kodi_companion']:
                dialog("ok", heading="{emby}", line1=_(33138))
コード例 #25
0
ファイル: library.py プロジェクト: loidy/jellyfin-kodi
    def select_libraries(self, mode=None):

        ''' Select from libraries synced. Either update or repair libraries.
            Send event back to service.py
        '''
        modes = {
            'SyncLibrarySelection': 'SyncLibrary',
            'RepairLibrarySelection': 'RepairLibrary',
            'AddLibrarySelection': 'SyncLibrary',
            'RemoveLibrarySelection': 'RemoveLibrary'
        }
        sync = get_sync()
        whitelist = [x.replace('Mixed:', "") for x in sync['Whitelist']]
        libraries = []

        with Database('jellyfin') as jellyfindb:
            db = jellyfin_db.JellyfinDatabase(jellyfindb.cursor)

            if mode in ('SyncLibrarySelection', 'RepairLibrarySelection', 'RemoveLibrarySelection'):
                for library in sync['Whitelist']:

                    name = db.get_view_name(library.replace('Mixed:', ""))
                    libraries.append({'Id': library, 'Name': name})
            else:
                available = [x for x in sync['SortedViews'] if x not in whitelist]

                for library in available:
                    name, media = db.get_view(library)

                    if media in ('movies', 'tvshows', 'musicvideos', 'mixed', 'music'):
                        libraries.append({'Id': library, 'Name': name})

        choices = [x['Name'] for x in libraries]
        choices.insert(0, translate(33121))

        titles = {
            "RepairLibrarySelection": 33199,
            "SyncLibrarySelection": 33198,
            "RemoveLibrarySelection": 33200,
            "AddLibrarySelection": 33120
        }
        title = titles.get(mode, "Failed to get title {}".format(mode))
        
        selection = dialog("multi", translate(title), choices)

        if selection is None:
            return

        if 0 in selection:
            selection = list(range(1, len(libraries) + 1))

        selected_libraries = []

        for x in selection:

            library = libraries[x - 1]
            selected_libraries.append(library['Id'])

        event(modes[mode], {'Id': ','.join([libraries[x - 1]['Id'] for x in selection]), 'Update': mode == 'SyncLibrarySelection'})
コード例 #26
0
ファイル: service.py プロジェクト: molandtoxx/jellyfin-kodi
    def onSettingsChanged(self):
        ''' React to setting changes that impact window values.
        '''
        if window('jellyfin_should_stop.bool'):
            return

        if settings('logLevel') != self.settings['log_level']:

            log_level = settings('logLevel')
            window('jellyfin_logLevel', str(log_level))
            self.settings['logLevel'] = log_level
            LOG.info("New log level: %s", log_level)

        if settings('enableContext.bool') != self.settings['enable_context']:

            window('jellyfin_context', settings('enableContext'))
            self.settings['enable_context'] = settings('enableContext.bool')
            LOG.info("New context setting: %s",
                     self.settings['enable_context'])

        if settings('enableContextTranscode.bool'
                    ) != self.settings['enable_context_transcode']:

            window('jellyfin_context_transcode',
                   settings('enableContextTranscode'))
            self.settings['enable_context_transcode'] = settings(
                'enableContextTranscode.bool')
            LOG.info("New context transcode setting: %s",
                     self.settings['enable_context_transcode'])

        if settings('useDirectPaths'
                    ) != self.settings['mode'] and self.library_thread.started:

            self.settings['mode'] = settings('useDirectPaths')
            LOG.info("New playback mode setting: %s", self.settings['mode'])

            if not self.settings.get('mode_warn'):

                self.settings['mode_warn'] = True
                dialog("yesno", heading="{jellyfin}", line1=translate(33118))

        if settings('kodiCompanion.bool') != self.settings['kodi_companion']:
            self.settings['kodi_companion'] = settings('kodiCompanion.bool')

            if not self.settings['kodi_companion']:
                dialog("ok", heading="{jellyfin}", line1=translate(33138))
コード例 #27
0
ファイル: library.py プロジェクト: loidy/jellyfin-kodi
    def fast_sync(self):

        ''' Movie and userdata not provided by server yet.
        '''
        last_sync = settings('LastIncrementalSync')
        filters = ["tvshows", "boxsets", "musicvideos", "music", "movies"]
        sync = get_sync()
        LOG.info("--[ retrieve changes ] %s", last_sync)

        try:
            updated = []
            userdata = []
            removed = []

            for media in filters:
                result = self.server.jellyfin.get_sync_queue(last_sync, ",".join([x for x in filters if x != media]))
                updated.extend(result['ItemsAdded'])
                updated.extend(result['ItemsUpdated'])
                userdata.extend(result['UserDataChanged'])
                removed.extend(result['ItemsRemoved'])

            total = len(updated) + len(userdata)

            if total > int(settings('syncIndicator') or 99):

                ''' Inverse yes no, in case the dialog is forced closed by Kodi.
                '''
                if dialog("yesno", heading="{jellyfin}", line1=translate(33172).replace('{number}', str(total)), nolabel=translate(107), yeslabel=translate(106)):
                    LOG.warning("Large updates skipped.")

                    return True

            self.updated(updated)
            self.userdata(userdata)
            self.removed(removed)

            """
            result = self.server.jellyfin.get_sync_queue(last_sync)
            self.userdata(result['UserDataChanged'])
            self.removed(result['ItemsRemoved'])


            filters.extend(["tvshows", "boxsets", "musicvideos", "music"])

            # Get only movies.
            result = self.server.jellyfin.get_sync_queue(last_sync, ",".join(filters))
            self.updated(result['ItemsAdded'])
            self.updated(result['ItemsUpdated'])
            self.userdata(result['UserDataChanged'])
            self.removed(result['ItemsRemoved'])
            """

        except Exception as error:
            LOG.exception(error)

            return False

        return True
コード例 #28
0
    def start(self):
        
        ''' Main sync process.
        '''
        LOG.info("starting sync with %s", self.sync['Libraries'])
        save_sync(self.sync)
        start_time = datetime.datetime.now()

        if not settings('dbSyncScreensaver.bool'):

            xbmc.executebuiltin('InhibitIdleShutdown(true)')
            screensaver = get_screensaver()
            set_screensaver(value="")

        try:
            for library in list(self.sync['Libraries']):

                self.process_library(library)

                if not library.startswith('Boxsets:') and library not in self.sync['Whitelist']:
                    self.sync['Whitelist'].append(library)

                self.sync['Libraries'].pop(self.sync['Libraries'].index(library))
                self.sync['RestorePoint'] = {}
        except Exception as error:

            if not settings('dbSyncScreensaver.bool'):

                xbmc.executebuiltin('InhibitIdleShutdown(false)')
                set_screensaver(value=screensaver)

            raise

        elapsed = datetime.datetime.now() - start_time
        settings('SyncInstallRunDone.bool', True)
        self.library.save_last_sync()
        save_sync(self.sync)

        xbmc.executebuiltin('UpdateLibrary(video)')
        dialog("notification", heading="{emby}", message="%s %s" % (_(33025), str(elapsed).split('.')[0]),
               icon="{emby}", sound=False)
        LOG.info("Full sync completed in: %s", str(elapsed).split('.')[0])
コード例 #29
0
    def delete_item(self):

        delete = True

        if not settings('skipContextMenu.bool'):

            if not dialog("yesno", "{jellyfin}", translate(33015)):
                delete = False

        if delete:
            TheVoid('DeleteItem', {'ServerId': self.server, 'Id': self.item['Id']})
コード例 #30
0
    def delete_item(self):

        delete = True

        if not settings('skipContextMenu.bool'):

            if not dialog("yesno", heading="{emby}", line1=_(33015)):
                delete = False

        if delete:
            TheVoid('DeleteItem', {'ServerId': self.server, 'Id': self.item['Id']})