flexget.plugins.cached_input
Covered: 52 lines
Missed: 0 lines
Skipped 29 lines
Percent: 100 %
 1
import copy
 2
import logging
 3
from flexget.plugin import register_plugin
 5
log = logging.getLogger('cached')
 8
class cached(object):
10
    """
11
    Implements transparent caching decorator @cached for inputs.
13
    Decorator has two parameters
15
    :name: in which the configuration is present in feeds configuration.
16
    :key: in which the configuration has the cached resource identifier (ie. url). If the :key: is not
17
    given or present in the configuration :name: is expected to be a cache name (ie. url)
19
    Configuration assumptions may make this unusable in some (future) inputs
20
    """
22
    cache = {}
24
    def __init__(self, name, key=None):
25
        self.name = name
26
        self.key = key
28
    def __call__(self, func):
30
        def wrapped_func(*args, **kwargs):
33
            feed = args[1]
36
            if not self.name in feed.config:
37
                raise Exception('@cache config name %s is not configured in feed %s' % (self.name, feed.name))
38
            config = feed.config[self.name]
40
            log.log(5, 'config: %s' % config)
41
            log.log(5, 'self.name: %s' % self.name)
42
            log.log(5, 'self.key: %s' % self.key)
44
            if isinstance(config, dict) and self.key in config:
45
                name = feed.config[self.name][self.key]
46
            else:
47
                name = feed.config[self.name]
49
            log.debug('cache name: %s (has: %s)' % (name, ', '.join(self.cache.keys())))
51
            if name in self.cache:
52
                log.log(5, 'cache hit')
53
                count = 0
54
                for entry in self.cache[name]:
55
                    fresh = copy.deepcopy(entry)
56
                    feed.entries.append(fresh)
57
                    count += 1
58
                if count > 0:
59
                    feed.verbose_progress('Restored %s entries from cache' % count, log)
60
            else:
61
                log.log(5, 'cache miss')
63
                func(*args, **kwargs)
65
                log.debug('storing to cache %s %s entries' % (name, len(feed.entries)))
66
                self.cache[name] = copy.deepcopy(feed.entries)
68
        return wrapped_func
71
class CacheClearer:
73
    def on_process_start(self, feed):
74
        """Internal. Clears the input cache on every process"""
77
        global cache
78
        cache = {}
80
register_plugin(CacheClearer, 'cache_clearer', builtin=True)