Пример #1
0
def add(request):
    """View for adding new samples.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    user = request.user
    if request.method == "POST":
        add_samples_form = AddSamplesForm(user, request.POST)
        if add_samples_form.is_valid():
            # FixMe: Find more reliable way to find stared sample names
            max_cycles = 10
            while max_cycles > 0:
                max_cycles -= 1
                try:
                    savepoint_without_samples = transaction.savepoint()
                    new_names, samples = add_samples_to_database(add_samples_form, user)
                except IntegrityError:
                    if max_cycles > 0:
                        transaction.savepoint_rollback(savepoint_without_samples)
                    else:
                        raise
                else:
                    break
            ids = [sample.pk for sample in samples]
            utils.Reporter(user).report_new_samples(samples)
            if add_samples_form.cleaned_data["topic"]:
                for watcher in (user_details.user
                                for user_details in add_samples_form.cleaned_data["topic"].auto_adders.all()):
                    for sample in samples:
                        watcher.my_samples.add(sample)
            if len(new_names) > 1:
                success_report = \
                    _("Your samples have the names from {first_name} to {last_name}.  "
                      "They were added to “My Samples”.").format(first_name=new_names[0], last_name=new_names[-1])
            else:
                success_report = _("Your sample has the name {name}.  It was added to “My Samples”."). \
                    format(name=new_names[0])
            if add_samples_form.cleaned_data["rename"] == "new-style":
                return utils.successful_response(request, success_report, "samples.views.bulk_rename.bulk_rename",
                                                 query_string="ids=" + ",".join(str(id_) for id_ in ids),
                                                 forced=True, json_response=ids)
            else:
                return utils.successful_response(request, success_report, json_response=ids)
    else:
        add_samples_form = AddSamplesForm(user)
    return render(request, "samples/add_samples.html", {"title": _("Add samples"),
                                                        "add_samples": add_samples_form,
                                                        "external_operators_available": user.external_contacts.exists()})
Пример #2
0
def delete_process(request, process_id):
    """Deletes an existing physical process.

    :param request: the current HTTP Request object
    :param process_id: the process's ID

    :type request: HttpRequest
    :type process_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    process = get_object_or_404(Process,
                                pk=int_or_zero(process_id)).actual_instance
    affected_objects = permissions.assert_can_delete_physical_process(
        request.user, process)
    for instance in affected_objects:
        if isinstance(instance, models.Sample):
            utils.Reporter(request.user).report_deleted_sample(instance)
        elif isinstance(instance, models.Process):
            utils.Reporter(request.user).report_deleted_process(instance)
    success_message = _(
        "Process {process} was successfully deleted in the database.").format(
            process=process)
    process.delete()
    return utils.successful_response(request, success_message)
Пример #3
0
def add(request):
    """With this function, the messages are stored into the database.  It also gets
    the information for displaying the "add_status_message" template.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    if request.method == "POST":
        status_form = StatusForm(request.user, request.POST)
        if status_form.is_valid():
            status = status_form.save()
            for process_class in status.process_classes.all():
                utils.Reporter(request.user).report_status_message(
                    process_class, status)
            return utils.successful_response(
                request,
                _("The status message was successfully added to the database.")
            )
    else:
        status_form = StatusForm(request.user)
    title = _("Add status message")
    return render(request, "samples/add_status_message.html", {
        "title": title,
        "status": status_form
    })
Пример #4
0
def new(request):
    """View for adding a new external operator.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    permissions.assert_can_add_external_operator(request.user)
    if request.method == "POST":
        external_operator_form = AddExternalOperatorForm(request.user, request.POST)
        initials_form = utils.InitialsForm(person=None, initials_mandatory=True, data=request.POST)
        if external_operator_form.is_valid() and initials_form.is_valid():
            external_operator = external_operator_form.save()
            initials_form.save(external_operator)
            return utils.successful_response(
                request,
                _("The external operator “{operator}” was successfully added.".format(operator=external_operator.name)))
    else:
        external_operator_form = AddExternalOperatorForm(request.user)
        initials_form = utils.InitialsForm(person=None, initials_mandatory=True)
    return render(request, "samples/edit_external_operator.html", {"title": capfirst(_("add external operator")),
                                                                   "external_operator": external_operator_form,
                                                                   "initials": initials_form})
Пример #5
0
def show(request):
    """Shows the task lists the user wants to see.
    It also provides the multiple choice list to select the task lists
    for the user.

    :Paramerters:
    :param request: the current HTTP Request object

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    if request.method == "POST":
        choose_task_lists_form = ChooseTaskListsForm(request.user,
                                                     request.POST)
        if choose_task_lists_form.is_valid():
            request.user.samples_user_details.visible_task_lists = \
                [ContentType.objects.get_for_id(int(id_))
                 for id_ in choose_task_lists_form.cleaned_data["visible_task_lists"] if id_]
            # In order to have a GET instead of a POST as the last request
            return utils.successful_response(request,
                                             view="samples:show_task_lists")
    else:
        choose_task_lists_form = ChooseTaskListsForm(request.user)
    task_lists = create_task_lists(request.user)
    return render(
        request, "samples/task_lists.html", {
            "title": capfirst(_("task lists")),
            "choose_task_lists": choose_task_lists_form,
            "task_lists": task_lists
        })
Пример #6
0
def edit(request, login_name):
    """View for editing the “My Layers”.

    :param request: the current HTTP Request object
    :param login_name: the login name of the user whose “My Layers” should be
        changed

    :type request: HttpRequest
    :type login_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    user = get_object_or_404(django.contrib.auth.models.User, username=login_name)
    if not request.user.is_superuser and request.user != user:
        raise permissions.PermissionError(request.user, _("You can't access the “My Layers” section of another user."))
    if request.method == "POST":
        my_layer_forms, structure_changed = forms_from_post_data(request.POST)
        all_valid = all([my_layer_form.is_valid() for my_layer_form in my_layer_forms])
        referentially_valid = is_referentially_valid(my_layer_forms)
        if all_valid and referentially_valid and not structure_changed:
            result = save_to_database(my_layer_forms, user)
            return utils.successful_response(request, result)
        elif all_valid and referentially_valid and structure_changed:
            messages.error(request, _("Changes are not saved yet."))
    else:
        my_layer_forms = forms_from_database(user)
    my_layer_forms.append(MyLayerForm(prefix=str(len(my_layer_forms))))
    return render(request, "samples/edit_my_layers.html", {"title": _("My Layers"), "my_layers": my_layer_forms})
Пример #7
0
def merge(request):
    """The merging of the samples is handled in this function.
    It creates the necessary forms, initiates the merging
    and returns the HttpResponse to the web browser.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    def build_merge_forms(data=None):
        merge_samples_forms = [MergeSamplesForm(request.user, data, prefix=str(0))]
        choices = merge_samples_forms[0].fields["from_sample"].choices
        merge_samples_forms += [MergeSamplesForm(request.user, data, prefix=str(index), choices=choices)
                                for index in range(1, number_of_pairs)]
        return merge_samples_forms
    if request.method == "POST":
        merge_samples_forms = build_merge_forms(request.POST)
        all_valid = all([merge_samples_form.is_valid() for merge_samples_form in merge_samples_forms])
        referentially_valid = is_referentially_valid(merge_samples_forms)
        if all_valid and referentially_valid:
            for merge_samples_form in merge_samples_forms:
                from_sample = merge_samples_form.cleaned_data.get("from_sample")
                to_sample = merge_samples_form.cleaned_data.get("to_sample")
                if from_sample and to_sample:
                    merge_samples(from_sample, to_sample)
            return utils.successful_response(request, _("Samples were successfully merged."))
    else:
        merge_samples_forms = build_merge_forms()
    return render(request, "samples/merge_samples.html", {"title": capfirst(_("merge samples")),
                                                          "merge_forms": merge_samples_forms})
Пример #8
0
def new(request, sample_name):
    """View for killing samples.  Note that it is not possible to re-kill an
    already dead sample.  Furthermore, you must be the currently responsible
    person to be able to kill a sample.

    :param request: the current HTTP Request object
    :param sample_name: name of the sample to be killed

    :type request: HttpRequest
    :type sample_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample = utils.lookup_sample(sample_name, request.user)
    permissions.assert_can_edit_sample(request.user, sample)
    if sample.is_dead():
        raise Http404("Sample is already dead.")
    if request.method == "POST":
        sample_death_form = SampleDeathForm(sample, request.POST)
        if sample_death_form.is_valid():
            sample_death = sample_death_form.save(commit=False)
            sample_death.timestamp = datetime.datetime.now()
            sample_death.operator = request.user
            sample_death.save()
            sample_death.samples = [sample]
            # FixMe: Feed entries
            return utils.successful_response(request, _("Sample “{sample}” was killed.").format(sample=sample),
                                             "show_sample_by_name", {"sample_name": sample_name})
    else:
        sample_death_form = SampleDeathForm(sample)
    return render(request, "samples/edit_sample_death.html", {"title": _("Kill sample “{sample}”").format(sample=sample),
                                                              "sample_death": sample_death_form})
Пример #9
0
def withdraw(request, id_):
    """This function withdraws a status message for good.  Note that it
    withdraws it for all its connected process types.  It is idempotent.

    :param request: the current HTTP Request object
    :param id_: the id of the message to be withdrawn

    :type request: HttpRequest
    :type id_: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    status_message = get_object_or_404(models.StatusMessage,
                                       withdrawn=False,
                                       pk=utils.convert_id_to_int(id_))
    if request.user != status_message.operator:
        raise PermissionError(
            request.user,
            "You cannot withdraw status messages of another user.")
    status_message.withdrawn = True
    status_message.save()
    for process_class in status_message.process_classes.all():
        utils.Reporter(request.user).report_withdrawn_status_message(
            process_class, status_message)
    return utils.successful_response(
        request, _("The status message was successfully withdrawn."), show)
Пример #10
0
def show(request):
    """Shows the task lists the user wants to see.
    It also provides the multiple choice list to select the task lists
    for the user.

    :Paramerters:
    :param request: the current HTTP Request object

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    if request.method == "POST":
        choose_task_lists_form = ChooseTaskListsForm(request.user, request.POST)
        if choose_task_lists_form.is_valid():
            request.user.samples_user_details.visible_task_lists = \
                [ContentType.objects.get_for_id(int(id_))
                 for id_ in choose_task_lists_form.cleaned_data["visible_task_lists"] if id_]
            # In order to have a GET instead of a POST as the last request
            return utils.successful_response(request, view=show)
    else:
        choose_task_lists_form = ChooseTaskListsForm(request.user)
    task_lists = create_task_lists(request.user)
    return render(request, "samples/task_lists.html", {"title": capfirst(_("task lists")),
                                                       "choose_task_lists": choose_task_lists_form,
                                                       "task_lists": task_lists})
Пример #11
0
def new(request):
    """View for creating a new sample series.  Note that you can add arbitrary
    samples to a sample series, even those you can't see.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    if request.method == "POST":
        sample_series_form = SampleSeriesForm(request.user, request.POST)
        if sample_series_form.is_valid():
            timestamp = datetime.datetime.today()
            full_name = "{0}-{1}-{2}".format(
                request.user.username, timestamp.strftime("%y"),
                sample_series_form.cleaned_data["short_name"])
            if models.SampleSeries.objects.filter(name=full_name).exists():
                sample_series_form.add_error(
                    "short_name",
                    _("This sample series name is already given."))
            elif len(full_name) > models.SampleSeries._meta.get_field(
                    "name").max_length:
                overfull_letters = len(
                    full_name) - models.SampleSeries._meta.get_field(
                        "name").max_length
                error_message = ungettext(
                    "The name is {number} letter too long.",
                    "The name is {number} letters too long.",
                    overfull_letters).format(number=overfull_letters)
                sample_series_form.add_error("short_name", error_message)
            else:
                sample_series = sample_series_form.save(commit=False)
                sample_series.name = full_name
                sample_series.timestamp = timestamp
                sample_series.save()
                sample_series_form.save_m2m()
                utils.Reporter(
                    request.user).report_new_sample_series(sample_series)
                return utils.successful_response(
                    request,
                    _("Sample series {name} was successfully added to the database."
                      ).format(name=full_name))
    else:
        sample_series_form = SampleSeriesForm(request.user)
    return render(
        request, "samples/edit_sample_series.html", {
            "title":
            _("Create new sample series"),
            "sample_series":
            sample_series_form,
            "is_new":
            True,
            "name_prefix":
            "{0}-{1}".format(request.user.username,
                             datetime.datetime.today().strftime("%y"))
        })
Пример #12
0
def edit(request, process_id):
    """View for editing existing results, and for creating new ones.

    :param request: the current HTTP Request object
    :param process_id: the ID of the result process; ``None`` if we're creating
        a new one

    :type request: HttpRequest
    :type process_id: str

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    form_set = FormSet(request, process_id)
    if form_set.result:
        permissions.assert_can_edit_result_process(request.user, form_set.result)
    if request.method == "POST":
        form_set.from_post_data(request.POST, request.FILES)
        result = form_set.save_to_database(request.FILES)
        if result:
            utils.Reporter(request.user).report_result_process(
                result, form_set.edit_description_form.cleaned_data if form_set.edit_description_form else None)
            return utils.successful_response(request, json_response=result.pk)
    else:
        form_set.from_database()
    form_set.update_previous_dimensions_form()
    title = _("Edit result") if form_set.result else _("New result")
    context_dict = {"title": title}
    context_dict.update(form_set.get_context_dict())
    return render(request, "samples/edit_result.html", context_dict)
