~le-chi-thu/lava-test/add-verbose-argument

« back to all changes in this revision

Viewing changes to abrek/cache.py

  • Committer: Paul Larson
  • Date: 2011-09-22 17:58:01 UTC
  • mfrom: (92.1.4 using-lava-tool-2)
  • Revision ID: paul.larson@canonical.com-20110922175801-l99rky1xxsr6k3fn
Big refactoring branch to make lava-test use lava-tool.  Thanks to
Zygmunt and ChiThu!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""
2
 
Cache module for Abrek
3
 
"""
4
 
import contextlib
5
 
import hashlib
6
 
import os
7
 
import urllib2
8
 
 
9
 
 
10
 
class AbrekCache(object):
11
 
    """
12
 
    Cache class for Abrek
13
 
    """
14
 
 
15
 
    _instance = None
16
 
 
17
 
    def __init__(self):
18
 
        home = os.environ.get('HOME', '/')
19
 
        basecache = os.environ.get('XDG_CACHE_HOME',
20
 
                     os.path.join(home, '.cache'))
21
 
        self.cache_dir = os.path.join(basecache, 'abrek')
22
 
 
23
 
    @classmethod
24
 
    def get_instance(cls):
25
 
        if cls._instance is None:
26
 
            cls._instance = cls()
27
 
        return cls._instance
28
 
 
29
 
    def open_cached(self, key, mode="r"):
30
 
        """
31
 
        Acts like open() but the pathname is relative to the
32
 
        abrek-specific cache directory.
33
 
        """
34
 
        if "w" in mode and not os.path.exists(self.cache_dir):
35
 
            os.makedirs(self.cache_dir)
36
 
        if os.path.isabs(key):
37
 
            raise ValueError("key cannot be an absolute path")
38
 
        try:
39
 
            stream = open(os.path.join(self.cache_dir, key), mode)
40
 
            yield stream
41
 
        finally:
42
 
            stream.close()
43
 
 
44
 
    def _key_for_url(self, url):
45
 
        return hashlib.sha1(url).hexdigest()
46
 
 
47
 
    def _refresh_url_cache(self, key, url):
48
 
        with contextlib.nested(
49
 
            contextlib.closing(urllib2.urlopen(url)),
50
 
            self.open_cached(key, "wb")) as (in_stream, out_stream):
51
 
            out_stream.write(in_stream.read())
52
 
 
53
 
    @contextlib.contextmanager
54
 
    def open_cached_url(self, url):
55
 
        """
56
 
        Like urlopen.open() but the content may be cached.
57
 
        """
58
 
        # Do not cache local files, this is not what users would expect
59
 
 
60
 
        # workaround - not using cache at all.
61
 
        # TODO: fix this and use the cache
62
 
        # if url.startswith("file://"):
63
 
        if True:
64
 
            stream = urllib2.urlopen(url)
65
 
        else:
66
 
            key = self._key_for_url(url)
67
 
            try:
68
 
                stream = self.open_cached(key, "rb")
69
 
            except IOError as exc:
70
 
                self._refresh_url_cache(key, url)
71
 
                stream = self.open_cached(key, "rb")
72
 
        yield stream
73
 
        stream.close()