Exemple #1
0
def question_view(request, question_id):
    question = get_object_or_404(
        m.Question.objects.prefetch_related('answers'),
        activity_id=question_id)
    answer_form = None
    status = 200
    if request.user.is_authenticated:
        if request.method == 'POST':
            if not request.user.has_perm('learning.add_question'):
                context = build_base_context(request)
                context['pcode'] = 'l_question'
                context['title'] = context[
                    'msg_title'] = 'Insuficiência de permissões'
                context[
                    'msg_content'] = 'O seu utilizador não tem permissões para responder.'
                return render(request,
                              'supernova/message.html',
                              context,
                              status=403)

            if 'submit' in request.GET and request.GET['submit'] == 'answer':
                answer_form = f.AnswerForm(request.POST)
                if answer_form.is_valid():
                    with reversion.create_revision():
                        answer = answer_form.save(commit=False)
                        answer.to = question
                        answer.user = request.user
                        answer.save()
                        # Reload data, new form
                        question.refresh_from_db()
                        reversion.set_user(request.user)
                    m.AnswerNotification.objects.create(receiver=question.user,
                                                        answer=answer)
                    return HttpResponseRedirect(answer.get_absolute_url())
            else:
                status = 400
        else:
            answer_form = f.AnswerForm()

    context = build_base_context(request)
    context['pcode'] = 'l_question'
    context['title'] = 'Dúvida: %s' % question.title
    context['question'] = question
    context['answer_form'] = answer_form
    context['sub_nav'] = [{
        'name': 'Questões',
        'url': reverse('learning:questions')
    }, {
        'name':
        question.title,
        'url':
        reverse('learning:question', args=[question_id])
    }]
    return render(request, 'learning/question.html', context, status=status)
Exemple #2
0
def user_evaluations_view(request, nickname):
    if request.user.nickname != nickname:
        raise PermissionDenied()
    profile_user = get_object_or_404(m.User.objects, nickname=nickname)
    context = build_base_context(request)
    context['pcode'] = "u_evaluations"
    context['title'] = f"Avaliações de {profile_user.name}"
    context['profile_user'] = profile_user
    context['enrollments'] = college.Enrollment.objects \
        .filter(student__user=profile_user) \
        .exclude(class_instance__year=settings.COLLEGE_YEAR, class_instance__period__gte=settings.COLLEGE_PERIOD) \
        .select_related('class_instance__parent') \
        .order_by('class_instance__year', 'class_instance__period') \
        .reverse() \
        .all()
    events = college.ClassInstanceEvent.objects \
        .filter(date__gte=datetime.today().date(), class_instance__student__user=profile_user) \
        .select_related('class_instance__parent')
    context['next_evaluations'] = next_evaluations \
        = list(filter(lambda e: e.type in (college.ctypes.EventType.TEST, college.ctypes.EventType.EXAM), events))
    context['next_events'] = list(
        filter(lambda e: e not in next_evaluations, events))
    context['sub_nav'] = [{
        'name': profile_user.name,
        'url': reverse('users:profile', args=[nickname])
    }, {
        'name': 'Eventos',
        'url': request.get_raw_uri()
    }]
    return render(request, 'users/profile_evaluations.html', context)
Exemple #3
0
def review_create_view(request, content_type_id, object_id):
    try:
        object_type = ContentType.objects.get_for_id(content_type_id)
        if object_type.natural_key() not in settings.REVIEWABLE_ENTITIES:
            raise Exception()
        obj = object_type.get_object_for_this_type(id=object_id)
    except:
        return Http404()

    if request.method == 'POST':
        form = f.ReviewForm(request.POST)
        if form.is_valid():
            with reversion.create_revision():
                review = form.save(commit=False)
                review.content_object = obj
                review.user = request.user
                review.save()
            return redirect(obj.get_absolute_url())
    else:
        form = f.ReviewForm()
    context = build_base_context(request)
    context['form'] = form
    context['title'] = f"Nova avaliação a {obj}"
    context['pcode'] = "c_feedback_review"
    context['sub_nav'] = [{
        'name': 'Avaliação',
        'url': reverse('feedback:index')
    }, {
        'name': "Nova",
        'url': reverse('feedback:suggestion_create')
    }]
    return render(request, 'feedback/review_create.html', context)
