# Path: devmason_server/models.py
# class Project(models.Model):
#     name = models.CharField(max_length=200)
#     slug = models.SlugField(unique=True)
#     owner = models.ForeignKey(User, related_name='projects', blank=True, null=True)
# 
#     class Meta:
#         ordering = ['name']
# 
#     def __unicode__(self):
#         return self.name
# 
#     @models.permalink
#     def get_absolute_url(self):
#         return ('project_detail', [self.slug])
# 
# class Build(models.Model):
#     project = models.ForeignKey(Project, related_name='builds')
#     success = models.BooleanField()
#     started = models.DateTimeField()
#     finished = models.DateTimeField()
#     host = models.CharField(max_length=250)
#     arch = models.CharField(max_length=250)
#     user = models.ForeignKey(User, blank=True, null=True, related_name='builds')
#     extra_info = JSONField()
# 
#     class Meta:
#         ordering = ['-finished']
# 
#     def __unicode__(self):
#         return u"Build %s for %s" % (self.pk, self.project)
# 
#     @models.permalink
#     def get_absolute_url(self):
#         return ('build_detail', [self.project.slug, self.pk])
# 
# class BuildStep(models.Model):
#     build = models.ForeignKey(Build, related_name='steps')
#     success = models.BooleanField()
#     started = models.DateTimeField()
#     finished = models.DateTimeField()
#     name = models.CharField(max_length=250)
#     output = models.TextField(blank=True)
#     errout = models.TextField(blank=True)
#     extra_info = JSONField()
# 
#     class Meta:
#         ordering = ['build', 'started']
# 
#     def __unicode__(self):
#         return "%s: %s" % (self.build, self.name)
# 
# Path: devmason_server/utils.py
# def link(rel, to_handler, *args, **getargs):
#     """
#     Create a link resource - a dict with rel, href, and allowed_methods keys.
#     Extra args taken by the view may be passed in as *args; GET may be passed
#     as **kwargs.
#     """
#     href = urlresolvers.reverse(to_handler.viewname, args=args)
#     if getargs:
#         href = "%s?%s" % (href, urlencode(getargs))
#     return {
#         'rel': rel,
#         'href': href,
#         'allowed_methods': to_handler.allowed_methods
#     }
# 
# def allow_404(func):
#     """
#     decorator that catches Http404 exceptions and safely returns
#     piston style 404 responses (rc.NOT_FOUND).
#     """
#     def wrapper(*args, **kwargs):
#         try:
#             return func(*args, **kwargs)
#         except Http404:
#             return piston.utils.rc.NOT_FOUND
#     return wrapper
# 
# def authentication_required(callback):
#     """
#     Require that a handler method be called with authentication.
# 
#     Pony server has somewhat "interesting" authentication: new users are
#     created transparently when creating new resources, so this needs to keep
#     track of whether a user is "new" or not so that the handler may optionally
#     save the user if needed. Thus, this annotates `request.user` with the user
#     (new or not), and sets a `is_new_user` attribute on this user.
#     """
#     @functools.wraps(callback)
#     def _view(self, request, *args, **kwargs):
#         user, password = _get_user(request)
#         if not user or user.is_anonymous():
#             return HttpResponseUnauthorized()
#         if not user.check_password(password):
#             return HttpResponseForbidden()
#         request.user = user
#         return callback(self, request, *args, **kwargs)
#     return _view
# 
# def authentication_optional(callback):
#     """
#     Optionally allow authentication for a view.
# 
#     Like `authentication_required`, except that if there's no auth info then
#     `request.user` will be `AnonymousUser`.
#     """
#     @functools.wraps(callback)
#     def _view(self, request, *args, **kwargs):
#         user, password = _get_user(request)
#         if not user:
#             return HttpResponseUnauthorized()
#         if user.is_authenticated() and not user.check_password(password):
#             return HttpResponseForbidden()
#         request.user = user
#         return callback(self, request, *args, **kwargs)
#     return _view
# 
# def format_dt(dt):
#     return dateformat.format(dt, 'r')
# 
# class HttpResponseCreated(HttpResponseRedirect):
#     status_code = 201
# 
# class HttpResponseNoContent(HttpResponse):
#     status_code = 204
# 
# def mk_datetime(string):
#     return datetime.datetime.fromtimestamp(time.mktime(email.utils.parsedate(string)))


from django.db import transaction
from django.core.paginator import Paginator, InvalidPage
from django.core import urlresolvers
from django.http import Http404, HttpResponseForbidden, HttpResponseBadRequest
from django.shortcuts import get_object_or_404, redirect
from django.utils import simplejson
from piston.handler import BaseHandler
from piston.utils import require_mime
from tagging.models import Tag
from .models import Project, Build, BuildStep
from .utils import (link, allow_404, authentication_required,
                    authentication_optional, format_dt, HttpResponseCreated,
                    HttpResponseNoContent, mk_datetime)

class ProjectListHandler(BaseHandler):
    allowed_methods = ['GET']
    viewname = 'project_list'

    def read(self, request):
        latest_builds = Build.objects.order_by('-pk')[:10]
        projects =  Project.objects.filter(builds__isnull=False).distinct()
        builds = {}
        for project in projects:
            try:
                builds[project.name] = list(project.builds.order_by('-pk'))[0]
            except:
                pass
        return {
            'projects': projects,
            'latest_builds': latest_builds,
            'builds': builds,
            'links': [link('self', ProjectListHandler)]
        }

class ProjectHandler(BaseHandler):
    allowed_methods = ['GET', 'PUT', 'DELETE']
    model = Project
    viewname = 'project_detail'
    fields = ('name', 'owner', 'links')

    @allow_404
    def read(self, request, slug):

