From 7b969772cc9f280255ef51d55f1e1ed9123af1fd Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 13 Dec 2010 13:58:40 -0600 Subject: Add a mirror status JSON view Requested in FS#21144. This should provide most if not all of the data that was provided on the archlinux.de website, although there are some differences in what is returned to the user. It is nearly the same data as that provided in the HTML view, the difference being things are a bit more machine-friendly and the list is not split into good and bad portions. Signed-off-by: Dan McGee --- mirrors/views.py | 37 ++++++++++++++++++++++++++++++++++++- urls.py | 1 + 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/mirrors/views.py b/mirrors/views.py index b9df6ba1..a2b94de8 100644 --- a/mirrors/views.py +++ b/mirrors/views.py @@ -1,10 +1,12 @@ from django import forms +from django.core.serializers.json import DjangoJSONEncoder from django.db.models import Avg, Count, Max, Min, StdDev from django.db.models import Q -from django.http import Http404 +from django.http import Http404, HttpResponse 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 main.utils import make_choice from .models import Mirror, MirrorUrl, MirrorProtocol @@ -129,4 +131,37 @@ def status(request): }) 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.''' + url_attributes = ['url', 'protocol', 'last_sync', 'completion_pct', + 'delay', 'duration_avg', 'duration_stddev', 'score'] + + def default(self, obj): + if isinstance(obj, datetime.timedelta): + # always returned as integer seconds + return obj.days * 24 * 3600 + obj.seconds + if hasattr(obj, '__iter__'): + # mainly for queryset serialization + return list(obj) + if isinstance(obj, MirrorUrl): + data = {} + for attr in self.url_attributes: + data[attr] = getattr(obj, attr) + # separate because it isn't on the URL directly + data['country'] = obj.mirror.country + 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'] = 1 + to_json = simplejson.dumps(data, ensure_ascii=False, + cls=MirrorStatusJSONEncoder) + response = HttpResponse(to_json, mimetype='application/json') + return response + # vim: set ts=4 sw=4 et: diff --git a/urls.py b/urls.py index 5c792035..45dc8065 100644 --- a/urls.py +++ b/urls.py @@ -73,6 +73,7 @@ urlpatterns = patterns('', (r'^mirrors/$', 'mirrors.views.mirrors', {}, 'mirrors-list'), (r'^mirrors/status/$', 'mirrors.views.status', {}, 'mirror-status'), + (r'^mirrors/status/json/$', 'mirrors.views.status_json', {}, 'mirror-status-json'), (r'^mirrors/(?P[\.\-\w]+)/$', 'mirrors.views.mirror_details'), (r'^mirrorlist/$', 'mirrors.views.generate_mirrorlist', {}, 'mirrorlist'), -- cgit v1.2.3-55-g3dc8