rosedu/wouso

View on GitHub
wouso/games/workshop/cpanel.py

Summary

Maintainability
D
1 day
Test Coverage
from django import forms
from django.shortcuts import render_to_response, redirect, get_object_or_404
from django.template.context import RequestContext
from django.views.generic import View, ListView, UpdateView, CreateView, \
    DetailView

from models import WorkshopGame, Semigroup, Schedule, DAY_CHOICES, Answer, \
    MIN_HOUR, MAX_HOUR
from wouso.core.decorators import staff_required
from wouso.core.user.models import Player
from wouso.games.workshop.models import Workshop, Assessment, Review


class SCForm(forms.ModelForm):
    class Meta:
        model = Schedule
        fields = ('name', 'start_date', 'end_date', 'count')


class AGForm(forms.ModelForm):
    class Meta:
        model = Semigroup
        fields = ('name', 'day', 'hour', 'room', 'assistant')

    def __init__(self, **kwargs):
        super(AGForm, self).__init__(**kwargs)
        self.fields['assistant'].queryset = Player.get_by_permission('change_semigroup')


class WAForm(forms.ModelForm):
    class Meta:
        model = Workshop
        exclude = ('start_at', 'active_until', 'status')

    def __init__(self, data=None, **kwargs):
        super(WAForm, self).__init__(data=data, **kwargs)
        self.fields['semigroup'].queryset = Semigroup.objects.all().order_by('name')


@staff_required
def workshop_home(request, **kwargs):

    return render_to_response('workshop/cpanel/index.html',
                        {'module': 'workshop',
                         'days': DAY_CHOICES,
                         'semigroups': Semigroup.objects.all().order_by('name'),
                         'hours': range(MIN_HOUR, MAX_HOUR + 2, 2),
                         'info': WorkshopGame},
                        context_instance=RequestContext(request)
    )


class AddGroupView(CreateView):
    template_name = 'workshop/cpanel/addgroup.html'
    form_class = AGForm

    def form_valid(self, form):
        sg = form.save()
        sg.owner = WorkshopGame.get_instance()
        sg.save()
        return redirect('ws_edit_spot', day=sg.day, hour=sg.hour)

    def get_context_data(self, **kwargs):
        context = super(AddGroupView, self).get_context_data(**kwargs)
        context.update({'module': 'workshop'})
        return context

add_group = staff_required(AddGroupView.as_view())


class EditGroupView(UpdateView):
    template_name = 'workshop/cpanel/editgroup.html'
    model = Semigroup
    pk_url_kwarg = 'semigroup'
    form_class = AGForm

    def form_valid(self, form):
        sg = form.save()
        sg.owner = WorkshopGame.get_instance()
        sg.save()
        return redirect('ws_edit_spot', day=sg.day, hour=sg.hour)

    def get_context_data(self, **kwargs):
        context = super(EditGroupView, self).get_context_data(**kwargs)
        context.update({'module': 'workshop', 'instance': self.get_object()})
        return context

edit_group = staff_required(EditGroupView.as_view())

@staff_required
def edit_spot(request, day, hour):
    day, hour = int(day), int(hour)
    sgs = WorkshopGame.get_by_day_and_hour(day, hour)

    if not sgs:
        return redirect('ws_add_group')

    if request.method == 'POST':
        semigroup = get_object_or_404(Semigroup, pk=request.GET.get('semigroup'))
        try:
            player = Player.objects.get(pk=int(request.POST.get('player')))
        except (ValueError, Player.DoesNotExist):
            pass
        else:
            semigroup.add_player(player)

    return render_to_response('workshop/cpanel/editspot.html',
                        {'module': 'workshop',
                         'semigroups': sgs,
                         },
                        context_instance=RequestContext(request)
    )

@staff_required
def kick_off(request, player):
    player = get_object_or_404(Player, pk=player)

    sgs = player.playergroup_set.filter(owner=WorkshopGame.get_instance())
    for s in sgs:
        s.players.remove(player)

    return redirect('workshop_home')

@staff_required
def schedule(request):
    schedules = Schedule.objects.all().order_by('start_date', 'name')

    return render_to_response('workshop/cpanel/schedule.html',
                        {'module': 'workshop',
                         'schedules': schedules,
                         'category': WorkshopGame.get_question_category(),
                         'page': 'schedule'},
                        context_instance=RequestContext(request)
    )


class ScheduleChangeView(UpdateView):
    template_name = 'workshop/cpanel/schedule_change.html'
    model = Schedule
    pk_url_kwarg = 'schedule'
    form_class = SCForm

    def get_object(self, queryset=None):
        if 'schedule' in self.kwargs.keys():
            schedule = get_object_or_404(Schedule, pk=self.kwargs['schedule'])
        else:
            schedule = None
        return schedule

    def form_valid(self, form):
        sc = form.save()
        sc.category = WorkshopGame.get_question_category()
        sc.save()
        return redirect('ws_schedule')

    def get_context_data(self, **kwargs):
        context = super(ScheduleChangeView, self).get_context_data(**kwargs)
        context.update({'module': 'workshop', 'instance': self.get_object(),
                       'page': 'schedule'})
        return context

schedule_change = staff_required(ScheduleChangeView.as_view())


class WorkshopList(ListView):
    model = Workshop
    template_name = 'workshop/cpanel/workshops.html'
    paginate_by = 25
    context_object_name = 'workshops'

    def get_queryset(self):
        return self.model.objects.all().order_by('-active_until')

    def get_context_data(self, **kwargs):
        context = super(WorkshopList, self).get_context_data(**kwargs)
        context.update({'module': 'workshop', 'page': 'workshops', 'info': WorkshopGame,
                        'integrity_check': self.request.GET.get('integrity_check', False)
        })
        return context

workshops = staff_required(WorkshopList.as_view())


@staff_required
def workshop_mark4review(request, workshop):
    workshop = get_object_or_404(Workshop, pk=workshop)

    if workshop.is_started():
        WorkshopGame.start_reviewing(workshop)

    return redirect('ws_workshops')


@staff_required
def workshop_mark4grading(request, workshop):
    workshop = get_object_or_404(Workshop, pk=workshop)

    if workshop.is_reviewable():
        workshop.set_gradable()

    return redirect('ws_workshops')


@staff_required
def workshop_update_grades(request, workshop):
    workshop = get_object_or_404(Workshop, pk=workshop)

    for ass in workshop.assessment_set.all():
        ass.update_grade()

    return redirect('ws_reviewers_map', workshop=workshop.id)

@staff_required
def workshop_reviewers(request, workshop):
    workshop = get_object_or_404(Workshop, pk=workshop)

    if workshop.is_started():
        return redirect('ws_workshops')

    assessments = workshop.assessment_set.all().order_by('player__user__last_name', 'player__user__first_name')

    return render_to_response('workshop/cpanel/workshop_map.html',
                        {'module': 'workshop',
                         'workshop': workshop,
                         'assessments': assessments,
                         'page': 'workshops',
                         'integrity_check': request.GET.get('integrity_check', False),
                         },
                        context_instance=RequestContext(request)
    )


def get_next_assessment(assessment):
    """
    Find the next assessment in list (ordered alphabetically)
    """
    assessments = list(assessment.workshop.assessment_set.all().order_by('player__user__last_name', 'player__user__first_name'))
    index = assessments.index(assessment)
    if index == len(assessments) - 1:
        return None
    return assessments[index + 1]


@staff_required
def workshop_grade_assessment(request, assessment):
    assessment = get_object_or_404(Assessment, pk=assessment)
    assistant = request.user.get_profile()
    next_ass = get_next_assessment(assessment)

    if request.method == 'POST':
        data = request.POST
        for a in assessment.answer_set.all():
            try:
                grade = int(data.get('grade_%d' % a.id, ''))
            except ValueError:
                pass
            else:
                a.grade = grade
                a.save()

            # Update review
            feedback = data.get('feedback_%d' % a.id, '')
            review = Review.objects.get_or_create(answer=a, reviewer=assistant)[0]
            review.feedback = feedback
            review.save()

            # Update other reviews' grades
            for r in a.review_set.all():
                try:
                    grade = int(data.get('review_grade_%d' % r.id, ''))
                except ValueError:
                    pass
                else:
                    r.review_grade = grade
                    r.review_reviewer = assistant
                    r.save()
        # Grade the entire assessment
        assessment.update_grade()
        submit = data.get('submit', 'save')
        if submit == 'save':
            pass
        elif submit == 'save_return':
            return redirect('ws_reviewers_map', workshop=assessment.workshop.id)
        elif submit == 'save_next':
            if next_ass:
                return redirect('ws_grade_assessment', assessment=next_ass.id)
            else:
                return redirect('ws_reviewers_map', workshop=assessment.workshop.id)

    return render_to_response('workshop/cpanel/workshop_grade_assessment.html',
                        {'module': 'workshop',
                         'assessment': assessment,
                         'next_ass': next_ass,
                         'page': 'workshops',
                         },
                         context_instance=RequestContext(request)
    )


class AddWorkshopView(View):

    def get(self, request, *args, **kwargs):
        form = WAForm()
        return render_to_response(
            'workshop/cpanel/workshop_add.html',
            {'module': 'workshop',
             'form': form,
             'info': WorkshopGame,
             'error': '',
             'page': 'workshops'},
            context_instance=RequestContext(request),
        )

    def post(self, request, *args, **kwargs):
        error = ''
        form = WAForm(request.POST)
        if form.is_valid():
            try:
                workshop = WorkshopGame.create_workshop(
                    semigroup=form.cleaned_data['semigroup'],
                    date=form.cleaned_data['date'],
                    title=form.cleaned_data['title'],
                    question_count=form.cleaned_data['question_count']
                )
            except ValueError as e:
                error = str(e)
            else:
                return redirect('ws_status', pk=workshop.pk)

        return render_to_response(
            'workshop/cpanel/workshop_add.html',
            {'module': 'workshop', 'form': form, 'info': WorkshopGame,
             'error': error, 'page': 'workshops'},
            context_instance=RequestContext(request)
        )


workshop_add = staff_required(AddWorkshopView.as_view())

@staff_required
def workshop_edit(request, workshop):
    workshop = get_object_or_404(Workshop, pk=workshop)

    class WForm(forms.ModelForm):
        class Meta:
            model = Workshop
            exclude = ('status',)

    if request.method == 'POST':
        form = WForm(request.POST, instance=workshop)
        if form.is_valid():
            form.save()
            return redirect('ws_workshops')
    else:
        form = WForm(instance=workshop)

    return render_to_response('workshop/cpanel/workshop_edit.html',
                        {'module': 'workshop', 'form': form, 'info': WorkshopGame,
                         'page': 'workshops'},
                        context_instance=RequestContext(request)
    )

@staff_required
def workshop_delete(request, workshop):
    workshop = get_object_or_404(Workshop, pk=workshop)
    workshop.delete()
    return redirect('ws_workshops')

@staff_required
def workshop_start(request, workshop):
    workshop = get_object_or_404(Workshop, pk=workshop)
    workshop.start() # set start_at and active_until
    return redirect('ws_status', pk=workshop.pk)


@staff_required
def workshop_stop(request, workshop):
    workshop = get_object_or_404(Workshop, pk=workshop)
    workshop.stop() # set active_until
    return redirect('ws_status', pk=workshop.pk)


@staff_required
def workshop_assessments(request, workshop, assessment=None):
    workshop = get_object_or_404(Workshop, pk=workshop)
    if assessment:
        assessment = get_object_or_404(Assessment, pk=assessment)

    return render_to_response('workshop/cpanel/workshop_assessments.html',
                        {'module': 'workshop', 'page': 'workshops', 'workshop': workshop, 'assessment': assessment},
                        context_instance=RequestContext(request)
    )


@staff_required
def workshop_assessment_edit(request, assessment, **kwargs):
    assessment = get_object_or_404(Assessment, pk=assessment)

    for q in assessment.questions.all():
        Answer.objects.get_or_create(question=q, assessment=assessment)

    if request.method == 'POST':
        for a in assessment.answer_set.all():
            text = request.POST.get('answer_%d' % a.id, '')
            if text:
                a.text = text
                a.save()
    return render_to_response('workshop/cpanel/workshop_assessment_change.html',
                              {'module': 'workshop', 'page': 'workshops', 'workshop': assessment.workshop, 'assessment': assessment},
                              context_instance=RequestContext(request)
    )


@staff_required
def reset_reviews(request, workshop, assessment):
    """
    Remove all non expected reviews given to this assessment
    """
    assessment = get_object_or_404(Assessment, pk=assessment)
    assessment.remove_non_expected_reviews()

    return redirect('ws_reviewers_map', workshop=assessment.workshop.id)


class GradebookView(ListView):
    """
    List all students and grades
    """
    template_name = 'workshop/cpanel/gradebook.html'
    context_object_name = 'players'

    def get_queryset(self):
        self.semigroup = get_object_or_404(Semigroup, pk=self.kwargs['semigroup'])
        players = self.semigroup.players.all().order_by('user__last_name', 'user__first_name')
        return players

    def get_context_data(self, **kwargs):
        context = super(GradebookView, self).get_context_data(**kwargs)
        context.update({'module': 'workshop', 'page': 'semigroups', 'semigroup': self.semigroup})
        return context

gradebook = staff_required(GradebookView.as_view())



@staff_required
def semigroups(request):
    player = request.user.get_profile()

    return render_to_response(
        'workshop/cpanel/semigroups.html',
        {
            'my_semigroups': player.semigroups.all(),
            'all_semigroups': Semigroup.objects.all(),
            'page': 'semigroups',
            'module': 'workshop',
        },
        context_instance=RequestContext(request)
    )


class WorkshopStatus(DetailView):
    """
    Show a status page and allow start, stop and edit actions for a workshop.
    """
    model = Workshop
    template_name = 'workshop/cpanel/workshop_status.html'


workshop_status = staff_required(WorkshopStatus.as_view())