# Path: devmason_server/models.py
# class Project(models.Model):
#     name = models.CharField(max_length=200)
#     slug = models.SlugField(unique=True)
#     owner = models.ForeignKey(User, related_name='projects', blank=True, null=True)
# 
#     class Meta:
#         ordering = ['name']
# 
#     def __unicode__(self):
#         return self.name
# 
#     @models.permalink
#     def get_absolute_url(self):
#         return ('project_detail', [self.slug])
# 
# class Build(models.Model):
#     project = models.ForeignKey(Project, related_name='builds')
#     success = models.BooleanField()
#     started = models.DateTimeField()
#     finished = models.DateTimeField()
#     host = models.CharField(max_length=250)
#     arch = models.CharField(max_length=250)
#     user = models.ForeignKey(User, blank=True, null=True, related_name='builds')
#     extra_info = JSONField()
# 
#     class Meta:
#         ordering = ['-finished']
# 
#     def __unicode__(self):
#         return u"Build %s for %s" % (self.pk, self.project)
# 
#     @models.permalink
#     def get_absolute_url(self):
#         return ('build_detail', [self.project.slug, self.pk])
# 
# class BuildStep(models.Model):
#     build = models.ForeignKey(Build, related_name='steps')
#     success = models.BooleanField()
#     started = models.DateTimeField()
#     finished = models.DateTimeField()
#     name = models.CharField(max_length=250)
#     output = models.TextField(blank=True)
#     errout = models.TextField(blank=True)
#     extra_info = JSONField()
# 
#     class Meta:
#         ordering = ['build', 'started']
# 
#     def __unicode__(self):
#         return "%s: %s" % (self.build, self.name)
# 
# Path: devmason_server/utils.py
# def link(rel, to_handler, *args, **getargs):
#     """
#     Create a link resource - a dict with rel, href, and allowed_methods keys.
#     Extra args taken by the view may be passed in as *args; GET may be passed
#     as **kwargs.
#     """
#     href = urlresolvers.reverse(to_handler.viewname, args=args)
#     if getargs:
#         href = "%s?%s" % (href, urlencode(getargs))
#     return {
#         'rel': rel,
#         'href': href,
#         'allowed_methods': to_handler.allowed_methods
#     }
# 
# def allow_404(func):
#     """
#     decorator that catches Http404 exceptions and safely returns
#     piston style 404 responses (rc.NOT_FOUND).
#     """
#     def wrapper(*args, **kwargs):
#         try:
#             return func(*args, **kwargs)
#         except Http404:
#             return piston.utils.rc.NOT_FOUND
#     return wrapper
# 
# def authentication_required(callback):
#     """
#     Require that a handler method be called with authentication.
# 
#     Pony server has somewhat "interesting" authentication: new users are
#     created transparently when creating new resources, so this needs to keep
#     track of whether a user is "new" or not so that the handler may optionally
#     save the user if needed. Thus, this annotates `request.user` with the user
#     (new or not), and sets a `is_new_user` attribute on this user.
#     """
#     @functools.wraps(callback)
#     def _view(self, request, *args, **kwargs):
#         user, password = _get_user(request)
#         if not user or user.is_anonymous():
#             return HttpResponseUnauthorized()
#         if not user.check_password(password):
#             return HttpResponseForbidden()
#         request.user = user
#         return callback(self, request, *args, **kwargs)
#     return _view
# 
# def authentication_optional(callback):
#     """
#     Optionally allow authentication for a view.
# 
#     Like `authentication_required`, except that if there's no auth info then
#     `request.user` will be `AnonymousUser`.
#     """
#     @functools.wraps(callback)
#     def _view(self, request, *args, **kwargs):
#         user, password = _get_user(request)
#         if not user:
#             return HttpResponseUnauthorized()
#         if user.is_authenticated() and not user.check_password(password):
#             return HttpResponseForbidden()
#         request.user = user
#         return callback(self, request, *args, **kwargs)
#     return _view
# 
# def format_dt(dt):
#     return dateformat.format(dt, 'r')
# 
# class HttpResponseCreated(HttpResponseRedirect):
#     status_code = 201
# 
# class HttpResponseNoContent(HttpResponse):
#     status_code = 204
# 
# def mk_datetime(string):
#     return datetime.datetime.fromtimestamp(time.mktime(email.utils.parsedate(string)))


# Path: devmason_server/handlers.py
from django.db import transaction
from django.core.paginator import Paginator, InvalidPage
from django.core import urlresolvers
from django.http import Http404, HttpResponseForbidden, HttpResponseBadRequest
from django.shortcuts import get_object_or_404, redirect
from django.utils import simplejson
from piston.handler import BaseHandler
from piston.utils import require_mime
from tagging.models import Tag
from .models import Project, Build, BuildStep
from .utils import (link, allow_404, authentication_required,
                    authentication_optional, format_dt, HttpResponseCreated,
                    HttpResponseNoContent, mk_datetime)


class ProjectListHandler(BaseHandler):
    allowed_methods = ['GET']
    viewname = 'project_list'

    def read(self, request):
        latest_builds = Build.objects.order_by('-pk')[:10]
        projects =  Project.objects.filter(builds__isnull=False).distinct()
        builds = {}
        for project in projects:
            try:
                builds[project.name] = list(project.builds.order_by('-pk'))[0]
            except:
                pass
        return {
            'projects': projects,
            'latest_builds': latest_builds,
            'builds': builds,
            'links': [link('self', ProjectListHandler)]
        }

class ProjectHandler(BaseHandler):
    allowed_methods = ['GET', 'PUT', 'DELETE']
    model = Project
    viewname = 'project_detail'
    fields = ('name', 'owner', 'links')

    @allow_404
    def read(self, request, slug):

        return  get_object_or_404(Project, slug=slug)