Beispiel #1
0
def inform_process_supervisors(sender, instance, **kwargs):
    """Send an email to the supervisors of an apparatus when a user creates
    his or her first process of this apparatus.  If no supervisors are found,
    the administrators are emailed.
    """
    # FixMe: The following line is only necessary as long as
    # http://code.djangoproject.com/ticket/9318 is not fixed.  When it is
    # fixed, this function must be connected only with senders of
    # ``PhysicalProcess``.  If this is not possible because ``PhysicalProcess``
    # is abstract, this line must stay, and this function must be connected
    # with senders of ``Process`` only.  The check ``raw==False`` must stay,
    # though.
    _ = ugettext
    if not kwargs.get("raw") and isinstance(instance, PhysicalProcess) and instance.finished:
        user = instance.operator
        process_class = instance.__class__
        if not process_class.objects.filter(operator=user).exists():
            try:
                permission = django.contrib.auth.models.Permission.objects.get(
                    codename="edit_permissions_for_{0}".format(process_class.__name__.lower()),
                    content_type=ContentType.objects.get_for_model(process_class))
            except django.contrib.auth.models.Permission.DoesNotExist:
                return
            recipients = list(django.contrib.auth.models.User.objects.filter(user_permissions=permission)) or \
                list(django.contrib.auth.models.User.objects.filter(is_superuser=True).exclude(email=""))
            if recipients:
                _ = lambda x: x
                utils.send_email(_(u"{user_name} uses {apparatus}"),
                                 _(u"Dear supervisors of {apparatus_plural},\n\n{user_name} has "
                                   u"created their first {apparatus}.\n"), recipients,
                                 {"apparatus_plural": process_class._meta.verbose_name_plural,
                                  "apparatus": process_class._meta.verbose_name,
                                  "user_name": utils.get_really_full_name(user)})
Beispiel #2
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})
Beispiel #3
0
def inform_process_supervisors(sender, instance, **kwargs):
    """Send an email to the supervisors of an apparatus when a user creates
    his or her first process of this apparatus.  If no supervisors are found,
    the administrators are emailed.
    """
    # FixMe: The following line is only necessary as long as
    # http://code.djangoproject.com/ticket/9318 is not fixed.  When it is
    # fixed, this function must be connected only with senders of
    # ``PhysicalProcess``.  If this is not possible because ``PhysicalProcess``
    # is abstract, this line must stay, and this function must be connected
    # with senders of ``Process`` only.  The check ``raw==False`` must stay,
    # though.
    _ = ugettext
    if not kwargs.get("raw") and isinstance(
            instance, PhysicalProcess) and instance.finished:
        user = instance.operator
        process_class = instance.__class__
        if not process_class.objects.filter(operator=user).exists():
            try:
                permission = django.contrib.auth.models.Permission.objects.get(
                    codename="edit_permissions_for_{0}".format(
                        process_class.__name__.lower()),
                    content_type=ContentType.objects.get_for_model(
                        process_class))
            except django.contrib.auth.models.Permission.DoesNotExist:
                return
            recipients = list(django.contrib.auth.models.User.objects.filter(user_permissions=permission)) or \
                list(django.contrib.auth.models.User.objects.filter(is_staff=True).exclude(email=""))
            if recipients:
                _ = lambda x: x
                utils.send_email(
                    _(u"{user_name} uses {apparatus}"),
                    _(u"Dear supervisors of {apparatus_plural},\n\n{user_name} has "
                      u"created their first {apparatus}.\n"), recipients, {
                          "apparatus_plural":
                          process_class._meta.verbose_name_plural,
                          "apparatus": process_class._meta.verbose_name,
                          "user_name": utils.get_really_full_name(user)
                      })
Beispiel #4
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
        })
Beispiel #5
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})
Beispiel #6
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})
Beispiel #7
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
        })
Beispiel #8
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
        })