diff options
author | Andy Doan <andy.doan@linaro.org> | 2015-06-08 10:20:17 -0500 |
---|---|---|
committer | Andy Doan <andy.doan@linaro.org> | 2015-07-07 08:31:27 -0500 |
commit | 8f2768db323a3462c6d4963cead5aa8029f37f5b (patch) | |
tree | e6008a3cc47607e81faef86b5cc484e53e74af80 | |
parent | c5a1adcdb82f15f5e1b5541c5e6a9faa861d8815 (diff) |
move more build-info handling into artifact base
This allows us to make the logic smart enough to cache the
build-info buffer for a given directory listing. This is more
efficient locally, and will be required for S3 to perform well.
Change-Id: I8c28c35dde535a56ec40fcc7e0cafa561f2703c6
-rw-r--r-- | license_protected_downloads/common.py | 40 | ||||
-rw-r--r-- | license_protected_downloads/tests/test_common.py | 18 |
2 files changed, 49 insertions, 9 deletions
diff --git a/license_protected_downloads/common.py b/license_protected_downloads/common.py index 5790f9b..23aff14 100644 --- a/license_protected_downloads/common.py +++ b/license_protected_downloads/common.py @@ -87,12 +87,12 @@ def find_artifact(request, path): if fullpath is None: raise Http404 if os.path.isfile(fullpath) or os.path.isdir(fullpath): - return LocalArtifact('', path, False, basepath) + return LocalArtifact(None, '', path, False, basepath) fullpath = _handle_wildcard(request, fullpath) if fullpath: basepath, path = os.path.split(fullpath) - return LocalArtifact('', path, False, basepath) + return LocalArtifact(None, '', path, False, basepath) raise Http404 @@ -130,6 +130,17 @@ def _sizeof_fmt(num): return "%3.1f%s" % (num, 'T') +def cached_prop(fn): + attr_name = '_cached_' + fn.__name__ + + @property + def _cached_prop(self): + if not hasattr(self, attr_name): + setattr(self, attr_name, fn(self)) + return getattr(self, attr_name) + return _cached_prop + + class Artifact(object): def __init__(self, urlbase, file_name, size, mtime, human_readable): self.urlbase = urlbase @@ -172,7 +183,12 @@ class Artifact(object): raise NotImplementedError() def get_build_info(self): - raise NotImplementedError() + buf = self.build_info_buffer + if buf: + sp = fn = self.urlbase[1:] + if not self.isdir(): + fn = sp + '/' + self.file_name + return buildinfo.BuildInfoBase(fn, sp, buf) def get_listing(self): if self.isdir(): @@ -287,7 +303,8 @@ class Artifact(object): class LocalArtifact(Artifact): '''An artifact that lives on the local filesystem''' - def __init__(self, urlbase, file_name, human_readable, path): + def __init__(self, parent, urlbase, file_name, human_readable, path): + self.parent = parent self.full_path = os.path.join(path, file_name) size = mtime = 0 @@ -310,9 +327,16 @@ class LocalArtifact(Artifact): mtype = 'text' return mtype - def get_build_info(self): - if buildinfo.BuildInfo.build_info_exists(self.full_path): - return buildinfo.BuildInfo(self.full_path) + @cached_prop + def build_info_buffer(self): + if self.parent and not self.isdir(): + return self.parent.build_info_buffer + + p = buildinfo.BuildInfo.get_search_path(self.full_path) + p = os.path.join(p, 'BUILD-INFO.txt') + if os.path.exists(p): + with open(p) as f: + return f.read() def get_eulas(self): if self.isdir(): @@ -329,7 +353,7 @@ class LocalArtifact(Artifact): def dir_list(artifact, human_readable=True): path = artifact.full_path url = artifact.url() - artifacts = [LocalArtifact(url, x, human_readable, path) + artifacts = [LocalArtifact(artifact, url, x, human_readable, path) for x in os.listdir(path)] artifacts.sort(_sort_artifacts) diff --git a/license_protected_downloads/tests/test_common.py b/license_protected_downloads/tests/test_common.py index eec6b3d..b8b070a 100644 --- a/license_protected_downloads/tests/test_common.py +++ b/license_protected_downloads/tests/test_common.py @@ -20,9 +20,25 @@ class CommonTests(unittest.TestCase): (['10', 'foo', '100', 'latest'], ['latest', '10', '100', 'foo']), ] for files, expected in patterns: - artifacts = [common.LocalArtifact('', x, True, '') for x in files] + artifacts = [common.LocalArtifact(None, '', x, True, '') + for x in files] artifacts.sort(common._sort_artifacts) self.assertEqual(expected, [x.file_name for x in artifacts]) + def test_cached_property(self): + class Foo(object): + def __init__(self): + self.count = 0 + + @common.cached_prop + def bar(self): + v = self.count + self.count += 1 + return v + + f = Foo() + self.assertEqual(0, f.bar) + self.assertEqual(0, f.bar) + if __name__ == '__main__': unittest.main() |