summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/admin.py9
-rw-r--r--ishtar_common/data.py23
-rw-r--r--ishtar_common/management/commands/ishtar_maintenance.py18
-rw-r--r--ishtar_common/migrations/0240_state_number_max_len.py36
-rw-r--r--ishtar_common/migrations/0241_migrate_old_department.py50
-rw-r--r--ishtar_common/models_common.py2
-rw-r--r--ishtar_common/utils.py78
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(