Пример #13
0
def merge(request):
    """The merging of the samples is handled in this function.
    It creates the necessary forms, initiates the merging
    and returns the HttpResponse to the web browser.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    def build_merge_forms(data=None):
        merge_samples_forms = [MergeSamplesForm(request.user, data, prefix=str(0))]
        choices = merge_samples_forms[0].fields["from_sample"].choices
        merge_samples_forms += [MergeSamplesForm(request.user, data, prefix=str(index), choices=choices)
                                for index in range(1, number_of_pairs)]
        return merge_samples_forms
    if request.method == "POST":
        merge_samples_forms = build_merge_forms(request.POST)
        all_valid = all([merge_samples_form.is_valid() for merge_samples_form in merge_samples_forms])
        referentially_valid = is_referentially_valid(merge_samples_forms)
        if all_valid and referentially_valid:
            for merge_samples_form in merge_samples_forms:
                from_sample = merge_samples_form.cleaned_data.get("from_sample")
                to_sample = merge_samples_form.cleaned_data.get("to_sample")
                if from_sample and to_sample:
                    merge_samples(from_sample, to_sample)
            return utils.successful_response(request, _("Samples were successfully merged."))
    else:
        merge_samples_forms = build_merge_forms()
    return render(request, "samples/merge_samples.html", {"title": _("Merge samples"),
                                                          "merge_forms": merge_samples_forms})
Пример #14
0
def edit(request, process_id):
    """View for editing existing results, and for creating new ones.

    :param request: the current HTTP Request object
    :param process_id: the ID of the result process; ``None`` if we're creating
        a new one

    :type request: HttpRequest
    :type process_id: str

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    form_set = FormSet(request, process_id)
    if form_set.result:
        permissions.assert_can_edit_result_process(request.user, form_set.result)
    if request.method == "POST":
        form_set.from_post_data(request.POST, request.FILES)
        result = form_set.save_to_database(request.FILES)
        if result:
            utils.Reporter(request.user).report_result_process(
                result, form_set.edit_description_form.cleaned_data if form_set.edit_description_form else None)
            return utils.successful_response(request, json_response=result.pk)
    else:
        form_set.from_database()
    form_set.update_previous_dimensions_form()
    title = _("Edit result") if form_set.result else _("New result")
    context_dict = {"title": title}
    context_dict.update(form_set.get_context_dict())
    return render(request, "samples/edit_result.html", context_dict)
Пример #15
0
def edit(request, external_operator_id):
    """View for editing existing external operators.  You can also give the
    operator initials here.

    :param request: the current HTTP Request object
    :param external_operator_id: the database ID for the external operator

    :type request: HttpRequest
    :type external_operator_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    external_operator = get_object_or_404(models.ExternalOperator, pk=utils.convert_id_to_int(external_operator_id))
    permissions.assert_can_edit_external_operator(request.user, external_operator)
    if request.method == "POST":
        external_operator_form = EditExternalOperatorForm(request.user, request.POST, instance=external_operator)
        if external_operator_form.is_valid():
            external_operator = external_operator_form.save()
            return utils.successful_response(
                request,
                _("The external operator “{operator}” was successfully changed.").format(operator=external_operator.name))
    else:
        external_operator_form = EditExternalOperatorForm(request.user, instance=external_operator)
    initials_form = utils.InitialsForm(external_operator, initials_mandatory=True)
    return render(request, "samples/edit_external_operator.html",
                  {"title": _("Edit external operator “{operator}”").format(operator=external_operator.name),
                   "external_operator": external_operator_form,
                   "initials": initials_form})
Пример #16
0
def new(request, sample_name):
    """View for killing samples.  Note that it is not possible to re-kill an
    already dead sample.  Furthermore, you must be the currently responsible
    person to be able to kill a sample.

    :param request: the current HTTP Request object
    :param sample_name: name of the sample to be killed

    :type request: HttpRequest
    :type sample_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample = utils.lookup_sample(sample_name, request.user)
    permissions.assert_can_edit_sample(request.user, sample)
    if sample.is_dead():
        raise Http404("Sample is already dead.")
    if request.method == "POST":
        sample_death_form = SampleDeathForm(sample, request.POST)
        if sample_death_form.is_valid():
            sample_death = sample_death_form.save(commit=False)
            sample_death.timestamp = django.utils.timezone.now()
            sample_death.operator = request.user
            sample_death.save()
            sample_death.samples = [sample]
            # FixMe: Feed entries
            return utils.successful_response(request, _("Sample “{sample}” was killed.").format(sample=sample),
                                             "samples:show_sample_by_name", {"sample_name": sample_name})
    else:
        sample_death_form = SampleDeathForm(sample)
    return render(request, "samples/edit_sample_death.html", {"title": _("Kill sample “{sample}”").format(sample=sample),
                                                              "sample_death": sample_death_form})
Пример #17
0
def edit(request, username):
    """View for doing various things with the samples listed under “My
    Samples”.  For example, copying them to the “My Samples” list of another
    user, or simply removing them from the list.

    Note that there are two different user variables in this view and its
    associated functions.  ``current_user`` is the same as ``request.user``.
    Thus, it is the currently logged-in user.  However, ``user`` is the user
    whose “My Samples” are to be processed.  Almost always both are the same,
    especially because you are not allowed to see or change the “My Samples” of
    another user.  However, staff users *are* allowed to change them, so then
    both are different.

    :param request: the current HTTP Request object
    :param username: the login name of the user whose “My Samples” should be
        changed

    :type request: HttpRequest
    :type username: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    user = get_object_or_404(django.contrib.auth.models.User,
                             username=username)
    if not request.user.is_superuser and request.user != user:
        raise permissions.PermissionError(
            request.user,
            _("You can't access the “My Samples” section of another user."))
    if request.method == "POST":
        my_samples_form = MySamplesForm(user, request.POST)
        action_form = ActionForm(user, request.POST)
        referentially_valid = is_referentially_valid(request.user,
                                                     my_samples_form,
                                                     action_form)
        if my_samples_form.is_valid() and action_form.is_valid(
        ) and referentially_valid:
            save_to_database(user, my_samples_form, action_form)
            return utils.successful_response(
                request, _("Successfully processed “My Samples”."))
    else:
        if is_json_requested(request):
            return respond_in_json(
                request.user.my_samples.values_list("id", flat=True))
        my_samples_form = MySamplesForm(user)
        action_form = ActionForm(user)
    return render(
        request, "samples/edit_my_samples.html", {
            "title":
            _("Manage “My Samples” of {user_name}").format(
                user_name=get_really_full_name(user)),
            "my_samples":
            my_samples_form,
            "action":
            action_form
        })
Пример #18
0
def copy_informal_stack(request, sample_name):
    """View for copying the informal stack of a sample to other samples.

    :param request: the current HTTP Request object
    :param sample_name: the name of the sample

    :type request: HttpRequest
    :type sample_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample, __ = utils.lookup_sample(sample_name,
                                     request.user,
                                     with_clearance=True)
    if request.method == "POST":
        destination_samples_form = DestinationSamplesForm(
            request.user, sample, request.POST)
        if destination_samples_form.is_valid():
            destination_samples = destination_samples_form.cleaned_data[
                "samples"]
            informal_layers = sample.sample_details.informal_layers.all()
            for destination_sample in destination_samples:
                destination_sample.sample_details.informal_layers.all().delete(
                )
                for layer in informal_layers:
                    layer.sample_details = destination_sample.sample_details
                    layer.id = None
                    layer.save()
            feed_reporter = utils.Reporter(request.user)
            message = _(
                "Informal stack was copied from sample {sample}.".format(
                    sample=sample))
            feed_reporter.report_edited_samples(destination_samples,
                                                edit_description={
                                                    "important": False,
                                                    "description": message
                                                })
            return utils.successful_response(
                request,
                _("Informal stack of {sample} was successfully copied.").
                format(sample=sample), "samples:show_sample_by_id", {
                    "sample_id": sample.id,
                    "path_suffix": ""
                })
    else:
        destination_samples_form = DestinationSamplesForm(request.user, sample)
    context = {
        "title": _("Copy informal stack of “{sample}”").format(sample=sample),
        "sample": sample,
        "destination_samples": destination_samples_form
    }
    context.update(sample.sample_details.get_context_for_user(
        request.user, {}))
    return render(request, "samples/copy_informal_stack.html", context)
Пример #19
0
def edit(request, id):
    """View for changing the members of a particular topic, and to set the
    restriction status.  This is only allowed to heads of institute groups and
    topic managers.

    :param request: the current HTTP Request object
    :param id: the id of the topic

    :type request: HttpRequest
    :type name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    topic = get_object_or_404(Topic, id=int_or_zero(id), parent_topic=None)
    permissions.assert_can_edit_topic(request.user, topic)
    if request.method == "POST":
        edit_topic_form = EditTopicForm(request.user, topic, request.POST)
        added_members = []
        removed_members = []
        if edit_topic_form.is_valid():
            old_manager = topic.manager
            new_manager = edit_topic_form.cleaned_data["topic_manager"]
            topic.manager = new_manager
            old_members = list(topic.members.all())
            new_members = edit_topic_form.cleaned_data["members"] + [new_manager]
            topic.members = new_members
            topic.confidential = edit_topic_form.cleaned_data["confidential"]
            topic.save()
            if old_manager != new_manager:
                if not old_manager.managed_topics.all():
                    old_manager.user_permissions.remove(PermissionsModels.topic_manager_permission)
                if not permissions.has_permission_to_edit_users_topics(new_manager):
                    new_manager.user_permissions.add(PermissionsModels.topic_manager_permission)
            for user in new_members:
                if user not in old_members:
                    added_members.append(user)
                    topic.auto_adders.add(user.samples_user_details)
            for user in old_members:
                if user not in new_members:
                    removed_members.append(user)
                    topic.auto_adders.remove(user.samples_user_details)
            if added_members:
                utils.Reporter(request.user).report_changed_topic_membership(added_members, topic, "added")
            if removed_members:
                utils.Reporter(request.user).report_changed_topic_membership(removed_members, topic, "removed")
            return utils.successful_response(
                request, _("Members of topic “{name}” were successfully updated.").format(name=topic.name))
    else:
        edit_topic_form = \
            EditTopicForm(request.user, topic, initial={"members": topic.members.values_list("pk", flat=True),
                                                        "topic_manager": topic.manager.pk})
    return render(request, "samples/edit_topic.html", {"title": _("Change topic memberships of “{0}”").format(topic.name),
                                                       "edit_topic": edit_topic_form})
Пример #20
0
def split_and_rename(request, parent_name=None, old_split_id=None):
    """Both splitting of a sample and re-split of an already existing split
    are handled here.  *Either* ``parent_name`` *or* ``old_split`` are unequal
    to ``None``.

    :param request: the current HTTP Request object
    :param parent_name: if given, the name of the sample to be split
    :param old_split_id: if given the process ID of the split to be modified

    :type request: HttpRequest
    :type parent_name: unicode or NoneType
    :type old_split_id: int or NoneType

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    assert (parent_name or old_split_id) and not (parent_name and old_split_id)
    if parent_name:
        old_split = None
        parent = utils.lookup_sample(parent_name, request.user)
    else:
        old_split = get_object_or_404(models.SampleSplit, pk=utils.convert_id_to_int(old_split_id))
        parent = old_split.parent
        permissions.assert_can_edit_sample(request.user, parent)
        if parent.last_process_if_split() != old_split:
            raise Http404("This split is not the last one in the sample's process list.")
    number_of_old_pieces = old_split.pieces.count() if old_split else 0
    automatic_split_form = AutomaticSplitForm(request.POST)
    if request.method == "POST":
        new_name_forms, global_data_form, automatic_split_form, structure_changed, next_prefix = \
            forms_from_post_data(request.POST, parent, request.user)
        all_valid = is_all_valid(new_name_forms, global_data_form, automatic_split_form)
        referentially_valid = is_referentially_valid(new_name_forms, global_data_form, number_of_old_pieces)
        if all_valid and referentially_valid and not structure_changed:
            sample_split, new_pieces = save_to_database(new_name_forms, global_data_form, parent, old_split, request.user)
            utils.Reporter(request.user).report_sample_split(
                sample_split, global_data_form.cleaned_data["sample_completely_split"])
            return utils.successful_response(
                request, _("Sample “{sample}” was successfully split.").format(sample=parent),
                "show_sample_by_name", {"sample_name": parent.name}, json_response=new_pieces)
    else:
        new_name_forms, global_data_form, automatic_split_form = forms_from_database(parent, request.user)
        next_prefix = "0"
    new_name_forms.append(NewNameForm(request.user, parent.name,
                                      initial={"new_name": parent.name, "new_purpose": parent.purpose},
                                      prefix=next_prefix))
    return render(request, "samples/split_and_rename.html",
                  {"title": _("Split sample “{sample}”").format(sample=parent),
                   "new_names": list(zip(range(number_of_old_pieces + 1,
                                               number_of_old_pieces + 1 + len(new_name_forms)),
                                         new_name_forms)),
                   "automatic_split": automatic_split_form,
                   "global_data": global_data_form,
                   "old_split": old_split})
