Пример #1
0
def list_(request, username):
    """View for listing claim, both those with you being the requester and the
    reviewer.  The ``username`` parameter is actually superfluous because it
    must be the currently logged-in user anyway.  But this way, it is more
    consistent and more RESTful.

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

    :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 user != request.user and not user.is_staff:
        raise permissions.PermissionError(
            request.user,
            _("You are not allowed to see claims of another user."))
    return render(
        request, "samples/list_claims.html", {
            "title":
            _("Claims for {user}").format(user=get_really_full_name(user)),
            "claims": user.claims.filter(closed=False),
            "claims_as_reviewer": user.claims_as_reviewer.filter(closed=False)
        })
Пример #2
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
        })
Пример #3
0
def topics_and_permissions(request, login_name):
    user = get_object_or_404(django.contrib.auth.models.User, username=login_name)
    if not request.user.is_staff and request.user != user:
        raise permissions.PermissionError(
            request.user, _("You can't access the list of topics and permissions of another user."))
    return render(request, "samples/topics_and_permissions.html",
                  {"title": _("Topics and permissions for {user_name}").format(user_name=get_really_full_name(request.user)),
                   "topics": user.topics.all(), "managed_topics": user.managed_topics.all(),
                   "permissions": permissions.get_user_permissions(user),
                   "full_user_name": get_really_full_name(request.user),
                   "permissions_url": django.core.urlresolvers.reverse("samples.views.permissions.list_")})
Пример #4
0
def topics_and_permissions(request, login_name):
    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 list of topics and permissions of another user."))
    if jb_common_utils.is_json_requested(request):
        return jb_common_utils.respond_in_json((user.topics.values_list("pk", flat=True),
                                                user.managed_topics.values_list("pk", flat=True),
                                                user.get_all_permissions()))
    return render(request, "samples/topics_and_permissions.html",
                  {"title": _("Topics and permissions for {user_name}").format(user_name=get_really_full_name(request.user)),
                   "topics": user.topics.all(), "managed_topics": user.managed_topics.all(),
                   "permissions": permissions.get_user_permissions(user),
                   "full_user_name": get_really_full_name(request.user),
                   "permissions_url": django.core.urlresolvers.reverse("samples:list_permissions")})
Пример #5
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})
Пример #6
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")
Пример #7
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
    })
Пример #8
0
def available_items(request, model_name):
    """Returns the unique ids of all items that are already in the database for
    this model.  The point is that it will return primary keys only as a
    fallback.  Instead, it returns the “official” id of the respective model,
    represented by the `JBMeta.identifying_field` attribute, if given.  This
    may be the number of a deposition, or the number of a measurement run, etc.

    :param request: the current HTTP Request object
    :param model_name: the name of the database model

    :type request: HttpRequest
    :type model_name: unicode

    :return:
      The HTTP response object.  It is a JSON list object with all the ids of
      the objects in the database for the model.

    :rtype: HttpResponse
    """
    if not request.user.is_staff:
        raise permissions.PermissionError(
            request.user,
            _("Only the administrator can access this resource."))
    # FixMe: This must be revisited; it is ugly.
    for app_name in settings.INSTALLED_APPS:
        try:
            model = sys.modules[app_name + ".models"].__dict__[model_name]
        except KeyError:
            continue
        break
    else:
        raise Http404("Model name not found.")
    try:
        pk = model.JBMeta.identifying_field
    except AttributeError:
        pk = "pk"
    return respond_in_json(list(model.objects.values_list(pk, flat=True)))
Пример #9
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
        })
Пример #10
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()})
Пример #11
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
        })
Пример #12
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
        })