diff options
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/admin.py | 9 | ||||
| -rw-r--r-- | ishtar_common/data.py | 23 | ||||
| -rw-r--r-- | ishtar_common/management/commands/ishtar_maintenance.py | 18 | ||||
| -rw-r--r-- | ishtar_common/migrations/0240_state_number_max_len.py | 36 | ||||
| -rw-r--r-- | ishtar_common/migrations/0241_migrate_old_department.py | 50 | ||||
| -rw-r--r-- | ishtar_common/models_common.py | 2 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 78 | 
7 files changed, 163 insertions, 53 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index ae521729d..ae0f9eb3f 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -1196,7 +1196,6 @@ class ImportJSONActionAdmin(admin.ModelAdmin):                      with open(filename, "wb+") as zipped_file:                          for chunk in request.FILES["json_file"].chunks():                              zipped_file.write(chunk) -                    result = None                      result = restore_serialized(filename)                      try:                          result = restore_serialized(filename) @@ -1431,7 +1430,7 @@ class CreateAreaForm(forms.Form):          area = self.cleaned_data.get("area", 0)          if (not area_name and not area) or (area and area_name):              raise forms.ValidationError( -                _("Choose an area or set an area " "reference.") +                _("Choose an area or set an area reference.")              )          return self.cleaned_data @@ -1469,8 +1468,10 @@ class CreateDepartmentActionAdmin(GeneralTypeAdmin):              form = CreateAreaForm(request.POST)              if form.is_valid():                  area_name = form.cleaned_data.get("area_name", "") +                dpt_num = form.cleaned_data["department_number"] +                dpt_num = "0" + str(dpt_num) if dpt_num < 10 else str(dpt_num)                  if area_name: -                    slug = "dpt-" + area_name +                    slug = "dep-" + dpt_num                      while models.Area.objects.filter(txt_idx=slug).count():                          slug += "b"                      area = models.Area.objects.create(label=area_name, txt_idx=slug) @@ -1479,8 +1480,6 @@ class CreateDepartmentActionAdmin(GeneralTypeAdmin):                      )                  else:                      area = models.Area.objects.get(id=form.cleaned_data["area"]) -                dpt_num = form.cleaned_data["department_number"] -                dpt_num = "0" + str(dpt_num) if dpt_num < 10 else str(dpt_num)                  current_towns = [a.numero_insee for a in area.towns.all()]                  nb = 0                  for town in ( diff --git a/ishtar_common/data.py b/ishtar_common/data.py new file mode 100644 index 000000000..dcbc4aa09 --- /dev/null +++ b/ishtar_common/data.py @@ -0,0 +1,23 @@ +FRENCH_STATES = [ +    ("Auvergne-Rhône-Alpe", "FR-ARA", ("01", "03", "07", "15", "26", "38", "42", "43", "63", "69", "73", "74",)), +    ("Bourgogne-Franche-Comté", "FR-BFC", ("21", "25", "39", "58", "70", "71", "89", "90",)), +    ("Bretagne", "FR-BRE", ("22", "29", "35", "56",)), +    ("Centre-Val de Loire", "FR-CVL", ("18", "28", "36", "37", "41", "45",)), +    ("Corse", "FR-COR", ("2A", "2B",)), +    ("Grand Est", "FR-GES", ("08", "10", "51", "52", "54", "55", "57", "67", "68", "88",)), +    ("Hauts-de-France", "FR-HDF", ("02", "59", "60", "62", "80",)), +    ("Ile-de-France", "FR-IDF", ("75", "77", "78", "91", "92", "93", "94", "95", )), +    ("Normandie", "FR-NOR", ("14", "27", "50", "61", "76",)), +    ("Nouvelle-Aquitaine", "FR-NAQ", ("16", "17", "19", "23", "24", "33", "40", "47", "64", "79", "86", "87",)), +    ("Occitanie", "FR-OCC", ("09", "11", "12", "30", "31", "32", "34", "46", "48", "65", "66", "81", "82",)), +    ("Pays de la Loire", "FR-PDL", ("44", "49", "53", "72", "85",)), +    ("Provence Alpes Côte d’Azur", "FR-PAC", ("04", "05", "06", "13", "83", "84",)), +] + +FRENCH_TOM_STATES = [ +    ("Guadeloupe", "FR-GUA", []), +    ("Guyane", "FR-GUF", []), +    ("Martinique", "FR-MTQ", []), +    ("La Réunion", "FR-LRE", []), +    ("Mayotte", "FR-MAY", []), +] diff --git a/ishtar_common/management/commands/ishtar_maintenance.py b/ishtar_common/management/commands/ishtar_maintenance.py index 8bfd06812..260fbd46c 100644 --- a/ishtar_common/management/commands/ishtar_maintenance.py +++ b/ishtar_common/management/commands/ishtar_maintenance.py @@ -18,6 +18,7 @@ from django.core.management.base import BaseCommand, CommandError  from django.template.defaultfilters import slugify  from ishtar_common import models_common +from ishtar_common.utils import create_default_areas  APPS = (      "ishtar_common", @@ -245,6 +246,11 @@ def task_regenerate_permissions(options):          create_permissions(apps.get_app_config(app)) +def task_default_areas(options): +    verbose = not options.get("quiet", False) +    create_default_areas(verbose=verbose) + +  def task_missing_parcels(options):      quiet = options.get("quiet", False)      Parcel = apps.get_model("archaeological_operations", "Parcel") @@ -286,6 +292,14 @@ def get_filter(filter_str):  TASKS = { +    "admin_permissions": { +        "help": "regenerate basic model permissions", +        "action": task_regenerate_permissions, +    }, +    "admin_default_areas": { +        "help": "create default areas from department and states", +        "action": task_default_areas, +    },      "fix_main_image": {          "help": "for items with images and no main image, put the first one created as a main image",          "action": task_main_image, @@ -299,10 +313,6 @@ TASKS = {          "help": "regenerate cached label",          "action": task_check_cached_label,      }, -    "update_permissions": { -        "help": "regenerate basic model permissions", -        "action": task_regenerate_permissions, -    },      "update_qrcodes": {          "help": "regenerate qrcodes",          "action": task_regenerate_qrcodes, diff --git a/ishtar_common/migrations/0240_state_number_max_len.py b/ishtar_common/migrations/0240_state_number_max_len.py new file mode 100644 index 000000000..3755035cf --- /dev/null +++ b/ishtar_common/migrations/0240_state_number_max_len.py @@ -0,0 +1,36 @@ +# Generated by Django 2.2.24 on 2024-03-08 10:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0239_shootingangle_parent'), +    ] + +    operations = [ +        migrations.AlterModelOptions( +            name='language', +            options={'verbose_name': 'Language type', 'verbose_name_plural': 'Language types'}, +        ), +        migrations.AlterModelOptions( +            name='shootingangle', +            options={'ordering': ('order', 'label'), 'verbose_name': 'Shooting angle type', 'verbose_name_plural': 'Shooting angle types'}, +        ), +        migrations.AlterField( +            model_name='historicalorganization', +            name='museum_museofile_id', +            field=models.TextField(blank=True, default='', verbose_name='Museofile ID'), +        ), +        migrations.AlterField( +            model_name='organization', +            name='museum_museofile_id', +            field=models.TextField(blank=True, default='', verbose_name='Museofile ID'), +        ), +        migrations.AlterField( +            model_name='state', +            name='number', +            field=models.CharField(max_length=10, unique=True, verbose_name='Number'), +        ), +    ] diff --git a/ishtar_common/migrations/0241_migrate_old_department.py b/ishtar_common/migrations/0241_migrate_old_department.py new file mode 100644 index 000000000..4e5c2432a --- /dev/null +++ b/ishtar_common/migrations/0241_migrate_old_department.py @@ -0,0 +1,50 @@ +# Generated by Django 2.2.24 on 2024-03-07 17:52 + +from django.db import migrations +from django.db.models.functions import Length +from ishtar_common.data import FRENCH_STATES, FRENCH_TOM_STATES + + +def migrate(apps, __): +    Area = apps.get_model('ishtar_common', 'Area') +    Department = apps.get_model('ishtar_common', 'Department') +    State = apps.get_model('ishtar_common', 'State') +    Town = apps.get_model('ishtar_common', 'Town') + +    if not State.objects.filter(label="Nord-Pas-de-Calais").count(): +        # already OK or not french +        return + +    State.objects.filter(pk__isnull=False).delete() +    Area.objects.filter(txt_idx__startswith="dep-").delete() +    Area.objects.filter(txt_idx__startswith="state-").delete() + +    for lbl, code, departments in (FRENCH_STATES + FRENCH_TOM_STATES): +        state = State.objects.create(label=lbl, number=code) +        state_area = Area.objects.create(label=lbl, txt_idx=f'state-{code}') +        for dep_code in departments: +            q = Department.objects.filter(number=dep_code) +            if not q.count(): +                print(f"{dep_code} department is missing") +                continue +            dep = q.all()[0] +            dep.state = state +            dep.save() +            dep_area = Area.objects.create(label=dep.label, txt_idx=f'dep-{dep.number}') +            dep_area.parent = state_area +            dep_area.save() +            dep_area.towns.clear() +            q2 = Town.objects.annotate(insee_len=Length('numero_insee')).filter( +                numero_insee__startswith=dep_code, insee_len=5) +            dep_area.towns.add(*list(q2.all())) + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0240_state_number_max_len'), +    ] + +    operations = [ +        migrations.RunPython(migrate) +    ] diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 8a9de207e..26bc1c63f 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -2003,7 +2003,7 @@ class NumberManager(models.Manager):  class State(models.Model):      label = models.CharField(_("Label"), max_length=30) -    number = models.CharField(_("Number"), unique=True, max_length=3) +    number = models.CharField(_("Number"), unique=True, max_length=10)      objects = NumberManager()      class Meta: diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 3161e0003..08e7a49b4 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -65,6 +65,7 @@ from django.core.files.storage import FileSystemStorage  from django.core.validators import EMPTY_VALUES, MaxValueValidator  from django.db import models  from django.db.models import Q +from django.db.models.functions import Length  from django.http import HttpResponseRedirect  from django.urls import reverse, NoReverseMatch  from django.utils.crypto import get_random_string @@ -1496,61 +1497,52 @@ def create_default_areas(models=None, verbose=False):      areas = {} -    idx = 0 -    for state in State.objects.all(): -        slug = "state-" + slugify(state.label) -        area, created = Area.objects.get_or_create( +    created = 0 +    q = State.objects +    total = q.count() +    for idx, state in enumerate(q.all()): +        if verbose: +            sys.stdout.write(f"State \t{idx + 1}/{total}\r") +        slug = "state-" + state.number +        area, create = Area.objects.get_or_create(              txt_idx=slug, defaults={"label": state.label}          ) -        areas["state-{}".format(state.pk)] = area -        if created: -            idx += 1 +        areas[f"state-{state.pk}"] = area +        if create: +            created += 1      if verbose: -        print("\n* {} state areas added".format(idx)) +        sys.stdout.write(f"* {created} state areas added\n") -    idx, idx2 = 0, 0 -    for dep in Department.objects.all(): -        slug = "dep-" + slugify(dep.label) -        area, created = Area.objects.get_or_create( +    created, association, association2 = 0, 0, 0 +    q = Department.objects +    total = q.count() +    for idx, dep in enumerate(q.all()): +        if verbose: +            sys.stdout.write(f"Department \t{idx + 1}/{total}\r") +        slug = f"dep-{dep.number}" +        area, create = Area.objects.get_or_create(              txt_idx=slug, defaults={"label": dep.label}          )          areas["dep-" + dep.number] = area -        if created: -            idx += 1 +        if create: +            created += 1          if not dep.state_id:              continue          state_slug = "state-{}".format(dep.state_id) -        if state_slug not in areas: -            continue -        if area.parent and area.parent.pk == areas[state_slug].pk: -            continue -        idx2 += 1 -        area.parent = areas[state_slug] -        area.save() -    if verbose: -        print( -            "* {} department areas added with {} associations to state".format( -                idx, idx2 -            ) -        ) - -    idx = 0 -    for town in Town.objects.all(): -        if not town.numero_insee or len(town.numero_insee) != 5: -            continue -        code_dep = "dep-" + town.numero_insee[:2] -        code_dep_dom = "dep-" + town.numero_insee[:3] -        if code_dep in areas: -            if not areas[code_dep].towns.filter(pk=town.pk).count(): -                areas[code_dep].towns.add(town) -                idx += 1 -        elif code_dep_dom in areas: -            if not areas[code_dep_dom].towns.filter(pk=town.pk).count(): -                areas[code_dep_dom].towns.add(town) -                idx += 1 +        if state_slug in areas and (not area.parent or area.parent.pk != areas[state_slug].pk): +            association += 1 +            area.parent = areas[state_slug] +            area.save() +        area.towns.clear() +        q2 = Town.objects.annotate(insee_len=Length('numero_insee')).filter( +            numero_insee__startswith=dep.number, insee_len=5) +        area.towns.add(*list(q2.all()))      if verbose: -        print("* {} town associated to department area".format(idx)) +        sys.stdout.write( +            f"* {created} department areas added with {association} associations to state\n" +        ) +        sys.stdout.write(f"* {association} town associated to department area")  def get_relations_for_graph(  | 
