Code: Alles auswählen
from contextlib import closing
import logging
import sys
if sys.version_info >= (3, 0):
_is_py3 = True
from urllib.request import build_opener, ContentTooShortError
else:
_is_py3 = False
from urllib2 import build_opener
from urllib import FancyURLopener
logger = logging.getLogger('glad.opener')
def build_urllib_opener(user_agent, *args, **kwargs):
if _is_py3:
return None
class UrllibURLOpener(FancyURLopener):
version = user_agent
return UrllibURLOpener(*args, **kwargs)
def _urlretrieve_with_opener(opener, url, filename, data=None):
if not _is_py3:
raise SyntaxError('Only call this in Python 3 code.')
# borrowed from the original implementation at urllib.request.urlretrieve.
with closing(opener.open(url, data=data)) as src:
headers = src.info()
with open(filename, 'wb') as dest:
result = filename, headers
bs = 1024*8
size = -1
read = 0
blocknum = 0
if "content-length" in headers:
size = int(headers["Content-Length"])
while True:
block = src.read(bs)
if not block:
break
read += len(block)
dest.write(block)
blocknum += 1
if size >= 0 and read < size:
raise ContentTooShortError(
'retrieval incomplete: got only %i out of %i bytes'
% (read, size), result)
return result
class URLOpener(object):
"""
Class to download/find Khronos related files, like
the official specs and khrplatform.h.
Can also be used to download files, exists mainly because of
Python 2 and Python 3 incompatibilities.
"""
def __init__(self, user_agent='Mozilla/5.0'):
# the urllib2/urllib.request opener
self.opener = build_opener()
self.opener.addheaders = [('User-agent', user_agent)]
# the urllib opener (Python 2 only)
self.opener2 = build_urllib_opener(user_agent)
def urlopen(self, url, data=None, *args, **kwargs):
"""
Same as urllib2.urlopen or urllib.request.urlopen,
the only difference is that it links to the internal opener.
"""
logger.info('opening: \'%s\'', url)
if data is None:
return self.opener.open(url)
return self.opener.open(url, data)
def urlretrieve(self, url, filename, data=None):
"""
Similar to urllib.urlretrieve or urllib.request.urlretrieve
only that *filname* is required.
:param url: URL to download.
:param filename: Filename to save the content to.
:param data: Valid URL-encoded data.
:return: Tuple containing path and headers.
"""
logger.info('saving: \'%s\' to \'%s\'', url, filename)
if _is_py3:
return _urlretrieve_with_opener(self.opener, url, filename, data=data)
return self.opener2.retrieve(url, filename, data=data)
# just a singleton helper:
_default = None
@classmethod
def default(cls):
if cls._default is None:
cls._default = cls()
return cls._default