Exemple #1
0
    def increase_play_count(self, movie: MovieType) -> None:
        """

        :param movie:
        :return:
        """
        PlayStatistics.increase_play_count(movie)
    def get_next_movie(self):
        # type: () -> MovieType
        """

        :return:
        """
        clz = PlayableTrailersContainer
        movie = self._ready_to_play_queue.get(block=False)
        if movie is not None:
            PlayStatistics.increase_play_count(movie)
            if clz.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE):
                clz.logger.exit('movie:', movie[Movie.TITLE])
        else:
            if clz.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE):
                clz.logger.exit('No movie in queue')
        return movie
    def throw_exception_on_forced_to_stop(self, delay=0):
        # type: (float) -> None
        """

        :param delay:
        :return:
        """
        clz = BaseDiscoverMovies

        try:
            Monitor.throw_exception_if_abort_requested(timeout=delay)
            if self._movie_data.restart_discovery_event.isSet():
                raise RestartDiscoveryException()
        except AbortException:
            if clz.logger.is_trace_enabled(Trace.TRACE_PLAY_STATS):
                PlayStatistics.report_play_count_stats()
            reraise(*sys.exc_info())
Exemple #4
0
    def add(self, movie: MovieType) -> None:
        """

        :param movie:
        :return:
        """
        clz = MovieList

        # if self.logger.isEnabledFor(LazyLogger.DEBUG):
        # self.logger.debug('movie:', movie[Movie.TITLE], 'source:',
        #                   movie[Movie.SOURCE])
        key = clz.get_key(movie)
        with self._lock:
            if key in self._ordered_dict.keys():
                raise DuplicateException()

            self._ordered_dict[key] = movie
            self._number_of_added_movies += 1

        PlayStatistics.add(movie)
    def _do_next(self):
        # type: () -> Union[dict, None]
        """

        :return:
        """
        clz = PlayableTrailerService
        try:
            while not PlayableTrailersContainer.is_any_trailers_available_to_play(
            ):
                self.throw_exception_on_forced_to_stop(movie_data=None,
                                                       delay=0.25)

        except Exception as e:
            self.logger.exception('')

        total_number_of_trailers = 0
        start_time = datetime.datetime.now()

        # Considered locking all TrailerManagers here to guarantee
        # that lengths don't change while finding the right trailer
        # but that might block the readyToPlayQueue from getting
        # loaded. Besides, it doesn't matter too much if we play
        # the incorrect trailer, as long as we get one. The
        # major fear is if we have no trailers at all, but that
        # will be handled elsewhere.

        # Get total number of trailers from all managers.

        # It is possible that all discovery is complete and there is nothing
        # to play.

        nothing_to_play = True
        # playable_trailers_map = None  # type: Dict[str,
        # PlayableTrailersContainer]
        # type:
        playable_trailers_map = PlayableTrailersContainer.get_instances()
        # Dict[str, PlayableTrailersContainer]

        # Need to use the same projected sizes throughout this method.

        projected_sizes_map = {}
        for source in playable_trailers_map:
            playable_trailers = playable_trailers_map[source]
            if not playable_trailers.is_playable_trailers():
                continue

            movie_data = playable_trailers.get_movie_data()
            self.throw_exception_on_forced_to_stop(movie_data=movie_data)
            number_of_trailers = movie_data.get_number_of_movies()
            trailers_queue_size = movie_data.get_discovered_trailer_queue_size(
            )
            if self.logger.isEnabledFor(LazyLogger.DISABLED):
                self.logger.debug_extra_verbose(
                    source, 'size:', number_of_trailers,
                    'discoveredTrailersQueue size:', trailers_queue_size,
                    'readyToPlayQueue size:',
                    playable_trailers.get_ready_to_play_queue().qsize(),
                    'trailersToFetchQueue size:',
                    movie_data.get_trailers_to_fetch_queue_size())

            projected_size = movie_data.get_projected_number_of_trailers()
            projected_sizes_map[source] = projected_size
            total_number_of_trailers += projected_size
            if not movie_data.is_discovery_complete(
            ) or number_of_trailers != 0:
                nothing_to_play = False

            # If we have played everything, then we start over.

            if (trailers_queue_size == 0
                    and playable_trailers.is_playable_trailers()):
                if self.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE):
                    self.logger.debug(
                        'Shuffling because discoveredTrailerQueue empty',
                        trace=Trace.TRACE_DISCOVERY)
                movie_data.shuffle_discovered_trailers(mark_unplayed=True)

        if nothing_to_play:
            if self.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE):
                self.logger.debug_verbose('Nothing to Play! numTrailers:',
                                          total_number_of_trailers)
            raise StopIteration
            # return None

        # Now, randomly pick playable_trailers to get a trailer from based upon
        # the number of trailers in each.
        #
        # We loop here because there may not be any trailers in the readyToPlayQueue
        # for a specific playable_trailers

        trailer = None
        attempts = 0
        while trailer is None and attempts < 10:
            try:
                trailer_index_to_play = DiskUtils.RandomGenerator.randint(
                    0, total_number_of_trailers - 1)
                if self.logger.isEnabledFor(LazyLogger.DISABLED):
                    self.logger.debug_extra_verbose(
                        'PlayableTrailerService.next trailer_index_to_play:',
                        trailer_index_to_play)
            except (ValueError) as e:  # Empty range
                Monitor.throw_exception_if_abort_requested(timeout=0.10)
                continue

            total_number_of_trailers = 0
            found_playable_trailers = None
            for source in playable_trailers_map:
                playable_trailers = playable_trailers_map[source]
                if not playable_trailers.is_playable_trailers():
                    continue

                movie_data = playable_trailers.get_movie_data()
                self.throw_exception_on_forced_to_stop(movie_data=movie_data)

                projected_size = playable_trailers.get_projected_number_of_trailers(
                )
                if self.logger.isEnabledFor(LazyLogger.DISABLED):
                    self.logger.debug_extra_verbose('source:', source,
                                                    'projected size:',
                                                    projected_size)
                total_number_of_trailers += projected_sizes_map[source]

                if self.logger.isEnabledFor(LazyLogger.DISABLED):
                    self.logger.debug_extra_verbose(
                        'total_number_of_trailers:', total_number_of_trailers)
                if trailer_index_to_play < total_number_of_trailers:
                    found_playable_trailers = playable_trailers
                    break

            try:
                attempts += 1
                if attempts > 1 and self.logger.isEnabledFor(
                        LazyLogger.DEBUG_VERBOSE):
                    self.logger.debug_verbose(
                        'PlayableTrailerService.next Attempt:', attempts,
                        'manager:', found_playable_trailers.__class__.__name__)
                trailer = found_playable_trailers.get_next_movie()
                TrailerCache.validate_cached_files(trailer)

                # If cached trailer is invalid, then skip over this trailer.

                if trailer[
                        Movie.
                        DISCOVERY_STATE] != Movie.DISCOVERY_READY_TO_DISPLAY:
                    trailer = None
                else:
                    found_playable_trailers.set_starving(False)
                    title = trailer[Movie.TITLE] + \
                        ' : ' + trailer[Movie.TRAILER]
            except queue.Empty:
                found_playable_trailers.set_starving(True)
                trailer = None

        duration_of_first_attempt = datetime.datetime.now() - start_time
        second_attempt_start_time = None
        second_method_attempts = None

        if trailer is None:
            if self.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE):
                self.logger.debug_verbose(
                    'Trailer not found by preferred method', trace=Trace.TRACE)

            # Alternative method is to pick a random PlayableTrailersContainer to start
            # with and then find one that has a trailer. Otherwise, camp out.

            second_attempt_start_time = datetime.datetime.now()
            second_method_attempts = 0
            iteration = 0
            playable_trailers_list = [*playable_trailers_map.keys()]
            DiskUtils.RandomGenerator.shuffle(playable_trailers_list)
            for source in itertools.cycle(playable_trailers_list):
                try:
                    playable_trailers = playable_trailers_map[source]
                    movie_data = playable_trailers.get_movie_data()
                    self.throw_exception_on_forced_to_stop(
                        movie_data=movie_data)

                    if (playable_trailers.get_number_of_playable_movies() == 0
                            and playable_trailers.get_movie_data(
                            ).get_number_of_movies() > 0
                            and playable_trailers.is_playable_trailers()):
                        if self.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE):
                            self.logger.debug_verbose(
                                'Shuffling because',
                                'discoveredTrailerQueue empty',
                                'source:',
                                source,
                                trace=Trace.TRACE_DISCOVERY)
                        playable_trailers.get_movie_data().\
                            shuffle_discovered_trailers(mark_unplayed=True)
                    trailer = playable_trailers.get_next_movie()

                    # If cached trailer is invalid, then skip over this
                    # trailer.

                    if trailer[
                            Movie.
                            DISCOVERY_STATE] != Movie.DISCOVERY_READY_TO_DISPLAY:
                        trailer = None

                    if trailer is not None:
                        break
                except queue.Empty:
                    pass  # try again

                recently_played_trailers = \
                    PlayableTrailersContainer.get_recently_played_trailers()
                if len(recently_played_trailers) != 0:
                    recently_played_list = list(
                        recently_played_trailers.values())
                    trailer_index_to_play = DiskUtils.RandomGenerator.randint(
                        0,
                        len(recently_played_trailers) - 1)
                    trailer = recently_played_list[trailer_index_to_play]
                    break

                iteration += 1
                if iteration % len(playable_trailers_list) == 0:
                    second_method_attempts += 1
                    Monitor.throw_exception_if_abort_requested(timeout=0.5)

        if trailer is None:
            self._next_failures += 1
        else:
            trailer[Movie.TRAILER_PLAYED] = True
            title = trailer[Movie.TITLE] + ' : ' + trailer[Movie.TRAILER]

        duration = datetime.datetime.now() - start_time
        self._next_total_duration += duration.seconds
        self._next_calls += 1
        self._next_attempts += attempts
        self._next_total_first_method_attempts += attempts

        Statistics.add_next_trailer_wait_time(
            duration_of_first_attempt.seconds, attempts)
        if second_method_attempts is not None:
            self._next_attempts += second_method_attempts
            self._next_second_attempts += second_method_attempts
            second_duration = datetime.datetime.now(
            ) - second_attempt_start_time
            self._next_second_total_Duration += second_duration.seconds
            Statistics.add_next_trailer_second_attempt_wait_time(
                second_duration.seconds, second_method_attempts)

        if trailer is None:
            raise StopIteration

        if self.logger.isEnabledFor(LazyLogger.DEBUG_VERBOSE):
            self.logger.debug_verbose('Playing:',
                                      trailer[Movie.DETAIL_TITLE],
                                      trace=Trace.TRACE)
        Debug.validate_detailed_movie_properties(trailer)

        # Periodically report on played movie statistics

        self._played_movies_count += 1
        if self.logger.is_trace_enabled(Trace.TRACE_PLAY_STATS):
            if (self._played_movies_count % 100) == 0:
                PlayStatistics.report_play_count_stats()

        return trailer