Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
from devilry.utils.passed_in_previous_period import MarkAsPassedInPreviousPeriod
from devilry.utils.passed_in_previous_period import MarkAsPassedInPreviousPeriodError
from devilry.apps.core.models import Assignment, StaticFeedback
from .errors import NotFoundError
from .errors import BadRequestFieldError
from .auth import IsAssignmentAdmin
from .group import GroupSerializer
class PassedInPreviousPeriodForm(forms.Form):
id = forms.IntegerField(required=True)
newfeedback_points = forms.IntegerField(required=True)
class PassedInPreviousPeriodResource(FormResource):
form = PassedInPreviousPeriodForm
class ResultSerializer(object):
def __init__(self, result):
self.result = result
def _serialize_basenode(self, basenode):
return {'id': basenode.id,
'short_name': basenode.short_name,
'long_name': basenode.long_name}
def _serialize_group(self, group):
groupserializer = GroupSerializer(group)
return {'id': group.id,
'name': group.name,
from .auth import IsAssignmentAdmin
from .errors import NotFoundError
from .fields import ListOfDictField
from .log import logger
class GroupIdsField(ListOfDictField):
class Form(forms.Form):
id = forms.IntegerField(required=True)
class MergeIntoGroupForm(forms.Form):
source_group_ids = GroupIdsField(required=True)
target_group_id = forms.IntegerField(required=True)
class MergeIntoGroupResource(FormResource):
form = MergeIntoGroupForm
class MergeIntoGroup(View):
"""
REST API for the ``merge_into`` method of ``devilry.apps.code.models.AssignmentGroup``.
# POST
Merge groups (called sources) into another group (called target).
## Parameters
The assignment ID is the last part of the URL.
The following parameters must be part of the request body:
- ``source_group_ids`` (array): List of IDs of the source groups.
- ``target_group_id`` (int): The ID of the target group.
def get_description(view):
"""
Provide a description for the view.
By default this is the view's docstring with nice unindention applied.
"""
# If we're looking up the name of a view callable, as found by reverse,
# grok the class instance that we stored when as_view was called.
if getattr(view, 'cls_instance', None):
view = view.cls_instance
# If this view has a resource that's been overridden, then use the resource's doctring
if getattr(view, 'resource', None) not in (None, Resource, FormResource, ModelResource):
doc = view.resource.__doc__
# Otherwise use the view doctring
elif getattr(view, '__doc__', None):
doc = view.__doc__
# I ain't got nuthin fo' ya
else:
return ''
if not doc:
return ''
whitespace_counts = [len(line) - len(line.lstrip(' ')) for line in doc.splitlines()[1:] if line.lstrip()]
# unindent the docstring if needed
help_text='Copy from this assignment if ``setupstudents_mode=="copyfromassignment"``.')
setupstudents_mode = forms.ChoiceField(required=False,
choices=(('do_not_setup', 'Do not setup'),
('allrelated', 'Add all related students.'),
('copyfromassignment', 'Copy from ``copyfromassignment_id``.')),
help_text='Specifies how to setup examiners. Ignored if ``setupstudents_mode=="do_not_setup"``.')
setupexaminers_mode = forms.ChoiceField(required=False,
choices=(('do_not_setup', 'Do not setup'),
('bytags', 'Setup examiners by tags. If ``setupstudents_mode!="allrelated"``, this option is the same as selecting ``do_not_setup``.'),
('copyfromassignment', 'Copy from ``copyfromassignment_id``. If ``setupstudents_mode!="copyfromassignment"``, this option is the same as selecting ``do_not_setup``.'),
('make_authenticated_user_examiner', 'Make the authenticated user examiner on all groups.')),
help_text='Specifies how to setup examiners. Ignored if ``setupstudents_mode=="do_not_setup"``.')
only_copy_passing_groups = forms.BooleanField(required=False)
class RestCreateNewAssignmentResource(FormResource):
form = RestCreateNewAssignmentForm
def validate_request(self, data, files=None):
"""
Remove ``id`` from input data to enable us to have it in models.
"""
if 'id' in data:
del data['id']
return super(RestCreateNewAssignmentResource, self).validate_request(data, files)
class RestCreateNewAssignment(SelfdocumentingMixin, View):
"""
Simplifies creating and setting up new assignments.
"""
resource = RestCreateNewAssignmentResource
#: Signal used to signal that a delivery has been successfully completed
successful_delivery_signal = django.dispatch.Signal(providing_args=["delivery"])
DEFAULT_DEADLINE_EXPIRED_MESSAGE = _('Your active deadline, {deadline} has expired, and the administrators of {assignment} have configured HARD deadlines. This means that you can not add more deliveries to this assignment before an administrator have extended your deadline.')
DEADLINE_EXPIRED_MESSAGE = getattr(settings, 'DEADLINE_EXPIRED_MESSAGE', DEFAULT_DEADLINE_EXPIRED_MESSAGE)
class AddDeliveryForm(forms.Form):
delivery_id = forms.IntegerField(required=False)
finish = forms.BooleanField(required=False)
respond_with_html_contenttype = forms.BooleanField(required=False)
respond_with_200_status_on_error = forms.BooleanField(required=False)
class AddDeliveryResource(FormResource):
form = AddDeliveryForm
def validate_request(self, data, files=None):
if 'file_to_add' in data:
del data['file_to_add']
return super(AddDeliveryResource, self).validate_request(data, files)
class AddDeliveryView(View):
"""
Makes it easy to add a delivery on a Group.
**NOTE:** This is not strictly a REST API, however it is a programming API, developed using Djangorestframework.
# POST
)
ordering = ('name',)
depth = 1
class PostgresDatabaseConfigResource(FormResource):
model = PostgresInstance
fields = ('alias', 'host', 'port', 'user', 'password')
def host(self, instance):
return instance.service.host.hostname
def port(self, instance):
return instance.service.port
class LoadBalancerConfigResource(FormResource):
model = LoadBalancer
fields = ('ipv4',)
def ipv4(self, instance):
return instance.host.public_ipv4
class DomainAliasConfigResource(FormResource):
model = DomainAlias # Doesnt seem to be used?
fields = ('name',)
class GunicornInstanceConfigResource(FormResource):
model = GunicornInstance # Doesnt seem to be used?
fields = ('workers', 'max_requests', 'ipv4', 'hostname')
def hostname(self, instance):
return instance.service.host.hostname
from django.core.exceptions import ValidationError
class LanguageCodeField(forms.CharField):
def validate(self, languagecode):
super(LanguageCodeField, self).validate(languagecode)
languages_dict = dict(settings.LANGUAGES)
if not languagecode in languages_dict:
raise ValidationError('Invalid languagecode: {0}'.format(languagecode))
class LanguageSelectForm(forms.Form):
preferred = LanguageCodeField(required=True)
class LanguageSelectResource(FormResource):
form = LanguageSelectForm
def validate_request(self, data, files=None):
# We want to be able to push what we got from GET, but the extra stuff should be ignored.
if 'selected' in data:
del data['selected']
if 'available' in data:
del data['available']
return super(LanguageSelectResource, self).validate_request(data, files)
class LanguageSelect(View):
"""
Provides an API for selecting the language.
# GET
def port(self, instance):
return instance.service.port
class LoadBalancerConfigResource(FormResource):
model = LoadBalancer
fields = ('ipv4',)
def ipv4(self, instance):
return instance.host.public_ipv4
class DomainAliasConfigResource(FormResource):
model = DomainAlias # Doesnt seem to be used?
fields = ('name',)
class GunicornInstanceConfigResource(FormResource):
model = GunicornInstance # Doesnt seem to be used?
fields = ('workers', 'max_requests', 'ipv4', 'hostname')
def hostname(self, instance):
return instance.service.host.hostname
def ipv4(self, instance):
# TODO: Use hostname instead of ipv4/ipv6?
return instance.service.host.public_ipv4
class DeploymentConfigResource(FormResource):
model = Deployment
def path(self, instance):
return "/home/%s/app/" % instance.identifier
from djangorestframework import status
from devilry.apps.core.models import AssignmentGroup
from devilry.apps.core.models.assignment_group import GroupPopValueError
from devilry.apps.core.models import Candidate
from .auth import IsAssignmentAdmin
from .errors import NotFoundError
from .log import logger
class PopFromGroupForm(forms.Form):
group_id = forms.IntegerField(required=True)
candidate_id = forms.IntegerField(required=True,
help_text='The ID of the candidate to pop.')
class PopFromGroupResource(FormResource):
form = PopFromGroupForm
class PopFromGroup(View):
"""
REST API for the ``pop_candidate`` method of ``devilry.apps.code.models.AssignmentGroup``.
# POST
Pop a candidate from a group(called source), copy the source, except for
the candidates, and add the popped candidate to the newly created group.
## Parameters
The assignment ID is the last part of the URL.
The following parameters must be part of the request body:
- ``group_id`` (int): The ID of the source group.
class CreateOrUpdateForm(forms.Form):
deadline = forms.DateTimeField(required=True)
text = forms.CharField(required=False, widget=forms.Textarea)
createmode = forms.TypedChoiceField(required=False,
coerce=str,
choices=[('failed', 'Only add deadline for groups with failing grade'),
('failed-or-no-feedback', 'Only add deadline for groups with failing grade or no feedback'),
('no-deadlines', 'Only add deadline for groups with no deadlines.'),
('specific-groups', 'Specify a list of group IDs using the group_ids argument.')],
help_text='Only used for POST')
group_ids = ListOfTypedField(required=False,
coerce=int,
help_text='List of group IDs (int).')
class CreateOrUpdateResource(FormResource):
form = CreateOrUpdateForm
def validate_request(self, data, files=None):
if 'bulkdeadline_id' in data:
del data['bulkdeadline_id']
return super(CreateOrUpdateResource, self).validate_request(data, files)
class DeadlinesBulkListOrCreate(View):
"""
Handle deadlines on an assignment in bulk.
# About bulkdeadline_id
The ``bulkdeadline_id`` is a generated string on this format: