diff options
Diffstat (limited to 'mirrors/views.py')
-rw-r--r-- | mirrors/views.py | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/mirrors/views.py b/mirrors/views.py index e93097a3..c52656f7 100644 --- a/mirrors/views.py +++ b/mirrors/views.py @@ -1,4 +1,8 @@ +from datetime import timedelta +from operator import attrgetter, itemgetter + from django import forms +from django.forms.widgets import CheckboxSelectMultiple from django.core.serializers.json import DjangoJSONEncoder from django.db.models import Q from django.http import Http404, HttpResponse @@ -6,33 +10,55 @@ from django.shortcuts import get_object_or_404 from django.views.decorators.csrf import csrf_exempt from django.views.generic.simple import direct_to_template from django.utils import simplejson +from django_countries.countries import COUNTRIES -from main.utils import make_choice from .models import Mirror, MirrorUrl, MirrorProtocol from .utils import get_mirror_statuses, get_mirror_errors -import datetime +COUNTRY_LOOKUP = dict(COUNTRIES) + class MirrorlistForm(forms.Form): country = forms.MultipleChoiceField(required=False) - protocol = forms.MultipleChoiceField(required=False) + protocol = forms.MultipleChoiceField(required=False, + widget=CheckboxSelectMultiple) ip_version = forms.MultipleChoiceField(required=False, - label="IP version", choices=(('4','IPv4'), ('6','IPv6'))) + label="IP version", choices=(('4','IPv4'), ('6','IPv6')), + widget=CheckboxSelectMultiple) use_mirror_status = forms.BooleanField(required=False) def __init__(self, *args, **kwargs): super(MirrorlistForm, self).__init__(*args, **kwargs) - countries = Mirror.objects.filter(active=True).values_list( - 'country', flat=True).distinct().order_by('country') - self.fields['country'].choices = [('all','All')] + make_choice( - countries) - self.fields['country'].initial = ['all'] - protos = make_choice( - MirrorProtocol.objects.filter(is_download=True)) + fields = self.fields + fields['country'].choices = [('all','All')] + self.get_countries() + fields['country'].initial = ['all'] + protos = [(p.protocol, p.protocol) for p in + MirrorProtocol.objects.filter(is_download=True)] initial = MirrorProtocol.objects.filter(is_download=True, default=True) - self.fields['protocol'].choices = protos - self.fields['protocol'].initial = [p.protocol for p in initial] - self.fields['ip_version'].initial = ['4'] + fields['protocol'].choices = protos + fields['protocol'].initial = [p.protocol for p in initial] + fields['ip_version'].initial = ['4'] + + def get_countries(self): + country_codes = set() + country_codes.update(Mirror.objects.filter(active=True).exclude( + country='').values_list( + 'country', flat=True).order_by().distinct()) + country_codes.update(MirrorUrl.objects.filter( + mirror__active=True).exclude(country='').values_list( + 'country', flat=True).order_by().distinct()) + countries = [(code, COUNTRY_LOOKUP[code]) for code in country_codes] + return sorted(countries, key=itemgetter(1)) + + def as_div(self): + "Returns this form rendered as HTML <divs>s." + return self._html_output( + normal_row = u'<div%(html_class_attr)s>%(label)s %(field)s%(help_text)s</div>', + error_row = u'%s', + row_ender = '</div>', + help_text_html = u' <span class="helptext">%s</span>', + errors_on_separate_row = True) + @csrf_exempt def generate_mirrorlist(request): @@ -49,9 +75,10 @@ def generate_mirrorlist(request): else: form = MirrorlistForm() - return direct_to_template(request, 'mirrors/index.html', + return direct_to_template(request, 'mirrors/mirrorlist_generate.html', {'mirrorlist_form': form}) + def find_mirrors(request, countries=None, protocols=None, use_status=False, ipv4_supported=True, ipv6_supported=True): if not protocols: @@ -74,7 +101,7 @@ def find_mirrors(request, countries=None, protocols=None, use_status=False, if not use_status: urls = qset.order_by('mirror__name', 'url') - urls = sorted(urls, key=lambda x: x.real_country) + urls = sorted(urls, key=attrgetter('real_country')) template = 'mirrors/mirrorlist.txt' else: status_info = get_mirror_statuses() @@ -96,6 +123,7 @@ def find_mirrors(request, countries=None, protocols=None, use_status=False, }, mimetype='text/plain') + def mirrors(request): mirror_list = Mirror.objects.select_related().order_by('tier', 'country') if not request.user.is_authenticated(): @@ -103,6 +131,7 @@ def mirrors(request): return direct_to_template(request, 'mirrors/mirrors.html', {'mirror_list': mirror_list}) + def mirror_details(request, name): mirror = get_object_or_404(Mirror, name=name) if not request.user.is_authenticated() and \ @@ -116,13 +145,14 @@ def mirror_details(request, name): # get each item from checked_urls and supplement with anything in all_urls # if it wasn't there all_urls = set(checked_urls).union(all_urls) - all_urls = sorted(all_urls, key=lambda x: x.url) + all_urls = sorted(all_urls, key=attrgetter('url')) return direct_to_template(request, 'mirrors/mirror_details.html', {'mirror': mirror, 'urls': all_urls}) + def status(request): - bad_timedelta = datetime.timedelta(days=3) + bad_timedelta = timedelta(days=3) status_info = get_mirror_statuses() urls = status_info['urls'] @@ -137,12 +167,13 @@ def status(request): context = status_info.copy() context.update({ - 'good_urls': good_urls, - 'bad_urls': bad_urls, + 'good_urls': sorted(good_urls, key=attrgetter('score')), + 'bad_urls': sorted(bad_urls, key=lambda u: u.delay or timedelta.max), 'error_logs': get_mirror_errors(), }) return direct_to_template(request, 'mirrors/status.html', context) + class MirrorStatusJSONEncoder(DjangoJSONEncoder): '''Base JSONEncoder extended to handle datetime.timedelta and MirrorUrl serialization. The base class takes care of datetime.datetime types.''' @@ -150,7 +181,7 @@ class MirrorStatusJSONEncoder(DjangoJSONEncoder): 'delay', 'duration_avg', 'duration_stddev', 'score'] def default(self, obj): - if isinstance(obj, datetime.timedelta): + if isinstance(obj, timedelta): # always returned as integer seconds return obj.days * 24 * 3600 + obj.seconds if hasattr(obj, '__iter__'): @@ -159,17 +190,20 @@ class MirrorStatusJSONEncoder(DjangoJSONEncoder): if isinstance(obj, MirrorUrl): data = dict((attr, getattr(obj, attr)) for attr in self.url_attributes) - # separate because it isn't on the URL directly - data['country'] = obj.real_country + # get any override on the country attribute first + country = obj.real_country + data['country'] = unicode(country.name) + data['country_code'] = country.code return data if isinstance(obj, MirrorProtocol): return unicode(obj) return super(MirrorStatusJSONEncoder, self).default(obj) + def status_json(request): status_info = get_mirror_statuses() data = status_info.copy() - data['version'] = 2 + data['version'] = 3 to_json = simplejson.dumps(data, ensure_ascii=False, cls=MirrorStatusJSONEncoder) response = HttpResponse(to_json, mimetype='application/json') |