2 # GObject-Introspection - a framework for introspecting GObject libraries
3 # Copyright (C) 2008 Johan Dahlin
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2 of the License, or (at your option) any later version.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the
17 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 # Boston, MA 02111-1307, USA.
30 homedir = os.environ.get('HOME')
33 if not os.path.exists(homedir):
36 cachedir = os.path.join(homedir, '.cache')
37 if not os.path.exists(cachedir):
39 os.mkdir(cachedir, 0755)
43 scannerdir = os.path.join(cachedir, 'g-ir-scanner')
44 if not os.path.exists(scannerdir):
45 os.mkdir(scannerdir, 0755)
46 # If it exists and is a file, don't cache at all
47 elif not os.path.isdir(scannerdir):
52 class CacheStore(object):
56 self._directory = _get_cachedir()
58 if e.errno != errno.EPERM:
60 self._directory = None
62 def _get_filename(self, filename):
63 # If we couldn't create the directory we're probably
64 # on a read only home directory where we just disable
65 # the cache all together.
66 if self._directory is None:
68 hexdigest = hashlib.sha1(filename).hexdigest()
69 return os.path.join(self._directory, hexdigest)
71 def _cache_is_valid(self, store_filename, filename):
72 return (os.stat(store_filename).st_mtime >=
73 os.stat(filename).st_mtime)
75 def _remove_filename(self, filename):
80 if e.errno == errno.EACCES:
86 if e.errno == errno.ENOENT:
91 def store(self, filename, data):
92 store_filename = self._get_filename(filename)
93 if store_filename is None:
96 if (os.path.exists(store_filename) and
97 self._cache_is_valid(store_filename, filename)):
100 tmp_fd, tmp_filename = tempfile.mkstemp(prefix='g-ir-scanner-cache-')
102 cPickle.dump(data, os.fdopen(tmp_fd, 'w'))
104 # No space left on device
105 if e.errno == errno.ENOSPC:
106 self._remove_filename(tmp_filename)
112 shutil.move(tmp_filename, store_filename)
115 if e.errno == errno.EACCES:
116 self._remove_filename(tmp_filename)
120 def load(self, filename):
121 store_filename = self._get_filename(filename)
122 if store_filename is None:
125 fd = open(store_filename)
127 if e.errno == errno.ENOENT:
131 if not self._cache_is_valid(store_filename, filename):
134 data = cPickle.load(fd)
135 except (AttributeError, EOFError, ValueError, cPickle.BadPickleGet):
136 # Broken cache entry, remove it
137 self._remove_filename(store_filename)