from piston.handler import AnonymousBaseHandler, BaseHandler from piston.utils import rc, HttpStatusCode from django.db.models import Sum, Max from django.core.exceptions import ObjectDoesNotExist 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 class catch_and_return(object): def __init__(self, err, response): self.err = err self.response = response def __call__(self, fn): def wrapper(*args, **kwargs): try: return fn(*args, **kwargs) except self.err: return self.response return wrapper # /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): 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 # /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', ('last_version_gentoo', ('version',)), ('last_version_overlay', ('version',)), ('last_version_upstream', ('version',))) model = Package @catch_and_return(ObjectDoesNotExist, rc.NOT_FOUND) def read(self, request, **kwargs): data = {} if 'category' in kwargs: packages = Package.objects.filter(category=kwargs['category']) data = { 'category' : kwargs['category'] } elif 'herd' in kwargs: herd = Herd.objects.get(herd=kwargs['herd']) packages = Package.objects.filter(herds__id=herd.id) data = { 'herd' : herd } elif 'maintainer_id' in kwargs: maintainer = Maintainer.objects.get(id=kwargs['maintainer_id']) packages = Package.objects.filter(maintainers__id=maintainer.id) data = { 'maintainer' : maintainer } packages = packages.select_related('last_version_gentoo', 'last_version_overlay', 'last_version_upstream') data['packages'] = packages if not data: return rc.NOT_FOUND return data # /api/1.0/package/ class PackageHandler(AnonymousBaseHandler): allowed_methods = ('GET',) @catch_and_return(ObjectDoesNotExist, rc.NOT_FOUND) def read(self, request, category, package): package = Package.objects.get(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(): 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