1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
import os.path
import logging
import shutil
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
try:
from pkg_resources import resource_exists, resource_stream
except ImportError:
def resource_exists(*args, **kwargs):
return False
def resource_stream(*args, **kwargs):
return None
BASE_PATH = os.path.abspath(os.path.dirname(__file__))
logger = logging.getLogger('glad.files')
class GladFileException(Exception):
pass
def open_local(name, *args, **kwargs):
# use pkg_resources when available, makes it work in zipped modules
# or other environments
if resource_exists(__name__, name):
logger.info('opening packaged resource: %r', name)
return resource_stream(__name__, name)
# fallback to filesystem
logger.info('opening packaged path: %r', name)
local_path = os.path.normpath(os.path.join(BASE_PATH, os.path.join(name)))
if not local_path.startswith(BASE_PATH):
raise GladFileException('unsafe file path, won\'t open {!r}'.format(local_path))
return open(local_path, *args, **kwargs)
class StaticFileOpener(object):
def urlopen(self, url, data=None, *args, **kwargs):
logger.debug('intercepted attempt to retrieve resource: %r', url)
if data is not None:
raise GladFileException('can not resolve requests with payload')
filename = urlparse(url).path.rsplit('/', 1)[-1]
return open_local(filename, 'rb')
def urlretrieve(self, url, filename, *args, **kwargs):
with self.urlopen(url) as src:
with open(filename, 'wb') as dst:
shutil.copyfileobj(src, dst)
|