コード例 #1
0
ファイル: claim.py プロジェクト: msincan/juliabase
 def clean_samples(self):
     sample_names = self.cleaned_data["samples"].split(",")
     valid_names = []
     invalid_names = []
     for name in sample_names:
         name = name.strip()
         if name:
             if utils.sample_name_format(name) == "old":
                 if name in valid_names:
                     raise ValidationError(_("The name {name} appears more than once.").format(name=name))
                 valid_names.append(name)
             else:
                 invalid_names.append(name)
     if invalid_names:
         error_message = ungettext(
             "The name {invalid_names} is not valid.", "The names {invalid_names} are not valid.",
             len(invalid_names)).format(invalid_names=format_enumeration(invalid_names))
         raise ValidationError(error_message)
     if not valid_names:
         raise ValidationError(self.fields["samples"].error_messages["required"])
     existing_names = [name for name in valid_names if utils.does_sample_exist(name)]
     if existing_names:
         # This opens a small security hole because people can find out that
         # confidential samples are existing.  However, such samples mostly
         # have non-oldstyle names anyway.
         error_message = ungettext(
             "The name {existing_names} is already existing.", "The names {existing_names} are already existing.",
             len(existing_names)).format(existing_names=format_enumeration(existing_names))
         raise ValidationError(error_message)
     return valid_names
コード例 #2
0
 def clean_new_name(self):
     new_name = self.cleaned_data["new_name"]
     sample_name_format, match = utils.sample_name_format(
         new_name, with_match_object=True)
     if not sample_name_format:
         raise ValidationError(_("The sample name has an invalid format."))
     elif not new_name.startswith(self.parent_name):
         if sample_name_format not in self.possible_new_name_formats:
             error_message = _(
                 "The new sample name must start with the parent sample's name."
             )
             if self.possible_new_name_formats:
                 further_error_message = ungettext(
                     "  Alternatively, it must be a valid “{sample_formats}” name.",
                     "  Alternatively, it must be a valid name of one of these types: "
                     "{sample_formats}",
                     len(self.possible_new_name_formats))
                 further_error_message = further_error_message.format(
                     sample_formats=format_enumeration(
                         utils.verbose_sample_name_format(name_format)
                         for name_format in self.possible_new_name_formats))
                 error_message += further_error_message
             raise ValidationError(error_message)
         utils.check_sample_name(match, self.user)
     if utils.does_sample_exist(new_name):
         raise ValidationError(_("Name does already exist in database."))
     return new_name
コード例 #3
0
 def clean_new_name(self):
     if "sample" in self.cleaned_data:
         new_name = self.cleaned_data["new_name"]
         if new_name != self.cleaned_data["sample"].name and utils.does_sample_exist(new_name):
             raise ValidationError(_("This sample name exists already."))
         elif utils.sample_name_format(new_name) == "provisional":
             raise ValidationError(_("You must get rid of the provisional sample name."))
         return new_name
コード例 #4
0
ファイル: split_and_rename.py プロジェクト: msincan/juliabase
 def __init__(self, user, parent_name, *args, **kwargs):
     super(NewNameForm, self).__init__(*args, **kwargs)
     self.parent_name = parent_name
     parent_name_format = utils.sample_name_format(parent_name)
     if parent_name_format:
         self.possible_new_name_formats = settings.SAMPLE_NAME_FORMATS[parent_name_format].get("possible_renames", set())
     else:
         self.possible_new_name_formats = set()
     self.user = user
