from datetime import datetime
from django.db.models import Count, Max
from ...simplified import SimplifiedModelApi, simplified_modelapi, PermissionDenied, FieldSpec
from ..core import models
from devilry.coreutils.simplified.metabases import (SimplifiedSubjectMetaMixin,
SimplifiedFileMetaMetaMixin,
SimplifiedPeriodMetaMixin,
SimplifiedAssignmentMetaMixin,
SimplifiedAssignmentGroupMetaMixin,
SimplifiedDeadlineMetaMixin,
SimplifiedDeliveryMetaMixin,
SimplifiedStaticFeedbackMetaMixin,)
class PublishedWhereIsExaminerMixin(SimplifiedModelApi):
""" Mixin class extended by many of the classes in the Simplified API for Examiner """
@classmethod
def create_searchqryset(cls, user, **kwargs):
""" Returns all objects of this type that matches arguments
given in ``\*\*kwargs`` where ``user`` is an examiner.
:param user: A django user object.
:param \*\*kwargs: A dict containing search-parameters.
:rtype: a django queryset
"""
return cls._meta.model.published_where_is_examiner(user)
@classmethod
def read_authorize(cls, user, obj):
""" Checks if the given ``user`` is an examiner for the given
``obj``, and raises ``PermissionDenied`` if not.
:param user: A django user object.
:param obj: An object of the type this method is used in.
:throws PermissionDenied:
"""
if not cls._meta.model.published_where_is_examiner(user).filter(id=obj.id):
raise PermissionDenied()
@simplified_modelapi
[docs]class SimplifiedSubject(PublishedWhereIsExaminerMixin):
""" Simplified wrapper for :class:`devilry.apps.core.models.Subject`. """
@simplified_modelapi
[docs]class SimplifiedPeriod(PublishedWhereIsExaminerMixin):
""" Simplified wrapper for :class:`devilry.apps.core.models.Period`. """
@simplified_modelapi
[docs]class SimplifiedAssignment(PublishedWhereIsExaminerMixin):
""" Simplified wrapper for :class:`devilry.apps.core.models.Assignment`. """
@classmethod
[docs] def create_searchqryset(cls, user, **kwargs):
""" Returns all Assignment objects that matches the arguments
given in ``\*\*kwargs`` where ``user`` is an examiner.
:param user: A django user object.
:param \*\*kwargs: A dict containing search-parameters.
:rtype: a django queryset
"""
old = kwargs.pop('old', True)
active = kwargs.pop('active', True)
subject_short_name = kwargs.pop('subject_short_name', None)
period_short_name = kwargs.pop('period_short_name', None)
qryset = models.Assignment.published_where_is_examiner(user, old=old,
active=active)
if subject_short_name and period_short_name:
qryset = qryset.filter(parentnode__short_name=period_short_name,
parentnode__parentnode__short_name=subject_short_name)
return qryset
@simplified_modelapi
[docs]class SimplifiedAssignmentGroup(PublishedWhereIsExaminerMixin):
""" Simplified wrapper for :class:`devilry.apps.core.models.AssignmentGroup`. """
@classmethod
[docs] def create_searchqryset(cls, user):
""" Returns all AssignmentGroup-objects where given ``user`` is examiners.
:param user: A django user object.
:rtype: a django queryset
"""
return cls._meta.model.published_where_is_examiner(user).annotate(latest_delivery_id=Max('deadlines__deliveries__id'),
latest_deadline_id=Max('deadlines__id'),
latest_deadline_deadline=Max('deadlines__deadline'),
number_of_deliveries=Count('deadlines__deliveries'))
@classmethod
[docs] def write_authorize(cls, user, obj):
""" Checks if the given ``user`` is an examiner in the given
StaticFeedback ``obj``, and raises ``PermissionDenied`` if not.
:param user: A django user object.
:param obj: A StaticFeedback-object.
:throws PermissionDenied:
"""
if not cls._meta.model.published_where_is_examiner(user).filter(id=obj.id):
raise PermissionDenied()
if obj.id == None:
raise PermissionDenied() # We only allow update
@simplified_modelapi
[docs]class SimplifiedDelivery(PublishedWhereIsExaminerMixin):
""" Simplified wrapper for :class:`devilry.apps.core.models.Delivery`. """
@classmethod
[docs] def write_authorize_examinercommon(cls, user, obj):
""" Used by this class and the corresponding class in apps.administrator.simplified. """
if obj.delivered_by != None:
raise PermissionDenied()
@classmethod
def examiner_pre_full_clean(cls, user, obj):
obj.time_of_delivery = datetime.now()
obj.delivered_by = None # None marks this as delivered by an administrator
if obj.id == None:
obj.number = 0
@classmethod
def pre_full_clean(cls, user, obj):
cls.examiner_pre_full_clean(user, obj)
@classmethod
[docs] def write_authorize(cls, user, obj):
""" Check if the given ``user`` can save changes to the given
``obj``, and raise ``PermissionDenied`` if not.
:param user: A django user object.
:param obj: A object of the type this method is used in.
:throws PermissionDenied:
"""
if not models.AssignmentGroup.published_where_is_examiner(user).filter(id=obj.deadline.assignment_group.id):
raise PermissionDenied()
cls.write_authorize_examinercommon(user, obj)
@simplified_modelapi
[docs]class SimplifiedStaticFeedback(PublishedWhereIsExaminerMixin):
""" Simplified wrapper for :class:`devilry.apps.core.models.StaticFeedback`. """
@classmethod
def pre_full_clean(cls, user, obj):
if not obj.id == None:
raise ValueError('BUG: Examiners should only have create permission on StaticFeedback.')
obj.saved_by = user
@classmethod
[docs] def write_authorize(cls, user, obj):
""" Checks if the given ``user`` is an examiner in the given
StaticFeedback ``obj``, and raises ``PermissionDenied`` if not.
:param user: A django user object.
:param obj: A StaticFeedback-object.
:throws PermissionDenied:
"""
if not obj.delivery.deadline.assignment_group.is_examiner(user):
raise PermissionDenied()
@simplified_modelapi
[docs]class SimplifiedDeadline(PublishedWhereIsExaminerMixin):
""" Simplified wrapper for :class:`devilry.apps.core.models.Deadline`. """
@classmethod
def create_searchqryset(cls, user, **kwargs):
return cls._meta.model.published_where_is_examiner(user).annotate(number_of_deliveries=Count('deliveries'))
@classmethod
[docs] def write_authorize(cls, user, obj):
""" Checks if the given ``user`` is an examiner in the given
Deadline ``obj``, and raises ``PermissionDenied`` if not.
:param user: A django user object.
:param obj: A Deadline-object.
:throws PermissionDenied:
"""
if not obj.assignment_group.is_examiner(user):
raise PermissionDenied()
@classmethod
def is_empty(cls, obj):
return obj.deliveries.count() == 0
@simplified_modelapi