Пример #21
0
def edit(request, id):
    """View for changing the members of a particular topic, and to set the
    restriction status.  This is only allowed to heads of institute groups and
    topic managers.

    :param request: the current HTTP Request object
    :param id: the id of the topic

    :type request: HttpRequest
    :type name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    topic = get_object_or_404(Topic, id=int_or_zero(id), parent_topic=None)
    permissions.assert_can_edit_topic(request.user, topic)
    if request.method == "POST":
        edit_topic_form = EditTopicForm(request.user, topic, request.POST)
        added_members = []
        removed_members = []
        if edit_topic_form.is_valid():
            old_manager = topic.manager
            new_manager = edit_topic_form.cleaned_data["topic_manager"]
            topic.manager = new_manager
            old_members = list(topic.members.all())
            new_members = edit_topic_form.cleaned_data["members"] + [new_manager]
            topic.members = new_members
            topic.confidential = edit_topic_form.cleaned_data["confidential"]
            topic.save()
            if old_manager != new_manager:
                if not old_manager.managed_topics.all():
                    old_manager.user_permissions.remove(PermissionsModels.topic_manager_permission)
                if not permissions.has_permission_to_edit_users_topics(new_manager):
                    new_manager.user_permissions.add(PermissionsModels.topic_manager_permission)
            for user in new_members:
                if user not in old_members:
                    added_members.append(user)
                    topic.auto_adders.add(user.samples_user_details)
            for user in old_members:
                if user not in new_members:
                    removed_members.append(user)
                    topic.auto_adders.remove(user.samples_user_details)
            if added_members:
                utils.Reporter(request.user).report_changed_topic_membership(added_members, topic, "added")
            if removed_members:
                utils.Reporter(request.user).report_changed_topic_membership(removed_members, topic, "removed")
            return utils.successful_response(
                request, _("Members of topic “{name}” were successfully updated.").format(name=topic.name))
    else:
        edit_topic_form = \
            EditTopicForm(request.user, topic, initial={"members": topic.members.values_list("pk", flat=True),
                                                        "topic_manager": topic.manager.pk})
    return render(request, "samples/edit_topic.html", {"title": _("Change topic memberships of “{0}”").format(topic.name),
                                                       "edit_topic": edit_topic_form})
Пример #22
0
def edit(request, sample_name):
    """View for editing existing samples.  You can't use it to add new
    samples.

    :param request: the current HTTP Request object
    :param sample_name: the name of the sample

    :type request: HttpRequest
    :type sample_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample = utils.lookup_sample(sample_name, request.user)
    permissions.assert_can_edit_sample(request.user, sample)
    old_topic, old_responsible_person = sample.topic, sample.currently_responsible_person
    user_details = request.user.samples_user_details
    sample_details = sample.get_sample_details()
    if request.method == "POST":
        sample_form = SampleForm(request.user, request.POST, instance=sample)
        edit_description_form = utils.EditDescriptionForm(request.POST)
        all_valid = all([sample_form.is_valid(), edit_description_form.is_valid()])
        referentially_valid = is_referentially_valid(sample, sample_form, edit_description_form)
        if sample_details:
            sample_details_context, sample_details_valid = \
                sample_details.process_post(request.user, request.POST, sample_form, edit_description_form)
            all_valid = all_valid and sample_details_valid
        else:
            sample_details_context = {}
        if all_valid and referentially_valid:
            sample = sample_form.save()
            if sample_details:
                sample_details.save_form_data(sample_details_context)
            feed_reporter = utils.Reporter(request.user)
            if sample.currently_responsible_person != old_responsible_person:
                sample.currently_responsible_person.my_samples.add(sample)
                feed_reporter.report_new_responsible_person_samples([sample], edit_description_form.cleaned_data)
            if sample.topic and sample.topic != old_topic:
                for watcher in (user_details.user for user_details in sample.topic.auto_adders.all()):
                    watcher.my_samples.add(sample)
                feed_reporter.report_changed_sample_topic([sample], old_topic, edit_description_form.cleaned_data)
            feed_reporter.report_edited_samples([sample], edit_description_form.cleaned_data)
            return utils.successful_response(
                request, _("Sample {sample} was successfully changed in the database.").format(sample=sample),
                by_id, {"sample_id": sample.pk, "path_suffix": ""})
    else:
        sample_form = SampleForm(request.user, instance=sample)
        edit_description_form = utils.EditDescriptionForm()
        sample_details_context = sample_details.process_get(request.user) if sample_details else {}
    context = {"title": _("Edit sample “{sample}”").format(sample=sample), "sample": sample_form,
               "edit_description": edit_description_form}
    context.update(sample_details_context)
    return render(request, "samples/edit_sample.html", context)
Пример #23
0
def add(request, username):
    """View for adding a new claim.  The ``username`` parameter is actually
    superfluous because it must be the currently logged-in user anyway.  But
    this way, we don't get into trouble if a user happens to be called
    ``"add"``.  Additionally, the URLs become RESTful.

    :param request: the current HTTP Request object
    :param username: the name of the user whose claim this will be; it must be
        the currently logged-in user

    :type request: HttpRequest
    :type username: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    _ = ugettext
    user = get_object_or_404(django.contrib.auth.models.User, username=username)
    if user != request.user:
        raise permissions.PermissionError(request.user, _("You are not allowed to add a claim in another user's name."))
    if request.method == "POST":
        samples_form = SamplesForm(user, request.POST)
        reviewer_form = ReviewerForm(request.POST)
        if samples_form.is_valid() and reviewer_form.is_valid():
            reviewer = reviewer_form.cleaned_data["reviewer"]
            claim = models.SampleClaim(requester=user, reviewer=reviewer)
            claim.save()
            _ = lambda x: x
            send_email(_("Sample request from {requester}"),
                       _("""Hello {reviewer},

{requester} wants to become the new “currently responsible person”
of one or more samples.  Please visit

    {url}

for reviewing this request.  If you don't want or cannot approve
the request, please contact {requester} directly and ask him or her
to withdraw the request.

JuliaBase.
"""), reviewer, {"reviewer": get_really_full_name(reviewer), "requester": get_really_full_name(user),
                 "url": request.build_absolute_uri(django.core.urlresolvers.reverse(show, kwargs={"claim_id": claim.pk}))})
            _ = ugettext
            claim.samples = samples_form.cleaned_data["samples"]
            return utils.successful_response(request,
                                             _("Sample claim {id_} was successfully submitted.").format(id_=claim.pk),
                                             show, kwargs={"claim_id": claim.pk})
    else:
        samples_form = SamplesForm(user)
        reviewer_form = ReviewerForm()
    return render(request, "samples/add_claim.html", {"title": _("Assert claim"), "samples": samples_form,
                                                      "reviewer": reviewer_form})
Пример #24
0
def show(request):
    """Shows the task lists the user wants to see.
    It also provides the multiple choice list to select the task lists
    for the user.

    :Paramerters:
    :param request: the current HTTP Request object

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    if request.method == "POST":
        choose_task_lists_form = ChooseTaskListsForm(request.user,
                                                     request.POST)
        if choose_task_lists_form.is_valid():
            request.user.samples_user_details.visible_task_lists = \
                [ContentType.objects.get_for_id(int(id_))
                 for id_ in choose_task_lists_form.cleaned_data["visible_task_lists"] if id_]
            # In order to have a GET instead of a POST as the last request
            return utils.successful_response(request, view=show)
    else:
        choose_task_lists_form = ChooseTaskListsForm(request.user)
    one_week_ago = datetime.datetime.now() - datetime.timedelta(weeks=1)
    task_lists = {}
    for process_content_type in request.user.samples_user_details.visible_task_lists.all(
    ):
        active_tasks = process_content_type.tasks.order_by("-status", "priority", "last_modified"). \
            exclude(Q(status="0 finished") & Q(last_modified__lt=one_week_ago))
        task_lists[process_content_type] = [
            TaskForTemplate(task, request.user) for task in active_tasks
        ]
    task_lists_for_department = {}
    for process_content_type, tasks in task_lists.items():
        # FixMe: it is possible that some processes are in more then one department available
        # maybe we need a better way to determine the department
        department_names = {
            name
            for name, app_label in Department.objects.values_list(
                "name", "app_label")
            if app_label == process_content_type.model_class()._meta.app_label
        }
        assert len(department_names) == 1
        department_name = department_names.pop()
        task_lists_for_department.setdefault(department_name, {}).update(
            {process_content_type: tasks})
    return render(
        request, "samples/task_lists.html", {
            "title": _("Task lists"),
            "choose_task_lists": choose_task_lists_form,
            "task_lists": task_lists_for_department
        })
Пример #25
0
def edit(request, username):
    """View for editing user permissions.  You can change two kinds of user
    permissions here: The “add”, “view all”, and “edit permissions”
    permissions, as well as whether the user is a so-called “topic manager”.
    See `list_` for further information.

    :param request: the current HTTP Request object
    :param username: the username of the user whose permissions should be
        changed

    :type request: HttpRequest
    :type username: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    edited_user = get_object_or_404(User, username=username)
    user = request.user
    has_global_edit_permission = user.has_perm("samples.edit_permissions_for_all_physical_processes")
    addable_models = get_addable_models(user)
    permissions_list = []
    for model in addable_models:
        if model.add_permission or model.view_all_permission or model.edit_all_permission or \
                model.edit_permissions_permission:
            if user in model.permission_editors or has_global_edit_permission:
                if request.method == "POST":
                    permissions_list.append((model, PermissionsForm(edited_user, model, request.POST,
                                                                      prefix=model.codename)))
                else:
                    permissions_list.append((model, PermissionsForm(edited_user, model, prefix=model.codename)))
    if request.method == "POST":
        if all(permission[1].is_valid() for permission in permissions_list):
            for model, permissions_form in permissions_list:
                cleaned_data = permissions_form.cleaned_data
                def model_permission(form_key, attribute_name, permission):
                    if permission:
                        if cleaned_data[form_key]:
                            if edited_user not in getattr(model, attribute_name):
                                edited_user.user_permissions.add(permission)
                        else:
                            if edited_user in getattr(model, attribute_name):
                                edited_user.user_permissions.remove(permission)
                model_permission("can_add", "adders", model.add_permission)
                model_permission("can_view_all", "full_viewers", model.view_all_permission)
                model_permission("can_edit_all", "full_editors", model.edit_all_permission)
                model_permission("can_edit_permissions", "permission_editors", model.edit_permissions_permission)
            return utils.successful_response(request, _("The permissions of {name} were successfully changed."). \
                                                 format(name=get_really_full_name(edited_user)), list_)
    return render(request, "samples/edit_permissions.html",
                  {"title": _("Change permissions of {name}").format(name=get_really_full_name(edited_user)),
                   "permissions_list": permissions_list})
Пример #26
0
def split_and_rename_after_deposition(request, deposition_number):
    """View for renaming and/or splitting samples immediately after they have
    been deposited in the same run.

    Optionally, you can give query string parameters of the form
    ``new-name-21=super`` where 21 is the sample ID and “super” is the
    suggested new name of this sample.

    :param request: the current HTTP Request object
    :param deposition_number: the number of the deposition after which samples
        should be split and/or renamed

    :type request: HttpRequest
    :type deposition_number: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    deposition = get_object_or_404(models.Deposition, number=deposition_number).actual_instance
    permissions.assert_can_edit_physical_process(request.user, deposition)
    if not deposition.finished:
        raise Http404("This deposition is not finished yet.")
    if deposition.split_done:
        raise Http404("You can use the split and rename function only once after a deposition.")
    remote_client = is_json_requested(request)
    if request.POST:
        original_data_forms, new_name_form_lists, global_new_data_form = \
            forms_from_post_data(request.user, request.POST, deposition, remote_client)
        all_valid = is_all_valid(original_data_forms, new_name_form_lists, global_new_data_form)
        structure_changed = change_structure(request.user, original_data_forms, new_name_form_lists)
        referentially_valid = is_referentially_valid(original_data_forms, new_name_form_lists, deposition)
        if all_valid and referentially_valid and not structure_changed:
            sample_splits = save_to_database(original_data_forms, new_name_form_lists, global_new_data_form, deposition)
            for sample_split in sample_splits:
                utils.Reporter(request.user).report_sample_split(sample_split, sample_completely_split=True)
            return utils.successful_response(request, _("Samples were successfully split and/or renamed."),
                                             json_response=True)
    else:
        new_names = dict((int_or_zero(key[len("new-name-"):]), new_name)
                         for key, new_name in request.GET.items() if key.startswith("new-name-"))
        new_names.pop(0, None)
        original_data_forms, new_name_form_lists, global_new_data_form = \
            forms_from_database(request.user, deposition, remote_client, new_names)
    return render(request, "samples/split_after_deposition.html",
                  {"title": _("Bulk sample rename for {deposition}").format(deposition=deposition),
                   "samples": list(zip(original_data_forms, new_name_form_lists)),
                   "new_sample_data": global_new_data_form})
