diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7acd3bd6..84a17a15 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/psf/black - rev: 25.1.0 + rev: 25.12.0 hooks: - id: black - repo: https://github.com/pycqa/isort - rev: 6.0.1 + rev: 7.0.0 hooks: - id: isort @@ -17,32 +17,32 @@ repos: files: \.html$ - repo: https://github.com/asottile/pyupgrade - rev: v3.19.1 + rev: v3.21.2 hooks: - id: pyupgrade - args: [ "--py310-plus" ] + args: [ "--py313-plus" ] - repo: https://github.com/rtts/djhtml - rev: '3.0.7' + rev: '3.0.10' hooks: - id: djhtml - id: djcss - id: djjs - repo: https://github.com/adamchainz/django-upgrade - rev: 1.24.0 + rev: 1.29.1 hooks: - id: django-upgrade - args: [ --target-version, "4.1" ] + args: [ --target-version, "6.0" ] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: 'v0.11.3' + rev: 'v0.14.10' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/adamchainz/djade-pre-commit - rev: '1.3.2' + rev: '1.7.0' hooks: - id: djade args: [--target-version, "5.1"] diff --git a/catalog/management/commands/download_programs.py b/catalog/management/commands/download_programs.py index 22d29bf8..cae6fd65 100644 --- a/catalog/management/commands/download_programs.py +++ b/catalog/management/commands/download_programs.py @@ -71,7 +71,7 @@ def handle(self, *args: Any, **options: Any) -> None: if mnemonic_span.text not in known_slugs: fac = mnemonic_span.find_previous_siblings("a") program_name = mnemonic_span.find_previous( - "strong", "search-result__structure-intitule" + "strong", {"class": "search-result__structure-intitule"} ).text faculties: list = [] @@ -91,13 +91,13 @@ def handle(self, *args: Any, **options: Any) -> None: } if option_div := mnemonic_span.find_previous( - "div", "search-result__resultat--fille" + "div", {"class": "search-result__resultat--fille"} ): parent_program_div = option_div.find_previous( - "div", "search-result__result-item" + "div", {"class": "search-result__result-item"} ) parent_mnemonic_span = parent_program_div.find( - "span", "search-result__mnemonique" + "span", {"class": "search-result__mnemonique"} ) p["parent"] = parent_mnemonic_span.text parent_programs.add(parent_mnemonic_span.text) diff --git a/catalog/migrations/0004_alter_coursecategory_unique_together_and_more.py b/catalog/migrations/0004_alter_coursecategory_unique_together_and_more.py new file mode 100644 index 00000000..7e5f6b76 --- /dev/null +++ b/catalog/migrations/0004_alter_coursecategory_unique_together_and_more.py @@ -0,0 +1,63 @@ +# Generated by Django 6.0 on 2025-12-21 20:19 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("catalog", "0003_category_is_archive_course_is_archive"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AlterUniqueTogether( + name="coursecategory", + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name="courseuserview", + unique_together=set(), + ), + migrations.AlterField( + model_name="category", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="course", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="coursecategory", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="courseuserview", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AddConstraint( + model_name="coursecategory", + constraint=models.UniqueConstraint( + fields=("course", "category"), name="unique_course_category" + ), + ), + migrations.AddConstraint( + model_name="courseuserview", + constraint=models.UniqueConstraint( + fields=("user", "course"), name="unique_user_course_view" + ), + ), + ] diff --git a/catalog/models.py b/catalog/models.py index 05f4714b..de944e22 100644 --- a/catalog/models.py +++ b/catalog/models.py @@ -108,7 +108,7 @@ class Course(models.Model): description = models.TextField(default="") period = models.CharField( max_length=4, - choices=PeriodType.choices, + choices=PeriodType, default=PeriodType.UNKNOWN, ) @@ -142,7 +142,11 @@ class CourseCategory(models.Model): mandatory = models.BooleanField(default=True) class Meta: - unique_together = ("course", "category") + constraints = [ + models.UniqueConstraint( + fields=["course", "category"], name="unique_course_category" + ), + ] class CourseUserView(models.Model): @@ -152,7 +156,11 @@ class CourseUserView(models.Model): last_view = models.DateTimeField(auto_now=True) class Meta: - unique_together = ("user", "course") + constraints = [ + models.UniqueConstraint( + fields=["user", "course"], name="unique_user_course_view" + ), + ] @classmethod def visit(cls, user, course: Course): diff --git a/catalog/suggestions.py b/catalog/suggestions.py index 5c25811a..e1897ffd 100644 --- a/catalog/suggestions.py +++ b/catalog/suggestions.py @@ -8,7 +8,7 @@ def distance(v1: list[bool], v2: list[bool]) -> float: - absolute_difference = [abs(c1 - c2) for c1, c2 in zip(v1, v2)] + absolute_difference = [abs(c1 - c2) for c1, c2 in zip(v1, v2, strict=True)] distance = sum(absolute_difference) return distance diff --git a/documents/migrations/0005_alter_vote_unique_together_alter_bulkdocuments_id_and_more.py b/documents/migrations/0005_alter_vote_unique_together_alter_bulkdocuments_id_and_more.py new file mode 100644 index 00000000..ba5a1e01 --- /dev/null +++ b/documents/migrations/0005_alter_vote_unique_together_alter_bulkdocuments_id_and_more.py @@ -0,0 +1,58 @@ +# Generated by Django 6.0 on 2025-12-21 20:19 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("documents", "0004_document_thumbnail"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AlterUniqueTogether( + name="vote", + unique_together=set(), + ), + migrations.AlterField( + model_name="bulkdocuments", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="document", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="document", + name="thumbnail", + field=models.FileField(blank=True, default="", upload_to="thumbnail"), + ), + migrations.AlterField( + model_name="documenterror", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AlterField( + model_name="vote", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + migrations.AddConstraint( + model_name="vote", + constraint=models.UniqueConstraint( + fields=("user", "document"), name="unique_user_document_vote" + ), + ), + ] diff --git a/documents/models.py b/documents/models.py index a9763586..e0d26968 100644 --- a/documents/models.py +++ b/documents/models.py @@ -52,7 +52,7 @@ class DocumentState(models.TextChoices): file_type = models.CharField(max_length=255, default="") original = models.FileField(upload_to="original_document") pdf = models.FileField(upload_to="pdf_document") - thumbnail = models.FileField(upload_to="thumbnail", null=True) + thumbnail = models.FileField(upload_to="thumbnail", blank=True, default="") state = models.CharField( max_length=20, @@ -179,7 +179,11 @@ class VoteType(models.TextChoices): vote_type = models.CharField(max_length=10, choices=VoteType.choices) class Meta: - unique_together = ("user", "document") + constraints = [ + models.UniqueConstraint( + fields=["user", "document"], name="unique_user_document_vote" + ), + ] class DocumentError(models.Model): diff --git a/documents/tasks.py b/documents/tasks.py index 3bf36ca5..6178fb70 100644 --- a/documents/tasks.py +++ b/documents/tasks.py @@ -219,7 +219,7 @@ def repair(self, document_id: int) -> int: ): try: subprocess.check_output( - ["mutool", "clean", "-gggg", "-l", tmpfile.name, output_path], + ["mutool", "clean", "-gggg", tmpfile.name, output_path], stderr=subprocess.STDOUT, ) except OSError as e: diff --git a/documents/templates/documents/document_edit.html b/documents/templates/documents/document_edit.html index abcb7e85..daa22930 100644 --- a/documents/templates/documents/document_edit.html +++ b/documents/templates/documents/document_edit.html @@ -3,7 +3,7 @@ {% block title %}Éditer {{ doc.name }}{% endblock %} {% block head %} - {% endblock head %} diff --git a/documents/templates/documents/document_upload.html b/documents/templates/documents/document_upload.html index d34d52b3..de61994c 100644 --- a/documents/templates/documents/document_upload.html +++ b/documents/templates/documents/document_upload.html @@ -3,7 +3,7 @@ {% block title %}Ajouter un document à {{ course.slug|upper }}{% endblock %} {% block head %} -