Exemple #4
0
def settings_view(request, group_abbr):
    group = get_object_or_404(m.Group, abbreviation=group_abbr)
    context = build_base_context(request)
    pcode, nav_type = resolve_group_type(group)
    context['pcode'] = pcode + '_settings'
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        nav_type,
        {'name': group.abbreviation, 'url': reverse('groups:group', args=[group_abbr])},
        {'name': 'Definições', 'url': reverse('groups:settings', args=[group_abbr])}]

    permission_flags = permissions.get_user_group_permissions(request.user, group)
    if not (permission_flags & permissions.IS_ADMIN):
        context['title'] = context['msg_title'] = 'Insuficiência de permissões'
        context['msg_content'] = 'O seu utilizador não tem permissões suficientes para mudar as definições do grupo.'
        return render(request, 'supernova/message.html', context)

    context['title'] = f'Definições de {group.name}'
    context['group'] = group

    if request.method == 'POST':
        group_form = f.GroupSettingsForm(request.POST, request.FILES, instance=group)
        if group_form.is_valid():
            group_form.save()
            return redirect('groups:group', group_abbr=group_abbr)
    else:
        group_form = f.GroupSettingsForm(instance=group)

    context['group_form'] = group_form
    return render(request, 'groups/settings.html', context)
Exemple #5
0
def group_candidates_view(request, group_abbr):
    group = get_object_or_404(m.Group.objects.select_related('default_role'), abbreviation=group_abbr)

    # Check for permissions
    permission_flags = 0 if request.user.is_anonymous else permissions.get_user_group_permissions(request.user, group)
    roles_acc = permission_flags & permissions.CAN_ASSIGN_ROLES
    if not roles_acc:
        raise PermissionDenied("No permission to manage roles.")

    accepted = request.GET.get('accept')
    denied = request.GET.get('deny')
    try:
        if accepted:
            m.MembershipRequest.objects.get(id=int(accepted)).accept()
        elif denied:
            m.MembershipRequest.objects.get(id=int(accepted)).deny()
    except ValueError:
        pass

    pcode, nav_type = resolve_group_type(group)
    context = build_base_context(request)
    context['title'] = f'Candidaturas a {group.name}'
    context['default_role'] = group.default_role
    context['candidates'] = m.MembershipRequest.objects.filter(group=group, granted=None).select_related('user').all()
    context['group'] = group
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        nav_type,
        {'name': group.abbreviation, 'url': reverse('groups:group', args=[group_abbr])},
        {'name': 'Candidatos', 'url': reverse('groups:candidates', args=[group_abbr])}]
    return render(request, 'groups/membership_requests.html', context)
Exemple #6
0
def login_view(request):
    context = build_base_context(request)
    context['title'] = "Autenticação"

    if request.user.is_authenticated:
        if 'next' in request.GET:
            return HttpResponseRedirect(request.GET['next'])
        return HttpResponseRedirect(
            reverse('users:profile', args=[request.user]))

    if request.method == 'POST':
        form = f.LoginForm(data=request.POST)
        if form.is_valid():
            user: m.User = form.get_user()
            login(request, user)

            # First login (TODO change to some sort of tutorial)
            if user.last_login is None:
                return HttpResponseRedirect(
                    reverse('users:profile', args=[user.username]))

            if 'next' in request.GET:
                return HttpResponseRedirect(request.GET['next'])
            return HttpResponseRedirect(reverse('index'))
        else:
            context['login_form'] = form
    else:
        context['login_form'] = f.LoginForm()
    return render(request, 'users/login.html', context)
Exemple #7
0
def group_membership_request_view(request, group_abbr):
    group = get_object_or_404(m.Group, abbreviation=group_abbr)

    if m.Membership.objects.filter(member=request.user, group=group).exists():
        return redirect('groups:group', group_abbr=group_abbr)

    # Find existing for past requests that have not been granted (pending + denied)
    existing_request = m.MembershipRequest.objects \
        .filter(user=request.user, group=group) \
        .exclude(granted=True) \
        .first()

    context = build_base_context(request)
    if previously_requested := (existing_request is not None):
        if existing_request.granted is not None:  # Has been denied once, can no longer request
            raise PermissionDenied("Membership has been refused.")

        # \/ Deletion secret. Not the best secret, but this is unlikely to get attacked
        secret = str(existing_request.id)
        if 'remove' in request.GET:
            # Deleting existing request (pending request without neither approval nor disapproval)
            if request.GET['remove'] == secret:
                existing_request.delete()
                return redirect('groups:group', group_abbr=group_abbr)
            else:
                raise PermissionDenied("No authorization to post in this conversation.")
        # Warning the user that a pending request exists, show no form
        form = None
        context['secret'] = secret
        context['pending'] = existing_request.granted is None