Пример #27
0
def add(request):
    """View for adding a new topic.  This action is only allowed to the heads
    of institute groups.  The name of topics may contain arbitrary characters.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    permissions.assert_can_edit_users_topics(request.user)
    if not request.user.jb_user_details.department:
        if request.user.is_superuser:
            return HttpResponseSeeOther("/admin/jb_common/topic/add/")
        else:
            raise permissions.PermissionError(request.user,
                                              _("You cannot add topics here because you are not in any department."))
    if request.method == "POST":
        new_topic_form = NewTopicForm(request.user, request.POST)
        if new_topic_form.is_valid():
            parent_topic = new_topic_form.cleaned_data.get("parent_topic", None)
            new_topic = Topic(name=new_topic_form.cleaned_data["new_topic_name"],
                              confidential=new_topic_form.cleaned_data["confidential"],
                              department=request.user.jb_user_details.department,
                              manager=new_topic_form.cleaned_data["topic_manager"])
            new_topic.save()
            if parent_topic:
                new_topic.parent_topic = parent_topic
                new_topic.confidential = parent_topic.confidential
                new_topic.members = parent_topic.members.all()
                new_topic.save()
                next_view = None
                next_view_kwargs = {}
            else:
                next_view = "samples.views.topic.edit"
                next_view_kwargs = {"id": django.utils.http.urlquote(new_topic.id, safe="")}
            new_topic.manager.user_permissions.add(PermissionsModels.topic_manager_permission)
            request.user.topics.add(new_topic)
            request.user.samples_user_details.auto_addition_topics.add(new_topic)
            return utils.successful_response(
                request, _("Topic {name} was successfully created.").format(name=new_topic.name),
                next_view, kwargs=next_view_kwargs)
    else:
        new_topic_form = NewTopicForm(request.user)
    return render(request, "samples/add_topic.html", {"title": capfirst(_("add new topic")), "new_topic": new_topic_form})
Пример #28
0
def edit(request, name):
    """View for editing an existing sample series.  Only the currently
    responsible person can edit a sample series.

    :param request: the current HTTP Request object
    :param name: name of the sample series

    :type request: HttpRequest
    :type name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample_series = get_object_or_404(models.SampleSeries, name=name)
    permissions.assert_can_edit_sample_series(request.user, sample_series)
    if request.method == "POST":
        sample_series_form = SampleSeriesForm(request.user, request.POST, instance=sample_series)
        edit_description_form = utils.EditDescriptionForm(request.POST)
        all_valid = sample_series_form.is_valid()
        all_valid = edit_description_form.is_valid() and all_valid
        referentially_valid = is_referentially_valid(sample_series, sample_series_form, edit_description_form)
        if all_valid and referentially_valid:
            edit_description = edit_description_form.cleaned_data
            feed_reporter = utils.Reporter(request.user)
            if sample_series.currently_responsible_person != sample_series_form.cleaned_data["currently_responsible_person"]:
                feed_reporter.report_new_responsible_person_sample_series(sample_series, edit_description)
            if sample_series.topic != sample_series_form.cleaned_data["topic"]:
                feed_reporter.report_changed_sample_series_topic(sample_series, sample_series.topic, edit_description)
            feed_reporter.report_edited_sample_series(sample_series, edit_description)
            sample_series = sample_series_form.save()
            feed_reporter.report_edited_sample_series(sample_series, edit_description)
            return utils.successful_response(
                request,
                _("Sample series {name} was successfully updated in the database.").format(name=sample_series.name))
    else:
        sample_series_form = \
            SampleSeriesForm(request.user, instance=sample_series,
                             initial={"short_name": sample_series.name.split("-", 2)[-1],
                                      "currently_responsible_person": sample_series.currently_responsible_person.pk,
                                      "topic": sample_series.topic.pk,
                                      "samples": [sample.pk for sample in sample_series.samples.all()]})
        edit_description_form = utils.EditDescriptionForm()
    return render(request, "samples/edit_sample_series.html",
                  {"title": _("Edit sample series “{name}”").format(name=sample_series.name),
                   "sample_series": sample_series_form,
                   "is_new": False, "edit_description": edit_description_form})
Пример #29
0
def edit(request, name):
    """View for editing an existing sample series.  Only the currently
    responsible person can edit a sample series.

    :param request: the current HTTP Request object
    :param name: name of the sample series

    :type request: HttpRequest
    :type name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample_series = get_object_or_404(models.SampleSeries, name=name)
    permissions.assert_can_edit_sample_series(request.user, sample_series)
    if request.method == "POST":
        sample_series_form = SampleSeriesForm(request.user, request.POST, instance=sample_series)
        edit_description_form = utils.EditDescriptionForm(request.POST)
        all_valid = sample_series_form.is_valid()
        all_valid = edit_description_form.is_valid() and all_valid
        referentially_valid = is_referentially_valid(sample_series, sample_series_form, edit_description_form)
        if all_valid and referentially_valid:
            edit_description = edit_description_form.cleaned_data
            feed_reporter = utils.Reporter(request.user)
            if sample_series.currently_responsible_person != sample_series_form.cleaned_data["currently_responsible_person"]:
                feed_reporter.report_new_responsible_person_sample_series(sample_series, edit_description)
            if sample_series.topic != sample_series_form.cleaned_data["topic"]:
                feed_reporter.report_changed_sample_series_topic(sample_series, sample_series.topic, edit_description)
            feed_reporter.report_edited_sample_series(sample_series, edit_description)
            sample_series = sample_series_form.save()
            feed_reporter.report_edited_sample_series(sample_series, edit_description)
            return utils.successful_response(
                request,
                _("Sample series {name} was successfully updated in the database.").format(name=sample_series.name))
    else:
        sample_series_form = \
            SampleSeriesForm(request.user, instance=sample_series,
                             initial={"short_name": sample_series.name.split("-", 2)[-1],
                                      "currently_responsible_person": sample_series.currently_responsible_person.pk,
                                      "topic": sample_series.topic.pk,
                                      "samples": [sample.pk for sample in sample_series.samples.all()]})
        edit_description_form = utils.EditDescriptionForm()
    return render(request, "samples/edit_sample_series.html",
                  {"title": _("Edit sample series “{name}”").format(name=sample_series.name),
                   "sample_series": sample_series_form,
                   "is_new": False, "edit_description": edit_description_form})
Пример #30
0
def add(request):
    """View for adding a new topic.  This action is only allowed to the heads
    of institute groups.  The name of topics may contain arbitrary characters.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    permissions.assert_can_edit_users_topics(request.user)
    if not request.user.jb_user_details.department:
        if request.user.is_superuser:
            return HttpResponseSeeOther("/admin/jb_common/topic/add/")
        else:
            raise permissions.PermissionError(request.user,
                                              _("You cannot add topics here because you are not in any department."))
    if request.method == "POST":
        new_topic_form = NewTopicForm(request.user, request.POST)
        if new_topic_form.is_valid():
            parent_topic = new_topic_form.cleaned_data.get("parent_topic", None)
            new_topic = Topic(name=new_topic_form.cleaned_data["new_topic_name"],
                              confidential=new_topic_form.cleaned_data["confidential"],
                              department=request.user.jb_user_details.department,
                              manager=new_topic_form.cleaned_data["topic_manager"])
            new_topic.save()
            if parent_topic:
                new_topic.parent_topic = parent_topic
                new_topic.confidential = parent_topic.confidential
                new_topic.save()
                next_view = None
                next_view_kwargs = {}
            else:
                next_view = "samples.views.topic.edit"
                next_view_kwargs = {"id": django.utils.http.urlquote(new_topic.id, safe="")}
            new_topic.manager.user_permissions.add(PermissionsModels.topic_manager_permission)
            request.user.topics.add(new_topic)
            request.user.samples_user_details.auto_addition_topics.add(new_topic)
            return utils.successful_response(
                request, _("Topic {name} was successfully created.").format(name=new_topic.name),
                next_view, kwargs=next_view_kwargs)
    else:
        new_topic_form = NewTopicForm(request.user)
    return render(request, "samples/add_topic.html", {"title": _("Add new topic"), "new_topic": new_topic_form})
Пример #31
0
def remove(request, task_id):
    """Deletes a task from the database.

    :Paramerters:
    :param request: the current HTTP Request object
    :param task_id: the id from the task, which has to be deleted

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    task = get_object_or_404(Task, id=utils.convert_id_to_int(task_id))
    if task.customer != request.user:
        raise permissions.PermissionError(request.user, _("You are not the customer of this task."))
    utils.Reporter(request.user).report_removed_task(task)
    task.delete()
    return utils.successful_response(request, _("The task was successfully removed."), show)
Пример #32
0
def edit(request, external_operator_id):
    """View for editing existing external operators.  You can also give the
    operator initials here.

    :param request: the current HTTP Request object
    :param external_operator_id: the database ID for the external operator

    :type request: HttpRequest
    :type external_operator_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    external_operator = get_object_or_404(
        models.ExternalOperator,
        pk=utils.convert_id_to_int(external_operator_id))
    permissions.assert_can_edit_external_operator(request.user,
                                                  external_operator)
    if request.method == "POST":
        external_operator_form = EditExternalOperatorForm(
            request.user, request.POST, instance=external_operator)
        if external_operator_form.is_valid():
            external_operator = external_operator_form.save()
            return utils.successful_response(
                request,
                _("The external operator “{operator}” was successfully changed."
                  ).format(operator=external_operator.name))
    else:
        external_operator_form = EditExternalOperatorForm(
            request.user, instance=external_operator)
    initials_form = utils.InitialsForm(external_operator,
                                       initials_mandatory=True)
    return render(
        request, "samples/edit_external_operator.html", {
            "title":
            _("Edit external operator “{operator}”").format(
                operator=external_operator.name),
            "external_operator":
            external_operator_form,
            "initials":
            initials_form
        })
Пример #33
0
def new(request):
    """View for creating a new sample series.  Note that you can add arbitrary
    samples to a sample series, even those you can't see.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    if request.method == "POST":
        sample_series_form = SampleSeriesForm(request.user, request.POST)
        if sample_series_form.is_valid():
            timestamp = datetime.datetime.today()
            full_name = "{0}-{1}-{2}".format(
                request.user.username, timestamp.strftime("%y"), sample_series_form.cleaned_data["short_name"])
            if models.SampleSeries.objects.filter(name=full_name).exists():
                sample_series_form.add_error("short_name", ValidationError(_("This sample series name is already given."),
                                                                           code="duplicate"))
            elif len(full_name) > models.SampleSeries._meta.get_field("name").max_length:
                overfull_letters = len(full_name) - models.SampleSeries._meta.get_field("name").max_length
                sample_series_form.add_error("short_name", ValidationError(
                    ungettext("The name is %(number)s letter too long.", "The name is %(number)s letters too long.",
                              overfull_letters), params={"number": overfull_letters}, code="invalid"))
            else:
                sample_series = sample_series_form.save(commit=False)
                sample_series.name = full_name
                sample_series.timestamp = timestamp
                sample_series.save()
                sample_series_form.save_m2m()
                utils.Reporter(request.user).report_new_sample_series(sample_series)
                return utils.successful_response(
                    request, _("Sample series {name} was successfully added to the database.").format(name=full_name))
    else:
        sample_series_form = SampleSeriesForm(request.user)
    return render(request, "samples/edit_sample_series.html",
                  {"title": _("Create new sample series"),
                   "sample_series": sample_series_form,
                   "is_new": True,
                   "name_prefix": "{0}-{1}".format(request.user.username, datetime.datetime.today().strftime("%y"))})
Пример #34
0
def edit(request, username):
    """View for doing various things with the samples listed under “My
    Samples”.  For example, copying them to the “My Samples” list of another
    user, or simply removing them from the list.

    Note that there are two different user variables in this view and its
    associated functions.  ``current_user`` is the same as ``request.user``.
    Thus, it is the currently logged-in user.  However, ``user`` is the user
    whose “My Samples” are to be processed.  Almost always both are the same,
    especially because you are not allowed to see or change the “My Samples” of
    another user.  However, staff users *are* allowed to change them, so then
    both are different.

    :param request: the current HTTP Request object
    :param username: the login name of the user whose “My Samples” should be
        changed

    :type request: HttpRequest
    :type username: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    user = get_object_or_404(django.contrib.auth.models.User, username=username)
    if not request.user.is_superuser and request.user != user:
        raise permissions.PermissionError(request.user, _("You can't access the “My Samples” section of another user."))
    if request.method == "POST":
        my_samples_form = MySamplesForm(user, request.POST)
        action_form = ActionForm(user, request.POST)
        referentially_valid = is_referentially_valid(request.user, my_samples_form, action_form)
        if my_samples_form.is_valid() and action_form.is_valid() and referentially_valid:
            save_to_database(user, my_samples_form, action_form)
            return utils.successful_response(request, _("Successfully processed “My Samples”."))
    else:
        if is_json_requested(request):
            return respond_in_json(request.user.my_samples.values_list("id", flat=True))
        my_samples_form = MySamplesForm(user)
        action_form = ActionForm(user)
    return render(request, "samples/edit_my_samples.html",
                  {"title": _("Manage “My Samples” of {user_name}").format(user_name=get_really_full_name(user)),
                   "my_samples": my_samples_form, "action": action_form})
