List\xa0All\xa0\xa0| \xa0On\xa0Mailing\xa0Lists\xa0|\xa0On\xa0Meetings\xa0|\xa0On\xa0Procedures\xa0|\xa0On\xa0Technical\xa0Issues
' - iesg_page.save_revision(user=User.objects.get(username='robert.sparks')).publish() + iesg_page.key_info[6].value.source = ( + 'List\xa0All\xa0\xa0| \xa0On\xa0Mailing\xa0Lists\xa0|\xa0On\xa0Meetings\xa0|\xa0On\xa0Procedures\xa0|\xa0On\xa0Technical\xa0Issues
' + ) + iesg_page.save_revision( + user=User.objects.get(username="robert.sparks") + ).publish() diff --git a/ietf/iesg_statement/migrations/0001_initial.py b/ietf/iesg_statement/migrations/0001_initial.py index 3bb27277..677e999b 100644 --- a/ietf/iesg_statement/migrations/0001_initial.py +++ b/ietf/iesg_statement/migrations/0001_initial.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-04-10 18:46 -from __future__ import unicode_literals import django.db.models.deletion import modelcluster.fields diff --git a/ietf/iesg_statement/migrations/0008_alter_iesgstatementpage_body.py b/ietf/iesg_statement/migrations/0008_alter_iesgstatementpage_body.py index c6190cee..58f89e90 100644 --- a/ietf/iesg_statement/migrations/0008_alter_iesgstatementpage_body.py +++ b/ietf/iesg_statement/migrations/0008_alter_iesgstatementpage_body.py @@ -1,6 +1,5 @@ # Generated by Django 4.2.7 on 2024-04-03 13:40 -from django.db import migrations import wagtail.blocks import wagtail.contrib.table_block.blocks import wagtail.contrib.typed_table_block.blocks @@ -8,18 +7,72 @@ import wagtail.fields import wagtail.images.blocks import wagtailmarkdown.blocks +from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('iesg_statement', '0007_alter_iesgstatementpage_body'), + ("iesg_statement", "0007_alter_iesgstatementpage_body"), ] operations = [ migrations.AlterField( - model_name='iesgstatementpage', - name='body', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], use_json_field=True), + model_name="iesgstatementpage", + name="body", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + use_json_field=True, + ), ), ] diff --git a/ietf/iesg_statement/models.py b/ietf/iesg_statement/models.py index 831e3bc8..7855493d 100644 --- a/ietf/iesg_statement/models.py +++ b/ietf/iesg_statement/models.py @@ -18,7 +18,6 @@ from ..bibliography.models import BibliographyMixin from ..snippets.models import Topic from ..utils.blocks import StandardBlock - from ..utils.models import PromoteMixin @@ -159,7 +158,7 @@ def siblings(self): ) def get_context(self, request, *args, **kwargs): - context = super(IESGStatementPage, self).get_context(request, *args, **kwargs) + context = super().get_context(request, *args, **kwargs) siblings = self.siblings query_string = "?" filter_text_builder = build_filter_text @@ -170,7 +169,7 @@ def get_context(self, request, *args, **kwargs): try: related_object = functions[0](search_query) siblings = functions[1](siblings, related_object) - query_string += "%s=%s&" % (parameter, search_query) + query_string += f"{parameter}={search_query}&" filter_text_builder = partial( filter_text_builder, **{parameter: related_object.__str__()} ) @@ -258,7 +257,7 @@ def redirect_first(self, request, *args, **kwargs): try: related_object = functions[0](search_query) statements = functions[1](statements, related_object) - query_string += "%s=%s&" % (parameter, search_query) + query_string += f"{parameter}={search_query}&" except (ValueError, ObjectDoesNotExist): pass if statements: diff --git a/ietf/iesg_statement/tests.py b/ietf/iesg_statement/tests.py index 9ca417db..56569884 100644 --- a/ietf/iesg_statement/tests.py +++ b/ietf/iesg_statement/tests.py @@ -1,12 +1,12 @@ from datetime import timedelta -import factory import pytest from bs4 import BeautifulSoup from django.test import Client from django.utils import timezone from ietf.home.models import HomePage + from .factories import IESGStatementIndexPageFactory, IESGStatementPageFactory from .models import IESGStatementIndexPage, IESGStatementPage diff --git a/ietf/images/migrations/0001_initial.py b/ietf/images/migrations/0001_initial.py index d5dffcf0..2d4fdf2b 100644 --- a/ietf/images/migrations/0001_initial.py +++ b/ietf/images/migrations/0001_initial.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-04-10 18:46 -from __future__ import unicode_literals import django.db.models.deletion import taggit.managers diff --git a/ietf/images/migrations/0002_alter_ietfimage_file_hash.py b/ietf/images/migrations/0002_alter_ietfimage_file_hash.py index cd64bf42..20df0236 100644 --- a/ietf/images/migrations/0002_alter_ietfimage_file_hash.py +++ b/ietf/images/migrations/0002_alter_ietfimage_file_hash.py @@ -6,13 +6,15 @@ class Migration(migrations.Migration): dependencies = [ - ('images', '0001_initial'), + ("images", "0001_initial"), ] operations = [ migrations.AlterField( - model_name='ietfimage', - name='file_hash', - field=models.CharField(blank=True, db_index=True, editable=False, max_length=40), + model_name="ietfimage", + name="file_hash", + field=models.CharField( + blank=True, db_index=True, editable=False, max_length=40 + ), ), ] diff --git a/ietf/images/migrations/0003_wagtail_42_wagtailimagefield.py b/ietf/images/migrations/0003_wagtail_42_wagtailimagefield.py index 5844449f..5ecdf480 100644 --- a/ietf/images/migrations/0003_wagtail_42_wagtailimagefield.py +++ b/ietf/images/migrations/0003_wagtail_42_wagtailimagefield.py @@ -1,24 +1,33 @@ # Generated by Django 4.0.10 on 2023-11-29 10:19 -from django.db import migrations import wagtail.images.models +from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('images', '0002_alter_ietfimage_file_hash'), + ("images", "0002_alter_ietfimage_file_hash"), ] operations = [ migrations.AlterField( - model_name='ietfimage', - name='file', - field=wagtail.images.models.WagtailImageField(height_field='height', upload_to=wagtail.images.models.get_upload_to, verbose_name='file', width_field='width'), + model_name="ietfimage", + name="file", + field=wagtail.images.models.WagtailImageField( + height_field="height", + upload_to=wagtail.images.models.get_upload_to, + verbose_name="file", + width_field="width", + ), ), migrations.AlterField( - model_name='ietfrendition', - name='file', - field=wagtail.images.models.WagtailImageField(height_field='height', upload_to=wagtail.images.models.get_rendition_upload_to, width_field='width'), + model_name="ietfrendition", + name="file", + field=wagtail.images.models.WagtailImageField( + height_field="height", + upload_to=wagtail.images.models.get_rendition_upload_to, + width_field="width", + ), ), ] diff --git a/ietf/images/migrations/0004_django_42_rendition_storage.py b/ietf/images/migrations/0004_django_42_rendition_storage.py index e5348115..4772265b 100644 --- a/ietf/images/migrations/0004_django_42_rendition_storage.py +++ b/ietf/images/migrations/0004_django_42_rendition_storage.py @@ -1,19 +1,24 @@ # Generated by Django 4.2.7 on 2023-11-29 12:17 -from django.db import migrations import wagtail.images.models +from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('images', '0003_wagtail_42_wagtailimagefield'), + ("images", "0003_wagtail_42_wagtailimagefield"), ] operations = [ migrations.AlterField( - model_name='ietfrendition', - name='file', - field=wagtail.images.models.WagtailImageField(height_field='height', storage=wagtail.images.models.get_rendition_storage, upload_to=wagtail.images.models.get_rendition_upload_to, width_field='width'), + model_name="ietfrendition", + name="file", + field=wagtail.images.models.WagtailImageField( + height_field="height", + storage=wagtail.images.models.get_rendition_storage, + upload_to=wagtail.images.models.get_rendition_upload_to, + width_field="width", + ), ), ] diff --git a/ietf/images/models.py b/ietf/images/models.py index 062aa9da..a07564c9 100644 --- a/ietf/images/models.py +++ b/ietf/images/models.py @@ -1,20 +1,17 @@ from django.db import models - -from wagtail.images.models import Image, AbstractImage, AbstractRendition +from wagtail.images.models import AbstractImage, AbstractRendition, Image class IETFImage(AbstractImage): caption = models.CharField(max_length=255, null=True, blank=True) - admin_form_fields = Image.admin_form_fields + ( - 'caption', - ) + admin_form_fields = Image.admin_form_fields + ("caption",) class IETFRendition(AbstractRendition): - image = models.ForeignKey(IETFImage, related_name='renditions', on_delete=models.CASCADE) + image = models.ForeignKey( + IETFImage, related_name="renditions", on_delete=models.CASCADE + ) class Meta: - unique_together = ( - ('image', 'filter_spec', 'focal_point_key'), - ) + unique_together = (("image", "filter_spec", "focal_point_key"),) diff --git a/ietf/search/tests.py b/ietf/search/tests.py index 592ef6d2..f60f52b5 100644 --- a/ietf/search/tests.py +++ b/ietf/search/tests.py @@ -27,8 +27,9 @@ def test_search(self): assert resp.status_code == 200 assert resp.context["search_query"] == query - assert list(resp.context["search_results"]) == \ - [Page.objects.get(pk=self.standard_page.pk)] + assert list(resp.context["search_results"]) == [ + Page.objects.get(pk=self.standard_page.pk) + ] def test_empty_query(self): resp = self.client.get(f"{reverse('search')}?query=") @@ -38,12 +39,14 @@ def test_empty_page(self): query = "random" resp = self.client.get(f"{reverse('search')}?query={query}&page=100") assert resp.status_code == 200 - assert list(resp.context["search_results"]) == \ - [Page.objects.get(pk=self.standard_page.pk)] + assert list(resp.context["search_results"]) == [ + Page.objects.get(pk=self.standard_page.pk) + ] def test_non_integer_page(self): query = "random" resp = self.client.get(f"{reverse('search')}?query={query}&page=foo") assert resp.status_code == 200 - assert list(resp.context["search_results"]) == \ - [Page.objects.get(pk=self.standard_page.pk)] + assert list(resp.context["search_results"]) == [ + Page.objects.get(pk=self.standard_page.pk) + ] diff --git a/ietf/search/views.py b/ietf/search/views.py index 448951fd..a7614460 100644 --- a/ietf/search/views.py +++ b/ietf/search/views.py @@ -1,7 +1,7 @@ from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.shortcuts import render -from wagtail.models import Page from wagtail.contrib.search_promotions.models import Query +from wagtail.models import Page def search(request): diff --git a/ietf/settings/base.py b/ietf/settings/base.py index 9115f39a..e7c2acd4 100644 --- a/ietf/settings/base.py +++ b/ietf/settings/base.py @@ -13,8 +13,6 @@ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os -from django.conf import global_settings - PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(PROJECT_DIR) @@ -246,7 +244,7 @@ _cf_purge_bearer_token = os.environ.get("CLOUDFLARE_CACHE_PURGE_BEARER_TOKEN") _cf_purge_zone_id = os.environ.get("CLOUDFLARE_CACHE_PURGE_ZONE_ID") if _cf_purge_bearer_token and _cf_purge_zone_id: # pragma: no cover - INSTALLED_APPS += ( "wagtail.contrib.frontend_cache", ) + INSTALLED_APPS += ("wagtail.contrib.frontend_cache",) WAGTAILFRONTENDCACHE = { "cloudflare": { "BACKEND": "wagtail.contrib.frontend_cache.backends.CloudflareBackend", diff --git a/ietf/settings/dev.py b/ietf/settings/dev.py index 848a5481..b593a467 100644 --- a/ietf/settings/dev.py +++ b/ietf/settings/dev.py @@ -1,14 +1,15 @@ -from .base import * +import contextlib +from .base import * # noqa: F403 # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'CHANGEME!!!' +SECRET_KEY = "CHANGEME!!!" -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" # Process all tasks synchronously. @@ -16,7 +17,5 @@ CELERY_EAGER_PROPAGATES_EXCEPTIONS = True CELERY_ALWAYS_EAGER = True -try: # pragma: no cover - from .local import * -except ImportError: # pragma: no cover - pass +with contextlib.suppress(ImportError): + from .local import * # noqa: F403 diff --git a/ietf/settings/docker/__init__.py b/ietf/settings/docker/__init__.py index 3b2a403a..4e665532 100644 --- a/ietf/settings/docker/__init__.py +++ b/ietf/settings/docker/__init__.py @@ -1,10 +1,11 @@ from typed_environment_configuration import ( BoolVariable, - StringVariable, - StringListVariable, FillVars, + StringListVariable, + StringVariable, ) -from ..base import * + +from ..base import * # noqa: F403 _ENVVARS = [ StringVariable( @@ -30,4 +31,4 @@ FillVars(_ENVVARS, vars()) FillVars(_DJANGO_ENVVARS, vars(), "DJANGO_") -ALLOWED_HOSTS = ADDRESSES +ALLOWED_HOSTS = ADDRESSES # noqa: F405 diff --git a/ietf/settings/docker/base.py b/ietf/settings/docker/base.py index d764d0bf..9cde3a0b 100644 --- a/ietf/settings/docker/base.py +++ b/ietf/settings/docker/base.py @@ -1,4 +1,3 @@ -from . import * - -from .grains.database import * -from .grains.logging import * +from . import * # noqa: F403 +from .grains.database import * # noqa: F403 +from .grains.logging import * # noqa: F403 diff --git a/ietf/settings/docker/dev.py b/ietf/settings/docker/dev.py index 99684588..8923e8be 100644 --- a/ietf/settings/docker/dev.py +++ b/ietf/settings/docker/dev.py @@ -1,4 +1,4 @@ -from .base import * +from .base import * # noqa: F403 DEBUG = True CACHE_MIDDLEWARE_ALIAS = "dummy" diff --git a/ietf/settings/production.py b/ietf/settings/production.py index ca495e2d..84ff4736 100644 --- a/ietf/settings/production.py +++ b/ietf/settings/production.py @@ -1,7 +1,7 @@ +import contextlib import os -import sys -from .base import * +from .base import * # noqa: F403 # Do not set SECRET_KEY, Postgres or LDAP password or any other sensitive data here. # Instead, create a local.py file on the server. @@ -17,58 +17,57 @@ # On Torchbox servers, many environment variables are prefixed with "CFG_" for key, value in os.environ.items(): - if key.startswith('CFG_'): + if key.startswith("CFG_"): env[key[4:]] = value # Basic configuration -APP_NAME = env.get('APP_NAME', 'ietf') +APP_NAME = env.get("APP_NAME", "ietf") -if 'SECRET_KEY' in env: - SECRET_KEY = env['SECRET_KEY'] +if "SECRET_KEY" in env: + SECRET_KEY = env["SECRET_KEY"] -if 'ALLOWED_HOSTS' in env: - ALLOWED_HOSTS = env['ALLOWED_HOSTS'].split(',') +if "ALLOWED_HOSTS" in env: + ALLOWED_HOSTS = env["ALLOWED_HOSTS"].split(",") -if 'CSRF_TRUSTED_ORIGINS' in env: - CSRF_TRUSTED_ORIGINS = env['CSRF_TRUSTED_ORIGINS'].split(',') +if "CSRF_TRUSTED_ORIGINS" in env: + CSRF_TRUSTED_ORIGINS = env["CSRF_TRUSTED_ORIGINS"].split(",") -if 'PRIMARY_HOST' in env: - WAGTAILADMIN_BASE_URL = 'http://%s/' % env['PRIMARY_HOST'] +if "PRIMARY_HOST" in env: + WAGTAILADMIN_BASE_URL = "http://{}/".format(env["PRIMARY_HOST"]) -if 'SERVER_EMAIL' in env: - SERVER_EMAIL = env['SERVER_EMAIL'] +if "SERVER_EMAIL" in env: + SERVER_EMAIL = env["SERVER_EMAIL"] -if 'CACHE_PURGE_URL' in env: - INSTALLED_APPS += ( 'wagtail.contrib.frontend_cache', ) +if "CACHE_PURGE_URL" in env: + INSTALLED_APPS += ("wagtail.contrib.frontend_cache",) # noqa: F405 WAGTAILFRONTENDCACHE = { - 'default': { - 'BACKEND': 'wagtail.contrib.frontend_cache.backends.HTTPBackend', - 'LOCATION': env['CACHE_PURGE_URL'], + "default": { + "BACKEND": "wagtail.contrib.frontend_cache.backends.HTTPBackend", + "LOCATION": env["CACHE_PURGE_URL"], }, } -if 'STATIC_URL' in env: - STATIC_URL = env['STATIC_URL'] +if "STATIC_URL" in env: + STATIC_URL = env["STATIC_URL"] -if 'STATIC_DIR' in env: - STATIC_ROOT = env['STATIC_DIR'] +if "STATIC_DIR" in env: + STATIC_ROOT = env["STATIC_DIR"] -if 'MEDIA_URL' in env: - MEDIA_URL = env['MEDIA_URL'] +if "MEDIA_URL" in env: + MEDIA_URL = env["MEDIA_URL"] -if 'MEDIA_DIR' in env: - MEDIA_ROOT = env['MEDIA_DIR'] +if "MEDIA_DIR" in env: + MEDIA_ROOT = env["MEDIA_DIR"] # Database DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': env.get('PGDATABASE', APP_NAME), - 'CONN_MAX_AGE': 600, # number of seconds database connections should persist for - + "default": { + "ENGINE": "django.db.backends.postgresql_psycopg2", + "NAME": env.get("PGDATABASE", APP_NAME), + "CONN_MAX_AGE": 600, # number of seconds database connections should persist for # User, host and port can be configured by the PGUSER, PGHOST and # PGPORT environment variables (these get picked up by libpq). } @@ -76,52 +75,50 @@ # Caches -if 'CACHE_DEFAULT' in env: - CACHES['default']['LOCATION'] = env.get('CACHE_DEFAULT') +if "CACHE_DEFAULT" in env: + CACHES["default"]["LOCATION"] = env.get("CACHE_DEFAULT") # noqa: F405 -if 'CACHE_SESSIONS' in env: - CACHES['sessions']['LOCATION'] = env.get('CACHE_SESSIONS') +if "CACHE_SESSIONS" in env: + CACHES["sessions"]["LOCATION"] = env.get("CACHE_SESSIONS") # noqa: F405 # Logging LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - 'mail_admins': { - 'level': 'ERROR', - 'class': 'django.utils.log.AdminEmailHandler', + "version": 1, + "disable_existing_loggers": False, + "handlers": { + "mail_admins": { + "level": "ERROR", + "class": "django.utils.log.AdminEmailHandler", }, }, - 'loggers': { - 'django.request': { - 'handlers': ['mail_admins'], - 'level': 'ERROR', - 'propagate': False, + "loggers": { + "django.request": { + "handlers": ["mail_admins"], + "level": "ERROR", + "propagate": False, }, - 'django.security': { - 'handlers': ['mail_admins'], - 'level': 'ERROR', - 'propagate': False, + "django.security": { + "handlers": ["mail_admins"], + "level": "ERROR", + "propagate": False, }, }, } # Log errors to file -if 'ERROR_LOG' in env: - LOGGING['handlers']['errors_file'] = { - 'level': 'ERROR', - 'class': 'logging.handlers.RotatingFileHandler', - 'filename': env['ERROR_LOG'], - 'maxBytes': 5242880, # 5MB - 'backupCount': 5 +if "ERROR_LOG" in env: + LOGGING["handlers"]["errors_file"] = { + "level": "ERROR", + "class": "logging.handlers.RotatingFileHandler", + "filename": env["ERROR_LOG"], + "maxBytes": 5242880, # 5MB + "backupCount": 5, } - LOGGING['loggers']['django.request']['handlers'].append('errors_file') - LOGGING['loggers']['django.security']['handlers'].append('errors_file') + LOGGING["loggers"]["django.request"]["handlers"].append("errors_file") + LOGGING["loggers"]["django.security"]["handlers"].append("errors_file") -try: - from .local import * # pyflakes:ignore -except ImportError: - pass +with contextlib.suppress(ImportError): + from .local import * # noqa: F403 diff --git a/ietf/snippets/migrations/0001_initial.py b/ietf/snippets/migrations/0001_initial.py index a5a4beb5..1b8f72bd 100644 --- a/ietf/snippets/migrations/0001_initial.py +++ b/ietf/snippets/migrations/0001_initial.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-04-10 18:46 -from __future__ import unicode_literals import django.db.models.deletion import wagtail.fields diff --git a/ietf/snippets/migrations/0002_auto_20200414_2027.py b/ietf/snippets/migrations/0002_auto_20200414_2027.py index f4cc307a..cc9c8f6a 100644 --- a/ietf/snippets/migrations/0002_auto_20200414_2027.py +++ b/ietf/snippets/migrations/0002_auto_20200414_2027.py @@ -1,31 +1,50 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-04-14 20:27 -from __future__ import unicode_literals -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('snippets', '0001_initial'), + ("snippets", "0001_initial"), ] operations = [ migrations.AlterField( - model_name='group', - name='image', - field=models.ForeignKey(blank=True, help_text='An image to represent this group.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.IETFImage'), + model_name="group", + name="image", + field=models.ForeignKey( + blank=True, + help_text="An image to represent this group.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="images.IETFImage", + ), ), migrations.AlterField( - model_name='group', - name='role', - field=models.ForeignKey(blank=True, help_text="This group's role within the IETF.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='snippets.Role'), + model_name="group", + name="role", + field=models.ForeignKey( + blank=True, + help_text="This group's role within the IETF.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="snippets.Role", + ), ), migrations.AlterField( - model_name='rfc', - name='working_group', - field=models.ForeignKey(blank=True, help_text='The working group that produced this RFC', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='snippets.WorkingGroup'), + model_name="rfc", + name="working_group", + field=models.ForeignKey( + blank=True, + help_text="The working group that produced this RFC", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="snippets.WorkingGroup", + ), ), ] diff --git a/ietf/snippets/migrations/0003_alter_workinggroup_list_subscribe.py b/ietf/snippets/migrations/0003_alter_workinggroup_list_subscribe.py index 8fe4e083..3ea9c610 100644 --- a/ietf/snippets/migrations/0003_alter_workinggroup_list_subscribe.py +++ b/ietf/snippets/migrations/0003_alter_workinggroup_list_subscribe.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('snippets', '0002_auto_20200414_2027'), + ("snippets", "0002_auto_20200414_2027"), ] operations = [ migrations.AlterField( - model_name='workinggroup', - name='list_subscribe', + model_name="workinggroup", + name="list_subscribe", field=models.URLField(blank=True), ), ] diff --git a/ietf/snippets/migrations/0003_person_slug.py b/ietf/snippets/migrations/0003_person_slug.py index 2185cee4..076bbf5c 100644 --- a/ietf/snippets/migrations/0003_person_slug.py +++ b/ietf/snippets/migrations/0003_person_slug.py @@ -14,14 +14,14 @@ def generate_person_slugs(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('snippets', '0002_auto_20200414_2027'), + ("snippets", "0002_auto_20200414_2027"), ] operations = [ migrations.AddField( - model_name='person', - name='slug', - field=models.SlugField(default='', max_length=511), + model_name="person", + name="slug", + field=models.SlugField(default="", max_length=511), preserve_default=False, ), migrations.RunPython(generate_person_slugs, migrations.RunPython.noop), diff --git a/ietf/snippets/migrations/0004_merge_20231215_0352.py b/ietf/snippets/migrations/0004_merge_20231215_0352.py index 4c423377..e7c180df 100644 --- a/ietf/snippets/migrations/0004_merge_20231215_0352.py +++ b/ietf/snippets/migrations/0004_merge_20231215_0352.py @@ -6,14 +6,14 @@ class Migration(migrations.Migration): dependencies = [ - ('snippets', '0003_alter_workinggroup_list_subscribe'), - ('snippets', '0003_person_slug'), + ("snippets", "0003_alter_workinggroup_list_subscribe"), + ("snippets", "0003_person_slug"), ] operations = [ migrations.AlterField( - model_name='person', - name='slug', + model_name="person", + name="slug", field=models.SlugField(max_length=511, unique=True), ), ] diff --git a/ietf/snippets/models.py b/ietf/snippets/models.py index 8114bfe8..3bacf85e 100644 --- a/ietf/snippets/models.py +++ b/ietf/snippets/models.py @@ -119,7 +119,7 @@ class RFC(models.Model, index.Indexed): ] def __str__(self): # pragma: no cover - return "RFC {}".format(self.rfc) + return f"RFC {self.rfc}" @property def long_title(self): @@ -323,13 +323,10 @@ class MailingListSignup(models.Model, Indexed, RenderableSnippetMixin): @property def link(self): - if self.sign_up: - link = self.sign_up - else: - link = self.working_group.list_subscribe + link = self.sign_up if self.sign_up else self.working_group.list_subscribe if "@" in link: - return "mailto:{}".format(link) + return f"mailto:{link}" else: return link @@ -430,7 +427,7 @@ def __str__(self): # pragma: no cover def url(self): from ietf.glossary.models import GlossaryPage - return "{}?query={}".format(GlossaryPage.objects.first().url, self.title) + return f"{GlossaryPage.objects.first().url}?query={self.title}" class Meta: ordering = ["title"] diff --git a/ietf/snippets/tests/test_charter.py b/ietf/snippets/tests/test_charter.py index 1a73e277..8e59aad2 100644 --- a/ietf/snippets/tests/test_charter.py +++ b/ietf/snippets/tests/test_charter.py @@ -1,4 +1,5 @@ import pytest + from ietf.snippets.factories import CharterFactory, WorkingGroupFactory pytestmark = pytest.mark.django_db diff --git a/ietf/snippets/tests/test_mailing_list_signup.py b/ietf/snippets/tests/test_mailing_list_signup.py index 27cf1f56..8f615e98 100644 --- a/ietf/snippets/tests/test_mailing_list_signup.py +++ b/ietf/snippets/tests/test_mailing_list_signup.py @@ -1,11 +1,11 @@ -from bs4 import BeautifulSoup -from django.urls import reverse import pytest +from bs4 import BeautifulSoup from django.test import Client +from django.urls import reverse from ietf.home.models import HomePage -from ietf.standard.factories import StandardPageFactory from ietf.snippets.factories import MailingListSignupFactory, WorkingGroupFactory +from ietf.standard.factories import StandardPageFactory pytestmark = pytest.mark.django_db diff --git a/ietf/snippets/urls.py b/ietf/snippets/urls.py index 1e2d4824..c7bd7565 100644 --- a/ietf/snippets/urls.py +++ b/ietf/snippets/urls.py @@ -2,7 +2,6 @@ from .views import disclaimer - urlpatterns = [ - re_path(r'^disclaimer/(\d+)/$', disclaimer, name='disclaimer'), - ] + re_path(r"^disclaimer/(\d+)/$", disclaimer, name="disclaimer"), +] diff --git a/ietf/snippets/views.py b/ietf/snippets/views.py index 1adc2d07..a3b9bc66 100644 --- a/ietf/snippets/views.py +++ b/ietf/snippets/views.py @@ -1,5 +1,5 @@ -from django.shortcuts import get_object_or_404, render from django.conf import settings +from django.shortcuts import get_object_or_404, render from .models import MailingListSignup diff --git a/ietf/standard/migrations/0001_initial.py b/ietf/standard/migrations/0001_initial.py index d276a7ee..31e7eed2 100644 --- a/ietf/standard/migrations/0001_initial.py +++ b/ietf/standard/migrations/0001_initial.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-04-10 18:46 -from __future__ import unicode_literals import django.db.models.deletion import modelcluster.fields diff --git a/ietf/standard/migrations/0004_auto_20220902_0524.py b/ietf/standard/migrations/0004_auto_20220902_0524.py index bfc31686..d913adc8 100644 --- a/ietf/standard/migrations/0004_auto_20220902_0524.py +++ b/ietf/standard/migrations/0004_auto_20220902_0524.py @@ -1,39 +1,131 @@ # Generated by Django 3.2.13 on 2022-09-02 04:24 -from django.db import migrations import wagtail.blocks import wagtail.contrib.table_block.blocks import wagtail.embeds.blocks import wagtail.fields import wagtail.images.blocks import wagtailmarkdown.blocks +from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('standard', '0003_auto_20211101_0113'), + ("standard", "0003_auto_20211101_0113"), ] operations = [ migrations.AlterField( - model_name='standardindexpage', - name='in_depth', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True, use_json_field=True), + model_name="standardindexpage", + name="in_depth", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='standardindexpage', - name='key_info', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True, use_json_field=True), + model_name="standardindexpage", + name="key_info", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='standardpage', - name='in_depth', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True, use_json_field=True), + model_name="standardpage", + name="in_depth", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='standardpage', - name='key_info', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True, use_json_field=True), + model_name="standardpage", + name="key_info", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ], + blank=True, + use_json_field=True, + ), ), ] diff --git a/ietf/standard/migrations/0005_iabstandardpage.py b/ietf/standard/migrations/0005_iabstandardpage.py index ea8719c9..87eefe8d 100644 --- a/ietf/standard/migrations/0005_iabstandardpage.py +++ b/ietf/standard/migrations/0005_iabstandardpage.py @@ -1,6 +1,5 @@ # Generated by Django 3.2.13 on 2023-02-27 20:53 -from django.db import migrations, models import django.db.models.deletion import wagtail.blocks import wagtail.contrib.table_block.blocks @@ -8,36 +7,178 @@ import wagtail.fields import wagtail.images.blocks import wagtailmarkdown.blocks +from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('snippets', '0002_auto_20200414_2027'), - ('wagtailcore', '0078_referenceindex'), - ('images', '0002_alter_ietfimage_file_hash'), - ('standard', '0004_auto_20220902_0524'), + ("snippets", "0002_auto_20200414_2027"), + ("wagtailcore", "0078_referenceindex"), + ("images", "0002_alter_ietfimage_file_hash"), + ("standard", "0004_auto_20220902_0524"), ] operations = [ migrations.CreateModel( - name='IABStandardPage', + name="IABStandardPage", fields=[ - ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')), - ('social_text', models.CharField(blank=True, help_text='Description of this page as it should appear when shared on social networks, or in Google results', max_length=255)), - ('introduction', models.CharField(blank=True, help_text='Enter the title to display on the page, you can use only 255 characters.', max_length=255)), - ('key_info', wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True, use_json_field=True)), - ('in_depth', wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True, use_json_field=True)), - ('prepared_key_info', models.TextField(blank=True, help_text='The prepared key info field after bibliography styling has been applied. Auto-generated on each save.', null=True)), - ('prepared_in_depth', models.TextField(blank=True, help_text='The prepared in depth field after bibliography styling has been applied. Auto-generated on each save.', null=True)), - ('call_to_action', models.ForeignKey(blank=True, help_text='Specify the page you would like visitors to go to next.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='snippets.calltoaction')), - ('feed_image', models.ForeignKey(blank=True, help_text='This image will be used in listings and indexes across the site, if no feed image is added, the social image will be used.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.ietfimage')), - ('mailing_list_signup', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='snippets.mailinglistsignup')), - ('social_image', models.ForeignKey(blank=True, help_text="Image to appear alongside 'social text', particularly for sharing on social networks", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.ietfimage')), + ( + "page_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="wagtailcore.page", + ), + ), + ( + "social_text", + models.CharField( + blank=True, + help_text="Description of this page as it should appear when shared on social networks, or in Google results", + max_length=255, + ), + ), + ( + "introduction", + models.CharField( + blank=True, + help_text="Enter the title to display on the page, you can use only 255 characters.", + max_length=255, + ), + ), + ( + "key_info", + wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ( + "markdown", + wagtailmarkdown.blocks.MarkdownBlock(icon="code"), + ), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ( + "raw_html", + wagtail.blocks.RawHTMLBlock(icon="placeholder"), + ), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + ( + "in_depth", + wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ( + "markdown", + wagtailmarkdown.blocks.MarkdownBlock(icon="code"), + ), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ( + "raw_html", + wagtail.blocks.RawHTMLBlock(icon="placeholder"), + ), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + ( + "prepared_key_info", + models.TextField( + blank=True, + help_text="The prepared key info field after bibliography styling has been applied. Auto-generated on each save.", + null=True, + ), + ), + ( + "prepared_in_depth", + models.TextField( + blank=True, + help_text="The prepared in depth field after bibliography styling has been applied. Auto-generated on each save.", + null=True, + ), + ), + ( + "call_to_action", + models.ForeignKey( + blank=True, + help_text="Specify the page you would like visitors to go to next.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="snippets.calltoaction", + ), + ), + ( + "feed_image", + models.ForeignKey( + blank=True, + help_text="This image will be used in listings and indexes across the site, if no feed image is added, the social image will be used.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="images.ietfimage", + ), + ), + ( + "mailing_list_signup", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="snippets.mailinglistsignup", + ), + ), + ( + "social_image", + models.ForeignKey( + blank=True, + help_text="Image to appear alongside 'social text', particularly for sharing on social networks", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="images.ietfimage", + ), + ), ], options={ - 'verbose_name': 'IAB Standard Page', + "verbose_name": "IAB Standard Page", }, - bases=('wagtailcore.page', models.Model), + bases=("wagtailcore.page", models.Model), ), ] diff --git a/ietf/standard/migrations/0009_alter_iabstandardpage_in_depth_and_more.py b/ietf/standard/migrations/0009_alter_iabstandardpage_in_depth_and_more.py index d1f32eac..0c345d99 100644 --- a/ietf/standard/migrations/0009_alter_iabstandardpage_in_depth_and_more.py +++ b/ietf/standard/migrations/0009_alter_iabstandardpage_in_depth_and_more.py @@ -1,6 +1,5 @@ # Generated by Django 4.2.7 on 2024-04-03 13:40 -from django.db import migrations import wagtail.blocks import wagtail.contrib.table_block.blocks import wagtail.contrib.typed_table_block.blocks @@ -8,43 +7,368 @@ import wagtail.fields import wagtail.images.blocks import wagtailmarkdown.blocks +from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('standard', '0008_auto_20230414_0340'), + ("standard", "0008_auto_20230414_0340"), ] operations = [ migrations.AlterField( - model_name='iabstandardpage', - name='in_depth', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], blank=True, use_json_field=True), + model_name="iabstandardpage", + name="in_depth", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='iabstandardpage', - name='key_info', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], blank=True, use_json_field=True), + model_name="iabstandardpage", + name="key_info", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='standardindexpage', - name='in_depth', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], blank=True, use_json_field=True), + model_name="standardindexpage", + name="in_depth", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='standardindexpage', - name='key_info', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], blank=True, use_json_field=True), + model_name="standardindexpage", + name="key_info", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='standardpage', - name='in_depth', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], blank=True, use_json_field=True), + model_name="standardpage", + name="in_depth", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='standardpage', - name='key_info', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], blank=True, use_json_field=True), + model_name="standardpage", + name="key_info", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + blank=True, + use_json_field=True, + ), ), ] diff --git a/ietf/standard/templatetags/has_tabs.py b/ietf/standard/templatetags/has_tabs.py index 9ec07130..3009697d 100644 --- a/ietf/standard/templatetags/has_tabs.py +++ b/ietf/standard/templatetags/has_tabs.py @@ -2,6 +2,7 @@ register = template.Library() + @register.simple_tag def has_tabs(key_info, in_depth): - return True if key_info and in_depth else False + return bool(key_info and in_depth) diff --git a/ietf/standard/tests.py b/ietf/standard/tests.py index 8152fe2b..f09b8ecd 100644 --- a/ietf/standard/tests.py +++ b/ietf/standard/tests.py @@ -1,8 +1,13 @@ -from django.test import Client import pytest +from django.test import Client from ietf.home.models import HomePage, IABHomePage -from .factories import IABStandardPageFactory, StandardIndexPageFactory, StandardPageFactory + +from .factories import ( + IABStandardPageFactory, + StandardIndexPageFactory, + StandardPageFactory, +) from .models import IABStandardPage, StandardIndexPage, StandardPage pytestmark = pytest.mark.django_db diff --git a/ietf/topics/factories.py b/ietf/topics/factories.py index bf9ffded..83f9d0b2 100644 --- a/ietf/topics/factories.py +++ b/ietf/topics/factories.py @@ -1,7 +1,7 @@ import factory import wagtail_factories -from .models import TopicIndexPage, PrimaryTopicPage +from .models import PrimaryTopicPage, TopicIndexPage class PrimaryTopicPageFactory(wagtail_factories.PageFactory): diff --git a/ietf/topics/migrations/0001_initial.py b/ietf/topics/migrations/0001_initial.py index e67fd6fc..5e7091a2 100644 --- a/ietf/topics/migrations/0001_initial.py +++ b/ietf/topics/migrations/0001_initial.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-04-10 18:46 -from __future__ import unicode_literals import django.db.models.deletion import modelcluster.fields diff --git a/ietf/topics/migrations/0004_auto_20220902_0524.py b/ietf/topics/migrations/0004_auto_20220902_0524.py index 4e792178..b491ebf6 100644 --- a/ietf/topics/migrations/0004_auto_20220902_0524.py +++ b/ietf/topics/migrations/0004_auto_20220902_0524.py @@ -1,29 +1,75 @@ # Generated by Django 3.2.13 on 2022-09-02 04:24 -from django.db import migrations import wagtail.blocks import wagtail.contrib.table_block.blocks import wagtail.embeds.blocks import wagtail.fields import wagtail.images.blocks import wagtailmarkdown.blocks +from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('topics', '0003_auto_20211101_0113'), + ("topics", "0003_auto_20211101_0113"), ] operations = [ migrations.AlterField( - model_name='primarytopicpage', - name='in_depth', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True, use_json_field=True), + model_name="primarytopicpage", + name="in_depth", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='primarytopicpage', - name='key_info', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html'))], blank=True, use_json_field=True), + model_name="primarytopicpage", + name="key_info", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ], + blank=True, + use_json_field=True, + ), ), ] diff --git a/ietf/topics/migrations/0008_alter_primarytopicpage_in_depth_and_more.py b/ietf/topics/migrations/0008_alter_primarytopicpage_in_depth_and_more.py index a9c724e8..ec147a1f 100644 --- a/ietf/topics/migrations/0008_alter_primarytopicpage_in_depth_and_more.py +++ b/ietf/topics/migrations/0008_alter_primarytopicpage_in_depth_and_more.py @@ -1,6 +1,5 @@ # Generated by Django 4.2.7 on 2024-04-03 13:40 -from django.db import migrations import wagtail.blocks import wagtail.contrib.table_block.blocks import wagtail.contrib.typed_table_block.blocks @@ -8,23 +7,132 @@ import wagtail.fields import wagtail.images.blocks import wagtailmarkdown.blocks +from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('topics', '0007_auto_20230414_0340'), + ("topics", "0007_auto_20230414_0340"), ] operations = [ migrations.AlterField( - model_name='primarytopicpage', - name='in_depth', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], blank=True, use_json_field=True), + model_name="primarytopicpage", + name="in_depth", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + blank=True, + use_json_field=True, + ), ), migrations.AlterField( - model_name='primarytopicpage', - name='key_info', - field=wagtail.fields.StreamField([('heading', wagtail.blocks.CharBlock(icon='title')), ('paragraph', wagtail.blocks.RichTextBlock(icon='pilcrow')), ('image', wagtail.images.blocks.ImageChooserBlock(icon='image', template='includes/imageblock.html')), ('markdown', wagtailmarkdown.blocks.MarkdownBlock(icon='code')), ('embed', wagtail.embeds.blocks.EmbedBlock(icon='code')), ('raw_html', wagtail.blocks.RawHTMLBlock(icon='placeholder')), ('table', wagtail.contrib.table_block.blocks.TableBlock(table_options={'renderer': 'html'}, template='includes/tableblock.html')), ('typed_table', wagtail.contrib.typed_table_block.blocks.TypedTableBlock([('text', wagtail.blocks.CharBlock(required=False)), ('numeric', wagtail.blocks.FloatBlock(required=False, template='blocks/float_block.html')), ('rich_text', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(required=False))])), ('note_well', wagtail.blocks.StructBlock([], icon='placeholder', label='Note Well Text'))], blank=True, use_json_field=True), + model_name="primarytopicpage", + name="key_info", + field=wagtail.fields.StreamField( + [ + ("heading", wagtail.blocks.CharBlock(icon="title")), + ("paragraph", wagtail.blocks.RichTextBlock(icon="pilcrow")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + icon="image", template="includes/imageblock.html" + ), + ), + ("markdown", wagtailmarkdown.blocks.MarkdownBlock(icon="code")), + ("embed", wagtail.embeds.blocks.EmbedBlock(icon="code")), + ("raw_html", wagtail.blocks.RawHTMLBlock(icon="placeholder")), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + table_options={"renderer": "html"}, + template="includes/tableblock.html", + ), + ), + ( + "typed_table", + wagtail.contrib.typed_table_block.blocks.TypedTableBlock( + [ + ("text", wagtail.blocks.CharBlock(required=False)), + ( + "numeric", + wagtail.blocks.FloatBlock( + required=False, + template="blocks/float_block.html", + ), + ), + ( + "rich_text", + wagtail.blocks.RichTextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ), + ( + "note_well", + wagtail.blocks.StructBlock( + [], icon="placeholder", label="Note Well Text" + ), + ), + ], + blank=True, + use_json_field=True, + ), ), ] diff --git a/ietf/topics/models.py b/ietf/topics/models.py index 9ea68381..bea2546f 100644 --- a/ietf/topics/models.py +++ b/ietf/topics/models.py @@ -62,8 +62,12 @@ class PrimaryTopicPage(Page, PromoteMixin): max_length=255, help_text="Enter the title to display on the page, you can use only 255 characters.", ) - key_info = StreamField(StandardBlock(required=False), blank=True, use_json_field=True) - in_depth = StreamField(StandardBlock(required=False), blank=True, use_json_field=True) + key_info = StreamField( + StandardBlock(required=False), blank=True, use_json_field=True + ) + in_depth = StreamField( + StandardBlock(required=False), blank=True, use_json_field=True + ) call_to_action = models.ForeignKey( "snippets.CallToAction", null=True, diff --git a/ietf/topics/test.py b/ietf/topics/test.py index d8ccea12..ed337f46 100644 --- a/ietf/topics/test.py +++ b/ietf/topics/test.py @@ -2,6 +2,7 @@ from django.test import Client from ietf.home.models import HomePage + from .factories import PrimaryTopicPageFactory, TopicIndexPageFactory from .models import PrimaryTopicPage, TopicIndexPage diff --git a/ietf/utils/apps.py b/ietf/utils/apps.py index b01340df..40788f4c 100644 --- a/ietf/utils/apps.py +++ b/ietf/utils/apps.py @@ -2,7 +2,7 @@ class UtilsAppConfig(AppConfig): - name = 'ietf.utils' + name = "ietf.utils" verbose_name = "IETF Website Utils" def ready(self): diff --git a/ietf/utils/blocks.py b/ietf/utils/blocks.py index 2c12ac43..ee60825d 100644 --- a/ietf/utils/blocks.py +++ b/ietf/utils/blocks.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.utils.functional import cached_property from wagtail.blocks import ( CharBlock, @@ -17,13 +18,11 @@ from wagtail.images.blocks import ImageChooserBlock from wagtailmarkdown.blocks import MarkdownBlock -from django.conf import settings - class NoteWellBlock(StructBlock): def get_context(self, value): context = super().get_context(value) - context['note_well_git_url'] = settings.NOTE_WELL_REPO + context["note_well_git_url"] = settings.NOTE_WELL_REPO return context class Meta: diff --git a/ietf/utils/context_processors.py b/ietf/utils/context_processors.py index 3b200206..f985ff10 100644 --- a/ietf/utils/context_processors.py +++ b/ietf/utils/context_processors.py @@ -90,8 +90,7 @@ def get_footer(): def get_preview_footer(current): items = [ - current if item == current else item - for item in FooterColumn.objects.all() + current if item == current else item for item in FooterColumn.objects.all() ] if not current.pk: items.append(current) diff --git a/ietf/utils/migrations/0001_initial.py b/ietf/utils/migrations/0001_initial.py index 0bf9e9b5..6a7b08ac 100644 --- a/ietf/utils/migrations/0001_initial.py +++ b/ietf/utils/migrations/0001_initial.py @@ -1,10 +1,8 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-04-10 18:46 -from __future__ import unicode_literals -from django.db import migrations, models import django.db.models.deletion import modelcluster.fields +from django.db import migrations, models class Migration(migrations.Migration): @@ -12,94 +10,272 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('images', '0001_initial'), - ('wagtaildocs', '0008_document_file_size'), - ('wagtailcore', '0040_page_draft_title'), + ("images", "0001_initial"), + ("wagtaildocs", "0008_document_file_size"), + ("wagtailcore", "0040_page_draft_title"), ] operations = [ migrations.CreateModel( - name='FeedSettings', + name="FeedSettings", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('blog_feed_title', models.CharField(blank=True, max_length=255)), - ('blog_feed_description', models.CharField(blank=True, max_length=255)), - ('site', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, to='wagtailcore.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("blog_feed_title", models.CharField(blank=True, max_length=255)), + ("blog_feed_description", models.CharField(blank=True, max_length=255)), + ( + "site", + models.OneToOneField( + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="wagtailcore.Site", + ), + ), ], options={ - 'verbose_name': 'Feeds', + "verbose_name": "Feeds", }, ), migrations.CreateModel( - name='FooterLinkItem', + name="FooterLinkItem", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sort_order', models.IntegerField(blank=True, editable=False, null=True)), - ('link_external', models.URLField(blank=True, verbose_name='External link')), - ('title', models.CharField(max_length=255)), - ('link_document', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtaildocs.Document')), - ('link_page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.Page')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "link_external", + models.URLField(blank=True, verbose_name="External link"), + ), + ("title", models.CharField(max_length=255)), + ( + "link_document", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtaildocs.Document", + ), + ), + ( + "link_page", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.Page", + ), + ), ], options={ - 'ordering': ['sort_order'], - 'abstract': False, + "ordering": ["sort_order"], + "abstract": False, }, ), migrations.CreateModel( - name='FooterLinks', + name="FooterLinks", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('site', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, to='wagtailcore.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "site", + models.OneToOneField( + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="wagtailcore.Site", + ), + ), ], options={ - 'abstract': False, + "abstract": False, }, ), migrations.CreateModel( - name='SecondaryMenu', + name="SecondaryMenu", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('contact_page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.Page')), - ('site', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, to='wagtailcore.Site')), - ('tools_page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.Page')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "contact_page", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailcore.Page", + ), + ), + ( + "site", + models.OneToOneField( + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="wagtailcore.Site", + ), + ), + ( + "tools_page", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailcore.Page", + ), + ), ], options={ - 'abstract': False, + "abstract": False, }, ), migrations.CreateModel( - name='SocialMediaSettings', + name="SocialMediaSettings", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('twitter_handle', models.CharField(blank='True', help_text='Your Twitter username without the @, e.g. flickr', max_length=255)), - ('facebook_app_id', models.CharField(blank='True', help_text='Your Facebook app id', max_length=255)), - ('default_sharing_text', models.CharField(blank='True', help_text='Default sharing text to use if social text has not been set on a page.', max_length=255)), - ('site_name', models.CharField(blank='True', default='ietf', help_text='Site name, used by facebook open graph.', max_length=255)), - ('default_sharing_image', models.ForeignKey(blank=True, help_text='Default sharing image to use if social image has not been set on a page.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.IETFImage')), - ('site', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, to='wagtailcore.Site')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "twitter_handle", + models.CharField( + blank="True", + help_text="Your Twitter username without the @, e.g. flickr", + max_length=255, + ), + ), + ( + "facebook_app_id", + models.CharField( + blank="True", help_text="Your Facebook app id", max_length=255 + ), + ), + ( + "default_sharing_text", + models.CharField( + blank="True", + help_text="Default sharing text to use if social text has not been set on a page.", + max_length=255, + ), + ), + ( + "site_name", + models.CharField( + blank="True", + default="ietf", + help_text="Site name, used by facebook open graph.", + max_length=255, + ), + ), + ( + "default_sharing_image", + models.ForeignKey( + blank=True, + help_text="Default sharing image to use if social image has not been set on a page.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="images.IETFImage", + ), + ), + ( + "site", + models.OneToOneField( + editable=False, + on_delete=django.db.models.deletion.CASCADE, + to="wagtailcore.Site", + ), + ), ], options={ - 'abstract': False, + "abstract": False, }, ), migrations.CreateModel( - name='ToolsMenuItem', + name="ToolsMenuItem", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sort_order', models.IntegerField(blank=True, editable=False, null=True)), - ('link', models.URLField(blank=True)), - ('text', models.CharField(blank=True, max_length=255)), - ('model', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tools_menu_items', to='utils.SecondaryMenu')), - ('page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.Page')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ("link", models.URLField(blank=True)), + ("text", models.CharField(blank=True, max_length=255)), + ( + "model", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tools_menu_items", + to="utils.SecondaryMenu", + ), + ), + ( + "page", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailcore.Page", + ), + ), ], options={ - 'ordering': ['sort_order'], - 'abstract': False, + "ordering": ["sort_order"], + "abstract": False, }, ), migrations.AddField( - model_name='footerlinkitem', - name='model', - field=modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='footer_link_items', to='utils.FooterLinks'), + model_name="footerlinkitem", + name="model", + field=modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="footer_link_items", + to="utils.FooterLinks", + ), ), ] diff --git a/ietf/utils/migrations/0002_auto_20211101_0113.py b/ietf/utils/migrations/0002_auto_20211101_0113.py index 25816526..fb9a1914 100644 --- a/ietf/utils/migrations/0002_auto_20211101_0113.py +++ b/ietf/utils/migrations/0002_auto_20211101_0113.py @@ -1,15 +1,15 @@ # Generated by Django 2.2.19 on 2021-11-01 01:13 -from django.db import migrations, models import django.db.models.deletion import modelcluster.fields +from django.db import migrations, models def migrate_data(apps, schema_editor): - SecondaryMenu = apps.get_model('utils', 'SecondaryMenu') - ToolsMenuItem = apps.get_model('utils', 'ToolsMenuItem') - MenuItem = apps.get_model('utils', 'MenuItem') - SubMenuItem = apps.get_model('utils', 'SubMenuItem') + SecondaryMenu = apps.get_model("utils", "SecondaryMenu") + ToolsMenuItem = apps.get_model("utils", "ToolsMenuItem") + MenuItem = apps.get_model("utils", "MenuItem") + SubMenuItem = apps.get_model("utils", "SubMenuItem") menu = SecondaryMenu.objects.first() if menu is not None: contact_menu = MenuItem(page=menu.contact_page, sort_order=1) @@ -18,58 +18,107 @@ def migrate_data(apps, schema_editor): tools_menu.save() for item in ToolsMenuItem.objects.all(): - sub_menu = SubMenuItem(parent=tools_menu, page=item.page, link=item.link, text=item.text) + sub_menu = SubMenuItem( + parent=tools_menu, page=item.page, link=item.link, text=item.text + ) sub_menu.save() class Migration(migrations.Migration): dependencies = [ - ('wagtailcore', '0059_apply_collection_ordering'), - ('utils', '0001_initial'), + ("wagtailcore", "0059_apply_collection_ordering"), + ("utils", "0001_initial"), ] operations = [ migrations.CreateModel( - name='MenuItem', + name="MenuItem", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sort_order', models.IntegerField(blank=True, editable=False, null=True)), - ('text', models.CharField(blank=True, max_length=40)), - ('page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.Page')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ("text", models.CharField(blank=True, max_length=40)), + ( + "page", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailcore.Page", + ), + ), ], options={ - 'abstract': False, + "abstract": False, }, ), migrations.CreateModel( - name='SubMenuItem', + name="SubMenuItem", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sort_order', models.IntegerField(blank=True, editable=False, null=True)), - ('link', models.URLField(blank=True)), - ('text', models.CharField(blank=True, max_length=40)), - ('page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.Page')), - ('parent', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='sub_menu_items', to='utils.MenuItem')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ("link", models.URLField(blank=True)), + ("text", models.CharField(blank=True, max_length=40)), + ( + "page", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailcore.Page", + ), + ), + ( + "parent", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="sub_menu_items", + to="utils.MenuItem", + ), + ), ], options={ - 'ordering': ['sort_order'], - 'abstract': False, + "ordering": ["sort_order"], + "abstract": False, }, ), migrations.RunPython(migrate_data), migrations.RemoveField( - model_name='toolsmenuitem', - name='model', + model_name="toolsmenuitem", + name="model", ), migrations.RemoveField( - model_name='toolsmenuitem', - name='page', + model_name="toolsmenuitem", + name="page", ), migrations.DeleteModel( - name='SecondaryMenu', + name="SecondaryMenu", ), migrations.DeleteModel( - name='ToolsMenuItem', + name="ToolsMenuItem", ), ] diff --git a/ietf/utils/migrations/0003_auto_20211105_0019.py b/ietf/utils/migrations/0003_auto_20211105_0019.py index 142b458b..586a7c7f 100644 --- a/ietf/utils/migrations/0003_auto_20211105_0019.py +++ b/ietf/utils/migrations/0003_auto_20211105_0019.py @@ -1,24 +1,24 @@ # Generated by Django 2.2.19 on 2021-11-05 00:19 -from django.db import migrations, models +from django.db import migrations + def add_missing_menu(apps, schema_editor): - MenuItem = apps.get_model('utils', 'MenuItem') - Page = apps.get_model('wagtailcore', 'Page') + MenuItem = apps.get_model("utils", "MenuItem") + Page = apps.get_model("wagtailcore", "Page") page = Page.objects.filter(pk=42).first() if page: - MenuItem.objects.create(page=page, sort_order=0, text='News & blog') + MenuItem.objects.create(page=page, sort_order=0, text="News & blog") tools_menu = MenuItem.objects.filter(page__title="Links").first() if tools_menu: tools_menu.text = "Tools" tools_menu.save() + class Migration(migrations.Migration): dependencies = [ - ('utils', '0002_auto_20211101_0113'), + ("utils", "0002_auto_20211101_0113"), ] - operations = [ - migrations.RunPython(add_missing_menu) - ] + operations = [migrations.RunPython(add_missing_menu)] diff --git a/ietf/utils/migrations/0004_alter_menuitem_options.py b/ietf/utils/migrations/0004_alter_menuitem_options.py index d294177f..39ee4cdb 100644 --- a/ietf/utils/migrations/0004_alter_menuitem_options.py +++ b/ietf/utils/migrations/0004_alter_menuitem_options.py @@ -6,12 +6,12 @@ class Migration(migrations.Migration): dependencies = [ - ('utils', '0003_auto_20211105_0019'), + ("utils", "0003_auto_20211105_0019"), ] operations = [ migrations.AlterModelOptions( - name='menuitem', - options={'verbose_name_plural': 'Secondary Menu'}, + name="menuitem", + options={"verbose_name_plural": "Secondary Menu"}, ), ] diff --git a/ietf/utils/migrations/0007_auto_20230524_0551.py b/ietf/utils/migrations/0007_auto_20230524_0551.py index e748a99b..c3651b03 100644 --- a/ietf/utils/migrations/0007_auto_20230524_0551.py +++ b/ietf/utils/migrations/0007_auto_20230524_0551.py @@ -6,28 +6,48 @@ class Migration(migrations.Migration): dependencies = [ - ('utils', '0006_textchunk'), + ("utils", "0006_textchunk"), ] operations = [ migrations.AddField( - model_name='socialmediasettings', - name='linkedin', - field=models.CharField(blank='True', help_text='Link to linkedin profile', max_length=255, verbose_name='LinkedIn link'), + model_name="socialmediasettings", + name="linkedin", + field=models.CharField( + blank="True", + help_text="Link to linkedin profile", + max_length=255, + verbose_name="LinkedIn link", + ), ), migrations.AddField( - model_name='socialmediasettings', - name='mastodon', - field=models.CharField(blank='True', help_text='Link to mastodon profile', max_length=255, verbose_name='Mastodon link'), + model_name="socialmediasettings", + name="mastodon", + field=models.CharField( + blank="True", + help_text="Link to mastodon profile", + max_length=255, + verbose_name="Mastodon link", + ), ), migrations.AddField( - model_name='socialmediasettings', - name='twitter', - field=models.CharField(blank='True', help_text='Link to twitter profile', max_length=255, verbose_name='Twitter link'), + model_name="socialmediasettings", + name="twitter", + field=models.CharField( + blank="True", + help_text="Link to twitter profile", + max_length=255, + verbose_name="Twitter link", + ), ), migrations.AddField( - model_name='socialmediasettings', - name='youtube', - field=models.CharField(blank='True', help_text='Link to youtube account', max_length=255, verbose_name='Youtube link'), + model_name="socialmediasettings", + name="youtube", + field=models.CharField( + blank="True", + help_text="Link to youtube account", + max_length=255, + verbose_name="Youtube link", + ), ), ] diff --git a/ietf/utils/migrations/0008_socialmediasettings_github_and_more.py b/ietf/utils/migrations/0008_socialmediasettings_github_and_more.py index c0445784..a6cb1d40 100644 --- a/ietf/utils/migrations/0008_socialmediasettings_github_and_more.py +++ b/ietf/utils/migrations/0008_socialmediasettings_github_and_more.py @@ -6,33 +6,58 @@ class Migration(migrations.Migration): dependencies = [ - ('utils', '0007_auto_20230524_0551'), + ("utils", "0007_auto_20230524_0551"), ] operations = [ migrations.AddField( - model_name='socialmediasettings', - name='github', - field=models.CharField(blank='True', help_text='Link to GitHub profile', max_length=255, verbose_name='GitHub link'), + model_name="socialmediasettings", + name="github", + field=models.CharField( + blank="True", + help_text="Link to GitHub profile", + max_length=255, + verbose_name="GitHub link", + ), ), migrations.AlterField( - model_name='socialmediasettings', - name='linkedin', - field=models.CharField(blank='True', help_text='Link to LinkedIn profile', max_length=255, verbose_name='LinkedIn link'), + model_name="socialmediasettings", + name="linkedin", + field=models.CharField( + blank="True", + help_text="Link to LinkedIn profile", + max_length=255, + verbose_name="LinkedIn link", + ), ), migrations.AlterField( - model_name='socialmediasettings', - name='mastodon', - field=models.CharField(blank='True', help_text='Link to Mastodon profile', max_length=255, verbose_name='Mastodon link'), + model_name="socialmediasettings", + name="mastodon", + field=models.CharField( + blank="True", + help_text="Link to Mastodon profile", + max_length=255, + verbose_name="Mastodon link", + ), ), migrations.AlterField( - model_name='socialmediasettings', - name='twitter', - field=models.CharField(blank='True', help_text='Link to Twitter profile', max_length=255, verbose_name='Twitter link'), + model_name="socialmediasettings", + name="twitter", + field=models.CharField( + blank="True", + help_text="Link to Twitter profile", + max_length=255, + verbose_name="Twitter link", + ), ), migrations.AlterField( - model_name='socialmediasettings', - name='youtube', - field=models.CharField(blank='True', help_text='Link to YouTube account', max_length=255, verbose_name='Youtube link'), + model_name="socialmediasettings", + name="youtube", + field=models.CharField( + blank="True", + help_text="Link to YouTube account", + max_length=255, + verbose_name="Youtube link", + ), ), ] diff --git a/ietf/utils/migrations/0009_megamenu.py b/ietf/utils/migrations/0009_megamenu.py index 9a581714..49decd49 100644 --- a/ietf/utils/migrations/0009_megamenu.py +++ b/ietf/utils/migrations/0009_megamenu.py @@ -2,11 +2,11 @@ import uuid -from django.db import migrations, models import django.db.models.deletion import wagtail.blocks import wagtail.fields import wagtail.models +from django.db import migrations, models def populate_main_menu(apps, schema_editor): @@ -18,7 +18,11 @@ def live_children(page): if not page: return Page.objects.none() # path of children is path of parent with 4 more characters at the end - return Page.objects.filter(path__regex=f"^{page.path}....$").filter(live=True).order_by("path") + return ( + Page.objects.filter(path__regex=f"^{page.path}....$") + .filter(live=True) + .order_by("path") + ) homepage = HomePage.objects.first() if not homepage: @@ -62,27 +66,102 @@ def live_children(page): class Migration(migrations.Migration): dependencies = [ - ('images', '0004_django_42_rendition_storage'), - ('wagtailcore', '0089_log_entry_data_json_null_to_object'), - ('utils', '0008_socialmediasettings_github_and_more'), + ("images", "0004_django_42_rendition_storage"), + ("wagtailcore", "0089_log_entry_data_json_null_to_object"), + ("utils", "0008_socialmediasettings_github_and_more"), ] operations = [ migrations.RenameModel( - old_name='MenuItem', - new_name='SecondaryMenuItem', + old_name="MenuItem", + new_name="SecondaryMenuItem", ), migrations.CreateModel( - name='MainMenuItem', + name="MainMenuItem", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('secondary_sections', wagtail.fields.StreamField([('section', wagtail.blocks.StructBlock([('title', wagtail.blocks.CharBlock(label='Section title', required=True)), ('links', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('page', wagtail.blocks.PageChooserBlock(label='Page', required=False)), ('title', wagtail.blocks.CharBlock(label='Link text', required=False)), ('external_url', wagtail.blocks.URLBlock(label='External URL', required=False))])))]))], blank=True, use_json_field=True)), - ('sort_order', models.PositiveSmallIntegerField()), - ('image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.ietfimage')), - ('page', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.page')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "secondary_sections", + wagtail.fields.StreamField( + [ + ( + "section", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + label="Section title", required=True + ), + ), + ( + "links", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "page", + wagtail.blocks.PageChooserBlock( + label="Page", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + label="Link text", + required=False, + ), + ), + ( + "external_url", + wagtail.blocks.URLBlock( + label="External URL", + required=False, + ), + ), + ] + ) + ), + ), + ] + ), + ) + ], + blank=True, + use_json_field=True, + ), + ), + ("sort_order", models.PositiveSmallIntegerField()), + ( + "image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="images.ietfimage", + ), + ), + ( + "page", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.page", + ), + ), ], options={ - 'ordering': ['sort_order'], + "ordering": ["sort_order"], }, bases=(wagtail.models.PreviewableMixin, models.Model), ), diff --git a/ietf/utils/migrations/0010_footercolumn.py b/ietf/utils/migrations/0010_footercolumn.py index 35d73676..69527854 100644 --- a/ietf/utils/migrations/0010_footercolumn.py +++ b/ietf/utils/migrations/0010_footercolumn.py @@ -1,28 +1,69 @@ # Generated by Django 4.2.7 on 2024-03-29 14:06 -from django.db import migrations, models import wagtail.blocks import wagtail.fields import wagtail.models +from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('utils', '0009_megamenu'), + ("utils", "0009_megamenu"), ] operations = [ migrations.CreateModel( - name='FooterColumn', + name="FooterColumn", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255)), - ('links', wagtail.fields.StreamField([('link', wagtail.blocks.StructBlock([('page', wagtail.blocks.PageChooserBlock(label='Page', required=False)), ('title', wagtail.blocks.CharBlock(label='Link text', required=False)), ('external_url', wagtail.blocks.URLBlock(label='External URL', required=False))]))], blank=True, use_json_field=True)), - ('sort_order', models.PositiveSmallIntegerField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=255)), + ( + "links", + wagtail.fields.StreamField( + [ + ( + "link", + wagtail.blocks.StructBlock( + [ + ( + "page", + wagtail.blocks.PageChooserBlock( + label="Page", required=False + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + label="Link text", required=False + ), + ), + ( + "external_url", + wagtail.blocks.URLBlock( + label="External URL", required=False + ), + ), + ] + ), + ) + ], + blank=True, + use_json_field=True, + ), + ), + ("sort_order", models.PositiveSmallIntegerField()), ], options={ - 'ordering': ['sort_order'], + "ordering": ["sort_order"], }, bases=(wagtail.models.PreviewableMixin, models.Model), ), diff --git a/ietf/utils/models.py b/ietf/utils/models.py index 7e2ddb60..3589573d 100644 --- a/ietf/utils/models.py +++ b/ietf/utils/models.py @@ -1,6 +1,5 @@ from django.conf import settings from django.db import models -from django.utils.translation import gettext_lazy as _ from modelcluster.fields import ParentalKey from modelcluster.models import ClusterableModel from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel @@ -105,7 +104,9 @@ def get_social_text(self): class MainMenuItem(PreviewableMixin, models.Model): - page = models.ForeignKey("wagtailcore.Page", related_name="+", on_delete=models.CASCADE) + page = models.ForeignKey( + "wagtailcore.Page", related_name="+", on_delete=models.CASCADE + ) image = models.ForeignKey( "images.IETFImage", null=True, @@ -262,33 +263,33 @@ class SocialMediaSettings(BaseSiteSetting): max_length=255, help_text="Link to LinkedIn profile", blank="True", - verbose_name="LinkedIn link" + verbose_name="LinkedIn link", ) twitter = models.CharField( max_length=255, help_text="Link to Twitter profile", blank="True", - verbose_name="Twitter link" + verbose_name="Twitter link", ) youtube = models.CharField( max_length=255, help_text="Link to YouTube account", blank="True", - verbose_name="Youtube link" + verbose_name="Youtube link", ) mastodon = models.CharField( max_length=255, help_text="Link to Mastodon profile", blank="True", - verbose_name="Mastodon link" + verbose_name="Mastodon link", ) github = models.CharField( max_length=255, help_text="Link to GitHub profile", blank="True", - verbose_name="GitHub link" + verbose_name="GitHub link", ) - + panels = [ FieldPanel("twitter_handle"), FieldPanel("facebook_app_id"), diff --git a/ietf/utils/signal_handlers.py b/ietf/utils/signal_handlers.py index d607bf46..cf6eb3a8 100644 --- a/ietf/utils/signal_handlers.py +++ b/ietf/utils/signal_handlers.py @@ -11,14 +11,13 @@ def page_published_or_unpublished_handler(instance, **kwargs): home_page = instance.get_site().root_page purge_pages = set() - if not instance.pk == home_page.pk: + if instance.pk != home_page.pk: parent = instance.get_parent() purge_pages.add(parent) for obj, _ in ReferenceIndex.get_grouped_references_to(instance): - if isinstance(obj, Page): - if obj.live: - purge_pages.add(obj) + if isinstance(obj, Page) and obj.live: + purge_pages.add(obj) if isinstance(obj, MainMenuItem): purge_pages.add(home_page) diff --git a/ietf/utils/templatetags/ietf_tags.py b/ietf/utils/templatetags/ietf_tags.py index 4963487f..d31c05ef 100644 --- a/ietf/utils/templatetags/ietf_tags.py +++ b/ietf/utils/templatetags/ietf_tags.py @@ -1,7 +1,6 @@ from urllib.parse import quote from django.template import Library -from wagtail.models import Site from ..models import PromoteMixin, SocialMediaSettings diff --git a/ietf/utils/tests/test_500_page.py b/ietf/utils/tests/test_500_page.py index 4f4029c6..129e86b0 100644 --- a/ietf/utils/tests/test_500_page.py +++ b/ietf/utils/tests/test_500_page.py @@ -1,6 +1,7 @@ from unittest.mock import Mock -from django.test import Client + import pytest +from django.test import Client pytestmark = pytest.mark.django_db diff --git a/ietf/utils/tests/test_footer.py b/ietf/utils/tests/test_footer.py index fe405cda..7a2cebb2 100644 --- a/ietf/utils/tests/test_footer.py +++ b/ietf/utils/tests/test_footer.py @@ -1,5 +1,5 @@ -from bs4 import BeautifulSoup import pytest +from bs4 import BeautifulSoup from django.test import Client, RequestFactory from ietf.home.models import HomePage @@ -85,14 +85,14 @@ def test_links(self): def test_order_in_preview(self): item1 = FooterColumn.objects.create(title="One", sort_order=10) - item2 = FooterColumn.objects.create(title="Two", sort_order=20) + FooterColumn.objects.create(title="Two", sort_order=20) item1.sort_order = 30 context = item1.get_preview_context(RequestFactory().get("/"), "") assert [i.title for i in context["FOOTER"]] == ["Two", "One"] def test_order_in_preview_new_object(self): - item1 = FooterColumn.objects.create(title="One", sort_order=10) + FooterColumn.objects.create(title="One", sort_order=10) item2 = FooterColumn(title="Two", sort_order=5) context = item2.get_preview_context(RequestFactory().get("/"), "") diff --git a/ietf/utils/tests/test_iab_main_menu.py b/ietf/utils/tests/test_iab_main_menu.py index 56bec58c..9d417dce 100644 --- a/ietf/utils/tests/test_iab_main_menu.py +++ b/ietf/utils/tests/test_iab_main_menu.py @@ -1,6 +1,6 @@ +import pytest from bs4 import BeautifulSoup from django.test import Client -import pytest from ietf.home.models import IABHomePage from ietf.standard.factories import IABStandardPageFactory @@ -28,7 +28,7 @@ def test_pages_in_menu(self): soup = BeautifulSoup(html, "html.parser") def get_nav_item(item): - """ Get the menu item link, and the links within the menu. """ + """Get the menu item link, and the links within the menu.""" [main_link] = item.select("a.nav-link") child_links = item.select("ul.dropdown-menu > li > a") return ( @@ -40,5 +40,5 @@ def get_nav_item(item): assert menu == [ (page1.url, [page1a.url, page1b.url]), (page2.url, [page2a.url, page2b.url]), - ('/search', []), + ("/search", []), ] diff --git a/ietf/utils/tests/test_mega_menu.py b/ietf/utils/tests/test_mega_menu.py index 7558c2ad..bad072e1 100644 --- a/ietf/utils/tests/test_mega_menu.py +++ b/ietf/utils/tests/test_mega_menu.py @@ -1,5 +1,5 @@ -from bs4 import BeautifulSoup import pytest +from bs4 import BeautifulSoup from django.test import Client, RequestFactory from ietf.home.models import HomePage @@ -100,7 +100,7 @@ def test_secondary_section(self): def test_order_in_preview(self): item1 = MainMenuItem.objects.create(page=self.standard_index, sort_order=10) - item2 = MainMenuItem.objects.create(page=self.standard_page, sort_order=20) + MainMenuItem.objects.create(page=self.standard_page, sort_order=20) item1.sort_order = 30 context = item1.get_preview_context(RequestFactory().get("/"), "") @@ -110,7 +110,7 @@ def test_order_in_preview(self): ] def test_order_in_preview_new_object(self): - item1 = MainMenuItem.objects.create(page=self.standard_index, sort_order=10) + MainMenuItem.objects.create(page=self.standard_index, sort_order=10) item2 = MainMenuItem(page=self.standard_page, sort_order=5) context = item2.get_preview_context(RequestFactory().get("/"), "") diff --git a/ietf/utils/tests/test_secondary_menu.py b/ietf/utils/tests/test_secondary_menu.py index 83746c09..db82f685 100644 --- a/ietf/utils/tests/test_secondary_menu.py +++ b/ietf/utils/tests/test_secondary_menu.py @@ -1,5 +1,5 @@ -from django.test import Client import pytest +from django.test import Client from wagtail.test.utils import WagtailTestUtils from ietf.events.factories import EventListingPageFactory, EventPageFactory @@ -21,8 +21,12 @@ def set_up(self, home: HomePage): ) def _build_menu(self): - SecondaryMenuItem.objects.create(page=self.eventlisting, text="Menu One", sort_order=0) - SecondaryMenuItem.objects.create(page=self.eventpage, text="Menu Two", sort_order=1) + SecondaryMenuItem.objects.create( + page=self.eventlisting, text="Menu One", sort_order=0 + ) + SecondaryMenuItem.objects.create( + page=self.eventpage, text="Menu Two", sort_order=1 + ) def test_admin_menu_item_index(self, admin_client): response = admin_client.get("/admin/utils/secondarymenuitem/") diff --git a/ietf/utils/wagtail_hooks.py b/ietf/utils/wagtail_hooks.py index d75dca5c..4d818bde 100644 --- a/ietf/utils/wagtail_hooks.py +++ b/ietf/utils/wagtail_hooks.py @@ -1,8 +1,8 @@ from django.conf import settings from django.utils.html import format_html from wagtail import hooks -from wagtail.snippets.views.snippets import SnippetViewSet from wagtail.snippets.models import register_snippet +from wagtail.snippets.views.snippets import SnippetViewSet from wagtail_modeladmin.options import ModelAdmin, modeladmin_register from wagtailorderable.modeladmin.mixins import OrderableMixin diff --git a/k8s/ietfweb/local.py b/k8s/ietfweb/local.py index 3392becc..9704389e 100644 --- a/k8s/ietfweb/local.py +++ b/k8s/ietfweb/local.py @@ -1,8 +1,8 @@ # Copyright The IETF Trust 2007-2024, All Rights Reserved -# -*- coding: utf-8 -*- -from email.utils import parseaddr import os +from email.utils import parseaddr + def _multiline_to_list(s): """Helper to split at newlines and conver to list""" @@ -63,7 +63,9 @@ def _multiline_to_list(s): # Leave IETFWWW_MATOMO_SITE_ID unset to disable Matomo reporting if "IETFWWW_MATOMO_SITE_ID" in os.environ: - MATOMO_DOMAIN_PATH = os.environ.get("IETFWWW_MATOMO_DOMAIN_PATH", "analytics.ietf.org") + MATOMO_DOMAIN_PATH = os.environ.get( + "IETFWWW_MATOMO_DOMAIN_PATH", "analytics.ietf.org" + ) MATOMO_SITE_ID = os.environ.get("IETFWWW_MATOMO_SITE_ID", None) MATOMO_DISABLE_COOKIES = True diff --git a/pyproject.toml b/pyproject.toml index 99977b55..728984be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,3 +7,20 @@ filterwarnings = [ "ignore:'index_together'.*'taggit.TaggedItem':django.utils.deprecation.RemovedInDjango51Warning:", "ignore::UserWarning", ] + +[tool.ruff] +target-version = "py312" + +[tool.ruff.lint] +extend-select = [ + "E", # pycodestyle + "F", # Pyflakes + "UP", # pyupgrade + "B", # flake8-bugbear + "SIM", # flake8-simplify + "I", # isort +] + +extend-ignore = [ + "E501", # no line length errors +] diff --git a/requirements/dev.in b/requirements/dev.in index 78f9dcca..84317e8f 100644 --- a/requirements/dev.in +++ b/requirements/dev.in @@ -1,6 +1,9 @@ -c base.txt +black pip-tools +pre-commit pytest-cov pytest-django +ruff wagtail-factories diff --git a/requirements/dev.txt b/requirements/dev.txt index 52c14df4..f6225bc7 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -16,18 +16,24 @@ beautifulsoup4==4.11.2 # via # -c base.txt # wagtail +black==24.8.0 + # via -r dev.in build==1.2.1 # via pip-tools certifi==2024.7.4 # via # -c base.txt # requests +cfgv==3.4.0 + # via pre-commit charset-normalizer==3.3.2 # via # -c base.txt # requests click==8.1.7 - # via pip-tools + # via + # black + # pip-tools coverage[toml]==7.6.1 # via # coverage @@ -36,7 +42,9 @@ defusedxml==0.7.1 # via # -c base.txt # willow -django==4.2.14 +distlib==0.3.8 + # via virtualenv +django==4.2.15 # via # -c base.txt # django-filter @@ -80,8 +88,10 @@ et-xmlfile==1.1.0 # openpyxl factory-boy==3.3.0 # via wagtail-factories -faker==26.1.0 +faker==26.2.0 # via factory-boy +filelock==3.15.4 + # via virtualenv filetype==1.2.0 # via # -c base.txt @@ -90,6 +100,8 @@ html5lib==1.1 # via # -c base.txt # wagtail +identify==2.6.0 + # via pre-commit idna==3.7 # via # -c base.txt @@ -100,6 +112,10 @@ l18n==2021.3 # via # -c base.txt # wagtail +mypy-extensions==1.0.0 + # via black +nodeenv==1.9.1 + # via pre-commit openpyxl==3.1.5 # via # -c base.txt @@ -107,8 +123,11 @@ openpyxl==3.1.5 packaging==24.1 # via # -c base.txt + # black # build # pytest +pathspec==0.12.1 + # via black pillow==10.4.0 # via # -c base.txt @@ -120,8 +139,14 @@ pillow-heif==0.18.0 # willow pip-tools==7.4.1 # via -r dev.in +platformdirs==4.2.2 + # via + # black + # virtualenv pluggy==1.5.0 # via pytest +pre-commit==3.8.0 + # via -r dev.in pyproject-hooks==1.1.0 # via # build @@ -141,10 +166,14 @@ pytz==2024.1 # -c base.txt # django-modelcluster # l18n +pyyaml==6.0.2 + # via pre-commit requests==2.32.3 # via # -c base.txt # wagtail +ruff==0.5.6 + # via -r dev.in six==1.16.0 # via # -c base.txt @@ -167,6 +196,8 @@ urllib3==2.2.2 # via # -c base.txt # requests +virtualenv==20.26.3 + # via pre-commit wagtail==5.2.6 # via # -c base.txt @@ -187,4 +218,4 @@ willow[heif]==1.6.3 # The following packages are considered to be unsafe in a requirements file: # pip -# setuptools +# setuptools \ No newline at end of file