Exemple #8
0
def index_view(request):
    context = build_base_context(request)
    context['title'] = "Grupos"
    context['pcode'] = "g"
    context['groups'] = m.Group.objects.prefetch_related('members').all()
    context['sub_nav'] = [{'name': 'Grupos', 'url': reverse('groups:index')}]
    return render(request, 'groups/groups.html', context)
Exemple #9
0
def conversations_view(request, group_abbr):
    group = get_object_or_404(m.Group, abbreviation=group_abbr)
    permission_flags = 0 if request.user.is_anonymous else permissions.get_user_group_permissions(request.user, group)
    read_acc = permission_flags & permissions.CAN_READ_CONVERSATIONS
    context = build_base_context(request)
    context['title'] = f'Contactos com {group.name}'
    context['group'] = group
    pcode, nav_type = resolve_group_type(group)
    context['pcode'] = pcode + '_cnt'
    if read_acc:
        context['conversations'] = chat.GroupExternalConversation.objects \
            .filter(group=group) \
            .order_by('-creation') \
            .select_related('last_activity_user')
    else:
        context['conversations'] = chat.GroupExternalConversation.objects \
            .filter(group=group, creator=request.user) \
            .exclude(creator=request.user) \
            .order_by('-creation') \
            .select_related('last_activity_user')
    context['actions'] = [
        {'name': 'Criar nova', 'url': reverse('groups:conversation_create', args=[group_abbr])}]
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        nav_type,
        {'name': group.abbreviation, 'url': reverse('groups:group', args=[group_abbr])},
        {'name': 'Conversas', 'url': reverse('groups:conversations', args=[group_abbr])}]
    return render(request, 'groups/conversations.html', context)
Exemple #10
0
def calendar_management_view(request, group_abbr):
    group = get_object_or_404(m.Group, abbreviation=group_abbr)

    if 'del' in request.GET:
        try:
            del_id = int(request.GET['del'])
            m.ScheduleEntry.objects.get(id=del_id, group=group).delete()
            return redirect('users:calendar_manage', abbreviation=group_abbr)
        except (ValueError, m.ScheduleOnce.DoesNotExist):
            return HttpResponse(status=400)

    context = build_base_context(request)
    pcode, nav_type = resolve_group_type(group)
    context['pcode'] = pcode + '_cal_man'

    permission_flags = permissions.get_user_group_permissions(request.user, group)
    if not permission_flags & permissions.CAN_CHANGE_SCHEDULE:
        context['title'] = context['msg_title'] = 'Insuficiência de permissões'
        context['msg_content'] = 'O seu utilizador não tem permissões suficientes para alterar a agenda do grupo.'
        return render(request, 'supernova/message.html', context)

    context['group'] = group
    once_schedule_entries = m.ScheduleOnce.objects.filter(group=group)
    periodic_schedule_entries = m.SchedulePeriodic.objects.filter(group=group)
    context['once_entries'] = once_schedule_entries
    context['periodic_entries'] = periodic_schedule_entries

    # Show empty forms by default
    once_form = f.ScheduleOnceForm()
    periodic_form = f.SchedulePeriodicForm()
    if 'type' in request.GET:
        rtype = request.GET['type']
        if rtype == "periodic" and request.method == 'POST':
            filled_form = f.SchedulePeriodicForm(request.POST)
            if filled_form.is_valid():
                entry = filled_form.save(commit=False)
                entry.group = group
                entry.save()
                m.ScheduleCreation.objects.create(group=group, author=request.user, entry=entry)
            else:
                periodic_form = filled_form  # Replace empty form with filled form with form filled with errors
        elif rtype == "once" and request.method == 'POST':
            filled_form = f.ScheduleOnceForm(request.POST)
            if filled_form.is_valid():
                entry = filled_form.save(commit=False)
                entry.group = group
                entry.save()
                m.ScheduleCreation.objects.create(group=group, author=request.user, entry=entry)
            else:
                once_form = filled_form  # Replace empty form with form filled with errors

    context['once_form'] = once_form
    context['periodic_form'] = periodic_form
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        nav_type,
        {'name': group.abbreviation, 'url': reverse('groups:group', args=[group_abbr])},
        {'name': 'Agenda', 'url': reverse('groups:calendar_manage', args=[group_abbr])}]

    return render(request, 'groups/calendar_manage.html', context)
Exemple #11
0
def create_invite_view(request, nickname):
    if request.user.nickname != nickname:
        raise PermissionDenied()
    user = get_object_or_404(m.User.objects.prefetch_related('invites'),
                             nickname=nickname)
    if 'confirmed' in request.GET and request.GET['confirmed'] == 'true':
        token = registrations.generate_token(10)
        m.Invite.objects.create(issuer=user,
                                token=token,
                                expiration=(datetime.now() +
                                            timedelta(days=2)))
        return HttpResponseRedirect(reverse('users:invites', args=[nickname]))

    context = build_base_context(request)
    context['pcode'] = "u_invites"
    context['title'] = f"Convites emitidos por {user.name}"
    context['profile_user'] = user
    context['sub_nav'] = [{
        'name': user.name,
        'url': reverse('users:profile', args=[nickname])
    }, {
        'name': 'Convites',
        'url': reverse('users:invites', args=[nickname])
    }]
    return render(request, 'users/invite_new.html', context)
Exemple #12
0
def create_exercise_view(request):
    if request.method == 'POST':
        form = f.ExerciseForm(request.POST)
        if form.is_valid():
            with reversion.create_revision():
                exercise = form.save(commit=False)
                exercise.author = request.user
                exercise.save()
                form.save_m2m()
                reversion.set_user(request.user)
            return redirect('learning:exercise', exercise_id=exercise.id)
    else:
        if 'section' in request.GET:
            section = get_object_or_404(m.Section, id=request.GET['section'])
            form = f.ExerciseForm(initial={'synopses_sections': [
                section,
            ]})
        else:
            form = f.ExerciseForm()

    context = build_base_context(request)
    context['pcode'] = 'l_exercises'
    context['title'] = 'Submeter exercício'
    context['form'] = form
    editor = MarkdownxWidget().render(name='', value='', attrs=dict())
    context['markdown_editor'] = editor
    context['sub_nav'] = [{
        'name': 'Exercícios',
        'url': reverse('learning:exercises')
    }, {
        'name': 'Submeter exercício',
        'url': reverse('learning:exercise_create')
    }]
    return render(request, 'learning/editor.html', context)
Exemple #13
0
def edit_exercise_view(request, exercise_id):
    exercise = get_object_or_404(m.Exercise, id=exercise_id)
    if request.method == 'POST':
        form = f.ExerciseForm(request.POST, instance=exercise)
        if form.is_valid():
            with reversion.create_revision():
                exercise = form.save()
                reversion.set_user(request.user)
            return redirect('learning:exercise', exercise_id=exercise.id)
    else:
        form = f.ExerciseForm(instance=exercise)

    context = build_base_context(request)
    context['pcode'] = 'l_exercises'
    context['title'] = f'Editar exercício #{exercise.id}'
    context['form'] = form
    context['sub_nav'] = [{
        'name': 'Exercícios',
        'url': reverse('learning:exercises')
    }, {
        'name':
        f'#{exercise_id}',
        'url':
        reverse('learning:exercise', args=[exercise_id])
    }, {
        'name':
        'Editar',
        'url':
        reverse('learning:exercise_edit', args=[exercise_id])
    }]
    return render(request, 'learning/editor.html', context)
Exemple #14
0
def subarea_section_view(request, subarea_id, section_id):
    """
    View where a section is displayed as direct child of a subarea.
    """
    section = get_object_or_404(m.Section.objects.select_related(
        'subarea__area').prefetch_related('classes').annotate(
            question_count=Count('linked_questions', distinct=True),
            exercise_count=Count('exercises', distinct=True)),
                                id=section_id)
    subarea = section.subarea
    if subarea.id != subarea_id:
        raise Http404('Mismatched section')
    area = subarea.area
    context = build_base_context(request)
    __section_common(section, context)
    context['title'] = '%s - %s' % (section.title, area.title)
    context['sub_nav'] = [{
        'name': 'Sínteses',
        'url': reverse('learning:areas')
    }, {
        'name': area.title,
        'url': reverse('learning:area', args=[area.id])
    }, {
        'name': subarea.title,
        'url': reverse('learning:subarea', args=[subarea_id])
    }, {
        'name': section.title,
        'url': '#'
    }]
    return render(request, 'learning/section.html', context)
Exemple #15
0
def group_view(request, group_abbr):
    group = get_object_or_404(m.Group, abbreviation=group_abbr)
    permission_flags = 0 if request.user.is_anonymous else permissions.get_user_group_permissions(request.user, group)

    context = build_base_context(request)
    context['membership_perms'] = {
        'is_admin': permission_flags & permissions.IS_ADMIN,
        'can_announce': permission_flags & permissions.CAN_ANNOUNCE,
        'can_modify_roles': permission_flags & permissions.CAN_MODIFY_ROLES,
        'can_change_schedule': permission_flags & permissions.CAN_CHANGE_SCHEDULE}
    context['title'] = group.name
    context['group'] = group
    context['pcode'], nav_type = resolve_group_type(group)
    context['activities'] = m.Activity.objects.filter(group=group).order_by('datetime').reverse()
    context['is_member'] = is_member = not request.user.is_anonymous and group in request.user.groups_custom.all()

    if is_member:
        context['actions'] = [
            {'name': 'Sair do grupo', 'url': '#TODO'}]  # TODO
    else:
        if group.outsiders_openness == m.Group.REQUEST:
            context['actions'] = [
                {'name': 'Solicitar admissão', 'url': reverse('groups:membership_req', args=[group_abbr])}]
        elif group.outsiders_openness == m.Group.OPEN:
            context['actions'] = [
                {'name': 'Entrar no grupo', 'url': reverse('groups:membership_req', args=[group_abbr])}]

    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        nav_type,
        {'name': group.abbreviation, 'url': reverse('groups:group', args=[group_abbr])}]
    return render(request, 'groups/group.html', context)
Exemple #16
0
def subsection_view(request, parent_id, child_id):
    """
    View where a section is displayed as a part of another section.
    """
    parent = get_object_or_404(m.Section, id=parent_id)
    child = get_object_or_404(
        m.Section.objects.prefetch_related('classes').annotate(
            question_count=Count('linked_questions', distinct=True),
            exercise_count=Count('exercises', distinct=True)),
        id=child_id)
    context = build_base_context(request)
    __section_common(child, context)
    context['title'] = '%s - %s' % (child.title, parent.title)
    context['sub_nav'] = [{
        'name': 'Sínteses',
        'url': reverse('learning:areas')
    }, {
        'name': '...',
        'url': '#'
    }, {
        'name': parent.title,
        'url': reverse('learning:section', args=[parent_id])
    }, {
        'name': child.title,
        'url': '#'
    }]
    return render(request, 'learning/section.html', context)
Exemple #17
0
def announce_view(request, group_abbr):
    group = get_object_or_404(m.Group, abbreviation=group_abbr)
    context = build_base_context(request)
    pcode, nav_type = resolve_group_type(group)
    context['pcode'] = pcode + '_announce'
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        nav_type,
        {'name': group.abbreviation, 'url': reverse('groups:group', args=[group_abbr])},
        {'name': 'Anunciar', 'url': reverse('groups:announce', args=[group_abbr])}]

    permission_flags = permissions.get_user_group_permissions(request.user, group)
    if not (permission_flags & permissions.CAN_ANNOUNCE):
        context['title'] = context['msg_title'] = 'Insuficiência de permissões'
        context['msg_content'] = 'O seu utilizador não tem permissões suficientes para anúnciar pelo grupo.'
        return render(request, 'supernova/message.html', context)

    context['title'] = f'Anúnciar por {group.name}'
    context['group'] = group

    if request.method == 'POST':
        form = f.AnnounceForm(request.POST)
        if form.is_valid():
            announcement = form.save(commit=False)
            announcement.group = group
            announcement.author = request.user
            announcement.save()
            group.notify_subscribers(announcement)
            return redirect('groups:announcement', group_abbr=group_abbr, announcement_id=announcement.id)
    else:
        form = f.AnnounceForm()

    context['form'] = form
    return render(request, 'groups/announce.html', context)
Exemple #18
0
def subarea_create_view(request, area_id):
    area = get_object_or_404(m.Area, id=area_id)

    if request.method == 'POST':
        form = f.SubareaForm(data=request.POST)
        if form.is_valid():
            with reversion.create_revision():
                new_subarea = form.save()
                reversion.set_user(request.user)
            return HttpResponseRedirect(
                reverse('learning:subarea', args=[new_subarea.id]))
    else:
        form = f.SubareaForm(initial={'area': area})
        form.fields['area'].widget = HiddenInput()

    context = build_base_context(request)
    context['pcode'] = 'l_synopses_subarea'
    context['title'] = 'Criar nova categoria de "%s"' % area.title
    context['area'] = area
    context['form'] = form
    context['action_page'] = reverse('learning:subarea_create', args=[area_id])
    context['action_name'] = 'Criar'
    context['sub_nav'] = [{
        'name': 'Sínteses',
        'url': reverse('learning:areas')
    }, {
        'name': area.title,
        'url': reverse('learning:area', args=[area.id])
    }, {
        'name':
        'Propor nova categoria',
        'url':
        reverse('learning:subarea_create', args=[area_id])
    }]
    return render(request, 'learning/generic_form.html', context)
