diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-04-16 16:41:46 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-04-16 16:41:46 +0200 | 
| commit | 6e95beabf26ddd3d8de69e34dfbfb97bc1625d80 (patch) | |
| tree | 364c2688b46f47d3ee9243e70cbaf5485e177b0f /ishtar_common | |
| parent | 303a62efae3d3f568545c682649a29de1fb7fc83 (diff) | |
| download | Ishtar-6e95beabf26ddd3d8de69e34dfbfb97bc1625d80.tar.bz2 Ishtar-6e95beabf26ddd3d8de69e34dfbfb97bc1625d80.zip  | |
🗃️ museum module: new db fields, add admin
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/admin.py | 4 | ||||
| -rw-r--r-- | ishtar_common/forms_common.py | 4 | ||||
| -rw-r--r-- | ishtar_common/migrations/0236_auto_20240208_1635.py | 112 | ||||
| -rw-r--r-- | ishtar_common/models.py | 80 | ||||
| -rw-r--r-- | ishtar_common/models_common.py | 18 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/sheet_document.html | 2 | 
6 files changed, 210 insertions, 10 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index 50b6d05b3..e5cb1b67b 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -553,6 +553,7 @@ class IshtarSiteProfileAdmin(admin.ModelAdmin):                  "mapping",                  "preventive_operator",                  "underwater", +                "museum",              ),          }),          (_("Advanced configuration"), { @@ -1349,9 +1350,10 @@ class GeneralTypeAdmin(ChangeParentAdmin, ImportActionAdmin, ImportJSONActionAdm  general_models = [      models.SourceType,      models.AuthorType, -    models.LicenseType,      models.Language, +    models.LicenseType,      models.PersonType, +    models.ShootingAngle,      models_common.GeoProviderType,      models_common.GeoDataType,      models_common.GeoOriginType, diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 7f37e86ce..e2597175b 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -1986,7 +1986,7 @@ class DocumentForm(forms.ModelForm, CustomForm, ManageOldType):          required=False,      )      licenses = widgets.Select2MultipleField( -        label=_("Licenses"), required=False, model=models.LicenseType +        label=_("Rights of use / licenses"), required=False, model=models.LicenseType      )      tags = widgets.Select2MultipleField(          label=_("Tags"), @@ -2367,7 +2367,7 @@ class DocumentSelect(HistorySelect):      language = forms.ChoiceField(label=_("Language"), choices=[])      isbn = forms.CharField(label=_("ISBN"))      issn = forms.CharField(label=_("ISSN")) -    licenses = forms.ChoiceField(label=_("License"), choices=[]) +    licenses = forms.ChoiceField(label=_("Rights of use / licenses"), choices=[])      comment = forms.CharField(label=_("Comment"))      additional_information = forms.CharField(label=_("Additional informations")) diff --git a/ishtar_common/migrations/0236_auto_20240208_1635.py b/ishtar_common/migrations/0236_auto_20240208_1635.py new file mode 100644 index 000000000..48b1060d6 --- /dev/null +++ b/ishtar_common/migrations/0236_auto_20240208_1635.py @@ -0,0 +1,112 @@ +# Generated by Django 2.2.24 on 2024-02-08 16:35 + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import ishtar_common.models_common +import re + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0235_default_geo_types'), +    ] + +    operations = [ +        migrations.CreateModel( +            name='ShootingAngle', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('label', models.TextField(verbose_name='Label')), +                ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), +                ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), +                ('available', models.BooleanField(default=True, verbose_name='Available')), +                ('order', models.IntegerField(default=10, verbose_name='Order')), +            ], +            options={ +                'verbose_name': 'Shooting angle', +                'verbose_name_plural': 'Shooting angles', +                'ordering': ('label',), +            }, +            bases=(ishtar_common.models_common.Cached, models.Model), +        ), +        migrations.AlterModelOptions( +            name='licensetype', +            options={'ordering': ('parent__label', 'order', 'label'), 'verbose_name': 'License type', 'verbose_name_plural': 'License types'}, +        ), +        migrations.AddField( +            model_name='document', +            name='copyright', +            field=models.TextField(blank=True, default='', verbose_name='Copyright'), +        ), +        migrations.AddField( +            model_name='document', +            name='rights_owner', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.Organization', verbose_name='Rights owner'), +        ), +        migrations.AddField( +            model_name='historicaldocument', +            name='copyright', +            field=models.TextField(blank=True, default='', verbose_name='Copyright'), +        ), +        migrations.AddField( +            model_name='historicaldocument', +            name='rights_owner', +            field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.Organization', verbose_name='Rights owner'), +        ), +        migrations.AddField( +            model_name='historicalorganization', +            name='museum_museofile_id', +            field=models.TextField(blank=True, default='', verbose_name='Museofile id'), +        ), +        migrations.AddField( +            model_name='licensetype', +            name='order', +            field=models.IntegerField(default=10, verbose_name='Order'), +        ), +        migrations.AddField( +            model_name='licensetype', +            name='parent', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.LicenseType', verbose_name='Parent'), +        ), +        migrations.AddField( +            model_name='organization', +            name='museum_museofile_id', +            field=models.TextField(blank=True, default='', verbose_name='Museofile id'), +        ), +        migrations.AlterField( +            model_name='document', +            name='licenses', +            field=models.ManyToManyField(blank=True, to='ishtar_common.LicenseType', verbose_name='Rights of use / license'), +        ), +        migrations.AlterField( +            model_name='gdprlog', +            name='activity', +            field=models.CharField(choices=[('DC', 'Directory consultation'), ('DE', 'Directory export'), ('PV', "Viewing a person's notice"), ('PE', "Exporting a person's notice"), ('PC', 'Person creation'), ('PM', 'Person modification'), ('Pm', 'Person merge'), ('PD', 'Person deletion'), ('AC', 'Admin - Directory consultation'), ('AV', 'Admin - Person view'), ('AM', 'Admin - Person modification'), ('AD', 'Admin - Person deletion')], max_length=2, verbose_name='Activity'), +        ), +        migrations.CreateModel( +            name='BiographicalNote', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('denomination', models.TextField(verbose_name='Denomination')), +                ('last_name', models.TextField(blank=True, default='', verbose_name='Last name')), +                ('first_name', models.TextField(blank=True, default='', verbose_name='First name')), +                ('birth_year', models.PositiveIntegerField(blank=True, null=True, verbose_name='Year of birth')), +                ('death_year', models.PositiveIntegerField(blank=True, null=True, verbose_name='Year of death')), +                ('biography', models.TextField(blank=True, default='', verbose_name='Biography')), +                ('biography_format', models.CharField(blank=True, choices=[('NO', 'None'), ('MD', 'Markdown'), ('HT', 'HTML')], default='NO', max_length=2, verbose_name='Biography format')), +                ('person', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.Person', verbose_name='Person')), +            ], +        ), +        migrations.AddField( +            model_name='document', +            name='shooting_angle', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.ShootingAngle', verbose_name='Shooting angle'), +        ), +        migrations.AddField( +            model_name='historicaldocument', +            name='shooting_angle', +            field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.ShootingAngle', verbose_name='Shooting angle'), +        ), +    ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index c978b087b..bd457e970 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -24,6 +24,7 @@ from ipware import get_client_ip  import sys  from bs4 import BeautifulSoup +import bleach  import copy  import datetime  import inspect @@ -78,6 +79,7 @@ from django.template import Context, Template  from django.template.defaultfilters import slugify  from django.urls import reverse  from django.utils.functional import lazy +from django.utils.safestring import mark_safe  from ishtar_common.data_importer import post_importer_action  from ishtar_common.utils import (      ugettext_lazy as _, @@ -141,6 +143,8 @@ from ishtar_common.utils import (  from ishtar_common.models_common import (      GeneralType,      HierarchicalType, +    OrderedHierarchicalType, +    OrderedType,      BaseHistorizedItem,      LightHistorizedItem,      HistoricalRecords, @@ -194,6 +198,8 @@ __all__ = [      "Regexp",      "ImportTarget",      "ItemKey", +    "OrderedHierarchicalType", +    "OrderedType",      "TargetKey",      "FormaterType",      "Import", @@ -2612,6 +2618,7 @@ class Organization(Address, Merge, OwnPerms, BaseGenderedType, ValueGetter, Main          default="",          help_text=documentation_get_gender_values,      ) +    museum_museofile_id = models.TextField(_("Museofile id"), blank=True, default="")      cached_label = models.TextField(          _("Cached name"), blank=True, default="", db_index=True      ) @@ -3204,6 +3211,38 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):  post_save.connect(cached_label_changed, sender=Person) +TEXT_FORMAT = ( +    ("NO", _("None")), +    ("MD", _("Markdown")), +    ("HT", _("HTML")), +) + + +def text_format(text, text_format): +    if text_format == "MD": +        return mark_safe(markdown(text)) +    elif text_format == "HT": +        return mark_safe(bleach.clean(text)) +    return text_format + + +class BiographicalNote(models.Model): +    denomination = models.TextField(_("Denomination")) +    last_name = models.TextField(_("Last name"), blank=True, default="") +    first_name = models.TextField(_("First name"), blank=True, default="") +    birth_year = models.PositiveIntegerField(_("Year of birth"), blank=True, null=True) +    death_year = models.PositiveIntegerField(_("Year of death"), blank=True, null=True) +    biography = models.TextField(_("Biography"), blank=True, default="") +    biography_format = models.CharField( +        _("Biography format"), blank=True, default="NO", max_length=2, choices=TEXT_FORMAT +    ) +    person = models.ForeignKey(Person, verbose_name=_("Person"), blank=True, null=True, on_delete=models.SET_NULL) + +    @property +    def formatted_biography(self): +        return text_format(self.biography, self.biography_format) + +  GDPR_ACTIVITY = (      ("DC", _("Directory consultation")),      ("DE", _("Directory export")), @@ -3939,16 +3978,20 @@ post_save.connect(post_save_cache, sender=Format)  post_delete.connect(post_save_cache, sender=Format) -class LicenseType(GeneralType): +class LicenseType(OrderedHierarchicalType):      url = models.URLField(_("URL"), blank=True, null=True)      class Meta:          verbose_name = _("License type")          verbose_name_plural = _("License types") -        ordering = ("label",) +        ordering = ("parent__label", "order", "label",)      ADMIN_SECTION = _("Documents") +post_save.connect(post_save_cache, sender=LicenseType) +post_delete.connect(post_save_cache, sender=LicenseType) + +  class DocumentTag(GeneralType):      SLUG = "documenttag" @@ -3959,8 +4002,20 @@ class DocumentTag(GeneralType):      ADMIN_SECTION = _("Documents") -post_save.connect(post_save_cache, sender=LicenseType) -post_delete.connect(post_save_cache, sender=LicenseType) +post_save.connect(post_save_cache, sender=DocumentTag) +post_delete.connect(post_save_cache, sender=DocumentTag) + + +class ShootingAngle(OrderedType): +    class Meta: +        verbose_name = _("Shooting angle") +        verbose_name_plural = _("Shooting angles") +        ordering = ("order", "label",) +    ADMIN_SECTION = _("Documents") + + +post_save.connect(post_save_cache, sender=ShootingAngle) +post_delete.connect(post_save_cache, sender=ShootingAngle)  class Document( @@ -4391,9 +4446,17 @@ class Document(      publishing_year = models.PositiveIntegerField(          _("Year of publication"), blank=True, null=True      ) +    rights_owner = models.ForeignKey( +        Organization, +        verbose_name=_("Rights owner"), +        blank=True, +        null=True, +        on_delete=models.SET_NULL, +    )      licenses = models.ManyToManyField( -        LicenseType, verbose_name=_("License"), blank=True +        LicenseType, verbose_name=_("Rights of use / license"), blank=True      ) +    copyright = models.TextField(_("Copyright"), blank=True, default="")      tags = models.ManyToManyField(DocumentTag, verbose_name=_("Tags"), blank=True)      language = models.ForeignKey(          Language, @@ -4439,6 +4502,13 @@ class Document(          null=True,      )      scale = models.CharField(_("Scale"), max_length=30, null=True, blank=True) +    shooting_angle = models.ForeignKey( +        ShootingAngle, +        verbose_name=_("Shooting angle"), +        on_delete=models.SET_NULL, +        blank=True, +        null=True, +    )      authors = models.ManyToManyField(          Author, verbose_name=_("Authors"), related_name="documents",          blank=True diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 928b22630..c6b1316e4 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -725,6 +725,17 @@ class GeneralType(Cached, models.Model):              item.generate_key() +class OrderedModel(models.Model): +    order = models.IntegerField(_("Order"), default=10) +    class Meta: +        abstract = True + + +class OrderedType(OrderedModel, GeneralType): +    class Meta: +        abstract = True + +  class HierarchicalType(GeneralType):      parent = models.ForeignKey(          "self", @@ -758,6 +769,11 @@ class HierarchicalType(GeneralType):              parent = parent.parent +class OrderedHierarchicalType(OrderedModel, HierarchicalType): +    class Meta: +        abstract = True + +  class StatisticItem:      STATISTIC_MODALITIES = []  # example: "year", "operation_type__label"      STATISTIC_MODALITIES_OPTIONS = OrderedDict()  # example: @@ -3297,7 +3313,7 @@ class MainItem(ShortMenuItem, SerializeItem, SheetItem):          if not getattr(request.user, "ishtaruser", None):              return False          user = request.user -        return user.ishtaruser.has_right(action_name, request.session)\ +        return user.ishtaruser.has_right(action_name, request.session)      def get_extra_actions(self, request):          if not hasattr(self, "SLUG"): diff --git a/ishtar_common/templates/ishtar/sheet_document.html b/ishtar_common/templates/ishtar/sheet_document.html index e4ce47af5..304d13579 100644 --- a/ishtar_common/templates/ishtar/sheet_document.html +++ b/ishtar_common/templates/ishtar/sheet_document.html @@ -86,7 +86,7 @@      {% field_flex "Language" item.language %}      {% field_flex "ISBN" item.isbn %}      {% field_flex "ISSN" item.issn %} -    {% field_flex_multiple_obj "Licenses" item 'licenses' %} +    {% field_flex_multiple_obj "Rights of use / licenses" item 'licenses' %}      {% endif %}      {% if item.source or item.source_free_input %}  | 
