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
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')