Пример #35
0
def remove(request, task_id):
    """Deletes a task from the database.

    :Paramerters:
    :param request: the current HTTP Request object
    :param task_id: the id from the task, which has to be deleted

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    task = get_object_or_404(Task, id=utils.convert_id_to_int(task_id))
    if task.customer != request.user:
        raise permissions.PermissionError(
            request.user, _("You are not the customer of this task."))
    utils.Reporter(request.user).report_removed_task(task)
    task.delete()
    return utils.successful_response(request,
                                     _("The task was successfully removed."),
                                     "samples:show_task_lists")
Пример #36
0
def rename_sample(request):
    """Rename a sample given by its id.  This view should only be available for
    adminstative users.  For normal users use
    ``samples.views.bulk_rename.bulk_rename``

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample_id = request.GET.get("sample_id")
    if sample_id:
        sample = get_object_or_404(models.Sample, pk=utils.convert_id_to_int(sample_id))
        permissions.assert_can_rename_sample(request.user, sample)
    else:
        sample = None
    if request.method == "POST":
        sample_rename_form = SampleRenameForm(request.user, request.POST)
        if sample_rename_form.is_valid():
            old_name = sample_rename_form.cleaned_data["old_name"]
            if not sample:
                sample = models.Sample.objects.get(name=old_name)
            sample.name = sample_rename_form.cleaned_data["new_name"]
            sample.save()
            if sample_rename_form.cleaned_data["create_alias"]:
                models.SampleAlias.objects.create(name=old_name, sample=sample)
            feed_reporter = utils.Reporter(request.user)
            feed_reporter.report_edited_samples([sample], {"important": True,
               "description": _("Sample {old_name} was renamed to {new_name}").
                                                           format(new_name=sample.name, old_name=old_name)})
            return utils.successful_response(
                request, _("Sample {sample} was successfully changed in the database.").format(sample=sample))
    else:
        sample_rename_form = SampleRenameForm(request.user, initial={"old_name": sample.name if sample else ""})
    title = capfirst(_("rename sample")) + " “{sample}”".format(sample=sample) if sample else ""
    return render(request, "samples/rename_sample.html", {"title": title, "sample_rename": sample_rename_form})
Пример #37
0
def copy_informal_stack(request, sample_name):
    """View for copying the informal stack of a sample to other samples.

    :param request: the current HTTP Request object
    :param sample_name: the name of the sample

    :type request: HttpRequest
    :type sample_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample, __ = utils.lookup_sample(sample_name, request.user, with_clearance=True)
    if request.method == "POST":
        destination_samples_form = DestinationSamplesForm(request.user, sample, request.POST)
        if destination_samples_form.is_valid():
            destination_samples = destination_samples_form.cleaned_data["samples"]
            informal_layers = sample.sample_details.informal_layers.all()
            for destination_sample in destination_samples:
                destination_sample.sample_details.informal_layers.all().delete()
                for layer in informal_layers:
                    layer.sample_details = destination_sample.sample_details
                    layer.id = None
                    layer.save()
            feed_reporter = utils.Reporter(request.user)
            message = _("Informal stack was copied from sample {sample}.".format(sample=sample))
            feed_reporter.report_edited_samples(destination_samples,
                                                edit_description={"important": False, "description": message})
            return utils.successful_response(
                request, _("Informal stack of {sample} was successfully copied.").format(sample=sample),
                "samples.views.sample.by_id", {"sample_id": sample.id, "path_suffix": ""})
    else:
        destination_samples_form = DestinationSamplesForm(request.user, sample)
    context = {"title": _("Copy informal stack of “{sample}”").format(sample=sample),
               "sample": sample, "destination_samples": destination_samples_form}
    context.update(sample.sample_details.get_context_for_user(request.user, {}))
    return render(request, "samples/copy_informal_stack.html", context)
Пример #38
0
def edit(request, login_name):
    """View for editing the “My Layers”.

    :param request: the current HTTP Request object
    :param login_name: the login name of the user whose “My Layers” should be
        changed

    :type request: HttpRequest
    :type login_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    user = get_object_or_404(django.contrib.auth.models.User,
                             username=login_name)
    if not request.user.is_superuser and request.user != user:
        raise permissions.PermissionError(
            request.user,
            _("You can't access the “My Layers” section of another user."))
    if request.method == "POST":
        my_layer_forms, structure_changed = forms_from_post_data(request.POST)
        all_valid = all(
            [my_layer_form.is_valid() for my_layer_form in my_layer_forms])
        referentially_valid = is_referentially_valid(my_layer_forms)
        if all_valid and referentially_valid and not structure_changed:
            result = save_to_database(my_layer_forms, user)
            return utils.successful_response(request, result)
        elif all_valid and referentially_valid and structure_changed:
            messages.error(request, _("Changes are not saved yet."))
    else:
        my_layer_forms = forms_from_database(user)
    my_layer_forms.append(MyLayerForm(prefix=str(len(my_layer_forms))))
    return render(request, "samples/edit_my_layers.html", {
        "title": _("My Layers"),
        "my_layers": my_layer_forms
    })
Пример #39
0
def withdraw(request, id_):
    """This function withdraws a status message for good.  Note that it
    withdraws it for all its connected process types.  It is idempotent.

    :param request: the current HTTP Request object
    :param id_: the id of the message to be withdrawn

    :type request: HttpRequest
    :type id_: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    status_message = get_object_or_404(models.StatusMessage, withdrawn=False, pk=utils.convert_id_to_int(id_))
    if request.user != status_message.operator:
        raise PermissionError(request.user, "You cannot withdraw status messages of another user.")
    status_message.withdrawn = True
    status_message.save()
    for process_class in status_message.process_classes.all():
        utils.Reporter(request.user).report_withdrawn_status_message(process_class, status_message)
    return utils.successful_response(request, _("The status message was successfully withdrawn."), show)
Пример #40
0
def add(request):
    """With this function, the messages are stored into the database.  It also gets
    the information for displaying the "add_status_message" template.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    if request.method == "POST":
        status_form = StatusForm(request.user, request.POST)
        if status_form.is_valid():
            status = status_form.save()
            for process_class in status.process_classes.all():
                utils.Reporter(request.user).report_status_message(process_class, status)
            return utils.successful_response(request, _("The status message was successfully added to the database."))
    else:
        status_form = StatusForm(request.user)
    title = _("Add status message")
    return render(request, "samples/add_status_message.html", {"title": title, "status": status_form})
Пример #41
0
def new(request):
    """View for adding a new external operator.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    permissions.assert_can_add_external_operator(request.user)
    if request.method == "POST":
        external_operator_form = AddExternalOperatorForm(
            request.user, request.POST)
        initials_form = utils.InitialsForm(person=None,
                                           initials_mandatory=True,
                                           data=request.POST)
        if external_operator_form.is_valid() and initials_form.is_valid():
            external_operator = external_operator_form.save()
            initials_form.save(external_operator)
            return utils.successful_response(
                request,
                _("The external operator “{operator}” was successfully added.".
                  format(operator=external_operator.name)))
    else:
        external_operator_form = AddExternalOperatorForm(request.user)
        initials_form = utils.InitialsForm(person=None,
                                           initials_mandatory=True)
    return render(
        request, "samples/edit_external_operator.html", {
            "title": _("Add external operator"),
            "external_operator": external_operator_form,
            "initials": initials_form
        })
Пример #42
0
def show(request, claim_id):
    """View for reviewing a claim.

    :param request: the current HTTP Request object
    :param claim_id: the primary key of the claim to be viewed

    :type request: HttpRequest
    :type claim_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    _ = ugettext
    claim = get_object_or_404(models.SampleClaim,
                              pk=utils.convert_id_to_int(claim_id))
    is_reviewer = request.user == claim.reviewer or request.user.is_staff
    is_requester = request.user == claim.requester
    if not is_reviewer and not is_requester:
        raise permissions.PermissionError(
            request.user,
            _("You are neither the requester nor the reviewer of this claim."))
    if request.method == "POST" and not claim.closed:
        withdraw_form = CloseForm(_("withdraw claim"),
                                  request.POST,
                                  prefix="withdraw") if is_requester else None
        approve_form = CloseForm(_("approve claim"),
                                 request.POST,
                                 prefix="approve") if is_reviewer else None
        all_valid = (withdraw_form is None or withdraw_form.is_valid()) and (
            approve_form is None or approve_form.is_valid())
        referencially_valid = is_referentially_valid(withdraw_form,
                                                     approve_form)
        if all_valid and referencially_valid:
            approved = approve_form and approve_form.cleaned_data["close"]
            closed = approved or (withdraw_form
                                  and withdraw_form.cleaned_data["close"])
            response = None
            if approved:
                sample_list = list(claim.samples.all())
                for sample in sample_list:
                    sample.currently_responsible_person = claim.requester
                    sample.save()
                sample_enumeration = "    " + ",\n    ".join(
                    six.text_type(sample) for sample in sample_list)
                _ = lambda x: x
                send_email(
                    _("Sample request approved"),
                    _("""Hello {requester},

your sample claim was approved.  You are now the “currently
responsible person” of the following samples:

{samples}

JuliaBase.
"""), claim.requester, {
                        "requester": get_really_full_name(claim.requester),
                        "samples": sample_enumeration
                    })
                _ = ugettext
                response = \
                    utils.successful_response(request,
                                              _("Sample claim {id_} was successfully approved.").format(id_=claim.pk))
            if closed:
                claim.closed = True
                claim.save()
                response = response or \
                    utils.successful_response(request,
                                              _("Sample claim {id_} was successfully withdrawn.").format(id_=claim.pk))
            return response
    else:
        withdraw_form = CloseForm(_("withdraw claim"),
                                  prefix="withdraw") if is_requester else None
        approve_form = CloseForm(_("approve claim"),
                                 prefix="approve") if is_reviewer else None
    return render(
        request, "samples/show_claim.html", {
            "title": _("Claim #{number}").format(number=claim_id),
            "claim": claim,
            "is_reviewer": is_reviewer,
            "is_requester": is_requester,
            "withdraw": withdraw_form,
            "approve": approve_form
        })
Пример #43
0
def add(request, username):
    """View for adding a new claim.  The ``username`` parameter is actually
    superfluous because it must be the currently logged-in user anyway.  But
    this way, we don't get into trouble if a user happens to be called
    ``"add"``.  Additionally, the URLs become RESTful.

    :param request: the current HTTP Request object
    :param username: the name of the user whose claim this will be; it must be
        the currently logged-in user

    :type request: HttpRequest
    :type username: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    _ = ugettext
    user = get_object_or_404(django.contrib.auth.models.User,
                             username=username)
    if user != request.user:
        raise permissions.PermissionError(
            request.user,
            _("You are not allowed to add a claim in another user's name."))
    if request.method == "POST":
        samples_form = SamplesForm(user, request.POST)
        reviewer_form = ReviewerForm(request.POST)
        if samples_form.is_valid() and reviewer_form.is_valid():
            reviewer = reviewer_form.cleaned_data["reviewer"]
            claim = models.SampleClaim(requester=user, reviewer=reviewer)
            claim.save()
            _ = lambda x: x
            send_email(
                _("Sample request from {requester}"),
                _("""Hello {reviewer},

{requester} wants to become the new “currently responsible person”
of one or more samples.  Please visit

    {url}

for reviewing this request.  If you don't want or cannot approve
the request, please contact {requester} directly and ask him or her
to withdraw the request.

