diff options
author | Jannis Pohlmann <jannis.pohlmann@codethink.co.uk> | 2012-04-18 13:29:17 +0100 |
---|---|---|
committer | Jannis Pohlmann <jannis.pohlmann@codethink.co.uk> | 2012-04-18 13:34:25 +0100 |
commit | 5eb0ee253316dc930a4f53a8366764c280ae8fe5 (patch) | |
tree | cb82a6bb54eb4d3bdff1f1a8c82f6af60ee820f8 /morphlib/remoterepocache.py | |
parent | ad31f7608febab04157e015a90f5047a6f0d8d83 (diff) | |
download | morph-5eb0ee253316dc930a4f53a8366764c280ae8fe5.tar.gz |
Add RemoteRepoCache and integrate it into _create_source_pool().
This adds a new setting called 'cache-server' to morph. It is None
by default and should be set to the HTTP URL of a morph cache server
to be used.
The RemoteRepoCache object provides two methods: resolve_ref() and
cat_file(), both of which wrap the communication with the cache
server and return a SHA1 string and file contents, respectively.
The _create_source_pool() method now takes a local and an optional
remote repo cache and tries to do whatever is best to resolve
refs and load morphologies for the Source objects it creates.
Diffstat (limited to 'morphlib/remoterepocache.py')
-rw-r--r-- | morphlib/remoterepocache.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/morphlib/remoterepocache.py b/morphlib/remoterepocache.py new file mode 100644 index 00000000..fd843682 --- /dev/null +++ b/morphlib/remoterepocache.py @@ -0,0 +1,84 @@ +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +import cliapp +import json +import urllib2 +import urlparse + + +class ResolveRefError(cliapp.AppException): + + def __init__(self, repo_name, ref): + cliapp.AppException.__init__( + self, 'Failed to resolve ref %s for repo %s' % + (ref, repo_name)) + + +class CatFileError(cliapp.AppException): + + def __init__(self, repo_name, ref, filename): + cliapp.AppException.__init__( + self, 'Failed to cat file %s in ref %s of repo %s' % + (filename, ref, repo_name)) + + +class RemoteRepoCache(object): + + def __init__(self, server_url, base_urls): + self.server_url = server_url + self._base_urls = base_urls + + def _base_iterate(self, repo_name): + for base_url in self._base_urls: + if not base_url.endswith('/'): + base_url += '/' + repo_url = urlparse.urljoin(base_url, repo_name) + yield repo_url + + def resolve_ref(self, repo_name, ref): + for repo_url in self._base_iterate(repo_name): + try: + return self._resolve_ref_for_repo_url(repo_url, ref) + except: + pass + raise ResolveRefError(repo_name, ref) + + def cat_file(self, repo_name, ref, filename): + for repo_url in self._base_iterate(repo_name): + try: + return self._cat_file_for_repo_url(repo_url, ref, filename) + except: + pass + raise CatFileError(repo_name, ref, filename) + + def _resolve_ref_for_repo_url(self, repo_url, ref): # pragma: no cover + data = self._make_request('sha1s?repo=%s&ref=%s' % (repo_url, ref)) + info = json.loads(data) + return info['sha1'] + + def _cat_file_for_repo_url(self, repo_url, ref, + filename): # pragma: no cover + return self._make_request( + 'files?repo=%s&ref=%s&filename=%s' % (repo_url, ref, filename)) + + def _make_request(self, path): + server_url = self.server_url + if not server_url.endswith('/'): + server_url += '/' + url = urlparse.urljoin(server_url, '/1.0/%s' % path) + handle = urllib2.urlopen(url) + return handle.read() |