コード例 #5
0
ファイル: json_client.py プロジェクト: msincan/juliabase
def add_sample(request):
    """Adds a new sample to the database.  It is added without processes.  This
    view can only be used by admin accounts.

    :param request: the current HTTP Request object; it must contain the sample
        data in the POST data.

    :return:
      The primary key of the created sample.  ``False`` if something went
      wrong.  It may return a 404 if the topic or the currently responsible
      person wasn't found.

    :rtype: HttpResponse
    """
    try:
        name = request.POST["name"]
        current_location = request.POST["current_location"]
        currently_responsible_person = request.POST["currently_responsible_person"]
        purpose = request.POST.get("purpose", "")
        tags = request.POST.get("tags", "")
        topic = request.POST.get("topic")
    except KeyError as error:
        raise JSONRequestException(3, "'{}' parameter missing.".format(error.args[0]))
    if len(name) > 30:
        raise JSONRequestException(5, "The sample name is too long.")
    name_format = utils.sample_name_format(name)
    if name_format is None or \
       not request.user.is_superuser and \
       name_format not in settings.SAMPLE_NAME_FORMATS["provisional"].get("possible_renames", set()):
        raise JSONRequestException(5, "The sample name is invalid.")
    eligible_users = django.contrib.auth.models.User.objects.filter(is_active=True, jb_user_details__department__isnull=False)
    try:
        currently_responsible_person = eligible_users.get(pk=utils.convert_id_to_int(currently_responsible_person))
    except django.contrib.auth.models.User.DoesNotExist:
        raise Http404("Currently reponsible user not found.")
    if topic:
        all_topics = Topic.objects.all() if request.user.is_superuser else \
                     Topic.objects.filter(Q(confidential=False) | Q(members=request.user))
        try:
            topic = all_topics.get(pk=utils.convert_id_to_int(topic))
        except Topic.DoesNotExist:
            raise Http404("Topic not found")
    try:
        sample = models.Sample.objects.create(name=name, current_location=current_location,
                                              currently_responsible_person=currently_responsible_person, purpose=purpose,
                                              tags=tags, topic=topic)
        # They will be shadowed anyway.  Nevertheless, this action is an
        # emergency measure.  Probably the samples the aliases point to should
        # be merged with the sample but this can't be decided automatically.
        models.SampleAlias.objects.filter(name=name).delete()
    except IntegrityError as error:
        error_message = "The sample with this data could not be added."
        if request.user.is_superuser:
            error_message += " {}".format(error)
        raise JSONRequestException(5, error_message)
    sample.watchers.add(request.user)
    return respond_in_json(sample.pk)
コード例 #6
0
 def __init__(self, user, parent_name, *args, **kwargs):
     super(NewNameForm, self).__init__(*args, **kwargs)
     self.parent_name = parent_name
     parent_name_format = utils.sample_name_format(parent_name)
     if parent_name_format:
         self.possible_new_name_formats = settings.SAMPLE_NAME_FORMATS[
             parent_name_format].get("possible_renames", set())
     else:
         self.possible_new_name_formats = set()
     self.user = user
コード例 #7
0
 def clean_name(self):
     new_name = self.prefix_ + self.cleaned_data["name"]
     name_format, match = utils.sample_name_format(new_name, with_match_object=True)
     if name_format not in self.possible_new_name_formats:
         error_message = ungettext("New name must be a valid “{sample_formats}” name.",
                                   "New name must be a valid name of one of these types: {sample_formats}",
                                   len(self.possible_new_name_formats))
         error_message = error_message.format(sample_formats=format_enumeration(
             utils.verbose_sample_name_format(name_format) for name_format in self.possible_new_name_formats))
         raise ValidationError(error_message)
     utils.check_sample_name(match, self.user)
     if utils.does_sample_exist(new_name):
         raise ValidationError(_("This sample name exists already."))
     return new_name
コード例 #8
0
 def clean(self):
     cleaned_data = super(OriginalDataForm, self).clean()
     if "new_name" in cleaned_data:
         new_name = cleaned_data["new_name"]
         sample = cleaned_data.get("sample")
         if sample:
             old_sample_name_format = utils.sample_name_format(sample.name)
             if old_sample_name_format not in utils.get_renamable_name_formats():
                 if not new_name.startswith(sample.name):
                     self.add_error("new_name", _("The new name must begin with the old name."))
             elif sample and sample.name != new_name:
                 if not new_name.startswith(self.deposition_number):
                     self.add_error("new_name", _("The new name must begin with the deposition number."))
     return cleaned_data