JuliaBase.
"""), reviewer, {
                    "reviewer":
                    get_really_full_name(reviewer),
                    "requester":
                    get_really_full_name(user),
                    "url":
                    request.build_absolute_uri(
                        django.core.urlresolvers.reverse(
                            show, kwargs={"claim_id": claim.pk}))
                })
            _ = ugettext
            claim.samples = samples_form.cleaned_data["samples"]
            return utils.successful_response(
                request,
                _("Sample claim {id_} was successfully submitted.").format(
                    id_=claim.pk),
                show,
                kwargs={"claim_id": claim.pk})
    else:
        samples_form = SamplesForm(user)
        reviewer_form = ReviewerForm()
    return render(
        request, "samples/add_claim.html", {
            "title": _("Assert claim"),
            "samples": samples_form,
            "reviewer": reviewer_form
        })
Пример #44
0
def split_and_rename(request, parent_name=None, old_split_id=None):
    """Both splitting of a sample and re-split of an already existing split
    are handled here.  *Either* ``parent_name`` *or* ``old_split`` are unequal
    to ``None``.

    :param request: the current HTTP Request object
    :param parent_name: if given, the name of the sample to be split
    :param old_split_id: if given the process ID of the split to be modified

    :type request: HttpRequest
    :type parent_name: unicode or NoneType
    :type old_split_id: int or NoneType

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    assert (parent_name or old_split_id) and not (parent_name and old_split_id)
    if parent_name:
        old_split = None
        parent = utils.lookup_sample(parent_name, request.user)
    else:
        old_split = get_object_or_404(models.SampleSplit,
                                      pk=utils.convert_id_to_int(old_split_id))
        parent = old_split.parent
        permissions.assert_can_edit_sample(request.user, parent)
        if parent.last_process_if_split() != old_split:
            raise Http404(
                "This split is not the last one in the sample's process list.")
    number_of_old_pieces = old_split.pieces.count() if old_split else 0
    automatic_split_form = AutomaticSplitForm(request.POST)
    if request.method == "POST":
        new_name_forms, global_data_form, automatic_split_form, structure_changed, next_prefix = \
            forms_from_post_data(request.POST, parent, request.user)
        all_valid = is_all_valid(new_name_forms, global_data_form,
                                 automatic_split_form)
        referentially_valid = is_referentially_valid(new_name_forms,
                                                     global_data_form,
                                                     number_of_old_pieces)
        if all_valid and referentially_valid and not structure_changed:
            sample_split, new_pieces = save_to_database(
                new_name_forms, global_data_form, parent, old_split,
                request.user)
            utils.Reporter(request.user).report_sample_split(
                sample_split,
                global_data_form.cleaned_data["sample_completely_split"])
            return utils.successful_response(
                request,
                _("Sample “{sample}” was successfully split.").format(
                    sample=parent),
                "samples:show_sample_by_name", {"sample_name": parent.name},
                json_response=new_pieces)
    else:
        new_name_forms, global_data_form, automatic_split_form = forms_from_database(
            parent, request.user)
        next_prefix = "0"
    new_name_forms.append(
        NewNameForm(request.user,
                    parent.name,
                    initial={
                        "new_name": parent.name,
                        "new_purpose": parent.purpose
                    },
                    prefix=next_prefix))
    return render(
        request, "samples/split_and_rename.html", {
            "title":
            _("Split sample “{sample}”").format(sample=parent),
            "new_names":
            list(
                zip(
                    range(number_of_old_pieces + 1, number_of_old_pieces + 1 +
                          len(new_name_forms)), new_name_forms)),
            "automatic_split":
            automatic_split_form,
            "global_data":
            global_data_form,
            "old_split":
            old_split
        })
Пример #45
0
def edit(request, username):
    """View for editing user permissions.  You can change two kinds of user
    permissions here: The “add”, “view all”, and “edit permissions”
    permissions, as well as whether the user is a so-called “topic manager”.
    See `list_` for further information.

    :param request: the current HTTP Request object
    :param username: the username of the user whose permissions should be
        changed

    :type request: HttpRequest
    :type username: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    edited_user = get_object_or_404(User, username=username)
    user = request.user
    has_global_edit_permission = user.has_perm(
        "samples.edit_permissions_for_all_physical_processes")
    addable_models = get_addable_models(user)
    permissions_list = []
    for model in addable_models:
        if model.add_permission or model.view_all_permission or model.edit_all_permission or \
                model.edit_permissions_permission:
            if user in model.permission_editors or has_global_edit_permission:
                if request.method == "POST":
                    permissions_list.append(
                        (model,
                         PermissionsForm(edited_user,
                                         model,
                                         request.POST,
                                         prefix=model.codename)))
                else:
                    permissions_list.append(
                        (model,
                         PermissionsForm(edited_user,
                                         model,
                                         prefix=model.codename)))
    if request.method == "POST":
        if all(permission[1].is_valid() for permission in permissions_list):
            for model, permissions_form in permissions_list:
                cleaned_data = permissions_form.cleaned_data

                def model_permission(form_key, attribute_name, permission):
                    if permission:
                        if cleaned_data[form_key]:
                            if edited_user not in getattr(
                                    model, attribute_name):
                                edited_user.user_permissions.add(permission)
                        else:
                            if edited_user in getattr(model, attribute_name):
                                edited_user.user_permissions.remove(permission)

                model_permission("can_add", "adders", model.add_permission)
                model_permission("can_view_all", "full_viewers",
                                 model.view_all_permission)
                model_permission("can_edit_all", "full_editors",
                                 model.edit_all_permission)
                model_permission("can_edit_permissions", "permission_editors",
                                 model.edit_permissions_permission)
            return utils.successful_response(request, _("The permissions of {name} were successfully changed."). \
                                                 format(name=get_really_full_name(edited_user)), "samples:list_permissions")
    return render(
        request, "samples/edit_permissions.html", {
            "title":
            _("Change permissions of {name}").format(
                name=get_really_full_name(edited_user)),
            "permissions_list":
            permissions_list
        })
Пример #46
0
def edit_depositions(request,
                     deposition_number,
                     form_set,
                     institute_model,
                     edit_url,
                     rename_conservatively=False):
    """This function is the central view for editing, creating, and duplicating for
    any deposition.  The edit functions in the deposition views are wrapper
    functions who provides this function with the specific informations.  If
    `deposition_number` is ``None``, a new depositon is created (possibly by
    duplicating another one).

    :param request: the HTTP request object
    :param deposition_number: the number (=name) or the deposition
    :param form_set: the related formset object for the deposition
    :param institute_model: the related Database model
    :param edit_url: the location of the edit template
    :param rename_conservatively: If ``True``, rename only provisional and
        cleaning process names.  This is used by the Large Sputter deposition.
        See the ``new_names`` parameter in
        `samples.views.split_after_deposition.forms_from_database` for how this
        is achieved

    :type request: QueryDict
    :type deposition_number: unicode or NoneType
    :type form_set: FormSet
    :type institute_model: `samples.models.Deposition`
    :type edit_url: unicode
    :type rename_conservatively: bool

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    permissions.assert_can_add_edit_physical_process(request.user,
                                                     form_set.deposition,
                                                     institute_model)
    if request.method == "POST":
        form_set.from_post_data(request.POST)
        deposition = form_set.save_to_database()
        if deposition:
            if form_set.remove_from_my_samples_form and \
                    form_set.remove_from_my_samples_form.cleaned_data["remove_from_my_samples"]:
                utils.remove_samples_from_my_samples(deposition.samples.all(),
                                                     form_set.user)
            next_view = next_view_kwargs = None
            query_string = ""
            newly_finished = deposition.finished and (
                not form_set.deposition
                or getattr(form_set, "unfinished", False))
            if newly_finished:
                rename = False
                new_names = {}
                if rename_conservatively:
                    for sample in deposition.samples.all():
                        name_format = utils.sample_name_format(sample.name)
                        if name_format == "provisional" or name_format == "old" and sample.name[
                                2] in ["N", "V"]:
                            rename = True
                        elif name_format == "old":
                            new_names[sample.id] = sample.name
                else:
                    rename = True
                if rename:
                    next_view = "samples.views.split_after_deposition.split_and_rename_after_deposition"
                    next_view_kwargs = {"deposition_number": deposition.number}
                    query_string = urllib.parse.urlencode([
                        ("new-name-{0}".format(id_), new_name)
                        for id_, new_name in new_names.items()
                    ])
            elif not deposition.finished:
                next_view, __, next_view_kwargs = django.core.urlresolvers.resolve(
                    request.path)
                next_view_kwargs["deposition_number"] = deposition.number
            if deposition_number:
                message = _("Deposition {number} was successfully changed in the database."). \
                    format(number=deposition.number)
                json_response = True
            else:
                message = _(
                    "Deposition {number} was successfully added to the database."
                ).format(number=deposition.number)
                json_response = deposition.pk
            return utils.successful_response(request,
                                             message,
                                             next_view,
                                             next_view_kwargs or {},
                                             query_string,
                                             forced=next_view is not None,
                                             json_response=json_response)
        else:
            messages.error(
                request,
                _("The deposition was not saved due to incorrect or missing data."
                  ))
    else:
        form_set.from_database(request.GET)
    institute_model_name = capitalize_first_letter(
        institute_model._meta.verbose_name)
    title = _("Edit {name} “{number}”").format(name=institute_model_name, number=deposition_number) if deposition_number \
        else _("Add {name}").format(name=institute_model._meta.verbose_name)
    title = capitalize_first_letter(title)
    context_dict = {"title": title}
    context_dict.update(form_set.get_context_dict())
    return render(request, edit_url, context_dict)
Пример #47
0
def edit(request, task_id):
    """Edit or create a task.

    :param request: the current HTTP Request object
    :param task_id: number of the task to be edited.  If this is
        ``None``, create a new one.

    :type request: HttpRequest
    :type task_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    task = get_object_or_404(Task, id=utils.convert_id_to_int(task_id)) if task_id else None
    user = request.user
    if task and user != task.customer:
        permissions.assert_can_add_physical_process(request.user, task.process_class.model_class())
    preset_sample = utils.extract_preset_sample(request) if not task_id else None
    if request.method == "POST":
        task_form = TaskForm(user, request.POST, instance=task)
        samples_form = SamplesForm(user, preset_sample, task, request.POST)
        if task_id:
            old_task = copy.copy(task)
            old_samples = set(task.samples.all())
        if task_form.is_valid() and (not samples_form.is_bound or samples_form.is_valid()):
            task = save_to_database(task_form, samples_form, old_task=old_task if task_id else None)
            if task_id:
                edit_description = {"important": True, "description": ""}
                if old_task.status != task.status:
                    edit_description["description"] += \
                        _("* Status is now “{new_status}”.\n").format(new_status=task.get_status_display())
                if old_task.priority != task.priority:
                    edit_description["description"] += \
                        _("* Priority is now “{new_priority}̣”.\n").format(new_priority=task.get_priority_display())
                if old_task.finished_process != task.finished_process:
                    edit_description["description"] += _("* Connected process.\n")
                if old_task.operator != task.operator:
                    if task.operator:
                        edit_description["description"] += _("* Operator is now {operator}.\n").format(
                            operator=common_utils.get_really_full_name(task.operator))
                    else:
                        edit_description["description"] += _("* No operator is set anymore.\n")
                if old_samples != set(task.samples.all()):
                    edit_description["description"] += "* {0}.\n".format(common_utils.capitalize_first_letter(_("samples")))
                if old_task.comments != task.comments:
                    edit_description["description"] += "* {0}.\n".format(common_utils.capitalize_first_letter(_("comments")))
            else:
                edit_description = None
            utils.Reporter(request.user).report_task(task, edit_description)
            message = _("Task was {verb} successfully.").format(verb=_("edited") if task_id else _("added"))
            return utils.successful_response(request, message, "samples.views.task_lists.show")
    else:
        samples_form = SamplesForm(user, preset_sample, task)
        initial = {}
        if "process_class" in request.GET:
            initial["process_class"] = request.GET["process_class"]
        task_form = TaskForm(request.user, instance=task, initial=initial)
    title = capfirst(_("edit task")) if task else capfirst(_("add task"))
    return render(request, "samples/edit_task.html", {"title": title, "task": task_form, "samples": samples_form})
Пример #48
0
def bulk_rename(request):
    """View for bulk-renaming samples that have had a provisional name so far.  If
    the user doesn't have initials yet, he is redirected to his preferences
    page.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    # FixMe: Get rid of the "numbers" parameter.  I think it is only used in
    # the remote client.
    if "numbers" in request.GET:
        numbers_list = request.GET.get("numbers", "")
        samples = [get_object_or_404(models.Sample, name="*" + number.zfill(5)) for number in numbers_list.split(",")]
    elif "ids" in request.GET:
        ids = request.GET["ids"].split(",")
        samples = [get_object_or_404(models.Sample, pk=utils.convert_id_to_int(id_)) for id_ in ids]
        if not all(utils.sample_name_format(sample.name) in utils.get_renamable_name_formats() for sample in samples):
            raise Http404("Some given samples cannot be renamed.")
    else:
        samples = None
    if not samples:
        raise Http404("No samples given.")
    for sample in samples:
        permissions.assert_can_edit_sample(request.user, sample)

    available_prefixes = find_prefixes(request.user)
    if not available_prefixes and any("{user_initials}" in format_ for format_ in settings.NAME_PREFIX_TEMPLATES) \
       and not models.Initials.objects.filter(user=request.user).exists():
        query_string = "initials_mandatory=True&next=" + django.utils.http.urlquote_plus(
            request.path + "?" + request.META["QUERY_STRING"], safe="/")
        messages.info(request, _("You may change the sample names, but you must choose initials first."))
        return utils.successful_response(request, view="samples.views.user_details.edit_preferences",
                                         kwargs={"login_name": request.user.username},
                                         query_string=query_string, forced=True)
    single_prefix = available_prefixes[0][1] if len(available_prefixes) == 1 else None
    if request.method == "POST":
        if single_prefix:
            prefixes_form = None
            prefix = single_prefix
        elif available_prefixes:
            prefixes_form = PrefixesForm(available_prefixes, request.POST)
            prefix = prefixes_form.cleaned_data["prefix"] if prefixes_form.is_valid() else ""
        else:
            prefixes_form = None
            prefix = ""
        if prefix == "*":
            prefix = ""
        new_name_forms = [NewNameForm(request.user, prefix, sample, request.POST, prefix=str(sample.pk))
                          for sample in samples]
        all_valid = prefixes_form is None or prefixes_form.is_valid()
        all_valid = all([new_name_form.is_valid() for new_name_form in new_name_forms]) and all_valid
        referentially_valid = is_referentially_valid(samples, new_name_forms)
        if all_valid and referentially_valid:
            for sample, new_name_form in zip(samples, new_name_forms):
                if not sample.name.startswith("*"):
                    models.SampleAlias(name=sample.name, sample=sample).save()
                sample.name = new_name_form.cleaned_data["name"]
                sample.save()
            return utils.successful_response(request, _("Successfully renamed the samples."))
    else:
        prefixes_form = PrefixesForm(available_prefixes, initial={"prefix": available_prefixes[0][0]}) \
                            if available_prefixes else None
        new_name_forms = [NewNameForm(request.user, "", sample, prefix=str(sample.pk)) for sample in samples]
    return render(request, "samples/bulk_rename.html",
                  {"title": _("Rename samples"),
                   "prefixes": prefixes_form, "single_prefix": single_prefix,
                   "samples": list(zip(samples, new_name_forms))})
