def start(self): alang = Config.get("player", "preferred audio", default="eng") slang = Config.get("player", "preferred subtitle", default="eng") vo = Config.get("player", "video output", default="vdpau,opengl-hq,x11,opengl") self.player = VideoPlayer(alang=alang, slang=slang, vo=vo, fs="yes") asyncio.async(self.update_per_second()) asyncio.async(self.event_listener()) yield from websockets.serve(self.handle_websocket, "0.0.0.0", 5002)
def update_track_info(self): yield from asyncio.gather( self.broadcast_available_subtitles(), self.broadcast_available_audio(), self.broadcast_subtitle(), broadcast_player_property("selected_audio", str(self.audio)), events.broadcast("list-subtitles", path=self.client.path), ) if ( self.sub != 0 and self.audio_language() != "unk" and self.audio_language() == self.sub_language() and not int(Config.get("player", "subtitles for matching audio")) ): log.info("Disabling subtitle as it's the same as the language") self.client.sub = 0
parser = argparse.ArgumentParser() parser.add_argument( '--log-level', default='INFO', help="Log Level. Must be one of CRITICAL, ERROR, WARNING, INFO or DEBUG") options = parser.parse_args() try: setup_logging('aesop.processor', 'INFO') except LookupError: parser.error("--log-level must be one of CRITICAL, ERROR, WARNING, INFO or DEBUG") init() max_lookups = int(Config.get('processor', 'concurrency', default=50)) sources = list(Source.select(Source.path, Source.type)) events.info.blocking("Starting scan") log.info("Starting scan") total = unscanned = removed = 0 for source in sources: t, u, r = catalog_videos(database_proxy, source, max_lookups) total += t unscanned += u removed += r msg = "Scan complete. {} new items, {} could not be added. {} items were removed from the db".format(total, unscanned, removed)
def ws_seek_backward(self): seek_size = int(Config.get("player", "seek size", default=15)) self.player.seek_backward(seek_size)
def catalog_videos(database, source, max_lookups): from aesop.processor.movie import MovieLookup from aesop.processor.episode import AnimeLookup, TVShowLookup model, lookup_model = { 'movies': (Movie, MovieLookup), 'tv': (TVShow, TVShowLookup), 'anime': (TVShow, AnimeLookup), }[source.type] log.info("Cataloguing {} videos for {}", source.type, source.path) if model == Movie: query = model.select(model.path) known_paths = set(itertools.chain.from_iterable(m.path.split('|') for m in query)) else: query = TVShowEpisode.select(TVShowEpisode.path).where(TVShowEpisode.path.startswith(source.path)) known_paths = {m.path for m in query} known_video_types = set(Config.get('processor', 'video types', default='avi, mp4, mkv, ogm').replace(' ', '').split(',')) lookups = [] paths = [] log.debug("Known paths {}", known_paths) removed = 0 for path in set(known_paths): if not os.path.exists(path): known_paths.remove(path) log.info("{} does not exist, removing from database.", path) if model == Movie: Movie.delete().where( (Movie.path == path) | Movie.path.contains(path+'|') | Movie.path.contains('|'+path) ).execute() else: ep = TVShowEpisode.select().where(TVShowEpisode.path == path).get() show = ep.show removed += 1 with database_proxy.transaction(): ep.delete_instance() if not list(show.episodes): show.delete_instance() else: if all([episode.watched for episode in show.episodes]): show.watched = True if show.is_dirty(): show.save() start_time = time.time() successes = 0 lookup_failures = 0 for root, dirs, files in os.walk(source.path): for path in (os.path.join(root, p) for p in files): if '/.AppleDouble/' in path: log.debug('Skipping {} as it looks like an Apple double.', path) continue if os.path.basename(path).startswith('.'): continue if os.path.splitext(path)[1][1:] not in known_video_types: continue if '/sample/' in path.lower() or os.path.splitext(path)[0].lower().endswith('-sample'): log.debug('Skipping {} as it looks like a sample.', path) continue if path in known_paths: continue with FingersCrossedHandler(default_handler): try: path_lookups = lookup_model.from_path(path) except SkipIt as e: log.error("Skipping path: {} {}", path, str(e)) except Exception as e: lookup_failures += 1 exception = ''.join(traceback.format_exception(e.__class__, e, e.__traceback__)) log.error("Error retrieving information for {}: {}", path, exception) else: lookups.extend(path_lookups) paths.extend([path]*len(path_lookups)) loop = asyncio.get_event_loop() log.info("{} lookups to do", len(lookups)) for i in range(0, len(lookups), max_lookups): chunk = lookups[i:i+max_lookups] f = asyncio.gather( *[asyncio.async(c, loop=loop) for c in chunk], loop=loop, return_exceptions=True) completed = loop.run_until_complete(f) with database.transaction(): for path, lookup in zip(paths[i:i+max_lookups], completed): if isinstance(lookup, SkipIt): # logged earlier, no need to log now lookup_failures += 1 elif isinstance(lookup, Exception): lookup_failures += 1 exception = ''.join(traceback.format_exception(lookup.__class__, lookup, lookup.__traceback__)) log.error("Error retrieving information for {}: {}", path, exception) else: genres = [Genre.get_or_create(text=g) for g in lookup.genres] if source.type == 'movies': save_movie(lookup, path, genres) else: save_episode(lookup, path, genres, source.type) successes += 1 end_time = time.time() log.info("Took {:.2f} seconds to do {} lookups", end_time - start_time, len(lookups)) log.info("{} lookups failed", lookup_failures) return successes, lookup_failures, removed