コード例 #1
0
    def is_trailer_from_cache(cls, path):
        #  type: (str) -> bool
        """

        :param path:
        :return:
        """
        cache_path_prefix = Settings.get_downloaded_trailer_cache_path()
        if path.startswith(cache_path_prefix):
            return True
        return False
コード例 #2
0
    def get_stats_for_caches(self) -> Dict[str, UsageData]:
        """
            Get disk usage information for the caches.
            Returns a map of UsageData for each cache. Primarily used
            by garbage collection and reporting.

        :return:
        """
        local_class = CacheManager
        TRAILER_PATTERN = re.compile(r'^.*-trailer\..*$')
        JSON_PATTERN = re.compile(r'^.*\.json$')
        TFH_PATTERN = re.compile(r'^.*-movie\..*$')

        TRAILER_TYPE = 'trailer'
        JSON_TYPE = 'json'

        # When the Trailer Cache and Data Cache (.json) are the same

        if (Settings.get_downloaded_trailer_cache_path() ==
                Settings.get_remote_db_cache_path()):
            usage_data_map = DiskUtils.get_stats_for_path(
                Settings.get_downloaded_trailer_cache_path(), {
                    'trailer': (TRAILER_PATTERN, TRAILER_TYPE),
                    'json': (JSON_PATTERN, JSON_TYPE),
                    'tfh': (TFH_PATTERN, TRAILER_TYPE)
                })
        else:
            # When Trailer Cache and Data Cache are different directories.

            usage_data_map = DiskUtils.get_stats_for_path(
                Settings.get_downloaded_trailer_cache_path(), {
                    'trailer': (TRAILER_PATTERN, TRAILER_TYPE),
                    'tfh': (TFH_PATTERN, TRAILER_TYPE)
                })
            json_usage_data = DiskUtils.get_stats_for_path(
                Settings.get_remote_db_cache_path(),
                {'json': (JSON_PATTERN, JSON_TYPE)})
            usage_data_map['json'] = json_usage_data['json']

        return usage_data_map
コード例 #3
0
    def record_played_trailer(self, trailer, use_movie_path=False, msg=''):
        # type: (Dict[str, Any], bool, str) -> None
        """

        :param trailer:
        :param use_movie_path:
        :param msg:
        :return:
        """
        if self.playlist_format:
            use_movie_path = True

        name = trailer.get(Movie.TITLE, 'unknown Title')
        year = '(' + str(trailer.get(Movie.YEAR, 'unknown Year')) + ')'
        movie_type = trailer.get(Movie.TYPE, 'Unknown MovieType')
        movie_path = trailer.get(Movie.FILE, None)
        if movie_path is None:
            if use_movie_path:  # Nothing to do if there is no movie path
                return
            movie_path = 'Unknown movie path'
        trailer_path = trailer.get(Movie.TRAILER, '')
        cache_path_prefix = Settings.get_downloaded_trailer_cache_path()
        trailer_path = trailer_path.replace(cache_path_prefix, '<cache_path>')
        missing_detail_msg = Messages.get_msg(Messages.MISSING_DETAIL)
        if trailer_path == missing_detail_msg:
            trailer_path = ''
        if name is None:
            name = 'name is None'
        if year is None:
            year = 'year is None'
        if movie_type is None:
            movie_type = 'movie_type is None'

        path = trailer_path
        if use_movie_path:
            path = movie_path

        formatted_title = Messages.get_formated_title(trailer)

        with Playlist._playlist_lock:
            # file closed
            if self._file is None:
                return

        if self.playlist_format:
            line = Playlist.PLAYLIST_ENTRY_PREFIX + name + '\n'
            line += path + '\n'
        else:
            line = name + '  ' + year + '  # path: ' + formatted_title + ' ' +\
                path + ' ' + msg + '\n'
        self._file.writelines(line)
