示例#1
0
文件: plex.py 项目: shayward/bw_plex
def client_action(offset=None,
                  sessionkey=None,
                  action='jump'):  # pragma: no cover
    """Seek the client to the offset.

       Args:
            offset(int): Default None
            sessionkey(int): So we made sure we control the correct client.

       Returns:
            None
    """
    global JUMP_LIST
    LOG.info('Called client_action with %s %s %s %s', offset, to_time(offset),
             sessionkey, action)

    def proxy_on_fail(func):
        import plexapi

        @wraps(func)
        def inner():
            try:
                func()
            except plexapi.exceptions.BadRequest:
                try:
                    LOG.info(
                        'Failed to reach the client directly, trying via server.'
                    )
                    correct_client.proxyThroughServer()
                    func()
                except:  # pragma: no cover
                    correct_client.proxyThroughServer(value=False)
                    raise

    if offset == -1:
        return

    conf_clients = CONFIG.get('general', {}).get('clients', [])
    conf_users = CONFIG.get('general', {}).get('users', [])
    correct_client = None

    clients = PMS.clients()
    for media in PMS.sessions():
        # Find the client.. This client does not have the correct address
        # or 'protocolCapabilities' so we have to get the correct one.
        # or we can proxy thru the server..
        if sessionkey and int(sessionkey) == media.sessionKey:
            client = media.players[0]
            user = media.usernames[0]
            LOG.info('client %s %s', client.title, (media.viewOffset / 1000))

            # Check that this client is allowed.
            if conf_clients and client.title not in conf_clients:
                LOG.info('Client %s is not whitelisted', client.title)
                return

            # Check that this user is allowed.
            if conf_users and user not in conf_users:
                LOG.info('User %s is not whitelisted', user)
                return

            # To stop processing. from func task if we have used to much time..
            # This will not work if/when credits etc are added. Need a better way.
            # if offset <= media.viewOffset / 1000:
            #    LOG.debug('Didnt jump because of offset')
            #    return

            for c in clients:
                LOG.info('%s %s' %
                         (c.machineIdentifier, client.machineIdentifier))
                # So we got the correct client..
                if c.machineIdentifier == client.machineIdentifier:
                    # Plex web sometimes add loopback..
                    if '127.0.0.1' in c._baseurl:
                        c._baseurl = c._baseurl.replace(
                            '127.0.0.1', client.address)
                    correct_client = c
                    break

            if correct_client:
                try:
                    LOG.info('Connectiong to %s', correct_client.title)
                    correct_client.connect()
                except requests.exceptions.ConnectionError:
                    LOG.exception('Cant connect to %s', client.title)
                    return

                if action != 'stop':
                    if ignore_ratingkey(
                            media,
                            CONFIG['general'].get('ignore_intro_ratingkeys')):
                        LOG.info(
                            'Didnt send seek command this show, season or episode is ignored'
                        )
                        return

                    # PMP seems to be really picky about timeline calls, if we dont
                    # it returns 406 errors after 90 sec.
                    if correct_client.product == 'Plex Media Player':
                        correct_client.sendCommand('timeline/poll', wait=0)

                    proxy_on_fail(correct_client.seekTo(int(offset * 1000)))
                    LOG.info('Jumped %s %s to %s %s', user, client.title,
                             offset, media._prettyfilename())
                else:
                    if not ignore_ratingkey(
                            media,
                            CONFIG['general'].get('ignore_intro_ratingkeys')):
                        proxy_on_fail(correct_client.stop())
                        # We might need to login on pms as the user..
                        # urs_pms = users_pms(PMS, user)
                        # new_media = urs_pms.fetchItem(int(media.ratingkey))
                        # new_media.markWatched()
                        # LOG.debug('Stopped playback on %s and marked %s as watched.', client.title, media._prettyfilename())

                        # Check if we just start the next ep instantly.
                        if CONFIG['tv'].get(
                                'check_credits_start_next_ep') is True:
                            nxt = find_next(
                                media)  # This is always false for movies.
                            if nxt:
                                LOG.info('Start playback on %s with %s', user,
                                         nxt._prettyfilename())
                                proxy_on_fail(correct_client.playMedia(nxt))
            else:
                LOG.info('Didnt find the correct client.')

            # Some clients needs some time..
            # time.sleep(0.2)
            # client.play()
            # JUMP_LIST.remove(sessionkey)
            # time.sleep(1)

            return