Пример #49
0
def edit_preferences(request, login_name):
    """View for editing preferences of a user.  Note that by giving the
    ``login_name`` explicitly, it is possible to edit the preferences of
    another user.  However, this is only allowed to staff.  The main reason for
    this explicitness is to be more “RESTful”.

    You can't switch the prefered language here because there are the flags
    anyway.

    Moreover, for good reason, you can't change your real name here.  This is
    taken automatically from the domain database through LDAP.  I want to give
    as few options as possible in order to avoid misbehaviour.

    :param request: the current HTTP Request object
    :param login_name: the login name of the user who's preferences should be
        edited.

    :type request: HttpRequest
    :type login_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    def __change_folded_processes(default_folded_process_classes, user):
        """Creates the new exceptional processes dictionary and saves it into the user details.
        """
        old_default_classes = set(cls.id for cls in ContentType.objects.filter(dont_show_to_user=user.samples_user_details))
        new_default_classes = set(int(class_id) for class_id in default_folded_process_classes if class_id)
        differences = old_default_classes ^ new_default_classes
        exceptional_processes_dict = json.loads(user.samples_user_details.folded_processes)
        for process_id_list in exceptional_processes_dict.values():
            for process_id in copy.copy(process_id_list):
                try:
                    if models.Process.objects.get(pk=process_id).content_type.id in differences:
                        process_id_list.remove(process_id)
                except models.Process.DoesNotExist:
                    # FixMe: the missing process should be removed from the exceptional_processes_dict
                    pass
        user.samples_user_details.folded_processes = json.dumps(exceptional_processes_dict)
        user.samples_user_details.save()

    user = get_object_or_404(django.contrib.auth.models.User, username=login_name)
    if not request.user.is_superuser and request.user != user:
        raise permissions.PermissionError(request.user, _("You can't access the preferences of another user."))
    initials_mandatory = request.GET.get("initials_mandatory") == "True"
    user_details = user.samples_user_details
    if request.method == "POST":
        user_details_form = UserDetailsForm(user, request.POST, instance=user_details)
        initials_form = utils.InitialsForm(user, initials_mandatory, request.POST)
        if user_details_form.is_valid() and initials_form.is_valid():
            __change_folded_processes(user_details_form.cleaned_data["default_folded_process_classes"], user)
            user_details = user_details_form.save(commit=False)
            user_details.show_users_from_departments = Department.objects.filter(id__in=
                                                        user_details_form.cleaned_data["show_users_from_departments"])
            user_details.default_folded_process_classes = [ContentType.objects.get_for_id(int(id_))
                 for id_ in user_details_form.cleaned_data["default_folded_process_classes"]]
            user_details.save()
            initials_form.save()
            return utils.successful_response(request, _("The preferences were successfully updated."))
    else:
        user_details_form = UserDetailsForm(user, instance=user_details)
        initials_form = utils.InitialsForm(user, initials_mandatory)
    return render(request, "samples/edit_preferences.html",
                  {"title": _("Change preferences for {user_name}").format(user_name=get_really_full_name(request.user)),
                   "user_details": user_details_form, "initials": initials_form,
                   "has_topics": user.topics.exists()})
Пример #50
0
def edit_preferences(request, login_name):
    """View for editing preferences of a user.  Note that by giving the
    ``login_name`` explicitly, it is possible to edit the preferences of
    another user.  However, this is only allowed to staff.  The main reason for
    this explicitness is to be more “RESTful”.

    You can't switch the prefered language here because there are the flags
    anyway.

    Moreover, for good reason, you can't change your real name here.  This is
    taken automatically from the domain database through LDAP.  I want to give
    as few options as possible in order to avoid misbehaviour.

    :param request: the current HTTP Request object
    :param login_name: the login name of the user who's preferences should be
        edited.

    :type request: HttpRequest
    :type login_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    def __change_folded_processes(default_folded_process_classes, user):
        """Creates the new exceptional processes dictionary and saves it into the user details.
        """
        old_default_classes = set(cls.id for cls in ContentType.objects.filter(dont_show_to_user=user.samples_user_details))
        new_default_classes = set(map(int, default_folded_process_classes))
        differences = old_default_classes ^ new_default_classes
        exceptional_processes_dict = json.loads(user.samples_user_details.folded_processes)
        for process_id_list in exceptional_processes_dict.values():
            for process_id in copy.copy(process_id_list):
                try:
                    if models.Process.objects.get(pk=process_id).content_type.id in differences:
                        process_id_list.remove(process_id)
                except models.Process.DoesNotExist:
                    # FixMe: the missing process should be removed from the exceptional_processes_dict
                    pass
        user.samples_user_details.folded_processes = json.dumps(exceptional_processes_dict)
        user.samples_user_details.save()

    user = get_object_or_404(django.contrib.auth.models.User, username=login_name)
    if not request.user.is_superuser and request.user != user:
        raise permissions.PermissionError(request.user, _("You can't access the preferences of another user."))
    initials_mandatory = request.GET.get("initials_mandatory") == "True"
    user_details = user.samples_user_details
    if request.method == "POST":
        user_details_form = UserDetailsForm(user, request.POST, instance=user_details)
        initials_form = utils.InitialsForm(user, initials_mandatory, request.POST)
        if user_details_form.is_valid() and initials_form.is_valid():
            __change_folded_processes(user_details_form.cleaned_data["default_folded_process_classes"], user)
            user_details = user_details_form.save(commit=False)
            user_details.show_users_from_departments = Department.objects.filter(id__in=
                                                        user_details_form.cleaned_data["show_users_from_departments"])
            user_details.default_folded_process_classes = [ContentType.objects.get_for_id(int(id_))
                 for id_ in user_details_form.cleaned_data["default_folded_process_classes"]]
            user_details.save()
            initials_form.save()
            return utils.successful_response(request, _("The preferences were successfully updated."))
    else:
        user_details_form = UserDetailsForm(user, instance=user_details)
        initials_form = utils.InitialsForm(user, initials_mandatory)
    return render(request, "samples/edit_preferences.html",
                  {"title": _("Change preferences for {user_name}").format(user_name=get_really_full_name(request.user)),
                   "user_details": user_details_form, "initials": initials_form,
                   "has_topics": user.topics.exists()})
Пример #51
0
def bulk_rename(request):
    """View for bulk-renaming samples that have had a provisional name so far.  If
    the user doesn't have initials yet, he is redirected to his preferences
    page.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    # FixMe: Get rid of the "numbers" parameter.  I think it is only used in
    # the remote client.
    if "numbers" in request.GET:
        numbers_list = request.GET.get("numbers", "")
        samples = [get_object_or_404(models.Sample, name="*" + number.zfill(5)) for number in numbers_list.split(",")]
    elif "ids" in request.GET:
        ids = request.GET["ids"].split(",")
        samples = [get_object_or_404(models.Sample, pk=utils.convert_id_to_int(id_)) for id_ in ids]
        if not all(utils.sample_name_format(sample.name) in utils.get_renamable_name_formats() for sample in samples):
            raise Http404("Some given samples cannot be renamed.")
    else:
        samples = None
    if not samples:
        raise Http404("No samples given.")
    for sample in samples:
        permissions.assert_can_edit_sample(request.user, sample)

    available_prefixes = find_prefixes(request.user)
    if not available_prefixes and any("{user_initials}" in format_ for format_ in settings.NAME_PREFIX_TEMPLATES) \
       and not models.Initials.objects.filter(user=request.user).exists():
        query_string = "initials_mandatory=True&next=" + django.utils.http.urlquote_plus(
            request.path + "?" + request.META["QUERY_STRING"], safe="/")
        messages.info(request, _("You may change the sample names, but you must choose initials first."))
        return utils.successful_response(request, view="samples.views.user_details.edit_preferences",
                                         kwargs={"login_name": request.user.username},
                                         query_string=query_string, forced=True)
    single_prefix = available_prefixes[0][1] if len(available_prefixes) == 1 else None
    if request.method == "POST":
        if single_prefix:
            prefixes_form = None
            prefix = single_prefix
        elif available_prefixes:
            prefixes_form = PrefixesForm(available_prefixes, request.POST)
            prefix = prefixes_form.cleaned_data["prefix"] if prefixes_form.is_valid() else ""
        else:
            prefixes_form = None
            prefix = ""
        if prefix == "*":
            prefix = ""
        new_name_forms = [NewNameForm(request.user, prefix, sample, request.POST, prefix=str(sample.pk))
                          for sample in samples]
        all_valid = prefixes_form is None or prefixes_form.is_valid()
        all_valid = all([new_name_form.is_valid() for new_name_form in new_name_forms]) and all_valid
        referentially_valid = is_referentially_valid(samples, new_name_forms)
        if all_valid and referentially_valid:
            for sample, new_name_form in zip(samples, new_name_forms):
                if not sample.name.startswith("*"):
                    models.SampleAlias(name=sample.name, sample=sample).save()
                sample.name = new_name_form.cleaned_data["name"]
                sample.save()
            return utils.successful_response(request, _("Successfully renamed the samples."))
    else:
        prefixes_form = PrefixesForm(available_prefixes, initial={"prefix": available_prefixes[0][0]}) \
                            if available_prefixes else None
        new_name_forms = [NewNameForm(request.user, "", sample, prefix=str(sample.pk)) for sample in samples]
    return render(request, "samples/bulk_rename.html",
                  {"title": _("Rename samples"),
                   "prefixes": prefixes_form, "single_prefix": single_prefix,
                   "samples": list(zip(samples, new_name_forms))})
Пример #52
0
def add(request):
    """View for adding new samples.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    user = request.user
    if request.method == "POST":
        add_samples_form = AddSamplesForm(user, request.POST)
        if add_samples_form.is_valid():
            # FixMe: Find more reliable way to find stared sample names
            max_cycles = 10
            while max_cycles > 0:
                max_cycles -= 1
                try:
                    savepoint_without_samples = transaction.savepoint()
                    new_names, samples = add_samples_to_database(
                        add_samples_form, user)
                except IntegrityError:
                    if max_cycles > 0:
                        transaction.savepoint_rollback(
                            savepoint_without_samples)
                    else:
                        raise
                else:
                    break
            ids = [sample.pk for sample in samples]
            utils.Reporter(user).report_new_samples(samples)
            if add_samples_form.cleaned_data["topic"]:
                for watcher in (user_details.user
                                for user_details in add_samples_form.
                                cleaned_data["topic"].auto_adders.all()):
                    for sample in samples:
                        watcher.my_samples.add(sample)
            if len(new_names) > 1:
                success_report = \
                    _("Your samples have the names from {first_name} to {last_name}.  "
                      "They were added to “My Samples”.").format(first_name=new_names[0], last_name=new_names[-1])
            else:
                success_report = _("Your sample has the name {name}.  It was added to “My Samples”."). \
                    format(name=new_names[0])
            if add_samples_form.cleaned_data["rename"] == "new-style":
                return utils.successful_response(
                    request,
                    success_report,
                    "samples:bulk_rename",
                    query_string="ids=" + ",".join(str(id_) for id_ in ids),
                    forced=True,
                    json_response=ids)
            else:
                return utils.successful_response(request,
                                                 success_report,
                                                 json_response=ids)
    else:
        add_samples_form = AddSamplesForm(user)
    return render(
        request, "samples/add_samples.html", {
            "title": _("Add samples"),
            "add_samples": add_samples_form,
            "external_operators_available": user.external_contacts.exists()
        })