コード例 #4
0
 def is_trailer_from_cache(path):
     cache_path_prefix = Settings.get_downloaded_trailer_cache_path()
     if path.startswith(cache_path_prefix):
         return True
     return False
コード例 #5
0
    def get_stats_for_path(
            cls, top: str, patterns: Dict[str,
                                          Tuple[Pattern[str],
                                                str]]) -> Dict[str, UsageData]:
        """
            Gets disk usage information for a subtree of the filesystem

        :param top:
        :param patterns:
        :return:
        """
        usage_data = None
        fileMap = {}

        usage_data_map = {}
        try:
            free = 0
            total = 0
            used = 0
            size_on_disk = 0
            block_size = None
            # Available in Python >= 3.3
            # shutil.disk_usage(top)
            # _ntuple_diskusage = collections.namedtuple('usage', 'total used free')

            # units in bytes
            disk_usage = cls.disk_usage(top)

            if disk_usage is not None:
                free = disk_usage['free']
                total = disk_usage['total']
                used = disk_usage['used']
                block_size = disk_usage['blocksize']

            #statvfs = os.statvfs(top)
            #block_size = statvfs.f_bsize
            #free = int(statvfs.f_bavail * statvfs.f_frsize / megaByte)
            #total = int(statvfs.f_blocks * statvfs.f_frsize / megaByte)
            # used = int((statvfs.f_blocks - statvfs.f_bfree) *
            #           statvfs.f_frsize / megaByte)
            # st.f_blocks is # blocks in filesystem
            # f_bavail free blocks for non-super user
            # f_bsize # preferred block size
            # f_frsize # fundamental file system block size
            # f_blocks total blocks in filesystem
            # f_bfree total # free blocks in filesystem

            for cache_name, (pattern, cache_type) in patterns.items():
                usage_data = UsageData(cache_name, pattern)
                usage_data.set_free_size(free)
                usage_data.set_total_size(total)
                usage_data.set_used_space(used)
                usage_data.set_block_size(block_size)
                usage_data_map[cache_name] = usage_data

            db_cache_file_expiration_days = \
                Settings.get_expire_remote_db_cache_entry_days()
            db_cache_file_expiration_seconds =\
                db_cache_file_expiration_days * 24 * 60 * 60
            db_cache_path_top = Settings.get_remote_db_cache_path()

            trailer_cache_file_expiration_days = Settings.get_expire_trailer_cache_days(
            )
            trailer_cache_file_expiration_seconds = \
                trailer_cache_file_expiration_days * 24 * 60 * 60
            trailer_cache_path_top = Settings.get_downloaded_trailer_cache_path(
            )
            now = datetime.datetime.now()

            found_directories = set()
            for root, dirs, files in os.walk(top):
                for filename in files:
                    for cache_name, (pattern, cache_type) in patterns.items():
                        Monitor.throw_exception_if_abort_requested()
                        usage_data = usage_data_map[cache_name]
                        if pattern.match(filename):
                            path = os.path.join(root, filename)
                            mod_time = now
                            try:
                                if not os.path.isdir(path):
                                    st = os.stat(path)
                                    mod_time = datetime.datetime.fromtimestamp(
                                        st.st_mtime)
                                    size_in_blocks = st.st_size
                                    size_on_disk = (
                                        (size_in_blocks - 1) / block_size +
                                        1) * block_size
                                else:
                                    found_directories.add(path)
                            except OSError as e:
                                continue  # File doesn't exist
                            except Exception as e:
                                cls._logger.exception('')
                                continue

                            deleted = False
                            try:
                                if (top == db_cache_path_top
                                        and cache_type == 'json'):
                                    if ((now - mod_time).total_seconds() >
                                            db_cache_file_expiration_seconds):
                                        if cls._logger.isEnabledFor(
                                                LazyLogger.INFO):
                                            cls._logger.info('deleting:', path)
                                        os.remove(path)
                                        deleted = True
                                        usage_data.add_to_disk_deleted(
                                            size_on_disk)
                                    break  # Next file

                                if (top == trailer_cache_path_top
                                        and cache_type == 'trailer'):
                                    if ((now - mod_time).total_seconds(
                                    ) > trailer_cache_file_expiration_seconds):
                                        if cls._logger.isEnabledFor(
                                                LazyLogger.INFO):
                                            cls._logger.info('deleting:', path)
                                        os.remove(path)
                                        deleted = True
                                        usage_data.add_to_disk_deleted(
                                            size_on_disk)
                                    break  # Next file

                            except AbortException:
                                reraise(*sys.exc_info())
                            except Exception as e:
                                cls._logger.exception('')

                            if not deleted:
                                file_data = FileData(path, mod_time,
                                                     size_on_disk)
                                usage_data.add_file_data(file_data)
                                usage_data.add_to_disk_used_by_cache(
                                    size_on_disk)

            for directory in found_directories:
                try:
                    os.rmdir(directory)
                except Exception as e:
                    pass

        except AbortException:
            reraise(*sys.exc_info())

        except Exception as e:
            cls._logger.exception('')

        cls._logger.exit()
        return usage_data_map
