summaryrefslogtreecommitdiff
path: root/mirrors
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2015-02-26 19:53:44 -0600
committerDan McGee <dan@archlinux.org>2015-02-26 19:53:44 -0600
commite739d440e91ff58e2efa59f8b142a7f71fa1e77f (patch)
tree5820175cf5569bf54653b34d5a5cd6b3053c754d /mirrors
parent5ec5b1a70245fa4c0bec4026de14ea54cec00353 (diff)
Break out mirror JSON API views
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'mirrors')
-rw-r--r--mirrors/urls.py9
-rw-r--r--mirrors/views/__init__.py102
-rw-r--r--mirrors/views/api.py106
3 files changed, 114 insertions, 103 deletions
diff --git a/mirrors/urls.py b/mirrors/urls.py
index b1054380..a41bfdc3 100644
--- a/mirrors/urls.py
+++ b/mirrors/urls.py
@@ -3,13 +3,16 @@ from django.conf.urls import patterns
urlpatterns = patterns('mirrors.views',
(r'^$', 'mirrors', {}, 'mirror-list'),
(r'^status/$', 'status', {}, 'mirror-status'),
- (r'^status/json/$', 'status_json', {}, 'mirror-status-json'),
(r'^status/tier/(?P<tier>\d+)/$', 'status', {}, 'mirror-status-tier'),
+ (r'^(?P<name>[\.\-\w]+)/$', 'mirror_details'),
+ (r'^(?P<name>[\.\-\w]+)/(?P<url_id>\d+)/$', 'url_details'),
+)
+
+urlpatterns += patterns('mirrors.views.api',
+ (r'^status/json/$', 'status_json', {}, 'mirror-status-json'),
(r'^status/tier/(?P<tier>\d+)/json/$', 'status_json', {}, 'mirror-status-tier-json'),
(r'^locations/json/$', 'locations_json', {}, 'mirror-locations-json'),
- (r'^(?P<name>[\.\-\w]+)/$', 'mirror_details'),
(r'^(?P<name>[\.\-\w]+)/json/$', 'mirror_details_json'),
- (r'^(?P<name>[\.\-\w]+)/(?P<url_id>\d+)/$', 'url_details'),
)
# vim: set ts=4 sw=4 et:
diff --git a/mirrors/views/__init__.py b/mirrors/views/__init__.py
index d84b0b10..01e8519d 100644
--- a/mirrors/views/__init__.py
+++ b/mirrors/views/__init__.py
@@ -1,20 +1,17 @@
from datetime import timedelta
from itertools import groupby
-import json
from operator import attrgetter, itemgetter
-from django.core.serializers.json import DjangoJSONEncoder
from django.db import connection
-from django.http import Http404, HttpResponse
+from django.http import Http404
from django.shortcuts import get_object_or_404, render
from django.utils.timezone import now
-from django.views.decorators.cache import cache_page
from django.views.decorators.http import condition
from django_countries.fields import Country
from ..models import (Mirror, MirrorUrl, MirrorProtocol, MirrorLog,
CheckLocation)
-from ..utils import get_mirror_statuses, get_mirror_errors, DEFAULT_CUTOFF
+from ..utils import get_mirror_statuses, get_mirror_errors
def mirrors(request):
@@ -84,21 +81,6 @@ def mirror_details(request, name):
return render(request, 'mirrors/mirror_details.html', context)
-def mirror_details_json(request, name):
- authorized = request.user.is_authenticated()
- mirror = get_object_or_404(Mirror, name=name)
- if not authorized and (not mirror.public or not mirror.active):
- raise Http404
- status_info = get_mirror_statuses(mirror_id=mirror.id,
- show_all=authorized)
- data = status_info.copy()
- data['version'] = 3
- to_json = json.dumps(data, ensure_ascii=False,
- cls=ExtendedMirrorStatusJSONEncoder)
- response = HttpResponse(to_json, content_type='application/json')
- return response
-
-
def url_details(request, name, url_id):
url = get_object_or_404(MirrorUrl.objects.select_related(),
id=url_id, mirror__name=name)
@@ -164,84 +146,4 @@ def status(request, tier=None):
})
return render(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, timedelta):
- # always returned as integer seconds
- return obj.days * 24 * 3600 + obj.seconds
- if isinstance(obj, MirrorUrl):
- data = {attr: getattr(obj, attr) for attr in self.url_attributes}
- country = obj.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)
-
-
-class ExtendedMirrorStatusJSONEncoder(MirrorStatusJSONEncoder):
- '''Adds URL check history information.'''
- log_attributes = ('check_time', 'last_sync', 'duration', 'is_success',
- 'location_id')
-
- def default(self, obj):
- if isinstance(obj, MirrorUrl):
- data = super(ExtendedMirrorStatusJSONEncoder, self).default(obj)
- cutoff = now() - DEFAULT_CUTOFF
- data['logs'] = list(obj.logs.filter(
- check_time__gte=cutoff).order_by('check_time'))
- return data
- if isinstance(obj, MirrorLog):
- return {attr: getattr(obj, attr) for attr in self.log_attributes}
- return super(ExtendedMirrorStatusJSONEncoder, self).default(obj)
-
-
-@cache_page(67)
-@condition(last_modified_func=status_last_modified)
-def status_json(request, tier=None):
- if tier is not None:
- tier = int(tier)
- if tier not in [t[0] for t in Mirror.TIER_CHOICES]:
- raise Http404
- status_info = get_mirror_statuses()
- data = status_info.copy()
- if tier is not None:
- data['urls'] = [url for url in data['urls'] if url.mirror.tier == tier]
- data['version'] = 3
- to_json = json.dumps(data, ensure_ascii=False, cls=MirrorStatusJSONEncoder)
- response = HttpResponse(to_json, content_type='application/json')
- return response
-
-
-class LocationJSONEncoder(DjangoJSONEncoder):
- '''Base JSONEncoder extended to handle CheckLocation objects.'''
-
- def default(self, obj):
- if isinstance(obj, CheckLocation):
- return {
- 'id': obj.pk,
- 'hostname': obj.hostname,
- 'source_ip': obj.source_ip,
- 'country': unicode(obj.country.name),
- 'country_code': obj.country.code,
- 'ip_version': obj.ip_version,
- }
- return super(LocationJSONEncoder, self).default(obj)
-
-
-def locations_json(request):
- data = {}
- data['version'] = 1
- data['locations'] = list(CheckLocation.objects.all().order_by('pk'))
- to_json = json.dumps(data, ensure_ascii=False, cls=LocationJSONEncoder)
- response = HttpResponse(to_json, content_type='application/json')
- return response
-
# vim: set ts=4 sw=4 et:
diff --git a/mirrors/views/api.py b/mirrors/views/api.py
new file mode 100644
index 00000000..06574082
--- /dev/null
+++ b/mirrors/views/api.py
@@ -0,0 +1,106 @@
+from datetime import timedelta
+import json
+
+from django.core.serializers.json import DjangoJSONEncoder
+from django.http import Http404, HttpResponse
+from django.shortcuts import get_object_or_404
+from django.utils.timezone import now
+
+from ..models import (Mirror, MirrorUrl, MirrorProtocol, MirrorLog,
+ CheckLocation)
+from ..utils import get_mirror_statuses, DEFAULT_CUTOFF
+
+
+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, timedelta):
+ # always returned as integer seconds
+ return obj.days * 24 * 3600 + obj.seconds
+ if isinstance(obj, MirrorUrl):
+ data = {attr: getattr(obj, attr) for attr in self.url_attributes}
+ country = obj.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)
+
+
+class ExtendedMirrorStatusJSONEncoder(MirrorStatusJSONEncoder):
+ '''Adds URL check history information.'''
+ log_attributes = ('check_time', 'last_sync', 'duration', 'is_success',
+ 'location_id')
+
+ def default(self, obj):
+ if isinstance(obj, MirrorUrl):
+ data = super(ExtendedMirrorStatusJSONEncoder, self).default(obj)
+ cutoff = now() - DEFAULT_CUTOFF
+ data['logs'] = list(obj.logs.filter(
+ check_time__gte=cutoff).order_by('check_time'))
+ return data
+ if isinstance(obj, MirrorLog):
+ return {attr: getattr(obj, attr) for attr in self.log_attributes}
+ return super(ExtendedMirrorStatusJSONEncoder, self).default(obj)
+
+
+class LocationJSONEncoder(DjangoJSONEncoder):
+ '''Base JSONEncoder extended to handle CheckLocation objects.'''
+
+ def default(self, obj):
+ if isinstance(obj, CheckLocation):
+ return {
+ 'id': obj.pk,
+ 'hostname': obj.hostname,
+ 'source_ip': obj.source_ip,
+ 'country': unicode(obj.country.name),
+ 'country_code': obj.country.code,
+ 'ip_version': obj.ip_version,
+ }
+ return super(LocationJSONEncoder, self).default(obj)
+
+
+def status_json(request, tier=None):
+ if tier is not None:
+ tier = int(tier)
+ if tier not in [t[0] for t in Mirror.TIER_CHOICES]:
+ raise Http404
+ status_info = get_mirror_statuses()
+ data = status_info.copy()
+ if tier is not None:
+ data['urls'] = [url for url in data['urls'] if url.mirror.tier == tier]
+ data['version'] = 3
+ to_json = json.dumps(data, ensure_ascii=False, cls=MirrorStatusJSONEncoder)
+ response = HttpResponse(to_json, content_type='application/json')
+ return response
+
+
+def mirror_details_json(request, name):
+ authorized = request.user.is_authenticated()
+ mirror = get_object_or_404(Mirror, name=name)
+ if not authorized and (not mirror.public or not mirror.active):
+ raise Http404
+ status_info = get_mirror_statuses(mirror_id=mirror.id,
+ show_all=authorized)
+ data = status_info.copy()
+ data['version'] = 3
+ to_json = json.dumps(data, ensure_ascii=False,
+ cls=ExtendedMirrorStatusJSONEncoder)
+ response = HttpResponse(to_json, content_type='application/json')
+ return response
+
+
+def locations_json(request):
+ data = {}
+ data['version'] = 1
+ data['locations'] = list(CheckLocation.objects.all().order_by('pk'))
+ to_json = json.dumps(data, ensure_ascii=False, cls=LocationJSONEncoder)
+ response = HttpResponse(to_json, content_type='application/json')
+ return response
+
+# vim: set ts=4 sw=4 et: