summaryrefslogtreecommitdiff
path: root/ishtar_common/models.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2021-03-19 11:05:22 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2021-03-19 11:05:22 +0100
commite2d6c50f231f636fed362be37e7bf3319fc5d6b8 (patch)
tree5d7fde3628825aebeeef3d85d2dfcf09a52116de /ishtar_common/models.py
parente6af0225df8f539308bc3fd8c9dbc967bba5a807 (diff)
downloadIshtar-e2d6c50f231f636fed362be37e7bf3319fc5d6b8.tar.bz2
Ishtar-e2d6c50f231f636fed362be37e7bf3319fc5d6b8.zip
Format - black: ishtar_common
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r--ishtar_common/models.py3310
1 files changed, 2036 insertions, 1274 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 56c65c1f3..88aa993c6 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -54,8 +54,11 @@ from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.indexes import GinIndex
from django.contrib.sites.models import Site
from django.core.cache import cache
-from django.core.exceptions import ObjectDoesNotExist, ValidationError, \
- MultipleObjectsReturned
+from django.core.exceptions import (
+ ObjectDoesNotExist,
+ ValidationError,
+ MultipleObjectsReturned,
+)
from django.core.files.base import ContentFile
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.urlresolvers import reverse
@@ -65,55 +68,136 @@ from django.db.utils import DatabaseError
from django.template import Context, Template
from django.template.defaultfilters import slugify
from django.utils.functional import lazy
-from ishtar_common.utils import ugettext_lazy as _, ugettext, \
- pgettext_lazy, get_generated_id, get_current_profile, duplicate_item, \
- get_image_path
+from ishtar_common.utils import (
+ ugettext_lazy as _,
+ ugettext,
+ pgettext_lazy,
+ get_generated_id,
+ get_current_profile,
+ duplicate_item,
+ get_image_path,
+)
from ishtar_common.utils_secretary import IshtarSecretaryRenderer
-from ishtar_common.alternative_configs import ALTERNATE_CONFIGS, \
- ALTERNATE_CONFIGS_CHOICES
+from ishtar_common.alternative_configs import (
+ ALTERNATE_CONFIGS,
+ ALTERNATE_CONFIGS_CHOICES,
+)
from ishtar_common.data_importer import pre_importer_action
-from ishtar_common.model_managers import SlugModelManager, ExternalIdManager, \
- UUIDModelManager
+from ishtar_common.model_managers import (
+ SlugModelManager,
+ ExternalIdManager,
+ UUIDModelManager,
+)
from ishtar_common.model_merging import merge_model_objects
-from ishtar_common.models_imports import ImporterModel, ImporterType, \
- ImporterDefault, ImporterDefaultValues, ImporterColumn, \
- ImporterDuplicateField, Regexp, ImportTarget, TargetKey, FormaterType, \
- Import, TargetKeyGroup, ValueFormater
-from ishtar_common.utils import get_cache, create_slug, \
- get_all_field_names, cached_label_changed, \
- generate_relation_graph, max_size_help
-
-from ishtar_common.models_common import GeneralType, HierarchicalType, \
- BaseHistorizedItem, LightHistorizedItem, FullSearch, \
- SearchAltName, OwnPerms, Cached, \
- Address, post_save_cache, TemplateItem, SpatialReferenceSystem, \
- DashboardFormItem, document_attached_changed, SearchAltName, \
- DynamicRequest, GeoItem, CompleteIdentifierItem, SearchVectorConfig, \
- DocumentItem, QuickAction, MainItem, Merge, ShortMenuItem, Town, \
- ImageContainerModel, StatisticItem, CachedGen, CascasdeUpdate, \
- Department, State
+from ishtar_common.models_imports import (
+ ImporterModel,
+ ImporterType,
+ ImporterDefault,
+ ImporterDefaultValues,
+ ImporterColumn,
+ ImporterDuplicateField,
+ Regexp,
+ ImportTarget,
+ TargetKey,
+ FormaterType,
+ Import,
+ TargetKeyGroup,
+ ValueFormater,
+)
+from ishtar_common.utils import (
+ get_cache,
+ create_slug,
+ get_all_field_names,
+ cached_label_changed,
+ generate_relation_graph,
+ max_size_help,
+)
+
+from ishtar_common.models_common import (
+ GeneralType,
+ HierarchicalType,
+ BaseHistorizedItem,
+ LightHistorizedItem,
+ FullSearch,
+ SearchAltName,
+ OwnPerms,
+ Cached,
+ Address,
+ post_save_cache,
+ TemplateItem,
+ SpatialReferenceSystem,
+ DashboardFormItem,
+ document_attached_changed,
+ SearchAltName,
+ DynamicRequest,
+ GeoItem,
+ CompleteIdentifierItem,
+ SearchVectorConfig,
+ DocumentItem,
+ QuickAction,
+ MainItem,
+ Merge,
+ ShortMenuItem,
+ Town,
+ ImageContainerModel,
+ StatisticItem,
+ CachedGen,
+ CascasdeUpdate,
+ Department,
+ State,
+)
__all__ = [
- 'ImporterModel', 'ImporterType', 'ImporterDefault', 'ImporterDefaultValues',
- 'ImporterColumn', 'ImporterDuplicateField', 'Regexp', 'ImportTarget',
- 'TargetKey', 'FormaterType', 'Import', 'TargetKeyGroup', 'ValueFormater',
- 'Organization', 'Person', 'valid_id', 'Town', 'SpatialReferenceSystem',
- 'OrganizationType', 'Document', 'GeneralType', 'get_generated_id',
- 'LightHistorizedItem', 'OwnPerms', 'Address', 'post_save_cache',
- 'DashboardFormItem', 'ShortMenuItem', 'document_attached_changed',
- 'SearchAltName', 'DynamicRequest', 'GeoItem',
- 'SearchVectorConfig', 'DocumentItem', 'CachedGen', 'StatisticItem',
- 'CascasdeUpdate', 'Department', 'State', 'CompleteIdentifierItem'
+ "ImporterModel",
+ "ImporterType",
+ "ImporterDefault",
+ "ImporterDefaultValues",
+ "ImporterColumn",
+ "ImporterDuplicateField",
+ "Regexp",
+ "ImportTarget",
+ "TargetKey",
+ "FormaterType",
+ "Import",
+ "TargetKeyGroup",
+ "ValueFormater",
+ "Organization",
+ "Person",
+ "valid_id",
+ "Town",
+ "SpatialReferenceSystem",
+ "OrganizationType",
+ "Document",
+ "GeneralType",
+ "get_generated_id",
+ "LightHistorizedItem",
+ "OwnPerms",
+ "Address",
+ "post_save_cache",
+ "DashboardFormItem",
+ "ShortMenuItem",
+ "document_attached_changed",
+ "SearchAltName",
+ "DynamicRequest",
+ "GeoItem",
+ "SearchVectorConfig",
+ "DocumentItem",
+ "CachedGen",
+ "StatisticItem",
+ "CascasdeUpdate",
+ "Department",
+ "State",
+ "CompleteIdentifierItem",
]
logger = logging.getLogger(__name__)
def post_save_user(sender, **kwargs):
- user = kwargs['instance']
+ user = kwargs["instance"]
if kwargs["created"]:
try:
@@ -131,85 +215,106 @@ class ValueGetter(object):
COL_LABELS = {}
GET_VALUES_EXTRA = []
GET_VALUES_EXCLUDE_FIELDS = [
- 'search_vector', 'id', 'multi_polygon', 'point_2d', 'point',
- 'history_m2m']
+ "search_vector",
+ "id",
+ "multi_polygon",
+ "point_2d",
+ "point",
+ "history_m2m",
+ ]
GET_VALUES_ = [
- 'preservation_to_considers', 'alterations', 'alteration_causes']
+ "preservation_to_considers",
+ "alterations",
+ "alteration_causes",
+ ]
GET_VALUES_EXTRA_TYPES = [
- 'preservation_to_considers', 'alterations', 'alteration_causes']
+ "preservation_to_considers",
+ "alterations",
+ "alteration_causes",
+ ]
def _get_values_documents(self, prefix="", filtr=None):
values = {}
- if not hasattr(self, 'documents'):
+ if not hasattr(self, "documents"):
return values
if not filtr or prefix + "documents" in filtr:
values[prefix + "documents"] = [
- doc.get_values(no_values=True)
- for doc in self.documents.all()
+ doc.get_values(no_values=True) for doc in self.documents.all()
]
if filtr and prefix + "main_image" not in filtr:
return values
- if hasattr(self, "main_image") and self.main_image and hasattr(
- self.main_image, "get_values"):
+ if (
+ hasattr(self, "main_image")
+ and self.main_image
+ and hasattr(self.main_image, "get_values")
+ ):
values[prefix + "main_image"] = self.main_image.get_values(
- no_values=True)
+ no_values=True
+ )
return values
def _get_values_update_sub_filter(self, filtr, prefix):
if not filtr:
return
- return [k[len(prefix):] for k in filtr if k.startswith(prefix)]
+ return [k[len(prefix) :] for k in filtr if k.startswith(prefix)]
- def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
if not prefix:
prefix = self._prefix
exclude = kwargs.get("exclude", [])
values = {}
- if hasattr(self, "qrcode") and (
- not filtr or prefix + 'qrcode_path' in filtr) and \
- prefix + 'qrcode_path' not in exclude:
- values[prefix + 'qrcode_path'] = self.qrcode_path
+ if (
+ hasattr(self, "qrcode")
+ and (not filtr or prefix + "qrcode_path" in filtr)
+ and prefix + "qrcode_path" not in exclude
+ ):
+ values[prefix + "qrcode_path"] = self.qrcode_path
for field_name in get_all_field_names(self):
try:
value = getattr(self, field_name)
except (AttributeError, MultipleObjectsReturned):
continue
- if field_name in self.GET_VALUES_EXCLUDE_FIELDS or \
- prefix + field_name in exclude:
+ if (
+ field_name in self.GET_VALUES_EXCLUDE_FIELDS
+ or prefix + field_name in exclude
+ ):
continue
if filtr and not any(
- field_name for f in filtr
- if f.startswith(prefix + field_name)):
+ field_name for f in filtr if f.startswith(prefix + field_name)
+ ):
continue
- if hasattr(value, 'get_values'):
- new_prefix = prefix + field_name + '_'
+ if hasattr(value, "get_values"):
+ new_prefix = prefix + field_name + "_"
values.update(
- value.get_values(new_prefix, filtr=filtr, **kwargs))
+ value.get_values(new_prefix, filtr=filtr, **kwargs)
+ )
if hasattr(self, "get_values_for_" + field_name):
values[prefix + field_name] = getattr(
- self, "get_values_for_" + field_name)()
+ self, "get_values_for_" + field_name
+ )()
else:
values[prefix + field_name] = value
values.update(self._get_values_documents(prefix=prefix, filtr=filtr))
for extra_field in self.GET_VALUES_EXTRA:
- values[prefix + extra_field] = getattr(self, extra_field) or ''
+ values[prefix + extra_field] = getattr(self, extra_field) or ""
for key, val in values.items():
if val is None:
- val = ''
+ val = ""
elif (key in self.GET_VALUES_EXTRA_TYPES or "type" in key) and (
- val.__class__.__name__.split('.')[0] == 'ManyRelatedManager'):
+ val.__class__.__name__.split(".")[0] == "ManyRelatedManager"
+ ):
val = " ; ".join(str(v) for v in val.all())
elif not isinstance(val, (tuple, list, dict)):
val = str(val)
- if val.endswith('.None'):
- val = ''
+ if val.endswith(".None"):
+ val = ""
values[key] = val
if (prefix and prefix != self._prefix) or no_values:
# do not provide KEYS and VALUES for sub-items
return values
value_list = []
for key, value_ in values.items():
- if key in ('KEYS', 'VALUES'):
+ if key in ("KEYS", "VALUES"):
continue
value_list.append((key, str(value_)))
for global_var in GlobalVar.objects.all():
@@ -217,10 +322,12 @@ class ValueGetter(object):
return values
@classmethod
- def get_empty_values(cls, prefix=''):
+ def get_empty_values(cls, prefix=""):
if not prefix:
prefix = cls._prefix
- return {prefix + field_name: '' for field_name in get_all_field_names(cls)}
+ return {
+ prefix + field_name: "" for field_name in get_all_field_names(cls)
+ }
class HistoryModel(models.Model):
@@ -231,14 +338,14 @@ class HistoryModel(models.Model):
if not self.history_m2m or key not in self.history_m2m:
return
models = self.__class__.__module__
- if not models.endswith('.models'):
+ if not models.endswith(".models"):
models += ".models"
models = import_module(models)
- model = getattr(
- models, self.__class__.__name__[len('Historical'):])
+ model = getattr(models, self.__class__.__name__[len("Historical") :])
related_model = getattr(model, key).rel.model
- return related_model.history_decompress(self.history_m2m[key],
- create=create)
+ return related_model.history_decompress(
+ self.history_m2m[key], create=create
+ )
def valid_id(cls):
@@ -262,8 +369,7 @@ def valid_ids(cls):
try:
cls.objects.get(pk=v)
except ObjectDoesNotExist:
- raise ValidationError(
- _("A selected item is not a valid item."))
+ raise ValidationError(_("A selected item is not a valid item."))
return func
@@ -317,11 +423,11 @@ class ItemKey(models.Model):
key = models.TextField(_("Key"))
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
- content_object = GenericForeignKey('content_type', 'object_id')
+ content_object = GenericForeignKey("content_type", "object_id")
importer = models.ForeignKey(
- Import, null=True, blank=True,
- help_text=_("Specific key to an import"))
- user = models.ForeignKey('IshtarUser', blank=True, null=True)
+ Import, null=True, blank=True, help_text=_("Specific key to an import")
+ )
+ user = models.ForeignKey("IshtarUser", blank=True, null=True)
group = models.ForeignKey(TargetKeyGroup, blank=True, null=True)
def __str__(self):
@@ -329,14 +435,23 @@ class ItemKey(models.Model):
class ImageModel(models.Model, ImageContainerModel):
- image = models.ImageField(upload_to=get_image_path, blank=True, null=True,
- max_length=255, help_text=max_size_help())
+ image = models.ImageField(
+ upload_to=get_image_path,
+ blank=True,
+ null=True,
+ max_length=255,
+ help_text=max_size_help(),
+ )
thumbnail = models.ImageField(
- upload_to=get_image_path, blank=True, null=True, max_length=255,
- help_text=max_size_help())
+ upload_to=get_image_path,
+ blank=True,
+ null=True,
+ max_length=255,
+ help_text=max_size_help(),
+ )
IMAGE_MAX_SIZE = settings.IMAGE_MAX_SIZE
THUMB_MAX_SIZE = settings.THUMB_MAX_SIZE
- IMAGE_PREFIX = ''
+ IMAGE_PREFIX = ""
class Meta:
abstract = True
@@ -344,7 +459,7 @@ class ImageModel(models.Model, ImageContainerModel):
def has_changed(self, field):
if not self.pk:
return True
- manager = getattr(self.__class__, 'objects')
+ manager = getattr(self.__class__, "objects")
old = getattr(manager.get(pk=self.pk), field)
return getattr(self, field) != old
@@ -352,17 +467,17 @@ class ImageModel(models.Model, ImageContainerModel):
"""Returns the image resized to fit inside a box of the given size"""
image.thumbnail(size, Image.ANTIALIAS)
temp = BytesIO()
- image.save(temp, 'jpeg')
+ image.save(temp, "jpeg")
temp.seek(0)
- return SimpleUploadedFile('temp', temp.read())
+ return SimpleUploadedFile("temp", temp.read())
def save(self, *args, **kwargs):
- if 'force_copy' in kwargs:
- kwargs.pop('force_copy')
+ if "force_copy" in kwargs:
+ kwargs.pop("force_copy")
super(ImageModel, self).save(*args, **kwargs)
return
# manage images
- if not self.has_changed('image'):
+ if not self.has_changed("image"):
return super(ImageModel, self).save(*args, **kwargs)
if not self.image:
self.thumbnail = None
@@ -377,14 +492,16 @@ class ImageModel(models.Model, ImageContainerModel):
try:
image = Image.open(self.image.file)
# convert to RGB
- if image.mode not in ('L', 'RGB'):
- image = image.convert('RGB')
+ if image.mode not in ("L", "RGB"):
+ image = image.convert("RGB")
# resize if necessary
if self.IMAGE_MAX_SIZE:
- self.image.save(filename,
- self.create_thumb(image, self.IMAGE_MAX_SIZE),
- save=False)
+ self.image.save(
+ filename,
+ self.create_thumb(image, self.IMAGE_MAX_SIZE),
+ save=False,
+ )
if old_path != self.image.path:
try:
@@ -398,7 +515,8 @@ class ImageModel(models.Model, ImageContainerModel):
self.thumbnail.save(
thumb_filename,
self.create_thumb(image, self.THUMB_MAX_SIZE),
- save=False)
+ save=False,
+ )
except (IOError, ValueError):
self.thumbnail = None
self.image = None
@@ -408,10 +526,8 @@ class ImageModel(models.Model, ImageContainerModel):
return super(ImageModel, self).save(*args, **kwargs)
def _get_thumb_name(self, filename):
- splited = filename.split('.')
- return "{}-thumb.{}".format(
- ".".join(splited[:-1]), splited[-1]
- )
+ splited = filename.split(".")
+ return "{}-thumb.{}".format(".".join(splited[:-1]), splited[-1])
class BulkUpdatedItem(object):
@@ -428,7 +544,7 @@ class BulkUpdatedItem(object):
"""
if not transaction_id:
transaction_id = str(time.time())
- args = ['cached_label_bulk_update', transaction_id] + extra_args
+ args = ["cached_label_bulk_update", transaction_id] + extra_args
key, val = get_cache(cls, args)
if val:
return transaction_id, True
@@ -440,60 +556,98 @@ class RelationItem(models.Model):
"""
Items with relation between them
"""
+
MAIN_UP_MODEL_QUERY = ""
relation_image = models.FileField(
- _("Generated relation image (SVG)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated relation image (SVG)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
relation_bitmap_image = models.FileField(
- _("Generated relation image (PNG)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated relation image (PNG)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
relation_dot = models.FileField(
- _("Generated relation image (DOT)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated relation image (DOT)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
relation_image_above = models.FileField(
- _("Generated above relation image (SVG)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated above relation image (SVG)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
relation_dot_above = models.FileField(
- _("Generated above relation image (DOT)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated above relation image (DOT)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
relation_bitmap_image_above = models.FileField(
- _("Generated above relation image (PNG)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated above relation image (PNG)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
relation_image_below = models.FileField(
- _("Generated below relation image (SVG)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated below relation image (SVG)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
relation_dot_below = models.FileField(
- _("Generated below relation image (DOT)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated below relation image (DOT)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
relation_bitmap_image_below = models.FileField(
- _("Generated below relation image (PNG)"), null=True, blank=True,
- upload_to=get_image_path, help_text=max_size_help()
+ _("Generated below relation image (PNG)"),
+ null=True,
+ blank=True,
+ upload_to=get_image_path,
+ help_text=max_size_help(),
)
class Meta:
abstract = True
def generate_relation_image(
- self, highlight_current=True, render_above=True,
- render_below=True, full=False):
- generate_relation_graph(self, highlight_current=highlight_current,
- render_above=render_above,
- render_below=render_below, full=full)
+ self,
+ highlight_current=True,
+ render_above=True,
+ render_below=True,
+ full=False,
+ ):
+ generate_relation_graph(
+ self,
+ highlight_current=highlight_current,
+ render_above=render_above,
+ render_below=render_below,
+ full=full,
+ )
class JsonDataSectionManager(models.Manager):
def get_by_natural_key(self, name, app_label, model):
- return self.get(name=name,
- content_type__app_label=app_label,
- content_type__model=model)
+ return self.get(
+ name=name,
+ content_type__app_label=app_label,
+ content_type__model=model,
+ )
class JsonDataSection(models.Model):
@@ -505,7 +659,7 @@ class JsonDataSection(models.Model):
class Meta:
verbose_name = _("Json data - Menu")
verbose_name_plural = _("Json data - Menus")
- ordering = ['order', 'name']
+ ordering = ["order", "name"]
unique_together = ("name", "content_type")
def natural_key(self):
@@ -516,48 +670,59 @@ class JsonDataSection(models.Model):
JSON_VALUE_TYPES = (
- ('T', _("Text")),
- ('LT', _("Long text")),
- ('I', _("Integer")),
- ('B', _("Boolean")),
- ('F', _("Float")),
- ('D', _("Date")),
- ('C', _("Choices")),
+ ("T", _("Text")),
+ ("LT", _("Long text")),
+ ("I", _("Integer")),
+ ("B", _("Boolean")),
+ ("F", _("Float")),
+ ("D", _("Date")),
+ ("C", _("Choices")),
)
class JsonDataFieldManager(models.Manager):
def get_by_natural_key(self, key, app_label, model):
- return self.get(key=key, content_type__app_label=app_label,
- content_type__model=model)
+ return self.get(
+ key=key,
+ content_type__app_label=app_label,
+ content_type__model=model,
+ )
class JsonDataField(models.Model):
name = models.CharField(_("Name"), max_length=200)
content_type = models.ForeignKey(ContentType)
key = models.CharField(
- _("Key"), max_length=200,
- help_text=_("Value of the key in the JSON schema. For hierarchical "
- "key use \"__\" to explain it. For instance for the key "
- "'my_subkey' with data such as {'my_key': {'my_subkey': "
- "'value'}}, its value will be reached with "
- "my_key__my_subkey."))
+ _("Key"),
+ max_length=200,
+ help_text=_(
+ "Value of the key in the JSON schema. For hierarchical "
+ 'key use "__" to explain it. For instance for the key '
+ "'my_subkey' with data such as {'my_key': {'my_subkey': "
+ "'value'}}, its value will be reached with "
+ "my_key__my_subkey."
+ ),
+ )
display = models.BooleanField(_("Display"), default=True)
- value_type = models.CharField(_("Type"), default="T", max_length=10,
- choices=JSON_VALUE_TYPES)
+ value_type = models.CharField(
+ _("Type"), default="T", max_length=10, choices=JSON_VALUE_TYPES
+ )
order = models.IntegerField(_("Order"), default=10)
- search_index = models.BooleanField(_("Use in search indexes"),
- default=False)
- section = models.ForeignKey(JsonDataSection, blank=True, null=True,
- on_delete=models.SET_NULL)
+ search_index = models.BooleanField(
+ _("Use in search indexes"), default=False
+ )
+ section = models.ForeignKey(
+ JsonDataSection, blank=True, null=True, on_delete=models.SET_NULL
+ )
custom_forms = models.ManyToManyField(
- "CustomForm", blank=True, through="CustomFormJsonField")
+ "CustomForm", blank=True, through="CustomFormJsonField"
+ )
objects = JsonDataFieldManager()
class Meta:
verbose_name = _("Json data - Field")
verbose_name_plural = _("Json data - Fields")
- ordering = ['order', 'name']
+ ordering = ["order", "name"]
unique_together = ("content_type", "key")
def natural_key(self):
@@ -571,29 +736,35 @@ class JsonDataField(models.Model):
return
if self.section.content_type != self.content_type:
raise ValidationError(
- _("Content types of the field and of the menu do not match"))
+ _("Content types of the field and of the menu do not match")
+ )
LOGICAL_TYPES = (
- ('above', _("Above")),
- ('below', _("Below")),
- ('equal', _("Equal")),
- ('include', _("Include")),
- ('included', _("Is included")),
+ ("above", _("Above")),
+ ("below", _("Below")),
+ ("equal", _("Equal")),
+ ("include", _("Include")),
+ ("included", _("Is included")),
)
class GeneralRelationType(GeneralType):
order = models.IntegerField(_("Order"), default=1)
symmetrical = models.BooleanField(_("Symmetrical"))
- tiny_label = models.CharField(_("Tiny label"), max_length=50,
- blank=True, null=True)
+ tiny_label = models.CharField(
+ _("Tiny label"), max_length=50, blank=True, null=True
+ )
inverse_relation = models.ForeignKey(
- 'self', verbose_name=_("Inverse relation"), blank=True,
- null=True)
+ "self", verbose_name=_("Inverse relation"), blank=True, null=True
+ )
logical_relation = models.CharField(
- verbose_name=_("Logical relation"), max_length=10,
- choices=LOGICAL_TYPES, blank=True, null=True)
+ verbose_name=_("Logical relation"),
+ max_length=10,
+ choices=LOGICAL_TYPES,
+ blank=True,
+ null=True,
+ )
class Meta:
abstract = True
@@ -602,7 +773,8 @@ class GeneralRelationType(GeneralType):
# cannot have symmetrical and an inverse_relation
if self.symmetrical and self.inverse_relation:
raise ValidationError(
- _("Cannot have symmetrical and an inverse_relation"))
+ _("Cannot have symmetrical and an inverse_relation")
+ )
def get_tiny_label(self):
return self.tiny_label or self.label or ""
@@ -611,9 +783,10 @@ class GeneralRelationType(GeneralType):
obj = super(GeneralRelationType, self).save(*args, **kwargs)
# after saving check that the inverse_relation of the inverse_relation
# point to the saved object
- if self.inverse_relation \
- and (not self.inverse_relation.inverse_relation
- or self.inverse_relation.inverse_relation != self):
+ if self.inverse_relation and (
+ not self.inverse_relation.inverse_relation
+ or self.inverse_relation.inverse_relation != self
+ ):
self.inverse_relation.inverse_relation = self
self.inverse_relation.symmetrical = False
self.inverse_relation.save()
@@ -623,7 +796,7 @@ class GeneralRelationType(GeneralType):
class GeneralRecordRelations(object):
@classmethod
def general_types(cls):
- return ['relation_type']
+ return ["relation_type"]
def save(self, *args, **kwargs):
super(GeneralRecordRelations, self).save(*args, **kwargs)
@@ -638,8 +811,11 @@ class GeneralRecordRelations(object):
if not sym_rel_type:
return
- dct = {'right_record': self.left_record,
- 'left_record': self.right_record, 'relation_type': sym_rel_type}
+ dct = {
+ "right_record": self.left_record,
+ "left_record": self.right_record,
+ "relation_type": sym_rel_type,
+ }
self.__class__.objects.get_or_create(**dct)
return self
@@ -653,9 +829,11 @@ def post_delete_record_relation(sender, instance, **kwargs):
# no symetric/inverse is defined
if not sym_rel_type:
return
- dct = {'right_record_id': instance.left_record_id,
- 'left_record_id': instance.right_record_id,
- 'relation_type': sym_rel_type}
+ dct = {
+ "right_record_id": instance.left_record_id,
+ "left_record_id": instance.right_record_id,
+ "relation_type": sym_rel_type,
+ }
q = instance.__class__.objects.filter(**dct)
if q.count():
q.delete()
@@ -664,342 +842,474 @@ def post_delete_record_relation(sender, instance, **kwargs):
class SearchQuery(models.Model):
label = models.TextField(_("Label"), blank=True, default="")
query = models.TextField(_("Query"), blank=True, default="")
- content_type = models.ForeignKey(ContentType,
- verbose_name=_("Content type"))
+ content_type = models.ForeignKey(
+ ContentType, verbose_name=_("Content type")
+ )
profile = models.ForeignKey("UserProfile", verbose_name=_("Profile"))
is_alert = models.BooleanField(_("Is an alert"), default=False)
class Meta:
verbose_name = _("Search query")
verbose_name_plural = _("Search queries")
- ordering = ['label']
+ ordering = ["label"]
def __str__(self):
return str(self.label)
class Language(GeneralType):
- iso_code = models.CharField(_("ISO code"), null=True, blank=True,
- max_length=2)
+ iso_code = models.CharField(
+ _("ISO code"), null=True, blank=True, max_length=2
+ )
class Meta:
verbose_name = _("Language")
verbose_name_plural = _("Languages")
-CURRENCY = (("€", _("Euro")),
- ("$", _("US dollar")))
-FIND_INDEX_SOURCE = (("O", _("Operations")),
- ("CR", _("Context records")))
-SITE_LABELS = [('site', _("Site")), ('entity', _("Archaeological entity"))]
+CURRENCY = (("€", _("Euro")), ("$", _("US dollar")))
+FIND_INDEX_SOURCE = (("O", _("Operations")), ("CR", _("Context records")))
+SITE_LABELS = [("site", _("Site")), ("entity", _("Archaeological entity"))]
TRANSLATED_SITE_LABELS = {
- 'site': {
- 'search': _("Site search"),
- 'new': _("New site"),
- 'modification': _("Site modification"),
- 'deletion': _("Site deletion"),
+ "site": {
+ "search": _("Site search"),
+ "new": _("New site"),
+ "modification": _("Site modification"),
+ "deletion": _("Site deletion"),
"attached-to-operation": _("Site (attached to the operation)"),
- "name-attached-to-operation":
- _("Site name (attached to the operation)"),
+ "name-attached-to-operation": _(
+ "Site name (attached to the operation)"
+ ),
"attached-to-cr": _("Site (attached to the context record)"),
"name-attached-to-cr": _("Site name (attached to the context record)"),
},
- 'entity': {
- 'search': _("Archaeological entity search"),
- 'new': _("New archaeological entity"),
- 'modification': _("Archaeological entity modification"),
- 'deletion': _("Archaeological entity deletion"),
- "attached-to-operation": _("Archaeological entity (attached to the "
- "operation)"),
- "name-attached-to-operation": _("Archaeological entity name (attached "
- "to the operation)"),
- "attached-to-cr": _("Archaeological entity (attached to the context "
- "record)"),
- "name-attached-to-cr":
- _("Archaeological entity name (attached to the context record)"),
+ "entity": {
+ "search": _("Archaeological entity search"),
+ "new": _("New archaeological entity"),
+ "modification": _("Archaeological entity modification"),
+ "deletion": _("Archaeological entity deletion"),
+ "attached-to-operation": _(
+ "Archaeological entity (attached to the " "operation)"
+ ),
+ "name-attached-to-operation": _(
+ "Archaeological entity name (attached " "to the operation)"
+ ),
+ "attached-to-cr": _(
+ "Archaeological entity (attached to the context " "record)"
+ ),
+ "name-attached-to-cr": _(
+ "Archaeological entity name (attached to the context record)"
+ ),
},
}
ACCOUNT_NAMING_STYLE = (
- ('NF', _("name.firstname")),
- ('FN', _("firstname.name")),
+ ("NF", _("name.firstname")),
+ ("FN", _("firstname.name")),
)
class IshtarSiteProfile(models.Model, Cached):
- slug_field = 'slug'
+ slug_field = "slug"
label = models.TextField(_("Name"))
slug = models.SlugField(_("Slug"), unique=True)
active = models.BooleanField(_("Current active"), default=False)
experimental_feature = models.BooleanField(
- _("Activate experimental feature"), default=False)
+ _("Activate experimental feature"), default=False
+ )
description = models.TextField(_("Description"), blank=True, default="")
warning_name = models.TextField(_("Warning name"), blank=True, default="")
- warning_message = models.TextField(_("Warning message"), blank=True,
- default="")
+ warning_message = models.TextField(
+ _("Warning message"), blank=True, default=""
+ )
delete_image_zip_on_archive = models.BooleanField(
_("Import - Delete image/document zip on archive"), default=False
)
clean_redundant_document_association = models.BooleanField(
- _("Document - Remove redundant association"), default=False,
- help_text=_("For instance, remove operation association of a "
- "document also associated to a find of this operation. "
- "Only manage association of operations, context records "
- "and finds.")
+ _("Document - Remove redundant association"),
+ default=False,
+ help_text=_(
+ "For instance, remove operation association of a "
+ "document also associated to a find of this operation. "
+ "Only manage association of operations, context records "
+ "and finds."
+ ),
)
calculate_weight_on_full = models.BooleanField(
_("Container - calculate weight only when all find has a weight"),
- default=False)
+ default=False,
+ )
config = models.CharField(
- _("Alternate configuration"), max_length=200,
+ _("Alternate configuration"),
+ max_length=200,
choices=ALTERNATE_CONFIGS_CHOICES,
- help_text=_("Choose an alternate configuration for label, "
- "index management"),
- null=True, blank=True
+ help_text=_(
+ "Choose an alternate configuration for label, " "index management"
+ ),
+ null=True,
+ blank=True,
)
files = models.BooleanField(_("Files module"), default=False)
archaeological_site = models.BooleanField(
- _("Archaeological site module"), default=False)
+ _("Archaeological site module"), default=False
+ )
archaeological_site_label = models.CharField(
- _("Archaeological site type"), max_length=200,
+ _("Archaeological site type"),
+ max_length=200,
choices=SITE_LABELS,
- default='site'
+ default="site",
+ )
+ context_record = models.BooleanField(
+ _("Context records module"), default=False
+ )
+ find = models.BooleanField(
+ _("Finds module"),
+ default=False,
+ help_text=_("Need context records module"),
)
- context_record = models.BooleanField(_("Context records module"),
- default=False)
- find = models.BooleanField(_("Finds module"), default=False,
- help_text=_("Need context records module"))
find_index = models.CharField(
- _("Find index is based on"), default='O', max_length=2,
+ _("Find index is based on"),
+ default="O",
+ max_length=2,
choices=FIND_INDEX_SOURCE,
- help_text=_("To prevent irrelevant indexes, change this parameter "
- "only if there is no find in the database"))
+ help_text=_(
+ "To prevent irrelevant indexes, change this parameter "
+ "only if there is no find in the database"
+ ),
+ )
warehouse = models.BooleanField(
- _("Warehouses module"), default=False,
- help_text=_("Need finds module"))
- preservation = models.BooleanField(_("Preservation module"),
- default=False)
+ _("Warehouses module"), default=False, help_text=_("Need finds module")
+ )
+ preservation = models.BooleanField(_("Preservation module"), default=False)
mapping = models.BooleanField(_("Mapping module"), default=False)
point_precision = models.IntegerField(
- _("Point precision (search and sheets)"), null=True, blank=True,
+ _("Point precision (search and sheets)"),
+ null=True,
+ blank=True,
help_text=_(
"Number of digit to round from the decimal point for coordinates "
"in WGS84 (latitude, longitude). Empty value means no round."
- )
+ ),
)
locate_warehouses = models.BooleanField(
- _("Locate warehouse and containers"), default=False,
+ _("Locate warehouse and containers"),
+ default=False,
help_text=_(
"Mapping module must be activated. With many containers and "
"background task not activated, activating this option may "
- "consume many resources.")
+ "consume many resources."
+ ),
)
use_town_for_geo = models.BooleanField(
- _("Use town to locate when coordinates are missing"), default=True)
- relation_graph = models.BooleanField(_("Generate relation graph"),
- default=False)
+ _("Use town to locate when coordinates are missing"), default=True
+ )
+ relation_graph = models.BooleanField(
+ _("Generate relation graph"), default=False
+ )
underwater = models.BooleanField(_("Underwater module"), default=False)
parcel_mandatory = models.BooleanField(
- _("Parcel are mandatory for context records"), default=True)
+ _("Parcel are mandatory for context records"), default=True
+ )
homepage = models.TextField(
- _("Home page"), blank=True, default="",
- help_text=_("Homepage of Ishtar - if not defined a default homepage "
- "will appear. Use the markdown syntax. {random_image} "
- "can be used to display a random image."))
+ _("Home page"),
+ blank=True,
+ default="",
+ help_text=_(
+ "Homepage of Ishtar - if not defined a default homepage "
+ "will appear. Use the markdown syntax. {random_image} "
+ "can be used to display a random image."
+ ),
+ )
operation_prefix = models.CharField(
- _("Main operation code prefix"), default='OA', null=True, blank=True,
- max_length=20
+ _("Main operation code prefix"),
+ default="OA",
+ null=True,
+ blank=True,
+ max_length=20,
)
default_operation_prefix = models.CharField(
- _("Default operation code prefix"), default='OP', null=True,
- blank=True, max_length=20
+ _("Default operation code prefix"),
+ default="OP",
+ null=True,
+ blank=True,
+ max_length=20,
)
operation_region_code = models.CharField(
- _("Operation region code"), null=True, blank=True,
- max_length=5
+ _("Operation region code"), null=True, blank=True, max_length=5
)
operation_complete_identifier = models.TextField(
_("Operation complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage operation complete identifier."))
+ default="",
+ blank=True,
+ help_text=_("Formula to manage operation complete identifier."),
+ )
operation_custom_index = models.TextField(
_("Operation custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage operation custom index. "
- "Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage operation custom index. "
+ "Separate keys with a semicolon."
+ ),
+ )
site_complete_identifier = models.TextField(
_("Archaeological site complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage archaeological site complete"
- " identifier."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Formula to manage archaeological site complete" " identifier."
+ ),
+ )
site_custom_index = models.TextField(
_("Archaeological site custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage archaeological site custom "
- "index. Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage archaeological site custom "
+ "index. Separate keys with a semicolon."
+ ),
+ )
file_external_id = models.TextField(
_("File external id"),
default="{year}-{numeric_reference}",
- help_text=_("Formula to manage file external ID. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
+ help_text=_(
+ "Formula to manage file external ID. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
file_complete_identifier = models.TextField(
_("Archaeological file complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage archaeological file complete "
- "identifier."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Formula to manage archaeological file complete " "identifier."
+ ),
+ )
file_custom_index = models.TextField(
_("Archaeological file custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage archaeological file custom "
- "index. Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage archaeological file custom "
+ "index. Separate keys with a semicolon."
+ ),
+ )
parcel_external_id = models.TextField(
_("Parcel external id"),
default="{associated_file__external_id}{operation__code_patriarche}-"
- "{town__numero_insee}-{section}{parcel_number}",
- help_text=_("Formula to manage parcel external ID. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
+ "{town__numero_insee}-{section}{parcel_number}",
+ help_text=_(
+ "Formula to manage parcel external ID. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
context_record_external_id = models.TextField(
_("Context record external id"),
default="{parcel__external_id}-{label}",
- help_text=_("Formula to manage context record external ID. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
+ help_text=_(
+ "Formula to manage context record external ID. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
contextrecord_complete_identifier = models.TextField(
_("Context record complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage context record complete identifier."))
+ default="",
+ blank=True,
+ help_text=_("Formula to manage context record complete identifier."),
+ )
contextrecord_custom_index = models.TextField(
_("Context record custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage context record custom index. "
- "Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage context record custom index. "
+ "Separate keys with a semicolon."
+ ),
+ )
base_find_external_id = models.TextField(
_("Base find external id"),
default="{context_record__external_id}-{label}",
- help_text=_("Formula to manage base find external ID. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
+ help_text=_(
+ "Formula to manage base find external ID. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
basefind_complete_identifier = models.TextField(
_("Base find complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage base find complete identifier."))
+ default="",
+ blank=True,
+ help_text=_("Formula to manage base find complete identifier."),
+ )
basefind_custom_index = models.TextField(
_("Base find custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage base find custom index. "
- "Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage base find custom index. "
+ "Separate keys with a semicolon."
+ ),
+ )
find_external_id = models.TextField(
_("Find external id"),
default="{get_first_base_find__context_record__external_id}-{label}",
- help_text=_("Formula to manage find external ID. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
+ help_text=_(
+ "Formula to manage find external ID. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
find_complete_identifier = models.TextField(
_("Find complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage find complete identifier."))
+ default="",
+ blank=True,
+ help_text=_("Formula to manage find complete identifier."),
+ )
find_custom_index = models.TextField(
_("Find custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage find custom index. "
- "Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage find custom index. "
+ "Separate keys with a semicolon."
+ ),
+ )
container_external_id = models.TextField(
_("Container external id"),
- default="{parent_external_id}-{container_type__txt_idx}-"
- "{reference}",
- help_text=_("Formula to manage container external ID. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
+ default="{parent_external_id}-{container_type__txt_idx}-" "{reference}",
+ help_text=_(
+ "Formula to manage container external ID. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
container_complete_identifier = models.TextField(
_("Container complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage container complete identifier."))
+ default="",
+ blank=True,
+ help_text=_("Formula to manage container complete identifier."),
+ )
container_custom_index = models.TextField(
_("Container custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage container custom index. "
- "Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage container custom index. "
+ "Separate keys with a semicolon."
+ ),
+ )
warehouse_external_id = models.TextField(
_("Warehouse external id"),
default="{name|slug}",
- help_text=_("Formula to manage warehouse external ID. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
+ help_text=_(
+ "Formula to manage warehouse external ID. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
warehouse_complete_identifier = models.TextField(
_("Warehouse complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage warehouse complete identifier."))
+ default="",
+ blank=True,
+ help_text=_("Formula to manage warehouse complete identifier."),
+ )
warehouse_custom_index = models.TextField(
_("Warehouse custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage warehouse custom index. "
- "Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage warehouse custom index. "
+ "Separate keys with a semicolon."
+ ),
+ )
document_external_id = models.TextField(
_("Document external id"),
default="{index}",
- help_text=_("Formula to manage document external ID. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
+ help_text=_(
+ "Formula to manage document external ID. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
document_complete_identifier = models.TextField(
_("Document complete identifier"),
- default="", blank=True,
- help_text=_("Formula to manage document complete identifier."))
+ default="",
+ blank=True,
+ help_text=_("Formula to manage document complete identifier."),
+ )
document_custom_index = models.TextField(
_("Document custom index key"),
- default="", blank=True,
- help_text=_("Keys to be used to manage document custom index. "
- "Separate keys with a semicolon."))
+ default="",
+ blank=True,
+ help_text=_(
+ "Keys to be used to manage document custom index. "
+ "Separate keys with a semicolon."
+ ),
+ )
person_raw_name = models.TextField(
_("Raw name for person"),
default="{name|upper} {surname}",
- help_text=_("Formula to manage person raw_name. "
- "Change this with care. With incorrect formula, the "
- "application might be unusable and import of external "
- "data can be destructive."))
- find_use_index = models.BooleanField(_("Use auto index for finds"),
- default=True)
- currency = models.CharField(_("Currency"), default="€",
- choices=CURRENCY, max_length=5)
+ help_text=_(
+ "Formula to manage person raw_name. "
+ "Change this with care. With incorrect formula, the "
+ "application might be unusable and import of external "
+ "data can be destructive."
+ ),
+ )
+ find_use_index = models.BooleanField(
+ _("Use auto index for finds"), default=True
+ )
+ currency = models.CharField(
+ _("Currency"), default="€", choices=CURRENCY, max_length=5
+ )
account_naming_style = models.CharField(
- _("Naming style for accounts"), max_length=2, default="NF",
- choices=ACCOUNT_NAMING_STYLE
+ _("Naming style for accounts"),
+ max_length=2,
+ default="NF",
+ choices=ACCOUNT_NAMING_STYLE,
)
default_center = models.PointField(
- _("Maps - default center"),
- default='SRID=4326;POINT(2.4397 46.5528)')
- default_zoom = models.IntegerField(
- _("Maps - default zoom"), default=6)
+ _("Maps - default center"), default="SRID=4326;POINT(2.4397 46.5528)"
+ )
+ default_zoom = models.IntegerField(_("Maps - default zoom"), default=6)
display_srs = models.ForeignKey(
SpatialReferenceSystem,
verbose_name=_("Spatial Reference System for display"),
- blank=True, null=True,
- help_text=_("Spatial Reference System used for display when no SRS is "
- "defined")
+ blank=True,
+ null=True,
+ help_text=_(
+ "Spatial Reference System used for display when no SRS is "
+ "defined"
+ ),
)
default_language = models.ForeignKey(
Language,
verbose_name=_("Default language for documentation"),
- blank=True, null=True,
- help_text=_("If set, by default the selected language will be set for "
- "localized documents.")
+ blank=True,
+ null=True,
+ help_text=_(
+ "If set, by default the selected language will be set for "
+ "localized documents."
+ ),
)
objects = SlugModelManager()
class Meta:
verbose_name = _("Ishtar site profile")
verbose_name_plural = _("Ishtar site profiles")
- ordering = ['label']
+ ordering = ["label"]
def __str__(self):
return str(self.label)
@@ -1008,18 +1318,22 @@ class IshtarSiteProfile(models.Model, Cached):
return (self.slug,)
def has_overload(self, key):
- return self.config and self.config in ALTERNATE_CONFIGS and \
- hasattr(ALTERNATE_CONFIGS[self.config], key)
+ return (
+ self.config
+ and self.config in ALTERNATE_CONFIGS
+ and hasattr(ALTERNATE_CONFIGS[self.config], key)
+ )
@classmethod
def get_current_profile(cls, force=False):
- cache_key, value = get_cache(cls, ['is-current-profile'])
+ cache_key, value = get_cache(cls, ["is-current-profile"])
if value and not force:
return value
q = cls.objects.filter(active=True)
if not q.count():
obj = cls.objects.create(
- label="Default profile", slug='default', active=True)
+ label="Default profile", slug="default", active=True
+ )
else:
obj = q.all()[0]
cache.set(cache_key, obj, settings.CACHE_TIMEOUT)
@@ -1032,14 +1346,12 @@ class IshtarSiteProfile(models.Model, Cached):
def get_site_label(self, key=None):
if not key:
return str(dict(SITE_LABELS)[self.archaeological_site_label])
- return str(
- TRANSLATED_SITE_LABELS[self.archaeological_site_label][key]
- )
+ return str(TRANSLATED_SITE_LABELS[self.archaeological_site_label][key])
def save(self, *args, **kwargs):
raw = False
- if 'raw' in kwargs:
- raw = kwargs.pop('raw')
+ if "raw" in kwargs:
+ raw = kwargs.pop("raw")
super(IshtarSiteProfile, self).save(*args, **kwargs)
obj = self
if raw:
@@ -1074,6 +1386,7 @@ profile_mapping = lazy(_profile_mapping)
def cached_site_changed(sender, **kwargs):
get_current_profile(force=True)
from ishtar_common.menus import Menu
+
MAIN_MENU = Menu(None)
MAIN_MENU.init()
MAIN_MENU.reinit_menu_for_all_user()
@@ -1093,27 +1406,35 @@ class CustomForm(models.Model):
form = models.CharField(_("Form"), max_length=250)
available = models.BooleanField(_("Available"), default=True)
enabled = models.BooleanField(
- _("Enable this form"), default=True,
- help_text=_("Disable with caution: disabling a form with mandatory "
- "fields may lead to database errors."))
+ _("Enable this form"),
+ default=True,
+ help_text=_(
+ "Disable with caution: disabling a form with mandatory "
+ "fields may lead to database errors."
+ ),
+ )
apply_to_all = models.BooleanField(
- _("Apply to all"), default=False,
- help_text=_("Apply this form to all users. If set to True, selecting "
- "user and user type is useless."))
- users = models.ManyToManyField('IshtarUser', blank=True)
+ _("Apply to all"),
+ default=False,
+ help_text=_(
+ "Apply this form to all users. If set to True, selecting "
+ "user and user type is useless."
+ ),
+ )
+ users = models.ManyToManyField("IshtarUser", blank=True)
user_types = models.ManyToManyField(
- 'PersonType', blank=True,
- help_text=_("Deprecated - use profile types"))
+ "PersonType", blank=True, help_text=_("Deprecated - use profile types")
+ )
profile_types = models.ManyToManyField("ProfileType", blank=True)
objects = CustomFormManager()
- SERIALIZATION_EXCLUDE = ("users", )
+ SERIALIZATION_EXCLUDE = ("users",)
class Meta:
verbose_name = _("Custom form")
verbose_name_plural = _("Custom forms")
- ordering = ['name', 'form']
- unique_together = (('name', 'form'),)
+ ordering = ["name", "form"]
+ unique_together = (("name", "form"),)
def natural_key(self):
return (self.name, self.form)
@@ -1135,12 +1456,14 @@ class CustomForm(models.Model):
@classmethod
def register(cls):
- if hasattr(cls, '_register') and hasattr(cls, '_register_fields'):
+ if hasattr(cls, "_register") and hasattr(cls, "_register_fields"):
return cls._register, cls._register_fields
- cache_key, value = get_cache(cls.__class__, ['dct-forms'],
- app_label='ishtar_common')
+ cache_key, value = get_cache(
+ cls.__class__, ["dct-forms"], app_label="ishtar_common"
+ )
cache_key_fields, value_fields = get_cache(
- cls.__class__, ['dct-fields'], app_label='ishtar_common')
+ cls.__class__, ["dct-fields"], app_label="ishtar_common"
+ )
if value and value_fields:
cls._register = value
cls._register_fields = value_fields
@@ -1155,15 +1478,17 @@ class CustomForm(models.Model):
if app_name == "archaeological_files_pdl":
app_name = "archaeological_files"
for form in dir(app_form):
- if 'Form' not in form and 'Select' not in form:
+ if "Form" not in form and "Select" not in form:
# not very clean... but do not treat inappropriate items
continue
form = getattr(app_form, form)
- if not inspect.isclass(form) \
- or not issubclass(form, CustomFormForm) \
- or not getattr(form, 'form_slug', None):
+ if (
+ not inspect.isclass(form)
+ or not issubclass(form, CustomFormForm)
+ or not getattr(form, "form_slug", None)
+ ):
continue
- model_name = form.form_slug.split('-')[0].replace('_', '')
+ model_name = form.form_slug.split("-")[0].replace("_", "")
if app_name not in cls._register_fields:
cls._register_fields[app_name] = []
if model_name not in cls._register_fields[app_name]:
@@ -1182,36 +1507,43 @@ class CustomForm(models.Model):
if self.form not in self._register:
return []
current_form = register[self.form]
- app_name = current_form.__module__.split('.')[0]
+ app_name = current_form.__module__.split(".")[0]
if app_name == "archaeological_files_pdl":
app_name = "archaeological_files"
if app_name not in register_fields:
return []
res = []
for model_name in register_fields[app_name]:
- q = ContentType.objects.filter(app_label=app_name,
- model=model_name)
+ q = ContentType.objects.filter(app_label=app_name, model=model_name)
if not q.count():
continue
ct = q.all()[0]
for json_field in JsonDataField.objects.filter(
- content_type=ct).all():
- res.append((json_field.pk, "{} ({})".format(
- json_field.name,
- dict(JSON_VALUE_TYPES)[json_field.value_type])))
+ content_type=ct
+ ).all():
+ res.append(
+ (
+ json_field.pk,
+ "{} ({})".format(
+ json_field.name,
+ dict(JSON_VALUE_TYPES)[json_field.value_type],
+ ),
+ )
+ )
return res
class ExcludedFieldManager(models.Manager):
- def get_by_natural_key(self, custom_form_name, custom_form_form,
- field):
- return self.get(custom_form__name=custom_form_name,
- custom_form__form=custom_form_form,
- field=field)
+ def get_by_natural_key(self, custom_form_name, custom_form_form, field):
+ return self.get(
+ custom_form__name=custom_form_name,
+ custom_form__form=custom_form_form,
+ field=field,
+ )
class ExcludedField(models.Model):
- custom_form = models.ForeignKey(CustomForm, related_name='excluded_fields')
+ custom_form = models.ForeignKey(CustomForm, related_name="excluded_fields")
field = models.CharField(_("Field"), max_length=250)
objects = ExcludedFieldManager()
@@ -1221,29 +1553,33 @@ class ExcludedField(models.Model):
unique_together = ("custom_form", "field")
def natural_key(self):
- return (self.custom_form.name , self.custom_form.form,
- self.field)
+ return (self.custom_form.name, self.custom_form.form, self.field)
class CustomFormJsonFieldManager(models.Manager):
- def get_by_natural_key(self, custom_form_name, custom_form_form,
- json_field_key, json_field_app_label,
- json_field_model):
+ def get_by_natural_key(
+ self,
+ custom_form_name,
+ custom_form_form,
+ json_field_key,
+ json_field_app_label,
+ json_field_model,
+ ):
return self.get(
custom_form__name=custom_form_name,
custom_form__form=custom_form_form,
json_field__key=json_field_key,
json_field__content_type__app_label=json_field_app_label,
- json_field__content_type__model=json_field_model
+ json_field__content_type__model=json_field_model,
)
class CustomFormJsonField(models.Model):
- custom_form = models.ForeignKey(CustomForm, related_name='json_fields')
- json_field = models.ForeignKey(JsonDataField,
- related_name='custom_form_details')
- label = models.CharField(_("Label"), max_length=200, blank=True,
- default='')
+ custom_form = models.ForeignKey(CustomForm, related_name="json_fields")
+ json_field = models.ForeignKey(
+ JsonDataField, related_name="custom_form_details"
+ )
+ label = models.CharField(_("Label"), max_length=200, blank=True, default="")
order = models.IntegerField(verbose_name=_("Order"), default=1)
help_text = models.TextField(_("Help"), blank=True, default="")
objects = CustomFormJsonFieldManager()
@@ -1255,23 +1591,26 @@ class CustomFormJsonField(models.Model):
def natural_key(self):
return (
- self.custom_form.name, self.custom_form.form,
- self.json_field.key, self.json_field.content_type.app_label,
- self.json_field.content_type.model
+ self.custom_form.name,
+ self.custom_form.form,
+ self.json_field.key,
+ self.json_field.content_type.app_label,
+ self.json_field.content_type.model,
)
class GlobalVar(models.Model, Cached):
slug = models.SlugField(_("Variable name"), unique=True)
description = models.TextField(
- _("Description of the variable"), blank=True, default="")
+ _("Description of the variable"), blank=True, default=""
+ )
value = models.TextField(_("Value"), blank=True, default="")
objects = SlugModelManager()
class Meta:
verbose_name = _("Global variable")
verbose_name_plural = _("Global variables")
- ordering = ['slug']
+ ordering = ["slug"]
def natural_key(self):
return (self.slug,)
@@ -1281,9 +1620,9 @@ class GlobalVar(models.Model, Cached):
def cached_globalvar_changed(sender, **kwargs):
- if not kwargs['instance']:
+ if not kwargs["instance"]:
return
- var = kwargs['instance']
+ var = kwargs["instance"]
cache_key, value = get_cache(GlobalVar, var.slug)
cache.set(cache_key, var.value, settings.CACHE_TIMEOUT)
@@ -1293,10 +1632,12 @@ post_save.connect(cached_globalvar_changed, sender=GlobalVar)
class UserDashboard:
def __init__(self):
- types = IshtarUser.objects.values('person__person_types',
- 'person__person_types__label')
- self.types = types.annotate(number=Count('pk')) \
- .order_by('person__person_types')
+ types = IshtarUser.objects.values(
+ "person__person_types", "person__person_types__label"
+ )
+ self.types = types.annotate(number=Count("pk")).order_by(
+ "person__person_types"
+ )
class StatsCache(models.Model):
@@ -1312,8 +1653,9 @@ class StatsCache(models.Model):
class Dashboard(object):
- def __init__(self, model, slice='year', date_source=None, show_detail=None,
- fltr=None):
+ def __init__(
+ self, model, slice="year", date_source=None, show_detail=None, fltr=None
+ ):
if not fltr:
fltr = {}
# don't provide date_source if it is not relevant
@@ -1323,32 +1665,34 @@ class Dashboard(object):
history_model = self.model.history.model
# last edited - created
self.recents, self.lasts = [], []
- for last_lst, modif_type in ((self.lasts, '+'), (self.recents, '~')):
- last_ids = history_model.objects.values('id') \
- .annotate(hd=Max('history_date'))
+ for last_lst, modif_type in ((self.lasts, "+"), (self.recents, "~")):
+ last_ids = history_model.objects.values("id").annotate(
+ hd=Max("history_date")
+ )
last_ids = last_ids.filter(history_type=modif_type)
from archaeological_finds.models import Find
+
if self.model == Find:
- last_ids = last_ids.filter(
- downstream_treatment_id__isnull=True)
- if modif_type == '+':
+ last_ids = last_ids.filter(downstream_treatment_id__isnull=True)
+ if modif_type == "+":
last_ids = last_ids.filter(
- upstream_treatment_id__isnull=True)
- last_ids = last_ids.order_by('-hd').distinct().all()[:5]
+ upstream_treatment_id__isnull=True
+ )
+ last_ids = last_ids.order_by("-hd").distinct().all()[:5]
for idx in last_ids:
try:
- obj = self.model.objects.get(pk=idx['id'])
+ obj = self.model.objects.get(pk=idx["id"])
except self.model.DoesNotExist:
# deleted object are always referenced in history
continue
- obj.history_date = idx['hd']
+ obj.history_date = idx["hd"]
last_lst.append(obj)
# years
- base_kwargs = {'fltr': fltr.copy()}
+ base_kwargs = {"fltr": fltr.copy()}
if date_source:
- base_kwargs['date_source'] = date_source
+ base_kwargs["date_source"] = date_source
periods_kwargs = copy.deepcopy(base_kwargs)
- periods_kwargs['slice'] = slice
+ periods_kwargs["slice"] = slice
self.periods = model.get_periods(**periods_kwargs)
self.periods = list(set(self.periods))
self.periods.sort()
@@ -1357,36 +1701,45 @@ class Dashboard(object):
kwargs_num = copy.deepcopy(base_kwargs)
self.serie_labels = [_("Total")]
# numbers
- if slice == 'year':
- self.values = [('year', "",
- list(reversed(self.periods)))]
- self.numbers = [model.get_by_year(year, **kwargs_num).count()
- for year in self.periods]
- self.values += [('number', _("Number"),
- list(reversed(self.numbers)))]
- if slice == 'month':
+ if slice == "year":
+ self.values = [("year", "", list(reversed(self.periods)))]
+ self.numbers = [
+ model.get_by_year(year, **kwargs_num).count()
+ for year in self.periods
+ ]
+ self.values += [
+ ("number", _("Number"), list(reversed(self.numbers)))
+ ]
+ if slice == "month":
periods = list(reversed(self.periods))
- self.periods = ["%d-%s-01" % (p[0], ('0' + str(p[1]))
- if len(str(p[1])) == 1 else p[1]) for p in periods]
- self.values = [('month', "", self.periods)]
+ self.periods = [
+ "%d-%s-01"
+ % (p[0], ("0" + str(p[1])) if len(str(p[1])) == 1 else p[1])
+ for p in periods
+ ]
+ self.values = [("month", "", self.periods)]
if show_detail:
for dpt, lbl in settings.ISHTAR_DPTS:
self.serie_labels.append(str(dpt))
- idx = 'number_' + str(dpt)
- kwargs_num['fltr']["towns__numero_insee__startswith"] = \
- str(dpt)
- numbers = [model.get_by_month(*p.split('-')[:2],
- **kwargs_num).count()
- for p in self.periods]
+ idx = "number_" + str(dpt)
+ kwargs_num["fltr"]["towns__numero_insee__startswith"] = str(
+ dpt
+ )
+ numbers = [
+ model.get_by_month(
+ *p.split("-")[:2], **kwargs_num
+ ).count()
+ for p in self.periods
+ ]
self.values += [(idx, dpt, list(numbers))]
# put "Total" at the end
self.serie_labels.append(self.serie_labels.pop(0))
kwargs_num = base_kwargs.copy()
- self.numbers = [model.get_by_month(*p.split('-')[:2],
- **kwargs_num).count()
- for p in self.periods]
- self.values += [('number', _("Total"),
- list(self.numbers))]
+ self.numbers = [
+ model.get_by_month(*p.split("-")[:2], **kwargs_num).count()
+ for p in self.periods
+ ]
+ self.values += [("number", _("Total"), list(self.numbers))]
# calculate
self.average = self.get_average()
self.variance = self.get_variance()
@@ -1394,23 +1747,28 @@ class Dashboard(object):
self.median = self.get_median()
self.mode = self.get_mode()
# by operation
- if not hasattr(model, 'get_by_operation'):
+ if not hasattr(model, "get_by_operation"):
return
operations = model.get_operations()
- operation_numbers = [model.get_by_operation(op).count()
- for op in operations]
+ operation_numbers = [
+ model.get_by_operation(op).count() for op in operations
+ ]
# calculate
self.operation_average = self.get_average(operation_numbers)
self.operation_variance = self.get_variance(operation_numbers)
self.operation_standard_deviation = self.get_standard_deviation(
- operation_numbers)
+ operation_numbers
+ )
self.operation_median = self.get_median(operation_numbers)
- operation_mode_pk = self.get_mode(dict(zip(operations,
- operation_numbers)))
+ operation_mode_pk = self.get_mode(
+ dict(zip(operations, operation_numbers))
+ )
if operation_mode_pk:
from archaeological_operations.models import Operation
+
self.operation_mode = str(
- Operation.objects.get(pk=operation_mode_pk))
+ Operation.objects.get(pk=operation_mode_pk)
+ )
def get_average(self, vals=None):
if not vals:
@@ -1436,8 +1794,7 @@ class Dashboard(object):
if (len_vals % 2) == 1:
return vals[int(len_vals / 2)]
else:
- return (vals[int(len_vals / 2) - 1] +
- vals[int(len_vals / 2)]) / 2.0
+ return (vals[int(len_vals / 2) - 1] + vals[int(len_vals / 2)]) / 2.0
def get_mode(self, vals=None):
if not vals:
@@ -1453,34 +1810,47 @@ class DocumentTemplate(models.Model):
slug = models.SlugField(_("Slug"), max_length=100, unique=True)
associated_model = models.ForeignKey(ImporterModel)
template = models.FileField(
- _("Template"), upload_to="templates/%Y/", blank=True, null=True,
- help_text=max_size_help())
+ _("Template"),
+ upload_to="templates/%Y/",
+ blank=True,
+ null=True,
+ help_text=max_size_help(),
+ )
label_template = models.FileField(
- _("Base template for labels"), upload_to="templates/%Y/",
- blank=True, null=True, help_text=max_size_help())
+ _("Base template for labels"),
+ upload_to="templates/%Y/",
+ blank=True,
+ null=True,
+ help_text=max_size_help(),
+ )
label_targets = models.TextField(
_("Labels: targets for labels in the LibreOffice file"),
- blank=True, null=True,
- help_text=_("Each target is separated by a semi-colon. The first "
- "target is the name of the object including the data in "
- "base template. Following targets will be filled with the "
- "content of the first target. For instance: "
- "\"Cadre1;Cadre2;Cadre3;Cadre4;Cadre5;Cadre6\" for a "
- "sheet with 6 labels.")
+ blank=True,
+ null=True,
+ help_text=_(
+ "Each target is separated by a semi-colon. The first "
+ "target is the name of the object including the data in "
+ "base template. Following targets will be filled with the "
+ "content of the first target. For instance: "
+ '"Cadre1;Cadre2;Cadre3;Cadre4;Cadre5;Cadre6" for a '
+ "sheet with 6 labels."
+ ),
)
available = models.BooleanField(_("Available"), default=True)
for_labels = models.BooleanField(_("Used for labels"), default=False)
label_per_page = models.IntegerField(
- _("Number of label per page"), blank=True, null=True,
- help_text=_("Only relevant for label template")
+ _("Number of label per page"),
+ blank=True,
+ null=True,
+ help_text=_("Only relevant for label template"),
)
objects = SlugModelManager()
- SERIALIZATION_FILES = ("template", )
+ SERIALIZATION_FILES = ("template",)
class Meta:
verbose_name = _("Document template")
verbose_name_plural = _("Document templates")
- ordering = ['associated_model', 'name']
+ ordering = ["associated_model", "name"]
def __str__(self):
return self.name
@@ -1490,8 +1860,12 @@ class DocumentTemplate(models.Model):
def clean(self):
if self.for_labels and not self.label_per_page:
- raise ValidationError(_("For label template, you must provide "
- "number of label per page."))
+ raise ValidationError(
+ _(
+ "For label template, you must provide "
+ "number of label per page."
+ )
+ )
def generate_label_template(self):
if not self.label_template.name or not self.label_targets:
@@ -1500,10 +1874,11 @@ class DocumentTemplate(models.Model):
base_target = targets[0]
try:
with zipfile.ZipFile(self.label_template.path) as zip:
- with zip.open('content.xml') as content:
- soup = BeautifulSoup(content.read(), 'xml')
+ with zip.open("content.xml") as content:
+ soup = BeautifulSoup(content.read(), "xml")
base_content = soup.find(
- "draw:frame", attrs={"draw:name": base_target})
+ "draw:frame", attrs={"draw:name": base_target}
+ )
if not base_content:
return
base_content = base_content.contents
@@ -1520,12 +1895,13 @@ class DocumentTemplate(models.Model):
fixed_text = text.replace("items.0", replace_str)
text.replace_with(fixed_text)
for image in content.find_all(
- attrs={"draw:name": re.compile("items.0")}):
- image["draw:name"] = image["draw:name"].replace("items.0",
- replace_str)
+ attrs={"draw:name": re.compile("items.0")}
+ ):
+ image["draw:name"] = image["draw:name"].replace(
+ "items.0", replace_str
+ )
new_content.append(content)
- next_target = soup.find(
- "draw:frame", attrs={"draw:name": target})
+ next_target = soup.find("draw:frame", attrs={"draw:name": target})
if next_target:
next_target.contents = new_content
@@ -1536,15 +1912,15 @@ class DocumentTemplate(models.Model):
sp[-2] += "-label"
new_filename = ".".join(sp)
new_file = os.path.join(tmp, new_filename)
- with zipfile.ZipFile(new_file, 'w') as zip_out:
- with zipfile.ZipFile(self.label_template.path, 'r') as zip_in:
+ with zipfile.ZipFile(new_file, "w") as zip_out:
+ with zipfile.ZipFile(self.label_template.path, "r") as zip_in:
zip_out.comment = zip_in.comment
for item in zip_in.infolist():
if item.filename != "content.xml":
- zip_out.writestr(item,
- zip_in.read(item.filename))
- with zipfile.ZipFile(new_file, mode='a',
- compression=zipfile.ZIP_DEFLATED) as zf:
+ zip_out.writestr(item, zip_in.read(item.filename))
+ with zipfile.ZipFile(
+ new_file, mode="a", compression=zipfile.ZIP_DEFLATED
+ ) as zf:
zf.writestr("content.xml", str(soup))
media_dir = "templates/{}/".format(datetime.date.today().year)
@@ -1569,23 +1945,26 @@ class DocumentTemplate(models.Model):
if not self.slug:
self.slug = create_slug(DocumentTemplate, self.name)
super(DocumentTemplate, self).save(*args, **kwargs)
- if self.label_template.name and self.label_targets and not \
- self.template:
+ if (
+ self.label_template.name
+ and self.label_targets
+ and not self.template
+ ):
self.generate_label_template()
@classmethod
def get_tuples(cls, dct=None, empty_first=True):
if not dct:
dct = {}
- dct['available'] = True
+ dct["available"] = True
if empty_first:
- yield '', '----------'
+ yield "", "----------"
items = cls.objects.filter(**dct)
for item in items.distinct().order_by(*cls._meta.ordering).all():
yield item.pk, _(str(item))
def get_baselink_for_labels(self):
- return reverse('generate-labels', args=[self.slug])
+ return reverse("generate-labels", args=[self.slug])
def _exclude_filter(self, value):
"""
@@ -1604,36 +1983,48 @@ class DocumentTemplate(models.Model):
if not regexp_list:
return None
z = zipfile.ZipFile(template)
- content = z.open('content.xml')
+ content = z.open("content.xml")
full_content = content.read().decode("utf-8")
filtr = []
for regexp in regexp_list:
- iter = re.finditer(
- regexp,
- full_content)
+ iter = re.finditer(regexp, full_content)
for s in iter:
key = s.groups()[0]
if key not in filtr:
filtr.append(key)
new_filter = []
- OPERATORS = ["==", "not", "in", "&gt;", "&lt;", "!=", ">", "<", ">=",
- "<=", "or", "&gt;=", "&lt;="]
+ OPERATORS = [
+ "==",
+ "not",
+ "in",
+ "&gt;",
+ "&lt;",
+ "!=",
+ ">",
+ "<",
+ ">=",
+ "<=",
+ "or",
+ "&gt;=",
+ "&lt;=",
+ ]
for fil in filtr:
if not fil:
continue
- new_filter += [f for f in fil.split(" ")
- if f and f not in OPERATORS]
+ new_filter += [
+ f for f in fil.split(" ") if f and f not in OPERATORS
+ ]
filtr = new_filter
new_filter = []
for fil in filtr:
- keys = fil.strip().split("|")[0].split('.')
+ keys = fil.strip().split("|")[0].split(".")
new_filter += [k for k in keys if not self._exclude_filter(k)]
prefix = ""
for k in keys:
if self._exclude_filter(k):
continue
if prefix:
- prefix += '_'
+ prefix += "_"
if prefix + k in new_filter:
continue
new_filter.append(prefix + k)
@@ -1643,28 +2034,36 @@ class DocumentTemplate(models.Model):
ITEM_RE = r"([A-Za-z0-9_.]*)(?:[\[\]0-9-:])*(?:\|[^}]+)*"
BASE_RE = [
# {{ key1.key2 }}
- r'{{ *' + ITEM_RE + ' *}}',
+ r"{{ *" + ITEM_RE + " *}}",
# {% for item in key1.key2 %}
- r'{% *for +[A-Za-z0-9_]+ +in +' + ITEM_RE + r' *%}',
+ r"{% *for +[A-Za-z0-9_]+ +in +" + ITEM_RE + r" *%}",
# {% if ** %}
- r'{% (?:el)*if ([^}]*)%}',
- ]
+ r"{% (?:el)*if ([^}]*)%}",
+ ]
def publish(self, c_object):
tempdir = tempfile.mkdtemp("-ishtardocs")
- output_name = tempdir + os.path.sep + \
- slugify(self.name.replace(' ', '_').lower()) + '-' + \
- datetime.date.today().strftime('%Y-%m-%d') + \
- "." + self.template.name.split('.')[-1]
+ output_name = (
+ tempdir
+ + os.path.sep
+ + slugify(self.name.replace(" ", "_").lower())
+ + "-"
+ + datetime.date.today().strftime("%Y-%m-%d")
+ + "."
+ + self.template.name.split(".")[-1]
+ )
filtr = self.get_filter(self.template, self.BASE_RE)
# values = c_object.get_values(filtr=[])
if "VALUES" in filtr:
filtr = []
values = c_object.get_values(filtr=filtr)
- if not filtr or 'VALUES' in filtr:
- values['VALUES'] = json.dumps(
- values, indent=4, sort_keys=True,
- skipkeys=True, ensure_ascii=False,
+ if not filtr or "VALUES" in filtr:
+ values["VALUES"] = json.dumps(
+ values,
+ indent=4,
+ sort_keys=True,
+ skipkeys=True,
+ ensure_ascii=False,
separators=("", " : "),
).replace(" " * 4, "\t")
engine = IshtarSecretaryRenderer()
@@ -1676,28 +2075,32 @@ class DocumentTemplate(models.Model):
raise TemplateSyntaxError(str(e), 0)
except Exception as e:
raise TemplateSyntaxError(str(e), 0)
- with open(output_name, 'wb') as output:
+ with open(output_name, "wb") as output:
output.write(result)
return output_name
LABEL_ITEM_RE = r"items\.\d\.([A-Za-z0-9_.]*)(?:[\[\]0-9-:])*(?:\|[^}]+)*"
LABEL_RE = [
# {{items.4.key}}
- r'{{ *' + LABEL_ITEM_RE + r' *}}',
+ r"{{ *" + LABEL_ITEM_RE + r" *}}",
# {% if ** %}
- r'{% (?:el)*if ([^}]*)%}',
+ r"{% (?:el)*if ([^}]*)%}",
# {% for item in items.42.another_keys %}
- r'{% *for +[A-Za-z0-9_]+ +in +' + LABEL_ITEM_RE + r' *%}',
+ r"{% *for +[A-Za-z0-9_]+ +in +" + LABEL_ITEM_RE + r" *%}",
]
def publish_labels(self, objects):
if not objects:
return
tempdir = tempfile.mkdtemp("-ishtarlabels")
- main_output_name = tempdir + os.path.sep + \
- slugify(self.name.replace(' ', '_').lower()) + '-' + \
- datetime.datetime.now().strftime('%Y-%m-%d-%H%M%S')
- suffix = "." + self.template.name.split('.')[-1]
+ main_output_name = (
+ tempdir
+ + os.path.sep
+ + slugify(self.name.replace(" ", "_").lower())
+ + "-"
+ + datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S")
+ )
+ suffix = "." + self.template.name.split(".")[-1]
len_objects = len(objects)
names = []
@@ -1719,7 +2122,7 @@ class DocumentTemplate(models.Model):
raise TemplateSyntaxError(str(e), e.lineno)
output_name = main_output_name + "-" + str(idx) + suffix
names.append(output_name)
- with open(output_name, 'wb') as output:
+ with open(output_name, "wb") as output:
output.write(result)
output_name = main_output_name + suffix
o = OOoPy(infile=names[0], outfile=output_name)
@@ -1731,28 +2134,34 @@ class DocumentTemplate(models.Model):
OOTransforms.renumber_all(o.mimetype),
OOTransforms.set_meta(o.mimetype),
OOTransforms.Fix_OOo_Tag(),
- OOTransforms.Manifest_Append()
+ OOTransforms.Manifest_Append(),
)
- t.transform (o)
+ t.transform(o)
o.close()
return output_name
class Area(HierarchicalType):
- towns = models.ManyToManyField(Town, verbose_name=_("Towns"), blank=True,
- related_name='areas')
- reference = models.CharField(_("Reference"), max_length=200, blank=True,
- null=True)
+ towns = models.ManyToManyField(
+ Town, verbose_name=_("Towns"), blank=True, related_name="areas"
+ )
+ reference = models.CharField(
+ _("Reference"), max_length=200, blank=True, null=True
+ )
parent = models.ForeignKey(
- 'self', blank=True, null=True, verbose_name=_("Parent"),
+ "self",
+ blank=True,
+ null=True,
+ verbose_name=_("Parent"),
help_text=_("Only four level of parent are managed."),
- related_name='children', on_delete=models.SET_NULL
+ related_name="children",
+ on_delete=models.SET_NULL,
)
class Meta:
verbose_name = _("Area")
verbose_name_plural = _("Areas")
- ordering = ('label',)
+ ordering = ("label",)
def __str__(self):
if not self.reference:
@@ -1785,7 +2194,7 @@ def documentation_get_gender_values():
class BaseGenderedType(ValueGetter):
- def get_values(self, prefix='', **kwargs):
+ def get_values(self, prefix="", **kwargs):
dct = super(BaseGenderedType, self).get_values(prefix=prefix, **kwargs)
assert hasattr(self, "grammatical_gender")
dct[prefix + "grammatical_gender"] = self.grammatical_gender
@@ -1794,8 +2203,13 @@ class BaseGenderedType(ValueGetter):
class GenderedType(BaseGenderedType, GeneralType):
grammatical_gender = models.CharField(
- _("Grammatical gender"), max_length=1, choices=GENDER,
- blank=True, default="", help_text=documentation_get_gender_values)
+ _("Grammatical gender"),
+ max_length=1,
+ choices=GENDER,
+ blank=True,
+ default="",
+ help_text=documentation_get_gender_values,
+ )
class Meta:
abstract = True
@@ -1815,7 +2229,7 @@ class OrganizationType(GenderedType):
class Meta:
verbose_name = _("Organization type")
verbose_name_plural = _("Organization types")
- ordering = ('label',)
+ ordering = ("label",)
def get_orga_planning_service_label():
@@ -1841,52 +2255,62 @@ organization_type_pk_lazy = lazy(OrganizationType.get_or_create_pk, str)
organization_type_pks_lazy = lazy(OrganizationType.get_or_create_pks, str)
-class Organization(Address, Merge, OwnPerms, BaseGenderedType, ValueGetter,
- MainItem):
- TABLE_COLS = ('name', 'organization_type', 'town')
+class Organization(
+ Address, Merge, OwnPerms, BaseGenderedType, ValueGetter, MainItem
+):
+ TABLE_COLS = ("name", "organization_type", "town")
SLUG = "organization"
- SHOW_URL = 'show-organization'
- DELETE_URL = 'delete-organization'
+ SHOW_URL = "show-organization"
+ DELETE_URL = "delete-organization"
# search parameters
EXTRA_REQUEST_KEYS = {}
- BASE_SEARCH_VECTORS = [SearchVectorConfig('name'),
- SearchVectorConfig('town')]
+ BASE_SEARCH_VECTORS = [
+ SearchVectorConfig("name"),
+ SearchVectorConfig("town"),
+ ]
# alternative names of fields for searches
ALT_NAMES = {
- 'name': SearchAltName(
- pgettext_lazy("key for text search", "name"),
- 'name__iexact'
+ "name": SearchAltName(
+ pgettext_lazy("key for text search", "name"), "name__iexact"
),
- 'organization_type': SearchAltName(
+ "organization_type": SearchAltName(
pgettext_lazy("key for text search", "type"),
- 'organization_type__label__iexact'
+ "organization_type__label__iexact",
),
}
QA_EDIT = QuickAction(
- url="organization-qa-bulk-update", icon_class="fa fa-pencil",
- text=_("Bulk update"), target="many",
- rights=['change_organization'])
- QUICK_ACTIONS = [
- QA_EDIT
- ]
+ url="organization-qa-bulk-update",
+ icon_class="fa fa-pencil",
+ text=_("Bulk update"),
+ target="many",
+ rights=["change_organization"],
+ )
+ QUICK_ACTIONS = [QA_EDIT]
objects = UUIDModelManager()
# fields
uuid = models.UUIDField(default=uuid.uuid4)
name = models.CharField(_("Name"), max_length=500)
- organization_type = models.ForeignKey(OrganizationType,
- verbose_name=_("Type"))
+ organization_type = models.ForeignKey(
+ OrganizationType, verbose_name=_("Type")
+ )
url = models.URLField(verbose_name=_("Web address"), blank=True, null=True)
grammatical_gender = models.CharField(
- _("Grammatical gender"), max_length=1, choices=GENDER,
- blank=True, default="", help_text=documentation_get_gender_values)
- cached_label = models.TextField(_("Cached name"), blank=True, default="",
- db_index=True)
+ _("Grammatical gender"),
+ max_length=1,
+ choices=GENDER,
+ blank=True,
+ default="",
+ help_text=documentation_get_gender_values,
+ )
+ cached_label = models.TextField(
+ _("Cached name"), blank=True, default="", db_index=True
+ )
- DOWN_MODEL_UPDATE = ['members']
+ DOWN_MODEL_UPDATE = ["members"]
class Meta:
verbose_name = _("Organization")
@@ -1899,14 +2323,13 @@ class Organization(Address, Merge, OwnPerms, BaseGenderedType, ValueGetter,
("delete_own_organization", "Can delete own Organization"),
)
indexes = [
- GinIndex(fields=['data']),
+ GinIndex(fields=["data"]),
]
def simple_lbl(self):
if self.name:
return self.name
- return "{} - {}".format(self.organization_type,
- self.town or "")
+ return "{} - {}".format(self.organization_type, self.town or "")
def natural_key(self):
return (self.uuid,)
@@ -1918,33 +2341,36 @@ class Organization(Address, Merge, OwnPerms, BaseGenderedType, ValueGetter,
if self.name:
return self.name
attrs = ["organization_type", "address", "town"]
- items = [str(getattr(self, attr))
- for attr in attrs if getattr(self, attr)]
+ items = [
+ str(getattr(self, attr)) for attr in attrs if getattr(self, attr)
+ ]
if not items:
items = [str(_("unknown organization"))]
return " - ".join(items)
def generate_merge_key(self):
- self.merge_key = slugify(self.name or '')
+ self.merge_key = slugify(self.name or "")
if not self.merge_key:
self.merge_key = self.EMPTY_MERGE_KEY
if self.town:
- self.merge_key += "-" + slugify(self.town or '')
+ self.merge_key += "-" + slugify(self.town or "")
if self.address:
- self.merge_key += "-" + slugify(self.address or '')
+ self.merge_key += "-" + slugify(self.address or "")
@property
def associated_filename(self):
- values = [str(getattr(self, attr))
- for attr in ('organization_type', 'name')
- if getattr(self, attr)]
+ values = [
+ str(getattr(self, attr))
+ for attr in ("organization_type", "name")
+ if getattr(self, attr)
+ ]
return slugify("-".join(values))
@classmethod
@pre_importer_action
def import_get_publisher_type(cls, context, value):
if context["name"]:
- q = OrganizationType.objects.filter(txt_idx='publisher')
+ q = OrganizationType.objects.filter(txt_idx="publisher")
if not q.count():
return
context["organization_type"] = q.all()[0]
@@ -1957,7 +2383,7 @@ class PersonType(GeneralType):
class Meta:
verbose_name = _("Person type")
verbose_name_plural = _("Person types")
- ordering = ('label',)
+ ordering = ("label",)
post_save.connect(post_save_cache, sender=PersonType)
@@ -2030,7 +2456,7 @@ class TitleType(GenderedType):
class Meta:
verbose_name = _("Title type")
verbose_name_plural = _("Title types")
- ordering = ('label',)
+ ordering = ("label",)
@classmethod
def get_documentation_string(cls):
@@ -2041,7 +2467,7 @@ class TitleType(GenderedType):
doc += ", **long_title** {}".format(_("Long title"))
return doc
- def get_values(self, prefix='', **kwargs):
+ def get_values(self, prefix="", **kwargs):
dct = super(TitleType, self).get_values(prefix=prefix, **kwargs)
dct[prefix + "long_title"] = self.long_title
return dct
@@ -2053,109 +2479,139 @@ post_delete.connect(post_save_cache, sender=TitleType)
class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
SLUG = "person"
- _prefix = 'person_'
+ _prefix = "person_"
TYPE = (
- ('Mr', _('Mr')),
- ('Ms', _('Miss')),
- ('Mr and Miss', _('Mr and Mrs')),
- ('Md', _('Mrs')),
- ('Dr', _('Doctor')),
- )
- TABLE_COLS = ('name', 'surname', 'raw_name', 'email', 'person_types_list',
- 'attached_to', 'town')
- TABLE_COLS_ACCOUNT = ('name', 'surname', 'raw_name', 'email',
- 'profiles_list', 'attached_to', 'town')
- SHOW_URL = 'show-person'
- MODIFY_URL = 'person_modify'
- DELETE_URL = 'person_delete'
+ ("Mr", _("Mr")),
+ ("Ms", _("Miss")),
+ ("Mr and Miss", _("Mr and Mrs")),
+ ("Md", _("Mrs")),
+ ("Dr", _("Doctor")),
+ )
+ TABLE_COLS = (
+ "name",
+ "surname",
+ "raw_name",
+ "email",
+ "person_types_list",
+ "attached_to",
+ "town",
+ )
+ TABLE_COLS_ACCOUNT = (
+ "name",
+ "surname",
+ "raw_name",
+ "email",
+ "profiles_list",
+ "attached_to",
+ "town",
+ )
+ SHOW_URL = "show-person"
+ MODIFY_URL = "person_modify"
+ DELETE_URL = "person_delete"
BASE_SEARCH_VECTORS = [
- SearchVectorConfig('name'),
- SearchVectorConfig('surname'),
- SearchVectorConfig('raw_name'),
- SearchVectorConfig('town'),
- SearchVectorConfig('attached_to__name'),
- SearchVectorConfig('email')]
+ SearchVectorConfig("name"),
+ SearchVectorConfig("surname"),
+ SearchVectorConfig("raw_name"),
+ SearchVectorConfig("town"),
+ SearchVectorConfig("attached_to__name"),
+ SearchVectorConfig("email"),
+ ]
# search parameters
- REVERSED_BOOL_FIELDS = ['ishtaruser__isnull']
+ REVERSED_BOOL_FIELDS = ["ishtaruser__isnull"]
EXTRA_REQUEST_KEYS = {
- 'ishtaruser__isnull': 'ishtaruser__isnull',
- 'attached_to': 'attached_to',
- }
- COL_LABELS = {
- 'attached_to': _("Organization")
+ "ishtaruser__isnull": "ishtaruser__isnull",
+ "attached_to": "attached_to",
}
+ COL_LABELS = {"attached_to": _("Organization")}
# alternative names of fields for searches
ALT_NAMES = {
- 'name': SearchAltName(
- pgettext_lazy("key for text search", "name"),
- 'name__iexact'
+ "name": SearchAltName(
+ pgettext_lazy("key for text search", "name"), "name__iexact"
),
- 'surname': SearchAltName(
- pgettext_lazy("key for text search", "surname"),
- 'surname__iexact'
+ "surname": SearchAltName(
+ pgettext_lazy("key for text search", "surname"), "surname__iexact"
),
- 'email': SearchAltName(
- pgettext_lazy("key for text search", "email"),
- 'email__iexact'
+ "email": SearchAltName(
+ pgettext_lazy("key for text search", "email"), "email__iexact"
),
- 'person_types': SearchAltName(
+ "person_types": SearchAltName(
pgettext_lazy("key for text search", "type"),
- 'person_types__label__iexact'
+ "person_types__label__iexact",
),
- 'attached_to': SearchAltName(
+ "attached_to": SearchAltName(
pgettext_lazy("key for text search", "organization"),
- 'attached_to__cached_label__iexact'
+ "attached_to__cached_label__iexact",
),
- 'ishtaruser__isnull': SearchAltName(
+ "ishtaruser__isnull": SearchAltName(
pgettext_lazy("key for text search", "has-account"),
- 'ishtaruser__isnull'
+ "ishtaruser__isnull",
),
}
QA_EDIT = QuickAction(
- url="person-qa-bulk-update", icon_class="fa fa-pencil",
- text=_("Bulk update"), target="many",
- rights=['change_person'])
- QUICK_ACTIONS = [
- QA_EDIT
- ]
+ url="person-qa-bulk-update",
+ icon_class="fa fa-pencil",
+ text=_("Bulk update"),
+ target="many",
+ rights=["change_person"],
+ )
+ QUICK_ACTIONS = [QA_EDIT]
objects = UUIDModelManager()
# fields
uuid = models.UUIDField(default=uuid.uuid4)
- old_title = models.CharField(_("Title"), max_length=100, choices=TYPE,
- blank=True, null=True)
- title = models.ForeignKey(TitleType, verbose_name=_("Title"),
- on_delete=models.SET_NULL,
- blank=True, null=True)
- salutation = models.CharField(_("Salutation"), max_length=200,
- blank=True, null=True)
+ old_title = models.CharField(
+ _("Title"), max_length=100, choices=TYPE, blank=True, null=True
+ )
+ title = models.ForeignKey(
+ TitleType,
+ verbose_name=_("Title"),
+ on_delete=models.SET_NULL,
+ blank=True,
+ null=True,
+ )
+ salutation = models.CharField(
+ _("Salutation"), max_length=200, blank=True, null=True
+ )
surname = models.CharField(
- _("Surname"), max_length=50, blank=True, null=True,
- help_text=_("Attention, historical and unfortunate residue in the "
- "code of an initial translation error."))
- name = models.CharField(_("Name"), max_length=200, blank=True,
- null=True)
- raw_name = models.CharField(_("Raw name"), max_length=300, blank=True,
- null=True)
- contact_type = models.CharField(_("Contact type"), max_length=300,
- blank=True, null=True)
+ _("Surname"),
+ max_length=50,
+ blank=True,
+ null=True,
+ help_text=_(
+ "Attention, historical and unfortunate residue in the "
+ "code of an initial translation error."
+ ),
+ )
+ name = models.CharField(_("Name"), max_length=200, blank=True, null=True)
+ raw_name = models.CharField(
+ _("Raw name"), max_length=300, blank=True, null=True
+ )
+ contact_type = models.CharField(
+ _("Contact type"), max_length=300, blank=True, null=True
+ )
comment = models.TextField(_("Comment"), blank=True, default="")
person_types = models.ManyToManyField(PersonType, verbose_name=_("Types"))
attached_to = models.ForeignKey(
- 'Organization', related_name='members', on_delete=models.SET_NULL,
- verbose_name=_("Is attached to"), blank=True, null=True)
- cached_label = models.TextField(_("Cached name"), blank=True, default="",
- db_index=True)
+ "Organization",
+ related_name="members",
+ on_delete=models.SET_NULL,
+ verbose_name=_("Is attached to"),
+ blank=True,
+ null=True,
+ )
+ cached_label = models.TextField(
+ _("Cached name"), blank=True, default="", db_index=True
+ )
DOWN_MODEL_UPDATE = ["author"]
class Meta:
verbose_name = _("Person")
verbose_name_plural = _("Persons")
indexes = [
- GinIndex(fields=['data']),
+ GinIndex(fields=["data"]),
]
permissions = (
("view_person", "Can view all Persons"),
@@ -2176,7 +2632,9 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
def full_title(self):
return " ".join(
str(getattr(self, attr))
- for attr in ['title', 'salutation'] if getattr(self, attr))
+ for attr in ["title", "salutation"]
+ if getattr(self, attr)
+ )
@property
def current_profile(self):
@@ -2202,13 +2660,18 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
return []
items.append(
"""<span class="organization">{}</span>""".format(
- self.attached_to.name))
+ self.attached_to.name
+ )
+ )
items += orga_address
return items
def simple_lbl(self):
- values = [str(getattr(self, attr)) for attr in ('surname', 'name')
- if getattr(self, attr)]
+ values = [
+ str(getattr(self, attr))
+ for attr in ("surname", "name")
+ if getattr(self, attr)
+ ]
if not values and self.raw_name:
values = [self.raw_name]
return " ".join(values)
@@ -2217,7 +2680,7 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
return self.cached_label or ""
def _generate_cached_label(self):
- lbl = get_generated_id('person_raw_name', self)
+ lbl = get_generated_id("person_raw_name", self)
if not lbl:
return "-"
if self.attached_to:
@@ -2227,8 +2690,11 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
def fancy_str(self):
values = ["<strong>"]
- values += [str(getattr(self, attr)) for attr in ('surname', 'name')
- if getattr(self, attr)]
+ values += [
+ str(getattr(self, attr))
+ for attr in ("surname", "name")
+ if getattr(self, attr)
+ ]
if not values and self.raw_name:
values += [self.raw_name]
values += ["</strong>"]
@@ -2236,16 +2702,18 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
if self.attached_to:
attached_to = str(self.attached_to)
if values:
- values.append('-')
+ values.append("-")
values.append(attached_to)
return " ".join(values)
- def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
values = super(Person, self).get_values(
- prefix=prefix, no_values=no_values, filtr=filtr, **kwargs)
+ prefix=prefix, no_values=no_values, filtr=filtr, **kwargs
+ )
if not self.attached_to:
values.update(
- Person.get_empty_values(prefix=prefix + 'attached_to_'))
+ Person.get_empty_values(prefix=prefix + "attached_to_")
+ )
return values
person_types_list_lbl = _("Types")
@@ -2262,9 +2730,9 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
def generate_merge_key(self):
if self.name and self.name.strip():
- self.merge_key = slugify(self.name.strip()) + \
- (('-' + slugify(self.surname.strip()))
- if self.surname else '')
+ self.merge_key = slugify(self.name.strip()) + (
+ ("-" + slugify(self.surname.strip())) if self.surname else ""
+ )
elif self.raw_name and self.raw_name.strip():
self.merge_key = slugify(self.raw_name.strip())
elif self.attached_to:
@@ -2278,46 +2746,67 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
return not self.attached_to
def has_right(self, right_name, session=None, obj=None):
- if '.' in right_name:
- right_name = right_name.split('.')[-1]
+ if "." in right_name:
+ right_name = right_name.split(".")[-1]
res, cache_key = "", ""
if session:
- cache_key = 'session-{}-{}'.format(session.session_key, right_name)
+ cache_key = "session-{}-{}".format(session.session_key, right_name)
res = cache.get(cache_key)
if res in (True, False):
return res
# list all cache key in order to clean them on profile change
- cache_key_list = 'sessionlist-{}'.format(session.session_key)
+ cache_key_list = "sessionlist-{}".format(session.session_key)
key_list = cache.get(cache_key_list, [])
key_list.append(cache_key)
cache.set(cache_key_list, key_list, settings.CACHE_TIMEOUT)
if type(right_name) in (list, tuple):
- res = bool(self.profiles.filter(
- current=True,
- profile_type__txt_idx__in=right_name).count()) or \
- bool(self.profiles.filter(
- current=True,
- profile_type__groups__permissions__codename__in=right_name
- ).count()) or \
- bool(self.ishtaruser.user_ptr.groups.filter(
- permissions__codename__in=right_name
- ).count()) or \
- bool(self.ishtaruser.user_ptr.user_permissions.filter(
- codename__in=right_name).count())
+ res = (
+ bool(
+ self.profiles.filter(
+ current=True, profile_type__txt_idx__in=right_name
+ ).count()
+ )
+ or bool(
+ self.profiles.filter(
+ current=True,
+ profile_type__groups__permissions__codename__in=right_name,
+ ).count()
+ )
+ or bool(
+ self.ishtaruser.user_ptr.groups.filter(
+ permissions__codename__in=right_name
+ ).count()
+ )
+ or bool(
+ self.ishtaruser.user_ptr.user_permissions.filter(
+ codename__in=right_name
+ ).count()
+ )
+ )
else:
- res = bool(
- self.profiles.filter(
- current=True,
- profile_type__txt_idx=right_name).count()) or \
- bool(self.profiles.filter(
- current=True,
- profile_type__groups__permissions__codename=right_name
- ).count()) or \
- bool(self.ishtaruser.user_ptr.groups.filter(
- permissions__codename__in=[right_name]
- ).count()) or \
- bool(self.ishtaruser.user_ptr.user_permissions.filter(
- codename__in=[right_name]).count())
+ res = (
+ bool(
+ self.profiles.filter(
+ current=True, profile_type__txt_idx=right_name
+ ).count()
+ )
+ or bool(
+ self.profiles.filter(
+ current=True,
+ profile_type__groups__permissions__codename=right_name,
+ ).count()
+ )
+ or bool(
+ self.ishtaruser.user_ptr.groups.filter(
+ permissions__codename__in=[right_name]
+ ).count()
+ )
+ or bool(
+ self.ishtaruser.user_ptr.user_permissions.filter(
+ codename__in=[right_name]
+ ).count()
+ )
+ )
if session:
cache.set(cache_key, res, settings.CACHE_TIMEOUT)
return res
@@ -2326,9 +2815,11 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
values = []
if self.title:
values = [self.title.label]
- values += [str(getattr(self, attr))
- for attr in ('salutation', 'surname', 'name')
- if getattr(self, attr)]
+ values += [
+ str(getattr(self, attr))
+ for attr in ("salutation", "surname", "name")
+ if getattr(self, attr)
+ ]
if not values and self.raw_name:
values = [self.raw_name]
if self.attached_to:
@@ -2337,9 +2828,11 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
@property
def associated_filename(self):
- values = [str(getattr(self, attr))
- for attr in ('surname', 'name', 'attached_to')
- if getattr(self, attr)]
+ values = [
+ str(getattr(self, attr))
+ for attr in ("surname", "name", "attached_to")
+ if getattr(self, attr)
+ ]
return slugify("-".join(values))
def docs_q(self):
@@ -2347,52 +2840,56 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
def operation_docs_q(self):
return Document.objects.filter(
- authors__person=self, operations__pk__isnull=False)
+ authors__person=self, operations__pk__isnull=False
+ )
def contextrecord_docs_q(self):
return Document.objects.filter(
- authors__person=self, context_records__pk__isnull=False)
+ authors__person=self, context_records__pk__isnull=False
+ )
def find_docs_q(self):
return Document.objects.filter(
- authors__person=self, finds__pk__isnull=False)
+ authors__person=self, finds__pk__isnull=False
+ )
def save(self, *args, **kwargs):
super(Person, self).save(*args, **kwargs)
- raw_name = get_generated_id('person_raw_name', self)
+ raw_name = get_generated_id("person_raw_name", self)
if raw_name and self.raw_name != raw_name:
self.raw_name = raw_name
self.save()
- if hasattr(self, 'responsible_town_planning_service'):
+ if hasattr(self, "responsible_town_planning_service"):
for fle in self.responsible_town_planning_service.all():
fle.save() # force update of raw_town_planning_service
- if hasattr(self, 'general_contractor'):
+ if hasattr(self, "general_contractor"):
for fle in self.general_contractor.all():
fle.save() # force update of raw_general_contractor
@classmethod
def get_query_owns(cls, ishtaruser):
- return \
- Q(operation_scientist_responsability__collaborators__ishtaruser
- =ishtaruser) | \
- Q(operation_scientist_responsability__scientist__ishtaruser
- =ishtaruser) | \
- Q(operation_collaborator__collaborators__ishtaruser
- =ishtaruser) | \
- Q(operation_collaborator__scientist__ishtaruser=ishtaruser)
+ return (
+ Q(
+ operation_scientist_responsability__collaborators__ishtaruser=ishtaruser
+ )
+ | Q(
+ operation_scientist_responsability__scientist__ishtaruser=ishtaruser
+ )
+ | Q(operation_collaborator__collaborators__ishtaruser=ishtaruser)
+ | Q(operation_collaborator__scientist__ishtaruser=ishtaruser)
+ )
post_save.connect(cached_label_changed, sender=Person)
class ProfileType(GeneralType):
- groups = models.ManyToManyField(Group, verbose_name=_("Groups"),
- blank=True)
+ groups = models.ManyToManyField(Group, verbose_name=_("Groups"), blank=True)
class Meta:
verbose_name = _("Profile type")
verbose_name_plural = _("Profile types")
- ordering = ('label',)
+ ordering = ("label",)
post_save.connect(post_save_cache, sender=ProfileType)
@@ -2409,36 +2906,42 @@ class ProfileTypeSummary(ProfileType):
class UserProfile(models.Model):
name = models.CharField(_("Name"), blank=True, default="", max_length=100)
profile_type = models.ForeignKey(
- ProfileType, verbose_name=_("Profile type"))
- areas = models.ManyToManyField("Area", verbose_name=_("Areas"),
- blank=True, related_name='profiles')
+ ProfileType, verbose_name=_("Profile type")
+ )
+ areas = models.ManyToManyField(
+ "Area", verbose_name=_("Areas"), blank=True, related_name="profiles"
+ )
current = models.BooleanField(_("Current profile"), default=False)
show_field_number = models.BooleanField(
- _("Show field number"), default=False)
+ _("Show field number"), default=False
+ )
auto_pin = models.BooleanField(_("Automatically pin"), default=False)
- display_pin_menu = models.BooleanField(_("Display pin menu"),
- default=False)
+ display_pin_menu = models.BooleanField(_("Display pin menu"), default=False)
person = models.ForeignKey(
- Person, verbose_name=_("Person"), related_name='profiles')
+ Person, verbose_name=_("Person"), related_name="profiles"
+ )
class Meta:
verbose_name = _("User profile")
verbose_name_plural = _("User profiles")
- unique_together = (('name', 'profile_type', 'person'),)
+ unique_together = (("name", "profile_type", "person"),)
def __str__(self):
lbl = self.name or str(self.profile_type)
if not self.areas.count():
return lbl
- return "{} ({})".format(lbl, ", ".join(str(area) for area in self.areas.all()))
+ return "{} ({})".format(
+ lbl, ", ".join(str(area) for area in self.areas.all())
+ )
@property
def query_towns(self):
return Town.objects.filter(
- Q(areas__profiles=self) | Q(areas__parent__profiles=self) |
- Q(areas__parent__parent__profiles=self) |
- Q(areas__parent__parent__parent__profiles=self) |
- Q(areas__parent__parent__parent__parent__profiles=self)
+ Q(areas__profiles=self)
+ | Q(areas__parent__profiles=self)
+ | Q(areas__parent__parent__profiles=self)
+ | Q(areas__parent__parent__parent__profiles=self)
+ | Q(areas__parent__parent__parent__parent__profiles=self)
)
@property
@@ -2451,12 +2954,12 @@ class UserProfile(models.Model):
new_item.pk = None
name = self.name
for key in kwargs:
- if key == 'name':
+ if key == "name":
name = kwargs[key]
setattr(new_item, key, kwargs[key])
while UserProfile.objects.filter(
- name=name, profile_type=self.profile_type,
- person=self.person).count():
+ name=name, profile_type=self.profile_type, person=self.person
+ ).count():
name += str(_(" - duplicate"))
new_item.name = name
new_item.save()
@@ -2464,17 +2967,26 @@ class UserProfile(models.Model):
new_item.areas.add(area)
return new_item
- def save(self, force_insert=False, force_update=False, using=None,
- update_fields=None):
+ def save(
+ self,
+ force_insert=False,
+ force_update=False,
+ using=None,
+ update_fields=None,
+ ):
super(UserProfile, self).save(
- force_insert=force_insert, force_update=force_update, using=using,
- update_fields=update_fields)
+ force_insert=force_insert,
+ force_update=force_update,
+ using=using,
+ update_fields=update_fields,
+ )
# only one current profile per user
if not self.current:
return
q = UserProfile.objects.filter(
- person=self.person, current=True).exclude(pk=self.pk)
+ person=self.person, current=True
+ ).exclude(pk=self.pk)
if not q.count():
return
for p in q.all():
@@ -2483,9 +2995,9 @@ class UserProfile(models.Model):
def post_save_userprofile(sender, **kwargs):
- if not kwargs.get('instance'):
+ if not kwargs.get("instance"):
return
- instance = kwargs.get('instance')
+ instance = kwargs.get("instance")
try:
instance.person.ishtaruser.show_field_number(update=True)
except IshtarUser.DoesNotExist:
@@ -2497,64 +3009,72 @@ post_save.connect(post_save_userprofile, sender=UserProfile)
class IshtarUser(FullSearch):
SLUG = "ishtaruser"
- TABLE_COLS = ('username', 'person__name', 'person__surname',
- 'person__email', 'person__person_types_list',
- 'person__attached_to__name')
+ TABLE_COLS = (
+ "username",
+ "person__name",
+ "person__surname",
+ "person__email",
+ "person__person_types_list",
+ "person__attached_to__name",
+ )
BASE_SEARCH_VECTORS = [
- SearchVectorConfig('user_ptr__username'),
- SearchVectorConfig('person__name'),
- SearchVectorConfig('person__surname'),
- SearchVectorConfig('person__email'),
- SearchVectorConfig('person__town'),
- SearchVectorConfig('person__attached_to__name')]
+ SearchVectorConfig("user_ptr__username"),
+ SearchVectorConfig("person__name"),
+ SearchVectorConfig("person__surname"),
+ SearchVectorConfig("person__email"),
+ SearchVectorConfig("person__town"),
+ SearchVectorConfig("person__attached_to__name"),
+ ]
CACHED_LABELS = [] # needed to force search vector update
# search parameters
EXTRA_REQUEST_KEYS = {
- 'person__person_types_list': 'person__person_types__label'
+ "person__person_types_list": "person__person_types__label"
}
COL_LABELS = {
- 'person__attached_to__name': _("Organization"),
- 'username': _("Username")
+ "person__attached_to__name": _("Organization"),
+ "username": _("Username"),
}
# alternative names of fields for searches
ALT_NAMES = {
- 'username': SearchAltName(
+ "username": SearchAltName(
pgettext_lazy("key for text search", "username"),
- 'user_ptr__username__iexact'
+ "user_ptr__username__iexact",
),
- 'name': SearchAltName(
- pgettext_lazy("key for text search", "name"),
- 'person__name__iexact'
+ "name": SearchAltName(
+ pgettext_lazy("key for text search", "name"), "person__name__iexact"
),
- 'surname': SearchAltName(
+ "surname": SearchAltName(
pgettext_lazy("key for text search", "surname"),
- 'person__surname__iexact'
+ "person__surname__iexact",
),
- 'email': SearchAltName(
+ "email": SearchAltName(
pgettext_lazy("key for text search", "email"),
- 'person__email__iexact'
+ "person__email__iexact",
),
- 'person_types': SearchAltName(
+ "person_types": SearchAltName(
pgettext_lazy("key for text search", "type"),
- 'person__person_types__label__iexact'
+ "person__person_types__label__iexact",
),
- 'attached_to': SearchAltName(
+ "attached_to": SearchAltName(
pgettext_lazy("key for text search", "organization"),
- 'person__attached_to__cached_label__iexact'
+ "person__attached_to__cached_label__iexact",
),
}
# fields
- user_ptr = models.OneToOneField(User, primary_key=True,
- related_name='ishtaruser')
- person = models.OneToOneField(Person, verbose_name=_("Person"),
- related_name='ishtaruser')
+ user_ptr = models.OneToOneField(
+ User, primary_key=True, related_name="ishtaruser"
+ )
+ person = models.OneToOneField(
+ Person, verbose_name=_("Person"), related_name="ishtaruser"
+ )
advanced_shortcut_menu = models.BooleanField(
- _("Advanced shortcut menu"), default=False)
+ _("Advanced shortcut menu"), default=False
+ )
class Meta:
verbose_name = _("Ishtar user")
@@ -2564,7 +3084,7 @@ class IshtarUser(FullSearch):
return str(self.person)
def show_field_number(self, update=False):
- cache_key, value = get_cache(self.__class__, ['show_field_number'])
+ cache_key, value = get_cache(self.__class__, ["show_field_number"])
if not update and value is not None:
return value
value = False
@@ -2577,8 +3097,8 @@ class IshtarUser(FullSearch):
def current_profile_name(self):
q = UserProfile.objects.filter(current=True, person__ishtaruser=self)
if q.count():
- vals = q.values('profile_type__label', 'name').all()[0]
- return vals['name'] or vals['profile_type__label']
+ vals = q.values("profile_type__label", "name").all()[0]
+ return vals["name"] or vals["profile_type__label"]
profile = self.person.current_profile
if not profile:
return ""
@@ -2596,14 +3116,16 @@ class IshtarUser(FullSearch):
ishtaruser = q.all()[0]
person = ishtaruser.person
admin, created = ProfileType.objects.get_or_create(
- txt_idx='administrator')
+ txt_idx="administrator"
+ )
if user.is_superuser:
if UserProfile.objects.filter(
- profile_type=admin, person=person).count():
+ profile_type=admin, person=person
+ ).count():
return
UserProfile.objects.get_or_create(
- profile_type=admin, person=person,
- defaults={'current': True})
+ profile_type=admin, person=person, defaults={"current": True}
+ )
@classmethod
def create_from_user(cls, user):
@@ -2611,9 +3133,9 @@ class IshtarUser(FullSearch):
surname = user.first_name or default
name = user.last_name or default
email = user.email
- person = Person.objects.create(surname=surname,
- name=name, email=email,
- history_modifier=user)
+ person = Person.objects.create(
+ surname=surname, name=name, email=email, history_modifier=user
+ )
return cls.objects.create(user_ptr=user, person=person)
def has_right(self, right_name, session=None):
@@ -2634,6 +3156,7 @@ class Basket(FullSearch, OwnPerms, ValueGetter, TemplateItem):
Abstract class for a basket
Subclass must be defined with an "items" ManyToManyField
"""
+
IS_BASKET = True
uuid = models.UUIDField(default=uuid.uuid4)
label = models.CharField(_("Label"), max_length=1000)
@@ -2641,47 +3164,59 @@ class Basket(FullSearch, OwnPerms, ValueGetter, TemplateItem):
slug = models.SlugField(_("Slug"), blank=True, null=True)
public = models.BooleanField(_("Public"), default=False)
user = models.ForeignKey(
- IshtarUser, blank=True, null=True, related_name='%(class)ss',
+ IshtarUser,
+ blank=True,
+ null=True,
+ related_name="%(class)ss",
on_delete=models.SET_NULL,
- verbose_name=_("Owner"))
+ verbose_name=_("Owner"),
+ )
available = models.BooleanField(_("Available"), default=True)
shared_with = models.ManyToManyField(
- IshtarUser, verbose_name=_("Shared (read) with"), blank=True,
- related_name='shared_%(class)ss'
+ IshtarUser,
+ verbose_name=_("Shared (read) with"),
+ blank=True,
+ related_name="shared_%(class)ss",
)
shared_write_with = models.ManyToManyField(
- IshtarUser, verbose_name=_("Shared (read/edit) with"), blank=True,
- related_name='shared_write_%(class)ss'
+ IshtarUser,
+ verbose_name=_("Shared (read/edit) with"),
+ blank=True,
+ related_name="shared_write_%(class)ss",
)
objects = UUIDModelManager()
- TABLE_COLS = ['label', 'user']
+ TABLE_COLS = ["label", "user"]
BASE_SEARCH_VECTORS = [
- SearchVectorConfig('label'), SearchVectorConfig('comment', 'local'),
+ SearchVectorConfig("label"),
+ SearchVectorConfig("comment", "local"),
]
- PARENT_SEARCH_VECTORS = ['user']
+ PARENT_SEARCH_VECTORS = ["user"]
# M2M_SEARCH_VECTORS = [SearchVectorConfig('items')]
CACHED_LABELS = [] # needed to force search vector update
class Meta:
abstract = True
- ordering = ('label', )
- unique_together = (('label', 'user'),)
+ ordering = ("label",)
+ unique_together = (("label", "user"),)
def __str__(self):
return self.label
def natural_key(self):
- return (self.uuid, )
+ return (self.uuid,)
@classmethod
def BASE_REQUEST(cls, request):
- if not request.user or not getattr(request.user, 'ishtaruser', None):
+ if not request.user or not getattr(request.user, "ishtaruser", None):
return Q(pk=None)
ishtaruser = request.user.ishtaruser
- return Q(user=ishtaruser) | Q(shared_with=ishtaruser) | Q(
- shared_write_with=ishtaruser)
+ return (
+ Q(user=ishtaruser)
+ | Q(shared_with=ishtaruser)
+ | Q(shared_write_with=ishtaruser)
+ )
@property
def cached_label(self):
@@ -2693,22 +3228,25 @@ class Basket(FullSearch, OwnPerms, ValueGetter, TemplateItem):
@classmethod
def get_short_menu_class(cls, pk):
- return 'basket'
+ return "basket"
@property
def associated_filename(self):
- return "{}-{}".format(datetime.date.today().strftime(
- "%Y-%m-%d"), slugify(self.label))
+ return "{}-{}".format(
+ datetime.date.today().strftime("%Y-%m-%d"), slugify(self.label)
+ )
@classmethod
def get_query_owns(cls, ishtaruser):
- return Q(user=ishtaruser) | Q(shared_with=ishtaruser) | Q(
- shared_write_with=ishtaruser)
+ return (
+ Q(user=ishtaruser)
+ | Q(shared_with=ishtaruser)
+ | Q(shared_write_with=ishtaruser)
+ )
@classmethod
def get_write_query_owns(cls, ishtaruser):
- return Q(user=ishtaruser) | Q(
- shared_write_with=ishtaruser)
+ return Q(user=ishtaruser) | Q(shared_write_with=ishtaruser)
def duplicate(self, label=None, ishtaruser=None):
"""
@@ -2721,7 +3259,9 @@ class Basket(FullSearch, OwnPerms, ValueGetter, TemplateItem):
basket_pk = "{}_id".format(self.SLUG)
item_pk = "{}_id".format(self.items.model.SLUG)
q = through.objects.filter(**{basket_pk: self.pk})
- items = [r[item_pk] for r in q.values("pk", item_pk).order_by("pk").all()]
+ items = [
+ r[item_pk] for r in q.values("pk", item_pk).order_by("pk").all()
+ ]
new_item = self
new_item.pk = None
if ishtaruser:
@@ -2729,7 +3269,8 @@ class Basket(FullSearch, OwnPerms, ValueGetter, TemplateItem):
if not label:
label = new_item.label
while self.__class__.objects.filter(
- label=label, user=new_item.user).count():
+ label=label, user=new_item.user
+ ).count():
label += str(_(" - duplicate"))
new_item.label = label
new_item.save()
@@ -2744,7 +3285,7 @@ class AuthorType(GeneralType):
class Meta:
verbose_name = _("Author type")
verbose_name_plural = _("Author types")
- ordering = ['order', 'label']
+ ordering = ["order", "label"]
post_save.connect(post_save_cache, sender=AuthorType)
@@ -2753,20 +3294,22 @@ post_delete.connect(post_save_cache, sender=AuthorType)
class Author(FullSearch):
SLUG = "author"
- PARENT_SEARCH_VECTORS = ['person']
+ PARENT_SEARCH_VECTORS = ["person"]
uuid = models.UUIDField(default=uuid.uuid4)
- person = models.ForeignKey(Person, verbose_name=_("Person"),
- related_name='author')
+ person = models.ForeignKey(
+ Person, verbose_name=_("Person"), related_name="author"
+ )
author_type = models.ForeignKey(AuthorType, verbose_name=_("Author type"))
- cached_label = models.TextField(_("Cached name"), blank=True, default="",
- db_index=True)
+ cached_label = models.TextField(
+ _("Cached name"), blank=True, default="", db_index=True
+ )
objects = UUIDModelManager()
class Meta:
verbose_name = _("Author")
verbose_name_plural = _("Authors")
- ordering = ('author_type__order', 'person__name')
+ ordering = ("author_type__order", "person__name")
permissions = (
("view_author", "Can view all Authors"),
("view_own_author", "Can view own Author"),
@@ -2779,39 +3322,37 @@ class Author(FullSearch):
return self.cached_label or ""
def natural_key(self):
- return self.uuid,
+ return (self.uuid,)
def _generate_cached_label(self):
- return str(self.person) + settings.JOINT + \
- str(self.author_type)
+ return str(self.person) + settings.JOINT + str(self.author_type)
def fancy_str(self):
- return self.person.fancy_str() + settings.JOINT + \
- str(self.author_type)
+ return self.person.fancy_str() + settings.JOINT + str(self.author_type)
def related_sources(self):
- return list(self.treatmentsource_related.all()) + \
- list(self.operationsource_related.all()) + \
- list(self.findsource_related.all()) + \
- list(self.contextrecordsource_related.all())
+ return (
+ list(self.treatmentsource_related.all())
+ + list(self.operationsource_related.all())
+ + list(self.findsource_related.all())
+ + list(self.contextrecordsource_related.all())
+ )
def public_representation(self):
- return {
- "type": str(self.author_type),
- "person": str(self.person)
- }
+ return {"type": str(self.author_type), "person": str(self.person)}
def merge(self, item, keep_old=False):
merge_model_objects(self, item, keep_old=keep_old)
def author_post_save(sender, **kwargs):
- if not kwargs.get('instance'):
+ if not kwargs.get("instance"):
return
cached_label_changed(sender, **kwargs)
- instance = kwargs.get('instance')
- q = Author.objects.filter(person=instance.person,
- author_type=instance.author_type)
+ instance = kwargs.get("instance")
+ q = Author.objects.filter(
+ person=instance.person, author_type=instance.author_type
+ )
if q.count() <= 1:
return
authors = list(q.all())
@@ -2823,20 +3364,23 @@ post_save.connect(author_post_save, sender=Author)
class SourceType(HierarchicalType):
- coins_type = models.CharField(_("COInS export - type"), default='document',
- max_length=100)
- coins_genre = models.CharField(_("COInS export - genre"), blank=True,
- default='', max_length=100)
+ coins_type = models.CharField(
+ _("COInS export - type"), default="document", max_length=100
+ )
+ coins_genre = models.CharField(
+ _("COInS export - genre"), blank=True, default="", max_length=100
+ )
is_localized = models.BooleanField(
- _("Is localized"), default=False,
- help_text=_("Setting a language for this type of document is relevant")
+ _("Is localized"),
+ default=False,
+ help_text=_("Setting a language for this type of document is relevant"),
)
- code = models.CharField(_("Code"), blank=True, default='', max_length=100)
+ code = models.CharField(_("Code"), blank=True, default="", max_length=100)
class Meta:
verbose_name = _("Document type")
verbose_name_plural = _("Document types")
- ordering = ['label']
+ ordering = ["label"]
post_save.connect(post_save_cache, sender=SourceType)
@@ -2845,8 +3389,10 @@ post_delete.connect(post_save_cache, sender=SourceType)
class SupportType(GeneralType):
document_types = models.ManyToManyField(
- "SourceType", blank=True, related_name='supports',
- help_text=_("Only available for these document types")
+ "SourceType",
+ blank=True,
+ related_name="supports",
+ help_text=_("Only available for these document types"),
)
class Meta:
@@ -2860,19 +3406,26 @@ post_delete.connect(post_save_cache, sender=SupportType)
class Format(GeneralType):
iframe_template = models.TextField(
- _("Iframe template"), blank=True, default="",
- help_text=_("Template to insert an iframe for this format. Use django "
- "template with a {{document}} variable matching the "
- "current document."))
+ _("Iframe template"),
+ blank=True,
+ default="",
+ help_text=_(
+ "Template to insert an iframe for this format. Use django "
+ "template with a {{document}} variable matching the "
+ "current document."
+ ),
+ )
document_types = models.ManyToManyField(
- "SourceType", blank=True, related_name='formats',
- help_text=_("Only available for these document types")
+ "SourceType",
+ blank=True,
+ related_name="formats",
+ help_text=_("Only available for these document types"),
)
class Meta:
verbose_name = _("Format type")
verbose_name_plural = _("Format types")
- ordering = ['label']
+ ordering = ["label"]
post_save.connect(post_save_cache, sender=Format)
@@ -2885,7 +3438,7 @@ class LicenseType(GeneralType):
class Meta:
verbose_name = _("License type")
verbose_name_plural = _("License types")
- ordering = ('label',)
+ ordering = ("label",)
class DocumentTag(GeneralType):
@@ -2894,51 +3447,89 @@ class DocumentTag(GeneralType):
class Meta:
verbose_name = _("Document tag")
verbose_name_plural = _("Document tags")
- ordering = ('label',)
+ ordering = ("label",)
post_save.connect(post_save_cache, sender=LicenseType)
post_delete.connect(post_save_cache, sender=LicenseType)
-class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
- ValueGetter, MainItem):
+class Document(
+ BaseHistorizedItem,
+ CompleteIdentifierItem,
+ OwnPerms,
+ ImageModel,
+ ValueGetter,
+ MainItem,
+):
APP = "ishtar-common"
MODEL = "document"
- EXTERNAL_ID_KEY = 'document_external_id'
- DELETE_URL = 'delete-document'
+ EXTERNAL_ID_KEY = "document_external_id"
+ DELETE_URL = "delete-document"
# order is important: put the image in the first match found
# other will be symbolic links
RELATED_MODELS = [
- 'treatment_files', 'treatments', 'finds', 'context_records',
- 'operations', 'sites', 'warehouses', 'containers', 'files',
- 'administrativeacts',
+ "treatment_files",
+ "treatments",
+ "finds",
+ "context_records",
+ "operations",
+ "sites",
+ "warehouses",
+ "containers",
+ "files",
+ "administrativeacts",
]
# same fields but in order for forms
RELATED_MODELS_ALT = [
- 'finds', 'context_records', 'operations', 'sites', 'files',
- 'administrativeacts', 'warehouses', 'containers', 'treatments',
- 'treatment_files',
+ "finds",
+ "context_records",
+ "operations",
+ "sites",
+ "files",
+ "administrativeacts",
+ "warehouses",
+ "containers",
+ "treatments",
+ "treatment_files",
]
- SLUG = 'document'
+ SLUG = "document"
LINK_SPLIT = "<||>"
GET_VALUES_EXCLUDE_FIELDS = ValueGetter.GET_VALUES_EXCLUDE_FIELDS + [
- "warehouses", "operations", "treatments",
- "files", "treatment_files", "administrativeacts", "id",
- "associated_links", "source_type_id",
- "history_creator_id", "containers", "sites",
- "main_image_warehouses", "main_image_operations",
- "main_image_treatments", "main_image_files",
- "main_image_treatment_files", "main_image_id",
- "main_image_associated_links", "main_image_source_type_id",
- "main_image_history_creator_id", "main_image_containers",
+ "warehouses",
+ "operations",
+ "treatments",
+ "files",
+ "treatment_files",
+ "administrativeacts",
+ "id",
+ "associated_links",
+ "source_type_id",
+ "history_creator_id",
+ "containers",
+ "sites",
+ "main_image_warehouses",
+ "main_image_operations",
+ "main_image_treatments",
+ "main_image_files",
+ "main_image_treatment_files",
+ "main_image_id",
+ "main_image_associated_links",
+ "main_image_source_type_id",
+ "main_image_history_creator_id",
+ "main_image_containers",
"main_image_sites",
]
- _TABLE_COLS = ['title', 'source_type', 'cache_related_label',
- 'authors__cached_label', 'associated_url']
- COL_LINK = ['associated_url']
+ _TABLE_COLS = [
+ "title",
+ "source_type",
+ "cache_related_label",
+ "authors__cached_label",
+ "associated_url",
+ ]
+ COL_LINK = ["associated_url"]
BASE_SEARCH_VECTORS = [
SearchVectorConfig("title"),
SearchVectorConfig("source_type__label"),
@@ -2950,368 +3541,428 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
SearchVectorConfig("additional_information", "local"),
]
BASE_SEARCH_VECTORS += [
- SearchVectorConfig('treatment_files__name'),
- SearchVectorConfig('treatments__cached_label'),
- SearchVectorConfig('finds__cached_label'),
- SearchVectorConfig('context_records__cached_label'),
- SearchVectorConfig('operations__cached_label'),
- SearchVectorConfig('sites__cached_label'),
- SearchVectorConfig('warehouses__name'),
- SearchVectorConfig('containers__cached_label'),
- SearchVectorConfig('files__cached_label')
+ SearchVectorConfig("treatment_files__name"),
+ SearchVectorConfig("treatments__cached_label"),
+ SearchVectorConfig("finds__cached_label"),
+ SearchVectorConfig("context_records__cached_label"),
+ SearchVectorConfig("operations__cached_label"),
+ SearchVectorConfig("sites__cached_label"),
+ SearchVectorConfig("warehouses__name"),
+ SearchVectorConfig("containers__cached_label"),
+ SearchVectorConfig("files__cached_label"),
+ ]
+ PARENT_SEARCH_VECTORS = [
+ "authors",
+ ]
+ M2M_SEARCH_VECTORS = [
+ SearchVectorConfig("tags__label"),
]
- PARENT_SEARCH_VECTORS = ['authors', ]
- M2M_SEARCH_VECTORS = [SearchVectorConfig("tags__label"), ]
- BOOL_FIELDS = ['duplicate']
+ BOOL_FIELDS = ["duplicate"]
COL_LABELS = {
"authors__cached_label": _("Authors"),
"complete_identifier": _("Identifier"),
}
- CACHED_LABELS = ['cache_related_label']
+ CACHED_LABELS = ["cache_related_label"]
CACHED_COMPLETE_ID = ""
EXTRA_REQUEST_KEYS = {
"operations": "operations__pk",
"context_records": "context_records__pk",
"context_records__operation": "context_records__operation__pk",
"finds": "finds__pk",
- "finds__base_finds__context_record":
- "finds__base_finds__context_record__pk",
- "finds__base_finds__context_record__operation":
- "finds__base_finds__context_record__operation__pk",
- 'authors__cached_label': 'authors__cached_label',
- 'complete_identifier': 'complete_identifier',
- 'authors__person__pk': 'authors__person__pk',
+ "finds__base_finds__context_record": "finds__base_finds__context_record__pk",
+ "finds__base_finds__context_record__operation": "finds__base_finds__context_record__operation__pk",
+ "authors__cached_label": "authors__cached_label",
+ "complete_identifier": "complete_identifier",
+ "authors__person__pk": "authors__person__pk",
"container_id": "container_id",
- 'publisher__pk': 'publisher__pk'
+ "publisher__pk": "publisher__pk",
}
# alternative names of fields for searches
ALT_NAMES = {
- 'authors': SearchAltName(
+ "authors": SearchAltName(
pgettext_lazy("key for text search", "author"),
- 'authors__cached_label__iexact'
+ "authors__cached_label__iexact",
),
- 'publisher': SearchAltName(
+ "publisher": SearchAltName(
pgettext_lazy("key for text search", "publisher"),
- 'publisher__name__iexact'
+ "publisher__name__iexact",
),
- 'publishing_year': SearchAltName(
+ "publishing_year": SearchAltName(
pgettext_lazy("key for text search", "publishing-year"),
- 'publishing_year'
+ "publishing_year",
),
- 'title': SearchAltName(
- pgettext_lazy("key for text search", "title"),
- 'title__iexact'
+ "title": SearchAltName(
+ pgettext_lazy("key for text search", "title"), "title__iexact"
),
- 'source_type': SearchAltName(
+ "source_type": SearchAltName(
pgettext_lazy("key for text search", "type"),
- 'source_type__label__iexact'
+ "source_type__label__iexact",
),
- 'reference': SearchAltName(
+ "reference": SearchAltName(
pgettext_lazy("key for text search", "reference"),
- 'reference__iexact'
+ "reference__iexact",
),
- 'internal_reference': SearchAltName(
+ "internal_reference": SearchAltName(
pgettext_lazy("key for text search", "internal-reference"),
- 'internal_reference__iexact'
+ "internal_reference__iexact",
),
- 'description': SearchAltName(
+ "description": SearchAltName(
pgettext_lazy("key for text search", "description"),
- 'description__iexact'
+ "description__iexact",
),
- 'tag': SearchAltName(
- pgettext_lazy("key for text search", "tag"),
- 'tags__label__iexact'
+ "tag": SearchAltName(
+ pgettext_lazy("key for text search", "tag"), "tags__label__iexact"
),
- 'format': SearchAltName(
+ "format": SearchAltName(
pgettext_lazy("key for text search", "format"),
- 'format_type__label__iexact'
+ "format_type__label__iexact",
),
- 'support': SearchAltName(
+ "support": SearchAltName(
pgettext_lazy("key for text search", "medium"),
- 'support_type__label__iexact'
+ "support_type__label__iexact",
),
- 'language': SearchAltName(
+ "language": SearchAltName(
pgettext_lazy("key for text search", "language"),
- 'language__label__iexact'
+ "language__label__iexact",
),
- 'licenses': SearchAltName(
+ "licenses": SearchAltName(
pgettext_lazy("key for text search", "license"),
- 'licenses__label__iexact'
+ "licenses__label__iexact",
),
- 'scale': SearchAltName(
- pgettext_lazy("key for text search", "scale"),
- 'scale__iexact'
+ "scale": SearchAltName(
+ pgettext_lazy("key for text search", "scale"), "scale__iexact"
),
- 'associated_url': SearchAltName(
+ "associated_url": SearchAltName(
pgettext_lazy("key for text search", "url"),
- 'associated_url__iexact'
+ "associated_url__iexact",
),
- 'isbn': SearchAltName(
- pgettext_lazy("key for text search", "isbn"),
- 'isbn__iexact'
+ "isbn": SearchAltName(
+ pgettext_lazy("key for text search", "isbn"), "isbn__iexact"
),
- 'issn': SearchAltName(
- pgettext_lazy("key for text search", "issn"),
- 'issn__iexact'
+ "issn": SearchAltName(
+ pgettext_lazy("key for text search", "issn"), "issn__iexact"
),
- 'source': SearchAltName(
+ "source": SearchAltName(
pgettext_lazy("key for text search", "source"),
- 'source__title__iexact'
+ "source__title__iexact",
),
- 'source_free_input': SearchAltName(
+ "source_free_input": SearchAltName(
pgettext_lazy("key for text search", "source-free-input"),
- 'source_free_input__iexact'
+ "source_free_input__iexact",
),
- 'warehouse_container': SearchAltName(
+ "warehouse_container": SearchAltName(
pgettext_lazy("key for text search", "warehouse-container"),
- 'container__cached_label__iexact'
+ "container__cached_label__iexact",
),
- 'warehouse_container_ref': SearchAltName(
- pgettext_lazy("key for text search",
- "warehouse-container-reference"),
- 'container_ref__cached_label__iexact'
+ "warehouse_container_ref": SearchAltName(
+ pgettext_lazy(
+ "key for text search", "warehouse-container-reference"
+ ),
+ "container_ref__cached_label__iexact",
),
- 'comment': SearchAltName(
- pgettext_lazy("key for text search", "comment"),
- 'comment__iexact'
+ "comment": SearchAltName(
+ pgettext_lazy("key for text search", "comment"), "comment__iexact"
),
- 'additional_information': SearchAltName(
+ "additional_information": SearchAltName(
pgettext_lazy("key for text search", "additional-information"),
- 'additional_information__iexact'
+ "additional_information__iexact",
),
- 'duplicate': SearchAltName(
- pgettext_lazy("key for text search", "has-duplicate"),
- 'duplicate'
+ "duplicate": SearchAltName(
+ pgettext_lazy("key for text search", "has-duplicate"), "duplicate"
),
- 'operation': SearchAltName(
+ "operation": SearchAltName(
pgettext_lazy("key for text search", "operation"),
- 'operations__cached_label__iexact'
+ "operations__cached_label__iexact",
),
- 'context_record': SearchAltName(
+ "context_record": SearchAltName(
pgettext_lazy("key for text search", "context-record"),
- 'context_records__cached_label__iexact'
+ "context_records__cached_label__iexact",
),
- 'find_basket': SearchAltName(
+ "find_basket": SearchAltName(
pgettext_lazy("key for text search", "basket-finds"),
- 'finds__basket__label__iexact'
+ "finds__basket__label__iexact",
),
- 'find': SearchAltName(
+ "find": SearchAltName(
pgettext_lazy("key for text search", "find"),
- 'finds__cached_label__iexact'
+ "finds__cached_label__iexact",
),
- 'find__denomination': SearchAltName(
+ "find__denomination": SearchAltName(
pgettext_lazy("key for text search", "find-denomination"),
- 'finds__denomination__iexact'
+ "finds__denomination__iexact",
),
- 'file': SearchAltName(
+ "file": SearchAltName(
pgettext_lazy("key for text search", "file"),
- 'files__cached_label__iexact'
+ "files__cached_label__iexact",
),
- 'containers': SearchAltName(
+ "containers": SearchAltName(
pgettext_lazy("key for text search", "container"),
- 'containers__cached_label__iexact'
+ "containers__cached_label__iexact",
),
- 'site': SearchAltName(
+ "site": SearchAltName(
pgettext_lazy("key for text search", "site"),
- 'sites__cached_label__iexact'
+ "sites__cached_label__iexact",
),
- 'warehouse': SearchAltName(
+ "warehouse": SearchAltName(
pgettext_lazy("key for text search", "warehouse"),
- 'warehouses__name__iexact'
+ "warehouses__name__iexact",
+ ),
+ "image__isnull": SearchAltName(
+ pgettext_lazy("key for text search", "has-image"), "image__isnull"
+ ),
+ "associated_file__isnull": SearchAltName(
+ pgettext_lazy("key for text search", "has-file"),
+ "associated_file__isnull",
+ ),
+ "receipt_date__before": SearchAltName(
+ pgettext_lazy("key for text search", "receipt-date-before"),
+ "receipt_date__lte",
+ ),
+ "receipt_date__after": SearchAltName(
+ pgettext_lazy("key for text search", "receipt-date-after"),
+ "receipt_date__gte",
+ ),
+ "receipt_date_in_documentation__before": SearchAltName(
+ pgettext_lazy(
+ "key for text search", "receipt-in-documentation-date-before"
+ ),
+ "receipt_date_in_documentation__lte",
+ ),
+ "receipt_date_in_documentation__after": SearchAltName(
+ pgettext_lazy(
+ "key for text search", "receipt-in-documentation-date-after"
+ ),
+ "receipt_date_in_documentation__gte",
+ ),
+ "creation_date__before": SearchAltName(
+ pgettext_lazy("key for text search", "creation-date-before"),
+ "creation_date__lte",
+ ),
+ "creation_date__after": SearchAltName(
+ pgettext_lazy("key for text search", "creation-date-after"),
+ "creation_date__gte",
),
- 'image__isnull':
- SearchAltName(
- pgettext_lazy("key for text search", "has-image"),
- 'image__isnull'),
- 'associated_file__isnull':
- SearchAltName(
- pgettext_lazy("key for text search", "has-file"),
- 'associated_file__isnull'),
- 'receipt_date__before':
- SearchAltName(
- pgettext_lazy("key for text search", "receipt-date-before"),
- 'receipt_date__lte'),
- 'receipt_date__after':
- SearchAltName(
- pgettext_lazy("key for text search", "receipt-date-after"),
- 'receipt_date__gte'),
- 'receipt_date_in_documentation__before':
- SearchAltName(
- pgettext_lazy("key for text search",
- "receipt-in-documentation-date-before"),
- 'receipt_date_in_documentation__lte'),
- 'receipt_date_in_documentation__after':
- SearchAltName(
- pgettext_lazy("key for text search",
- "receipt-in-documentation-date-after"),
- 'receipt_date_in_documentation__gte'),
- 'creation_date__before':
- SearchAltName(
- pgettext_lazy("key for text search", "creation-date-before"),
- 'creation_date__lte'),
- 'creation_date__after':
- SearchAltName(
- pgettext_lazy("key for text search", "creation-date-after"),
- 'creation_date__gte'),
}
ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES)
# search parameters
- REVERSED_BOOL_FIELDS = ['image__isnull', 'associated_file__isnull']
+ REVERSED_BOOL_FIELDS = ["image__isnull", "associated_file__isnull"]
DATED_FIELDS = [
- 'receipt_date__lte',
- 'receipt_date__gte',
- 'receipt_date_in_documentation__lte',
- 'receipt_date_in_documentation__gte',
- 'creation_date__lte',
- 'creation_date__gte',
+ "receipt_date__lte",
+ "receipt_date__gte",
+ "receipt_date_in_documentation__lte",
+ "receipt_date_in_documentation__gte",
+ "creation_date__lte",
+ "creation_date__gte",
]
objects = ExternalIdManager()
RELATIVE_SESSION_NAMES = [
- ('find', 'finds__pk'),
- ('contextrecord', 'context_records__pk'),
- ('operation', 'operations__pk'),
- ('site', 'sites__pk'),
- ('file', 'files__pk'),
- ('warehouse', 'warehouses__pk'),
- ('treatment', 'treatments__pk'),
- ('treatmentfile', 'treatment_files__pk'),
- ('administrativeact', 'administrativeacts__pk'),
+ ("find", "finds__pk"),
+ ("contextrecord", "context_records__pk"),
+ ("operation", "operations__pk"),
+ ("site", "sites__pk"),
+ ("file", "files__pk"),
+ ("warehouse", "warehouses__pk"),
+ ("treatment", "treatments__pk"),
+ ("treatmentfile", "treatment_files__pk"),
+ ("administrativeact", "administrativeacts__pk"),
]
UP_MODEL_QUERY = {
- "operation": (pgettext_lazy("key for text search", "operation"),
- 'cached_label'),
- "contextrecord": (pgettext_lazy("key for text search",
- "context-record"), 'cached_label'),
- "file": (pgettext_lazy("key for text search", "file"), 'cached_label'),
- "find": (pgettext_lazy("key for text search", "find"), 'cached_label'),
- "site": (pgettext_lazy("key for text search", "site"), 'cached_label'),
- "warehouse": (pgettext_lazy("key for text search", "warehouse"),
- 'cached_label'),
- "treatment": (pgettext_lazy("key for text search", "treatment"),
- 'cached_label'),
- "treatmentfile": (pgettext_lazy("key for text search",
- "treatment-file"), 'cached_label'),
+ "operation": (
+ pgettext_lazy("key for text search", "operation"),
+ "cached_label",
+ ),
+ "contextrecord": (
+ pgettext_lazy("key for text search", "context-record"),
+ "cached_label",
+ ),
+ "file": (pgettext_lazy("key for text search", "file"), "cached_label"),
+ "find": (pgettext_lazy("key for text search", "find"), "cached_label"),
+ "site": (pgettext_lazy("key for text search", "site"), "cached_label"),
+ "warehouse": (
+ pgettext_lazy("key for text search", "warehouse"),
+ "cached_label",
+ ),
+ "treatment": (
+ pgettext_lazy("key for text search", "treatment"),
+ "cached_label",
+ ),
+ "treatmentfile": (
+ pgettext_lazy("key for text search", "treatment-file"),
+ "cached_label",
+ ),
}
QA_EDIT = QuickAction(
- url="document-qa-bulk-update", icon_class="fa fa-pencil",
- text=_("Bulk update"), target="many",
- rights=['change_document', 'change_own_document'])
+ url="document-qa-bulk-update",
+ icon_class="fa fa-pencil",
+ text=_("Bulk update"),
+ target="many",
+ rights=["change_document", "change_own_document"],
+ )
QUICK_ACTIONS = [
QA_EDIT,
QuickAction(
- url="document-qa-duplicate", icon_class="fa fa-clone",
- text=_("Duplicate"), target="one",
- rights=['change_document', 'change_own_document']),
+ url="document-qa-duplicate",
+ icon_class="fa fa-clone",
+ text=_("Duplicate"),
+ target="one",
+ rights=["change_document", "change_own_document"],
+ ),
QuickAction(
- url="document-qa-packaging", icon_class="fa fa-gift",
- text=_("Packaging"), target="many",
- rights=['change_document', 'change_own_document'],
- module='warehouse'
+ url="document-qa-packaging",
+ icon_class="fa fa-gift",
+ text=_("Packaging"),
+ target="many",
+ rights=["change_document", "change_own_document"],
+ module="warehouse",
),
]
SERIALIZATION_FILES = ["image", "thumbnail", "associated_file"]
- title = models.TextField(_("Title"), blank=True, default='')
+ title = models.TextField(_("Title"), blank=True, default="")
associated_file = models.FileField(
verbose_name=_("Associated file"),
- upload_to=get_image_path, blank=True, null=True, max_length=255,
- help_text=max_size_help())
- index = models.IntegerField(verbose_name=_("Index"), blank=True,
- null=True)
+ upload_to=get_image_path,
+ blank=True,
+ null=True,
+ max_length=255,
+ help_text=max_size_help(),
+ )
+ index = models.IntegerField(verbose_name=_("Index"), blank=True, null=True)
external_id = models.TextField(_("External ID"), blank=True, default="")
reference = models.TextField(_("Ref."), blank=True, default="")
- internal_reference = models.TextField(_("Internal ref."), blank=True,
- default="")
- source_type = models.ForeignKey(SourceType, verbose_name=_("Type"),
- on_delete=models.SET_NULL,
- null=True, blank=True)
+ internal_reference = models.TextField(
+ _("Internal ref."), blank=True, default=""
+ )
+ source_type = models.ForeignKey(
+ SourceType,
+ verbose_name=_("Type"),
+ on_delete=models.SET_NULL,
+ null=True,
+ blank=True,
+ )
publisher = models.ForeignKey(
- Organization, verbose_name=_("Publisher"), blank=True, null=True,
- related_name='publish')
+ Organization,
+ verbose_name=_("Publisher"),
+ blank=True,
+ null=True,
+ related_name="publish",
+ )
publishing_year = models.PositiveIntegerField(
- _("Year of publication"), blank=True, null=True)
- licenses = models.ManyToManyField(LicenseType, verbose_name=_("License"),
- blank=True)
- tags = models.ManyToManyField(DocumentTag, verbose_name=_("Tags"),
- blank=True)
+ _("Year of publication"), blank=True, null=True
+ )
+ licenses = models.ManyToManyField(
+ LicenseType, verbose_name=_("License"), blank=True
+ )
+ tags = models.ManyToManyField(
+ DocumentTag, verbose_name=_("Tags"), blank=True
+ )
language = models.ForeignKey(
- Language, verbose_name=_("Language"), blank=True, null=True)
+ Language, verbose_name=_("Language"), blank=True, null=True
+ )
issn = models.CharField(_("ISSN"), blank=True, null=True, max_length=10)
isbn = models.CharField(_("ISBN"), blank=True, null=True, max_length=17)
- source = models.ForeignKey("Document", verbose_name=_("Source"),
- blank=True, null=True, related_name="children")
+ source = models.ForeignKey(
+ "Document",
+ verbose_name=_("Source"),
+ blank=True,
+ null=True,
+ related_name="children",
+ )
source_free_input = models.CharField(
- verbose_name=_("Source - free input"), blank=True, null=True,
- max_length=500)
+ verbose_name=_("Source - free input"),
+ blank=True,
+ null=True,
+ max_length=500,
+ )
source_page_range = models.CharField(
- verbose_name=_("Source - page range"), blank=True, null=True,
- max_length=500)
- support_type = models.ForeignKey(SupportType, verbose_name=_("Medium"),
- on_delete=models.SET_NULL,
- blank=True, null=True, )
- format_type = models.ForeignKey(Format, verbose_name=_("Format"),
- on_delete=models.SET_NULL,
- blank=True, null=True)
- scale = models.CharField(_("Scale"), max_length=30, null=True,
- blank=True)
- authors = models.ManyToManyField(Author, verbose_name=_("Authors"),
- related_name="documents")
- authors_raw = models.CharField(verbose_name=_("Authors (raw)"),
- blank=True, null=True, max_length=250)
+ verbose_name=_("Source - page range"),
+ blank=True,
+ null=True,
+ max_length=500,
+ )
+ support_type = models.ForeignKey(
+ SupportType,
+ verbose_name=_("Medium"),
+ on_delete=models.SET_NULL,
+ blank=True,
+ null=True,
+ )
+ format_type = models.ForeignKey(
+ Format,
+ verbose_name=_("Format"),
+ on_delete=models.SET_NULL,
+ blank=True,
+ null=True,
+ )
+ scale = models.CharField(_("Scale"), max_length=30, null=True, blank=True)
+ authors = models.ManyToManyField(
+ Author, verbose_name=_("Authors"), related_name="documents"
+ )
+ authors_raw = models.CharField(
+ verbose_name=_("Authors (raw)"), blank=True, null=True, max_length=250
+ )
associated_url = models.URLField(
- blank=True, null=True, max_length=1000,
- verbose_name=_("Numerical ressource (web address)"))
- receipt_date = models.DateField(blank=True, null=True,
- verbose_name=_("Receipt date"))
- creation_date = models.DateField(blank=True, null=True,
- verbose_name=_("Creation date"))
+ blank=True,
+ null=True,
+ max_length=1000,
+ verbose_name=_("Numerical ressource (web address)"),
+ )
+ receipt_date = models.DateField(
+ blank=True, null=True, verbose_name=_("Receipt date")
+ )
+ creation_date = models.DateField(
+ blank=True, null=True, verbose_name=_("Creation date")
+ )
receipt_date_in_documentation = models.DateField(
- blank=True, null=True,
- verbose_name=_("Receipt date in documentation"))
+ blank=True, null=True, verbose_name=_("Receipt date in documentation")
+ )
item_number = models.IntegerField(_("Number of items"), default=1)
description = models.TextField(_("Description"), blank=True, default="")
container_id = models.PositiveIntegerField(
- verbose_name=_("Container ID"), blank=True, null=True)
+ verbose_name=_("Container ID"), blank=True, null=True
+ )
# container = models.ForeignKey("archaeological_warehouse.Container")
container_ref_id = models.PositiveIntegerField(
- verbose_name=_("Container ID"), blank=True, null=True)
+ verbose_name=_("Container ID"), blank=True, null=True
+ )
# container_ref = models.ForeignKey("archaeological_warehouse.Container")
comment = models.TextField(_("Comment"), blank=True, default="")
- additional_information = models.TextField(_("Additional information"),
- blank=True, default="")
- duplicate = models.NullBooleanField(_("Has a duplicate"), blank=True,
- null=True)
- associated_links = models.TextField(_("Symbolic links"), blank=True,
- default="")
+ additional_information = models.TextField(
+ _("Additional information"), blank=True, default=""
+ )
+ duplicate = models.NullBooleanField(
+ _("Has a duplicate"), blank=True, null=True
+ )
+ associated_links = models.TextField(
+ _("Symbolic links"), blank=True, default=""
+ )
cache_related_label = models.TextField(
- _("Related"), blank=True, default="", db_index=True,
- help_text=_("Cached value - do not edit"))
+ _("Related"),
+ blank=True,
+ default="",
+ db_index=True,
+ help_text=_("Cached value - do not edit"),
+ )
class Meta:
verbose_name = _("Document")
verbose_name_plural = _("Documents")
- ordering = ('title',)
+ ordering = ("title",)
permissions = (
- ("view_document",
- ugettext("Can view all Documents")),
- ("view_own_document",
- ugettext("Can view own Document")),
- ("add_own_document",
- ugettext("Can add own Document")),
- ("change_own_document",
- ugettext("Can change own Document")),
- ("delete_own_document",
- ugettext("Can delete own Document")),
+ ("view_document", ugettext("Can view all Documents")),
+ ("view_own_document", ugettext("Can view own Document")),
+ ("add_own_document", ugettext("Can add own Document")),
+ ("change_own_document", ugettext("Can change own Document")),
+ ("delete_own_document", ugettext("Can delete own Document")),
)
indexes = [
- GinIndex(fields=['data']),
+ GinIndex(fields=["data"]),
]
def __str__(self):
@@ -3329,18 +3980,24 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
def operation_codes(self):
Operation = apps.get_model("archaeological_operations", "Operation")
return "|".join(
- sorted([Operation.objects.get(pk=ope_id).code_patriarche
- for ope_id in self.get_related_operation_ids()]))
+ sorted(
+ [
+ Operation.objects.get(pk=ope_id).code_patriarche
+ for ope_id in self.get_related_operation_ids()
+ ]
+ )
+ )
def get_related_operation_ids(self):
- operations = list(
- self.operations.values_list("id", flat=True).all())
+ operations = list(self.operations.values_list("id", flat=True).all())
operations += list(
- self.context_records.values_list(
- "operation_id", flat=True).all())
+ self.context_records.values_list("operation_id", flat=True).all()
+ )
operations += list(
self.finds.values_list(
- "base_finds__context_record__operation_id", flat=True).all())
+ "base_finds__context_record__operation_id", flat=True
+ ).all()
+ )
return list(set(operations))
def get_index_operation(self):
@@ -3348,11 +4005,17 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
if len(operations) != 1:
return
current_operation = operations[0]
- q = Document.objects.exclude(pk=self.pk).filter(
- Q(operations__id=current_operation) |
- Q(context_records__operation_id=current_operation) |
- Q(finds__base_finds__context_record__operation_id=current_operation)
- ).order_by("-custom_index")
+ q = (
+ Document.objects.exclude(pk=self.pk)
+ .filter(
+ Q(operations__id=current_operation)
+ | Q(context_records__operation_id=current_operation)
+ | Q(
+ finds__base_finds__context_record__operation_id=current_operation
+ )
+ )
+ .order_by("-custom_index")
+ )
current_index = None
for doc in q.all():
if not doc.custom_index:
@@ -3385,7 +4048,8 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
if not self.has_iframe:
return ""
return Template(self.format_type.iframe_template).render(
- Context({"document": self}))
+ Context({"document": self})
+ )
@property
def container(self):
@@ -3409,8 +4073,9 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
@property
def pdf_attached(self):
- if not self.associated_file and (not self.source
- or not self.source.associated_file):
+ if not self.associated_file and (
+ not self.source or not self.source.associated_file
+ ):
return
extra = ""
if self.associated_file:
@@ -3432,6 +4097,7 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
return "{}-{:04d}".format(self.operation.code_patriarche or '',
self.index)
"""
+
def duplicate_item(self, user=None, data=None):
return duplicate_item(self, user, data)
@@ -3479,18 +4145,29 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
actions = super(Document, self).get_extra_actions(request)
# is_locked = self.is_locked(request.user)
- can_edit_document = self.can_do(request, 'change_document')
+ can_edit_document = self.can_do(request, "change_document")
if not can_edit_document:
return actions
actions += [
- (reverse("document-qa-duplicate", args=[self.pk]),
- _("Duplicate"), "fa fa-clone", "", "", True),
+ (
+ reverse("document-qa-duplicate", args=[self.pk]),
+ _("Duplicate"),
+ "fa fa-clone",
+ "",
+ "",
+ True,
+ ),
]
if get_current_profile().warehouse:
actions.append(
- (reverse("document-qa-packaging", args=[self.pk]),
- _("Packaging"),
- "fa fa-gift", "", "", True)
+ (
+ reverse("document-qa-packaging", args=[self.pk]),
+ _("Packaging"),
+ "fa fa-gift",
+ "",
+ "",
+ True,
+ )
)
return actions
@@ -3508,7 +4185,8 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
values = super(Document, self).get_values(
- prefix=prefix, no_values=no_values, filtr=filtr, **kwargs)
+ prefix=prefix, no_values=no_values, filtr=filtr, **kwargs
+ )
if not filtr or prefix + "image_path" in filtr:
values[prefix + "image_path"] = self.image_path
if not filtr or prefix + "thumbnail_path" in filtr:
@@ -3528,8 +4206,9 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
@property
def images(self):
# mimic a queryset pointing to himself
- return Document.objects.filter(
- pk=self.pk, image__isnull=False).exclude(image='')
+ return Document.objects.filter(pk=self.pk, image__isnull=False).exclude(
+ image=""
+ )
@property
def main_image(self):
@@ -3547,9 +4226,7 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
klass = getattr(cls, rel_model).rel.related_model
q_own_dct = klass._get_query_owns_dicts(ishtaruser)
if q_own_dct:
- query_own_list.append(
- (rel_model + "__", q_own_dct)
- )
+ query_own_list.append((rel_model + "__", q_own_dct))
q = None
for prefix, owns in query_own_list:
subq = cls._construct_query_own(prefix, owns)
@@ -3558,9 +4235,9 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
q = subq
else:
q |= subq
- q |= cls._construct_query_own('', [
- {'history_creator': ishtaruser.user_ptr}
- ])
+ q |= cls._construct_query_own(
+ "", [{"history_creator": ishtaruser.user_ptr}]
+ )
return q
def get_associated_operation(self):
@@ -3568,9 +4245,11 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
@property
def associated_filename(self):
- values = [str(getattr(self, attr))
- for attr in ('source_type', 'title')
- if getattr(self, attr)]
+ values = [
+ str(getattr(self, attr))
+ for attr in ("source_type", "title")
+ if getattr(self, attr)
+ ]
return slugify("-".join(values))
def _get_base_image_paths(self):
@@ -3600,14 +4279,14 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
the new_path
"""
- file_split = path.split('.')
+ file_split = path.split(".")
suffix, base = "", ""
if len(file_split) > 1:
base = ".".join(file_split[0:-1])
suffix = file_split[-1]
else:
base = path
- base_split = base.split('-')
+ base_split = base.split("-")
current_nb = 0
if len(base_split) > 1:
try:
@@ -3617,8 +4296,11 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
pass
while os.path.exists(path):
- if test_link and os.path.islink(path) \
- and os.readlink(path) == test_link:
+ if (
+ test_link
+ and os.path.islink(path)
+ and os.readlink(path) == test_link
+ ):
return path, True
current_nb += 1
path = "{}-{}.{}".format(base, current_nb, suffix)
@@ -3649,7 +4331,8 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
if not os.path.exists(os.path.dirname(new_path)):
os.makedirs(os.path.dirname(new_path))
new_path, match = self._get_available_filename(
- new_path, test_link=reference_path)
+ new_path, test_link=reference_path
+ )
links.append(new_path)
if match: # the current link is correct
continue
@@ -3671,11 +4354,14 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
@classmethod
def get_next_index(cls):
- q = cls.objects.values('index').filter(
- index__isnull=False).order_by("-index")
+ q = (
+ cls.objects.values("index")
+ .filter(index__isnull=False)
+ .order_by("-index")
+ )
if not q.count():
return 1
- cid = q.all()[0]['index']
+ cid = q.all()[0]["index"]
if not cid:
cid = 0
return cid + 1
@@ -3705,23 +4391,34 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
identifier = self.associated_url
elif Site.objects.count():
identifier = "http://{}{}".format(
- Site.objects.all()[0].domain, self.get_absolute_url())
+ Site.objects.all()[0].domain, self.get_absolute_url()
+ )
return identifier
def dublin_core_tags(self):
if not self.title:
return ""
tags = [
- ("link",
- {"rel": "schema.DC", "href": "http://purl.org/dc/elements/1.1/"}),
- ("link",
- {"rel": "schema.DCTERMS", "href": "http://purl.org/dc/terms/"}),
+ (
+ "link",
+ {
+ "rel": "schema.DC",
+ "href": "http://purl.org/dc/elements/1.1/",
+ },
+ ),
+ (
+ "link",
+ {"rel": "schema.DCTERMS", "href": "http://purl.org/dc/terms/"},
+ ),
]
title = {"name": "DC.title", "content": self.title}
tags.append(("meta", title))
if self.creation_date:
- date = {"name": "DC.date", "scheme": "DCTERMS.W3CDTF",
- "content": self.creation_date.strftime("%Y-%m-%d")}
+ date = {
+ "name": "DC.date",
+ "scheme": "DCTERMS.W3CDTF",
+ "content": self.creation_date.strftime("%Y-%m-%d"),
+ }
tags.append(("meta", date))
if self.tags.count():
content = ", ".join(str(t) for t in self.tags.all())
@@ -3729,55 +4426,58 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
tags.append(("meta", tg))
if self.description:
tags.append(
- ("meta", {"name": "DC.description",
- "content": self.description}))
+ (
+ "meta",
+ {"name": "DC.description", "content": self.description},
+ )
+ )
if self.publisher:
tags.append(
- ("meta", {"name": "DC.publisher",
- "content": self.publisher.name}))
+ (
+ "meta",
+ {"name": "DC.publisher", "content": self.publisher.name},
+ )
+ )
if self.authors.count():
- content = ", ".join(str(t.person.raw_name) for t in
- self.authors.all())
- tags.append(
- ("meta", {"name": "DC.creator",
- "content": content}))
+ content = ", ".join(
+ str(t.person.raw_name) for t in self.authors.all()
+ )
+ tags.append(("meta", {"name": "DC.creator", "content": content}))
if self.source_type:
tags.append(
- ("meta", {"name": "DC.type",
- "content": str(self.source_type)}))
+ ("meta", {"name": "DC.type", "content": str(self.source_type)})
+ )
if self.format_type:
tags.append(
- ("meta", {"name": "DC.format",
- "content": str(self.format_type)}))
+ (
+ "meta",
+ {"name": "DC.format", "content": str(self.format_type)},
+ )
+ )
identifier = self.dublin_core_identifier
if identifier:
tags.append(
- ("meta", {"name": "DC.identifier",
- "content": identifier}))
+ ("meta", {"name": "DC.identifier", "content": identifier})
+ )
if self.language:
lang = self.language.iso_code
- tags.append(
- ("meta", {"name": "DC.language",
- "content": lang}))
+ tags.append(("meta", {"name": "DC.language", "content": lang}))
if self.licenses.count():
licences = ", ".join(str(l) for l in self.licenses.all())
- tags.append(
- ("meta", {"name": "DC.rights",
- "content": licences}))
+ tags.append(("meta", {"name": "DC.rights", "content": licences}))
src = None
if self.source:
src = self.source.dublin_core_identifier
if src:
- tags.append(
- ("meta", {"name": "DC.relation",
- "content": src}))
- tags.append(
- ("meta", {"name": "DC.source",
- "content": src}))
+ tags.append(("meta", {"name": "DC.relation", "content": src}))
+ tags.append(("meta", {"name": "DC.source", "content": src}))
elif self.source_free_input:
tags.append(
- ("meta", {"name": "DC.source",
- "content": self.source_free_input}))
+ (
+ "meta",
+ {"name": "DC.source", "content": self.source_free_input},
+ )
+ )
html = ""
for tag, attrs in tags:
et = ET.Element(tag, attrib=attrs)
@@ -3796,13 +4496,19 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
("ctx_ver", "Z39.88-2004"),
("rft_val_fmt", "info:ofi/fmt:kev:mtx:dc"),
("rft.title", self.title),
- ("rft.btitle", self.title)
+ ("rft.btitle", self.title),
]
if self.associated_url:
info.append(("rft.identifier", self.associated_url))
elif Site.objects.count():
- info.append(("rft.identifier", "http://{}{}".format(
- Site.objects.all()[0].domain, self.get_absolute_url())))
+ info.append(
+ (
+ "rft.identifier",
+ "http://{}{}".format(
+ Site.objects.all()[0].domain, self.get_absolute_url()
+ ),
+ )
+ )
for author in self.authors.all():
person = author.person
if not person.raw_name:
@@ -3810,8 +4516,9 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
if person.first_name and person.name:
info.append(("rft.aulast", person.name))
info.append(("rft.aufirst", person.first_name))
- info.append(("rft.au", "{}+{}".format(person.first_name,
- person.name)))
+ info.append(
+ ("rft.au", "{}+{}".format(person.first_name, person.name))
+ )
else:
info.append(("rft.au", person.raw_name))
if self.source_type:
@@ -3826,8 +4533,9 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
if self.creation_date.day == 1 and self.creation_date.month == 1:
info.append(("rft.date", self.creation_date.year))
else:
- info.append(("rft.date",
- self.creation_date.strftime("%Y-%m-%d")))
+ info.append(
+ ("rft.date", self.creation_date.strftime("%Y-%m-%d"))
+ )
if self.source and self.source.title:
info.append(("rft.source", self.source.title))
elif self.source_free_input:
@@ -3844,8 +4552,9 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
return '<span class="Z3988" title="{}">'.format(urlencode(info))
def save(self, *args, **kwargs):
- no_path_change = 'no_path_change' in kwargs \
- and kwargs.pop('no_path_change')
+ no_path_change = "no_path_change" in kwargs and kwargs.pop(
+ "no_path_change"
+ )
self.set_index()
if not self.associated_url:
self.associated_url = None
@@ -3861,8 +4570,11 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel,
self.container_ref_id = container_ref.pk
super(Document, self).save(*args, **kwargs)
- if self.image and not no_path_change and \
- not getattr(self, '_no_path_change', False):
+ if (
+ self.image
+ and not no_path_change
+ and not getattr(self, "_no_path_change", False)
+ ):
links = self._move_image()
if not links:
return
@@ -3883,18 +4595,25 @@ class OperationType(GeneralType):
class Meta:
verbose_name = _("Operation type")
verbose_name_plural = _("Operation types")
- ordering = ['judiciary', '-preventive', 'order', 'label']
+ ordering = ["judiciary", "-preventive", "order", "label"]
@classmethod
- def get_types(cls, dct=None, instances=False, exclude=None,
- empty_first=True, default=None, initial=None):
+ def get_types(
+ cls,
+ dct=None,
+ instances=False,
+ exclude=None,
+ empty_first=True,
+ default=None,
+ initial=None,
+ ):
dct = dct or {}
exclude = exclude or []
initial = initial or []
tuples = []
- dct['available'] = True
+ dct["available"] = True
if not instances and empty_first and not default:
- tuples.append(('', '--'))
+ tuples.append(("", "--"))
if default and not instances:
try:
default = cls.objects.get(txt_idx=default)
@@ -3908,16 +4627,20 @@ class OperationType(GeneralType):
items = items.exclude(txt_idx__in=exclude)
current_preventive, current_judiciary, current_lst = None, None, None
item_list = list(items.order_by(*cls._meta.ordering).all())
- new_vals = cls._get_initial_types(initial, [i.pk for i in item_list],
- instance=True)
+ new_vals = cls._get_initial_types(
+ initial, [i.pk for i in item_list], instance=True
+ )
item_list += new_vals
for item in item_list:
item.rank = 0
if instances:
return item_list
for item in item_list:
- if not current_lst or item.preventive != current_preventive \
- or item.judiciary != current_judiciary:
+ if (
+ not current_lst
+ or item.preventive != current_preventive
+ or item.judiciary != current_judiciary
+ ):
if current_lst:
tuples.append(current_lst)
if item.judiciary:
@@ -3935,7 +4658,7 @@ class OperationType(GeneralType):
return tuples
@classmethod
- def is_preventive(cls, ope_type_id, key=''):
+ def is_preventive(cls, ope_type_id, key=""):
try:
op_type = cls.objects.get(pk=ope_type_id)
except cls.DoesNotExist:
@@ -3964,25 +4687,27 @@ class AdministrationScript(models.Model):
class Meta:
verbose_name = _("Administration script")
verbose_name_plural = _("Administration scripts")
- ordering = ['name']
+ ordering = ["name"]
def __str__(self):
return str(self.name)
-SCRIPT_STATE = (("S", _("Scheduled")),
- ("P", _("In progress")),
- ("FE", _("Finished with errors")),
- ("F", _("Finished")),
- )
+SCRIPT_STATE = (
+ ("S", _("Scheduled")),
+ ("P", _("In progress")),
+ ("FE", _("Finished with errors")),
+ ("F", _("Finished")),
+)
SCRIPT_STATE_DCT = dict(SCRIPT_STATE)
class AdministrationTask(models.Model):
script = models.ForeignKey(AdministrationScript)
- state = models.CharField(_("State"), max_length=2, choices=SCRIPT_STATE,
- default='S')
+ state = models.CharField(
+ _("State"), max_length=2, choices=SCRIPT_STATE, default="S"
+ )
creation_date = models.DateTimeField(default=datetime.datetime.now)
launch_date = models.DateTimeField(null=True, blank=True)
finished_date = models.DateTimeField(null=True, blank=True)
@@ -3991,17 +4716,16 @@ class AdministrationTask(models.Model):
class Meta:
verbose_name = _("Administration task")
verbose_name_plural = _("Administration tasks")
- ordering = ['script']
+ ordering = ["script"]
def __str__(self):
state = _("Unknown")
if self.state in SCRIPT_STATE_DCT:
state = str(SCRIPT_STATE_DCT[self.state])
- return "{} - {} - {}".format(self.script, self.creation_date,
- state)
+ return "{} - {} - {}".format(self.script, self.creation_date, state)
def execute(self):
- if self.state != 'S':
+ if self.state != "S":
return
self.launch_date = datetime.datetime.now()
@@ -4009,29 +4733,35 @@ class AdministrationTask(models.Model):
if not script_dir:
self.result = str(
- _("ISHTAR_SCRIPT_DIR is not set in your "
- "local_settings. Contact your administrator."))
- self.state = 'FE'
+ _(
+ "ISHTAR_SCRIPT_DIR is not set in your "
+ "local_settings. Contact your administrator."
+ )
+ )
+ self.state = "FE"
self.finished_date = datetime.datetime.now()
self.save()
return
- if '..' in script_dir:
+ if ".." in script_dir:
self.result = str(
- _("Your ISHTAR_SCRIPT_DIR is containing "
- "dots \"..\". As it can refer to relative "
- "paths, it can be a security issue and this is "
- "not allowed. Only put a full path."))
- self.state = 'FE'
+ _(
+ "Your ISHTAR_SCRIPT_DIR is containing "
+ 'dots "..". As it can refer to relative '
+ "paths, it can be a security issue and this is "
+ "not allowed. Only put a full path."
+ )
+ )
+ self.state = "FE"
self.finished_date = datetime.datetime.now()
self.save()
return
if not os.path.isdir(script_dir):
self.result = str(
- _("Your ISHTAR_SCRIPT_DIR: \"{}\" is not a valid directory.")
+ _('Your ISHTAR_SCRIPT_DIR: "{}" is not a valid directory.')
).format(script_dir)
- self.state = 'FE'
+ self.state = "FE"
self.finished_date = datetime.datetime.now()
self.save()
return
@@ -4045,14 +4775,16 @@ class AdministrationTask(models.Model):
break
if not script_name:
self.result = str(
- _("Script \"{}\" is not available in your script directory. "
- "Check your configuration.")
+ _(
+ 'Script "{}" is not available in your script directory. '
+ "Check your configuration."
+ )
).format(self.script.path)
- self.state = 'FE'
+ self.state = "FE"
self.finished_date = datetime.datetime.now()
self.save()
return
- self.state = 'P'
+ self.state = "P"
self.save()
self.finished_date = datetime.datetime.now()
@@ -4060,19 +4792,20 @@ class AdministrationTask(models.Model):
session = Popen([script_name], stdout=PIPE, stderr=PIPE)
stdout, stderr = session.communicate()
except OSError as e:
- self.state = 'FE'
- self.result = "Error executing \"{}\" script: {}".format(
- self.script.path, e)
+ self.state = "FE"
+ self.result = 'Error executing "{}" script: {}'.format(
+ self.script.path, e
+ )
self.save()
return
self.finished_date = datetime.datetime.now()
if stderr:
- self.state = 'FE'
- self.result = "Error: {}".format(stderr.decode('utf-8'))
+ self.state = "FE"
+ self.result = "Error: {}".format(stderr.decode("utf-8"))
else:
- self.state = 'F'
- self.result = "{}".format(stdout.decode('utf-8'))
+ self.state = "F"
+ self.result = "{}".format(stdout.decode("utf-8"))
self.save()
@@ -4093,24 +4826,40 @@ class ExportTask(models.Model):
_("Filter on"), max_length=2, choices=ITEM_TYPES, null=True, blank=True
)
filter_text = models.TextField(
- _("Filter query"), blank=True, default="",
- help_text=_("Textual query on this item (try it on the main "
- "interface)"))
+ _("Filter query"),
+ blank=True,
+ default="",
+ help_text=_(
+ "Textual query on this item (try it on the main " "interface)"
+ ),
+ )
geo = models.BooleanField(
- _("Export geographic data"), default=True,
- help_text=_("Geographic data can represent large volume of "
- "information. Geographic data can be excluded from the "
- "export"))
- state = models.CharField(_("State"), max_length=2, choices=EXPORT_STATE,
- default='C')
- put_locks = models.BooleanField(_("Put locks on associated items"),
- default=False)
+ _("Export geographic data"),
+ default=True,
+ help_text=_(
+ "Geographic data can represent large volume of "
+ "information. Geographic data can be excluded from the "
+ "export"
+ ),
+ )
+ state = models.CharField(
+ _("State"), max_length=2, choices=EXPORT_STATE, default="C"
+ )
+ put_locks = models.BooleanField(
+ _("Put locks on associated items"), default=False
+ )
lock_user = models.ForeignKey(
- User, related_name='+', on_delete=models.SET_NULL,
- verbose_name=_("Lock user"), blank=True, null=True,
- help_text=_("Owner of the lock if item are locked. Warning: if no "
- "user is provided the locks can be remove by any user "
- "with the permission to edit.")
+ User,
+ related_name="+",
+ on_delete=models.SET_NULL,
+ verbose_name=_("Lock user"),
+ blank=True,
+ null=True,
+ help_text=_(
+ "Owner of the lock if item are locked. Warning: if no "
+ "user is provided the locks can be remove by any user "
+ "with the permission to edit."
+ ),
)
export_types = models.BooleanField(_("Export types"), default=True)
export_conf = models.BooleanField(_("Export configuration"), default=True)
@@ -4122,15 +4871,17 @@ class ExportTask(models.Model):
creation_date = models.DateTimeField(default=datetime.datetime.now)
launch_date = models.DateTimeField(null=True, blank=True)
finished_date = models.DateTimeField(null=True, blank=True)
- result = models.FileField(_("Result"), null=True, blank=True,
- upload_to="exports/%Y/%m/")
- result_info = models.TextField(_("Result information"), blank=True,
- default="")
+ result = models.FileField(
+ _("Result"), null=True, blank=True, upload_to="exports/%Y/%m/"
+ )
+ result_info = models.TextField(
+ _("Result information"), blank=True, default=""
+ )
class Meta:
verbose_name = _("Archive - Export")
verbose_name_plural = _("Archive - Exports")
- ordering = ['creation_date']
+ ordering = ["creation_date"]
def __str__(self):
state = _("Unknown")
@@ -4149,7 +4900,8 @@ class ExportTask(models.Model):
def clean(self):
if (self.filter_text and not self.filter_type) or (
- self.filter_type and not self.filter_text):
+ self.filter_type and not self.filter_text
+ ):
raise ValidationError(
_("To filter filter type and filter text must be filled.")
)
@@ -4160,25 +4912,35 @@ class ImportTask(models.Model):
launch_date = models.DateTimeField(null=True, blank=True)
finished_date = models.DateTimeField(null=True, blank=True)
import_user = models.ForeignKey(
- User, related_name='+', on_delete=models.SET_NULL,
- verbose_name=_("Import user"), blank=True, null=True,
- help_text=_("If set the \"Import user\" will be the editor for last "
- "version. If the field is left empty no history will be "
- "recorded.")
- )
- state = models.CharField(_("State"), max_length=2, choices=EXPORT_STATE,
- default='C')
+ User,
+ related_name="+",
+ on_delete=models.SET_NULL,
+ verbose_name=_("Import user"),
+ blank=True,
+ null=True,
+ help_text=_(
+ 'If set the "Import user" will be the editor for last '
+ "version. If the field is left empty no history will be "
+ "recorded."
+ ),
+ )
+ state = models.CharField(
+ _("State"), max_length=2, choices=EXPORT_STATE, default="C"
+ )
delete_before = models.BooleanField(
- _("Delete before adding"), default=False,
- help_text=_("Delete existing items before adding"))
+ _("Delete before adding"),
+ default=False,
+ help_text=_("Delete existing items before adding"),
+ )
releasing_locks = models.BooleanField(
- _("Releasing locks on associated items"), default=False)
+ _("Releasing locks on associated items"), default=False
+ )
source = models.FileField(_("Source"), upload_to="imports/%Y/%m/")
class Meta:
verbose_name = _("Archive - Import")
verbose_name_plural = _("Archive - Imports")
- ordering = ['creation_date']
+ ordering = ["creation_date"]
def __str__(self):
state = _("Unknown")