Exemplo n.º 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})
Exemplo n.º 2
0
    def get_sources(self, source_id=None):
        ''' Return sources based on the optional source_id or the device profile.
        '''
        params = {
            'ServerId': self.info['ServerId'],
            'Id': self.item['Id'],
            'Profile': self.get_device_profile()
        }
        info = TheVoid('GetPlaybackInfo', params).get()
        LOG.info(info)
        self.info['PlaySessionId'] = info['PlaySessionId']
        sources = []

        if not info.get('MediaSources'):
            LOG.info("No MediaSources found.")

        elif source_id:
            for source in info:

                if source['Id'] == source_id:
                    sources.append(source)

                    break

        elif not self.is_selection(info) or len(info['MediaSources']) == 1:

            LOG.info("Skip source selection.")
            sources.append(info['MediaSources'][0])

        else:
            sources.extend([x for x in info['MediaSources']])

        return sources
Exemplo n.º 3
0
    def action_menu(self):

        selected = self._selected_option.decode('utf-8')

        if selected == OPTIONS['Refresh']:
            TheVoid('RefreshItem', {
                'ServerId': self.server,
                'Id': self.item['Id']
            })

        elif selected == OPTIONS['AddFav']:
            TheVoid('FavoriteItem', {
                'ServerId': self.server,
                'Id': self.item['Id'],
                'Favorite': True
            })

        elif selected == OPTIONS['RemoveFav']:
            TheVoid('FavoriteItem', {
                'ServerId': self.server,
                'Id': self.item['Id'],
                'Favorite': False
            })

        elif selected == OPTIONS['Addon']:
            xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)')

        elif selected == OPTIONS['Delete']:
            self.delete_item()
Exemplo n.º 4
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")
Exemplo n.º 5
0
    def transcode(self):

        item = TheVoid('GetItem', {
            'Id': self.item['Id'],
            'ServerId': self.server
        }).get()
        Actions(self.server).play(item, self.kodi_id, True)
    def __init__(self, server_id=None):

        self.server_id = server_id or None
        self.server = TheVoid('GetServerAddress', {
            'ServerId': self.server_id
        }).get()
        self.stack = []
Exemplo n.º 7
0
    def __init__(self, server_id=None, server=None, *args, **kwargs):

        self.server_id = server_id or None
        self.server = server or TheVoid('GetServerAddress', {
            'ServerId': self.server_id
        }).get()
        self.stack = []
Exemplo n.º 8
0
def get_fanart(item_id, path, server_id=None):

    ''' Get extra fanart for listitems. This is called by skinhelper.
        Images are stored locally, due to the Kodi caching system.
    '''
    if not item_id and 'plugin.video.emby' in path:
        item_id = path.split('/')[-2]

    if not item_id:
        return

    LOG.info("[ extra fanart ] %s", item_id)
    objects = Objects()
    list_li = []
    directory = xbmc.translatePath("special://thumbnails/emby/%s/" % item_id).decode('utf-8')
    server = TheVoid('GetServerAddress', {'ServerId': server_id}).get()

    if not xbmcvfs.exists(directory):

        xbmcvfs.mkdirs(directory)
        item = TheVoid('GetItem', {'ServerId': server_id, 'Id': item_id}).get()
        obj = objects.map(item, 'Artwork')
        backdrops = api.API(item, server).get_all_artwork(obj)
        tags = obj['BackdropTags']

        for index, backdrop in enumerate(backdrops):

            tag = tags[index]
            fanart = os.path.join(directory, "fanart%s.jpg" % tag)
            li = xbmcgui.ListItem(tag, path=fanart)
            xbmcvfs.copy(backdrop, fanart)
            list_li.append((fanart, li, False))
    else:
        LOG.debug("cached backdrop found")
        dirs, files = xbmcvfs.listdir(directory)

        for file in files:
            fanart = os.path.join(directory, file.decode('utf-8'))
            li = xbmcgui.ListItem(file, path=fanart)
            list_li.append((fanart, li, False))

    xbmcplugin.addDirectoryItems(int(sys.argv[1]), list_li, len(list_li))
    xbmcplugin.endOfDirectory(int(sys.argv[1]))
