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)
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) ))
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
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)
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
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, }))
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)
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 }))
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'