コード例 #9
0
ファイル: bulk_rename.py プロジェクト: msincan/juliabase
 def clean_name(self):
     new_name = self.prefix_ + self.cleaned_data["name"]
     name_format, match = utils.sample_name_format(new_name, with_match_object=True)
     if name_format not in self.possible_new_name_formats:
         error_message = ungettext("New name must be a valid “{sample_formats}” name.",
                                   "New name must be a valid name of one of these types: {sample_formats}",
                                   len(self.possible_new_name_formats))
         error_message = error_message.format(sample_formats=format_enumeration(
             utils.verbose_sample_name_format(name_format) for name_format in self.possible_new_name_formats))
         raise ValidationError(error_message)
     utils.check_sample_name(match, self.user)
     if utils.does_sample_exist(new_name):
         raise ValidationError(_("This sample name exists already."))
     return new_name
コード例 #10
0
 def new_name(sample):
     try:
         return new_names[sample.id]
     except KeyError:
         if utils.sample_name_format(sample.name) in utils.get_renamable_name_formats():
             name_postfix = ""
             try:
                 sample_positions = json.loads(deposition.sample_positions)
             except AttributeError:
                 pass
             else:
                 if sample_positions and sample_positions.get(str(sample.id)):
                     name_postfix = "-{0}".format(sample_positions[str(sample.id)])
             return deposition.number + name_postfix
         else:
             return sample.name
コード例 #11
0
ファイル: bulk_rename.py プロジェクト: msincan/juliabase
    def __init__(self, user, prefix_, sample, *args, **kwargs):
        """
        :param user: The user that requests the renaming.
        :param prefix_: The prefix to be used.  If, for some reason, there is no
            prefix available, give an empty string.  Validation will then fail,
            however, it would fail for the whole page anyway without a prefix.
        :param sample: The sample to be renamed.

        :type user: django.contrib.auth.models.User
        :type prefix_: str
        :type sample: samples.models.Sample
        """
        super(NewNameForm, self).__init__(*args, **kwargs)
        self.prefix_ = prefix_
        old_name_format = utils.sample_name_format(sample.name)
        if old_name_format:
            self.possible_new_name_formats = settings.SAMPLE_NAME_FORMATS[old_name_format].get("possible_renames", set())
        else:
            self.possible_new_name_formats = set()
        self.user = user
コード例 #12
0
ファイル: split_and_rename.py プロジェクト: msincan/juliabase
 def clean_new_name(self):
     new_name = self.cleaned_data["new_name"]
     sample_name_format, match = utils.sample_name_format(new_name, with_match_object=True)
     if not sample_name_format:
         raise ValidationError(_("The sample name has an invalid format."))
     elif not new_name.startswith(self.parent_name):
         if sample_name_format not in self.possible_new_name_formats:
             error_message = _("The new sample name must start with the parent sample's name.")
             if self.possible_new_name_formats:
                 further_error_message = ungettext("  Alternatively, it must be a valid “{sample_formats}” name.",
                                                   "  Alternatively, it must be a valid name of one of these types: "
                                                   "{sample_formats}", len(self.possible_new_name_formats))
                 further_error_message = further_error_message.format(sample_formats=format_enumeration(
                     utils.verbose_sample_name_format(name_format) for name_format in self.possible_new_name_formats))
                 error_message += further_error_message
             raise ValidationError(error_message)
         utils.check_sample_name(match, self.user)
     if utils.does_sample_exist(new_name):
         raise ValidationError(_("Name does already exist in database."))
     return new_name
コード例 #13
0
    def __init__(self, user, prefix_, sample, *args, **kwargs):
        """
        :param user: The user that requests the renaming.
        :param prefix_: The prefix to be used.  If, for some reason, there is no
            prefix available, give an empty string.  Validation will then fail,
            however, it would fail for the whole page anyway without a prefix.
        :param sample: The sample to be renamed.

        :type user: django.contrib.auth.models.User
        :type prefix_: str
        :type sample: samples.models.Sample
        """
        super(NewNameForm, self).__init__(*args, **kwargs)
        self.prefix_ = prefix_
        old_name_format = utils.sample_name_format(sample.name)
        if old_name_format:
            self.possible_new_name_formats = settings.SAMPLE_NAME_FORMATS[old_name_format].get("possible_renames", set())
        else:
            self.possible_new_name_formats = set()
        self.user = user