Exemplo n.º 9
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']})
Exemplo n.º 10
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']})
Exemplo n.º 11
0
def get_video_extras(item_id, path, server_id=None):
    ''' Returns the video files for the item as plugin listing, can be used
        to browse actual files or video extras, etc.
    '''
    if not item_id and 'plugin.video.jellyfin' in path:
        item_id = path.split('/')[-2]

    if not item_id:
        return

    item = TheVoid('GetItem', {'ServerId': server_id, 'Id': item_id}).get()
    # TODO
    """
Exemplo n.º 12
0
    def __init__(self, item, force_transcode=False, server_id=None, server=None, token=None):

        ''' Item will be updated with the property PlaybackInfo, which
            holds all the playback information.
        '''
        item['PlaybackInfo'] = {}
        self.info = {
            'Item': item,
            'ServerId': server_id,
            'ServerAddress': server,
            'ForceTranscode': force_transcode,
            'Token': token or TheVoid('GetToken', {'ServerId': server_id}).get()
        }
Exemplo n.º 13
0
    def live_stream(self, source):
        ''' Get live stream media info.
        '''
        params = {
            'ServerId': self.info['ServerId'],
            'Id': self.item['Id'],
            'Profile': self.get_device_profile(),
            'PlaySessionId': self.info['PlaySessionId'],
            'Token': source['OpenToken']
        }
        info = TheVoid('GetLiveStream', params).get()
        LOG.info(info)

        if info['MediaSource'].get('RequiresClosing'):
            self.info['LiveStreamId'] = source['LiveStreamId']

        return info['MediaSource']
Exemplo n.º 14
0
    def _set_additional_parts(self, item_id):

        ''' Create listitems and add them to the stack of playlist.
        '''
        parts = TheVoid('GetAdditionalParts', {'ServerId': self.server_id, 'Id': item_id}).get()

        for part in parts['Items']:

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

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

            self.stack.append([part['PlaybackInfo']['Path'], listitem])
Exemplo n.º 15
0
    def __init__(self, transcode=False, delete=False):

        try:
            self.kodi_id = sys.listitem.getVideoInfoTag().getDbId() or None
            self.media = self.get_media_type()
            self.server = sys.listitem.getProperty('embyserver') or None
            item_id = sys.listitem.getProperty('embyid')
        except AttributeError:
            self.server = None

            if xbmc.getInfoLabel('ListItem.Property(embyid)'):
                item_id = xbmc.getInfoLabel('ListItem.Property(embyid)')
            else:
                self.kodi_id = xbmc.getInfoLabel('ListItem.DBID')
                self.media = xbmc.getInfoLabel('ListItem.DBTYPE')
                item_id = None

        if self.server or item_id:
            self.item = TheVoid('GetItem', {
                'ServerId': self.server,
                'Id': item_id
            }).get()
        else:
            self.item = self.get_item_id()

        if self.item:

            if transcode:
                self.transcode()

            elif delete:
                self.delete_item()

            elif self.select_menu():
                self.action_menu()

                if self._selected_option.decode('utf-8') in (
                        OPTIONS['Delete'], OPTIONS['AddFav'],
                        OPTIONS['RemoveFav']):

                    xbmc.sleep(500)
                    xbmc.executebuiltin('Container.Refresh')
Exemplo n.º 16
0
    def __init__(self, play=False, transcode=False, delete=False):

        self.server = None
        self.kodi_id = None
        self.media = None

        try:
            self.kodi_id = max(
                sys.listitem.getVideoInfoTag().getDbId(), 0) or max(
                    sys.listitem.getMusicInfoTag().getDbId(), 0) or None
            self.media = self.get_media_type()
            self.server = sys.listitem.getProperty('embyserver') or None
            item_id = sys.listitem.getProperty('embyid')
        except AttributeError:

            if xbmc.getInfoLabel('ListItem.Property(embyid)'):
                item_id = xbmc.getInfoLabel('ListItem.Property(embyid)')
            else:
                self.kodi_id = xbmc.getInfoLabel('ListItem.DBID')
                self.media = xbmc.getInfoLabel('ListItem.DBTYPE')
                item_id = None

        if self.server or item_id:
            self.item = TheVoid('GetItem', {
                'ServerId': self.server,
                'Id': item_id
            }).get()
        else:
            self.item = self.get_item_id()

        if self.item:

            if play or transcode:
                self.play(transcode)

            elif delete:
                self.delete_item()

            elif self.select_menu():
                self.action_menu()
Exemplo n.º 17
0
    def __init__(self, params, server_id=None):

        ''' Workflow: Strm that calls our webservice in database. When played,
            the webserivce returns a dummy file to play. Meanwhile,
            PlayStrm adds the real listitems for items to play to the playlist.
        '''
        self.info = {
            'Item': None,
            'Id': params.get('id'),
            'DbId': params.get('dbid'),
            'Transcode': params.get('transcode'),
            'ServerId': server_id,
            'Server': TheVoid('GetServerAddress', {'ServerId': server_id}).get(),
        }
        if self.info['Transcode'] is None:
             self.info['Transcode'] = settings('playFromTranscode.bool') if settings('playFromStream.bool') else None

        self.actions = Actions(server_id, self.info['Server'])
        self.set_listitem = self.actions.set_listitem
        self.params = params
        self._detect_play()
        LOG.info("[ play simple ]")
Exemplo n.º 18
0
def browse_letters(media, view_id, server_id=None):
    ''' Display letters as options.
    '''
    letters = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get()
    xbmcplugin.setPluginCategory(int(sys.argv[1]), view['Name'])

    for node in letters:

        params = {
            'id': view_id,
            'mode': "browse",
            'type': media,
            'folder': 'firstletter-%s' % node,
            'server': server_id
        }
        path = "%s?%s" % ("plugin://plugin.video.jellyfin/", urlencode(params))
        directory(node, path)

    xbmcplugin.setContent(int(sys.argv[1]), 'files')
    xbmcplugin.endOfDirectory(int(sys.argv[1]))
Exemplo n.º 19
0
def browse_subfolders(media, view_id, server_id=None):
    ''' Display submenus for jellyfin views.
    '''
    from views import DYNNODES

    view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get()
    xbmcplugin.setPluginCategory(int(sys.argv[1]), view['Name'])
    nodes = DYNNODES[media]

    for node in nodes:

        params = {
            'id': view_id,
            'mode': "browse",
            'type': media,
            'folder': view_id if node[0] == 'all' else node[0],
            'server': server_id
        }
        path = "%s?%s" % ("plugin://plugin.video.jellyfin/", urlencode(params))
        directory(node[1] or view['Name'], path)

    xbmcplugin.setContent(int(sys.argv[1]), 'files')
    xbmcplugin.endOfDirectory(int(sys.argv[1]))
Exemplo n.º 20
0
def add_user(permanent=False):

    ''' Add or remove users from the default server session.
        permanent=True from the add-on settings.
    '''
    if not window('emby_online.bool'):
        return

    session = TheVoid('GetSession', {}).get()
    users = TheVoid('GetUsers', {'IsDisabled': False, 'IsHidden': False}).get()

    for user in users:

        if user['Id'] == session[0]['UserId']:
            users.remove(user)

            break

    while True:

        session = TheVoid('GetSession', {}).get()
        additional = current = session[0]['AdditionalUsers']
        add_session = True

        if permanent:

            perm_users = settings('addUsers').split(',') if settings('addUsers') else []
            current = []

            for user in users:
                for perm_user in perm_users:

                    if user['Id'] == perm_user:
                        current.append({'UserName': user['Name'], 'UserId': user['Id']})

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

        if result < 0:
            break

        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", _(33064), [x['Name'] for x in eligible])

            if resp < 0:
                break

            user = eligible[resp]

            if permanent:

                perm_users.append(user['Id'])
                settings('addUsers', ','.join(perm_users))

                if user['Id'] in [current_user['UserId'] for current_user in additional]:
                    add_session = False
            
            if add_session:
                event('AddUser', {'Id': user['Id'], 'Add': True})

            dialog("notification", heading="{emby}", message="%s %s" % (_(33067), user['Name']), icon="{emby}", time=1000, sound=False)
        else: # Remove user
            resp = dialog("select", _(33064), [x['UserName'] for x in current])

            if resp < 0:
                break

            user = current[resp]

            if permanent:

                perm_users.remove(user['UserId'])
                settings('addUsers', ','.join(perm_users))
            
            if add_session:
                event('AddUser', {'Id': user['UserId'], 'Add': False})

            dialog("notification", heading="{emby}", message="%s %s" % (_(33066), user['UserName']), icon="{emby}", time=1000, sound=False)
Exemplo n.º 21
0
 def _get_item(self):
     self.info['Item'] = TheVoid('GetItem', {'Id': self.info['Id'], 'ServerId': self.info['Server']}).get()
Exemplo n.º 22
0
    def __init__(self):

        ''' Parse the parameters. Reroute to our service.py
            where user is fully identified already.
        '''
        base_url = sys.argv[0]
        path = sys.argv[2]

        try:
            params = dict(urlparse.parse_qsl(path[1:]))
        except Exception:
            params = {}

        mode = params.get('mode')
        server = params.get('server')

        if server == 'None':
            server = None

        LOG.warn("path: %s params: %s", path, json.dumps(params, indent=4))

        if '/extrafanart' in base_url:

            emby_path = path[1:]
            emby_id = params.get('id')
            get_fanart(emby_id, emby_path, server)

        elif '/Extras' in base_url or '/VideoFiles' in base_url:

            emby_path = path[1:]
            emby_id = params.get('id')
            get_video_extras(emby_id, emby_path, server)

        elif mode == 'play':

            item = TheVoid('GetItem', {'Id': params['id'], 'ServerId': server}).get()
            Actions(server).play(item, params.get('dbid'), params.get('transcode') == 'true', playlist=params.get('playlist') == 'true')

        elif mode =='playstrm':

            while not window('emby.playlist.play.bool'):
                xbmc.sleep(50)

                if window('emby.playlist.aborted.bool'):
                    LOG.info("[ playback aborted ]")

                    break
            else:
                LOG.info("[ playback started ]")
                xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem())

            window('emby.playlist.aborted', clear=True)

        elif mode == 'playsimple':
            from helper import playsimple

            playsimple.PlaySimple(params, server).play()

        elif mode == 'playlist':
            event('PlayPlaylist', {'Id': params['id'], 'ServerId': server})
        elif mode == 'deviceid':
            client.reset_device_id()
        elif mode == 'reset':
            reset()
        elif mode == 'delete':
            delete_item()
        elif mode == 'refreshboxsets':
            event('SyncLibrary', {'Id': "Boxsets:Refresh"})
        elif mode == 'nextepisodes':
            get_next_episodes(params['id'], params['limit'])
        elif mode == 'browse':
            browse(params.get('type'), params.get('id'), params.get('folder'), server)
        elif mode == 'synclib':
            event('SyncLibrary', {'Id': params.get('id')})
        elif mode == 'updatelib':
            event('SyncLibrary', {'Id': params.get('id'), 'Update': True})
        elif mode == 'repairlib':
            event('RepairLibrary', {'Id': params.get('id')})
        elif mode == 'removelib':
            event('RemoveLibrary', {'Id': params.get('id')})
        elif mode == 'repairlibs':
            event('RepairLibrarySelection')
        elif mode == 'updatelibs':
            event('SyncLibrarySelection')
        elif mode == 'removelibs':
            event('RemoveLibrarySelection')
        elif mode == 'addlibs':
            event('AddLibrarySelection')
        elif mode == 'connect':
            event('EmbyConnect')
        elif mode == 'addserver':
            event('AddServer')
        elif mode == 'login':
            event('ServerConnect', {'Id': server})
        elif mode == 'removeserver':
            event('RemoveServer', {'Id': server})
        elif mode == 'settings':
            xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)')
        elif mode == 'adduser':
            add_user(params.get('permanent') == 'true')
        elif mode == 'checkupdate':
            event('CheckUpdate')
        elif mode == 'updateserver':
            event('UpdateServer')
        elif mode == 'thememedia':
            get_themes()
        elif mode == 'managelibs':
            manage_libraries()
        elif mode == 'texturecache':
            cache_artwork()
        elif mode == 'backup':
            backup()
        elif mode == 'restartservice':
            window('emby.restart.bool', True)
        elif mode == 'patchmusic':
            event('PatchMusic', {'Notification': True})
        else:
            listing()
Exemplo n.º 23
0
def browse(media, view_id=None, folder=None, server_id=None):

    ''' Browse content dynamically.
    '''
    LOG.info("--[ v:%s/%s ] %s", view_id, media, folder)

    if not window('emby_online.bool') and server_id is None:

        monitor = xbmc.Monitor()

        for i in range(300):
            if window('emby_online.bool'):
                break
            elif monitor.waitForAbort(0.1):
                return
        else:
            LOG.error("Default server is not online.")

            return

    folder = folder.lower() if folder else None

    if folder is None and media in ('homevideos', 'movies', 'books', 'audiobooks'):
        return browse_subfolders(media, view_id, server_id)

    if folder and folder == 'firstletter':
        return browse_letters(media, view_id, server_id)

    if view_id:

        view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get()
        xbmcplugin.setPluginCategory(int(sys.argv[1]), view['Name'])

    content_type = "files"

    if media in ('tvshows', 'seasons', 'episodes', 'movies', 'musicvideos', 'songs', 'albums'):
        content_type = media
    elif media in ('homevideos', 'photos'):
        content_type = "images"
    elif media in ('books', 'audiobooks'):
        content_type = "videos"
    elif media == 'music':
        content_type = "artists"


    if folder == 'recentlyadded':
        listing = TheVoid('RecentlyAdded', {'Id': view_id, 'ServerId': server_id}).get()
    elif folder == 'genres':
        listing = TheVoid('Genres', {'Id': view_id, 'ServerId': server_id}).get()
    elif media == 'livetv':
        listing = TheVoid('LiveTV', {'Id': view_id, 'ServerId': server_id}).get()
    elif folder == 'unwatched':
        listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Filters': ['IsUnplayed']}).get()
    elif folder == 'favorite':
        listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Filters': ['IsFavorite']}).get()
    elif folder == 'inprogress':
        listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Filters': ['IsResumable']}).get()
    elif folder == 'boxsets':
        listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Media': get_media_type('boxsets'), 'Recursive': True}).get()
    elif folder == 'random':
        listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Media': get_media_type(content_type), 'Sort': "Random", 'Limit': 25, 'Recursive': True}).get()
    elif (folder or "").startswith('firstletter-'):
        listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Media': get_media_type(content_type), 'Params': {'NameStartsWith': folder.split('-')[1]}}).get()
    elif (folder or "").startswith('genres-'):
        listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Media': get_media_type(content_type), 'Params': {'GenreIds': folder.split('-')[1]}}).get()
    elif folder == 'favepisodes':
        listing = TheVoid('Browse', {'Media': get_media_type(content_type), 'ServerId': server_id, 'Limit': 25, 'Filters': ['IsFavorite']}).get()
    elif media == 'homevideos':
        listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': get_media_type(content_type), 'ServerId': server_id, 'Recursive': False}).get()
    elif media == 'movies':
        listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': get_media_type(content_type), 'ServerId': server_id, 'Recursive': True}).get()
    elif media in ('boxset', 'library'):
        listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': True}).get()
    elif media == 'episodes':
        listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': get_media_type(content_type), 'ServerId': server_id, 'Recursive': True}).get()
    elif media == 'boxsets':
        listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': False, 'Filters': ["Boxsets"]}).get()
    elif media == 'tvshows':
        listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': True, 'Media': get_media_type(content_type)}).get()
    elif media == 'seasons':
        listing = TheVoid('BrowseSeason', {'Id': folder, 'ServerId': server_id}).get()
    elif media != 'files':
        listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': False, 'Media': get_media_type(content_type)}).get()
    else:
        listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': False}).get()


    if listing:

        actions = Actions(server_id)
        list_li = []
        listing = listing if type(listing) == list else listing.get('Items', [])

        for item in listing:

            li = xbmcgui.ListItem()
            li.setProperty('embyid', item['Id'])
            li.setProperty('embyserver', server_id)
            actions.set_listitem(item, li)

            if item.get('IsFolder'):

                params = {
                    'id': view_id or item['Id'],
                    'mode': "browse",
                    'type': get_folder_type(item, media) or media,
                    'folder': item['Id'],
                    'server': server_id
                }
                path = "%s?%s" % ("plugin://plugin.video.emby/",  urllib.urlencode(params))
                context = []

                if item['Type'] in ('Series', 'Season', 'Playlist'):
                    context.append(("Play", "RunPlugin(plugin://plugin.video.emby/?mode=playlist&id=%s&server=%s)" % (item['Id'], server_id)))

                if item['UserData']['Played']:
                    context.append((_(16104), "RunPlugin(plugin://plugin.video.emby/?mode=unwatched&id=%s&server=%s)" % (item['Id'], server_id)))
                else:
                    context.append((_(16103), "RunPlugin(plugin://plugin.video.emby/?mode=watched&id=%s&server=%s)" % (item['Id'], server_id)))

                li.addContextMenuItems(context)
                list_li.append((path, li, True))

            elif item['Type'] == 'Genre':

                params = {
                    'id': view_id or item['Id'],
                    'mode': "browse",
                    'type': get_folder_type(item, media) or media,
                    'folder': 'genres-%s' % item['Id'],
                    'server': server_id
                }
                path = "%s?%s" % ("plugin://plugin.video.emby/",  urllib.urlencode(params))
                list_li.append((path, li, True))

            else:
                if item['Type'] not in ('Photo', 'PhotoAlbum'):
                    params = {
                        'id': item['Id'],
                        'mode': "play",
                        'server': server_id
                    }
                    path = "%s?%s" % ("plugin://plugin.video.emby/", urllib.urlencode(params))
                    li.setProperty('path', path)
                    context = [(_(13412), "RunPlugin(plugin://plugin.video.emby/?mode=playlist&id=%s&server=%s)" % (item['Id'], server_id))]

                    if item['UserData']['Played']:
                        context.append((_(16104), "RunPlugin(plugin://plugin.video.emby/?mode=unwatched&id=%s&server=%s)" % (item['Id'], server_id)))
                    else:
                        context.append((_(16103), "RunPlugin(plugin://plugin.video.emby/?mode=watched&id=%s&server=%s)" % (item['Id'], server_id)))

                    li.addContextMenuItems(context)

                list_li.append((li.getProperty('path'), li, False))

        xbmcplugin.addDirectoryItems(int(sys.argv[1]), list_li, len(list_li))

    if content_type == 'images':
        xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_TITLE)
        xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_YEAR)
        xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
        xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RATING)
        xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RUNTIME)

    xbmcplugin.setContent(int(sys.argv[1]), content_type)
    xbmcplugin.endOfDirectory(int(sys.argv[1]))
Exemplo n.º 24
0
    def get_audio_subs(self, source, audio=None, subtitle=None):
        ''' For transcoding only
            Present the list of audio/subs to select from, before playback starts.

            Since Emby returns all possible tracks together, sort them.
            IsTextSubtitleStream if true, is available to download from server.
        '''
        prefs = ""
        audio_streams = collections.OrderedDict()
        subs_streams = collections.OrderedDict()
        streams = source['MediaStreams']

        for stream in streams:

            index = stream['Index']
            stream_type = stream['Type']

            if stream_type == 'Audio':

                codec = stream['Codec']
                channel = stream.get('ChannelLayout', "")

                if 'Language' in stream:
                    track = "%s - %s - %s %s" % (index, stream['Language'],
                                                 codec, channel)
                else:
                    track = "%s - %s %s" % (index, codec, channel)

                audio_streams[track] = index

            elif stream_type == 'Subtitle':

                if 'Language' in stream:
                    track = "%s - %s" % (index, stream['Language'])
                else:
                    track = "%s - %s" % (index, stream['Codec'])

                if stream['IsDefault']:
                    track = "%s - Default" % track
                if stream['IsForced']:
                    track = "%s - Forced" % track

                subs_streams[track] = index

        skip_dialog = int(settings('skipDialogTranscode') or 0)
        audio_selected = None

        if audio:
            audio_selected = audio

        elif skip_dialog in (0, 1):
            if len(audio_streams) > 1:

                selection = list(audio_streams.keys())
                resp = dialog("select", _(33013), selection)
                audio_selected = audio_streams[selection[
                    resp]] if resp else source['DefaultAudioStreamIndex']
            else:  # Only one choice
                audio_selected = audio_streams[next(iter(audio_streams))]
        else:
            audio_selected = source['DefaultAudioStreamIndex']

        self.info['AudioStreamIndex'] = audio_selected
        prefs += "&AudioStreamIndex=%s" % audio_selected
        prefs += "&AudioBitrate=384000" if streams[audio_selected].get(
            'Channels', 0) > 2 else "&AudioBitrate=192000"

        if subtitle:

            index = subtitle
            server_settings = TheVoid('GetTranscodeOptions', {
                'ServerId': self.info['ServerId']
            }).get()
            stream = streams[index]

            if server_settings['EnableSubtitleExtraction'] and stream[
                    'SupportsExternalStream']:
                self.info['SubtitleUrl'] = self.get_subtitles(
                    source, stream, index)
            else:
                prefs += "&SubtitleStreamIndex=%s" % index

            self.info['SubtitleStreamIndex'] = index

        elif skip_dialog in (0, 2) and len(subs_streams):

            selection = list(['No subtitles']) + list(subs_streams.keys())
            resp = dialog("select", _(33014), selection)

            if resp:
                index = subs_streams[
                    selection[resp]] if resp > -1 else source.get(
                        'DefaultSubtitleStreamIndex')

                if index is not None:

                    server_settings = TheVoid('GetTranscodeOptions', {
                        'ServerId': self.info['ServerId']
                    }).get()
                    stream = streams[index]

                    if server_settings['EnableSubtitleExtraction'] and stream[
                            'SupportsExternalStream']:
                        self.info['SubtitleUrl'] = self.get_subtitles(
                            source, stream, index)
                    else:
                        prefs += "&SubtitleStreamIndex=%s" % index

                self.info['SubtitleStreamIndex'] = index

        return prefs
Exemplo n.º 25
0
def get_themes():

    ''' Add theme media locally, via strm. This is only for tv tunes.
        If another script is used, adjust this code.
    '''
    from helper.utils import normalize_string
    from helper.playutils import PlayUtils
    from helper.xmls import tvtunes_nfo

    library = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library").decode('utf-8')
    play = settings('useDirectPaths') == "1"

    if not xbmcvfs.exists(library + '/'):
        xbmcvfs.mkdir(library)

    if xbmc.getCondVisibility('System.HasAddon(script.tvtunes)'):

        tvtunes = xbmcaddon.Addon(id="script.tvtunes")
        tvtunes.setSetting('custom_path_enable', "true")
        tvtunes.setSetting('custom_path', library)
        LOG.info("TV Tunes custom path is enabled and set.")
    else:
        dialog("ok", heading="{emby}", line1=_(33152))

        return

    with Database('emby') as embydb:
        all_views = emby_db.EmbyDatabase(embydb.cursor).get_views()
        views = [x[0] for x in all_views if x[2] in ('movies', 'tvshows', 'mixed')]


    items = {}
    server = TheVoid('GetServerAddress', {'ServerId': None}).get()
    token = TheVoid('GetToken', {'ServerId': None}).get()

    for view in views:
        result = TheVoid('GetThemes', {'Type': "Video", 'Id': view}).get()

        for item in result['Items']:

            folder = normalize_string(item['Name'].encode('utf-8'))
            items[item['Id']] = folder

        result = TheVoid('GetThemes', {'Type': "Song", 'Id': view}).get()

        for item in result['Items']:

            folder = normalize_string(item['Name'].encode('utf-8'))
            items[item['Id']] = folder

    for item in items:

        nfo_path = os.path.join(library, items[item])
        nfo_file = os.path.join(nfo_path, "tvtunes.nfo")

        if not xbmcvfs.exists(nfo_path):
            xbmcvfs.mkdir(nfo_path)

        themes = TheVoid('GetTheme', {'Id': item}).get()
        paths = []

        for theme in themes['ThemeVideosResult']['Items'] + themes['ThemeSongsResult']['Items']:
            putils = PlayUtils(theme, False, None, server, token)

            if play:
                paths.append(putils.direct_play(theme['MediaSources'][0]).encode('utf-8'))
            else:
                paths.append(putils.direct_url(theme['MediaSources'][0]).encode('utf-8'))

        tvtunes_nfo(nfo_file, paths)

    dialog("notification", heading="{emby}", message=_(33153), icon="{emby}", time=1000, sound=False)
Exemplo n.º 26
0
    def __init__(self):
        ''' Parse the parameters. Reroute to our service.py
            where user is fully identified already.
        '''
        base_url = sys.argv[0]
        path = sys.argv[2]

        try:
            params = dict(urlparse.parse_qsl(path[1:]))
        except Exception:
            params = {}

        mode = params.get('mode')
        server = params.get('server')

        if server == 'None':
            server = None

        LOG.warn("path: %s params: %s", path, json.dumps(params, indent=4))

        if '/extrafanart' in base_url:

            jellyfin_path = path[1:]
            jellyfin_id = params.get('id')
            get_fanart(jellyfin_id, jellyfin_path, server)

        elif '/Extras' in base_url or '/VideoFiles' in base_url:

            jellyfin_path = path[1:]
            jellyfin_id = params.get('id')
            get_video_extras(jellyfin_id, jellyfin_path, server)

        elif mode == 'play':

            item = TheVoid('GetItem', {
                'Id': params['id'],
                'ServerId': server
            }).get()
            Actions(server).play(item,
                                 params.get('dbid'),
                                 params.get('transcode') == 'true',
                                 playlist=params.get('playlist') == 'true')

        elif mode == 'playlist':
            event('PlayPlaylist', {'Id': params['id'], 'ServerId': server})
        elif mode == 'deviceid':
            client.reset_device_id()
        elif mode == 'reset':
            reset()
        elif mode == 'delete':
            delete_item()
        elif mode == 'refreshboxsets':
            event('SyncLibrary', {'Id': "Boxsets:Refresh"})
        elif mode == 'nextepisodes':
            get_next_episodes(params['id'], params['limit'])
        elif mode == 'browse':
            browse(params.get('type'), params.get('id'), params.get('folder'),
                   server)
        elif mode == 'synclib':
            event('SyncLibrary', {'Id': params.get('id')})
        elif mode == 'updatelib':
            event('SyncLibrary', {'Id': params.get('id'), 'Update': True})
        elif mode == 'repairlib':
            event('RepairLibrary', {'Id': params.get('id')})
        elif mode == 'removelib':
            event('RemoveLibrary', {'Id': params.get('id')})
        elif mode == 'repairlibs':
            event('RepairLibrarySelection')
        elif mode == 'updatelibs':
            event('SyncLibrarySelection')
        elif mode == 'removelibs':
            event('RemoveLibrarySelection')
        elif mode == 'addlibs':
            event('AddLibrarySelection')
        elif mode == 'addserver':
            event('AddServer')
        elif mode == 'login':
            event('ServerConnect', {'Id': server})
        elif mode == 'removeserver':
            event('RemoveServer', {'Id': server})
        elif mode == 'settings':
            xbmc.executebuiltin('Addon.OpenSettings(plugin.video.jellyfin)')
        elif mode == 'adduser':
            add_user()
        elif mode == 'updateserver':
            event('UpdateServer')
        elif mode == 'thememedia':
            get_themes()
        elif mode == 'managelibs':
            manage_libraries()
        elif mode == 'backup':
            backup()
        elif mode == 'restartservice':
            window('jellyfin.restart.bool', True)
        else:
            listing()
Exemplo n.º 27
0
    def get_audio_subs(self, source, audio=None, subtitle=None):
        ''' For transcoding only
            Present the list of audio/subs to select from, before playback starts.

            Since Jellyfin returns all possible tracks together, sort them.
            IsTextSubtitleStream if true, is available to download from server.
        '''
        prefs = ""
        audio_streams = collections.OrderedDict()
        subs_streams = collections.OrderedDict()
        streams = source['MediaStreams']

        allow_burned_subs = settings('allowBurnedSubs.bool')

        for stream in streams:

            index = stream['Index']
            stream_type = stream['Type']

            if stream_type == 'Audio':

                profile = stream['Profile'] if 'Profile' in stream else None
                codec = self.get_commercial_codec_name(stream['Codec'],
                                                       profile)
                channel = stream.get('ChannelLayout', "").capitalize()

                if 'Language' in stream:
                    track = "%s - %s %s" % (stream['Language'].capitalize(),
                                            codec, channel)
                else:
                    track = "%s %s" % (codec, channel)

                audio_streams[track] = index

            elif stream_type == 'Subtitle':
                downloadable = stream['IsTextSubtitleStream'] and stream[
                    'IsExternal'] and stream['SupportsExternalStream']
                if not downloadable and not allow_burned_subs:
                    continue

                codec = self.get_commercial_codec_name(stream['Codec'], None)

                if 'Language' in stream:
                    track = "%s - %s" % (stream['Language'].capitalize(),
                                         codec)
                else:
                    track = "%s" % codec

                if stream['IsDefault']:
                    track = "%s - Default" % track
                if stream['IsForced']:
                    track = "%s - Forced" % track

                subs_streams[track] = index

        skip_dialog = int(settings('skipDialogTranscode') or 0)
        audio_selected = None

        if audio:
            audio_selected = audio

        elif skip_dialog in (0, 1):
            if len(audio_streams) > 1:

                selection = list(audio_streams.keys())
                resp = dialog("select", translate(33013), selection)
                audio_selected = audio_streams[selection[
                    resp]] if resp else source['DefaultAudioStreamIndex']
            else:  # Only one choice
                audio_selected = audio_streams[next(iter(audio_streams))]
        else:
            audio_selected = source['DefaultAudioStreamIndex']

        self.info['AudioStreamIndex'] = audio_selected
        prefs += "&AudioStreamIndex=%s" % audio_selected

        if subtitle:

            index = subtitle
            server_settings = TheVoid('GetTranscodeOptions', {
                'ServerId': self.info['ServerId']
            }).get()
            stream = streams[index]

            if server_settings['EnableSubtitleExtraction'] and stream[
                    'SupportsExternalStream']:
                self.info['SubtitleUrl'] = self.get_subtitles(
                    source, stream, index)
                self.info['SubtitleStreamIndex'] = index
            elif allow_burned_subs:
                prefs += "&SubtitleStreamIndex=%s" % index
                self.info['SubtitleStreamIndex'] = index

        elif skip_dialog in (0, 2) and len(subs_streams):

            selection = list(['No subtitles']) + list(subs_streams.keys())
            resp = dialog("select", translate(33014), selection)

            if resp:
                index = subs_streams[
                    selection[resp]] if resp > -1 else source.get(
                        'DefaultSubtitleStreamIndex')

                if index is not None:

                    server_settings = TheVoid('GetTranscodeOptions', {
                        'ServerId': self.info['ServerId']
                    }).get()
                    stream = streams[index]

                    if server_settings['EnableSubtitleExtraction'] and stream[
                            'SupportsExternalStream']:
                        self.info['SubtitleUrl'] = self.get_subtitles(
                            source, stream, index)
                        self.info['SubtitleStreamIndex'] = index
                    elif allow_burned_subs:
                        prefs += "&SubtitleStreamIndex=%s" % index
                        self.info['SubtitleStreamIndex'] = index

        return prefs