コード例 #6
0
    def get_trailer_cache_file_path_for_movie_id(cls, trailer, orig_file_name,
                                                 normalized):
        # type: (Dict[str, Any], str, bool) -> Union[str, None]
        """
            Generates the path for a file in the cache
            for a trailer for given movie.

        :param trailer:
        :param orig_file_name:
        :param normalized:
        :return:
        """
        path = None
        movie_id = None
        source = None
        try:
            valid_sources = [Movie.LIBRARY_SOURCE, Movie.TMDB_SOURCE,
                             Movie.ITUNES_SOURCE, Movie.TFH_SOURCE]
            if trailer[Movie.SOURCE] in valid_sources:
                movie_id = Cache.get_video_id(trailer)
                source = trailer[Movie.SOURCE]
            else:
                if cls._logger.isEnabledFor(LazyLogger.DEBUG):
                    cls._logger.debug('Not valid video source title:',
                                      trailer[Movie.TITLE],
                                      'source:', trailer[Movie.SOURCE])

            if movie_id is not None:

                # movie_id may begin with an '_'.

                prefix = movie_id + '_'
                folder = None
                if source == Movie.LIBRARY_SOURCE:
                    folder = movie_id[0]
                elif source == Movie.TMDB_SOURCE:
                    x = prefix.split('_', 1)
                    folder = 't' + x[1][0]
                elif source == Movie.TFH_SOURCE:
                    x = prefix.split('_', 1)
                    folder = 'h' + x[1][0]
                elif source == Movie.ITUNES_SOURCE:
                    x = prefix.split('_', 1)
                    folder = 'a' + movie_id[1][0]

                # Possible that trailer was downloaded into cache

                orig_file_name = re.sub(
                    r'^' + re.escape(prefix), '', orig_file_name)

                if normalized:
                    if 'normalized_' in orig_file_name:
                        cls._logger.debug('Already normalized:',
                                          trailer.get(
                                              Movie.TITLE, 'no title'),
                                          'orig_file_name:', orig_file_name)
                        file_name = prefix + orig_file_name
                    else:
                        file_name = prefix + 'normalized_' + orig_file_name
                else:
                    file_name = prefix + orig_file_name

                path = os.path.join(Settings.get_downloaded_trailer_cache_path(),
                                    folder, file_name)
                # Should not be needed
                path = xbmcvfs.validatePath(path)

        except AbortException:
            reraise(*sys.exc_info())
        except Exception as e:
            title = trailer.get(Movie.TITLE, 'no title')
            cls._logger.exception('title:', title)

            path = None

        if cls._logger.isEnabledFor(LazyLogger.DEBUG_EXTRA_VERBOSE):
            cls._logger.debug_extra_verbose('Path:', path)
        return path