Languages

Previous versions

1.2
1.1

Source code for plmapp.references

import re
import datetime
from django.utils import timezone

from django.conf import settings

from django.utils.translation import ugettext_lazy as _
from openPLM.plmapp.models import PLMObject, Part, Document

#: Regular expression to test if a reference is invalid (forbidden characters)
rx_bad_ref = re.compile(r"[?/#\n\t\r\f]|\.\.")

#: default reference patterns, generates references like ``PART_00001`` and ``DOC_00001``
REFERENCE_PATTERNS = {
    "shared": False,
    "part": (u"PART_{number:05d}", r"^PART_(\d+)$"),
    "doc": (u"DOC_{number:05d}", r"^DOC_(\d+)$"),
}


[docs]def validate_reference(reference): """ Raises a :exc:`ValueError` if *reference* is not valid.""" if rx_bad_ref.search(reference): raise ValueError(_(u"Bad reference: '#', '?', '/' and '..' are not allowed"))
[docs]def validate_revision(revision): """ Raises a :exc:`ValueError` if *revision* is not valid.""" if not revision: raise ValueError("Empty value not permitted for revision") if rx_bad_ref.search(revision): raise ValueError(_(u"Bad revision: '#', '?', '/' and '..' are not allowed"))
[docs]def get_new_reference(user, cls, start=0, inbulk_cache=None): u""" Returns a new reference for creating a :class:`.PLMObject` of type *cls*. *user* is the user who will create the object. By default, the formatting is ``PART_000XX`` if *cls* is a subclass of :class:`.Part` and ``DOC_000XX`` otherwise. The number is the count of Parts or Documents plus *start* plus 1. It is incremented while an object with the same reference already exists. *start* can be used to create several creation forms at once. Parts and documents have an independent reference number. For example, the first suggested part reference is ``PART_00001`` and the first suggested document is ``DOC_00001`` even if parts have been created. .. note:: The returned referenced may not be valid if a new object has been created after the call to this function. """ patterns = getattr(settings, "REFERENCE_PATTERNS", REFERENCE_PATTERNS) if patterns["shared"]: base_cls = PLMObject name = "part" if issubclass(cls, Part) else "doc" elif issubclass(cls, Part): base_cls, name = Part, "part" else: base_cls, name = Document, "doc" format = patterns[name][0] if inbulk_cache is not None and "max_" + name in inbulk_cache: max_ref = inbulk_cache["max_" + name] else: try: max_ref = base_cls.objects.order_by("-reference_number")\ .values_list("reference_number", flat=True)[0] except IndexError: max_ref = 0 if inbulk_cache is not None: inbulk_cache["max_" + name] = max_ref nb = max_ref + start + 1 initials = user.first_name[:1] + user.last_name[:1] return format.format(user=user, now=timezone.now(), number=nb, initials=initials)
[docs]def parse_reference_number(reference, class_): """ Parses *reference* and returns the reference number. The reference number is the text that increases after each creation of a new document or part. :param reference: reference of the created object :param class_: class of the created object :return: the reference number, 0 if there is no reference :rtype: int """ try: patterns = getattr(settings, "REFERENCE_PATTERNS", REFERENCE_PATTERNS) name = "part" if issubclass(class_, Part) else "doc" reference_number = int(re.search(patterns[name][1], reference).group(1)) if reference_number > 2**31 - 1: reference_number = 0 except: reference_number = 0 return reference_number