euscanwww: add basic json/xml API
Signed-off-by: Corentin Chary <corentincj@iksaif.net>
This commit is contained in:
parent
5b2476c9a0
commit
0d5e1e0901
0
euscanwww/api/__init__.py
Normal file
0
euscanwww/api/__init__.py
Normal file
171
euscanwww/api/handlers.py
Normal file
171
euscanwww/api/handlers.py
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
from piston.handler import AnonymousBaseHandler, BaseHandler
|
||||||
|
from piston.utils import rc, HttpStatusCode
|
||||||
|
|
||||||
|
from django.db.models import Sum, Max
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.forms.models import model_to_dict
|
||||||
|
|
||||||
|
from euscan.models import Version, Package, Herd, Maintainer, EuscanResult, VersionLog
|
||||||
|
from euscan.forms import WorldForm, PackagesForm
|
||||||
|
|
||||||
|
def xint(i):
|
||||||
|
try:
|
||||||
|
return int(i)
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def renameFields(vqs, fields):
|
||||||
|
ret = []
|
||||||
|
for n in vqs:
|
||||||
|
for tr in fields:
|
||||||
|
if tr[0] in n:
|
||||||
|
n[tr[1]] = n[tr[0]]
|
||||||
|
del n[tr[0]]
|
||||||
|
ret.append(n)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# /api/1.0/
|
||||||
|
class RootHandler(AnonymousBaseHandler):
|
||||||
|
allowed_methods = ('GET',)
|
||||||
|
|
||||||
|
def read(self, request):
|
||||||
|
return {'api-version': '1.0'}
|
||||||
|
|
||||||
|
# /api/1.0/statistics
|
||||||
|
class StatisticsHandler(AnonymousBaseHandler):
|
||||||
|
allowed_methods = ('GET',)
|
||||||
|
|
||||||
|
def read(self, request):
|
||||||
|
print request
|
||||||
|
data = {}
|
||||||
|
data['n_packaged'] = xint(Package.objects.aggregate(Sum('n_packaged'))['n_packaged__sum'])
|
||||||
|
data['n_overlay'] = xint(Package.objects.aggregate(Sum('n_overlay'))['n_overlay__sum'])
|
||||||
|
data['n_versions'] = xint(Package.objects.aggregate(Sum('n_versions'))['n_versions__sum'])
|
||||||
|
data['n_upstream'] = data['n_versions'] - data['n_packaged'] - data['n_overlay']
|
||||||
|
data['n_packages'] = Package.objects.count()
|
||||||
|
data['n_herds'] = Herd.objects.count()
|
||||||
|
data['n_maintainers'] = Maintainer.objects.count()
|
||||||
|
data['last_scan'] = EuscanResult.objects.get(id=EuscanResult.objects.aggregate(Max('id'))['id__max']).datetime
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
# /api/1.0/maintainers
|
||||||
|
class MaintainersHandler(AnonymousBaseHandler):
|
||||||
|
allowed_methods = ('GET',)
|
||||||
|
|
||||||
|
def read(self, request):
|
||||||
|
maintainers = Package.objects.filter(maintainers__isnull=False)
|
||||||
|
maintainers = maintainers.values('maintainers__id', 'maintainers__name', 'maintainers__email')
|
||||||
|
maintainers = maintainers.annotate(n_packaged=Sum('n_packaged'),
|
||||||
|
n_overlay=Sum('n_overlay'),
|
||||||
|
n_versions=Sum('n_versions'))
|
||||||
|
|
||||||
|
maintainers = renameFields(maintainers, [('maintainers__id', 'id'),
|
||||||
|
('maintainers__name', 'name'),
|
||||||
|
('maintainers__email', 'email')])
|
||||||
|
return maintainers
|
||||||
|
|
||||||
|
# /api/1.0/herds
|
||||||
|
class HerdsHandler(AnonymousBaseHandler):
|
||||||
|
allowed_methods = ('GET',)
|
||||||
|
|
||||||
|
def read(self, request):
|
||||||
|
# FIXME: optimize the query, it uses 'LEFT OUTER JOIN' instead of 'INNER JOIN'
|
||||||
|
herds = Package.objects.filter(herds__isnull=False)
|
||||||
|
herds = herds.values('herds__herd').annotate(n_packaged=Sum('n_packaged'),
|
||||||
|
n_overlay=Sum('n_overlay'),
|
||||||
|
n_versions=Sum('n_versions'))
|
||||||
|
|
||||||
|
herds = renameFields(herds, [('herds__herd', 'herd')])
|
||||||
|
return herds
|
||||||
|
|
||||||
|
# /api/1.0/categories
|
||||||
|
class CategoriesHandler(AnonymousBaseHandler):
|
||||||
|
allowed_methods = ('GET',)
|
||||||
|
|
||||||
|
def read(self, request):
|
||||||
|
categories = Package.objects.values('category')
|
||||||
|
categories = categories.annotate(n_packaged=Sum('n_packaged'),
|
||||||
|
n_overlay=Sum('n_overlay'),
|
||||||
|
n_versions=Sum('n_versions'))
|
||||||
|
|
||||||
|
return { 'categories' : categories }
|
||||||
|
|
||||||
|
# /api/1.0/packages/by-maintainer/
|
||||||
|
# /api/1.0/packages/by-category/
|
||||||
|
# /api/1.0/packages/by-herd/
|
||||||
|
class PackagesHandler(AnonymousBaseHandler):
|
||||||
|
allowed_methods = ('GET',)
|
||||||
|
fields = ('category', 'name', 'n_packaged', 'n_overlay', 'n_versions')
|
||||||
|
model = Package
|
||||||
|
|
||||||
|
def read(self, request, **kwargs):
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
if 'category' in kwargs:
|
||||||
|
packages = Package.objects.filter(category=kwargs['category'])
|
||||||
|
data = { 'category' : kwargs['category'], 'packages' : packages }
|
||||||
|
elif 'herd' in kwargs:
|
||||||
|
herd = get_object_or_404(Herd, herd=kwargs['herd'])
|
||||||
|
packages = Package.objects.filter(herds__id=herd.id)
|
||||||
|
data = { 'herd' : herd, 'packages' : packages }
|
||||||
|
elif 'maintainer' in kwargs:
|
||||||
|
maintainer = get_object_or_404(Maintainer, id=kwargs['maintainer'])
|
||||||
|
packages = Package.objects.filter(maintainers__id=maintainer.id)
|
||||||
|
data = { 'maintainer' : maintainer, 'packages' : packages }
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
# /api/1.0/package/
|
||||||
|
class PackageHandler(AnonymousBaseHandler):
|
||||||
|
allowed_methods = ('GET',)
|
||||||
|
|
||||||
|
def read(self, request, category, package):
|
||||||
|
package = get_object_or_404(Package, category=category, name=package)
|
||||||
|
package.homepages = package.homepage.split(' ')
|
||||||
|
versions = Version.objects.filter(package=package)
|
||||||
|
log = EuscanResult.objects.filter(package=package).order_by('-datetime')[:1]
|
||||||
|
log = log[0] if log else None
|
||||||
|
vlog = VersionLog.objects.filter(package=package).order_by('-id')
|
||||||
|
|
||||||
|
herds = []
|
||||||
|
for herd in package.herds.all():
|
||||||
|
print herd
|
||||||
|
herds.append(model_to_dict(herd, ['herd']))
|
||||||
|
|
||||||
|
|
||||||
|
maintainers = []
|
||||||
|
for maintainer in package.maintainers.all():
|
||||||
|
maintainers.append(model_to_dict(maintainer, ['name', 'email']))
|
||||||
|
|
||||||
|
version_log = []
|
||||||
|
for v in vlog:
|
||||||
|
v = model_to_dict(v, ['version', 'revision', 'slot', 'overlay', 'datetime', 'action'])
|
||||||
|
if v['action'] == VersionLog.VERSION_ADDED:
|
||||||
|
v['action'] = 'added'
|
||||||
|
if v['action'] == VersionLog.VERSION_REMOVED:
|
||||||
|
v['action'] = 'removed'
|
||||||
|
version_log.append(v)
|
||||||
|
|
||||||
|
upstream = []
|
||||||
|
packaged = []
|
||||||
|
for version in versions:
|
||||||
|
unpackaged = not version.packaged
|
||||||
|
version = model_to_dict(version, ['version', 'revision', 'slot', 'overlay', 'urls'])
|
||||||
|
if unpackaged:
|
||||||
|
upstream.append(version)
|
||||||
|
else:
|
||||||
|
packaged.append(version)
|
||||||
|
|
||||||
|
package = model_to_dict(package, ['category', 'name', 'description',
|
||||||
|
'homepage'])
|
||||||
|
package['herds'] = herds
|
||||||
|
package['maintainers'] = maintainers
|
||||||
|
package['packaged'] = packaged
|
||||||
|
package['upstream'] = upstream
|
||||||
|
package['vlog'] = version_log
|
||||||
|
if log:
|
||||||
|
package['log'] = model_to_dict(log, ['result', 'datetime'])
|
||||||
|
|
||||||
|
return package
|
||||||
|
|
26
euscanwww/api/urls.py
Normal file
26
euscanwww/api/urls.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from django.conf.urls.defaults import *
|
||||||
|
|
||||||
|
from piston.resource import Resource
|
||||||
|
from api.handlers import *
|
||||||
|
|
||||||
|
root_handler = Resource(handler=RootHandler)
|
||||||
|
statistics_handler = Resource(handler=StatisticsHandler)
|
||||||
|
herds_handler = Resource(handler=HerdsHandler)
|
||||||
|
categories_handler = Resource(handler=CategoriesHandler)
|
||||||
|
maintainers_handler = Resource(handler=MaintainersHandler)
|
||||||
|
packages_handler = Resource(handler=PackagesHandler)
|
||||||
|
package_handler = Resource(handler=PackageHandler)
|
||||||
|
|
||||||
|
urlpatterns = patterns('api.views',
|
||||||
|
(r'^1.0/statistics\.(?P<emitter_format>.+)$', statistics_handler),
|
||||||
|
(r'^1.0/herds\.(?P<emitter_format>.+)$', herds_handler),
|
||||||
|
(r'^1.0/categories\.(?P<emitter_format>.+)$', categories_handler),
|
||||||
|
(r'^1.0/maintainers\.(?P<emitter_format>.+)$', maintainers_handler),
|
||||||
|
|
||||||
|
(r'^1.0/packages/by-maintainer/(?P<maintainer_id>\d+)\.(?P<emitter_format>.+)$', packages_handler),
|
||||||
|
(r'^1.0/packages/by-herd/(?P<herd>[\@\{\}\w+.-]*)\.(?P<emitter_format>.+)?$', packages_handler),
|
||||||
|
(r'^1.0/packages/by-category/(?P<category>[\w+][\w+.-]*)\.(?P<emitter_format>.+)?$', packages_handler),
|
||||||
|
(r'^1.0/package/(?P<category>[\w+][\w+.-]*)/(?P<package>[\w+][\w+.-]*)\.(?P<emitter_format>.+)$', package_handler),
|
||||||
|
|
||||||
|
(r'^1.0/api\.(?P<emitter_format>.+)$', root_handler),
|
||||||
|
)
|
@ -10,6 +10,7 @@ urlpatterns = patterns('',
|
|||||||
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||||
|
|
||||||
(r'^admin/', include(admin.site.urls)),
|
(r'^admin/', include(admin.site.urls)),
|
||||||
|
(r'^api/', include('api.urls')),
|
||||||
(r'^', include('euscan.urls')),
|
(r'^', include('euscan.urls')),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user