cache.py (2981B)
1 from __future__ import unicode_literals 2 3 import errno 4 import io 5 import json 6 import os 7 import re 8 import shutil 9 import traceback 10 11 from .compat import compat_getenv 12 from .utils import ( 13 expand_path, 14 write_json_file, 15 ) 16 17 18 class Cache(object): 19 def __init__(self, ydl): 20 self._ydl = ydl 21 22 def _get_root_dir(self): 23 res = self._ydl.params.get('cachedir') 24 if res is None: 25 cache_root = compat_getenv('XDG_CACHE_HOME', '~/.cache') 26 res = os.path.join(cache_root, 'youtube-dl') 27 return expand_path(res) 28 29 def _get_cache_fn(self, section, key, dtype): 30 assert re.match(r'^[a-zA-Z0-9_.-]+$', section), \ 31 'invalid section %r' % section 32 assert re.match(r'^[a-zA-Z0-9_.-]+$', key), 'invalid key %r' % key 33 return os.path.join( 34 self._get_root_dir(), section, '%s.%s' % (key, dtype)) 35 36 @property 37 def enabled(self): 38 return self._ydl.params.get('cachedir') is not False 39 40 def store(self, section, key, data, dtype='json'): 41 assert dtype in ('json',) 42 43 if not self.enabled: 44 return 45 46 fn = self._get_cache_fn(section, key, dtype) 47 try: 48 try: 49 os.makedirs(os.path.dirname(fn)) 50 except OSError as ose: 51 if ose.errno != errno.EEXIST: 52 raise 53 write_json_file(data, fn) 54 except Exception: 55 tb = traceback.format_exc() 56 self._ydl.report_warning( 57 'Writing cache to %r failed: %s' % (fn, tb)) 58 59 def load(self, section, key, dtype='json', default=None): 60 assert dtype in ('json',) 61 62 if not self.enabled: 63 return default 64 65 cache_fn = self._get_cache_fn(section, key, dtype) 66 try: 67 try: 68 with io.open(cache_fn, 'r', encoding='utf-8') as cachef: 69 return json.load(cachef) 70 except ValueError: 71 try: 72 file_size = os.path.getsize(cache_fn) 73 except (OSError, IOError) as oe: 74 file_size = str(oe) 75 self._ydl.report_warning( 76 'Cache retrieval from %s failed (%s)' % (cache_fn, file_size)) 77 except IOError: 78 pass # No cache available 79 80 return default 81 82 def remove(self): 83 if not self.enabled: 84 self._ydl.to_screen('Cache is disabled (Did you combine --no-cache-dir and --rm-cache-dir?)') 85 return 86 87 cachedir = self._get_root_dir() 88 if not any((term in cachedir) for term in ('cache', 'tmp')): 89 raise Exception('Not removing directory %s - this does not look like a cache dir' % cachedir) 90 91 self._ydl.to_screen( 92 'Removing cache dir %s .' % cachedir, skip_eol=True) 93 if os.path.exists(cachedir): 94 self._ydl.to_screen('.', skip_eol=True) 95 shutil.rmtree(cachedir) 96 self._ydl.to_screen('.')