def jump(item, sessionkey, sec=None, action=None): # pragma: no cover if sec is None: sec = best_time(item) if action: POOL.apply_async(client_action, args=(sec, sessionkey, action)) return if sessionkey not in JUMP_LIST: LOG.debug('Called jump with %s %s %s %s', item.prettyname, sessionkey, sec, action) JUMP_LIST.append(sessionkey) POOL.apply_async(client_action, args=(sec, sessionkey, action))
def watch(): # # pragma: no cover """Start watching the server for stuff to do.""" global HT HT = get_hashtable() click.echo('Watching for media on %s' % PMS.friendlyName) ffs = PMS.startAlertListener(check) try: while True: time.sleep(0.2) except KeyboardInterrupt: click.echo('Aborting') ffs.stop() POOL.terminate()
def find_all_movies_shows(func=None): # pragma: no cover """ Helper of get all the shows on a server. Args: func (callable): Run this function in a threadpool. Returns: List """ all_shows = [] for section in PMS.library.sections(): if section.TYPE in ('movie', 'show'): all_shows += section.all() if func: return POOL.map(func, all_shows) return all_shows
def check(data): global JUMP_LIST if data.get('type') == 'playing' and data.get( 'PlaySessionStateNotification'): sess = data.get('PlaySessionStateNotification')[0] if sess.get('state') != 'playing': return ratingkey = int(sess.get('ratingKey')) sessionkey = int(sess.get('sessionKey')) progress = sess.get('viewOffset', 0) / 1000 # converted to sec. mode = CONFIG['general'].get('mode', 'skip_only_theme') no_wait_tick = CONFIG['general'].get('no_wait_tick', 0) def best_time(item): """Find the best time in the db.""" if item.type == 'episode' and item.correct_theme_end and item.correct_theme_end != 1: sec = item.correct_theme_end elif item.correct_ffmpeg and item.correct_ffmpeg != 1: sec = item.correct_ffmpeg elif item.type == 'episode' and item.theme_end and item.theme_end != -1: sec = item.theme_end elif item.ffmpeg_end and item.ffmpeg_end != -1: sec = item.ffmpeg_end else: sec = -1 return sec def jump(item, sessionkey, sec=None, action=None): # pragma: no cover if sec is None: sec = best_time(item) if action: POOL.apply_async(client_action, args=(sec, sessionkey, action)) return if sessionkey not in JUMP_LIST: LOG.debug('Called jump with %s %s %s %s', item.prettyname, sessionkey, sec, action) JUMP_LIST.append(sessionkey) POOL.apply_async(client_action, args=(sec, sessionkey, action)) with session_scope() as se: try: item = se.query(Processed).filter_by(ratingKey=ratingkey).one() if item: bt = best_time(item) LOG.debug( 'Found %s theme start %s, theme end %s, ffmpeg_end %s progress %s ' 'best_time %s credits_start %s credits_end %s', item.prettyname, item.theme_start_str, item.theme_end_str, item.ffmpeg_end_str, to_time(progress), to_time(bt), item.credits_start_str, item.credits_end_str) if (item.type == 'episode' and CONFIG['tv'].get('check_credits') is True and CONFIG['tv'].get('check_credits_action') == 'stop' or item.type == 'movie' and CONFIG['movie'].get('check_credits') is True and CONFIG['movie'].get('check_credits_action') == 'stop'): # todo check for correct credits too if item.credits_start and item.credits_start != -1 and progress >= item.credits_start: LOG.debug('We found the start of the credits.') return jump(item, sessionkey, item.credits_start, action='stop') # Let's try to not wait for the next tick. progress = progress + no_wait_tick # If recap is detected just instantly skip to intro end. # Now this can failed is there is: recap, new episode stuff, intro, new episode stuff # So thats why skip_only_theme is default as its the safest option. if (mode == 'skip_if_recap' and item.type == 'episode' and item.has_recap is True and bt != -1): return jump(item, sessionkey, bt) # This mode will allow playback until the theme starts so it should be faster then skip_if_recap. if mode == 'skip_only_theme': # For manual corrected themes.. if item.type == 'episode' and item.correct_theme_end and item.correct_theme_start: if progress > item.correct_theme_start and progress < item.correct_theme_end: LOG.debug( '%s is in the correct time range correct_theme_end', item.prettyname) return jump(item, sessionkey, item.correct_theme_end) elif item.type == 'episode' and item.theme_end and item.theme_start: if progress > item.theme_start and progress < item.theme_end: LOG.debug( '%s is in the correct time range theme_end', item.prettyname) return jump(item, sessionkey, item.theme_end) except NoResultFound: if ratingkey not in IN_PROG: IN_PROG.append(ratingkey) LOG.debug('Failed to find ratingkey %s in the db', ratingkey) ret = POOL.apply_async(task, args=(ratingkey, sessionkey)) return ret elif data.get('type') == 'timeline': timeline = data.get('TimelineEntry')[0] state = timeline.get('state') ratingkey = timeline.get('itemID') title = timeline.get('title') metadata_type = timeline.get('type') identifier = timeline.get('identifier') metadata_state = timeline.get('metadataState') if (metadata_type in (1, 4) and state == 0 and metadata_state == 'created' and identifier == 'com.plexapp.plugins.library'): LOG.debug('%s was added to %s', title, PMS.friendlyName) # Youtubedl can fail if we batch add loads of eps at the same time if there is no # theme. if (metadata_type == 1 and not CONFIG['movie'].get('process_recently_added') or metadata_state == 4 and not CONFIG['tv'].get('process_recently_added')): LOG.debug( "Didnt start to process %s is process_recently_added is disabled" ) return if ratingkey not in IN_PROG: IN_PROG.append(ratingkey) ep = PMS.fetchItem(int(ratingkey)) ret = POOL.apply_async(process_to_db, args=(ep, )) return ret elif (metadata_type in (1, 4) and state == 9 and metadata_state == 'deleted'): if (metadata_type == 1 and not CONFIG['movie'].get('process_deleted') or metadata_state == 4 and not CONFIG['tv'].get('process_deleted')): LOG.debug( "Didnt start to process %s is process_deleted is disabled for" ) return with session_scope() as se: try: item = se.query(Processed).filter_by( ratingKey=ratingkey).one() item.delete() LOG.debug('%s was deleted from %s and from media.db', title, PMS.friendlyName) except NoResultFound: LOG.debug('%s was deleted from %s', title, PMS.friendlyName)