diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16ed0cf9..d3bd009d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,31 +8,19 @@ ci: autoupdate_schedule: monthly repos: -# Need to drop python 3.5 and 3.6 before we include python upgrade -# - repo: https://github.com/asottile/pyupgrade -# rev: v2.31.0 -# hooks: -# - id: pyupgrade -# args: ["--py38-plus"] -# - # manually run the upgrade command to fix the issue, no need for ci to run. - # - repo: https://github.com/adamchainz/django-upgrade - # rev: '1.16.0' - # hooks: - # - id: django-upgrade - # args: [--target-version, "4.2"] - - - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 + Need to drop python 3.5 and 3.6 before we include python upgrade + - repo: https://github.com/asottile/pyupgrade + rev: v2.31.0 hooks: - - id: ruff - args: [--fix, --exit-non-zero-on-fix] + - id: pyupgrade + args: ["--py38-plus"] - repo: https://github.com/asottile/yesqa rev: v1.5.0 hooks: - - id: ruff-format - + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: @@ -44,9 +32,3 @@ repos: - id: check-toml - id: end-of-file-fixer - id: trailing-whitespace - - # upgrade the isort version to fix compatiable issue withe peotry: https://stackoverflow.com/questions/75269700/pre-commit-fails-to-install-isort-5-11-4-with-error-runtimeerror-the-poetry-co - - repo: https://github.com/pycqa/isort - rev: 5.13.2 - hooks: - - id: isort diff --git a/src/djangocms_snippet/admin.py b/src/djangocms_snippet/admin.py index f7d3271b..a4de0d46 100644 --- a/src/djangocms_snippet/admin.py +++ b/src/djangocms_snippet/admin.py @@ -1,7 +1,7 @@ -from cms.utils import get_current_site -from cms.utils.permissions import get_model_permission_codename from typing import Any, ClassVar +from cms.utils import get_current_site +from cms.utils.permissions import get_model_permission_codename from django.conf import settings from django.contrib import admin from django.contrib.admin import helpers @@ -18,13 +18,19 @@ # Use the version mixin if djangocms-versioning is installed and enabled snippet_admin_classes = [admin.ModelAdmin] -djangocms_versioning_enabled = getattr(settings, "DJANGOCMS_SNIPPET_VERSIONING_ENABLED", True) +djangocms_versioning_enabled = getattr( + settings, "DJANGOCMS_SNIPPET_VERSIONING_ENABLED", True +) try: try: - from djangocms_versioning.admin import ExtendedIndicatorVersionAdminMixin + from djangocms_versioning.admin import ( + ExtendedIndicatorVersionAdminMixin, + ) except ImportError: - from djangocms_versioning.admin import ExtendedVersionAdminMixin as ExtendedIndicatorVersionAdminMixin + from djangocms_versioning.admin import ( + ExtendedVersionAdminMixin as ExtendedIndicatorVersionAdminMixin, + ) if djangocms_versioning_enabled: snippet_admin_classes.insert(0, ExtendedIndicatorVersionAdminMixin) @@ -38,23 +44,23 @@ class Media: js = ( "admin/vendor/ace/ace.js" if "djangocms_static_ace" in settings.INSTALLED_APPS - else "https://cdnjs.cloudflare.com/ajax/libs/ace/1.9.6/ace.js", + else "https://cdnjs.cloudflare.com/ajax/libs/ace/1.33.3/ace.js", ) list_display = ("name",) - search_fields: ClassVar[list[str]] = ['name'] + search_fields: ClassVar[list[str]] = ["name"] text_area_attrs: ClassVar[dict[str, Any]] = { - 'rows': 20, - 'data-editor': True, - 'data-mode': getattr(settings, 'DJANGOCMS_SNIPPET_THEME', 'html'), - 'data-theme': getattr(settings, 'DJANGOCMS_SNIPPET_MODE', 'github'), + "rows": 20, + "data-editor": True, + "data-mode": getattr(settings, "DJANGOCMS_SNIPPET_THEME", "html"), + "data-theme": getattr(settings, "DJANGOCMS_SNIPPET_MODE", "github"), } form = SnippetForm formfield_overrides: ClassVar[dict] = { - models.TextField: {'widget': Textarea(attrs=text_area_attrs)} + models.TextField: {"widget": Textarea(attrs=text_area_attrs)} } # This was move here from model, otherwise first() and last() return the same when handling grouper queries - ordering = ('name',) + ordering = ("name",) class Meta: model = Snippet @@ -71,7 +77,7 @@ def get_list_display(self, request): list_display = list(list_display) if not djangocms_versioning_enabled: - list_display.insert(0, 'slug') + list_display.insert(0, "slug") list_display = tuple(list_display) return list_display @@ -79,13 +85,13 @@ def get_list_display(self, request): def get_search_fields(self, request): search_fields = super().get_search_fields(request) if not djangocms_versioning_enabled: - search_fields.append('slug') + search_fields.append("slug") return search_fields def get_prepopulated_fields(self, obj, request): prepopulated_fields = super().get_prepopulated_fields(request) if not djangocms_versioning_enabled: - prepopulated_fields = {'slug': ('name',)} + prepopulated_fields = {"slug": ("name",)} return prepopulated_fields def get_list_display_links(self, request, list_display): @@ -95,16 +101,22 @@ def get_list_display_links(self, request, list_display): self.list_display_links = (None,) return self.list_display_links - def preview_view(self, request, snippet_id=None, form_url='', extra_context=None): + def preview_view( + self, request, snippet_id=None, form_url="", extra_context=None + ): """ Custom preview endpoint to display a change form in read only mode Solution based on django changeform view implementation https://github.com/django/django/blob/4b8e9492d9003ca357a4402f831112dd72efd2f8/django/contrib/admin/options.py#L1553 """ - to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) + to_field = request.POST.get( + TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR) + ) if to_field and not self.to_field_allowed(request, to_field): - raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field) + raise DisallowedModelAdminToField( + "The field %s cannot be referenced." % to_field + ) model = self.model opts = model._meta @@ -112,14 +124,18 @@ def preview_view(self, request, snippet_id=None, form_url='', extra_context=None obj = self.get_object(request, unquote(str(snippet_id)), to_field) if obj is None: - return self._get_obj_does_not_exist_redirect(request, opts, str(snippet_id)) + return self._get_obj_does_not_exist_redirect( + request, opts, str(snippet_id) + ) fieldsets = self.get_fieldsets(request, obj) model_form = self.get_form( request, obj, change=False, fields=flatten_fieldsets(fieldsets) ) form = model_form(instance=obj) - formsets, inline_instances = self._create_formsets(request, obj, change=True) + formsets, inline_instances = self._create_formsets( + request, obj, change=True + ) readonly_fields = flatten_fieldsets(fieldsets) @@ -129,40 +145,51 @@ def preview_view(self, request, snippet_id=None, form_url='', extra_context=None # Clear prepopulated fields on a view-only form to avoid a crash. {}, readonly_fields, - model_admin=self) + model_admin=self, + ) media = self.media + admin_form.media - inline_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj) + inline_formsets = self.get_inline_formsets( + request, formsets, inline_instances, obj + ) for inline_formset in inline_formsets: media = media + inline_formset.media - title = _('View %s') + title = _("View %s") context = { **self.admin_site.each_context(request), - 'title': title % opts.verbose_name, - 'subtitle': str(obj) if obj else None, - 'adminform': admin_form, - 'object_id': snippet_id, - 'original': obj, - 'is_popup': IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET, - 'to_field': to_field, - 'media': media, - 'inline_admin_formsets': inline_formsets, - 'errors': [], - 'preserved_filters': self.get_preserved_filters(request), + "title": title % opts.verbose_name, + "subtitle": str(obj) if obj else None, + "adminform": admin_form, + "object_id": snippet_id, + "original": obj, + "is_popup": IS_POPUP_VAR in request.POST + or IS_POPUP_VAR in request.GET, + "to_field": to_field, + "media": media, + "inline_admin_formsets": inline_formsets, + "errors": [], + "preserved_filters": self.get_preserved_filters(request), } context.update(extra_context or {}) - return self.render_change_form(request, context, add=False, change=False, obj=obj, form_url=form_url) + return self.render_change_form( + request, + context, + add=False, + change=False, + obj=obj, + form_url=form_url, + ) def get_urls(self): info = self.model._meta.app_label, self.model._meta.model_name return [ path( - "/preview/", - self.admin_site.admin_view(self.preview_view), - name="{}_{}_preview".format(*info), + "/preview/", + self.admin_site.admin_view(self.preview_view), + name="{}_{}_preview".format(*info), ), *super().get_urls(), ] @@ -175,6 +202,6 @@ def has_delete_permission(self, request, obj=None): """ if obj and not djangocms_versioning_enabled: return request.user.has_perm( - get_model_permission_codename(self.model, 'add'), + get_model_permission_codename(self.model, "add"), ) return False diff --git a/src/djangocms_snippet/cms_config.py b/src/djangocms_snippet/cms_config.py index e45cc725..adf7ec01 100644 --- a/src/djangocms_snippet/cms_config.py +++ b/src/djangocms_snippet/cms_config.py @@ -5,7 +5,7 @@ from djangocms_snippet.rendering import render_snippet try: - from djangocms_moderation import __version__ # NOQA + from djangocms_moderation import __version__ # NOQA: F401 djangocms_moderation_installed = True except ImportError: @@ -14,10 +14,10 @@ class SnippetCMSAppConfig(CMSAppConfig): djangocms_versioning_enabled = getattr( - settings, 'DJANGOCMS_SNIPPET_VERSIONING_ENABLED', True + settings, "DJANGOCMS_SNIPPET_VERSIONING_ENABLED", True ) djangocms_moderation_enabled = getattr( - settings, 'DJANGOCMS_SNIPPET_MODERATION_ENABLED', True + settings, "DJANGOCMS_SNIPPET_MODERATION_ENABLED", True ) cms_enabled = True diff --git a/src/djangocms_snippet/migrations/0015_alter_snippetgrouper_id.py b/src/djangocms_snippet/migrations/0015_alter_snippetgrouper_id.py new file mode 100644 index 00000000..10ad7f83 --- /dev/null +++ b/src/djangocms_snippet/migrations/0015_alter_snippetgrouper_id.py @@ -0,0 +1,12 @@ +# Generated by Django 5.0.6 on 2024-05-22 10:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("djangocms_snippet", "0014_merge_20240519_2117"), + ] + + operations = [ + ] diff --git a/src/djangocms_snippet/models.py b/src/djangocms_snippet/models.py index c0c34680..9b7a6762 100644 --- a/src/djangocms_snippet/models.py +++ b/src/djangocms_snippet/models.py @@ -11,8 +11,6 @@ SEARCH_ENABLED = getattr(settings, "DJANGOCMS_SNIPPET_SEARCH", False) - - class AdminQuerySet(models.QuerySet): def current_content(self, **kwargs): """If a versioning package is installed, this returns the currently valid content @@ -31,22 +29,26 @@ class SnippetGrouper(models.Model): """ The Grouper model for snippet, this is required for versioning """ + def __str__(self): return self.name @property def name(self): - snippet_qs = Snippet.admin_manager.filter( - snippet_grouper=self - ) + snippet_qs = Snippet.admin_manager.filter(snippet_grouper=self) return snippet_qs.first().name or super().__str__ - def snippet(self, show_editable=False): + def snippet(self, show_editable=False): # NOQA: FBT002 if show_editable: # When in "edit" or "preview" mode we should be able to see the latest content - return Snippet.admin_manager.current_content().filter( - snippet_grouper=self, - ).order_by("-pk").first() + return ( + Snippet.admin_manager.current_content() + .filter( + snippet_grouper=self, + ) + .order_by("-pk") + .first() + ) # When in "live" mode we should only be able to see the default published version return Snippet.objects.filter(snippet_grouper=self).first() @@ -58,7 +60,7 @@ class Snippet(models.Model): """ name = models.CharField( - verbose_name=_('Name'), + verbose_name=_("Name"), max_length=255, ) snippet_grouper = models.ForeignKey( @@ -87,7 +89,9 @@ class Snippet(models.Model): default="", max_length=255, ) - site = models.ForeignKey(Site, on_delete=models.CASCADE, null=True, blank=True) + site = models.ForeignKey( + Site, on_delete=models.CASCADE, null=True, blank=True + ) objects = models.Manager() admin_manager = AdminQuerySet.as_manager() @@ -127,12 +131,14 @@ class SnippetPtr(CMSPlugin): search_fields = ["snippet__html"] if SEARCH_ENABLED else [] def get_short_description(self): - snippet_label = SnippetGrouper.objects.filter(pk=self.snippet_grouper.pk).first() + snippet_label = SnippetGrouper.objects.filter( + pk=self.snippet_grouper.pk + ).first() return snippet_label class Meta: - verbose_name = _('Snippet Ptr') - verbose_name_plural = _('Snippet Ptrs') + verbose_name = _("Snippet Ptr") + verbose_name_plural = _("Snippet Ptrs") def __str__(self): # Return the referenced snippet's name rather than the default (ID #) diff --git a/src/djangocms_snippet/settings.py b/src/djangocms_snippet/settings.py index c5ec3774..4eb1dba4 100644 --- a/src/djangocms_snippet/settings.py +++ b/src/djangocms_snippet/settings.py @@ -1,32 +1,33 @@ #!/usr/bin/env python HELPER_SETTINGS = { - 'SECRET_KEY': "djangocmssnippetstestsuitekey", - 'INSTALLED_APPS': [ - 'tests.utils', - 'djangocms_versioning', - 'djangocms_snippet', + "SECRET_KEY": "djangocmssnippetstestsuitekey", + "INSTALLED_APPS": [ + "tests.utils", + "djangocms_versioning", + "djangocms_snippet", ], - 'CMS_LANGUAGES': { - 1: [{ - 'code': 'en', - 'name': 'English', - }] + "CMS_LANGUAGES": { + 1: [ + { + "code": "en", + "name": "English", + } + ] }, - 'LANGUAGE_CODE': 'en', - 'ALLOWED_HOSTS': ['localhost'], - 'DJANGOCMS_SNIPPET_VERSIONING_ENABLED': True, - 'DJANGOCMS_SNIPPET_MODERATION_ENABLED': True, - 'CMS_TEMPLATES': ( - ("page.html", "Normal page"), - ), + "LANGUAGE_CODE": "en", + "ALLOWED_HOSTS": ["localhost"], + "DJANGOCMS_SNIPPET_VERSIONING_ENABLED": True, + "DJANGOCMS_SNIPPET_MODERATION_ENABLED": True, + "CMS_TEMPLATES": (("page.html", "Normal page"),), "DEFAULT_AUTO_FIELD": "django.db.models.AutoField", } def run(): from app_helper import runner - runner.cms('djangocms_snippet') + runner.cms("djangocms_snippet") -if __name__ == '__main__': + +if __name__ == "__main__": run() diff --git a/src/djangocms_snippet/utils.py b/src/djangocms_snippet/utils.py index e1af8434..0588e7d2 100644 --- a/src/djangocms_snippet/utils.py +++ b/src/djangocms_snippet/utils.py @@ -2,13 +2,14 @@ from django.conf import settings try: - import djangocms_versioning + import djangocms_versioning # NOQA: F401 + is_versioning_installed = True except ImportError: is_versioning_installed = False djangocms_versioning_enabled = is_versioning_installed and getattr( - settings, 'DJANGOCMS_SNIPPET_VERSIONING_ENABLED', True + settings, "DJANGOCMS_SNIPPET_VERSIONING_ENABLED", True ) @@ -19,4 +20,6 @@ def show_draft_content(request=None): if not request: return False request_toolbar = get_toolbar_from_request(request) - return request_toolbar.edit_mode_active or getattr(request_toolbar, "preview_mode_active", True) + return request_toolbar.edit_mode_active or getattr( + request_toolbar, "preview_mode_active", True + )