diff options
author | Dan McGee <dan@archlinux.org> | 2012-02-18 19:17:00 -0600 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2012-05-02 12:48:59 -0500 |
commit | 12bf4c1b1e7df2d934b9dfde8629137dedeea99f (patch) | |
tree | d5b06a2608bacaa7929386b0aafd167c8e0c6626 /mirrors/views.py | |
parent | d2d0895f13835569ff25a3161ddb94cd655dfd4f (diff) |
Add a smart protocol filter to mirrorlist generator
This will only list FTP mirrors for a given country if there are no HTTP
mirrors available, since FTP must die.
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'mirrors/views.py')
-rw-r--r-- | mirrors/views.py | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/mirrors/views.py b/mirrors/views.py index 6f37ace1..eac78ff2 100644 --- a/mirrors/views.py +++ b/mirrors/views.py @@ -1,4 +1,5 @@ from datetime import timedelta +from itertools import groupby from operator import attrgetter, itemgetter from django import forms @@ -79,8 +80,34 @@ def generate_mirrorlist(request): {'mirrorlist_form': form}) +def default_protocol_filter(original_urls): + key_func = attrgetter('real_country') + sorted_urls = sorted(original_urls, key=key_func) + urls = [] + for _, group in groupby(sorted_urls, key=key_func): + cntry_urls = list(group) + if any(url.protocol.default for url in cntry_urls): + cntry_urls = [url for url in cntry_urls if url.protocol.default] + urls.extend(cntry_urls) + return urls + + +def status_filter(original_urls): + status_info = get_mirror_statuses() + scores = dict((u.id, u.score) for u in status_info['urls']) + urls = [] + for u in original_urls: + u.score = scores.get(u.id, None) + # also include mirrors that don't have an up to date score + # (as opposed to those that have been set with no score) + if (u.id not in scores) or (u.score and u.score < 100.0): + urls.append(u) + # if a url doesn't have a score, treat it as the highest possible + return sorted(urls, key=lambda x: x.score or 100.0) + + def find_mirrors(request, countries=None, protocols=None, use_status=False, - ipv4_supported=True, ipv6_supported=True): + ipv4_supported=True, ipv6_supported=True, smart_protocol=False): if not protocols: protocols = MirrorProtocol.objects.filter(is_download=True) elif hasattr(protocols, 'model') and protocols.model == MirrorProtocol: @@ -102,23 +129,17 @@ def find_mirrors(request, countries=None, protocols=None, use_status=False, ip_version |= Q(has_ipv6=True) qset = qset.filter(ip_version) + if smart_protocol: + urls = default_protocol_filter(qset) + else: + urls = qset + if not use_status: - urls = qset.order_by('mirror__name', 'url') - urls = sorted(urls, key=attrgetter('real_country')) + sort_key = attrgetter('real_country', 'mirror.name', 'url') + urls = sorted(urls, key=sort_key) template = 'mirrors/mirrorlist.txt' else: - status_info = get_mirror_statuses() - scores = dict([(u.id, u.score) for u in status_info['urls']]) - urls = [] - for u in qset: - u.score = scores.get(u.id, None) - # also include mirrors that don't have an up to date score - # (as opposed to those that have been set with no score) - if (u.id not in scores) or \ - (u.score and u.score < 100.0): - urls.append(u) - # if a url doesn't have a score, treat it as the highest possible - urls = sorted(urls, key=lambda x: x.score or 100.0) + urls = status_filter(urls) template = 'mirrors/mirrorlist_status.txt' return direct_to_template(request, template, { @@ -128,6 +149,10 @@ def find_mirrors(request, countries=None, protocols=None, use_status=False, def find_mirrors_simple(request, protocol): + if protocol == 'smart': + # generate a 'smart' mirrorlist, one that only includes FTP mirrors if + # no HTTP mirror is available in that country. + return find_mirrors(request, smart_protocol=True) proto = get_object_or_404(MirrorProtocol, protocol=protocol) return find_mirrors(request, protocols=[proto]) |