def load_trailers() -> None: """ Start up the configured trailer discovery threads. Called whenever settings have changed to start any threads that have just ben enabled. :return: """ module_logger.enter() if Settings.get_include_library_trailers(): lib_instance = DiscoverLibraryMovies() lib_instance.discover_basic_information() # Manufacture trailer entries for folders which contain trailer # files. Note that files are assumed to be videos. if Settings.get_include_trailer_folders(): DiscoverFolderTrailers().discover_basic_information() if Settings.get_include_itunes_trailers(): DiscoverItunesMovies().discover_basic_information() if Settings.get_include_tmdb_trailers(): DiscoverTmdbMovies().discover_basic_information() if Settings.is_include_tfh_trailers(): DiscoverTFHMovies().discover_basic_information() Monitor.throw_exception_if_abort_requested(timeout=1.0) Monitor.set_startup_complete()
def on_settings_changed(self): # type: () -> None """ Rediscover trailers if the changed settings impacts this manager. """ clz = DiscoverLibraryMovies if clz.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE): clz.logger.enter() try: if Settings.is_library_loading_settings_changed(): stop_thread = not Settings.get_include_library_trailers() self.restart_discovery(stop_thread) except Exception as e: clz.logger.exception('')
def run(self): # type: () -> None """ :return: """ clz = DiscoverLibraryMovies start_time = datetime.datetime.now() try: finished = False while not finished: try: self._some_movies_discovered_event.clear() self.run_worker() self.wait_until_restart_or_shutdown() except RestartDiscoveryException: # Restart discovery if clz.logger.isEnabledFor(LazyLogger.DEBUG): clz.logger.debug('Restarting discovery') self.prepare_for_restart_discovery() if not Settings.get_include_library_trailers(): finished = True self.remove_self() self._some_movies_discovered_event.set() except AbortException: return # Just exit thread except Exception as e: clz.logger.exception('') self.finished_discovery() # Unblock other discovery threads self._some_movies_discovered_event.set() duration = datetime.datetime.now() - start_time if clz.logger.isEnabledFor(LazyLogger.DEBUG): clz.logger.debug('Time to discover:', duration.seconds, 'seconds', trace=Trace.STATS)
def run_worker(self): # type: () -> None """ Initial Discovery of all movies in Kodi. :return: """ # Discovery is done in two parts: # # 1- query DB for every movie in library # 2- Get additional information # # There are three types of trailers for these movies: # # a- Movies with local trailers # b- Movies with trailer URLS (typically youtube links from tmdb) # TMdb will need to be queried for details # c. Movies with no trailer information, requiring a check with tmdb # to see if one exists # # Because of the above, this manager will query the DB for every movie # and then only process the ones with local trailers. The others will # be handed off to their own managers. This is done because of # the way that this application works: # Once enough information to identify a movie that matches # what the user wants, it is added to the pool of movies that # can be randomly selected for playing. Once a movie has been # selected, it is placed into a TrailerFetcherQueue. A # TrailerFetcher then gathers the remaining information so that # it can be played. # # If the lion's share of movies in the pool require significant # extra processing because they don't have local trailers, then # the fetcher can get overwhelmed. clz = DiscoverLibraryMovies self._selected_keywords = [] self._excluded_keywords = [] self._selected_genres = [] self._excluded_genres = [] if Settings.get_filter_genres(): self._selected_genres = GenreUtils.get_internal_kodi_genre_ids( GenreUtils.LOCAL_DATABASE, exclude=False) self._excluded_genres = GenreUtils.get_internal_kodi_genre_ids( GenreUtils.LOCAL_DATABASE, exclude=True) self._selected_keywords = GenreUtils.get_internal_kodi_keyword_ids( GenreUtils.LOCAL_DATABASE, exclude=False) self._excluded_keywords = GenreUtils.get_internal_kodi_keyword_ids( GenreUtils.LOCAL_DATABASE, exclude=True) query = self.create_query( self._selected_genres, self._excluded_genres, self._selected_keywords, self._excluded_keywords) if Monitor.is_abort_requested(): return start_time = datetime.datetime.now() Monitor.throw_exception_if_abort_requested() # Expensive operation query_result = JsonUtilsBasic.get_kodi_json(query, dump_results=False) Monitor.throw_exception_if_abort_requested() elapsed_time = datetime.datetime.now() - start_time if clz.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE): clz.logger.debug_verbose('Library query seconds:', elapsed_time.total_seconds()) movies_skipped = 0 movies_found = 0 movies_with_local_trailers = 0 movies_with_trailer_urls = 0 movies_without_trailer_info = 0 self.throw_exception_on_forced_to_stop() result = query_result.get('result', {}) del query_result movies = result.get('movies', []) del result DiskUtils.RandomGenerator.shuffle(movies) if self._libraryURLManager is None: self._libraryURLManager = DiscoverLibraryURLTrailerMovies() self._libraryNoTrailerInfoManager = DiscoverLibraryNoTrailerMovies() library_movies = [] library_url_movies = [] library_no_trailer_movies = [] empty_limit = 50 movie_data = None if Settings.is_enable_movie_stats(): movie_data = LibraryMovieStats() country_id = Settings.get_country_iso_3166_1().lower() certifications = WorldCertifications.get_certifications(country_id) unrated_id = certifications.get_unrated_certification().get_preferred_id() for movie in movies: self.throw_exception_on_forced_to_stop() try: #clz.logger.debug('movie:', movie) movies_found += 1 if Settings.get_hide_watched_movies() and Movie.LAST_PLAYED in movie: if (self.get_days_since_last_played(movie[Movie.LAST_PLAYED], movie[Movie.TITLE]) > Settings.get_minimum_days_since_watched()): movies_skipped += 1 if clz.logger.isEnabledFor(LazyLogger.DEBUG_EXTRA_VERBOSE): clz.logger.debug_extra_verbose(movie[Movie.TITLE], 'will not be played due to ' 'Hide', 'Watched Movies') continue # Normalize certification # if clz.logger.isEnabledFor(LazyLogger.DEBUG): # clz.logger.debug('mpaa:', movie[Movie.MPAA], # 'movie:', movie[Movie.TITLE]) if certifications.is_valid(movie.get(Movie.MPAA, '')): movie[Movie.MPAA] = unrated_id certification = certifications.get_certification( movie.get(Movie.MPAA), movie.get(Movie.ADULT)) movie[Movie.ADULT] = movie.get(Movie.ADULT, False) if not isinstance(movie[Movie.ADULT], bool): if clz.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE): clz.logger.debug_verbose(movie[Movie.TITLE], 'has invalid ADULT field: ', movie[Movie.ADULT]) movie[Movie.ADULT] = str(movie[Movie.ADULT]).lower == 'true' movie[Movie.SOURCE] = Movie.LIBRARY_SOURCE movie.setdefault(Movie.TRAILER, '') movie[Movie.TYPE] = '' if clz.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE): Debug.validate_basic_movie_properties(movie) if Settings.is_enable_movie_stats(): movie_data.collect_data(movie) # Basic discovery is complete at this point. Now send # all of the movies without any trailer information to # DiscoverLibraryNoTrailerMovies while # those with trailer URLs to DiscoverLibraryURLTrailerMovies if certifications.filter(certification): trailer = movie[Movie.TRAILER] if trailer == '': movies_without_trailer_info += 1 library_no_trailer_movies.append(movie) elif trailer.startswith('plugin://') or trailer.startswith('http'): movies_with_trailer_urls += 1 library_url_movies.append(movie) elif Settings.get_include_library_trailers(): movies_with_local_trailers += 1 library_movies.append(movie) if len(library_movies) >= empty_limit: self.add_to_discovered_trailers(library_movies) del library_movies[:] # Unblock other discovery now that a few movies have been # found. if not self._some_movies_discovered_event.isSet(): self._some_movies_discovered_event.set() if len(library_no_trailer_movies) >= empty_limit: self._libraryNoTrailerInfoManager.add_to_discovered_trailers( library_no_trailer_movies) del library_no_trailer_movies[:] if len(library_url_movies) >= empty_limit: self._libraryURLManager.add_to_discovered_trailers( library_url_movies) del library_no_trailer_movies[:] # Unblock other discovery now that a few movies have been # found. self._some_movies_discovered_event.set() except AbortException: reraise(*sys.exc_info()) except Exception: clz.logger.exception('') try: if len(library_movies) >= 0: self.add_to_discovered_trailers(library_movies) if len(library_no_trailer_movies) >= 0: self._libraryNoTrailerInfoManager.add_to_discovered_trailers( library_no_trailer_movies) if len(library_url_movies) >= 0: self._libraryURLManager.add_to_discovered_trailers( library_url_movies) except AbortException: reraise(*sys.exc_info()) except Exception: clz.logger.exception('') if (clz.logger.isEnabledFor(LazyLogger.DEBUG) and clz.logger.is_trace_enabled(Trace.STATS)): clz.logger.debug('Local movies found in library:', movies_found, trace=Trace.STATS) clz.logger.debug('Local movies filtered out', movies_skipped, trace=Trace.STATS) clz.logger.debug('Movies with local trailers:', movies_with_local_trailers, trace=Trace.STATS) clz.logger.debug('Movies with trailer URLs:', movies_with_trailer_urls, trace=Trace.STATS) clz.logger.debug('Movies with no trailer information:', movies_without_trailer_info, trace=Trace.STATS) if Settings.is_enable_movie_stats(): movie_data.report_data() del movie_data