astrXbian/.install/.kodi/addons/plugin.video.youtube/resources/lib/youtube_plugin/kodion/utils/function_cache.py

117 lines
3.3 KiB
Python

# -*- coding: utf-8 -*-
"""
Copyright (C) 2014-2016 bromix (plugin.video.youtube)
Copyright (C) 2016-2019 plugin.video.youtube
SPDX-License-Identifier: GPL-2.0-only
See LICENSES/GPL-2.0-only for more information.
"""
from functools import partial
import hashlib
from .storage import Storage
class FunctionCache(Storage):
ONE_MINUTE = 60
ONE_HOUR = 60 * ONE_MINUTE
ONE_DAY = 24 * ONE_HOUR
ONE_WEEK = 7 * ONE_DAY
ONE_MONTH = 4 * ONE_WEEK
def __init__(self, filename, max_file_size_mb=5):
max_file_size_kb = max_file_size_mb * 1024
Storage.__init__(self, filename, max_file_size_kb=max_file_size_kb)
self._enabled = True
def clear(self):
self._clear()
def enabled(self):
"""
Enables the caching
:return:
"""
self._enabled = True
def disable(self):
"""
Disable caching e.g. for tests
:return:
"""
self._enabled = False
@staticmethod
def _create_id_from_func(partial_func):
"""
Creats an id from the given function
:param partial_func:
:return: id for the given function
"""
m = hashlib.md5()
m.update(partial_func.func.__module__.encode('utf-8'))
m.update(partial_func.func.__name__.encode('utf-8'))
m.update(str(partial_func.args).encode('utf-8'))
m.update(str(partial_func.keywords).encode('utf-8'))
return m.hexdigest()
def _get_cached_data(self, partial_func):
cache_id = self._create_id_from_func(partial_func)
return self._get(cache_id), cache_id
def get_cached_only(self, func, *args, **keywords):
partial_func = partial(func, *args, **keywords)
# if caching is disabled call the function
if not self._enabled:
return partial_func()
# only return before cached data
data, cache_id = self._get_cached_data(partial_func)
if data is not None:
return data[0]
return None
def get(self, seconds, func, *args, **keywords):
"""
Returns the cached data of the given function.
:param partial_func: function to cache
:param seconds: time to live in seconds
:param return_cached_only: return only cached data and don't call the function
:return:
"""
partial_func = partial(func, *args, **keywords)
# if caching is disabled call the function
if not self._enabled:
return partial_func()
cached_data = None
cached_time = None
data, cache_id = self._get_cached_data(partial_func)
if data is not None:
cached_data = data[0]
cached_time = data[1]
diff_seconds = 0
if cached_time is not None:
# this is so stupid, but we have the function 'total_seconds' only starting with python 2.7
diff_seconds = self.get_seconds_diff(cached_time)
if cached_data is None or diff_seconds > seconds:
cached_data = partial_func()
self._set(cache_id, cached_data)
return cached_data
def _optimize_item_count(self):
# override method from resources/lib/youtube_plugin/kodion/utils/storage.py
# for function cache do not optimize by item count, using database size.
pass