Example #1
0
class CreateUserView(View):
    @method_decorator(login_required)
    @method_decorator(role_required('user manager'))
    def get(self, request):

        form = UserCreationForm()
        return render_to_response('users/create.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(login_required)
    @method_decorator(role_required('user manager'))
    def post(self, request):

        # Create and validate the form
        form = UserCreationForm(request.POST, request.FILES)
        if form.is_valid():

            # Retrieve the user, set the password, and create him/her
            user, password = form.instance, form.cleaned_data['password']
            user.save()

            user.refresh_from_db()
            grades = form.cleaned_data['grades']

            user.grades = grades
            user.set_password(password)
            user.save()

            # Redirect to user list
            return redirect(reverse_lazy('users:list'))

        return render_to_response('users/create.html',
                                  context=RequestContext(request, locals()),
                                  status=401)
Example #2
0
class CreateMaterialView(View):
    @method_decorator(login_required)
    @method_decorator(role_required('content manager'))
    def get(self, request):

        form = MaterialForm(initial={'user': request.user})
        fields = {
            'suggested_ages': SchoolGrade,
            'types': Type,
            'themes': Theme,
            'languages': Language
        }

        for field, queryset in fields.iteritems():
            form.fields[field].queryset = queryset.objects.active()

        return render_to_response('materials/create.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(login_required)
    @method_decorator(role_required('content manager'))
    @method_decorator(csrf_protect)
    def post(self, request):

        form = MaterialForm(request.POST,
                            request.FILES,
                            initial={'user': request.user})

        if form.is_valid():

            material = form.instance
            #TODO:set upload_to attribute to destination path
            form.save()

            ActionLog.objects.log_content(
                'Registered new material entry (id: %s)' % material.id,
                user=request.user,
                status=201)
            return redirect(
                reverse_lazy('content:view',
                             kwargs={'content_id': material.id}))

        ActionLog.objects.log_content('Failed to register new material entry',
                                      user=request.user,
                                      status=401)

        return render_to_response('materials/create.html',
                                  context=RequestContext(request, locals()),
                                  status=401)
Example #3
0
class SearchView(View):
    @method_decorator(login_required)
    @method_decorator(role_required('parent'))
    def get(self, request):

        users = User.objects.active()
        return render_to_response('users/list.html',
                                  context=RequestContext(request, locals()))
Example #4
0
class MaterialDownloadView(View):
    """
		This view handles the logic for downloading material
	"""
    @method_decorator(login_required)
    @method_decorator(role_required('parent'))
    def get(self, request, content_id=0):
        """ This method is called when the user requests to download a material
			It validates the material exists and is active, registers the download and serves the file
			Returns forbidden response if unsuccessful and HttpResponse with the material if successful
		"""

        # Attempt to load the material
        try:
            material = Material.objects.active().get(id=content_id)
        except Material.DoesNotExist:

            # If not exists, write in Action Log and return forbidden
            ActionLog.objects.log_content(
                'Attempted to load nonexistent material (id: %s)' % content_id,
                user=request.user,
                status=403)
            return HttpResponseForbidden()

        else:

            # Check if the material has a content attached
            if bool(material.content.name) is False:

                # If no content, write in Action Log and return forbidden
                ActionLog.objects.log_content(
                    'Attempted to download material without attached content (id: %s)'
                    % content_id,
                    user=request.user,
                    status=403)
                return HttpResponseForbidden()

            # Register the download
            Download.objects.create(
                user=request.user,
                material=material,
            )

            # Get the material content type we'll use it later
            content_type, _ = guess_type(material.content.name, strict=True)

            # Write in Action Log
            ActionLog.objects.log_content('Downloaded material (id: %s)' %
                                          content_id,
                                          user=request.user,
                                          status=200)

            # Read the file into the output stream and send it to the user
            return HttpResponse(material.content.read(),
                                content_type=content_type)
Example #5
0
class ReportView(View):
    """ Represents a generic report view which compiles a report within a transaction to speed
		up report generation. The report is compiled once and stored in the server for history
		purposes. The report is compiled as an HTML which presents the collected data in a simple
		way. This reports may only be created by an administrator.
	"""

    report_name = ''
    report_class = None
    template = ''

    @method_decorator(login_required)
    @method_decorator(role_required('administrator'))
    # @method_decorator(cache_page(1200))
    def get(self, request):

        # Record starting time
        start = now()

        # Perform basic filters based on time range (if set)
        query = self.report_class.objects.active()

        # Extract information within a transaction
        with atomic():
            data = self.generate_report(query)

        # Render the report
        name = self.report_name
        report_doc = render(template_name=self.template,
                            context=RequestContext(request, locals()),
                            request=request).encode('utf-8')

        # Count the elapsed time
        time = (now() - start).total_seconds()

        # Create the report output (save it if required to)
        filename = 'report_%s.html' % calendar.timegm(start.timetuple())
        with open('reports/%s' % filename, 'w') as f:
            f.write(report_doc)

        # Send file as attachment
        ActionLog.objects.log_reports(
            'Generated report (name: %s) in %s seconds' %
            (self.report_name, time),
            user=request.user)
        return HttpResponse(report_doc)

    def generate_report(self, query):
        raise NotImplementedError()
Example #6
0
class ViewUserView(View):
    """
		Class responsible to handle user requests inquiring about user profiles:
			Receives the logged user request containing the target user profile id to display.
				It evaluates if the user according to its role should be allowed or denied access to the target user profile
			Returns the target user profile view on success, 40X otherwise.
	"""
    @method_decorator(login_required)
    @method_decorator(role_required('teacher'))
    def get(self, request, user_id=0):

        try:
            u = User.objects.get(id=user_id)
        except User.DoesNotExist:

            ActionLog.objects.log_account(
                'Invalid user profile information request : (user_id: %s)' %
                user_id,
                user=request.user,
                status=401)
            return HttpResponseForbidden()
        else:
            if request.user.belongs_to('user manager'):
                form = UserViewForm(instance=u)
            else:
                if request.user.id == int(user_id):
                    form = UserViewForm(instance=u)
                else:
                    ActionLog.objects.log_account(
                        'Attempted to view user profile information without enough privileges : (user_id: %s)'
                        % user_id,
                        user=request.user,
                        status=401)
                    return HttpResponseForbidden()
        ActionLog.objects.log_account(
            'Displayed user profile information (email address: %s)' %
            u.email_address,
            user=request.user)
        return render_to_response('users/view.html',
                                  context=RequestContext(request, locals()))
Example #7
0
class DownloadsView(View):
	"""

	"""

	@method_decorator(login_required)
	@method_decorator(role_required('teacher'))
	def get(self, request, content_id = 0):

		# Serve file

		# Save download
		try: material = Material.objects.get(id = content_id)
		except Material.DoesNotExist:

			ActionLog.objects.log_content('Failed to locate material with ID \'%s\'' % content_id, status = 403, user = request.user)
			return HttpResponseForbidden()
		else:
			Download.objects.create(
				user = request.user,
				material = material,
			)

			ActionLog.objects.log_tags('Successfully downloaded material (id: %s)' % content_id, user = request.user)
Example #8
0
class SearchView(View):
    """ This view handles the material search function. The filters are received and then look in the database
		for materials that match with the filters. The average of the material rating is calculated and added to the
		properties of the object. The number of the materials to be displayed is handle with the paginator method. At
		the end, the objects are returned with a json format.
	"""
    @method_decorator(login_required)
    @method_decorator(role_required('parent'))
    def get(self, request):

        form = SearchForm()
        return render_to_response('home.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(login_required)
    @method_decorator(ajax_required)
    @method_decorator(role_required('parent'))
    @method_decorator(cache_page(300))
    def post(self, request):

        # Filter material based on query
        query = Material.objects.active()

        form = SearchForm(request.POST)
        form.is_valid()
        data = form.cleaned_data

        params = (Q(title__icontains=data['search'])
                  | Q(description__icontains=data['search']))

        query = query.filter(params)

        params_list = []

        if (len(data['grades']) > 0):
            params_list.append(('suggested_ages__in', data['grades']))

        if (len(data['type']) > 0):
            params_list.append(('types__in', data['type']))

        if (len(data['language']) > 0):
            params_list.append(('languages__in', data['language']))

        if (len(data['theme']) > 0):
            params_list.append(('themes__in', data['theme']))

        if len(params_list) > 0:
            params2 = [Q(x) for x in params_list]
            query = query.filter(reduce(operator.or_, params2))

        # Annotate the results with rating average
        query = query.annotate(rating=Avg('comments__rating_value'))

        # Paginate the results and serialize the response
        paginator = Paginator(query, request.GET.get('page_size', 10))
        page = request.GET.get('page', 1)

        try:
            materials = paginator.page(page)
        except EmptyPage:
            materials = paginator.page(paginator.num_pages)
        except PageNotAnInteger:
            materials = paginator.page(1)

        ActionLog.objects.log_content('Queried for materials (filters: %s)' %
                                      data,
                                      user=request.user,
                                      status=302)
        return JsonResponse({
            'version':
            '1.0.0',
            'status':
            302,
            'pages': {
                'prev':
                materials.previous_page_number()
                if materials.has_previous() else None,
                'next':
                materials.next_page_number() if materials.has_next() else None,
                'current':
                page,
                'total':
                paginator.num_pages,
                'count':
                query.count(),
                'page_size':
                paginator.per_page
            },
            'results': [{
                'id': m.id,
                'title': m.title,
                'description': m.description,
                'rating': int(round(m.rating or 0)),
                'tags': {
                    'types': [t.name for t in m.types.filter(active=True)],
                    'themes': [t.name for t in m.themes.filter(active=True)],
                    'languages':
                    [t.name for t in m.languages.filter(active=True)],
                    'ages':
                    [t.name for t in m.suggested_ages.filter(active=True)]
                }
            } for m in materials]
        })
Example #9
0
class TagsView(View):
    """
		Inputs: request.GET['query'] (optional): The filter criteria to use in order to select tags. Defaults to None.
		Outputs:
​
			A JSON document complying with the following schema:
​
			{
				"$schema": "http://json-schema.org/draft-04/schema#",
​
				"id": "http://jsonschema.net/tag-list",
				"type": "object",
				"properties": {
​
					"type": { "id": "http://jsonschema.net/tag-list/type", "type": "string" },
					"data": {
						"id": "http://jsonschema.net/tag-list/data",
						"type": "array",
						"items": [
							{
								"id": "http://jsonschema.net/tag-list/data/tag",
								"type": "object",
								"properties": {
									"id": { "id": "http://jsonschema.net/tag-list/data/tag/id", "type": "integer" },
									"name": { "id": "http://jsonschema.net/tag-list/data/tag/name", "type": "string" }
								}
							}
						]
					}
​
				},
				"required": [ "type", "data" ]
			}
​
			Possible values include:
​
			{ "type": "theme", "data": [] }
			{ "type": "language", "data": [ { "id": 1, "name": "inglés" } ] }
		"""
    @method_decorator(login_required)
    @method_decorator(ajax_required)
    @method_decorator(role_required('content manager'))
    def get(self, request, tag_type=''):

        # Retrieve parameters
        filters = request.GET.get('filter', '')

        # Query all tags from the specified tag, if valid
        if tag_type == 'theme':
            data = Theme.objects.active().filter(name__icontains=filters)
        elif tag_type == 'type':
            data = Type.objects.active().filter(name__icontains=filters)
        elif tag_type == 'language':
            data = Language.objects.active().filter(name__icontains=filters)
        else:

            # If type is invalid, return error
            ActionLog.objects.log_tags('Failed to display %s tags' % tag_type,
                                       user=request.user,
                                       status=401)
            return HttpResponseForbidden()

        # Return tags list JSON
        ActionLog.objects.log_tags('Located tag cluster', user=request.user)
        return JsonResponse({
            'version':
            '1.0.0',
            'status':
            200,
            'type':
            tag_type,
            'data': [{
                'id': tag.id,
                'name': tag.name
            } for tag in data]
        })

    @method_decorator(login_required)
    @method_decorator(ajax_required)
    @method_decorator(csrf_protect)
    @method_decorator(role_required('content manager'))
    def post(self, request, tag_id=0, tag_type='', action=''):

        # Tag creation request
        if action == 'create':

            # Retrieve parameters
            name = request.POST['name']

            # Determine tag type, if valid
            if tag_type == 'type': tag_cls = Type
            elif tag_type == 'theme': tag_cls = Theme
            elif tag_type == 'language': tag_cls = Language
            else:

                # If not valid, return error
                ActionLog.objects.log_tags(
                    'Failed to create tag entry (id: %s)' % tag_id,
                    user=request.user,
                    status=401)
                return HttpResponseForbidden()

            # Ensure that a tag with the same name does not exist
            if not tag_cls.objects.active().filter(name__iexact=name).exists():

                # Create tag
                tag = tag_cls.objects.create(name=name)

                # Return response JSON
                ActionLog.objects.log_tags('Created tag entry (id: %s)' %
                                           tag_id,
                                           user=request.user,
                                           status=201)
                return JsonResponse(
                    {
                        'version': '1.0.0',
                        'status': 201,
                        'data': {
                            'type': tag_type,
                            'id': tag.id,
                            'name': tag.name
                        }
                    },
                    status=201)
            elif bool(tag_cls.objects.inactive().filter(
                    name__iexact=name)) is True:

                tag = tag_cls.objects.inactive().get(name__iexact=name)
                tag.active = True
                tag.save()

                return JsonResponse(
                    {
                        'version': '1.0.0',
                        'status': 201,
                        'data': {
                            'type': tag_type,
                            'id': tag.id,
                            'name': tag.name
                        }
                    },
                    status=201)

            # Return duplicate tag response JSON
            ActionLog.objects.log_tags('Failed to create tag entry (id: %s)' %
                                       tag_id,
                                       user=request.user,
                                       status=302)
            return JsonResponse({
                'version': '1.0.0',
                'status': 302
            },
                                status=302)

        # Tag edition request
        elif action == 'edit':

            # Retrieve tag name
            name = request.POST['name']

            if tag_type == 'theme':

                tag = Theme.objects.get(id=tag_id)
                tag.name = name
                tag.save()
            elif tag_type == 'type':

                tag = Type.objects.get(id=tag_id)
                tag.name = name
                tag.save()
            elif tag_type == 'language':

                tag = Language.objects.get(id=tag_id)
                tag.name = name
                tag.save()

            ActionLog.objects.log_tags('Edited tag (category: %s, id: %s)' %
                                       (tag_type, tag_id),
                                       user=request.user,
                                       status=201)

            # Return response JSON
            return JsonResponse({
                'version': '1.0.0',
                'status': 200,
                'data': {
                    'type': tag_type,
                    'id': tag_id,
                    'name': name
                }
            })

        #Tag deletion request
        elif action == 'delete':

            if tag_type == 'theme': Theme.objects.get(id=tag_id).delete()
            elif tag_type == 'type': Type.objects.get(id=tag_id).delete()
            elif tag_type == 'language':
                Language.objects.get(id=tag_id).delete()
            else:
                # If not valid, return an error
                ActionLog.objects.log_tags(
                    'Failed to delete tag entry (id: %s)' % tag_id,
                    user=request.user,
                    status=401)
                return HttpResponseForbidden()

            # Return response JSON
            ActionLog.objects.log_tags('Deleted tag (id: %s)' % tag_id,
                                       user=request.user)
            return JsonResponse({'version': '1.0.0', 'status': 200})
Example #10
0
class EditMaterialView(View):
    @method_decorator(login_required)
    @method_decorator(role_required('content manager'))
    def get(self, request, content_id=0):

        material = Material.objects.active().get(id=content_id)

        form = MaterialForm(instance=material, initial={'user': request.user})
        fields = {
            'suggested_ages': SchoolGrade,
            'types': Type,
            'themes': Theme,
            'languages': Language
        }

        for field, queryset in fields.iteritems():
            form.fields[field].queryset = queryset.objects.active()

        return render_to_response('materials/edit.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(login_required)
    @method_decorator(role_required('content manager'))
    @method_decorator(csrf_protect)
    def post(self, request, content_id=0):

        material = Material.objects.active().get(id=content_id)
        form = MaterialForm(request.POST,
                            request.FILES,
                            instance=material,
                            initial={'user': request.user})

        #TODO: prepopulate form (checkboxes)
        if form.is_valid():

            material = form.instance
            form.save()
            ActionLog.objects.log_content('Edited material entry (id: %s)' %
                                          content_id,
                                          user=request.user,
                                          status=200)

            return redirect(
                reverse_lazy('content:view',
                             kwargs={'content_id': material.id}))

        ActionLog.objects.log_content(
            'Attempted to edit material entry (id: %s)' % content_id,
            user=request.user,
            status=401)
        return render_to_response('materials/edit.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(login_required)
    @method_decorator(role_required('content manager'))
    @method_decorator(csrf_protect)
    def delete(self, request, content_id=0):

        material = Material.objects.active().get(id=content_id)

        ActionLog.objects.log_content('Deleted material (id: %s)' %
                                      material.id,
                                      status=200,
                                      user=request.user)
        material.delete()

        return JsonResponse(data={
            'version': '1.0.0',
            'status': 200,
            'material': {
                'id': material.id,
                'status': 'delete'
            }
        },
                            content_type='application/json')
Example #11
0
class MaterialDetailView(View):
    @method_decorator(login_required)
    @method_decorator(role_required('parent'))
    def get(self, request, content_id=0):

        try:
            material = Material.objects.active().get(id=content_id)
        except Material.DoesNotExist:

            ActionLog.objects.log_content(
                'Attempted to load nonexistent material (id: %s)' % content_id,
                user=request.user,
                status=403)
            return HttpResponseForbidden()

        else:

            in_portfolio = Portfolio.objects.user(request.user).items.filter(
                material=material, active=True).exists()
            has_commented = Comment.objects.active().filter(
                user=request.user, material=material).exists()
            comments = Comment.objects.active().filter(material=material)
            types = material.types.active()
            languages = material.themes.active()
            themes = material.languages.active()
            ages = material.suggested_ages.active()
            ActionLog.objects.log_content('Viewed material (id: %s)' %
                                          content_id,
                                          user=request.user)
            return render_to_response('materials/detail.html',
                                      context=RequestContext(
                                          request, locals()))

    @method_decorator(login_required)
    @method_decorator(ajax_required)
    @method_decorator(role_required('teacher'))
    def post(self, request, content_id=0):
        """ This method is called when the user posts a comment on a material detail view.
			It validates that the user has already rated such material and that the comment's length is lower than 500 chars
		"""

        try:
            material = Material.objects.active().get(id=content_id)
        except Material.DoesNotExist:

            ActionLog.objects.log_content(
                'Attempted to recover nonexistent material (id: %s)' %
                content_id,
                user=request.user,
                status=403)
            return HttpResponseForbidden()
        else:

            if Comment.objects.active().filter(user=request.user,
                                               material=material).exists():

                ActionLog.objects.log_content(
                    'User has already issued comment for this material (id: %s)'
                    % content_id,
                    user=request.user,
                    status=403)
                return HttpResponseForbidden()

            content, rating = request.POST.get('content',
                                               None), request.POST.get(
                                                   'rating_value', None)
            if content is None or rating is None:

                ActionLog.objects.log_content(
                    'Comment data was missing or is invalid',
                    user=request.user,
                    status=403)
                return HttpResponseForbidden()

            comment = Comment.objects.create(user=request.user,
                                             material=material,
                                             content=content,
                                             rating_value=rating)

            ActionLog.objects.log_content(
                'Added comment for material (id: %s)' % content_id,
                user=request.user,
                status=201)
            return JsonResponse(
                {
                    'version': '1.0.0',
                    'status': 201,
                    'data': {
                        'content': comment.content,
                        'user': request.user.id,
                        'material': material.id,
                        'rating': int(comment.rating_value)
                    }
                },
                status=201)
Example #12
0
class ReportsView(View):
    """
		Inputs: request.GET['query'] (optional): The filter criteria to use in order to select tags. Defaults to None.
		Outputs:
​
			A JSON document complying with the following schema:
​
			{
				"$schema": "http://json-schema.org/draft-04/schema#",
​
				"id": "http://jsonschema.net/tag-list",
				"type": "object",
				"properties": {
​
					"data": {
						"id": "http://jsonschema.net/tag-list/data",
						"type": "array",
						"items": [
							{
								"description": "string"
								"material": "object"
								"user": "******"
							}
						]
					}
​
				},
				"required": [ "type", "data" ]
			}
​
			Possible values include:
​
			{ "data": [ { "description": "test", "material": "test_material", "user": "******" } ] }
			{ "data": [] }
		"""
    @method_decorator(login_required)
    @method_decorator(role_required('content manager'))
    def get(self, request):
        """
			Receives a get request and returns a JSON with all active reports currently in progress

		"""

        # Query reports in progress
        reports = Report.objects.active().filter(status=1)

        # Write action log
        ActionLog.objects.log_reports('Listed reports', user=request.user)

        # Send response
        return render_to_response('reports/view.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(login_required)
    @method_decorator(ajax_required)
    @method_decorator(csrf_protect)
    @method_decorator(role_required('teacher'))
    def post(self, request, content_id=0):
        """
			Receives a post request and material id, creates new report for that material and returns a JSON response

		"""

        # Attempt to load the material
        try:
            material = Material.objects.active().get(id=content_id)
        except Material.DoesNotExist:

            # If material doesn't exist, write in action log and returned forbidden response
            ActionLog.objects.log_reports(
                'Failed to locate material with ID \'%s\'' % content_id,
                status=403,
                user=request.user)
            return HttpResponseForbidden()
        else:

            # Get description parameter
            self.description = request.POST['description']

            # Create new report for specified material with the received description. Defaults to "in progress" status
            new_report = Report.objects.create(user=request.user,
                                               material=material,
                                               description=self.description,
                                               status=1)

            # Write action log
            ActionLog.objects.log_reports('Created report (id: %s)' %
                                          new_report.id,
                                          user=request.user,
                                          status=201)

            # Return response JSON
            return JsonResponse(
                {
                    'version': '1.0.0',
                    'status': 201,
                    'data': {
                        'description': new_report.description,
                        'material': new_report.material.id,
                        'user': new_report.user.id
                    }
                },
                status=201)

    @method_decorator(login_required)
    @method_decorator(ajax_required)
    @method_decorator(csrf_protect)
    @method_decorator(role_required('content manager'))
    def patch(self, request, report_id=0):
        """
			Receives a patch request and report id. Modifies specified report to "resolved" status and returns JSON

		"""

        # Query database for specified report
        report = Report.objects.get(id=report_id)
        # Change status
        report.status = 2
        report.save()

        # Write action log
        ActionLog.objects.log_reports('Updated report ( id: %s) to resolved' %
                                      report_id,
                                      user=request.user,
                                      status=201)

        # Return response JSON
        return JsonResponse({
            'version': '1.0.0',
            'status': 200,
            'data': {
                'description': report.description,
                'material': report.material.id,
                'user': report.user.id
            }
        })

    @method_decorator(login_required)
    @method_decorator(ajax_required)
    @method_decorator(csrf_protect)
    @method_decorator(role_required('content manager'))
    def delete(self, request, report_id=0):
        """
			Receives a delete request and report id. Modifies specified report to "rejected" status and returns JSON

		"""

        # Query database for specified report
        report = Report.objects.get(id=report_id)
        # Change status
        report.status = 4
        report.save()

        # Write action log
        ActionLog.objects.log_reports('Rejected report ( id: %s)' % report_id,
                                      user=request.user,
                                      status=201)

        # Return response JSON
        return JsonResponse({
            'version': '1.0.0',
            'status': 200,
            'data': {
                'description': report.description,
                'material': report.material.id,
                'user': report.user.id
            }
        })
Example #13
0
class EditUserView(View):
    """
		Class responsible to handle user requests to edit user profiles:
			Receives the logged user request containing the target user profile id to edit.
				It evaluates if the user according to its role should be allowed or denied the edit to the target user profile
			Returns the target user profile edit form on success, 40X otherwise.
	"""
    @method_decorator(login_required)
    @method_decorator(role_required('teacher'))
    def get(self, request, user_id=0):

        try:
            u = User.objects.active().get(id=user_id)
        except User.DoesNotExist:

            ActionLog.objects.log_account(
                'Invalid user profile information request : (user_id: %s)' %
                user_id,
                user=request.user,
                status=401)
            return HttpResponseForbidden()
        else:

            if request.user.belongs_to('user manager'):
                form = AdminEditForm(instance=u)
            else:

                if request.user.id == int(user_id):
                    form = BasicEditForm(instance=u)
                else:

                    ActionLog.objects.log_account(
                        'Attempted to view user profile information without enough privileges : (user_id: %s)'
                        % user_id,
                        user=request.user,
                        status=401)
                    return HttpResponseForbidden()

        return render_to_response('users/edit.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(csrf_protect)
    @method_decorator(login_required)
    @method_decorator(role_required('teacher'))
    def post(self, request, user_id=0):

        try:
            u = User.objects.active().get(id=user_id)
        except User.DoesNotExist:

            ActionLog.objects.log_account(
                'User requested to edit does not exist: (user_id: %s)' %
                user_id,
                user=request.user,
                status=401)
            return HttpResponseForbidden()
        else:

            if request.user.belongs_to('user manager'):
                form = AdminEditForm(request.POST, request.FILES, instance=u)
            else:
                if request.user.id == int(user_id):
                    form = BasicEditForm(request.POST,
                                         request.FILES,
                                         instance=u)
                else:

                    ActionLog.objects.log_account(
                        'Attempted to edit user profile information without enough privileges : (user_id: %s)'
                        % user_id,
                        user=request.user,
                        status=401)
                    return HttpResponseForbidden()

        # Validate the form and, if valid, save the user
        if form.is_valid():

            user = form.instance

            ActionLog.objects.log_account(
                'Edited user profile information (email address: %s)' %
                user.email_address,
                user=request.user)
            form.save(commit=True)

            password = form.cleaned_data['password']

            if password is not None:
                if password is not '' or is_password_usable(
                        password) and not user.check_password(password):
                    user.set_password(password)
                    user.save()

            return redirect(
                reverse_lazy('users:view', kwargs={'user_id': user.id}))

        # Log the error and resend the form
        ActionLog.objects.log_account(
            'Attempted to edit user profile information with invalid detail(s) (email address: %s)'
            % u.email_address,
            user=request.user,
            status=401)
        return render_to_response('users/edit.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(ajax_required)
    @method_decorator(login_required)
    @method_decorator(csrf_protect)
    @method_decorator(role_required('user manager'))
    def delete(self, request, user_id=0):

        #Fetch the user to delete
        try:
            u = User.objects.active().get(id=user_id)

            #It either does not exist or it is inactive
        except User.DoesNotExist:

            ActionLog.objects.log_account('Attempted to delete user account',
                                          user=request.user,
                                          status=401)
            return HttpResponseForbidden()

        else:
            u.delete()
            ActionLog.objects.log_account(
                'Deleted user account (email address: %s)' % u.email_address,
                user=request.user)

            return JsonResponse({'version': '1.0.0', 'status': 200})
Example #14
0
class SelectReportView(View):
    @method_decorator(login_required)
    @method_decorator(role_required('administrator'))
    def get(self, request):
        return render_to_response('reporting/select-report.html',
                                  context=RequestContext(request, locals()))
Example #15
0
class PortfolioView(View):
    """ This view handles the portfolio (favorite items). The provided views, except for the GET route which
		displays the portfolio for the current user, are all AJAX-based and called directly through the interface.
		The interface provided by the GET route is updated by the execution of the other methods. This view allows
		the user to: add an existing material to his/her portfolio (if it has not already been added) and remove
		a material from his/her portfolio (if it exists in the portfolio currently).
	"""
    @method_decorator(login_required)
    @method_decorator(role_required('teacher'))
    def get(self, request):

        portfolio = Portfolio.objects.user(request.user)

        paginator = Paginator(portfolio.items.filter(active=True),
                              request.GET.get('page_size', 15))
        page = request.GET.get('page', 1)

        try:
            items = paginator.page(page)
        except EmptyPage:
            items = paginator.page(paginator.num_pages)
        except PageNotAnInteger:
            items = paginator.page(1)

        return render_to_response('materials/portfolio.html',
                                  context=RequestContext(request, locals()))

    @method_decorator(ajax_required)
    @method_decorator(login_required)
    @method_decorator(csrf_protect)
    @method_decorator(role_required('teacher'))
    def put(self, request, content_id=0):

        # Attempt to load the material
        try:
            material = Material.objects.active().get(id=content_id)
        except Material.DoesNotExist:

            ActionLog.objects.log_content(
                'Failed to locate material with ID \'%s\'' % content_id,
                status=403,
                user=request.user)
            return HttpResponseForbidden()
        else:

            # Check the material is not already added
            portfolio = Portfolio.objects.user(request.user)
            if portfolio.items.filter(material=material, active=True).exists():

                ActionLog.objects.log_content(
                    'Cannot add already added material',
                    status=403,
                    user=request.user)
                return HttpResponseForbidden()

            # Add the item to the portfolio
            portfolio.items.create(material=material, portfolio=portfolio)
            ActionLog.objects.log_content(
                'Added material ID \'%s\' to user portfolio' % content_id,
                status=201,
                user=request.user)

            # Serialize the material
            return JsonResponse(
                {
                    'version': '1.0.0',
                    'status': 201,
                    'material': {
                        'id':
                        material.id,
                        'title':
                        material.title,
                        'description':
                        material.description,
                        'content':
                        material.content.url
                        if bool(material.content) is True else None,
                        'link':
                        material.link
                    }
                },
                status=201)

    @method_decorator(ajax_required)
    @method_decorator(login_required)
    @method_decorator(csrf_protect)
    @method_decorator(role_required('teacher'))
    def delete(self, request, content_id=0):

        # Attempt to load the material
        try:
            material = Material.objects.active().get(id=content_id)
        except Material.DoesNotExist:

            ActionLog.objects.log_content(
                'Failed to locate material with ID \'%s\'' % content_id,
                status=403,
                user=request.user)
            return HttpResponseForbidden()
        else:

            # Check the material is not already added
            portfolio = Portfolio.objects.user(request.user)
            if not portfolio.items.filter(active=True).filter(
                    material=material).exists():

                ActionLog.objects.log_content(
                    'Cannot remove non-included material',
                    status=403,
                    user=request.user)
                return HttpResponseForbidden()

            # Add the item to the portfolio
            portfolio.items.filter(active=True).get(material=material).delete()
            ActionLog.objects.log_content(
                'Removed material ID \'%s\' to user portfolio' % content_id,
                user=request.user)

            # Serialize the material
            return JsonResponse({
                'version': '1.0.0',
                'status': 200,
                'material': {
                    'id': material.id,
                    'title': material.title
                }
            })