From bad81ab61eb44a6c209345a0863f76626aaa6534 Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Sun, 21 Feb 2010 17:17:37 +0000 Subject: [PATCH] Rank digest algorithms and download using the best available --- zeroinstall/injector/fetch.py | 14 +++++++++----- zeroinstall/injector/model.py | 1 - zeroinstall/zerostore/manifest.py | 12 +++++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/zeroinstall/injector/fetch.py b/zeroinstall/injector/fetch.py index b6013b9..c43193e 100644 --- a/zeroinstall/injector/fetch.py +++ b/zeroinstall/injector/fetch.py @@ -300,11 +300,15 @@ class Fetcher(object): assert retrieval_method from zeroinstall.zerostore import manifest - for required_digest in impl.digests: - alg = required_digest.split('=', 1)[0] - if alg in manifest.algorithms: - break - else: + best = None + for digest in impl.digests: + alg_name = digest.split('=', 1)[0] + alg = manifest.algorithms.get(alg_name, None) + if alg and (best is None or best.rating < alg.rating): + best = alg + required_digest = digest + + if best is None: if not impl.digests: raise SafeException(_("No given for '%(implementation)s' version %(version)s") % {'implementation': impl.feed.get_name(), 'version': impl.get_version()}) diff --git a/zeroinstall/injector/model.py b/zeroinstall/injector/model.py index 9d27b06..77b8fdc 100644 --- a/zeroinstall/injector/model.py +++ b/zeroinstall/injector/model.py @@ -759,7 +759,6 @@ class ZeroInstallFeed(object): for aname, avalue in elem.attrs.iteritems(): if ' ' not in aname: impl.digests.append('%s=%s' % (aname, avalue)) - impl.digests.sort() elif elem.name == 'recipe': recipe = Recipe() for recipe_step in elem.childNodes: diff --git a/zeroinstall/zerostore/manifest.py b/zeroinstall/zerostore/manifest.py index 09ec81b..36d94bc 100644 --- a/zeroinstall/zerostore/manifest.py +++ b/zeroinstall/zerostore/manifest.py @@ -40,6 +40,8 @@ except: class Algorithm: """Abstract base class for algorithms. An algorithm knows how to generate a manifest from a directory tree. + @ivar rating: how much we like this algorithm (higher is better) + @type rating: int """ def generate_manifest(self, root): """Returns an iterator that yields each line of the manifest for the directory @@ -57,6 +59,9 @@ class Algorithm: class OldSHA1(Algorithm): """@deprecated: Injector versions before 0.20 only supported this algorithm.""" + + rating = 10 + def generate_manifest(self, root): def recurse(sub): # To ensure that a line-by-line comparison of the manifests @@ -414,13 +419,14 @@ def _copy_files(alg, wanted, source, target): class HashLibAlgorithm(Algorithm): new_digest = None # Constructor for digest objects - def __init__(self, name): + def __init__(self, name, rating): if name == 'sha1': self.new_digest = sha1_new self.name = 'sha1new' else: self.new_digest = getattr(hashlib, name) self.name = name + self.rating = rating def generate_manifest(self, root): def recurse(sub): @@ -477,11 +483,11 @@ class HashLibAlgorithm(Algorithm): algorithms = { 'sha1': OldSHA1(), - 'sha1new': HashLibAlgorithm('sha1'), + 'sha1new': HashLibAlgorithm('sha1', 50), } if hashlib is not None: - algorithms['sha256'] = HashLibAlgorithm('sha256') + algorithms['sha256'] = HashLibAlgorithm('sha256', 80) def fixup_permissions(root): """Set permissions recursively for children of root: -- 2.11.4.GIT