Created
June 8, 2012 00:46
-
-
Save Jc2k/2892709 to your computer and use it in GitHub Desktop.
isotoma.buildout.basicauth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Unauthorized(Exception): | |
def __init__(self, code): | |
self.code = code | |
class BaseAdaptor(object): | |
retries = 10 | |
adapts = None | |
param = "url" | |
def __init__(self, credentials): | |
self.credentials = credentials | |
def raise_buildout_error(self, message): | |
raise UserError(message) | |
def raise_http_error(self, code): | |
raise NotImplementedError | |
def call_wrapped(self, *args, **kwargs): | |
raise NotImplementedError | |
def call(self, *args, **kwargs): | |
for i in range(self.retries): | |
try: | |
return self.call_wrapped(*args, **kwargs) | |
except Unauthorized: | |
raise | |
except as e: | |
logger.critical('Attempt %d failed, retrying' % i) | |
logger.debug(e) | |
def __call__(self, *args, **kwargs): | |
# In general, the url we want to download is the first parameter - but this lets us be flexible | |
params, args, kwargs = inspect.getargspec(self.adapts) | |
if not self.param in params: | |
self.raise_buildout_error("Your buildout is really broken") | |
paramidx = params.find(self.param) | |
url = args[paramidx] | |
logger.debug('Downloading URL %s' % strip_auth(url)) | |
for username, password, cache in self.credentials.search(url): | |
new_url = _inject_credentials(url, username, password) | |
try: | |
args[paramidx] = new_url | |
res = self.call(*args, **kwargs) | |
except Unauthorized as e: | |
logger.critical('Could not authenticate %s. (%d)' % (url, e.code)) | |
self.raise_unauthorized(e.code) | |
except: | |
logger.critical('Cannot fetch %s (%r)' % (url, code)) | |
logger.debug(e) | |
raise | |
else: | |
self.credentials.success(url, username, password, cache) | |
return res | |
self.raise_unauthorized(401) | |
class OpenWithAuth(BaseAdaptor): | |
adapts = setuptools.package_index.open_with_auth | |
def raise_http_error(self, code): | |
raise HTTPError(url, code, "HTTP error", {}, None) | |
def call(self, *args, **kwargs): | |
try: | |
self.adapts(*args, **kwargs): | |
except HTTPError as e: | |
if e.code in (401, 403): | |
raise Unauthorized(e.code) | |
raise | |
class UrlRetrieve(BaseAdaptor): | |
adapts = urllib.urlretrieve | |
def raise_http_error(self, code): | |
raise IOError('http error', code, "HTTP error", {}) | |
def call(self, *args, **kwargs): | |
try: | |
self.adapts(*args, **kwargs): | |
except IOError as e: | |
if e.args[0] == "http error" and e.args[1] in (401, 403): | |
raise Unauthorized(a.args[1]) | |
raise | |
setuptools.package_index.open_with_auth = OpenWithAuth(credentials) | |
urllib.urlretrieve = UrlRetrieve(credentials) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment