From 4ab5d6947795f1fef0d38601ec7ad3ca5f62173e Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 10 Nov 2012 14:13:34 -0600 Subject: Add mirror extended status JSON view When asking for status for a single mirror, we can include logs from the past 24 hours in addition to the normal information we provide. This is slated for usage by a frontend graph still to come, similar to those on the NTP pool website. Signed-off-by: Dan McGee --- mirrors/urls.py | 1 + mirrors/views.py | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/mirrors/urls.py b/mirrors/urls.py index bb4eb969..857e99e2 100644 --- a/mirrors/urls.py +++ b/mirrors/urls.py @@ -6,6 +6,7 @@ urlpatterns = patterns('mirrors.views', (r'^status/json/$', 'status_json', {}, 'mirror-status-json'), (r'^status/tier/(?P\d+)/$', 'status', {}, 'mirror-status-tier'), (r'^(?P[\.\-\w]+)/$', 'mirror_details'), + (r'^(?P[\.\-\w]+)/json/$', 'mirror_details_json'), ) # vim: set ts=4 sw=4 et: diff --git a/mirrors/views.py b/mirrors/views.py index 11719223..cbd86611 100644 --- a/mirrors/views.py +++ b/mirrors/views.py @@ -9,10 +9,11 @@ from django.core.serializers.json import DjangoJSONEncoder from django.db.models import Q from django.http import Http404, HttpResponse from django.shortcuts import get_object_or_404, render +from django.utils.timezone import now from django.views.decorators.csrf import csrf_exempt from django_countries.countries import COUNTRIES -from .models import Mirror, MirrorUrl, MirrorProtocol +from .models import Mirror, MirrorUrl, MirrorProtocol, MirrorLog from .utils import get_mirror_statuses, get_mirror_errors COUNTRY_LOOKUP = dict(COUNTRIES) @@ -183,6 +184,19 @@ def mirror_details(request, name): {'mirror': mirror, 'urls': all_urls}) +def mirror_details_json(request, name): + mirror = get_object_or_404(Mirror, name=name) + status_info = get_mirror_statuses() + data = status_info.copy() + data['version'] = 3 + # include only URLs for this particular mirror + data['urls'] = [url for url in data['urls'] if url.mirror_id == mirror.id] + to_json = json.dumps(data, ensure_ascii=False, + cls=ExtendedMirrorStatusJSONEncoder) + response = HttpResponse(to_json, mimetype='application/json') + return response + + def status(request, tier=None): if tier is not None: tier = int(tier) @@ -222,8 +236,8 @@ def status(request, tier=None): 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'] + url_attributes = ('url', 'protocol', 'last_sync', 'completion_pct', + 'delay', 'duration_avg', 'duration_stddev', 'score') def default(self, obj): if isinstance(obj, timedelta): @@ -245,6 +259,23 @@ class MirrorStatusJSONEncoder(DjangoJSONEncoder): return super(MirrorStatusJSONEncoder, self).default(obj) +class ExtendedMirrorStatusJSONEncoder(MirrorStatusJSONEncoder): + '''Adds URL check history information.''' + log_attributes = ('check_time', 'last_sync', 'duration', 'is_success') + + def default(self, obj): + if isinstance(obj, MirrorUrl): + data = super(ExtendedMirrorStatusJSONEncoder, self).default(obj) + cutoff = now() - timedelta(hours=24) + data['logs'] = obj.logs.filter(check_time__gte=cutoff) + return data + if isinstance(obj, MirrorLog): + data = dict((attr, getattr(obj, attr)) + for attr in self.log_attributes) + return data + return super(ExtendedMirrorStatusJSONEncoder, self).default(obj) + + def status_json(request): status_info = get_mirror_statuses() data = status_info.copy() -- cgit v1.2.3-55-g3dc8