Exemple #19
0
def department_exercises_view(request, department_id):
    department = get_object_or_404(college.Department, id=department_id)
    context = build_base_context(request)
    context['pcode'] = 'l_exercises'
    context['title'] = f'Exercícios de {department.classes}'
    context['department'] = department
    if not request.user.is_anonymous and request.user.is_student:
        user_students = request.user.students.all()
        current_class_ids = department.classes \
            .filter(instances__enrollments__student__in=user_students,
                    instances__year=settings.COLLEGE_YEAR,
                    instances__period=settings.COLLEGE_PERIOD) \
            .distinct() \
            .values_list('id', flat=True) \
            .all()

        done_class_ids = department.classes \
            .filter(instances__enrollments__student__in=user_students, ) \
            .exclude(id__in=current_class_ids) \
            .distinct() \
            .values_list('id', flat=True) \
            .all()

        classes = department.classes \
            .annotate(section_count=djm.Count('synopsis_sections'),
                      exercise_count=djm.Count('synopsis_sections__exercises')) \
            .filter(instances__year__gt=settings.COLLEGE_YEAR - 2) \
            .order_by('name') \
            .all()

        current, done, other = [], [], []
        for class_ in classes:
            if class_.id in current_class_ids:
                current.append(class_)
            elif class_.id in done_class_ids:
                done.append(class_)
            else:
                other.append(class_)

        context['other_classes'] = other
        context['current_classes'] = current
        context['done_classes'] = done
    else:
        context['classes'] = department.classes \
            .annotate(section_count=djm.Count('synopsis_sections'),
                      exercise_count=djm.Count('synopsis_sections__exercises')) \
            .order_by('name') \
            .all()

    context['sub_nav'] = [{
        'name': 'Exercicios',
        'url': reverse('learning:exercises')
    }, {
        'name':
        department.name,
        'url':
        reverse('learning:department_exercises', args=[department_id])
    }]
    return render(request, 'learning/department_exercises.html', context)
Exemple #20
0
def index_view(request):
    context = build_base_context(request)
    context['pcode'] = "t_chat"
    context['title'] = "Salas de conversa"
    context['rooms'] = m.PublicRoom.objects.all()
    context['sub_nav'] = [
        {'name': 'Conversas', 'url': reverse('college:index')}]
    return render(request, 'chat/index.html', context)
Exemple #21
0
def section_edit_view(request, section_id):
    section = get_object_or_404(m.Section, id=section_id)
    if request.method == 'POST':
        section_form = f.SectionEditForm(data=request.POST, instance=section)
        sources_formset = f.SectionSourcesFormSet(request.POST,
                                                  instance=section,
                                                  prefix="sources")
        web_resources_formset = f.SectionWebpageResourcesFormSet(
            request.POST, instance=section, prefix="wp_resources")
        # doc_resources_formset = f.SectionDocumentResourcesFormSet(
        #     request.POST, instance=section, prefix="doc_resources")
        if section_form.is_valid() \
                and sources_formset.is_valid() \
                and web_resources_formset.is_valid():
            # and doc_resources_formset.is_valid():
            with reversion.create_revision():
                section = section_form.save()
                sources_formset.save()
                # doc_resources_formset.save()
                web_resources_formset.save()
                section.compact_indexes()
                reversion.set_user(request.user)
            # Redirect user to the updated section
            return HttpResponseRedirect(
                reverse('learning:section', args=[section.id]))
    else:
        section_form = f.SectionEditForm(instance=section)
        sources_formset = f.SectionSourcesFormSet(instance=section,
                                                  prefix="sources")
        web_resources_formset = f.SectionWebpageResourcesFormSet(
            instance=section, prefix="wp_resources")
        doc_resources_formset = f.SectionDocumentResourcesFormSet(
            instance=section, prefix="doc_resources")

    context = build_base_context(request)
    context['pcode'] = 'l_synopses_section'
    context['title'] = 'Editar %s' % section.title
    context['section'] = section
    context['form'] = section_form
    context['sources_formset'] = sources_formset
    context['web_resources_formset'] = web_resources_formset
    # context['doc_resources_formset'] = doc_resources_formset
    context['action_page'] = reverse('learning:section_edit',
                                     args=[section_id])
    context['action_name'] = 'Editar'
    context['sub_nav'] = [{
        'name': 'Sínteses',
        'url': reverse('learning:areas')
    }, {
        'name': '...',
        'url': '#'
    }, {
        'name': section.title,
        'url': reverse('learning:section', args=[section_id])
    }, {
        'name': 'Editar'
    }]
    return render(request, 'learning/section_management.html', context)