Пример #53
0
def add_oldstyle(request, username):
    """View for adding a new claim to old-style sample names.  This is a nice
    example of a view of the app “samples” which is *extended* in the institute
    app.  The template – in this case,
    :file:`institute/templates/samples/list_claims.html` – overrides and extends the
    default one, and adds a link to a URL listed in institute's URLconf and pointing
    to this view function.

    The important step is the template.  This is the hook for your extensions.
    You override the template from “samples” by creating a file called the same
    in :file:`institute/templates/samples/`.  Because ``TEMPLATE_DIRS`` and
    ``TEMPLATE_LOADERS`` are defined as recommended in
    :doc:`/programming/settings`, it shadows its counterpart.  By giving the
    full path, you can still access the original.  Thus, you may start your
    template with

    ::

        {% extends "samples/templates/samples/list_claims.html" %}

    in order to extend it.

    The `username` parameter of this view function is actually superfluous
    because it must be the currently logged-in user anyway.  But this way, we
    don't get into trouble if a user happens to be called ``"add"``.
    Additionally, the URLs become RESTful.

    :param request: the current HTTP Request object
    :param username: the name of the user whose claim this will be; it must be
        the currently logged-in user

    :type request: HttpRequest
    :type username: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    _ = ugettext
    user = get_object_or_404(django.contrib.auth.models.User,
                             username=username)
    if user != request.user:
        raise permissions.PermissionError(
            request.user,
            _("You are not allowed to add a claim in another user's name."))
    if request.method == "POST":
        samples_form = SamplesForm(request.POST)
        substrate_form = SubstrateForm(request.POST)
        reviewer_form = ReviewerForm(request.POST)
        if samples_form.is_valid() and substrate_form.is_valid(
        ) and reviewer_form.is_valid():
            reviewer = reviewer_form.cleaned_data["reviewer"]
            claim = SampleClaim(requester=user, reviewer=reviewer)
            claim.save()
            _ = lambda x: x
            send_email(
                _("Sample request from {requester}"),
                _("""Hello {reviewer},

{requester} wants to become the new “currently responsible person”
of one or more samples.  Please visit

    {url}

for reviewing this request.  If you don't want or cannot approve
the request, please contact {requester} directly and ask him or her
to withdraw the request.

JuliaBase.
"""), reviewer, {
                    "reviewer":
                    get_really_full_name(reviewer),
                    "requester":
                    get_really_full_name(user),
                    "url":
                    request.build_absolute_uri(
                        django.core.urlresolvers.reverse(
                            "samples.views.claim.show",
                            kwargs={"claim_id": claim.pk}))
                })
            _ = ugettext
            samples = []
            nobody = django.contrib.auth.models.User.objects.get(
                username="******")
            legacy = Topic.objects.get(name="Legacy")
            now = datetime.datetime.now()
            material, substrate_comments = substrate_form.cleaned_data[
                "material"], substrate_form.cleaned_data["comments"]
            for name in samples_form.cleaned_data["samples"]:
                substrate = models.Substrate(operator=nobody,
                                             timestamp=now,
                                             material=material,
                                             comments=substrate_comments)
                substrate.save()
                sample = Sample(name=name,
                                current_location="unknown",
                                currently_responsible_person=nobody,
                                topic=legacy)
                sample.save()
                sample.processes.add(substrate)
                samples.append(sample)
            claim.samples = samples
            return utils.successful_response(
                request,
                _("Sample claim {id_} was successfully submitted.").format(
                    id_=claim.pk),
                "samples.views.claim.show",
                kwargs={"claim_id": claim.pk})
    else:
        samples_form = SamplesForm()
        substrate_form = SubstrateForm()
        reviewer_form = ReviewerForm()
    return render(
        request, "samples/add_claim_oldstyle.html", {
            "title": _("Assert claim"),
            "samples": samples_form,
            "substrate": substrate_form,
            "reviewer": reviewer_form
        })
Пример #54
0
def show(request, claim_id):
    """View for reviewing a claim.

    :param request: the current HTTP Request object
    :param claim_id: the primary key of the claim to be viewed

    :type request: HttpRequest
    :type claim_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    _ = ugettext
    claim = get_object_or_404(models.SampleClaim, pk=utils.convert_id_to_int(claim_id))
    is_reviewer = request.user == claim.reviewer or request.user.is_superuser
    is_requester = request.user == claim.requester
    if not is_reviewer and not is_requester:
        raise permissions.PermissionError(request.user, _("You are neither the requester nor the reviewer of this claim."))
    if request.method == "POST" and not claim.closed:
        withdraw_form = CloseForm(_("withdraw claim"), request.POST, prefix="withdraw") if is_requester else None
        approve_form = CloseForm(_("approve claim"), request.POST, prefix="approve") if is_reviewer else None
        all_valid = (withdraw_form is None or withdraw_form.is_valid()) and (approve_form is None or approve_form.is_valid())
        referencially_valid = is_referentially_valid(withdraw_form, approve_form)
        if all_valid and referencially_valid:
            approved = approve_form and approve_form.cleaned_data["close"]
            closed = approved or (withdraw_form and withdraw_form.cleaned_data["close"])
            response = None
            if approved:
                sample_list = list(claim.samples.all())
                for sample in sample_list:
                    sample.currently_responsible_person = claim.requester
                    sample.save()
                sample_enumeration = "    " + ",\n    ".join(six.text_type(sample) for sample in sample_list)
                _ = lambda x: x
                send_email(_("Sample request approved"),
                       _("""Hello {requester},

your sample claim was approved.  You are now the “currently
responsible person” of the following samples:

{samples}

JuliaBase.
"""), claim.requester, {"requester": get_really_full_name(claim.requester), "samples": sample_enumeration})
                _ = ugettext
                response = \
                    utils.successful_response(request,
                                              _("Sample claim {id_} was successfully approved.").format(id_=claim.pk))
            if closed:
                claim.closed = True
                claim.save()
                response = response or \
                    utils.successful_response(request,
                                              _("Sample claim {id_} was successfully withdrawn.").format(id_=claim.pk))
            return response
    else:
        withdraw_form = CloseForm(_("withdraw claim"), prefix="withdraw") if is_requester else None
        approve_form = CloseForm(_("approve claim"), prefix="approve") if is_reviewer else None
    return render(request, "samples/show_claim.html", {"title": _("Claim #{number}").format(number=claim_id),
                                                       "claim": claim, "is_reviewer": is_reviewer,
                                                       "is_requester": is_requester,
                                                       "withdraw": withdraw_form, "approve": approve_form})
Пример #55
0
def add_oldstyle(request, username):
    """View for adding a new claim to old-style sample names.  This is a nice
    example of a view of the app “samples” which is *extended* in the institute
    app.  The template – in this case,
    :file:`institute/templates/samples/list_claims.html` – overrides and extends the
    default one, and adds a link to a URL listed in institute's URLconf and pointing
    to this view function.

    The important step is the template.  This is the hook for your extensions.
    You override the template from “samples” by creating a file called the same
    in :file:`institute/templates/samples/`.  Because ``DIRS`` and ``loaders``
    are defined as recommended in :doc:`/programming/settings`, it shadows its
    counterpart.  By giving the full path, you can still access the original.
    Thus, you may start your template with

    ::

        {% extends "samples/templates/samples/list_claims.html" %}

    in order to extend it.

    The `username` parameter of this view function is actually superfluous
    because it must be the currently logged-in user anyway.  But this way, we
    don't get into trouble if a user happens to be called ``"add"``.
    Additionally, the URLs become RESTful.

    :param request: the current HTTP Request object
    :param username: the name of the user whose claim this will be; it must be
        the currently logged-in user

    :type request: HttpRequest
    :type username: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    _ = ugettext
    user = get_object_or_404(django.contrib.auth.models.User, username=username)
    if user != request.user:
        raise permissions.PermissionError(request.user, _("You are not allowed to add a claim in another user's name."))
    if request.method == "POST":
        samples_form = SamplesForm(request.POST)
        substrate_form = SubstrateForm(request.POST)
        reviewer_form = ReviewerForm(request.POST)
        if samples_form.is_valid() and substrate_form.is_valid() and reviewer_form.is_valid():
            reviewer = reviewer_form.cleaned_data["reviewer"]
            claim = SampleClaim(requester=user, reviewer=reviewer)
            claim.save()
            _ = lambda x: x
            send_email(_("Sample request from {requester}"),
                       _("""Hello {reviewer},

{requester} wants to become the new “currently responsible person”
of one or more samples.  Please visit

    {url}

for reviewing this request.  If you don't want or cannot approve
the request, please contact {requester} directly and ask him or her
to withdraw the request.

JuliaBase.
"""), reviewer, {"reviewer": get_really_full_name(reviewer), "requester": get_really_full_name(user),
                 "url": request.build_absolute_uri(django.core.urlresolvers.reverse("samples.views.claim.show",
                                                                                    kwargs={"claim_id": claim.pk}))})
            _ = ugettext
            samples = []
            nobody = django.contrib.auth.models.User.objects.get(username="******")
            legacy = Topic.objects.get(name="Legacy")
            now = datetime.datetime.now()
            material, substrate_comments = substrate_form.cleaned_data["material"], substrate_form.cleaned_data["comments"]
            for name in samples_form.cleaned_data["samples"]:
                substrate = models.Substrate(operator=nobody, timestamp=now, material=material, comments=substrate_comments)
                substrate.save()
                sample = Sample(name=name, current_location="unknown", currently_responsible_person=nobody, topic=legacy)
                sample.save()
                sample.processes.add(substrate)
                samples.append(sample)
            claim.samples = samples
            return utils.successful_response(request,
                                             _("Sample claim {id_} was successfully submitted.").format(id_=claim.pk),
                                             "samples.views.claim.show", kwargs={"claim_id": claim.pk})
    else:
        samples_form = SamplesForm()
        substrate_form = SubstrateForm()
        reviewer_form = ReviewerForm()
    return render(request, "samples/add_claim_oldstyle.html", {"title": _("Assert claim"), "samples": samples_form,
                                                               "substrate": substrate_form, "reviewer": reviewer_form})
Пример #56
0
def edit(request, task_id):
    """Edit or create a task.

    :param request: the current HTTP Request object
    :param task_id: number of the task to be edited.  If this is
        ``None``, create a new one.

    :type request: HttpRequest
    :type task_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    task = get_object_or_404(
        Task, id=utils.convert_id_to_int(task_id)) if task_id else None
    user = request.user
    if task and user != task.customer:
        permissions.assert_can_add_physical_process(
            request.user, task.process_class.model_class())
    preset_sample = utils.extract_preset_sample(
        request) if not task_id else None
    if request.method == "POST":
        task_form = TaskForm(user, request.POST, instance=task)
        samples_form = SamplesForm(user, preset_sample, task, request.POST)
        if task_id:
            old_task = copy.copy(task)
            old_samples = set(task.samples.all())
        if task_form.is_valid() and (not samples_form.is_bound
                                     or samples_form.is_valid()):
            task = save_to_database(task_form,
                                    samples_form,
                                    old_task=old_task if task_id else None)
            if task_id:
                edit_description = {"important": True, "description": ""}
                if old_task.status != task.status:
                    edit_description["description"] += \
                        _("* Status is now “{new_status}”.\n").format(new_status=task.get_status_display())
                if old_task.priority != task.priority:
                    edit_description["description"] += \
                        _("* Priority is now “{new_priority}̣”.\n").format(new_priority=task.get_priority_display())
                if old_task.finished_process != task.finished_process:
                    edit_description["description"] += _(
                        "* Connected process.\n")
                if old_task.operator != task.operator:
                    if task.operator:
                        edit_description["description"] += _(
                            "* Operator is now {operator}.\n").format(
                                operator=common_utils.get_really_full_name(
                                    task.operator))
                    else:
                        edit_description["description"] += _(
                            "* No operator is set anymore.\n")
                if old_samples != set(task.samples.all()):
                    edit_description["description"] += "* {0}.\n".format(
                        common_utils.capitalize_first_letter(_("samples")))
                if old_task.comments != task.comments:
                    edit_description["description"] += "* {0}.\n".format(
                        common_utils.capitalize_first_letter(_("comments")))
            else:
                edit_description = None
            utils.Reporter(request.user).report_task(task, edit_description)
            message = _("Task was {verb} successfully.").format(
                verb=_("edited") if task_id else _("added"))
            return utils.successful_response(request, message,
                                             "samples:show_task_lists")
    else:
        samples_form = SamplesForm(user, preset_sample, task)
        initial = {}
        if "process_class" in request.GET:
            initial["process_class"] = request.GET["process_class"]
        task_form = TaskForm(request.user, instance=task, initial=initial)
    title = capfirst(_("edit task")) if task else capfirst(_("add task"))
    return render(request, "samples/edit_task.html", {
        "title": title,
        "task": task_form,
        "samples": samples_form
    })