Esempio n. 1
0
    def form_valid(self, form):
        """Create a :class:`apps.messaging.models.Message`
        and :class:`apps.messaging.models.CollectionRequest`
        objects directed to the owner of the collection.
        """
        collection = get_object_or_404(Collection,
                                       pk=form.cleaned_data['object_pk'])
        project = form.cleaned_data['project']
        msg = Message.objects.create(
            subject="Request for collections",
            text=form.cleaned_data['text'],
            user_from=self.request.user,
            user_to=collection.owner,
            date_sent=datetime_aware(),
            message_type=MessageType.COLLECTION_REQUEST)
        coll_req = CollectionRequest(name="Request for collections",
                                     user=collection.owner,
                                     user_from=self.request.user,
                                     message=msg,
                                     project=project)
        coll_req.save()
        coll_req.collections.add(collection)

        # send email to the owner of the collection
        if collection.owner.userprofile.system_notifications:
            send_mail(subject='Request for one of your collections',
                      message=form.cleaned_data['text'],
                      from_email=None,
                      recipient_list=[collection.owner.email],
                      fail_silently=True)

        messages.add_message(self.request, messages.SUCCESS, (
            'Your request for the collection <strong>{name}</strong> has been '
            'successfully submitted.').format(name=collection.name))
        return super(CollectionRequestView, self).form_valid(form)
Esempio n. 2
0
 def _get_random_datetime(cls):
     return datetime_aware(data=datetime.datetime(
         random.randint(2009, 2014),
         random.randint(1, 12),
         random.randint(1, 28),
         random.randint(0, 23),
         random.randint(0, 59),
         random.randint(0, 59)
     ))
Esempio n. 3
0
 def load_research_projects(self):
     """Load example research projects"""
     LOGGER.info(u" > research projects...")
     users = self.users.keys()
     research_project, _created = ResearchProject.objects.get_or_create(
         name="ResearchProject1",
         owner=self.users['alice'],
         status_date=datetime_aware(),
         status=ResearchProjectStatus.APPROVED,
     )
     self.research_project = research_project
Esempio n. 4
0
    def save(self, **kwargs):
        """
        If project has been accepted, then accept date is set,
        also when project is created, two notifications are sent:

        * to user, that project has been created
        * to admins, that project has been created and waiting for
          approve or decline
        """

        if (self.status is not None and self.status_date is None):
            self.status_date = datetime_aware()
        super(ResearchProject, self).save(**kwargs)
Esempio n. 5
0
 def api_ask_access_context(self, item, user):
     """Method used to determine if other users can ask for permissions
     Requests for permissions are allowed only for On demand collections and
     asking is allowed once per 24h
     """
     is_public = item.is_public
     context = {'is_public': is_public}
     if not is_public:
         if item.can_view(user=user):
             context['already_approved'] = True
         else:
             if user.is_authenticated():
                 already_approved = user.my_collection_requests.filter(
                     collections__pk=item.pk,
                     resolved_at__isnull=False,
                     is_approved=True).exists()
                 if already_approved:
                     context['already_approved'] = already_approved
                 else:
                     url = reverse('storage:collection_request',
                                   args=(item.pk, ))
                     try:
                         collection_request = \
                             user.my_collection_requests.filter(
                                 collections__pk=item.pk,
                                 resolved_at__isnull=True
                             ).latest('added_at')
                     except CollectionRequest.DoesNotExist:
                         request_status = None
                         context['url'] = url
                     else:
                         # If request is older than time defined in
                         # settings, then it doesn't matter
                         diff = (datetime_aware() -
                                 collection_request.added_at)
                         if diff.seconds > settings.REQUEST_FLOOD_DELAY:
                             context['url'] = url
                             request_status = None
                         else:
                             request_status = collection_request.added_at
                     context['delay'] = settings.REQUEST_FLOOD_DELAY / 3600
                     context['status'] = request_status
     return context
Esempio n. 6
0
    def post(self, request, *args, **kwargs):
        """
        """

        error_redirect = redirect(
            request.META.get('HTTP_REFERER')
            or reverse('media_classification:project_index'))
        user = request.user

        try:
            user_classification = UserClassification.objects.get(
                pk=kwargs['pk'])
        except UserClassification.DoesNotExist:
            messages.error(request=request,
                           message=ClassifyMessages.MSG_CLASSIFICATION_MISSING)
            return error_redirect

        classification = user_classification.classification

        if not classification.can_approve(user=user):
            messages.error(request=request,
                           message=ClassifyMessages.MSG_APPROVE_PERMS)
            return error_redirect

        classification.status = True
        classification.approved_by = user
        classification.approved_at = datetime_aware()
        classification.approved_source = user_classification
        classification.static_attrs = user_classification.static_attrs
        classification.save()

        classification.dynamic_attrs.all().delete()
        for dynamic_attr in user_classification.dynamic_attrs.all():
            user_attrs = dynamic_attr.attrs
            ClassificationDynamicAttrs.objects.create(
                classification=classification, attrs=user_attrs)
        messages.success(request=request,
                         message=ClassifyMessages.MSG_SUCCESS_APPROVED)
        return redirect(
            reverse('media_classification:classify',
                    kwargs={
                        'pk': classification.pk,
                    }))
Esempio n. 7
0
    def send_create_message(self):
        """Notify all django admins about new project using
        :class:`apps.messaging.models.Message` (application messaging)
        """
        User = get_user_model()
        recipients = User.objects.filter(is_active=True, is_superuser=True)

        body_template = (
            'New research project has been created. You can approve or reject it '
            'by changing its status at:\n'
            '{url}').format(url=reverse(
                'admin:research_researchproject_change', args=(self.pk, )))

        for recipient in recipients:
            Message.objects.create(
                subject=(u"New research project: <strong>{name}</strong> "
                         u"created").format(name=self.name),
                text=body_template,
                user_from=self.owner,
                user_to=recipient,
                date_sent=datetime_aware(),
                message_type=MessageType.RESEARCH_PROJECT_CREATED)
Esempio n. 8
0
    def post(self, request, *args, **kwargs):
        """When a user has enough permissions and filled all neccessery
        fields in classification forms then this method is used to save all 
        provided data to a database object
        :class:apps.media_classification.models.UserClassification`.

        If a currently logged in user is a Project Admin and decide that
        this classification should be approved, then after user classification
        is saved, :class:apps.media_classification.models.Classification`
        object is updated with current classification data and classification
        is marked as approved.
        """

        user = self.get_user()
        now = datetime_aware()

        collection = self.classification.collection
        project = self.classification.project
        base_resource = self.classification.resource

        # If there is no classificator, there is no reason to go further
        classificator = project.classificator
        if not classificator:
            messages.error(request=request,
                           message=ClassifyMessages.MSG_CLASSIFICATOR_MISSING)
            return self.get(request, *args, **kwargs)

        is_project_admin = project.is_project_admin(request.user)

        # Update classification other user is avaiilable for project admin
        if user != request.user and not is_project_admin:
            messages.error(request=request,
                           message=ClassifyMessages.MSG_PERMS_REQUIRED)
            return self.get(request, *args, **kwargs)

        # If user is not project admin and tries to approve it... Don't let it
        if not is_project_admin and 'approve_classification' in request.POST:
            messages.error(request=request,
                           message=ClassifyMessages.MSG_PERMS_REQUIRED)
            return self.get(request, *args, **kwargs)

        # seems like all base stuff is ok, we can prepare some stuff
        resources = {base_resource}

        if ('classify_multiple' in request.POST
                or 'approve_multiple' in request.POST):
            multiple_classify_form = ClassifyMultipleForm(request.POST,
                                                          initial={
                                                              'collection':
                                                              collection,
                                                          })
            if multiple_classify_form.is_valid():
                cleaned_data = multiple_classify_form.cleaned_data
                resources.update(cleaned_data['selected_resources'])
            else:
                messages.error(
                    request=request,
                    message=ClassifyMessages.MSG_CLASSIFY_MULTIPLE_FAILED)
                return self.get(request, *args, **kwargs)

        # finally we got there... we can work with resource(s)!
        fields_defs = classificator.prepare_form_fields()

        errors = False
        for resource in resources:
            classification, created = Classification.objects.get_or_create(
                resource=resource,
                collection=collection,
                project=project,
                defaults={
                    'created_at': now,
                    'owner': user,
                    'status': ClassificationStatus.REJECTED,
                    'updated_at': now,
                    'updated_by': user
                })

            if not created:
                classification.updated_at = now
                classification.updated_by = user
                classification.save()

            user_classification, created = \
                UserClassification.objects.get_or_create(
                    classification=classification,
                    owner=user,
                    defaults={
                        'created_at': now,
                        'updated_at': now,
                        }
                )

            if not created:
                user_classification.updated_at = now

            dynamic_form = self.get_dynamic_form(
                classificator=classificator,
                fields_defs=fields_defs,
                user_classification=user_classification,
            )
            static_form = self.get_static_form(
                classificator=classificator,
                fields_defs=fields_defs,
                user_classification=user_classification,
            )

            if (static_form and not static_form.is_valid()
                    or dynamic_form and not dynamic_form.is_valid()):
                messages.error(request=request,
                               message=ClassifyMessages.MSG_CLASSIFY_ERRORS)
                return self.get(request, *args, **kwargs)

            # process data POST'ed by static form
            if static_form:
                user_classification.static_attrs = static_form.cleaned_data

            # Now we should have all required data, so we can save
            user_classification.save()

            if dynamic_form:
                # bulk-delete of old rows
                user_classification.dynamic_attrs.all().delete()

                # populate new ones
                for form in dynamic_form.forms:
                    attrs = UserClassificationDynamicAttrs.objects.create(
                        userclassification=user_classification,
                        attrs=form.cleaned_data)
            # If processed resource is currently classified one, then
            # check if it shouldn't be approved
            if ((resource == base_resource
                 and 'approve_classification' in request.POST)
                    or ('approve_multiple' in request.POST)):
                if classification.project.is_project_admin(user=user):
                    classification.status = True
                    classification.approved_by = user
                    classification.approved_at = datetime_aware()
                    classification.approved_source = user_classification

                    if static_form:
                        classification.static_attrs = static_form.cleaned_data
                    classification.save()

                    classification.dynamic_attrs.all().delete()
                    for attr in user_classification.dynamic_attrs.all():
                        user_attrs = attr.attrs
                        ClassificationDynamicAttrs.objects.create(
                            classification=classification, attrs=user_attrs)
                else:
                    messages.error(request=request,
                                   message=ClassifyMessages.MSG_APPROVE_PERMS)
                    return self.get(request, *args, **kwargs)

        messages.success(request=request, message=ClassifyMessages.MSG_SUCCESS)
        return redirect(
            reverse('media_classification:classify_user',
                    kwargs={
                        'pk': classification.pk,
                        'user_pk': user.pk
                    }))
Esempio n. 9
0
    def post(self, request, *args, **kwargs):
        """
        `request.POST` method is used to create sequences for given
        list of resources using AJAX.

        List of project pks is passed in `pks` key as list of integers
        separated by comma.

        Sequence can be created for multiple resources that belong to the
        same classification project collection within classification project.

        Response contains status of creation/update and serialized sequence
        object.
        """
        msg = 'Invalid request'
        status = False
        record = None
        collection = None
        sequence_original = None

        collection_pk = request.POST.get('collection_pk') or None
        resources = request.POST.get('resources') or None

        sequence_pk = request.POST.get('pk') or None

        if collection_pk and resources:
            collection = self.get_collection(collection_pk=collection_pk)
            if collection:
                resources = self.get_resources(collection=collection,
                                               resource_pks=resources)
        if collection:
            project = collection.project
            if project.can_change_sequence(user=request.user):
                if resources:
                    description = request.POST.get('description', None)

                    try:
                        sequence = Sequence.objects.get(pk=sequence_pk)
                        sequence_original = sequence

                    except Sequence.DoesNotExist:
                        sequence = Sequence(
                            collection=collection,
                            created_by=request.user,
                            created_at=datetime_aware(),
                            description=description,
                        )
                    else:
                        sequence.description = description
                    sequence.save()

                    try:
                        seq_resources = []
                        for resource in resources:
                            obj = SequenceResourceM2M(sequence=sequence,
                                                      resource=resource)
                            obj.full_clean()
                            seq_resources.append(obj)
                    except ValidationError, e:
                        if sequence_original:
                            sequence = sequence_original
                            sequence.save()
                        else:
                            sequence.delete()
                        msg = e.messages[0]
                    else:
                        sequence.resources.clear()
                        for obj in seq_resources:
                            obj.save()
                        record = SequenceReadSerializer(instance=sequence,
                                                        context={
                                                            'request':
                                                            self.request
                                                        }).data
                        status = True
                        # update classification objects with
                        # sequence data
                        sequence.classifications.clear()
                        classifications = Classification.objects.filter(
                            collection=collection, resource__in=resources)
                        classifications.update(sequence=sequence)
            else:
                msg = 'You have not enough permissions to change sequence'