Exemple #22
0
def question_create_view(request):
    context = build_base_context(request)
    context['pcode'] = 'l_question_create'
    context['title'] = 'Colocar dúvida'
    if request.method == 'POST':
        form = f.QuestionForm(request.POST)
        if form.is_valid():
            with reversion.create_revision():
                question = form.save(commit=False)
                question.user = request.user
                question.save()
                form.save_m2m()
                reversion.set_user(request.user)
            return redirect('learning:question',
                            question_id=question.activity_id)
    else:
        initial = {}
        if 'section' in request.GET:
            try:
                section = m.Section.objects.filter(
                    id=int(request.GET['section'])).first()
                if section is not None:
                    initial['linked_sections'] = [
                        section,
                    ]
            except ValueError:
                pass
        if 'exercise' in request.GET:
            try:
                section = m.Exercise.objects.filter(
                    id=int(request.GET['exercise'])).first()
                if section is not None:
                    initial['linked_exercises'] = [
                        section,
                    ]
            except ValueError:
                pass
        if 'class' in request.GET:
            try:
                klass = college.Class.objects.filter(
                    id=int(request.GET['class'])).first()
                if klass is not None:
                    initial['linked_classes'] = [
                        klass,
                    ]
            except ValueError:
                pass
        form = f.QuestionForm(initial=initial)
    context['form'] = form
    context['sub_nav'] = [{
        'name': 'Questões',
        'url': reverse('learning:questions')
    }, {
        'name': 'Colocar questão',
        'url': reverse('learning:question_create')
    }]
    return render(request, 'learning/question_editor.html', context)
Exemple #23
0
def settings_view(request):
    context = build_base_context(request)
    context['title'] = "Definições"
    context['pcode'] = "manag_settings"
    context['sub_nav'] = [{
        'name': 'Alterações',
        'url': reverse('management:settings')
    }]
    return render(request, 'management/settings.html', context)
Exemple #24
0
def pedagogic_view(request):
    context = build_base_context(request)
    context['title'] = "Grupos"
    context['pcode'] = "g_ped"
    context['groups'] = m.Group.objects.prefetch_related('members').filter(type=m.Group.PEDAGOGIC).all()
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        {'name': 'Pedagogicos', 'url': reverse('groups:pedagogic')}]
    return render(request, 'groups/groups.html', context)
Exemple #25
0
def nuclei_view(request):
    context = build_base_context(request)
    context['title'] = "Grupos"
    context['pcode'] = "g_nucl"
    context['groups'] = m.Group.objects.prefetch_related('members').filter(type=m.Group.NUCLEI).all()
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        {'name': 'Núcleos', 'url': reverse('groups:nuclei')}]
    return render(request, 'groups/groups.html', context)
Exemple #26
0
def communities_view(request):
    context = build_base_context(request)
    context['title'] = "Grupos"
    context['pcode'] = "g_com"
    context['groups'] = m.Group.objects.prefetch_related('members').filter(type=m.Group.COMMUNITY).all()
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        {'name': 'Comunidades', 'url': reverse('groups:communities')}]
    return render(request, 'groups/groups.html', context)
Exemple #27
0
def index_view(request):
    context = build_base_context(request)
    context['title'] = "Painel administrativo"
    context['pcode'] = "manag_index"
    context['sub_nav'] = [{
        'name': 'Painel administrativo',
        'url': reverse('management:index')
    }]
    return render(request, 'management/index.html', context)
