summaryrefslogtreecommitdiff
path: root/mirrors/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'mirrors/views.py')
-rw-r--r--mirrors/views.py82
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')