示例#2
0
文件: plex.py 项目: shayward/bw_plex
def check_db(client_name, skip_done):  # pragma: no cover
    """Do a manual check of the db. This will start playback on a client and seek the video file where we have found
       theme start/end and ffmpeg_end. You will be asked if its a correct match, press y or set the correct time in
       mm:ss format.

       Args:
            client_name (None, str): Name of the client you want to use (watch)
            skip_done (bool): Skip episodes that already exist in the db.

       Returns:
            None
    """
    if client_name is None:
        client = choose('Select what client to use', PMS.clients(), 'title')
        if len(client):
            client = client[0]
        else:
            click.echo('No client to check with.. Aborting')
            return
    else:
        client = PMS.client(client_name).connect()

    client.proxyThroughServer()

    with session_scope() as se:
        items = se.query(Processed).all()
        click.echo('')

        for item in sorted(items, key=lambda k: k.ratingKey):

            click.echo('%s %s' %
                       (click.style('Checking', fg='white'),
                        click.style(item.prettyname, bold=True, fg='green')))
            click.echo('theme_start %s theme_end %s ffmpeg_end %s' %
                       (item.theme_start, item.theme_end_str, item.ffmpeg_end))
            click.echo('*%s*' % ('-' * 80))
            click.echo('')

            media = PMS.fetchItem(item.ratingKey)

            if item.theme_start == -1 or item.theme_end == -1:
                click.echo(
                    'Exists in the db but the start of the theme was not found.'
                    ' Check the audio file and run it again. Use cmd manually_correct_theme'
                )

            if item.theme_end != -1:

                if (not skip_done and item.correct_theme_start
                    ) or not item.correct_theme_start:

                    click.echo('Found theme_start at %s %s theme_end %s %s' %
                               (item.theme_start, item.theme_start_str,
                                item.theme_end, item.theme_end_str))

                    client.playMedia(media, offset=item.theme_start * 1000)
                    time.sleep(1)

                    start_match = click.prompt(
                        'Was theme_start at %s correct? [y or MM:SS]' %
                        item.theme_start_str)
                    if start_match:
                        if start_match in ['y', 'yes']:
                            item.correct_theme_start = item.theme_start
                        else:
                            item.correct_theme_start = to_sec(start_match)

                if (not skip_done and
                        item.correct_theme_end) or not item.correct_theme_end:

                    client.playMedia(media, offset=item.theme_end * 1000)
                    end_match = click.prompt(
                        'Was theme_end at %s correct? [y or MM:SS]' %
                        item.theme_end_str)
                    if end_match:
                        if end_match in ['y', 'yes']:
                            item.correct_theme_end = item.theme_end
                        else:
                            item.correct_theme_end = to_sec(end_match)

            if item.ffmpeg_end:
                if (not skip_done
                        and item.correct_ffmpeg) or not item.correct_ffmpeg:
                    click.echo('Found ffmpeg_end at sec %s time %s' %
                               (item.ffmpeg_end, item.ffmpeg_end_str))
                    if item.ffmpeg_end > 30:
                        j = item.ffmpeg_end - 20
                    else:
                        j = item.ffmpeg_end

                    client.playMedia(media, offset=j * 1000)
                    time.sleep(1)

                    match = click.prompt(
                        'Was ffmpeg_end at %s correct? [y or MM:SS]' %
                        item.ffmpeg_end_str)

                    if match:
                        if match.lower() in ['y', 'yes']:
                            item.correct_ffmpeg = item.ffmpeg_end
                        else:
                            item.correct_ffmpeg = to_sec(match)

            # This needs to be tested manually.
            if item.credits_start and item.credits_start != 1:
                if (not skip_done and item.correct_credits_start
                    ) or not item.correct_credits_start:
                    click.echo('Found credits start as sec %s time %s' %
                               (item.credits_start, item.credits_start_str))
                    client.playMedia(media, offset=item.credits_start - 10)
                    time.sleep(1)

                    match = click.prompt(
                        'Did the credits start at %s correct? [y or MM:SS]' %
                        item.credits_start_str)

                    if match:
                        if match.lower() in ['y', 'yes']:
                            item.correct_credits_start = item.credits_start
                        else:
                            item.correct_credits_start = to_sec(match)

            click.clear()

            # Commit this shit after each loop.
            if se.dirty:
                se.commit()

        click.echo('Done')