summaryrefslogtreecommitdiff
path: root/youtube_dl/cache.py
blob: 7bdade1bdb49a7406457688400830a91a98ef186 (plain)
    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('.')

Generated by cgit