コード例 #14
0
ファイル: claim.py プロジェクト: Midnighter/juliabase
 def clean_samples(self):
     sample_names = self.cleaned_data["samples"].split(",")
     valid_names = []
     invalid_names = []
     for name in sample_names:
         name = name.strip()
         if name:
             if utils.sample_name_format(name) == "old":
                 if name in valid_names:
                     raise ValidationError(
                         _("The name {name} appears more than once.").
                         format(name=name))
                 valid_names.append(name)
             else:
                 invalid_names.append(name)
     if invalid_names:
         error_message = ungettext(
             "The name {invalid_names} is not valid.",
             "The names {invalid_names} are not valid.",
             len(invalid_names)).format(
                 invalid_names=format_enumeration(invalid_names))
         raise ValidationError(error_message)
     if not valid_names:
         raise ValidationError(
             self.fields["samples"].error_messages["required"])
     existing_names = [
         name for name in valid_names if utils.does_sample_exist(name)
     ]
     if existing_names:
         # This opens a small security hole because people can find out that
         # confidential samples are existing.  However, such samples mostly
         # have non-oldstyle names anyway.
         error_message = ungettext(
             "The name {existing_names} is already existing.",
             "The names {existing_names} are already existing.",
             len(existing_names)).format(
                 existing_names=format_enumeration(existing_names))
         raise ValidationError(error_message)
     return valid_names
コード例 #15
0
 def clean_new_name(self):
     new_name = self.cleaned_data["new_name"]
     sample_name_format = utils.sample_name_format(new_name)
     if not sample_name_format:
         raise ValidationError(_("The sample name has an invalid format."))
     return new_name
コード例 #16
0
ファイル: views.py プロジェクト: Midnighter/juliabase
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)
コード例 #17
0
ファイル: bulk_rename.py プロジェクト: msincan/juliabase
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))})
コード例 #18
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))})
コード例 #19
0
ファイル: json_client.py プロジェクト: Midnighter/juliabase
def add_sample(request):
    """Adds a new sample to the database.  It is added without processes.  This
    view can only be used by admin accounts.

    :param request: the current HTTP Request object; it must contain the sample
        data in the POST data.

    :return:
      The primary key of the created sample.  ``False`` if something went
      wrong.  It may return a 404 if the topic or the currently responsible
      person wasn't found.

    :rtype: HttpResponse
    """
    try:
        name = request.POST["name"]
        current_location = request.POST["current_location"]
        currently_responsible_person = request.POST[
            "currently_responsible_person"]
        purpose = request.POST.get("purpose", "")
        tags = request.POST.get("tags", "")
        topic = request.POST.get("topic")
    except KeyError as error:
        raise JSONRequestException(
            3, "'{}' parameter missing.".format(error.args[0]))
    if len(name) > 30:
        raise JSONRequestException(5, "The sample name is too long.")
    name_format = utils.sample_name_format(name)
    if name_format is None or \
       not request.user.is_staff and name_format not in settings.SAMPLE_NAME_FORMATS["provisional"].get("possible_renames", set()):
        raise JSONRequestException(5, "The sample name is invalid.")
    eligible_users = django.contrib.auth.models.User.objects.filter(
        is_active=True, jb_user_details__department__isnull=False)
    try:
        currently_responsible_person = eligible_users.get(
            pk=utils.convert_id_to_int(currently_responsible_person))
    except django.contrib.auth.models.User.DoesNotExist:
        raise Http404("Currently reponsible user not found.")
    if topic:
        all_topics = Topic.objects.all() if request.user.is_staff else \
                     Topic.objects.filter(Q(confidential=False) | Q(members=request.user))
        try:
            topic = all_topics.get(pk=utils.convert_id_to_int(topic))
        except Topic.DoesNotExist:
            raise Http404("Topic not found")
    try:
        sample = models.Sample.objects.create(
            name=name,
            current_location=current_location,
            currently_responsible_person=currently_responsible_person,
            purpose=purpose,
            tags=tags,
            topic=topic)
        # They will be shadowed anyway.  Nevertheless, this action is an
        # emergency measure.  Probably the samples the aliases point to should
        # be merged with the sample but this can't be decided automatically.
        models.SampleAlias.objects.filter(name=name).delete()
    except IntegrityError as error:
        error_message = "The sample with this data could not be added."
        if request.user.is_staff:
            error_message += " {}".format(error)
        raise JSONRequestException(5, error_message)
    sample.watchers.add(request.user)
    return respond_in_json(sample.pk)
コード例 #20
0
def is_referentially_valid(original_data_forms, new_name_form_lists, deposition):
    """Test whether all forms are consistent with each other and with the
    database.  For example, no sample name must occur twice, and the sample
    names must not exist within the database already.

    :param original_data_forms: all old samples and pieces numbers
    :param new_name_form_lists: new names for all pieces
    :param deposition: the deposition after which the split takes place

    :type original_data_forms: list of `OriginalDataForm`
    :type new_name_form_lists: list of `NewNameForm`
    :type deposition: `samples.models.Deposition`

    :return:
      whether all forms are consistent with each other and the database

    :rtype: bool
    """
    referentially_valid = True
    samples = list(deposition.samples.all())
    more_than_one_piece = len(original_data_forms) > 1
    new_names = set()
    original_samples = set()
    for original_data_form in original_data_forms:
        if original_data_form.is_valid():
            original_sample = original_data_form.cleaned_data["sample"]
            if original_sample in original_samples:
                original_data_form.add_error("sample",
                                             _("Sample {sample} occurs multiple times.").format(sample=original_sample))
                referentially_valid = False
            original_samples.add(original_sample)
            if original_sample not in samples:
                original_data_form.add_error("sample",
                             _("Sample {sample} doesn't belong to this deposition.").format(sample=original_sample))
                referentially_valid = False
            new_name = original_data_form.cleaned_data["new_name"]
            if new_name in new_names:
                original_data_form.add_error("new_name", _("This sample name has been used already on this page."))
                referentially_valid = False
            new_names.add(new_name)
            if more_than_one_piece and new_name == deposition.number:
                original_data_form.add_error("new_name", _("Since there is more than one piece, the new name "
                                                   "must not be exactly the deposition's name."))
                referentially_valid = False
    if all(original_data_form.is_valid() for original_data_form in original_data_forms):
        assert len(original_samples) <= len(samples)
        if len(original_samples) < len(samples):
            original_data_form.add_error(None, _("At least one sample of the original deposition is missing."))
            referentially_valid = False
    for new_name_forms, original_data_form in zip(new_name_form_lists, original_data_forms):
        if original_data_form.is_valid():
            original_sample = original_data_form.cleaned_data["sample"]
            if deposition != original_sample.processes.exclude(content_type=ContentType.objects.
                                                               get_for_model(models.Result)) \
                .order_by("-timestamp")[0].actual_instance and original_data_form.cleaned_data["number_of_pieces"] > 1:
                original_data_form.add_error("sample",
                     _("The sample can't be split, because the deposition is not the latest process."))
                referentially_valid = False
            else:
                for new_name_form in new_name_forms:
                    if new_name_form.is_valid():
                        new_name = new_name_form.cleaned_data["new_name"]
                        if original_data_form.cleaned_data["number_of_pieces"] == 1:
                            if new_name != original_data_form.cleaned_data["new_name"]:
                                new_name_form.add_error("new_name",
                                                        _("If you don't split, you can't rename the single piece."))
                                referentially_valid = False
                        else:
                            if new_name in new_names:
                                new_name_form.add_error("new_name",
                                                        _("This sample name has been used already on this page."))
                                referentially_valid = False
                            new_names.add(new_name)
                            if utils.sample_name_format(new_name) in utils.get_renamable_name_formats() and \
                                    not new_name.startswith(original_data_form.cleaned_data["new_name"]):
                                new_name_form.add_error("new_name", _("If you choose a deposition-style name, it must begin "
                                                              "with the parent's new name."))
                                referentially_valid = False
                            if utils.does_sample_exist(new_name):
                                new_name_form.add_error("new_name", _("This sample name exists already."))
                                referentially_valid = False
    return referentially_valid