Exemple #28
0
def users_view(request):
    context = build_base_context(request)
    context['title'] = "Gestão"
    context['pcode'] = "manag_users"
    context['users'] = users.User.objects.all()
    context['latest_registrations'] = users.Registration.objects \
        .order_by('creation') \
        .select_related('requested_student', 'requested_teacher', 'resulting_user', 'invite__issuer') \
        .reverse()
    context['suspended_users'] = users.User.objects.order_by(
        'nickname').filter(is_active=False).all()

    context['registrations_with_claimed_teachers'] = users.Registration.objects \
        .order_by('creation') \
        .select_related('requested_student', 'requested_teacher', 'resulting_user', 'invite') \
        .exclude(requested_teacher=None) \
        .exclude(resulting_user=None) \
        .filter(requested_teacher__user=None) \
        .reverse()

    reputation_offset_form = f.ReputationOffsetForm(
        prefix='reputation_offset_')
    assign_student_form = f.BindStudentToUserForm(prefix='assign_student_')
    assign_teacher_form = f.BindTeacherToUserForm(prefix='assign_teacher_')
    password_reset_form = f.PasswordResetForm(prefix='password_reset_')
    if request.method == 'POST':
        if 'reputation_offset' in request.GET:
            reputation_offset_form = f.ReputationOffsetForm(
                request.POST, prefix='reputation_offset_')
            if reputation_offset_form.is_valid():
                offset = reputation_offset_form.save()
                offset.issue_notification()
        elif 'assign_student' in request.GET:
            assign_student_form = f.BindStudentToUserForm(
                request.POST, prefix='assign_student_')
            if assign_student_form.is_valid():
                assign_student_form.save()
        elif 'assign_teacher' in request.GET:
            assign_teacher_form = f.BindTeacherToUserForm(
                request.POST, prefix='assign_teacher_')
            if assign_teacher_form.is_valid():
                assign_teacher_form.save()
        elif 'password_reset' in request.GET:
            password_reset_form = f.PasswordResetForm(request.POST,
                                                      prefix='password_reset_')
            if password_reset_form.is_valid():
                context['new_password'] = password_reset_form.save()
    context['reputation_offset_form'] = reputation_offset_form
    context['assign_student_form'] = assign_student_form
    context['assign_teacher_form'] = assign_teacher_form
    context['password_reset_form'] = password_reset_form
    context['sub_nav'] = [{
        'name': 'Utilizadores',
        'url': reverse('management:users')
    }]
    return render(request, 'management/users.html', context)
Exemple #29
0
def user_profile_settings_view(request, nickname):
    if request.user.nickname != nickname and not request.user.is_staff:
        raise PermissionDenied()
    profile_user = get_object_or_404(m.User, nickname=nickname)
    context = build_base_context(request)

    if request.user.nickname != nickname and request.user.is_staff:
        context['permissions_form'] = f.AccountPermissionsForm(profile_user)
    settings_form = f.AccountSettingsForm(instance=profile_user)

    if request.method == 'POST':
        if 'permissions' in request.GET:
            if not request.user.is_staff:
                raise PermissionDenied(
                    "Only staff accounts can change user permissions.")
            if request.user == profile_user:
                raise PermissionDenied(
                    "Changing own permissions is forbidden.")
            permissions_form = f.AccountPermissionsForm(
                profile_user, request.POST)
            context['permissions_form'] = permissions_form
            if permissions_form.is_valid():
                permissions_form.save()
                profile_user.refresh_from_db()  # Reload permissions
        else:
            settings_form = f.AccountSettingsForm(request.POST,
                                                  request.FILES,
                                                  instance=profile_user)
            if settings_form.is_valid():
                profile_user = settings_form.save()
                if 'new_password' in settings_form.cleaned_data and settings_form.cleaned_data[
                        'new_password']:
                    profile_user.set_password(
                        settings_form.cleaned_data['new_password'])
                    profile_user.save()
                    # Prevent logout locally
                    if profile_user == request.user:
                        login(request, profile_user)

                cache.delete(f'profile_{nickname}')
                return HttpResponseRedirect(
                    reverse('users:profile', args=[profile_user.nickname]))

    context['settings_form'] = settings_form
    context['pcode'] = 'u_settings'
    context['title'] = 'Definições da conta'
    context['profile_user'] = profile_user
    context['sub_nav'] = [{
        'name': "Perfil de " + profile_user.name,
        'url': reverse('users:profile', args=[nickname])
    }, {
        'name': "Definições da conta",
        'url': reverse('users:settings', args=[nickname])
    }]

    return render(request, 'users/profile_settings.html', context)
Exemple #30
0
def institutional_view(request):
    context = build_base_context(request)
    context['title'] = "Grupos"
    context['pcode'] = "g_inst"
    context['groups'] = m.Group.objects.prefetch_related('members').filter(
        Q(type=m.Group.ACADEMIC_ASSOCIATION) | Q(type=m.Group.INSTITUTIONAL)).all()
    context['sub_nav'] = [
        {'name': 'Grupos', 'url': reverse('groups:index')},
        {'name': 'Institucionais', 'url': reverse('groups:institutional')}]
    return render(request, 'groups/groups.html', context)