From 39251a0b9a2199edca9574f7f9fa8795d17efeff Mon Sep 17 00:00:00 2001 From: Steve Jalim Date: Tue, 17 Sep 2019 10:06:57 +0100 Subject: [PATCH 1/7] 135: Full pass with `black`as first step towards autoformatting 252 files reformatted, 42 files left unchanged. Done with `black --exclude node_modules .` to avoid unnecessarily reformatting third-party package helper Python in JS deps Includes migration files for consistency, even though it adds noise (209/252 files are migrations...) Tests still passing. --- .../apps/articles/migrations/0001_initial.py | 24 +- .../articles/migrations/0002_article_body.py | 18 +- .../articles/migrations/0002_article_date.py | 14 +- .../articles/migrations/0003_article_intro.py | 12 +- .../migrations/0003_auto_20190517_1038.py | 32 +- .../migrations/0004_auto_20190516_0907.py | 12 +- .../migrations/0005_auto_20190516_1236.py | 14 +- .../migrations/0006_auto_20190516_1303.py | 18 +- .../migrations/0007_merge_20190517_1323.py | 7 +- .../migrations/0008_auto_20190521_0851.py | 50 ++- .../migrations/0009_auto_20190521_1048.py | 33 +- .../migrations/0010_article_labels.py | 18 +- .../migrations/0011_auto_20190522_1630.py | 18 +- .../migrations/0012_article_author.py | 18 +- .../migrations/0012_article_header_image.py | 18 +- .../migrations/0012_auto_20190603_1048.py | 17 +- .../migrations/0013_merge_20190603_1229.py | 7 +- .../migrations/0014_merge_20190604_0953.py | 7 +- .../migrations/0015_auto_20190604_1245.py | 50 ++- .../migrations/0016_auto_20190604_1317.py | 16 +- .../migrations/0017_auto_20190611_1344.py | 18 +- .../migrations/0018_auto_20190611_1403.py | 49 ++- .../migrations/0019_auto_20190611_1453.py | 16 +- .../migrations/0020_auto_20190612_0426.py | 9 +- .../migrations/0021_auto_20190618_0840.py | 12 +- .../migrations/0022_auto_20190624_1622.py | 18 +- .../migrations/0023_auto_20190709_0928.py | 9 +- .../migrations/0024_auto_20190711_1222.py | 50 +-- .../migrations/0025_auto_20190716_1346.py | 50 ++- .../migrations/0026_articles_description.py | 14 +- .../migrations/0026_auto_20190731_1109.py | 40 ++- .../0027_article_related_links_mdn.py | 27 +- .../migrations/0027_merge_20190802_1535.py | 7 +- .../migrations/0028_merge_20190805_1426.py | 7 +- .../migrations/0029_auto_20190813_1302.py | 18 +- .../migrations/0030_auto_20190813_1503.py | 171 ++++++++-- .../migrations/0031_auto_20190819_1304.py | 26 +- developerportal/apps/articles/models.py | 220 ++++++------ .../apps/articles/tests/test_articles.py | 21 +- .../apps/articles/wagtail_hooks.py | 2 +- developerportal/apps/common/blocks.py | 69 ++-- developerportal/apps/common/constants.py | 111 ++++--- developerportal/apps/common/feed.py | 2 +- developerportal/apps/common/fields.py | 34 +- developerportal/apps/common/helpers.py | 20 +- developerportal/apps/common/image_formats.py | 24 +- .../apps/common/tests/test_common.py | 2 +- developerportal/apps/common/utils.py | 51 ++- developerportal/apps/common/wagtail_hooks.py | 19 +- .../apps/content/migrations/0001_initial.py | 158 +++++++-- .../migrations/0002_contentpage_hero_image.py | 19 +- .../migrations/0003_auto_20190813_1503.py | 86 ++++- developerportal/apps/content/models.py | 81 +++-- .../apps/events/migrations/0001_initial.py | 24 +- .../migrations/0002_auto_20190704_1334.py | 291 ++++++++++++---- .../migrations/0003_auto_20190708_0858.py | 37 ++- .../migrations/0003_auto_20190709_0928.py | 9 +- .../migrations/0003_auto_20190709_1241.py | 12 +- .../migrations/0004_auto_20190708_1100.py | 43 ++- .../migrations/0004_auto_20190711_1501.py | 90 +++-- .../migrations/0004_merge_20190711_1925.py | 7 +- .../migrations/0005_merge_20190711_2019.py | 9 +- .../migrations/0006_auto_20190712_1231.py | 27 +- .../migrations/0007_auto_20190718_1424.py | 77 +++-- .../migrations/0010_auto_20190718_1551.py | 10 +- .../migrations/0011_auto_20190718_1724.py | 38 ++- .../migrations/0012_auto_20190725_1124.py | 79 ++--- .../migrations/0013_auto_20190731_1054.py | 40 ++- .../migrations/0014_auto_20190813_1302.py | 18 +- .../migrations/0015_auto_20190813_1503.py | 215 +++++++++++- .../migrations/0016_auto_20190814_1600.py | 70 +++- .../migrations/0017_auto_20190819_1304.py | 17 +- developerportal/apps/events/models.py | 304 +++++++++-------- developerportal/apps/events/wagtail_hooks.py | 2 +- .../migrations/0001_initial.py | 26 +- .../migrations/0002_auto_20190704_1221.py | 10 +- ...rnalarticle_externalevent_externalvideo.py | 64 ++-- .../migrations/0004_auto_20190705_1306.py | 14 +- .../migrations/0005_auto_20190709_1412.py | 20 +- .../migrations/0006_auto_20190709_1420.py | 18 +- .../migrations/0007_auto_20190711_1940.py | 20 +- .../0008_externalcontent_description.py | 12 +- .../migrations/0009_externalarticleauthor.py | 46 ++- .../migrations/0010_auto_20190723_1659.py | 160 ++++++--- .../migrations/0011_auto_20190723_1719.py | 105 ++++-- .../migrations/0012_auto_20190724_1437.py | 9 +- .../migrations/0013_externalevent_venue.py | 17 +- .../migrations/0014_auto_20190725_1225.py | 121 ++----- .../migrations/0015_auto_20190725_1226.py | 314 +++++++++++++----- .../migrations/0016_auto_20190731_1226.py | 40 ++- .../migrations/0017_auto_20190806_1041.py | 25 +- .../migrations/0018_auto_20190807_1244.py | 17 +- .../migrations/0019_auto_20190813_1302.py | 12 +- .../migrations/0020_auto_20190813_1503.py | 128 +++++-- .../migrations/0021_auto_20190814_1600.py | 24 +- .../migrations/0022_auto_20190819_1304.py | 17 +- .../apps/externalcontent/models.py | 293 +++++++++------- .../apps/externalcontent/wagtail_hooks.py | 37 +-- .../apps/health/tests/test_views.py | 22 +- developerportal/apps/health/urls.py | 8 +- developerportal/apps/health/views.py | 2 +- .../apps/home/migrations/0001_initial.py | 26 +- .../home/migrations/0002_create_homepage.py | 36 +- .../migrations/0003_auto_20190528_1305.py | 28 +- .../0004_homepagefeaturedarticle.py | 46 ++- .../migrations/0005_auto_20190618_1635.py | 28 +- .../migrations/0006_auto_20190625_1111.py | 18 +- .../migrations/0007_auto_20190625_1112.py | 18 +- .../migrations/0008_auto_20190625_1119.py | 18 +- .../migrations/0009_auto_20190702_0904.py | 16 +- .../home/migrations/0009_homepage_featured.py | 10 +- .../migrations/0010_auto_20190627_1527.py | 23 +- .../migrations/0010_auto_20190704_1031.py | 12 +- .../migrations/0011_auto_20190627_1528.py | 33 +- .../migrations/0011_auto_20190705_1258.py | 16 +- .../migrations/0012_auto_20190628_1113.py | 37 ++- .../migrations/0013_auto_20190628_1337.py | 42 ++- .../migrations/0014_auto_20190628_1338.py | 42 ++- .../migrations/0015_auto_20190628_1436.py | 44 ++- .../migrations/0016_auto_20190628_1437.py | 43 ++- .../migrations/0017_auto_20190628_1438.py | 42 ++- .../migrations/0018_merge_20190702_1247.py | 7 +- .../migrations/0019_merge_20190709_0910.py | 7 +- .../migrations/0020_auto_20190708_1243.py | 48 ++- .../migrations/0021_auto_20190711_1932.py | 89 +++-- .../migrations/0022_auto_20190711_1951.py | 41 ++- .../migrations/0023_auto_20190712_1023.py | 33 +- .../migrations/0024_auto_20190718_1438.py | 12 +- .../0025_homepage_external_promos.py | 31 +- .../migrations/0026_auto_20190813_1302.py | 14 +- .../migrations/0027_auto_20190813_1503.py | 66 +++- .../migrations/0028_auto_20190814_1600.py | 41 ++- developerportal/apps/home/models.py | 188 +++++++---- developerportal/apps/home/tests/test_home.py | 11 +- .../apps/mozimages/migrations/0001_initial.py | 147 ++++++-- developerportal/apps/mozimages/models.py | 12 +- developerportal/apps/people/edit_handlers.py | 4 +- .../apps/people/migrations/0001_initial.py | 75 +++-- .../apps/people/migrations/0002_people.py | 26 +- .../migrations/0003_auto_20190530_1437.py | 34 +- .../migrations/0004_auto_20190530_1441.py | 17 +- .../migrations/0005_person_is_mozillian.py | 10 +- .../migrations/0006_auto_20190604_1050.py | 21 +- .../migrations/0007_auto_20190611_1556.py | 49 ++- .../people/migrations/0008_featuredperson.py | 46 ++- .../migrations/0009_auto_20190625_1122.py | 28 +- .../migrations/0009_auto_20190626_0848.py | 9 +- .../migrations/0009_auto_20190626_1353.py | 9 +- .../migrations/0010_auto_20190625_1258.py | 9 +- .../migrations/0010_merge_20190627_1318.py | 7 +- .../migrations/0011_merge_20190627_1428.py | 7 +- .../migrations/0012_auto_20190702_1059.py | 12 +- .../migrations/0012_merge_20190628_1108.py | 7 +- .../migrations/0013_merge_20190702_1247.py | 7 +- .../migrations/0013_merge_20190702_1300.py | 7 +- .../migrations/0014_merge_20190702_1619.py | 7 +- .../migrations/0015_auto_20190709_0928.py | 9 +- .../migrations/0016_auto_20190711_1915.py | 115 ++++--- .../migrations/0017_auto_20190718_1424.py | 42 ++- .../people/migrations/0018_people_keywords.py | 18 +- .../migrations/0019_remove_people_keywords.py | 11 +- .../people/migrations/0020_people_keywords.py | 18 +- .../migrations/0021_auto_20190731_1057.py | 24 +- .../migrations/0022_people_description.py | 14 +- .../people/migrations/0022_person_websites.py | 35 +- .../migrations/0023_merge_20190802_1535.py | 7 +- .../migrations/0024_auto_20190813_1302.py | 14 +- .../migrations/0025_auto_20190813_1503.py | 56 +++- .../migrations/0026_auto_20190819_1304.py | 17 +- developerportal/apps/people/models.py | 255 +++++++------- developerportal/apps/people/wagtail_hooks.py | 2 +- .../staticbuild/migrations/0001_initial.py | 17 +- .../migrations/0002_staticbuild_date.py | 14 +- developerportal/apps/staticbuild/models.py | 5 +- .../apps/staticbuild/wagtail_hooks.py | 12 +- .../apps/topics/migrations/0001_initial.py | 24 +- .../apps/topics/migrations/0002_topics.py | 26 +- .../apps/topics/migrations/0003_subtopic.py | 26 +- .../migrations/0004_topicfeaturedarticle.py | 46 ++- .../migrations/0005_auto_20190610_1413.py | 14 +- .../migrations/0006_auto_20190611_1453.py | 54 ++- .../migrations/0007_auto_20190611_1542.py | 10 +- .../migrations/0008_auto_20190612_1759.py | 12 +- .../topics/migrations/0009_topic_color.py | 21 +- .../migrations/0010_auto_20190618_0840.py | 12 +- .../migrations/0010_topic_get_started.py | 28 +- .../migrations/0011_auto_20190614_0932.py | 27 +- .../migrations/0012_auto_20190614_1319.py | 30 +- .../migrations/0013_merge_20190618_1635.py | 7 +- .../migrations/0013_merge_20190619_1357.py | 7 +- .../apps/topics/migrations/0013_topic_icon.py | 12 +- .../migrations/0014_merge_20190618_1609.py | 7 +- .../migrations/0015_merge_20190619_1437.py | 7 +- .../migrations/0015_merge_20190619_1506.py | 7 +- .../migrations/0015_merge_20190621_1009.py | 9 +- .../migrations/0016_auto_20190619_1437.py | 12 +- .../migrations/0016_auto_20190619_1506.py | 12 +- .../migrations/0016_auto_20190624_1129.py | 12 +- .../migrations/0017_merge_20190621_1033.py | 7 +- .../migrations/0017_merge_20190624_0904.py | 7 +- .../migrations/0018_merge_20190624_1248.py | 7 +- .../migrations/0018_merge_20190624_1252.py | 7 +- .../migrations/0019_merge_20190625_1257.py | 7 +- .../migrations/0020_auto_20190701_1104.py | 39 ++- .../migrations/0020_auto_20190702_1401.py | 36 +- .../topics/migrations/0020_topic_featured.py | 42 ++- .../migrations/0021_auto_20190701_1105.py | 36 +- .../migrations/0021_auto_20190702_1402.py | 30 +- .../migrations/0022_auto_20190702_1123.py | 30 +- .../migrations/0023_auto_20190702_1318.py | 36 +- .../migrations/0024_merge_20190702_1619.py | 7 +- .../migrations/0025_auto_20190702_1620.py | 39 ++- .../migrations/0026_merge_20190704_1459.py | 7 +- .../migrations/0027_auto_20190709_0928.py | 9 +- .../migrations/0027_auto_20190710_1339.py | 33 +- .../migrations/0028_merge_20190710_1633.py | 7 +- .../migrations/0029_auto_20190711_1917.py | 85 +++-- .../migrations/0030_auto_20190711_1951.py | 37 ++- .../migrations/0031_auto_20190718_1424.py | 137 ++++++-- .../migrations/0033_auto_20190718_1452.py | 16 +- .../migrations/0034_auto_20190718_1504.py | 43 ++- .../migrations/0035_auto_20190725_1225.py | 75 ++++- .../migrations/0036_auto_20190725_1226.py | 43 ++- .../migrations/0037_auto_20190730_1057.py | 51 ++- .../0038_topic_latest_articles_count.py | 14 +- .../migrations/0039_auto_20190805_0806.py | 16 +- .../migrations/0040_auto_20190813_1302.py | 18 +- .../migrations/0041_auto_20190813_1503.py | 88 ++++- .../migrations/0042_auto_20190814_1600.py | 41 ++- .../migrations/0043_auto_20190819_1304.py | 17 +- developerportal/apps/topics/models.py | 239 +++++++------ .../apps/topics/tests/test_topics.py | 11 +- developerportal/apps/topics/wagtail_hooks.py | 2 +- .../apps/videos/migrations/0001_initial.py | 283 ++++++++++++---- .../0002_video_related_links_mdn.py | 27 +- .../migrations/0003_auto_20190807_1244.py | 21 +- .../migrations/0004_auto_20190813_1302.py | 18 +- .../migrations/0005_auto_20190813_1503.py | 95 ++++-- .../migrations/0006_auto_20190814_1600.py | 24 +- .../migrations/0007_auto_20190819_1304.py | 17 +- developerportal/apps/videos/models.py | 224 +++++++------ developerportal/apps/videos/wagtail_hooks.py | 2 +- developerportal/context_processors.py | 17 +- developerportal/pipeline.py | 35 +- developerportal/settings/base.py | 287 ++++++++-------- developerportal/settings/build.py | 4 +- developerportal/settings/dev.py | 4 +- developerportal/templatetags/app_filters.py | 16 +- developerportal/templatetags/app_tags.py | 6 +- developerportal/urls.py | 24 +- manage.py | 1 + 251 files changed, 6682 insertions(+), 3428 deletions(-) diff --git a/developerportal/apps/articles/migrations/0001_initial.py b/developerportal/apps/articles/migrations/0001_initial.py index b02f1d5e9..aaf4ebee8 100644 --- a/developerportal/apps/articles/migrations/0001_initial.py +++ b/developerportal/apps/articles/migrations/0001_initial.py @@ -9,18 +9,26 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural") ] operations = [ migrations.CreateModel( - name='Article', + name="Article", 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')), + ( + "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", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), - ), + options={"abstract": False}, + bases=("wagtailcore.page",), + ) ] diff --git a/developerportal/apps/articles/migrations/0002_article_body.py b/developerportal/apps/articles/migrations/0002_article_body.py index c862d524c..a86d1eff8 100644 --- a/developerportal/apps/articles/migrations/0002_article_body.py +++ b/developerportal/apps/articles/migrations/0002_article_body.py @@ -8,14 +8,18 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0001_initial'), - ] + dependencies = [("articles", "0001_initial")] operations = [ migrations.AddField( - model_name='article', - name='body', - field=wagtail.core.fields.StreamField([('paragraph', wagtail.core.blocks.RichTextBlock()), ('image', wagtail.images.blocks.ImageChooserBlock())], default=None), - ), + model_name="article", + name="body", + field=wagtail.core.fields.StreamField( + [ + ("paragraph", wagtail.core.blocks.RichTextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ], + default=None, + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0002_article_date.py b/developerportal/apps/articles/migrations/0002_article_date.py index 0e5bd1601..e5bd9e61b 100644 --- a/developerportal/apps/articles/migrations/0002_article_date.py +++ b/developerportal/apps/articles/migrations/0002_article_date.py @@ -6,14 +6,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0001_initial'), - ] + dependencies = [("articles", "0001_initial")] operations = [ migrations.AddField( - model_name='article', - name='date', - field=models.DateField(default=datetime.date.today, verbose_name='Article date'), - ), + model_name="article", + name="date", + field=models.DateField( + default=datetime.date.today, verbose_name="Article date" + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0003_article_intro.py b/developerportal/apps/articles/migrations/0003_article_intro.py index d0d07c798..87af26cc2 100644 --- a/developerportal/apps/articles/migrations/0003_article_intro.py +++ b/developerportal/apps/articles/migrations/0003_article_intro.py @@ -6,14 +6,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0002_article_date'), - ] + dependencies = [("articles", "0002_article_date")] operations = [ migrations.AddField( - model_name='article', - name='intro', - field=wagtail.core.fields.RichTextField(default=None, verbose_name='Intro'), - ), + model_name="article", + name="intro", + field=wagtail.core.fields.RichTextField(default=None, verbose_name="Intro"), + ) ] diff --git a/developerportal/apps/articles/migrations/0003_auto_20190517_1038.py b/developerportal/apps/articles/migrations/0003_auto_20190517_1038.py index 3a1161f07..35757e598 100644 --- a/developerportal/apps/articles/migrations/0003_auto_20190517_1038.py +++ b/developerportal/apps/articles/migrations/0003_auto_20190517_1038.py @@ -8,14 +8,32 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0002_article_body'), - ] + dependencies = [("articles", "0002_article_body")] operations = [ migrations.AlterField( - model_name='article', - name='body', - field=developerportal.apps.common.fields.CustomStreamField([('paragraph', wagtail.core.blocks.RichTextBlock(features=('bold', 'italic', 'link', 'ol', 'ul', 'blockquote', 'code', 'hr'))), ('image', wagtail.images.blocks.ImageChooserBlock())], default=None), - ), + model_name="article", + name="body", + field=developerportal.apps.common.fields.CustomStreamField( + [ + ( + "paragraph", + wagtail.core.blocks.RichTextBlock( + features=( + "bold", + "italic", + "link", + "ol", + "ul", + "blockquote", + "code", + "hr", + ) + ), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ], + default=None, + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0004_auto_20190516_0907.py b/developerportal/apps/articles/migrations/0004_auto_20190516_0907.py index 55e52dfb1..9fa33c1c7 100644 --- a/developerportal/apps/articles/migrations/0004_auto_20190516_0907.py +++ b/developerportal/apps/articles/migrations/0004_auto_20190516_0907.py @@ -6,14 +6,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0003_article_intro'), - ] + dependencies = [("articles", "0003_article_intro")] operations = [ migrations.AlterField( - model_name='article', - name='intro', - field=wagtail.core.fields.RichTextField(default='', verbose_name='Intro'), - ), + model_name="article", + name="intro", + field=wagtail.core.fields.RichTextField(default="", verbose_name="Intro"), + ) ] diff --git a/developerportal/apps/articles/migrations/0005_auto_20190516_1236.py b/developerportal/apps/articles/migrations/0005_auto_20190516_1236.py index c34b4a940..08a793ff8 100644 --- a/developerportal/apps/articles/migrations/0005_auto_20190516_1236.py +++ b/developerportal/apps/articles/migrations/0005_auto_20190516_1236.py @@ -5,17 +5,9 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0004_auto_20190516_0907'), - ] + dependencies = [("articles", "0004_auto_20190516_0907")] operations = [ - migrations.RemoveField( - model_name='article', - name='date', - ), - migrations.RemoveField( - model_name='article', - name='intro', - ), + migrations.RemoveField(model_name="article", name="date"), + migrations.RemoveField(model_name="article", name="intro"), ] diff --git a/developerportal/apps/articles/migrations/0006_auto_20190516_1303.py b/developerportal/apps/articles/migrations/0006_auto_20190516_1303.py index d99f63d23..e9c0093c4 100644 --- a/developerportal/apps/articles/migrations/0006_auto_20190516_1303.py +++ b/developerportal/apps/articles/migrations/0006_auto_20190516_1303.py @@ -7,19 +7,19 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0005_auto_20190516_1236'), - ] + dependencies = [("articles", "0005_auto_20190516_1236")] operations = [ migrations.AddField( - model_name='article', - name='date', - field=models.DateField(default=datetime.date.today, verbose_name='Article date'), + model_name="article", + name="date", + field=models.DateField( + default=datetime.date.today, verbose_name="Article date" + ), ), migrations.AddField( - model_name='article', - name='intro', - field=wagtail.core.fields.RichTextField(default='', verbose_name='Intro'), + model_name="article", + name="intro", + field=wagtail.core.fields.RichTextField(default="", verbose_name="Intro"), ), ] diff --git a/developerportal/apps/articles/migrations/0007_merge_20190517_1323.py b/developerportal/apps/articles/migrations/0007_merge_20190517_1323.py index 642665144..871cd1cfc 100644 --- a/developerportal/apps/articles/migrations/0007_merge_20190517_1323.py +++ b/developerportal/apps/articles/migrations/0007_merge_20190517_1323.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('articles', '0006_auto_20190516_1303'), - ('articles', '0003_auto_20190517_1038'), + ("articles", "0006_auto_20190516_1303"), + ("articles", "0003_auto_20190517_1038"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/articles/migrations/0008_auto_20190521_0851.py b/developerportal/apps/articles/migrations/0008_auto_20190521_0851.py index a287e477a..9aa804d45 100644 --- a/developerportal/apps/articles/migrations/0008_auto_20190521_0851.py +++ b/developerportal/apps/articles/migrations/0008_auto_20190521_0851.py @@ -9,25 +9,51 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('articles', '0007_merge_20190517_1323'), + ("taggit", "0002_auto_20150616_2121"), + ("articles", "0007_merge_20190517_1323"), ] operations = [ migrations.CreateModel( - name='ArticleTag', + name="ArticleTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='articles.Article')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles_articletag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="articles.Article", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="articles_articletag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='article', - name='tags', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='articles.ArticleTag', to='taggit.Tag', verbose_name='Tags'), + model_name="article", + name="tags", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="articles.ArticleTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/articles/migrations/0009_auto_20190521_1048.py b/developerportal/apps/articles/migrations/0009_auto_20190521_1048.py index abf345b52..3ce6339f6 100644 --- a/developerportal/apps/articles/migrations/0009_auto_20190521_1048.py +++ b/developerportal/apps/articles/migrations/0009_auto_20190521_1048.py @@ -9,24 +9,35 @@ class Migration(migrations.Migration): dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), - ('articles', '0008_auto_20190521_0851'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), + ("articles", "0008_auto_20190521_0851"), ] operations = [ migrations.CreateModel( - name='Articles', + name="Articles", 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')), + ( + "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", + ), + ) ], - options={ - 'abstract': False, - }, - bases=(wagtail.contrib.routable_page.models.RoutablePageMixin, 'wagtailcore.page'), + options={"abstract": False}, + bases=( + wagtail.contrib.routable_page.models.RoutablePageMixin, + "wagtailcore.page", + ), ), migrations.AlterField( - model_name='article', - name='intro', - field=wagtail.core.fields.RichTextField(default=''), + model_name="article", + name="intro", + field=wagtail.core.fields.RichTextField(default=""), ), ] diff --git a/developerportal/apps/articles/migrations/0010_article_labels.py b/developerportal/apps/articles/migrations/0010_article_labels.py index 8cc73d9a9..9c159890e 100644 --- a/developerportal/apps/articles/migrations/0010_article_labels.py +++ b/developerportal/apps/articles/migrations/0010_article_labels.py @@ -6,15 +6,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0001_initial'), - ('articles', '0009_auto_20190521_1048'), - ] + dependencies = [("topics", "0001_initial"), ("articles", "0009_auto_20190521_1048")] operations = [ migrations.AddField( - model_name='article', - name='labels', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='topics.Topic'), - ), + model_name="article", + name="labels", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="topics.Topic", + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0011_auto_20190522_1630.py b/developerportal/apps/articles/migrations/0011_auto_20190522_1630.py index 3b05c2474..7b29d0756 100644 --- a/developerportal/apps/articles/migrations/0011_auto_20190522_1630.py +++ b/developerportal/apps/articles/migrations/0011_auto_20190522_1630.py @@ -6,19 +6,15 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0001_initial'), - ('articles', '0010_article_labels'), - ] + dependencies = [("topics", "0001_initial"), ("articles", "0010_article_labels")] operations = [ - migrations.RemoveField( - model_name='article', - name='labels', - ), + migrations.RemoveField(model_name="article", name="labels"), migrations.AddField( - model_name='article', - name='labels', - field=modelcluster.fields.ParentalManyToManyField(blank=True, related_name='_article_labels_+', to='topics.Topic'), + model_name="article", + name="labels", + field=modelcluster.fields.ParentalManyToManyField( + blank=True, related_name="_article_labels_+", to="topics.Topic" + ), ), ] diff --git a/developerportal/apps/articles/migrations/0012_article_author.py b/developerportal/apps/articles/migrations/0012_article_author.py index ef954f7b6..d98270aae 100644 --- a/developerportal/apps/articles/migrations/0012_article_author.py +++ b/developerportal/apps/articles/migrations/0012_article_author.py @@ -7,14 +7,20 @@ class Migration(migrations.Migration): dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), - ('articles', '0011_auto_20190522_1630'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), + ("articles", "0011_auto_20190522_1630"), ] operations = [ migrations.AddField( - model_name='article', - name='author', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.Page'), - ), + model_name="article", + name="author", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailcore.Page", + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0012_article_header_image.py b/developerportal/apps/articles/migrations/0012_article_header_image.py index 688542afe..6e6c5b03f 100644 --- a/developerportal/apps/articles/migrations/0012_article_header_image.py +++ b/developerportal/apps/articles/migrations/0012_article_header_image.py @@ -7,14 +7,20 @@ class Migration(migrations.Migration): dependencies = [ - ('wagtailimages', '0001_squashed_0021'), - ('articles', '0011_auto_20190522_1630'), + ("wagtailimages", "0001_squashed_0021"), + ("articles", "0011_auto_20190522_1630"), ] operations = [ migrations.AddField( - model_name='article', - name='header_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.Image'), - ), + model_name="article", + name="header_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailimages.Image", + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0012_auto_20190603_1048.py b/developerportal/apps/articles/migrations/0012_auto_20190603_1048.py index a3e9a9863..93f601ecf 100644 --- a/developerportal/apps/articles/migrations/0012_auto_20190603_1048.py +++ b/developerportal/apps/articles/migrations/0012_auto_20190603_1048.py @@ -7,18 +7,17 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0003_subtopic'), - ('articles', '0011_auto_20190522_1630'), + ("topics", "0003_subtopic"), + ("articles", "0011_auto_20190522_1630"), ] operations = [ - migrations.RemoveField( - model_name='article', - name='labels', - ), + migrations.RemoveField(model_name="article", name="labels"), migrations.AddField( - model_name='article', - name='topics', - field=modelcluster.fields.ParentalManyToManyField(blank=True, related_name='_article_topics_+', to='topics.Topic'), + model_name="article", + name="topics", + field=modelcluster.fields.ParentalManyToManyField( + blank=True, related_name="_article_topics_+", to="topics.Topic" + ), ), ] diff --git a/developerportal/apps/articles/migrations/0013_merge_20190603_1229.py b/developerportal/apps/articles/migrations/0013_merge_20190603_1229.py index 45580f744..20bce10cb 100644 --- a/developerportal/apps/articles/migrations/0013_merge_20190603_1229.py +++ b/developerportal/apps/articles/migrations/0013_merge_20190603_1229.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('articles', '0012_article_header_image'), - ('articles', '0012_article_author'), + ("articles", "0012_article_header_image"), + ("articles", "0012_article_author"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/articles/migrations/0014_merge_20190604_0953.py b/developerportal/apps/articles/migrations/0014_merge_20190604_0953.py index a206cdc1b..fc8cd0648 100644 --- a/developerportal/apps/articles/migrations/0014_merge_20190604_0953.py +++ b/developerportal/apps/articles/migrations/0014_merge_20190604_0953.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('articles', '0012_auto_20190603_1048'), - ('articles', '0013_merge_20190603_1229'), + ("articles", "0012_auto_20190603_1048"), + ("articles", "0013_merge_20190603_1229"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/articles/migrations/0015_auto_20190604_1245.py b/developerportal/apps/articles/migrations/0015_auto_20190604_1245.py index ec0a25edd..2cf29fe06 100644 --- a/developerportal/apps/articles/migrations/0015_auto_20190604_1245.py +++ b/developerportal/apps/articles/migrations/0015_auto_20190604_1245.py @@ -8,26 +8,46 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0003_subtopic'), - ('articles', '0014_merge_20190604_0953'), + ("topics", "0003_subtopic"), + ("articles", "0014_merge_20190604_0953"), ] operations = [ - migrations.RemoveField( - model_name='article', - name='topics', - ), + migrations.RemoveField(model_name="article", name="topics"), migrations.CreateModel( - name='ArticleTopic', + name="ArticleTopic", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='articles.Article')), - ('topic', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="articles.Article", + ), + ), + ( + "topic", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/articles/migrations/0016_auto_20190604_1317.py b/developerportal/apps/articles/migrations/0016_auto_20190604_1317.py index 90857dc7e..fd04f8bd7 100644 --- a/developerportal/apps/articles/migrations/0016_auto_20190604_1317.py +++ b/developerportal/apps/articles/migrations/0016_auto_20190604_1317.py @@ -6,14 +6,16 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0015_auto_20190604_1245'), - ] + dependencies = [("articles", "0015_auto_20190604_1245")] operations = [ migrations.AlterField( - model_name='articletopic', - name='topic', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='topics.Topic'), - ), + model_name="articletopic", + name="topic", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="topics.Topic", + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0017_auto_20190611_1344.py b/developerportal/apps/articles/migrations/0017_auto_20190611_1344.py index 6de68be29..f838c3dcb 100644 --- a/developerportal/apps/articles/migrations/0017_auto_20190611_1344.py +++ b/developerportal/apps/articles/migrations/0017_auto_20190611_1344.py @@ -6,14 +6,18 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0016_auto_20190604_1317'), - ] + dependencies = [("articles", "0016_auto_20190604_1317")] operations = [ migrations.AlterField( - model_name='article', - name='author', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='articles', to='people.Person'), - ), + model_name="article", + name="author", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="articles", + to="people.Person", + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0018_auto_20190611_1403.py b/developerportal/apps/articles/migrations/0018_auto_20190611_1403.py index dd1864399..5beddf8ce 100644 --- a/developerportal/apps/articles/migrations/0018_auto_20190611_1403.py +++ b/developerportal/apps/articles/migrations/0018_auto_20190611_1403.py @@ -8,26 +8,45 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0006_auto_20190604_1050'), - ('articles', '0017_auto_20190611_1344'), + ("people", "0006_auto_20190604_1050"), + ("articles", "0017_auto_20190611_1344"), ] operations = [ - migrations.RemoveField( - model_name='article', - name='author', - ), + migrations.RemoveField(model_name="article", name="author"), migrations.CreateModel( - name='ArticleAuthor', + name="ArticleAuthor", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='authors', to='articles.Article')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="authors", + to="articles.Article", + ), + ), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="articles", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/articles/migrations/0019_auto_20190611_1453.py b/developerportal/apps/articles/migrations/0019_auto_20190611_1453.py index 233cac5c5..734d034a4 100644 --- a/developerportal/apps/articles/migrations/0019_auto_20190611_1453.py +++ b/developerportal/apps/articles/migrations/0019_auto_20190611_1453.py @@ -6,14 +6,16 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0018_auto_20190611_1403'), - ] + dependencies = [("articles", "0018_auto_20190611_1403")] operations = [ migrations.AlterField( - model_name='articletopic', - name='topic', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='topics.Topic'), - ), + model_name="articletopic", + name="topic", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="topics.Topic", + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0020_auto_20190612_0426.py b/developerportal/apps/articles/migrations/0020_auto_20190612_0426.py index 984070422..b45fcacf1 100644 --- a/developerportal/apps/articles/migrations/0020_auto_20190612_0426.py +++ b/developerportal/apps/articles/migrations/0020_auto_20190612_0426.py @@ -5,13 +5,8 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0019_auto_20190611_1453'), - ] + dependencies = [("articles", "0019_auto_20190611_1453")] operations = [ - migrations.AlterModelOptions( - name='article', - options={'ordering': ['-date']}, - ), + migrations.AlterModelOptions(name="article", options={"ordering": ["-date"]}) ] diff --git a/developerportal/apps/articles/migrations/0021_auto_20190618_0840.py b/developerportal/apps/articles/migrations/0021_auto_20190618_0840.py index 1618c96e8..023700f63 100644 --- a/developerportal/apps/articles/migrations/0021_auto_20190618_0840.py +++ b/developerportal/apps/articles/migrations/0021_auto_20190618_0840.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0020_auto_20190612_0426'), - ] + dependencies = [("articles", "0020_auto_20190612_0426")] operations = [ migrations.AlterField( - model_name='article', - name='intro', - field=models.TextField(blank=True, default='', max_length=250), - ), + model_name="article", + name="intro", + field=models.TextField(blank=True, default="", max_length=250), + ) ] diff --git a/developerportal/apps/articles/migrations/0022_auto_20190624_1622.py b/developerportal/apps/articles/migrations/0022_auto_20190624_1622.py index 26dbae9f0..d096afc4c 100644 --- a/developerportal/apps/articles/migrations/0022_auto_20190624_1622.py +++ b/developerportal/apps/articles/migrations/0022_auto_20190624_1622.py @@ -7,14 +7,20 @@ class Migration(migrations.Migration): dependencies = [ - ('mozimages', '0001_initial'), - ('articles', '0021_auto_20190618_0840'), + ("mozimages", "0001_initial"), + ("articles", "0021_auto_20190618_0840"), ] operations = [ migrations.AlterField( - model_name='article', - name='header_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage'), - ), + model_name="article", + name="header_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0023_auto_20190709_0928.py b/developerportal/apps/articles/migrations/0023_auto_20190709_0928.py index 421b24a3a..e431e0b9b 100644 --- a/developerportal/apps/articles/migrations/0023_auto_20190709_0928.py +++ b/developerportal/apps/articles/migrations/0023_auto_20190709_0928.py @@ -5,13 +5,10 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0022_auto_20190624_1622'), - ] + dependencies = [("articles", "0022_auto_20190624_1622")] operations = [ migrations.AlterModelOptions( - name='articles', - options={'verbose_name_plural': 'Articles'}, - ), + name="articles", options={"verbose_name_plural": "Articles"} + ) ] diff --git a/developerportal/apps/articles/migrations/0024_auto_20190711_1222.py b/developerportal/apps/articles/migrations/0024_auto_20190711_1222.py index d279964ea..bbe733f4a 100644 --- a/developerportal/apps/articles/migrations/0024_auto_20190711_1222.py +++ b/developerportal/apps/articles/migrations/0024_auto_20190711_1222.py @@ -7,43 +7,45 @@ class Migration(migrations.Migration): dependencies = [ - ('mozimages', '0001_initial'), - ('articles', '0023_auto_20190709_0928'), + ("mozimages", "0001_initial"), + ("articles", "0023_auto_20190709_0928"), ] operations = [ - migrations.AlterModelOptions( - name='article', - options={}, - ), + migrations.AlterModelOptions(name="article", options={}), migrations.RenameField( - model_name='article', - old_name='intro', - new_name='description', + model_name="article", old_name="intro", new_name="description" ), migrations.RenameField( - model_name='article', - old_name='header_image', - new_name='image', + model_name="article", old_name="header_image", new_name="image" ), migrations.RenameField( - model_name='article', - old_name='tags', - new_name='keywords', + model_name="article", old_name="tags", new_name="keywords" ), migrations.AddField( - model_name='article', - name='card_description', - field=models.TextField(blank=True, default='', max_length=140, verbose_name='Description'), + model_name="article", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=140, verbose_name="Description" + ), ), migrations.AddField( - model_name='article', - name='card_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage', verbose_name='Image'), + model_name="article", + name="card_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + verbose_name="Image", + ), ), migrations.AddField( - model_name='article', - name='card_title', - field=models.CharField(blank=True, default='', max_length=140, verbose_name='Title'), + model_name="article", + name="card_title", + field=models.CharField( + blank=True, default="", max_length=140, verbose_name="Title" + ), ), ] diff --git a/developerportal/apps/articles/migrations/0025_auto_20190716_1346.py b/developerportal/apps/articles/migrations/0025_auto_20190716_1346.py index 62f26bbc0..bd83dc9d9 100644 --- a/developerportal/apps/articles/migrations/0025_auto_20190716_1346.py +++ b/developerportal/apps/articles/migrations/0025_auto_20190716_1346.py @@ -9,25 +9,51 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('articles', '0024_auto_20190711_1222'), + ("taggit", "0002_auto_20150616_2121"), + ("articles", "0024_auto_20190711_1222"), ] operations = [ migrations.CreateModel( - name='ArticlesTag', + name="ArticlesTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='articles.Articles')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles_articlestag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="articles.Articles", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="articles_articlestag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='articles', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='articles.ArticlesTag', to='taggit.Tag', verbose_name='Tags'), + model_name="articles", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="articles.ArticlesTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/articles/migrations/0026_articles_description.py b/developerportal/apps/articles/migrations/0026_articles_description.py index 9407e4560..a84cd4c8a 100644 --- a/developerportal/apps/articles/migrations/0026_articles_description.py +++ b/developerportal/apps/articles/migrations/0026_articles_description.py @@ -5,14 +5,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0025_auto_20190716_1346'), - ] + dependencies = [("articles", "0025_auto_20190716_1346")] operations = [ migrations.AddField( - model_name='articles', - name='description', - field=models.TextField(blank=True, default='', max_length=250, verbose_name='Description'), - ), + model_name="articles", + name="description", + field=models.TextField( + blank=True, default="", max_length=250, verbose_name="Description" + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0026_auto_20190731_1109.py b/developerportal/apps/articles/migrations/0026_auto_20190731_1109.py index 9599aaae4..efabd92bf 100644 --- a/developerportal/apps/articles/migrations/0026_auto_20190731_1109.py +++ b/developerportal/apps/articles/migrations/0026_auto_20190731_1109.py @@ -8,17 +8,39 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0025_auto_20190716_1346'), - ] + dependencies = [("articles", "0025_auto_20190716_1346")] operations = [ migrations.AddField( - model_name='article', - name='authors', - field=wagtail.core.fields.StreamField([('author', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'])), ('external_author', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('image', wagtail.images.blocks.ImageChooserBlock()), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))]))], blank=True, null=True), - ), - migrations.DeleteModel( - name='ArticleAuthor', + model_name="article", + name="authors", + field=wagtail.core.fields.StreamField( + [ + ( + "author", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"] + ), + ), + ( + "external_author", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + ), ), + migrations.DeleteModel(name="ArticleAuthor"), ] diff --git a/developerportal/apps/articles/migrations/0027_article_related_links_mdn.py b/developerportal/apps/articles/migrations/0027_article_related_links_mdn.py index a116ee226..b8398aef0 100644 --- a/developerportal/apps/articles/migrations/0027_article_related_links_mdn.py +++ b/developerportal/apps/articles/migrations/0027_article_related_links_mdn.py @@ -7,14 +7,27 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0026_auto_20190731_1109'), - ] + dependencies = [("articles", "0026_auto_20190731_1109")] operations = [ migrations.AddField( - model_name='article', - name='related_links_mdn', - field=wagtail.core.fields.StreamField([('link', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('url', wagtail.core.blocks.URLBlock())]))], blank=True, null=True, verbose_name='Related MDN links'), - ), + model_name="article", + name="related_links_mdn", + field=wagtail.core.fields.StreamField( + [ + ( + "link", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("url", wagtail.core.blocks.URLBlock()), + ] + ), + ) + ], + blank=True, + null=True, + verbose_name="Related MDN links", + ), + ) ] diff --git a/developerportal/apps/articles/migrations/0027_merge_20190802_1535.py b/developerportal/apps/articles/migrations/0027_merge_20190802_1535.py index 42d790718..a0bebbc04 100644 --- a/developerportal/apps/articles/migrations/0027_merge_20190802_1535.py +++ b/developerportal/apps/articles/migrations/0027_merge_20190802_1535.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('articles', '0026_auto_20190731_1109'), - ('articles', '0026_articles_description'), + ("articles", "0026_auto_20190731_1109"), + ("articles", "0026_articles_description"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/articles/migrations/0028_merge_20190805_1426.py b/developerportal/apps/articles/migrations/0028_merge_20190805_1426.py index f82276add..66e983753 100644 --- a/developerportal/apps/articles/migrations/0028_merge_20190805_1426.py +++ b/developerportal/apps/articles/migrations/0028_merge_20190805_1426.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('articles', '0027_merge_20190802_1535'), - ('articles', '0027_article_related_links_mdn'), + ("articles", "0027_merge_20190802_1535"), + ("articles", "0027_article_related_links_mdn"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/articles/migrations/0029_auto_20190813_1302.py b/developerportal/apps/articles/migrations/0029_auto_20190813_1302.py index 327156ed8..e19a81829 100644 --- a/developerportal/apps/articles/migrations/0029_auto_20190813_1302.py +++ b/developerportal/apps/articles/migrations/0029_auto_20190813_1302.py @@ -5,19 +5,19 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0028_merge_20190805_1426'), - ] + dependencies = [("articles", "0028_merge_20190805_1426")] operations = [ migrations.AlterField( - model_name='article', - name='card_description', - field=models.TextField(blank=True, default='', max_length=400, verbose_name='Description'), + model_name="article", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=400, verbose_name="Description" + ), ), migrations.AlterField( - model_name='article', - name='description', - field=models.TextField(blank=True, default='', max_length=400), + model_name="article", + name="description", + field=models.TextField(blank=True, default="", max_length=400), ), ] diff --git a/developerportal/apps/articles/migrations/0030_auto_20190813_1503.py b/developerportal/apps/articles/migrations/0030_auto_20190813_1503.py index 401b399ff..49618acf4 100644 --- a/developerportal/apps/articles/migrations/0030_auto_20190813_1503.py +++ b/developerportal/apps/articles/migrations/0030_auto_20190813_1503.py @@ -11,39 +11,168 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0029_auto_20190813_1302'), - ] + dependencies = [("articles", "0029_auto_20190813_1302")] operations = [ migrations.AlterField( - model_name='article', - name='authors', - field=wagtail.core.fields.StreamField([('author', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'])), ('external_author', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('image', wagtail.images.blocks.ImageChooserBlock()), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))]))], blank=True, help_text='Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a profile on the system', null=True), + model_name="article", + name="authors", + field=wagtail.core.fields.StreamField( + [ + ( + "author", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"] + ), + ), + ( + "external_author", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ] + ), + ), + ], + blank=True, + help_text="Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a profile on the system", + null=True, + ), ), migrations.AlterField( - model_name='article', - name='body', - field=developerportal.apps.common.fields.CustomStreamField([('paragraph', wagtail.core.blocks.RichTextBlock(features=('h2', 'h3', 'h4', 'bold', 'italic', 'link', 'ol', 'ul', 'blockquote', 'code', 'hr'))), ('image', wagtail.images.blocks.ImageChooserBlock()), ('button', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(help_text='External URL to link to instead of a page.', required=False))])), ('embed', wagtail.embeds.blocks.EmbedBlock()), ('embed_html', wagtail.core.blocks.RawHTMLBlock(help_text='Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. This field is meant solely for third-party embeds.')), ('code_snippet', wagtail.core.blocks.StructBlock([('language', wagtail.core.blocks.ChoiceBlock(choices=[('css', 'CSS'), ('go', 'Go'), ('html', 'HTML'), ('js', 'JavaScript'), ('python', 'Python'), ('rust', 'Rust'), ('ts', 'TypeScript')])), ('code', wagtail.core.blocks.TextBlock())]))], default=None, help_text='The main article content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets'), + model_name="article", + name="body", + field=developerportal.apps.common.fields.CustomStreamField( + [ + ( + "paragraph", + wagtail.core.blocks.RichTextBlock( + features=( + "h2", + "h3", + "h4", + "bold", + "italic", + "link", + "ol", + "ul", + "blockquote", + "code", + "hr", + ) + ), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "button", + wagtail.core.blocks.StructBlock( + [ + ("text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock( + help_text="External URL to link to instead of a page.", + required=False, + ), + ), + ] + ), + ), + ("embed", wagtail.embeds.blocks.EmbedBlock()), + ( + "embed_html", + wagtail.core.blocks.RawHTMLBlock( + help_text="Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. This field is meant solely for third-party embeds." + ), + ), + ( + "code_snippet", + wagtail.core.blocks.StructBlock( + [ + ( + "language", + wagtail.core.blocks.ChoiceBlock( + choices=[ + ("css", "CSS"), + ("go", "Go"), + ("html", "HTML"), + ("js", "JavaScript"), + ("python", "Python"), + ("rust", "Rust"), + ("ts", "TypeScript"), + ] + ), + ), + ("code", wagtail.core.blocks.TextBlock()), + ] + ), + ), + ], + default=None, + help_text="The main article content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets", + ), ), migrations.AlterField( - model_name='article', - name='date', - field=models.DateField(default=datetime.date.today, help_text='The date the article was published', verbose_name='Article date'), + model_name="article", + name="date", + field=models.DateField( + default=datetime.date.today, + help_text="The date the article was published", + verbose_name="Article date", + ), ), migrations.AlterField( - model_name='article', - name='description', - field=models.TextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="article", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), migrations.AlterField( - model_name='article', - name='related_links_mdn', - field=wagtail.core.fields.StreamField([('link', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('url', wagtail.core.blocks.URLBlock())]))], blank=True, help_text='Optional links to MDN Web Docs for further reading', null=True, verbose_name='Related MDN links'), + model_name="article", + name="related_links_mdn", + field=wagtail.core.fields.StreamField( + [ + ( + "link", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("url", wagtail.core.blocks.URLBlock()), + ] + ), + ) + ], + blank=True, + help_text="Optional links to MDN Web Docs for further reading", + null=True, + verbose_name="Related MDN links", + ), ), migrations.AlterField( - model_name='articles', - name='description', - field=models.TextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="articles", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), ] diff --git a/developerportal/apps/articles/migrations/0031_auto_20190819_1304.py b/developerportal/apps/articles/migrations/0031_auto_20190819_1304.py index e7629c446..b0dabd43e 100644 --- a/developerportal/apps/articles/migrations/0031_auto_20190819_1304.py +++ b/developerportal/apps/articles/migrations/0031_auto_20190819_1304.py @@ -6,19 +6,27 @@ class Migration(migrations.Migration): - dependencies = [ - ('articles', '0030_auto_20190813_1503'), - ] + dependencies = [("articles", "0030_auto_20190813_1503")] operations = [ migrations.AlterField( - model_name='article', - name='description', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="article", + name="description", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), migrations.AlterField( - model_name='articles', - name='description', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="articles", + name="description", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), ] diff --git a/developerportal/apps/articles/models.py b/developerportal/apps/articles/models.py index a318de55d..de48b0fe1 100644 --- a/developerportal/apps/articles/models.py +++ b/developerportal/apps/articles/models.py @@ -2,7 +2,14 @@ import datetime import readtime -from django.db.models import CASCADE, CharField, DateField, ForeignKey, SET_NULL, TextField +from django.db.models import ( + CASCADE, + CharField, + DateField, + ForeignKey, + SET_NULL, + TextField, +) from wagtail.admin.edit_handlers import ( FieldPanel, @@ -29,20 +36,22 @@ class ArticlesTag(TaggedItemBase): - content_object = ParentalKey('Articles', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Articles", on_delete=CASCADE, related_name="tagged_items" + ) class Articles(Page): - parent_page_types = ['home.HomePage'] - subpage_types = ['Article'] - template = 'articles.html' + parent_page_types = ["home.HomePage"] + subpage_types = ["Article"] + template = "articles.html" # Content fields description = RichTextField( blank=True, - default='', + default="", features=RICH_TEXT_FEATURES_SIMPLE, - help_text='Optional short text description, max. 400 characters', + help_text="Optional short text description, max. 400 characters", max_length=400, ) @@ -50,33 +59,34 @@ class Articles(Page): keywords = ClusterTaggableManager(through=ArticlesTag, blank=True) # Content panels - content_panels = Page.content_panels + [ - FieldPanel('description'), - ] + content_panels = Page.content_panels + [FieldPanel("description")] # Meta panels meta_panels = [ - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ) ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - FieldPanel('show_in_menus'), - ] - - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + settings_panels = [FieldPanel("slug"), FieldPanel("show_in_menus")] + + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) class Meta: - verbose_name_plural = 'Articles' + verbose_name_plural = "Articles" @classmethod def can_create_at(cls, parent): @@ -85,7 +95,7 @@ def can_create_at(cls, parent): def get_context(self, request): context = super().get_context(request) - context['filters'] = self.get_filters() + context["filters"] = self.get_filters() return context @property @@ -94,136 +104,152 @@ def articles(self): def get_filters(self): from ..topics.models import Topic + return { - 'months': True, - 'topics': Topic.objects.live().public().order_by('title'), + "months": True, + "topics": Topic.objects.live().public().order_by("title"), } class ArticleTag(TaggedItemBase): - content_object = ParentalKey('Article', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Article", on_delete=CASCADE, related_name="tagged_items" + ) class ArticleTopic(Orderable): - article = ParentalKey('Article', related_name='topics') - topic = ForeignKey('topics.Topic', on_delete=CASCADE, related_name='+') + article = ParentalKey("Article", related_name="topics") + topic = ForeignKey("topics.Topic", on_delete=CASCADE, related_name="+") - panels = [ - PageChooserPanel('topic'), - ] + panels = [PageChooserPanel("topic")] class Article(Page): - resource_type = 'article' - parent_page_types = ['Articles'] + resource_type = "article" + parent_page_types = ["Articles"] subpage_types = [] - template = 'article.html' + template = "article.html" # Content fields description = RichTextField( blank=True, - default='', + default="", features=RICH_TEXT_FEATURES_SIMPLE, - help_text='Optional short text description, max. 400 characters', + help_text="Optional short text description, max. 400 characters", max_length=400, ) image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', + related_name="+", + ) + body = CustomStreamField( + help_text=( + "The main article content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets" + ) ) - body = CustomStreamField(help_text=( - 'The main article content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets' - )) related_links_mdn = StreamField( - StreamBlock([ - ('link', ExternalLinkBlock()) - ], required=False), + StreamBlock([("link", ExternalLinkBlock())], required=False), blank=True, null=True, - help_text='Optional links to MDN Web Docs for further reading', - verbose_name='Related MDN links', + help_text="Optional links to MDN Web Docs for further reading", + verbose_name="Related MDN links", ) # Card fields - card_title = CharField('Title', max_length=140, blank=True, default='') - card_description = TextField('Description', max_length=400, blank=True, default='') + card_title = CharField("Title", max_length=140, blank=True, default="") + card_description = TextField("Description", max_length=400, blank=True, default="") card_image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', - verbose_name='Image', + related_name="+", + verbose_name="Image", ) # Meta fields - date = DateField('Article date', default=datetime.date.today, help_text='The date the article was published') + date = DateField( + "Article date", + default=datetime.date.today, + help_text="The date the article was published", + ) authors = StreamField( - StreamBlock([ - ('author', PageChooserBlock(target_model='people.Person')), - ('external_author', ExternalAuthorBlock()), - ], required=False), + StreamBlock( + [ + ("author", PageChooserBlock(target_model="people.Person")), + ("external_author", ExternalAuthorBlock()), + ], + required=False, + ), blank=True, null=True, help_text=( - 'Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a ' - 'profile on the system' + "Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a " + "profile on the system" ), ) keywords = ClusterTaggableManager(through=ArticleTag, blank=True) # Content panels content_panels = Page.content_panels + [ - FieldPanel('description'), - MultiFieldPanel([ - ImageChooserPanel('image'), - ], heading='Image', help_text=( - 'Optional header image. If not specified a fallback will be used. This image is also shown when sharing ' - 'this page via social media' - )), - StreamFieldPanel('body'), - StreamFieldPanel('related_links_mdn'), + FieldPanel("description"), + MultiFieldPanel( + [ImageChooserPanel("image")], + heading="Image", + help_text=( + "Optional header image. If not specified a fallback will be used. This image is also shown when sharing " + "this page via social media" + ), + ), + StreamFieldPanel("body"), + StreamFieldPanel("related_links_mdn"), ] # Card panels card_panels = [ - FieldPanel('card_title'), - FieldPanel('card_description'), - ImageChooserPanel('card_image'), + FieldPanel("card_title"), + FieldPanel("card_description"), + ImageChooserPanel("card_image"), ] # Meta panels meta_panels = [ - FieldPanel('date'), - StreamFieldPanel('authors'), - MultiFieldPanel([ - InlinePanel('topics'), - ], heading='Topics', help_text=( - 'The topic pages this article will appear on. The first topic in the list will be treated as the ' - 'primary topic and will be shown in the page’s related content.' - )), - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + FieldPanel("date"), + StreamFieldPanel("authors"), + MultiFieldPanel( + [InlinePanel("topics")], + heading="Topics", + help_text=( + "The topic pages this article will appear on. The first topic in the list will be treated as the " + "primary topic and will be shown in the page’s related content." + ), + ), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ), ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - ] + settings_panels = [FieldPanel("slug")] # Tabs - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) # Rss feed def get_absolute_url(self): @@ -252,6 +278,6 @@ def month_group(self): def has_author(self, person): for author in self.authors: # pylint: disable=not-an-iterable - if (author.block_type == 'author' and str(author.value) == str(person.title)): + if author.block_type == "author" and str(author.value) == str(person.title): return True return False diff --git a/developerportal/apps/articles/tests/test_articles.py b/developerportal/apps/articles/tests/test_articles.py index 606a6a299..d28eea0ac 100644 --- a/developerportal/apps/articles/tests/test_articles.py +++ b/developerportal/apps/articles/tests/test_articles.py @@ -7,18 +7,21 @@ class ArticleTests(WagtailPageTests): """Tests for the Article page model.""" - fixtures = ['common.json'] + fixtures = ["common.json"] def test_article_page(self): """Get the first article.""" - article_page = Article.objects.all().order_by('pk')[0] - self.assertEqual('Faster smarter JavaScript debugging in Firefox DevTools', article_page.title) + article_page = Article.objects.all().order_by("pk")[0] + self.assertEqual( + "Faster smarter JavaScript debugging in Firefox DevTools", + article_page.title, + ) def test_article_page_topics(self): """Get the first article’s ‘JavaScript’ and ‘CSS’ topics.""" article_topic_pages = Article.objects.all()[0].topics.all() - self.assertEqual('JavaScript', article_topic_pages[0].topic.title) - self.assertEqual('CSS', article_topic_pages[1].topic.title) + self.assertEqual("JavaScript", article_topic_pages[0].topic.title) + self.assertEqual("CSS", article_topic_pages[1].topic.title) def test_article_page_parent_pages(self): """An article page should only exist under the articles page.""" @@ -31,23 +34,23 @@ def test_article_page_subpages(self): def test_primary_topic(self): """An article page should have a primary topic.""" article_page = Article.objects.all()[0] - self.assertEqual('JavaScript', article_page.primary_topic.title) + self.assertEqual("JavaScript", article_page.primary_topic.title) def read_time(self): """An article page should have an associated read time.""" article_page = Article.objects.all()[0] - self.assertEqual('1 min read', article_page.primary_topic.read_time) + self.assertEqual("1 min read", article_page.primary_topic.read_time) class ArticlesTests(WagtailPageTests): """Tests for the Articles page model.""" - fixtures = ['common.json'] + fixtures = ["common.json"] def test_articles_page(self): """Get the default ‘Articles’ page.""" articles_page = Articles.objects.all()[0] - self.assertEqual('Articles', articles_page.title) + self.assertEqual("Articles", articles_page.title) def test_articles_page_parent_pages(self): """The Articles page can exist under another page.""" diff --git a/developerportal/apps/articles/wagtail_hooks.py b/developerportal/apps/articles/wagtail_hooks.py index 135897222..18bbd4b87 100644 --- a/developerportal/apps/articles/wagtail_hooks.py +++ b/developerportal/apps/articles/wagtail_hooks.py @@ -6,7 +6,7 @@ class ArticlesAdmin(ModelAdmin): model = Articles - menu_icon = 'doc-full-inverse' + menu_icon = "doc-full-inverse" menu_order = 210 url_helper_class = ExplorerRedirectAdminURLHelper diff --git a/developerportal/apps/common/blocks.py b/developerportal/apps/common/blocks.py index 6ba392d01..435308222 100644 --- a/developerportal/apps/common/blocks.py +++ b/developerportal/apps/common/blocks.py @@ -4,77 +4,92 @@ class ButtonBlock(blocks.StructBlock): """Content for a button.""" + text = blocks.CharBlock() page_link = blocks.PageChooserBlock(required=False) - external_link = blocks.URLBlock(required=False, help_text='External URL to link to instead of a page.') + external_link = blocks.URLBlock( + required=False, help_text="External URL to link to instead of a page." + ) class Meta: - icon = 'link' - template = 'button_block.html' + icon = "link" + template = "button_block.html" class CodeSnippetBlock(blocks.StructBlock): - language = blocks.ChoiceBlock(choices=[ - ('css', 'CSS'), - ('go', 'Go'), - ('html', 'HTML'), - ('js', 'JavaScript'), - ('python', 'Python'), - ('rust', 'Rust'), - ('ts', 'TypeScript'), - ]) + language = blocks.ChoiceBlock( + choices=[ + ("css", "CSS"), + ("go", "Go"), + ("html", "HTML"), + ("js", "JavaScript"), + ("python", "Python"), + ("rust", "Rust"), + ("ts", "TypeScript"), + ] + ) code = blocks.TextBlock() class Meta: - icon = 'code' - template = 'code_snippet_block.html' + icon = "code" + template = "code_snippet_block.html" class TabbedPanelBlock(blocks.StructBlock): """Panel of content displayed on Topics Tabbed Panel organism, 1 to 3""" + title = blocks.CharBlock() image = ImageChooserBlock() description = blocks.TextBlock() button_text = blocks.CharBlock() page_link = blocks.PageChooserBlock(required=False) - external_link = blocks.URLBlock(required=False, help_text='External URL to link to instead of a page.') + external_link = blocks.URLBlock( + required=False, help_text="External URL to link to instead of a page." + ) class AgendaItemBlock(blocks.StructBlock): """Content for an event agenda item""" + start_time = blocks.TimeBlock() end_time = blocks.TimeBlock(required=False) title = blocks.CharBlock() - speaker = blocks.PageChooserBlock(required=False, page_type='people.Person') - external_speaker = blocks.StructBlock([ - ('name', blocks.CharBlock(required=False)), - ('url', blocks.URLBlock(label='URL', required=False)), - ]) + speaker = blocks.PageChooserBlock(required=False, page_type="people.Person") + external_speaker = blocks.StructBlock( + [ + ("name", blocks.CharBlock(required=False)), + ("url", blocks.URLBlock(label="URL", required=False)), + ] + ) class ExternalLinkBlock(blocks.StructBlock): """Content for a link to an external page without an image, e.g. MDN related links.""" - title = blocks.CharBlock(label='Name') + + title = blocks.CharBlock(label="Name") url = blocks.URLBlock() class ExternalSpeakerBlock(blocks.StructBlock): """Content for an external speaker, displayed on event page""" - title = blocks.CharBlock(label='Name') + + title = blocks.CharBlock(label="Name") job_title = blocks.CharBlock() image = ImageChooserBlock() - url = blocks.URLBlock(label='URL', required=False) + url = blocks.URLBlock(label="URL", required=False) class ExternalAuthorBlock(blocks.StructBlock): """Content for an external author, for an internal or external article""" - title = blocks.CharBlock(label='Name') + + title = blocks.CharBlock(label="Name") image = ImageChooserBlock() - url = blocks.URLBlock(label='URL', required=False) + url = blocks.URLBlock(label="URL", required=False) class FeaturedExternalBlock(blocks.StructBlock): """Content for a link to an external page displayed as featured card""" + url = blocks.URLBlock() title = blocks.CharBlock() description = blocks.TextBlock(required=False) @@ -82,9 +97,9 @@ class FeaturedExternalBlock(blocks.StructBlock): class PersonalWebsiteBlock(blocks.StructBlock): - url = blocks.URLBlock(label='URL') + url = blocks.URLBlock(label="URL") title = blocks.CharBlock(required=False) icon = ImageChooserBlock(required=False) class Meta: - help_text = 'Details of any other personal website, to be displayed alongside social profiles.' + help_text = "Details of any other personal website, to be displayed alongside social profiles." diff --git a/developerportal/apps/common/constants.py b/developerportal/apps/common/constants.py index ee17905d3..f496a02a3 100644 --- a/developerportal/apps/common/constants.py +++ b/developerportal/apps/common/constants.py @@ -1,68 +1,75 @@ COLOR_CHOICES = ( - ('pink-40', 'Pink 40%'), - ('red-40', 'Red 40%'), - ('orange-40', 'Orange 40%'), - ('yellow-40', 'Yellow 40%'), - ('green-40', 'Green 40%'), - ('blue-40', 'Blue 40%'), - ('violet-40', 'Violet 40%'), - ('purple-40', 'Purple 40%'), - ('pink-20', 'Pink 20%'), - ('red-20', 'Red 20%'), - ('orange-20', 'Orange 20%'), - ('yellow-20', 'Yellow 20%'), - ('green-20', 'Green 20%'), - ('blue-20', 'Blue 20%'), - ('violet-20', 'Violet 20%'), - ('purple-20', 'Purple 20%'), + ("pink-40", "Pink 40%"), + ("red-40", "Red 40%"), + ("orange-40", "Orange 40%"), + ("yellow-40", "Yellow 40%"), + ("green-40", "Green 40%"), + ("blue-40", "Blue 40%"), + ("violet-40", "Violet 40%"), + ("purple-40", "Purple 40%"), + ("pink-20", "Pink 20%"), + ("red-20", "Red 20%"), + ("orange-20", "Orange 20%"), + ("yellow-20", "Yellow 20%"), + ("green-20", "Green 20%"), + ("blue-20", "Blue 20%"), + ("violet-20", "Violet 20%"), + ("purple-20", "Purple 20%"), ) COLOR_VALUES = ( - ('pink-40', '#ff4aa2'), - ('red-40', '#ff6a75'), - ('orange-40', '#ff8a50'), - ('yellow-40', '#ffbd4f'), - ('green-40', '#54ffbd'), - ('blue-40', '#0090ed'), - ('violet-40', '#ab71ff'), - ('purple-40', '#d74cf0'), - ('pink-20', '#ff8ac5'), - ('red-20', '#ff9aa2'), - ('orange-20', '#ffb587'), - ('yellow-20', '#ffea80'), - ('green-20', '#b3ffe3'), - ('blue-20', '#00ddff'), - ('violet-20', '#cb9eff'), - ('purple-20', '#f68fff'), + ("pink-40", "#ff4aa2"), + ("red-40", "#ff6a75"), + ("orange-40", "#ff8a50"), + ("yellow-40", "#ffbd4f"), + ("green-40", "#54ffbd"), + ("blue-40", "#0090ed"), + ("violet-40", "#ab71ff"), + ("purple-40", "#d74cf0"), + ("pink-20", "#ff8ac5"), + ("red-20", "#ff9aa2"), + ("orange-20", "#ffb587"), + ("yellow-20", "#ffea80"), + ("green-20", "#b3ffe3"), + ("blue-20", "#00ddff"), + ("violet-20", "#cb9eff"), + ("purple-20", "#f68fff"), ) -RESOURCE_COUNT_CHOICES = ( - (3, '3'), - (6, '6'), - (9, '9'), -) +RESOURCE_COUNT_CHOICES = ((3, "3"), (6, "6"), (9, "9")) RICH_TEXT_FEATURES = ( - 'bold', 'blockquote', 'code', 'h2', 'h3', 'h4', 'hr', 'image', 'italic', 'link', 'ol', 'ul', + "bold", + "blockquote", + "code", + "h2", + "h3", + "h4", + "hr", + "image", + "italic", + "link", + "ol", + "ul", ) -RICH_TEXT_FEATURES_SIMPLE = ('bold', 'italic', 'code') +RICH_TEXT_FEATURES_SIMPLE = ("bold", "italic", "code") ROLE_CHOICES = ( - ('staff', 'Staff'), - ('tech-speaker', 'Tech Speaker'), - ('guest', 'Guest'), - ('contributor', 'Contributor'), + ("staff", "Staff"), + ("tech-speaker", "Tech Speaker"), + ("guest", "Guest"), + ("contributor", "Contributor"), ) VIDEO_TYPE = ( - ('conference', 'Conference'), - ('tutorial', 'Tutorial'), - ('webinar', 'Webinar'), - ('presentation', 'Presentation'), - ('talk', 'Talk'), - ('demo', 'Demo'), - ('vlog', 'Vlog'), - ('live stream', 'Live stream'), - ('technical briefing', 'Technical briefing'), + ("conference", "Conference"), + ("tutorial", "Tutorial"), + ("webinar", "Webinar"), + ("presentation", "Presentation"), + ("talk", "Talk"), + ("demo", "Demo"), + ("vlog", "Vlog"), + ("live stream", "Live stream"), + ("technical briefing", "Technical briefing"), ) diff --git a/developerportal/apps/common/feed.py b/developerportal/apps/common/feed.py index 26395219c..c57f7a8a4 100644 --- a/developerportal/apps/common/feed.py +++ b/developerportal/apps/common/feed.py @@ -9,7 +9,7 @@ class RssFeeds(Feed): description = "Articles published" def items(self): - return Article.objects.all().public().live().order_by('-date')[:20] + return Article.objects.all().public().live().order_by("-date")[:20] def item_title(self, item): return item.title diff --git a/developerportal/apps/common/fields.py b/developerportal/apps/common/fields.py index 9e06dc3cc..9b10854d8 100644 --- a/developerportal/apps/common/fields.py +++ b/developerportal/apps/common/fields.py @@ -9,17 +9,25 @@ class CustomStreamField(StreamField): def __init__(self, *args, **kwargs): - if 'default' not in kwargs: - kwargs['default'] = None + if "default" not in kwargs: + kwargs["default"] = None - super().__init__([ - ('paragraph', RichTextBlock(features=RICH_TEXT_FEATURES)), - ('image', ImageChooserBlock()), - ('button', ButtonBlock()), - ('embed', EmbedBlock()), - ('embed_html', RawHTMLBlock(help_text=( - 'Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. ' - 'This field is meant solely for third-party embeds.' - ))), - ('code_snippet', CodeSnippetBlock()), - ], **kwargs) + super().__init__( + [ + ("paragraph", RichTextBlock(features=RICH_TEXT_FEATURES)), + ("image", ImageChooserBlock()), + ("button", ButtonBlock()), + ("embed", EmbedBlock()), + ( + "embed_html", + RawHTMLBlock( + help_text=( + "Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. " + "This field is meant solely for third-party embeds." + ) + ), + ), + ("code_snippet", CodeSnippetBlock()), + ], + **kwargs + ) diff --git a/developerportal/apps/common/helpers.py b/developerportal/apps/common/helpers.py index fb695c876..46249c75b 100644 --- a/developerportal/apps/common/helpers.py +++ b/developerportal/apps/common/helpers.py @@ -8,19 +8,19 @@ class ExplorerRedirectAdminURLHelper(AdminURLHelper): def _get_action_url_pattern(self, action): - if action == 'index' and self.model.objects: + if action == "index" and self.model.objects: try: page = self.model.objects.first() if page: - return r'^pages/%s/$' % (page.pk) - action = 'add' + return r"^pages/%s/$" % (page.pk) + action = "add" except ProgrammingError: pass super()._get_action_url_pattern(action) class ViewPageButtonHelper(PageButtonHelper): - view_button_classnames = ['button-small'] + view_button_classnames = ["button-small"] def view_button(self, obj, classnames_add=None, classnames_exclude=None): if classnames_add is None: @@ -30,16 +30,14 @@ def view_button(self, obj, classnames_add=None, classnames_exclude=None): classnames = self.view_button_classnames + classnames_add cn = self.finalise_classname(classnames, classnames_exclude) return { - 'url': obj.url, - 'label': _('View live'), - 'classname': cn, - 'title': _("View live version of '%s'") % self.verbose_name, + "url": obj.url, + "label": _("View live"), + "classname": cn, + "title": _("View live version of '%s'") % self.verbose_name, } def get_buttons_for_obj(self, obj, **kwargs): - btns = [ - self.view_button(obj), - ] + btns = [self.view_button(obj)] btns += super().get_buttons_for_obj(obj, **kwargs) return btns diff --git a/developerportal/apps/common/image_formats.py b/developerportal/apps/common/image_formats.py index c343d398c..19def50b7 100644 --- a/developerportal/apps/common/image_formats.py +++ b/developerportal/apps/common/image_formats.py @@ -1,10 +1,20 @@ -from wagtail.images.formats import Format, register_image_format, unregister_image_format +from wagtail.images.formats import ( + Format, + register_image_format, + unregister_image_format, +) -unregister_image_format('fullwidth') -unregister_image_format('left') -unregister_image_format('right') +unregister_image_format("fullwidth") +unregister_image_format("left") +unregister_image_format("right") -register_image_format(Format('left', 'Left-aligned', 'richtext-image format-left', 'width-300')) -register_image_format(Format('right', 'Right-aligned', 'richtext-image format-right', 'width-300')) -register_image_format(Format('center', 'Center-aligned', 'richtext-image format-center', 'width-300')) +register_image_format( + Format("left", "Left-aligned", "richtext-image format-left", "width-300") +) +register_image_format( + Format("right", "Right-aligned", "richtext-image format-right", "width-300") +) +register_image_format( + Format("center", "Center-aligned", "richtext-image format-center", "width-300") +) diff --git a/developerportal/apps/common/tests/test_common.py b/developerportal/apps/common/tests/test_common.py index 975d1cf78..2f709cbdc 100644 --- a/developerportal/apps/common/tests/test_common.py +++ b/developerportal/apps/common/tests/test_common.py @@ -11,7 +11,7 @@ class UtilsTestCase(TestCase): - fixtures = ['common.json'] + fixtures = ["common.json"] @classmethod def setUpTestData(cls): diff --git a/developerportal/apps/common/utils.py b/developerportal/apps/common/utils.py index 9f43517db..2d8c7ce46 100644 --- a/developerportal/apps/common/utils.py +++ b/developerportal/apps/common/utils.py @@ -24,6 +24,7 @@ def get_resources(page, models, filters=None, order_by=None, reverse=False): order_by - key to order the combined set by, must be common to all models. reverse - whether to reverse the combined set, default false. """ + def callback(model): return model.objects.filter(**filters).public().live().not_page(page).specific() @@ -33,33 +34,47 @@ def callback(model): def get_combined_articles(page, **filters): """Get internal and external articles matching filters.""" - return get_resources(page, [ - 'articles.Article', - 'externalcontent.ExternalArticle', - ], filters=filters, order_by='date', reverse=True) + return get_resources( + page, + ["articles.Article", "externalcontent.ExternalArticle"], + filters=filters, + order_by="date", + reverse=True, + ) def get_combined_articles_and_videos(page, **filters): """Get internal and external articles and videos matching filters.""" - return get_resources(page, [ - 'articles.Article', - 'videos.Video', - 'externalcontent.ExternalArticle', - 'externalcontent.ExternalVideo', - ], filters=filters, order_by='date', reverse=True) + return get_resources( + page, + [ + "articles.Article", + "videos.Video", + "externalcontent.ExternalArticle", + "externalcontent.ExternalVideo", + ], + filters=filters, + order_by="date", + reverse=True, + ) def get_combined_events(page, **filters): """Get internal and external events matching filters.""" - return get_resources(page, [ - 'events.Event', - 'externalcontent.ExternalEvent', - ], filters=filters, order_by='start_date') + return get_resources( + page, + ["events.Event", "externalcontent.ExternalEvent"], + filters=filters, + order_by="start_date", + ) def get_combined_videos(page, **filters): """Get internal and external videos matching filters.""" - return get_resources(page, [ - 'videos.Video', - 'externalcontent.ExternalVideo', - ], filters=filters, order_by='date', reverse=True) + return get_resources( + page, + ["videos.Video", "externalcontent.ExternalVideo"], + filters=filters, + order_by="date", + reverse=True, + ) diff --git a/developerportal/apps/common/wagtail_hooks.py b/developerportal/apps/common/wagtail_hooks.py index b11028c4c..e0c1812d6 100644 --- a/developerportal/apps/common/wagtail_hooks.py +++ b/developerportal/apps/common/wagtail_hooks.py @@ -10,17 +10,20 @@ class NewWindowExternalLinkHandler(LinkHandler): # This specifies to do this override for external links only. # Other identifiers are available for other types of links. - identifier = 'external' + identifier = "external" @classmethod def expand_db_attributes(cls, attrs): - href = attrs['href'] + href = attrs["href"] # Let's add the target attr, and also rel="noopener" + noreferrer fallback. # See https://github.com/whatwg/html/issues/4078. - return '' % escape(href) + return ( + '' + % escape(href) + ) -@hooks.register('register_rich_text_features') +@hooks.register("register_rich_text_features") def register_external_link(features): features.register_link_type(NewWindowExternalLinkHandler) @@ -29,14 +32,14 @@ def _custom_slug_help_text(): # Generate slug help_text that uses the default site’s real URL, falling # back to example.com instead of the Wagtail default. default_site = Site.objects.filter(is_default_site=True).first() - base_url = default_site.root_url if default_site else 'https://example.com' - return f'The name of the page as it will appear in URLs e.g. for an article: {base_url}/articles/slug/' + base_url = default_site.root_url if default_site else "https://example.com" + return f"The name of the page as it will appear in URLs e.g. for an article: {base_url}/articles/slug/" try: # Apply the custom slug help text to all Page models - slug_field = Page._meta.get_field('slug') - slug_field.verbose_name = 'URL slug' + slug_field = Page._meta.get_field("slug") + slug_field.verbose_name = "URL slug" slug_field.help_text = _custom_slug_help_text() except ProgrammingError: # This will fail if core migrations have not yet been run diff --git a/developerportal/apps/content/migrations/0001_initial.py b/developerportal/apps/content/migrations/0001_initial.py index c4ed3b684..702995f48 100644 --- a/developerportal/apps/content/migrations/0001_initial.py +++ b/developerportal/apps/content/migrations/0001_initial.py @@ -15,40 +15,152 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), - ('mozimages', '0001_initial'), - ('taggit', '0002_auto_20150616_2121'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), + ("mozimages", "0001_initial"), + ("taggit", "0002_auto_20150616_2121"), ] operations = [ migrations.CreateModel( - name='ContentPage', + name="ContentPage", 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')), - ('body', developerportal.apps.common.fields.CustomStreamField([('paragraph', wagtail.core.blocks.RichTextBlock(features=('h2', 'h3', 'h4', 'bold', 'italic', 'link', 'ol', 'ul', 'blockquote', 'code', 'hr'))), ('image', wagtail.images.blocks.ImageChooserBlock()), ('embed', wagtail.embeds.blocks.EmbedBlock()), ('embed_html', wagtail.core.blocks.RawHTMLBlock(help_text='Warning: be careful what you paste here, since\n this field could introduce XSS (or similar) bugs.\n This field is meant solely for third-party embeds.')), ('code_snippet', wagtail.core.blocks.StructBlock([('language', wagtail.core.blocks.ChoiceBlock(choices=[('css', 'CSS'), ('go', 'Go'), ('html', 'HTML'), ('js', 'JavaScript'), ('python', 'Python'), ('rust', 'Rust'), ('ts', 'TypeScript')])), ('code', wagtail.core.blocks.TextBlock())]))], default=None)), - ('card_title', models.CharField(blank=True, default='', max_length=140, verbose_name='Title')), - ('card_description', models.TextField(blank=True, default='', max_length=140, verbose_name='Description')), - ('card_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage', verbose_name='Image')), + ( + "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", + ), + ), + ( + "body", + developerportal.apps.common.fields.CustomStreamField( + [ + ( + "paragraph", + wagtail.core.blocks.RichTextBlock( + features=( + "h2", + "h3", + "h4", + "bold", + "italic", + "link", + "ol", + "ul", + "blockquote", + "code", + "hr", + ) + ), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("embed", wagtail.embeds.blocks.EmbedBlock()), + ( + "embed_html", + wagtail.core.blocks.RawHTMLBlock( + help_text="Warning: be careful what you paste here, since\n this field could introduce XSS (or similar) bugs.\n This field is meant solely for third-party embeds." + ), + ), + ( + "code_snippet", + wagtail.core.blocks.StructBlock( + [ + ( + "language", + wagtail.core.blocks.ChoiceBlock( + choices=[ + ("css", "CSS"), + ("go", "Go"), + ("html", "HTML"), + ("js", "JavaScript"), + ("python", "Python"), + ("rust", "Rust"), + ("ts", "TypeScript"), + ] + ), + ), + ("code", wagtail.core.blocks.TextBlock()), + ] + ), + ), + ], + default=None, + ), + ), + ( + "card_title", + models.CharField( + blank=True, default="", max_length=140, verbose_name="Title" + ), + ), + ( + "card_description", + models.TextField( + blank=True, + default="", + max_length=140, + verbose_name="Description", + ), + ), + ( + "card_image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + verbose_name="Image", + ), + ), ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), + options={"abstract": False}, + bases=("wagtailcore.page",), ), migrations.CreateModel( - name='ContentPageTag', + name="ContentPageTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='content.ContentPage')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='content_contentpagetag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="content.ContentPage", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="content_contentpagetag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='contentpage', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='content.ContentPageTag', to='taggit.Tag', verbose_name='Tags'), + model_name="contentpage", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="content.ContentPageTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/content/migrations/0002_contentpage_hero_image.py b/developerportal/apps/content/migrations/0002_contentpage_hero_image.py index a628bb4e7..55d636e75 100644 --- a/developerportal/apps/content/migrations/0002_contentpage_hero_image.py +++ b/developerportal/apps/content/migrations/0002_contentpage_hero_image.py @@ -6,15 +6,18 @@ class Migration(migrations.Migration): - dependencies = [ - ('mozimages', '0001_initial'), - ('content', '0001_initial'), - ] + dependencies = [("mozimages", "0001_initial"), ("content", "0001_initial")] operations = [ migrations.AddField( - model_name='contentpage', - name='hero_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage'), - ), + model_name="contentpage", + name="hero_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), + ) ] diff --git a/developerportal/apps/content/migrations/0003_auto_20190813_1503.py b/developerportal/apps/content/migrations/0003_auto_20190813_1503.py index 8a4d035d5..34e39601b 100644 --- a/developerportal/apps/content/migrations/0003_auto_20190813_1503.py +++ b/developerportal/apps/content/migrations/0003_auto_20190813_1503.py @@ -9,14 +9,86 @@ class Migration(migrations.Migration): - dependencies = [ - ('content', '0002_contentpage_hero_image'), - ] + dependencies = [("content", "0002_contentpage_hero_image")] operations = [ migrations.AlterField( - model_name='contentpage', - name='body', - field=developerportal.apps.common.fields.CustomStreamField([('paragraph', wagtail.core.blocks.RichTextBlock(features=('h2', 'h3', 'h4', 'bold', 'italic', 'link', 'ol', 'ul', 'blockquote', 'code', 'hr'))), ('image', wagtail.images.blocks.ImageChooserBlock()), ('button', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(help_text='External URL to link to instead of a page.', required=False))])), ('embed', wagtail.embeds.blocks.EmbedBlock()), ('embed_html', wagtail.core.blocks.RawHTMLBlock(help_text='Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. This field is meant solely for third-party embeds.')), ('code_snippet', wagtail.core.blocks.StructBlock([('language', wagtail.core.blocks.ChoiceBlock(choices=[('css', 'CSS'), ('go', 'Go'), ('html', 'HTML'), ('js', 'JavaScript'), ('python', 'Python'), ('rust', 'Rust'), ('ts', 'TypeScript')])), ('code', wagtail.core.blocks.TextBlock())]))], default=None, help_text='Main page body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets'), - ), + model_name="contentpage", + name="body", + field=developerportal.apps.common.fields.CustomStreamField( + [ + ( + "paragraph", + wagtail.core.blocks.RichTextBlock( + features=( + "h2", + "h3", + "h4", + "bold", + "italic", + "link", + "ol", + "ul", + "blockquote", + "code", + "hr", + ) + ), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "button", + wagtail.core.blocks.StructBlock( + [ + ("text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock( + help_text="External URL to link to instead of a page.", + required=False, + ), + ), + ] + ), + ), + ("embed", wagtail.embeds.blocks.EmbedBlock()), + ( + "embed_html", + wagtail.core.blocks.RawHTMLBlock( + help_text="Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. This field is meant solely for third-party embeds." + ), + ), + ( + "code_snippet", + wagtail.core.blocks.StructBlock( + [ + ( + "language", + wagtail.core.blocks.ChoiceBlock( + choices=[ + ("css", "CSS"), + ("go", "Go"), + ("html", "HTML"), + ("js", "JavaScript"), + ("python", "Python"), + ("rust", "Rust"), + ("ts", "TypeScript"), + ] + ), + ), + ("code", wagtail.core.blocks.TextBlock()), + ] + ), + ), + ], + default=None, + help_text="Main page body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets", + ), + ) ] diff --git a/developerportal/apps/content/models.py b/developerportal/apps/content/models.py index 80b826114..013721c62 100644 --- a/developerportal/apps/content/models.py +++ b/developerportal/apps/content/models.py @@ -18,36 +18,40 @@ class ContentPageTag(TaggedItemBase): - content_object = ParentalKey('ContentPage', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "ContentPage", on_delete=CASCADE, related_name="tagged_items" + ) class ContentPage(Page): - parent_page_types = ['home.HomePage', 'content.ContentPage'] - subpage_types = ['people.People', 'content.ContentPage'] - template = 'content.html' + parent_page_types = ["home.HomePage", "content.ContentPage"] + subpage_types = ["people.People", "content.ContentPage"] + template = "content.html" # Content fields hero_image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+' + related_name="+", + ) + body = CustomStreamField( + help_text=( + "Main page body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets" + ) ) - body = CustomStreamField(help_text=( - 'Main page body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets' - )) # Card fields - card_title = CharField('Title', max_length=140, blank=True, default='') - card_description = TextField('Description', max_length=140, blank=True, default='') + card_title = CharField("Title", max_length=140, blank=True, default="") + card_description = TextField("Description", max_length=140, blank=True, default="") card_image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', - verbose_name='Image', + related_name="+", + verbose_name="Image", ) # Meta fields @@ -55,38 +59,43 @@ class ContentPage(Page): # Editor panel configuration content_panels = Page.content_panels + [ - MultiFieldPanel([ - ImageChooserPanel('hero_image') - ], heading='Hero image', help_text='Image should be at least 1024px x 438px (21:9 aspect ratio)'), - StreamFieldPanel('body'), + MultiFieldPanel( + [ImageChooserPanel("hero_image")], + heading="Hero image", + help_text="Image should be at least 1024px x 438px (21:9 aspect ratio)", + ), + StreamFieldPanel("body"), ] # Card panels card_panels = [ - FieldPanel('card_title'), - FieldPanel('card_description'), - ImageChooserPanel('card_image'), + FieldPanel("card_title"), + FieldPanel("card_description"), + ImageChooserPanel("card_image"), ] # Meta panels meta_panels = [ - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ) ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - FieldPanel('show_in_menus'), - ] + settings_panels = [FieldPanel("slug"), FieldPanel("show_in_menus")] # Tabs - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) diff --git a/developerportal/apps/events/migrations/0001_initial.py b/developerportal/apps/events/migrations/0001_initial.py index 902fb6bd5..847374fb4 100644 --- a/developerportal/apps/events/migrations/0001_initial.py +++ b/developerportal/apps/events/migrations/0001_initial.py @@ -9,18 +9,26 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural") ] operations = [ migrations.CreateModel( - name='Event', + name="Event", 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')), + ( + "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", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), - ), + options={"abstract": False}, + bases=("wagtailcore.page",), + ) ] diff --git a/developerportal/apps/events/migrations/0002_auto_20190704_1334.py b/developerportal/apps/events/migrations/0002_auto_20190704_1334.py index cbe91c2e2..9855f2bce 100644 --- a/developerportal/apps/events/migrations/0002_auto_20190704_1334.py +++ b/developerportal/apps/events/migrations/0002_auto_20190704_1334.py @@ -14,97 +14,276 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0021_auto_20190702_1402'), - ('people', '0013_merge_20190702_1300'), - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), - ('mozimages', '0001_initial'), - ('events', '0001_initial'), + ("topics", "0021_auto_20190702_1402"), + ("people", "0013_merge_20190702_1300"), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), + ("mozimages", "0001_initial"), + ("events", "0001_initial"), ] operations = [ migrations.CreateModel( - name='Events', + name="Events", 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')), + ( + "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", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), + options={"abstract": False}, + bases=("wagtailcore.page",), ), migrations.AlterModelOptions( - name='event', - options={'ordering': ['-start_date']}, + name="event", options={"ordering": ["-start_date"]} ), migrations.AddField( - model_name='event', - name='agenda', - field=wagtail.core.fields.StreamField([('agenda_item', wagtail.core.blocks.StructBlock([('start_time', wagtail.core.blocks.TimeBlock()), ('end_time', wagtail.core.blocks.TimeBlock(required=False)), ('title', wagtail.core.blocks.CharBlock()), ('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False)), ('external_speaker', wagtail.core.blocks.StructBlock([('name', wagtail.core.blocks.CharBlock(required=False)), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))]))]))], blank=True, null=True), + model_name="event", + name="agenda", + field=wagtail.core.fields.StreamField( + [ + ( + "agenda_item", + wagtail.core.blocks.StructBlock( + [ + ("start_time", wagtail.core.blocks.TimeBlock()), + ( + "end_time", + wagtail.core.blocks.TimeBlock(required=False), + ), + ("title", wagtail.core.blocks.CharBlock()), + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ), + ( + "external_speaker", + wagtail.core.blocks.StructBlock( + [ + ( + "name", + wagtail.core.blocks.CharBlock( + required=False + ), + ), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ] + ), + ), + ] + ), + ) + ], + blank=True, + null=True, + ), ), migrations.AddField( - model_name='event', - name='body', - field=developerportal.apps.common.fields.CustomStreamField([('paragraph', wagtail.core.blocks.RichTextBlock(features=('h2', 'h3', 'h4', 'bold', 'italic', 'link', 'ol', 'ul', 'blockquote', 'code', 'hr'))), ('image', wagtail.images.blocks.ImageChooserBlock()), ('embed', wagtail.embeds.blocks.EmbedBlock()), ('embed_html', wagtail.core.blocks.RawHTMLBlock(help_text='Warning: be careful what you paste here, since\n this field could introduce XSS (or similar) bugs.\n This field is meant solely for third-party embeds.')), ('code_snippet', wagtail.core.blocks.StructBlock([('language', wagtail.core.blocks.ChoiceBlock(choices=[('css', 'CSS'), ('go', 'Go'), ('html', 'HTML'), ('js', 'JavaScript'), ('python', 'Python'), ('rust', 'Rust'), ('ts', 'TypeScript')])), ('code', wagtail.core.blocks.TextBlock())]))], blank=True, default=None, null=True), + model_name="event", + name="body", + field=developerportal.apps.common.fields.CustomStreamField( + [ + ( + "paragraph", + wagtail.core.blocks.RichTextBlock( + features=( + "h2", + "h3", + "h4", + "bold", + "italic", + "link", + "ol", + "ul", + "blockquote", + "code", + "hr", + ) + ), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("embed", wagtail.embeds.blocks.EmbedBlock()), + ( + "embed_html", + wagtail.core.blocks.RawHTMLBlock( + help_text="Warning: be careful what you paste here, since\n this field could introduce XSS (or similar) bugs.\n This field is meant solely for third-party embeds." + ), + ), + ( + "code_snippet", + wagtail.core.blocks.StructBlock( + [ + ( + "language", + wagtail.core.blocks.ChoiceBlock( + choices=[ + ("css", "CSS"), + ("go", "Go"), + ("html", "HTML"), + ("js", "JavaScript"), + ("python", "Python"), + ("rust", "Rust"), + ("ts", "TypeScript"), + ] + ), + ), + ("code", wagtail.core.blocks.TextBlock()), + ] + ), + ), + ], + blank=True, + default=None, + null=True, + ), ), migrations.AddField( - model_name='event', - name='description', - field=models.TextField(blank=True, default='', max_length=250), + model_name="event", + name="description", + field=models.TextField(blank=True, default="", max_length=250), ), migrations.AddField( - model_name='event', - name='end_date', + model_name="event", + name="end_date", field=models.DateField(blank=True, null=True), ), migrations.AddField( - model_name='event', - name='header_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage'), + model_name="event", + name="header_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), ), migrations.AddField( - model_name='event', - name='register_url', - field=models.URLField(blank=True, null=True, verbose_name='Register URL'), + model_name="event", + name="register_url", + field=models.URLField(blank=True, null=True, verbose_name="Register URL"), ), migrations.AddField( - model_name='event', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False)), ('external_speaker', wagtail.core.blocks.StructBlock([('name', wagtail.core.blocks.CharBlock()), ('job_title', wagtail.core.blocks.CharBlock()), ('profile_picture', wagtail.images.blocks.ImageChooserBlock())], required=False))], blank=True, null=True), + model_name="event", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ), + ( + "external_speaker", + wagtail.core.blocks.StructBlock( + [ + ("name", wagtail.core.blocks.CharBlock()), + ("job_title", wagtail.core.blocks.CharBlock()), + ( + "profile_picture", + wagtail.images.blocks.ImageChooserBlock(), + ), + ], + required=False, + ), + ), + ], + blank=True, + null=True, + ), ), migrations.AddField( - model_name='event', - name='start_date', + model_name="event", + name="start_date", field=models.DateField(default=datetime.date.today), ), migrations.AddField( - model_name='event', - name='venue', - field=models.TextField(blank=True, default='', max_length=250), + model_name="event", + name="venue", + field=models.TextField(blank=True, default="", max_length=250), ), migrations.CreateModel( - name='EventTopic', + name="EventTopic", 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)), - ('event', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='events.Event')), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "event", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="events.Event", + ), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='EventSpeaker', + name="EventSpeaker", 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)), - ('event', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='speaker', to='events.Event')), - ('speaker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "event", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="speaker", + to="events.Event", + ), + ), + ( + "speaker", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/events/migrations/0003_auto_20190708_0858.py b/developerportal/apps/events/migrations/0003_auto_20190708_0858.py index cddb61480..b986c1a39 100644 --- a/developerportal/apps/events/migrations/0003_auto_20190708_0858.py +++ b/developerportal/apps/events/migrations/0003_auto_20190708_0858.py @@ -8,14 +8,37 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0002_auto_20190704_1334'), - ] + dependencies = [("events", "0002_auto_20190704_1334")] operations = [ migrations.AlterField( - model_name='event', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False)), ('external_speaker', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('job_title', wagtail.core.blocks.CharBlock()), ('profile_picture', wagtail.images.blocks.ImageChooserBlock())], required=False))], blank=True, null=True), - ), + model_name="event", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ), + ( + "external_speaker", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("job_title", wagtail.core.blocks.CharBlock()), + ( + "profile_picture", + wagtail.images.blocks.ImageChooserBlock(), + ), + ], + required=False, + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/events/migrations/0003_auto_20190709_0928.py b/developerportal/apps/events/migrations/0003_auto_20190709_0928.py index b76adb3fa..1ff7181dc 100644 --- a/developerportal/apps/events/migrations/0003_auto_20190709_0928.py +++ b/developerportal/apps/events/migrations/0003_auto_20190709_0928.py @@ -5,13 +5,10 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0002_auto_20190704_1334'), - ] + dependencies = [("events", "0002_auto_20190704_1334")] operations = [ migrations.AlterModelOptions( - name='events', - options={'verbose_name_plural': 'Events'}, - ), + name="events", options={"verbose_name_plural": "Events"} + ) ] diff --git a/developerportal/apps/events/migrations/0003_auto_20190709_1241.py b/developerportal/apps/events/migrations/0003_auto_20190709_1241.py index f4db0b9a4..ab0f6bdc7 100644 --- a/developerportal/apps/events/migrations/0003_auto_20190709_1241.py +++ b/developerportal/apps/events/migrations/0003_auto_20190709_1241.py @@ -5,19 +5,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0002_auto_20190704_1334'), - ] + dependencies = [("events", "0002_auto_20190704_1334")] operations = [ migrations.AddField( - model_name='event', - name='latitude', + model_name="event", + name="latitude", field=models.FloatField(blank=True, null=True), ), migrations.AddField( - model_name='event', - name='longitude', + model_name="event", + name="longitude", field=models.FloatField(blank=True, null=True), ), ] diff --git a/developerportal/apps/events/migrations/0004_auto_20190708_1100.py b/developerportal/apps/events/migrations/0004_auto_20190708_1100.py index 1074a7864..e2376ba90 100644 --- a/developerportal/apps/events/migrations/0004_auto_20190708_1100.py +++ b/developerportal/apps/events/migrations/0004_auto_20190708_1100.py @@ -8,14 +8,43 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0003_auto_20190708_0858'), - ] + dependencies = [("events", "0003_auto_20190708_0858")] operations = [ migrations.AlterField( - model_name='event', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False)), ('external_speaker', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('job_title', wagtail.core.blocks.CharBlock()), ('profile_picture', wagtail.images.blocks.ImageChooserBlock()), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))], required=False))], blank=True, null=True), - ), + model_name="event", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ), + ( + "external_speaker", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("job_title", wagtail.core.blocks.CharBlock()), + ( + "profile_picture", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ], + required=False, + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/events/migrations/0004_auto_20190711_1501.py b/developerportal/apps/events/migrations/0004_auto_20190711_1501.py index 38e308c3a..a2bc44a12 100644 --- a/developerportal/apps/events/migrations/0004_auto_20190711_1501.py +++ b/developerportal/apps/events/migrations/0004_auto_20190711_1501.py @@ -9,50 +9,82 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('mozimages', '0001_initial'), - ('events', '0003_auto_20190709_0928'), + ("taggit", "0002_auto_20150616_2121"), + ("mozimages", "0001_initial"), + ("events", "0003_auto_20190709_0928"), ] operations = [ - migrations.AlterModelOptions( - name='event', - options={}, - ), + migrations.AlterModelOptions(name="event", options={}), migrations.RenameField( - model_name='event', - old_name='header_image', - new_name='image', + model_name="event", old_name="header_image", new_name="image" ), migrations.AddField( - model_name='event', - name='card_description', - field=models.TextField(blank=True, default='', max_length=140, verbose_name='Description'), + model_name="event", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=140, verbose_name="Description" + ), ), migrations.AddField( - model_name='event', - name='card_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage', verbose_name='Image'), + model_name="event", + name="card_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + verbose_name="Image", + ), ), migrations.AddField( - model_name='event', - name='card_title', - field=models.CharField(blank=True, default='', max_length=140, verbose_name='Title'), + model_name="event", + name="card_title", + field=models.CharField( + blank=True, default="", max_length=140, verbose_name="Title" + ), ), migrations.CreateModel( - name='EventTag', + name="EventTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='events.Event')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events_eventtag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="events.Event", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="events_eventtag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='event', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='events.EventTag', to='taggit.Tag', verbose_name='Tags'), + model_name="event", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="events.EventTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/events/migrations/0004_merge_20190711_1925.py b/developerportal/apps/events/migrations/0004_merge_20190711_1925.py index c72fefc93..3143c9d9c 100644 --- a/developerportal/apps/events/migrations/0004_merge_20190711_1925.py +++ b/developerportal/apps/events/migrations/0004_merge_20190711_1925.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('events', '0003_auto_20190709_0928'), - ('events', '0003_auto_20190709_1241'), + ("events", "0003_auto_20190709_0928"), + ("events", "0003_auto_20190709_1241"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/events/migrations/0005_merge_20190711_2019.py b/developerportal/apps/events/migrations/0005_merge_20190711_2019.py index 00e7e0c03..d35db4852 100644 --- a/developerportal/apps/events/migrations/0005_merge_20190711_2019.py +++ b/developerportal/apps/events/migrations/0005_merge_20190711_2019.py @@ -6,10 +6,9 @@ class Migration(migrations.Migration): dependencies = [ - ('events', '0004_auto_20190708_1100'), - ('events', '0004_merge_20190711_1925'), - ('events', '0004_auto_20190711_1501'), + ("events", "0004_auto_20190708_1100"), + ("events", "0004_merge_20190711_1925"), + ("events", "0004_auto_20190711_1501"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/events/migrations/0006_auto_20190712_1231.py b/developerportal/apps/events/migrations/0006_auto_20190712_1231.py index 82a8d98f3..71cc7f68c 100644 --- a/developerportal/apps/events/migrations/0006_auto_20190712_1231.py +++ b/developerportal/apps/events/migrations/0006_auto_20190712_1231.py @@ -6,19 +6,28 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0005_merge_20190711_2019'), - ] + dependencies = [("events", "0005_merge_20190711_2019")] operations = [ migrations.AddField( - model_name='event', - name='card_venue', - field=models.CharField(blank=True, default='', help_text='Location details (city and country), displayed on event cards', max_length=100), + model_name="event", + name="card_venue", + field=models.CharField( + blank=True, + default="", + help_text="Location details (city and country), displayed on event cards", + max_length=100, + ), ), migrations.AddField( - model_name='events', - name='featured_event', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='events.Event'), + model_name="events", + name="featured_event", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="events.Event", + ), ), ] diff --git a/developerportal/apps/events/migrations/0007_auto_20190718_1424.py b/developerportal/apps/events/migrations/0007_auto_20190718_1424.py index fd6684645..67ad40e83 100644 --- a/developerportal/apps/events/migrations/0007_auto_20190718_1424.py +++ b/developerportal/apps/events/migrations/0007_auto_20190718_1424.py @@ -9,39 +9,72 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('events', '0006_auto_20190712_1231'), + ("taggit", "0002_auto_20150616_2121"), + ("events", "0006_auto_20190712_1231"), ] operations = [ - migrations.RemoveField( - model_name='event', - name='card_venue', - ), + migrations.RemoveField(model_name="event", name="card_venue"), migrations.AddField( - model_name='event', - name='location', - field=models.CharField(blank=True, default='', help_text='Location details (city and country), displayed on event cards', max_length=100), + model_name="event", + name="location", + field=models.CharField( + blank=True, + default="", + help_text="Location details (city and country), displayed on event cards", + max_length=100, + ), ), migrations.AlterField( - model_name='event', - name='venue', - field=models.TextField(blank=True, default='', help_text='Full address of the event venue, displayed on the event detail page', max_length=250), + model_name="event", + name="venue", + field=models.TextField( + blank=True, + default="", + help_text="Full address of the event venue, displayed on the event detail page", + max_length=250, + ), ), migrations.CreateModel( - name='EventsTag', + name="EventsTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='events.Events')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events_eventstag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="events.Events", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="events_eventstag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='events', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='events.EventsTag', to='taggit.Tag', verbose_name='Tags'), + model_name="events", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="events.EventsTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/events/migrations/0010_auto_20190718_1551.py b/developerportal/apps/events/migrations/0010_auto_20190718_1551.py index 6c419c2ed..24d80020e 100644 --- a/developerportal/apps/events/migrations/0010_auto_20190718_1551.py +++ b/developerportal/apps/events/migrations/0010_auto_20190718_1551.py @@ -5,14 +5,10 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0007_auto_20190718_1424'), - ] + dependencies = [("events", "0007_auto_20190718_1424")] operations = [ migrations.RenameField( - model_name='events', - old_name='featured_event', - new_name='featured', - ), + model_name="events", old_name="featured_event", new_name="featured" + ) ] diff --git a/developerportal/apps/events/migrations/0011_auto_20190718_1724.py b/developerportal/apps/events/migrations/0011_auto_20190718_1724.py index 4b8f4e78d..6b80fb77d 100644 --- a/developerportal/apps/events/migrations/0011_auto_20190718_1724.py +++ b/developerportal/apps/events/migrations/0011_auto_20190718_1724.py @@ -8,14 +8,38 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0010_auto_20190718_1551'), - ] + dependencies = [("events", "0010_auto_20190718_1551")] operations = [ migrations.AlterField( - model_name='events', - name='featured', - field=wagtail.core.fields.StreamField([('event', wagtail.core.blocks.PageChooserBlock(page_type=['events.Event', 'externalcontent.ExternalEvent'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, null=True), - ), + model_name="events", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "event", + wagtail.core.blocks.PageChooserBlock( + page_type=["events.Event", "externalcontent.ExternalEvent"], + required=False, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/events/migrations/0012_auto_20190725_1124.py b/developerportal/apps/events/migrations/0012_auto_20190725_1124.py index be8134d05..d5f4ae03a 100644 --- a/developerportal/apps/events/migrations/0012_auto_20190725_1124.py +++ b/developerportal/apps/events/migrations/0012_auto_20190725_1124.py @@ -6,62 +6,65 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0011_auto_20190718_1724'), - ] + dependencies = [("events", "0011_auto_20190718_1724")] operations = [ - migrations.RemoveField( - model_name='event', - name='location', - ), - migrations.RemoveField( - model_name='event', - name='venue', - ), + migrations.RemoveField(model_name="event", name="location"), + migrations.RemoveField(model_name="event", name="venue"), migrations.AddField( - model_name='event', - name='address_line_1', - field=models.CharField(blank=True, default='', max_length=100), + model_name="event", + name="address_line_1", + field=models.CharField(blank=True, default="", max_length=100), ), migrations.AddField( - model_name='event', - name='address_line_2', - field=models.CharField(blank=True, default='', max_length=100), + model_name="event", + name="address_line_2", + field=models.CharField(blank=True, default="", max_length=100), ), migrations.AddField( - model_name='event', - name='address_line_3', - field=models.CharField(blank=True, default='', max_length=100), + model_name="event", + name="address_line_3", + field=models.CharField(blank=True, default="", max_length=100), ), migrations.AddField( - model_name='event', - name='city', - field=models.CharField(blank=True, default='', max_length=100), + model_name="event", + name="city", + field=models.CharField(blank=True, default="", max_length=100), ), migrations.AddField( - model_name='event', - name='country', - field=django_countries.fields.CountryField(blank=True, default='', max_length=2), + model_name="event", + name="country", + field=django_countries.fields.CountryField( + blank=True, default="", max_length=2 + ), ), migrations.AddField( - model_name='event', - name='state', - field=models.CharField(blank=True, default='', max_length=100, verbose_name='State/Province/Region'), + model_name="event", + name="state", + field=models.CharField( + blank=True, + default="", + max_length=100, + verbose_name="State/Province/Region", + ), ), migrations.AddField( - model_name='event', - name='venue_name', - field=models.CharField(blank=True, default='', max_length=100), + model_name="event", + name="venue_name", + field=models.CharField(blank=True, default="", max_length=100), ), migrations.AddField( - model_name='event', - name='venue_url', - field=models.URLField(blank=True, default='', max_length=100, verbose_name='Venue URL'), + model_name="event", + name="venue_url", + field=models.URLField( + blank=True, default="", max_length=100, verbose_name="Venue URL" + ), ), migrations.AddField( - model_name='event', - name='zip_code', - field=models.CharField(blank=True, default='', max_length=100, verbose_name='Zip/Postal code'), + model_name="event", + name="zip_code", + field=models.CharField( + blank=True, default="", max_length=100, verbose_name="Zip/Postal code" + ), ), ] diff --git a/developerportal/apps/events/migrations/0013_auto_20190731_1054.py b/developerportal/apps/events/migrations/0013_auto_20190731_1054.py index d14e3621a..30af28937 100644 --- a/developerportal/apps/events/migrations/0013_auto_20190731_1054.py +++ b/developerportal/apps/events/migrations/0013_auto_20190731_1054.py @@ -8,14 +8,40 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0012_auto_20190725_1124'), - ] + dependencies = [("events", "0012_auto_20190725_1124")] operations = [ migrations.AlterField( - model_name='event', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False)), ('external_speaker', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('job_title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))], required=False))], blank=True, null=True), - ), + model_name="event", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ), + ( + "external_speaker", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("job_title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ], + required=False, + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/events/migrations/0014_auto_20190813_1302.py b/developerportal/apps/events/migrations/0014_auto_20190813_1302.py index e31fce7bb..9559e4a51 100644 --- a/developerportal/apps/events/migrations/0014_auto_20190813_1302.py +++ b/developerportal/apps/events/migrations/0014_auto_20190813_1302.py @@ -5,19 +5,19 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0013_auto_20190731_1054'), - ] + dependencies = [("events", "0013_auto_20190731_1054")] operations = [ migrations.AlterField( - model_name='event', - name='card_description', - field=models.TextField(blank=True, default='', max_length=400, verbose_name='Description'), + model_name="event", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=400, verbose_name="Description" + ), ), migrations.AlterField( - model_name='event', - name='description', - field=models.TextField(blank=True, default='', max_length=400), + model_name="event", + name="description", + field=models.TextField(blank=True, default="", max_length=400), ), ] diff --git a/developerportal/apps/events/migrations/0015_auto_20190813_1503.py b/developerportal/apps/events/migrations/0015_auto_20190813_1503.py index b010b02f6..6bd7e210c 100644 --- a/developerportal/apps/events/migrations/0015_auto_20190813_1503.py +++ b/developerportal/apps/events/migrations/0015_auto_20190813_1503.py @@ -10,34 +10,213 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0014_auto_20190813_1302'), - ] + dependencies = [("events", "0014_auto_20190813_1302")] operations = [ migrations.AlterField( - model_name='event', - name='agenda', - field=wagtail.core.fields.StreamField([('agenda_item', wagtail.core.blocks.StructBlock([('start_time', wagtail.core.blocks.TimeBlock()), ('end_time', wagtail.core.blocks.TimeBlock(required=False)), ('title', wagtail.core.blocks.CharBlock()), ('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False)), ('external_speaker', wagtail.core.blocks.StructBlock([('name', wagtail.core.blocks.CharBlock(required=False)), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))]))]))], blank=True, help_text='Optional list of agenda items for this event', null=True), + model_name="event", + name="agenda", + field=wagtail.core.fields.StreamField( + [ + ( + "agenda_item", + wagtail.core.blocks.StructBlock( + [ + ("start_time", wagtail.core.blocks.TimeBlock()), + ( + "end_time", + wagtail.core.blocks.TimeBlock(required=False), + ), + ("title", wagtail.core.blocks.CharBlock()), + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ), + ( + "external_speaker", + wagtail.core.blocks.StructBlock( + [ + ( + "name", + wagtail.core.blocks.CharBlock( + required=False + ), + ), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ] + ), + ), + ] + ), + ) + ], + blank=True, + help_text="Optional list of agenda items for this event", + null=True, + ), ), migrations.AlterField( - model_name='event', - name='body', - field=developerportal.apps.common.fields.CustomStreamField([('paragraph', wagtail.core.blocks.RichTextBlock(features=('h2', 'h3', 'h4', 'bold', 'italic', 'link', 'ol', 'ul', 'blockquote', 'code', 'hr'))), ('image', wagtail.images.blocks.ImageChooserBlock()), ('button', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(help_text='External URL to link to instead of a page.', required=False))])), ('embed', wagtail.embeds.blocks.EmbedBlock()), ('embed_html', wagtail.core.blocks.RawHTMLBlock(help_text='Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. This field is meant solely for third-party embeds.')), ('code_snippet', wagtail.core.blocks.StructBlock([('language', wagtail.core.blocks.ChoiceBlock(choices=[('css', 'CSS'), ('go', 'Go'), ('html', 'HTML'), ('js', 'JavaScript'), ('python', 'Python'), ('rust', 'Rust'), ('ts', 'TypeScript')])), ('code', wagtail.core.blocks.TextBlock())]))], blank=True, default=None, help_text='Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets', null=True), + model_name="event", + name="body", + field=developerportal.apps.common.fields.CustomStreamField( + [ + ( + "paragraph", + wagtail.core.blocks.RichTextBlock( + features=( + "h2", + "h3", + "h4", + "bold", + "italic", + "link", + "ol", + "ul", + "blockquote", + "code", + "hr", + ) + ), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "button", + wagtail.core.blocks.StructBlock( + [ + ("text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock( + help_text="External URL to link to instead of a page.", + required=False, + ), + ), + ] + ), + ), + ("embed", wagtail.embeds.blocks.EmbedBlock()), + ( + "embed_html", + wagtail.core.blocks.RawHTMLBlock( + help_text="Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. This field is meant solely for third-party embeds." + ), + ), + ( + "code_snippet", + wagtail.core.blocks.StructBlock( + [ + ( + "language", + wagtail.core.blocks.ChoiceBlock( + choices=[ + ("css", "CSS"), + ("go", "Go"), + ("html", "HTML"), + ("js", "JavaScript"), + ("python", "Python"), + ("rust", "Rust"), + ("ts", "TypeScript"), + ] + ), + ), + ("code", wagtail.core.blocks.TextBlock()), + ] + ), + ), + ], + blank=True, + default=None, + help_text="Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets", + null=True, + ), ), migrations.AlterField( - model_name='event', - name='description', - field=models.TextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="event", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), migrations.AlterField( - model_name='event', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False)), ('external_speaker', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('job_title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))], required=False))], blank=True, help_text='Optional list of speakers for this event', null=True), + model_name="event", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ), + ( + "external_speaker", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("job_title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ], + required=False, + ), + ), + ], + blank=True, + help_text="Optional list of speakers for this event", + null=True, + ), ), migrations.AlterField( - model_name='events', - name='featured', - field=wagtail.core.fields.StreamField([('event', wagtail.core.blocks.PageChooserBlock(page_type=['events.Event', 'externalcontent.ExternalEvent'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, help_text='Optional space to show a featured event', null=True), + model_name="events", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "event", + wagtail.core.blocks.PageChooserBlock( + page_type=["events.Event", "externalcontent.ExternalEvent"], + required=False, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + help_text="Optional space to show a featured event", + null=True, + ), ), ] diff --git a/developerportal/apps/events/migrations/0016_auto_20190814_1600.py b/developerportal/apps/events/migrations/0016_auto_20190814_1600.py index 9fbd8bef0..ca310928c 100644 --- a/developerportal/apps/events/migrations/0016_auto_20190814_1600.py +++ b/developerportal/apps/events/migrations/0016_auto_20190814_1600.py @@ -8,19 +8,71 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0015_auto_20190813_1503'), - ] + dependencies = [("events", "0015_auto_20190813_1503")] operations = [ migrations.AlterField( - model_name='event', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'])), ('external_speaker', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('job_title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))]))], blank=True, help_text='Optional list of speakers for this event', null=True), + model_name="event", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"] + ), + ), + ( + "external_speaker", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("job_title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ] + ), + ), + ], + blank=True, + help_text="Optional list of speakers for this event", + null=True, + ), ), migrations.AlterField( - model_name='events', - name='featured', - field=wagtail.core.fields.StreamField([('event', wagtail.core.blocks.PageChooserBlock(page_type=['events.Event', 'externalcontent.ExternalEvent'])), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, help_text='Optional space to show a featured event', null=True), + model_name="events", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "event", + wagtail.core.blocks.PageChooserBlock( + page_type=["events.Event", "externalcontent.ExternalEvent"] + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + help_text="Optional space to show a featured event", + null=True, + ), ), ] diff --git a/developerportal/apps/events/migrations/0017_auto_20190819_1304.py b/developerportal/apps/events/migrations/0017_auto_20190819_1304.py index bf18b6b2a..71bd8d34b 100644 --- a/developerportal/apps/events/migrations/0017_auto_20190819_1304.py +++ b/developerportal/apps/events/migrations/0017_auto_20190819_1304.py @@ -6,14 +6,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('events', '0016_auto_20190814_1600'), - ] + dependencies = [("events", "0016_auto_20190814_1600")] operations = [ migrations.AlterField( - model_name='event', - name='description', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), - ), + model_name="event", + name="description", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), + ) ] diff --git a/developerportal/apps/events/models.py b/developerportal/apps/events/models.py index 9b6b83021..ca17e7576 100644 --- a/developerportal/apps/events/models.py +++ b/developerportal/apps/events/models.py @@ -39,79 +39,86 @@ class EventsTag(TaggedItemBase): - content_object = ParentalKey('Events', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Events", on_delete=CASCADE, related_name="tagged_items" + ) class EventTag(TaggedItemBase): - content_object = ParentalKey('Event', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Event", on_delete=CASCADE, related_name="tagged_items" + ) class EventTopic(Orderable): - event = ParentalKey('Event', related_name='topics') - topic = ForeignKey('topics.Topic', on_delete=CASCADE, related_name='+') - panels = [ - PageChooserPanel('topic'), - ] + event = ParentalKey("Event", related_name="topics") + topic = ForeignKey("topics.Topic", on_delete=CASCADE, related_name="+") + panels = [PageChooserPanel("topic")] class EventSpeaker(Orderable): - event = ParentalKey('Event', related_name='speaker') - speaker = ForeignKey('people.Person', on_delete=CASCADE, related_name='+') - panels = [ - PageChooserPanel('speaker') - ] + event = ParentalKey("Event", related_name="speaker") + speaker = ForeignKey("people.Person", on_delete=CASCADE, related_name="+") + panels = [PageChooserPanel("speaker")] class Events(Page): - parent_page_types = ['home.HomePage'] - subpage_types = ['events.Event'] - template = 'events.html' + parent_page_types = ["home.HomePage"] + subpage_types = ["events.Event"] + template = "events.html" # Content fields featured = StreamField( - StreamBlock([ - ('event', PageChooserBlock(target_model=( - 'events.Event', - 'externalcontent.ExternalEvent', - ))), - ('external_page', FeaturedExternalBlock()), - ], max_num=1, required=False), + StreamBlock( + [ + ( + "event", + PageChooserBlock( + target_model=("events.Event", "externalcontent.ExternalEvent") + ), + ), + ("external_page", FeaturedExternalBlock()), + ], + max_num=1, + required=False, + ), null=True, blank=True, - help_text='Optional space to show a featured event', + help_text="Optional space to show a featured event", ) # Meta fields keywords = ClusterTaggableManager(through=EventsTag, blank=True) # Content panels - content_panels = Page.content_panels + [ - StreamFieldPanel('featured') - ] + content_panels = Page.content_panels + [StreamFieldPanel("featured")] # Meta panels meta_panels = [ - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ) ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - FieldPanel('show_in_menus'), - ] - - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + settings_panels = [FieldPanel("slug"), FieldPanel("show_in_menus")] + + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) class Meta: - verbose_name_plural = 'Events' + verbose_name_plural = "Events" @classmethod def can_create_at(cls, parent): @@ -120,7 +127,7 @@ def can_create_at(cls, parent): def get_context(self, request): context = super().get_context(request) - context['filters'] = self.get_filters() + context["filters"] = self.get_filters() return context @property @@ -130,64 +137,70 @@ def events(self): def get_filters(self): from ..topics.models import Topic + return { - 'months': True, - 'topics': Topic.objects.live().public().order_by('title'), + "months": True, + "topics": Topic.objects.live().public().order_by("title"), } class Event(Page): - resource_type = 'event' - parent_page_types = ['events.Events'] + resource_type = "event" + parent_page_types = ["events.Events"] subpage_types = [] - template = 'event.html' + template = "event.html" # Content fields description = RichTextField( blank=True, - default='', + default="", features=RICH_TEXT_FEATURES_SIMPLE, - help_text='Optional short text description, max. 400 characters', + help_text="Optional short text description, max. 400 characters", max_length=400, ) image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', + related_name="+", + ) + body = CustomStreamField( + blank=True, + null=True, + help_text=( + "Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets" + ), ) - body = CustomStreamField(blank=True, null=True, help_text=( - 'Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets' - )) agenda = StreamField( - StreamBlock([ - ('agenda_item', AgendaItemBlock()), - ], required=False), + StreamBlock([("agenda_item", AgendaItemBlock())], required=False), blank=True, null=True, - help_text='Optional list of agenda items for this event', + help_text="Optional list of agenda items for this event", ) speakers = StreamField( - StreamBlock([ - ('speaker', PageChooserBlock(target_model='people.Person')), - ('external_speaker', ExternalSpeakerBlock()), - ], required=False), + StreamBlock( + [ + ("speaker", PageChooserBlock(target_model="people.Person")), + ("external_speaker", ExternalSpeakerBlock()), + ], + required=False, + ), blank=True, null=True, - help_text='Optional list of speakers for this event', + help_text="Optional list of speakers for this event", ) # Card fields - card_title = CharField('Title', max_length=140, blank=True, default='') - card_description = TextField('Description', max_length=400, blank=True, default='') + card_title = CharField("Title", max_length=140, blank=True, default="") + card_description = TextField("Description", max_length=400, blank=True, default="") card_image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', - verbose_name='Image', + related_name="+", + verbose_name="Image", ) # Meta fields @@ -195,92 +208,105 @@ class Event(Page): end_date = DateField(blank=True, null=True) latitude = FloatField(blank=True, null=True) longitude = FloatField(blank=True, null=True) - register_url = URLField('Register URL', blank=True, null=True) - venue_name = CharField(max_length=100, blank=True, default='') - venue_url = URLField('Venue URL', max_length=100, blank=True, default='') - address_line_1 = CharField(max_length=100, blank=True, default='') - address_line_2 = CharField(max_length=100, blank=True, default='') - address_line_3 = CharField(max_length=100, blank=True, default='') - city = CharField(max_length=100, blank=True, default='') - state = CharField('State/Province/Region', max_length=100, blank=True, default='') - zip_code = CharField('Zip/Postal code', max_length=100, blank=True, default='') - country = CountryField(blank=True, default='') + register_url = URLField("Register URL", blank=True, null=True) + venue_name = CharField(max_length=100, blank=True, default="") + venue_url = URLField("Venue URL", max_length=100, blank=True, default="") + address_line_1 = CharField(max_length=100, blank=True, default="") + address_line_2 = CharField(max_length=100, blank=True, default="") + address_line_3 = CharField(max_length=100, blank=True, default="") + city = CharField(max_length=100, blank=True, default="") + state = CharField("State/Province/Region", max_length=100, blank=True, default="") + zip_code = CharField("Zip/Postal code", max_length=100, blank=True, default="") + country = CountryField(blank=True, default="") keywords = ClusterTaggableManager(through=EventTag, blank=True) # Content panels content_panels = Page.content_panels + [ - FieldPanel('description'), - MultiFieldPanel([ - ImageChooserPanel('image'), - ], heading='Image', help_text=( - 'Optional header image. If not specified a fallback will be used. This image is also shown when sharing ' - 'this page via social media' - )), - StreamFieldPanel('body'), - StreamFieldPanel('agenda'), - StreamFieldPanel('speakers'), + FieldPanel("description"), + MultiFieldPanel( + [ImageChooserPanel("image")], + heading="Image", + help_text=( + "Optional header image. If not specified a fallback will be used. This image is also shown when sharing " + "this page via social media" + ), + ), + StreamFieldPanel("body"), + StreamFieldPanel("agenda"), + StreamFieldPanel("speakers"), ] # Card panels card_panels = [ - FieldPanel('card_title'), - FieldPanel('card_description'), - ImageChooserPanel('card_image'), + FieldPanel("card_title"), + FieldPanel("card_description"), + ImageChooserPanel("card_image"), ] # Meta panels meta_panels = [ - MultiFieldPanel([ - FieldPanel('start_date'), - FieldPanel('end_date'), - FieldPanel('latitude'), - FieldPanel('longitude'), - FieldPanel('register_url'), - ], heading='Event details', - classname='collapsible', + MultiFieldPanel( + [ + FieldPanel("start_date"), + FieldPanel("end_date"), + FieldPanel("latitude"), + FieldPanel("longitude"), + FieldPanel("register_url"), + ], + heading="Event details", + classname="collapsible", help_text=mark_safe( - 'Optional time and location information for this event. Latitude and longitude are used to show a map ' - 'of the event’s location. For more information on finding these values for a given location, ' + "Optional time and location information for this event. Latitude and longitude are used to show a map " + "of the event’s location. For more information on finding these values for a given location, " 'see this article' - )), - MultiFieldPanel([ - FieldPanel('venue_name'), - FieldPanel('venue_url'), - FieldPanel('address_line_1'), - FieldPanel('address_line_2'), - FieldPanel('address_line_3'), - FieldPanel('city'), - FieldPanel('state'), - FieldPanel('zip_code'), - FieldPanel('country'), - ], heading='Event address', - classname='collapsible', - help_text='Optional address fields. The city and country are also shown on event cards' + ), + ), + MultiFieldPanel( + [ + FieldPanel("venue_name"), + FieldPanel("venue_url"), + FieldPanel("address_line_1"), + FieldPanel("address_line_2"), + FieldPanel("address_line_3"), + FieldPanel("city"), + FieldPanel("state"), + FieldPanel("zip_code"), + FieldPanel("country"), + ], + heading="Event address", + classname="collapsible", + help_text="Optional address fields. The city and country are also shown on event cards", + ), + MultiFieldPanel( + [InlinePanel("topics")], + heading="Topics", + help_text=( + "These are the topic pages the event will appear on. The first topic in the list will be treated as the " + "primary topic and will be shown in the page’s related content." + ), + ), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", ), - MultiFieldPanel([ - InlinePanel('topics'), - ], heading='Topics', help_text=( - 'These are the topic pages the event will appear on. The first topic in the list will be treated as the ' - 'primary topic and will be shown in the page’s related content.' - )), - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - ] - - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + settings_panels = [FieldPanel("slug")] + + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) @property def is_upcoming(self): @@ -317,6 +343,8 @@ def event_dates_full(self): def has_speaker(self, person): for speaker in self.speakers: # pylint: disable=not-an-iterable - if (speaker.block_type == 'speaker' and str(speaker.value) == str(person.title)): + if speaker.block_type == "speaker" and str(speaker.value) == str( + person.title + ): return True return False diff --git a/developerportal/apps/events/wagtail_hooks.py b/developerportal/apps/events/wagtail_hooks.py index c7d920099..ddba15b0b 100644 --- a/developerportal/apps/events/wagtail_hooks.py +++ b/developerportal/apps/events/wagtail_hooks.py @@ -6,7 +6,7 @@ class EventsAdmin(ModelAdmin): model = Events - menu_icon = 'date' + menu_icon = "date" menu_order = 220 url_helper_class = ExplorerRedirectAdminURLHelper diff --git a/developerportal/apps/externalcontent/migrations/0001_initial.py b/developerportal/apps/externalcontent/migrations/0001_initial.py index 1d778f0ea..3bc85e61b 100644 --- a/developerportal/apps/externalcontent/migrations/0001_initial.py +++ b/developerportal/apps/externalcontent/migrations/0001_initial.py @@ -9,19 +9,27 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural") ] operations = [ migrations.CreateModel( - name='ExternalContent', + name="ExternalContent", 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')), - ('url', models.URLField(blank=True, default='', max_length=2048)), + ( + "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", + ), + ), + ("url", models.URLField(blank=True, default="", max_length=2048)), ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), - ), + options={"abstract": False}, + bases=("wagtailcore.page",), + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0002_auto_20190704_1221.py b/developerportal/apps/externalcontent/migrations/0002_auto_20190704_1221.py index 7ec69eff0..af426d38d 100644 --- a/developerportal/apps/externalcontent/migrations/0002_auto_20190704_1221.py +++ b/developerportal/apps/externalcontent/migrations/0002_auto_20190704_1221.py @@ -5,14 +5,10 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0001_initial'), - ] + dependencies = [("externalcontent", "0001_initial")] operations = [ migrations.RenameField( - model_name='externalcontent', - old_name='url', - new_name='external_url', - ), + model_name="externalcontent", old_name="url", new_name="external_url" + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0003_externalarticle_externalevent_externalvideo.py b/developerportal/apps/externalcontent/migrations/0003_externalarticle_externalevent_externalvideo.py index 707b30b41..aef96c16a 100644 --- a/developerportal/apps/externalcontent/migrations/0003_externalarticle_externalevent_externalvideo.py +++ b/developerportal/apps/externalcontent/migrations/0003_externalarticle_externalevent_externalvideo.py @@ -6,39 +6,61 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0002_auto_20190704_1221'), - ] + dependencies = [("externalcontent", "0002_auto_20190704_1221")] operations = [ migrations.CreateModel( - name='ExternalArticle', + name="ExternalArticle", fields=[ - ('externalcontent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='externalcontent.ExternalContent')), + ( + "externalcontent_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="externalcontent.ExternalContent", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('externalcontent.externalcontent',), + options={"abstract": False}, + bases=("externalcontent.externalcontent",), ), migrations.CreateModel( - name='ExternalEvent', + name="ExternalEvent", fields=[ - ('externalcontent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='externalcontent.ExternalContent')), + ( + "externalcontent_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="externalcontent.ExternalContent", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('externalcontent.externalcontent',), + options={"abstract": False}, + bases=("externalcontent.externalcontent",), ), migrations.CreateModel( - name='ExternalVideo', + name="ExternalVideo", fields=[ - ('externalcontent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='externalcontent.ExternalContent')), + ( + "externalcontent_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="externalcontent.ExternalContent", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('externalcontent.externalcontent',), + options={"abstract": False}, + bases=("externalcontent.externalcontent",), ), ] diff --git a/developerportal/apps/externalcontent/migrations/0004_auto_20190705_1306.py b/developerportal/apps/externalcontent/migrations/0004_auto_20190705_1306.py index 6d6e76481..d3a36d245 100644 --- a/developerportal/apps/externalcontent/migrations/0004_auto_20190705_1306.py +++ b/developerportal/apps/externalcontent/migrations/0004_auto_20190705_1306.py @@ -6,18 +6,18 @@ class Migration(migrations.Migration): dependencies = [ - ('externalcontent', '0003_externalarticle_externalevent_externalvideo'), + ("externalcontent", "0003_externalarticle_externalevent_externalvideo") ] operations = [ migrations.AddField( - model_name='externalarticle', - name='readtime', - field=models.CharField(blank=True, default='0 min read', max_length=30), + model_name="externalarticle", + name="readtime", + field=models.CharField(blank=True, default="0 min read", max_length=30), ), migrations.AddField( - model_name='externalvideo', - name='video_duration', - field=models.CharField(blank=True, default='0:00', max_length=30), + model_name="externalvideo", + name="video_duration", + field=models.CharField(blank=True, default="0:00", max_length=30), ), ] diff --git a/developerportal/apps/externalcontent/migrations/0005_auto_20190709_1412.py b/developerportal/apps/externalcontent/migrations/0005_auto_20190709_1412.py index 9bd9c18ea..846ad03ab 100644 --- a/developerportal/apps/externalcontent/migrations/0005_auto_20190709_1412.py +++ b/developerportal/apps/externalcontent/migrations/0005_auto_20190709_1412.py @@ -7,19 +7,23 @@ class Migration(migrations.Migration): dependencies = [ - ('mozimages', '0001_initial'), - ('externalcontent', '0004_auto_20190705_1306'), + ("mozimages", "0001_initial"), + ("externalcontent", "0004_auto_20190705_1306"), ] operations = [ migrations.RenameField( - model_name='externalarticle', - old_name='readtime', - new_name='read_time', + model_name="externalarticle", old_name="readtime", new_name="read_time" ), migrations.AddField( - model_name='externalcontent', - name='header_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage'), + model_name="externalcontent", + name="header_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), ), ] diff --git a/developerportal/apps/externalcontent/migrations/0006_auto_20190709_1420.py b/developerportal/apps/externalcontent/migrations/0006_auto_20190709_1420.py index b888b2d49..af3e084d9 100644 --- a/developerportal/apps/externalcontent/migrations/0006_auto_20190709_1420.py +++ b/developerportal/apps/externalcontent/migrations/0006_auto_20190709_1420.py @@ -6,24 +6,22 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0005_auto_20190709_1412'), - ] + dependencies = [("externalcontent", "0005_auto_20190709_1412")] operations = [ migrations.AddField( - model_name='externalevent', - name='end_date', + model_name="externalevent", + name="end_date", field=models.DateField(blank=True, null=True), ), migrations.AddField( - model_name='externalevent', - name='start_date', + model_name="externalevent", + name="start_date", field=models.DateField(default=datetime.date.today), ), migrations.AddField( - model_name='externalevent', - name='venue', - field=models.TextField(blank=True, default='', max_length=250), + model_name="externalevent", + name="venue", + field=models.TextField(blank=True, default="", max_length=250), ), ] diff --git a/developerportal/apps/externalcontent/migrations/0007_auto_20190711_1940.py b/developerportal/apps/externalcontent/migrations/0007_auto_20190711_1940.py index 7e88b38ef..62c251fd1 100644 --- a/developerportal/apps/externalcontent/migrations/0007_auto_20190711_1940.py +++ b/developerportal/apps/externalcontent/migrations/0007_auto_20190711_1940.py @@ -5,24 +5,22 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0006_auto_20190709_1420'), - ] + dependencies = [("externalcontent", "0006_auto_20190709_1420")] operations = [ migrations.RenameField( - model_name='externalcontent', - old_name='header_image', - new_name='image', + model_name="externalcontent", old_name="header_image", new_name="image" ), migrations.AlterField( - model_name='externalarticle', - name='read_time', + model_name="externalarticle", + name="read_time", field=models.CharField(blank=True, max_length=30), ), migrations.AlterField( - model_name='externalcontent', - name='external_url', - field=models.URLField(blank=True, default='', max_length=2048, verbose_name='URL'), + model_name="externalcontent", + name="external_url", + field=models.URLField( + blank=True, default="", max_length=2048, verbose_name="URL" + ), ), ] diff --git a/developerportal/apps/externalcontent/migrations/0008_externalcontent_description.py b/developerportal/apps/externalcontent/migrations/0008_externalcontent_description.py index 93da187aa..df687d4ef 100644 --- a/developerportal/apps/externalcontent/migrations/0008_externalcontent_description.py +++ b/developerportal/apps/externalcontent/migrations/0008_externalcontent_description.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0007_auto_20190711_1940'), - ] + dependencies = [("externalcontent", "0007_auto_20190711_1940")] operations = [ migrations.AddField( - model_name='externalcontent', - name='description', - field=models.TextField(blank=True, default='', max_length=250), - ), + model_name="externalcontent", + name="description", + field=models.TextField(blank=True, default="", max_length=250), + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0009_externalarticleauthor.py b/developerportal/apps/externalcontent/migrations/0009_externalarticleauthor.py index f02555967..4fb7f0e49 100644 --- a/developerportal/apps/externalcontent/migrations/0009_externalarticleauthor.py +++ b/developerportal/apps/externalcontent/migrations/0009_externalarticleauthor.py @@ -7,22 +7,42 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0008_externalcontent_description'), - ] + dependencies = [("externalcontent", "0008_externalcontent_description")] operations = [ migrations.CreateModel( - name='ExternalArticleAuthor', + name="ExternalArticleAuthor", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='authors', to='externalcontent.ExternalArticle')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_articles', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="authors", + to="externalcontent.ExternalArticle", + ), + ), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_articles", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, - ), + options={"ordering": ["sort_order"], "abstract": False}, + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0010_auto_20190723_1659.py b/developerportal/apps/externalcontent/migrations/0010_auto_20190723_1659.py index 776f9e1cd..5cef308e1 100644 --- a/developerportal/apps/externalcontent/migrations/0010_auto_20190723_1659.py +++ b/developerportal/apps/externalcontent/migrations/0010_auto_20190723_1659.py @@ -9,68 +9,142 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0017_auto_20190718_1424'), - ('topics', '0034_auto_20190718_1504'), - ('externalcontent', '0009_externalarticleauthor'), + ("people", "0017_auto_20190718_1424"), + ("topics", "0034_auto_20190718_1504"), + ("externalcontent", "0009_externalarticleauthor"), ] operations = [ - migrations.RemoveField( - model_name='externalevent', - name='venue', - ), + migrations.RemoveField(model_name="externalevent", name="venue"), migrations.AddField( - model_name='externalarticle', - name='date', - field=models.DateField(default=datetime.date.today, verbose_name='Article date'), + model_name="externalarticle", + name="date", + field=models.DateField( + default=datetime.date.today, verbose_name="Article date" + ), ), migrations.AddField( - model_name='externalevent', - name='location', - field=models.CharField(blank=True, default='', help_text='Location details (city and country), displayed on event cards', max_length=100), + model_name="externalevent", + name="location", + field=models.CharField( + blank=True, + default="", + help_text="Location details (city and country), displayed on event cards", + max_length=100, + ), ), migrations.AlterField( - model_name='externalarticle', - name='read_time', - field=models.CharField(blank=True, help_text='Optional, approximate read-time for this article, e.g. “2 mins”. This is shown as a small hint when the article is displayed as a card.', max_length=30), + model_name="externalarticle", + name="read_time", + field=models.CharField( + blank=True, + help_text="Optional, approximate read-time for this article, e.g. “2 mins”. This is shown as a small hint when the article is displayed as a card.", + max_length=30, + ), ), migrations.CreateModel( - name='ExternalEventTopic', + name="ExternalEventTopic", 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)), - ('event', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='externalcontent.ExternalEvent')), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_events', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "event", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="externalcontent.ExternalEvent", + ), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_events", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='ExternalEventSpeaker', + name="ExternalEventSpeaker", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='speakers', to='externalcontent.ExternalEvent')), - ('speaker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_events', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="speakers", + to="externalcontent.ExternalEvent", + ), + ), + ( + "speaker", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_events", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='ExternalArticleTopic', + name="ExternalArticleTopic", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='externalcontent.ExternalArticle')), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_articles', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="externalcontent.ExternalArticle", + ), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_articles", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/externalcontent/migrations/0011_auto_20190723_1719.py b/developerportal/apps/externalcontent/migrations/0011_auto_20190723_1719.py index 02e55b809..fc51d8b87 100644 --- a/developerportal/apps/externalcontent/migrations/0011_auto_20190723_1719.py +++ b/developerportal/apps/externalcontent/migrations/0011_auto_20190723_1719.py @@ -9,46 +9,97 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0034_auto_20190718_1504'), - ('people', '0018_people_keywords'), - ('externalcontent', '0010_auto_20190723_1659'), + ("topics", "0034_auto_20190718_1504"), + ("people", "0018_people_keywords"), + ("externalcontent", "0010_auto_20190723_1659"), ] operations = [ migrations.AddField( - model_name='externalvideo', - name='date', - field=models.DateField(default=datetime.date.today, verbose_name='Video date'), + model_name="externalvideo", + name="date", + field=models.DateField( + default=datetime.date.today, verbose_name="Video date" + ), ), migrations.AlterField( - model_name='externalvideo', - name='video_duration', - field=models.CharField(blank=True, help_text='Optional, duration for this video in MM:SS format e.g. “12:34”. This is shown as a small hint when the video is displayed as a card.', max_length=30, null=True), + model_name="externalvideo", + name="video_duration", + field=models.CharField( + blank=True, + help_text="Optional, duration for this video in MM:SS format e.g. “12:34”. This is shown as a small hint when the video is displayed as a card.", + max_length=30, + null=True, + ), ), migrations.CreateModel( - name='ExternalVideoTopic', + name="ExternalVideoTopic", 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)), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_videos', to='topics.Topic')), - ('video', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='externalcontent.ExternalVideo')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_videos", + to="topics.Topic", + ), + ), + ( + "video", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="externalcontent.ExternalVideo", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='ExternalVideoPerson', + name="ExternalVideoPerson", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='people', to='externalcontent.ExternalVideo')), - ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_videos', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="people", + to="externalcontent.ExternalVideo", + ), + ), + ( + "person", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_videos", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/externalcontent/migrations/0012_auto_20190724_1437.py b/developerportal/apps/externalcontent/migrations/0012_auto_20190724_1437.py index 023aabe18..f68760ff6 100644 --- a/developerportal/apps/externalcontent/migrations/0012_auto_20190724_1437.py +++ b/developerportal/apps/externalcontent/migrations/0012_auto_20190724_1437.py @@ -5,13 +5,10 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0011_auto_20190723_1719'), - ] + dependencies = [("externalcontent", "0011_auto_20190723_1719")] operations = [ migrations.AlterModelOptions( - name='externalcontent', - options={'verbose_name_plural': 'External Content'}, - ), + name="externalcontent", options={"verbose_name_plural": "External Content"} + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0013_externalevent_venue.py b/developerportal/apps/externalcontent/migrations/0013_externalevent_venue.py index d8214e925..5571db3e4 100644 --- a/developerportal/apps/externalcontent/migrations/0013_externalevent_venue.py +++ b/developerportal/apps/externalcontent/migrations/0013_externalevent_venue.py @@ -5,14 +5,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0012_auto_20190724_1437'), - ] + dependencies = [("externalcontent", "0012_auto_20190724_1437")] operations = [ migrations.AddField( - model_name='externalevent', - name='venue', - field=models.TextField(blank=True, default='', help_text='Full address of the event venue, displayed on the event detail page', max_length=250), - ), + model_name="externalevent", + name="venue", + field=models.TextField( + blank=True, + default="", + help_text="Full address of the event venue, displayed on the event detail page", + max_length=250, + ), + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0014_auto_20190725_1225.py b/developerportal/apps/externalcontent/migrations/0014_auto_20190725_1225.py index c86c8188d..aae050841 100644 --- a/developerportal/apps/externalcontent/migrations/0014_auto_20190725_1225.py +++ b/developerportal/apps/externalcontent/migrations/0014_auto_20190725_1225.py @@ -5,102 +5,43 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0013_externalevent_venue'), - ] + dependencies = [("externalcontent", "0013_externalevent_venue")] operations = [ - migrations.RemoveField( - model_name='externalarticletopic', - name='article', - ), - migrations.RemoveField( - model_name='externalarticletopic', - name='topic', - ), - migrations.RemoveField( - model_name='externaleventspeaker', - name='article', - ), - migrations.RemoveField( - model_name='externaleventspeaker', - name='speaker', - ), - migrations.RemoveField( - model_name='externaleventtopic', - name='event', - ), - migrations.RemoveField( - model_name='externaleventtopic', - name='topic', - ), - migrations.RemoveField( - model_name='externalvideoperson', - name='article', - ), - migrations.RemoveField( - model_name='externalvideoperson', - name='person', - ), - migrations.RemoveField( - model_name='externalvideotopic', - name='topic', - ), - migrations.RemoveField( - model_name='externalvideotopic', - name='video', - ), - migrations.AlterModelOptions( - name='externalcontent', - options={}, - ), - migrations.RemoveField( - model_name='externalarticle', - name='date', - ), - migrations.RemoveField( - model_name='externalcontent', - name='description', - ), - migrations.RemoveField( - model_name='externalevent', - name='location', - ), - migrations.RemoveField( - model_name='externalvideo', - name='date', - ), + migrations.RemoveField(model_name="externalarticletopic", name="article"), + migrations.RemoveField(model_name="externalarticletopic", name="topic"), + migrations.RemoveField(model_name="externaleventspeaker", name="article"), + migrations.RemoveField(model_name="externaleventspeaker", name="speaker"), + migrations.RemoveField(model_name="externaleventtopic", name="event"), + migrations.RemoveField(model_name="externaleventtopic", name="topic"), + migrations.RemoveField(model_name="externalvideoperson", name="article"), + migrations.RemoveField(model_name="externalvideoperson", name="person"), + migrations.RemoveField(model_name="externalvideotopic", name="topic"), + migrations.RemoveField(model_name="externalvideotopic", name="video"), + migrations.AlterModelOptions(name="externalcontent", options={}), + migrations.RemoveField(model_name="externalarticle", name="date"), + migrations.RemoveField(model_name="externalcontent", name="description"), + migrations.RemoveField(model_name="externalevent", name="location"), + migrations.RemoveField(model_name="externalvideo", name="date"), migrations.AlterField( - model_name='externalarticle', - name='read_time', + model_name="externalarticle", + name="read_time", field=models.CharField(blank=True, max_length=30), ), migrations.AlterField( - model_name='externalevent', - name='venue', - field=models.TextField(blank=True, default='', max_length=250), + model_name="externalevent", + name="venue", + field=models.TextField(blank=True, default="", max_length=250), ), migrations.AlterField( - model_name='externalvideo', - name='video_duration', - field=models.CharField(blank=True, default='0:00', max_length=30), - ), - migrations.DeleteModel( - name='ExternalArticleAuthor', - ), - migrations.DeleteModel( - name='ExternalArticleTopic', - ), - migrations.DeleteModel( - name='ExternalEventSpeaker', - ), - migrations.DeleteModel( - name='ExternalEventTopic', - ), - migrations.DeleteModel( - name='ExternalVideoPerson', - ), - migrations.DeleteModel( - name='ExternalVideoTopic', - ), + model_name="externalvideo", + name="video_duration", + field=models.CharField(blank=True, default="0:00", max_length=30), + ), + migrations.DeleteModel(name="ExternalArticleAuthor"), + migrations.DeleteModel(name="ExternalArticleTopic"), + migrations.DeleteModel(name="ExternalEventSpeaker"), + migrations.DeleteModel(name="ExternalEventTopic"), + migrations.DeleteModel(name="ExternalVideoPerson"), + migrations.DeleteModel(name="ExternalVideoTopic"), ] diff --git a/developerportal/apps/externalcontent/migrations/0015_auto_20190725_1226.py b/developerportal/apps/externalcontent/migrations/0015_auto_20190725_1226.py index 867a5182c..2884a3137 100644 --- a/developerportal/apps/externalcontent/migrations/0015_auto_20190725_1226.py +++ b/developerportal/apps/externalcontent/migrations/0015_auto_20190725_1226.py @@ -9,127 +9,281 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0036_auto_20190725_1226'), - ('people', '0019_remove_people_keywords'), - ('externalcontent', '0014_auto_20190725_1225'), + ("topics", "0036_auto_20190725_1226"), + ("people", "0019_remove_people_keywords"), + ("externalcontent", "0014_auto_20190725_1225"), ] operations = [ migrations.AlterModelOptions( - name='externalcontent', - options={'verbose_name_plural': 'External Content'}, + name="externalcontent", options={"verbose_name_plural": "External Content"} ), migrations.AddField( - model_name='externalarticle', - name='date', - field=models.DateField(default=datetime.date.today, verbose_name='Article date'), + model_name="externalarticle", + name="date", + field=models.DateField( + default=datetime.date.today, verbose_name="Article date" + ), ), migrations.AddField( - model_name='externalcontent', - name='description', - field=models.TextField(blank=True, default='', max_length=250), + model_name="externalcontent", + name="description", + field=models.TextField(blank=True, default="", max_length=250), ), migrations.AddField( - model_name='externalevent', - name='location', - field=models.CharField(blank=True, default='', help_text='Location details (city and country), displayed on event cards', max_length=100), + model_name="externalevent", + name="location", + field=models.CharField( + blank=True, + default="", + help_text="Location details (city and country), displayed on event cards", + max_length=100, + ), ), migrations.AddField( - model_name='externalvideo', - name='date', - field=models.DateField(default=datetime.date.today, verbose_name='Video date'), + model_name="externalvideo", + name="date", + field=models.DateField( + default=datetime.date.today, verbose_name="Video date" + ), ), migrations.AlterField( - model_name='externalarticle', - name='read_time', - field=models.CharField(blank=True, help_text='Optional, approximate read-time for this article, e.g. “2 mins”. This is shown as a small hint when the article is displayed as a card.', max_length=30), + model_name="externalarticle", + name="read_time", + field=models.CharField( + blank=True, + help_text="Optional, approximate read-time for this article, e.g. “2 mins”. This is shown as a small hint when the article is displayed as a card.", + max_length=30, + ), ), migrations.AlterField( - model_name='externalevent', - name='venue', - field=models.TextField(blank=True, default='', help_text='Full address of the event venue, displayed on the event detail page', max_length=250), + model_name="externalevent", + name="venue", + field=models.TextField( + blank=True, + default="", + help_text="Full address of the event venue, displayed on the event detail page", + max_length=250, + ), ), migrations.AlterField( - model_name='externalvideo', - name='video_duration', - field=models.CharField(blank=True, help_text='Optional, duration for this video in MM:SS format e.g. “12:34”. This is shown as a small hint when the video is displayed as a card.', max_length=30, null=True), + model_name="externalvideo", + name="video_duration", + field=models.CharField( + blank=True, + help_text="Optional, duration for this video in MM:SS format e.g. “12:34”. This is shown as a small hint when the video is displayed as a card.", + max_length=30, + null=True, + ), ), migrations.CreateModel( - name='ExternalVideoTopic', + name="ExternalVideoTopic", 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)), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_videos', to='topics.Topic')), - ('video', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='externalcontent.ExternalVideo')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_videos", + to="topics.Topic", + ), + ), + ( + "video", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="externalcontent.ExternalVideo", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='ExternalVideoPerson', + name="ExternalVideoPerson", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='people', to='externalcontent.ExternalVideo')), - ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_videos', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="people", + to="externalcontent.ExternalVideo", + ), + ), + ( + "person", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_videos", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='ExternalEventTopic', + name="ExternalEventTopic", 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)), - ('event', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='externalcontent.ExternalEvent')), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_events', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "event", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="externalcontent.ExternalEvent", + ), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_events", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='ExternalEventSpeaker', + name="ExternalEventSpeaker", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='speakers', to='externalcontent.ExternalEvent')), - ('speaker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_events', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="speakers", + to="externalcontent.ExternalEvent", + ), + ), + ( + "speaker", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_events", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='ExternalArticleTopic', + name="ExternalArticleTopic", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='externalcontent.ExternalArticle')), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_articles', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="externalcontent.ExternalArticle", + ), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_articles", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='ExternalArticleAuthor', + name="ExternalArticleAuthor", 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)), - ('article', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='authors', to='externalcontent.ExternalArticle')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_articles', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="authors", + to="externalcontent.ExternalArticle", + ), + ), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="external_articles", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/externalcontent/migrations/0016_auto_20190731_1226.py b/developerportal/apps/externalcontent/migrations/0016_auto_20190731_1226.py index 53c4ceb37..27301112e 100644 --- a/developerportal/apps/externalcontent/migrations/0016_auto_20190731_1226.py +++ b/developerportal/apps/externalcontent/migrations/0016_auto_20190731_1226.py @@ -8,17 +8,39 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0015_auto_20190725_1226'), - ] + dependencies = [("externalcontent", "0015_auto_20190725_1226")] operations = [ migrations.AddField( - model_name='externalarticle', - name='authors', - field=wagtail.core.fields.StreamField([('author', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'])), ('external_author', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('image', wagtail.images.blocks.ImageChooserBlock()), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))]))], blank=True, null=True), - ), - migrations.DeleteModel( - name='ExternalArticleAuthor', + model_name="externalarticle", + name="authors", + field=wagtail.core.fields.StreamField( + [ + ( + "author", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"] + ), + ), + ( + "external_author", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + ), ), + migrations.DeleteModel(name="ExternalArticleAuthor"), ] diff --git a/developerportal/apps/externalcontent/migrations/0017_auto_20190806_1041.py b/developerportal/apps/externalcontent/migrations/0017_auto_20190806_1041.py index 2e2fb001a..408e47bb0 100644 --- a/developerportal/apps/externalcontent/migrations/0017_auto_20190806_1041.py +++ b/developerportal/apps/externalcontent/migrations/0017_auto_20190806_1041.py @@ -7,19 +7,26 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0016_auto_20190731_1226'), - ] + dependencies = [("externalcontent", "0016_auto_20190731_1226")] operations = [ migrations.RenameField( - model_name='externalvideo', - old_name='video_duration', - new_name='duration', + model_name="externalvideo", old_name="video_duration", new_name="duration" ), migrations.AddField( - model_name='externalvideo', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False))], blank=True, null=True), + model_name="externalvideo", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ) + ], + blank=True, + null=True, + ), ), ] diff --git a/developerportal/apps/externalcontent/migrations/0018_auto_20190807_1244.py b/developerportal/apps/externalcontent/migrations/0018_auto_20190807_1244.py index cc65644ab..d50b7815f 100644 --- a/developerportal/apps/externalcontent/migrations/0018_auto_20190807_1244.py +++ b/developerportal/apps/externalcontent/migrations/0018_auto_20190807_1244.py @@ -5,14 +5,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0017_auto_20190806_1041'), - ] + dependencies = [("externalcontent", "0017_auto_20190806_1041")] operations = [ migrations.AlterField( - model_name='externalvideo', - name='duration', - field=models.CharField(blank=True, help_text='Optional. Video duration in MM:SS format e.g. “12:34”. Shown as a small hint when the video is displayed as a card.', max_length=30, null=True), - ), + model_name="externalvideo", + name="duration", + field=models.CharField( + blank=True, + help_text="Optional. Video duration in MM:SS format e.g. “12:34”. Shown as a small hint when the video is displayed as a card.", + max_length=30, + null=True, + ), + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0019_auto_20190813_1302.py b/developerportal/apps/externalcontent/migrations/0019_auto_20190813_1302.py index 3f52b5ca6..23ffb5044 100644 --- a/developerportal/apps/externalcontent/migrations/0019_auto_20190813_1302.py +++ b/developerportal/apps/externalcontent/migrations/0019_auto_20190813_1302.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0018_auto_20190807_1244'), - ] + dependencies = [("externalcontent", "0018_auto_20190807_1244")] operations = [ migrations.AlterField( - model_name='externalcontent', - name='description', - field=models.TextField(blank=True, default='', max_length=400), - ), + model_name="externalcontent", + name="description", + field=models.TextField(blank=True, default="", max_length=400), + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0020_auto_20190813_1503.py b/developerportal/apps/externalcontent/migrations/0020_auto_20190813_1503.py index 3ff4925df..950f4b584 100644 --- a/developerportal/apps/externalcontent/migrations/0020_auto_20190813_1503.py +++ b/developerportal/apps/externalcontent/migrations/0020_auto_20190813_1503.py @@ -9,54 +9,122 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0019_auto_20190813_1302'), - ] + dependencies = [("externalcontent", "0019_auto_20190813_1302")] operations = [ migrations.AlterField( - model_name='externalarticle', - name='authors', - field=wagtail.core.fields.StreamField([('author', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'])), ('external_author', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('image', wagtail.images.blocks.ImageChooserBlock()), ('url', wagtail.core.blocks.URLBlock(label='URL', required=False))]))], blank=True, help_text='Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a profile on the system', null=True), + model_name="externalarticle", + name="authors", + field=wagtail.core.fields.StreamField( + [ + ( + "author", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"] + ), + ), + ( + "external_author", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "url", + wagtail.core.blocks.URLBlock( + label="URL", required=False + ), + ), + ] + ), + ), + ], + blank=True, + help_text="Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a profile on the system", + null=True, + ), ), migrations.AlterField( - model_name='externalarticle', - name='date', - field=models.DateField(default=datetime.date.today, help_text='The date the article was published', verbose_name='Article date'), + model_name="externalarticle", + name="date", + field=models.DateField( + default=datetime.date.today, + help_text="The date the article was published", + verbose_name="Article date", + ), ), migrations.AlterField( - model_name='externalcontent', - name='description', - field=models.TextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="externalcontent", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), migrations.AlterField( - model_name='externalcontent', - name='external_url', - field=models.URLField(blank=True, default='', help_text='The URL that this content links to, max. 2048 characters for compatibility with older web browsers', max_length=2048, verbose_name='URL'), + model_name="externalcontent", + name="external_url", + field=models.URLField( + blank=True, + default="", + help_text="The URL that this content links to, max. 2048 characters for compatibility with older web browsers", + max_length=2048, + verbose_name="URL", + ), ), migrations.AlterField( - model_name='externalevent', - name='end_date', - field=models.DateField(blank=True, help_text='The date the event is scheduled to end', null=True), + model_name="externalevent", + name="end_date", + field=models.DateField( + blank=True, + help_text="The date the event is scheduled to end", + null=True, + ), ), migrations.AlterField( - model_name='externalevent', - name='start_date', - field=models.DateField(default=datetime.date.today, help_text='The date the event is scheduled to start'), + model_name="externalevent", + name="start_date", + field=models.DateField( + default=datetime.date.today, + help_text="The date the event is scheduled to start", + ), ), migrations.AlterField( - model_name='externalvideo', - name='date', - field=models.DateField(default=datetime.date.today, help_text='The date the video was published', verbose_name='Video date'), + model_name="externalvideo", + name="date", + field=models.DateField( + default=datetime.date.today, + help_text="The date the video was published", + verbose_name="Video date", + ), ), migrations.AlterField( - model_name='externalvideo', - name='duration', - field=models.CharField(blank=True, help_text='Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card', max_length=30, null=True), + model_name="externalvideo", + name="duration", + field=models.CharField( + blank=True, + help_text="Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card", + max_length=30, + null=True, + ), ), migrations.AlterField( - model_name='externalvideo', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False))], blank=True, help_text='Optional list of people associated with or starring in the video', null=True), + model_name="externalvideo", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ) + ], + blank=True, + help_text="Optional list of people associated with or starring in the video", + null=True, + ), ), ] diff --git a/developerportal/apps/externalcontent/migrations/0021_auto_20190814_1600.py b/developerportal/apps/externalcontent/migrations/0021_auto_20190814_1600.py index d445660f3..ba25dea63 100644 --- a/developerportal/apps/externalcontent/migrations/0021_auto_20190814_1600.py +++ b/developerportal/apps/externalcontent/migrations/0021_auto_20190814_1600.py @@ -7,14 +7,24 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0020_auto_20190813_1503'), - ] + dependencies = [("externalcontent", "0020_auto_20190813_1503")] operations = [ migrations.AlterField( - model_name='externalvideo', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person']))], blank=True, help_text='Optional list of people associated with or starring in the video', null=True), - ), + model_name="externalvideo", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"] + ), + ) + ], + blank=True, + help_text="Optional list of people associated with or starring in the video", + null=True, + ), + ) ] diff --git a/developerportal/apps/externalcontent/migrations/0022_auto_20190819_1304.py b/developerportal/apps/externalcontent/migrations/0022_auto_20190819_1304.py index 5cc54fdc1..ad4ee7d48 100644 --- a/developerportal/apps/externalcontent/migrations/0022_auto_20190819_1304.py +++ b/developerportal/apps/externalcontent/migrations/0022_auto_20190819_1304.py @@ -6,14 +6,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('externalcontent', '0021_auto_20190814_1600'), - ] + dependencies = [("externalcontent", "0021_auto_20190814_1600")] operations = [ migrations.AlterField( - model_name='externalcontent', - name='description', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), - ), + model_name="externalcontent", + name="description", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), + ) ] diff --git a/developerportal/apps/externalcontent/models.py b/developerportal/apps/externalcontent/models.py index 04606cca4..d1071241c 100644 --- a/developerportal/apps/externalcontent/models.py +++ b/developerportal/apps/externalcontent/models.py @@ -1,7 +1,15 @@ # pylint: disable=no-member import datetime -from django.db.models import CASCADE, CharField, DateField, ForeignKey, SET_NULL, TextField, URLField +from django.db.models import ( + CASCADE, + CharField, + DateField, + ForeignKey, + SET_NULL, + TextField, + URLField, +) from modelcluster.fields import ParentalKey @@ -30,44 +38,48 @@ class ExternalContent(Page): # Card fields description = RichTextField( blank=True, - default='', + default="", features=RICH_TEXT_FEATURES_SIMPLE, - help_text='Optional short text description, max. 400 characters', + help_text="Optional short text description, max. 400 characters", max_length=400, ) external_url = URLField( - 'URL', + "URL", blank=True, - default='', - help_text='The URL that this content links to, max. 2048 characters for compatibility with older web browsers', + default="", + help_text="The URL that this content links to, max. 2048 characters for compatibility with older web browsers", max_length=2048, ) image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+' + related_name="+", ) card_panels = Page.content_panels + [ - FieldPanel('description'), - MultiFieldPanel([ - ImageChooserPanel('image'), - ], heading='Image', help_text=( - 'Optional header image. If not specified a fallback will be used. This image is also shown when sharing ' - 'this page via social media' - )), - FieldPanel('external_url'), + FieldPanel("description"), + MultiFieldPanel( + [ImageChooserPanel("image")], + heading="Image", + help_text=( + "Optional header image. If not specified a fallback will be used. This image is also shown when sharing " + "this page via social media" + ), + ), + FieldPanel("external_url"), ] - edit_handler = TabbedInterface([ - ObjectList(card_panels, heading='Card'), - ObjectList(Page.settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(card_panels, heading="Card"), + ObjectList(Page.settings_panels, heading="Settings", classname="settings"), + ] + ) class Meta: - verbose_name_plural = 'External Content' + verbose_name_plural = "External Content" def get_full_url(self, request=None): return self.external_url @@ -84,49 +96,64 @@ def url(self): class ExternalArticleTopic(Orderable): - article = ParentalKey('ExternalArticle', on_delete=CASCADE, related_name='topics') - topic = ForeignKey('topics.Topic', on_delete=CASCADE, related_name='external_articles') + article = ParentalKey("ExternalArticle", on_delete=CASCADE, related_name="topics") + topic = ForeignKey( + "topics.Topic", on_delete=CASCADE, related_name="external_articles" + ) - panels = [ - PageChooserPanel('topic') - ] + panels = [PageChooserPanel("topic")] class ExternalArticle(ExternalContent): - resource_type = 'article' + resource_type = "article" - date = DateField('Article date', default=datetime.date.today, help_text='The date the article was published') + date = DateField( + "Article date", + default=datetime.date.today, + help_text="The date the article was published", + ) authors = StreamField( - StreamBlock([ - ('author', PageChooserBlock(target_model='people.Person')), - ('external_author', ExternalAuthorBlock()), - ], required=False), + StreamBlock( + [ + ("author", PageChooserBlock(target_model="people.Person")), + ("external_author", ExternalAuthorBlock()), + ], + required=False, + ), blank=True, null=True, help_text=( - 'Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a ' - 'profile on the system' + "Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a " + "profile on the system" + ), + ) + read_time = CharField( + max_length=30, + blank=True, + help_text=( + "Optional, approximate read-time for this article, e.g. “2 mins”. This " + "is shown as a small hint when the article is displayed as a card." ), ) - read_time = CharField(max_length=30, blank=True, help_text=( - 'Optional, approximate read-time for this article, e.g. “2 mins”. This ' - 'is shown as a small hint when the article is displayed as a card.' - )) meta_panels = [ - FieldPanel('date'), - StreamFieldPanel('authors'), - MultiFieldPanel([ - InlinePanel('topics'), - ], heading='Topics', help_text='The topic pages this article will appear on'), - FieldPanel('read_time'), + FieldPanel("date"), + StreamFieldPanel("authors"), + MultiFieldPanel( + [InlinePanel("topics")], + heading="Topics", + help_text="The topic pages this article will appear on", + ), + FieldPanel("read_time"), ] - edit_handler = TabbedInterface([ - ObjectList(ExternalContent.card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(Page.settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(ExternalContent.card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(Page.settings_panels, heading="Settings", classname="settings"), + ] + ) @property def article(self): @@ -138,61 +165,87 @@ def month_group(self): def has_author(self, person): for author in self.authors: # pylint: disable=not-an-iterable - if (author.block_type == 'author' and str(author.value) == str(person.title)): + if author.block_type == "author" and str(author.value) == str(person.title): return True return False class ExternalEventTopic(Orderable): - event = ParentalKey('ExternalEvent', on_delete=CASCADE, related_name='topics') - topic = ForeignKey('topics.Topic', on_delete=CASCADE, related_name='external_events') + event = ParentalKey("ExternalEvent", on_delete=CASCADE, related_name="topics") + topic = ForeignKey( + "topics.Topic", on_delete=CASCADE, related_name="external_events" + ) - panels = [ - PageChooserPanel('topic') - ] + panels = [PageChooserPanel("topic")] class ExternalEventSpeaker(Orderable): - article = ParentalKey('ExternalEvent', on_delete=CASCADE, related_name='speakers') - speaker = ForeignKey('people.Person', on_delete=CASCADE, related_name='external_events') + article = ParentalKey("ExternalEvent", on_delete=CASCADE, related_name="speakers") + speaker = ForeignKey( + "people.Person", on_delete=CASCADE, related_name="external_events" + ) - panels = [ - PageChooserPanel('speaker') - ] + panels = [PageChooserPanel("speaker")] class ExternalEvent(ExternalContent): - resource_type = 'event' + resource_type = "event" - start_date = DateField(default=datetime.date.today, help_text='The date the event is scheduled to start') - end_date = DateField(blank=True, null=True, help_text='The date the event is scheduled to end') - venue = TextField(max_length=250, blank=True, default='', help_text=( - 'Full address of the event venue, displayed on the event detail page' - )) - location = CharField(max_length=100, blank=True, default='', help_text=( - 'Location details (city and country), displayed on event cards' - )) + start_date = DateField( + default=datetime.date.today, + help_text="The date the event is scheduled to start", + ) + end_date = DateField( + blank=True, null=True, help_text="The date the event is scheduled to end" + ) + venue = TextField( + max_length=250, + blank=True, + default="", + help_text=( + "Full address of the event venue, displayed on the event detail page" + ), + ) + location = CharField( + max_length=100, + blank=True, + default="", + help_text=("Location details (city and country), displayed on event cards"), + ) meta_panels = [ - MultiFieldPanel([ - FieldPanel('start_date'), - FieldPanel('end_date'), - FieldPanel('venue'), - FieldPanel('location'), - ], heading='Event details'), - InlinePanel('topics', heading='Topics', help_text=( - 'Optional topics this event is associated with. Adds the event to the list of events on those topic pages' - )), - InlinePanel('speakers', heading='Speakers', help_text=( - 'Optional speakers associated with this event. Adds the event to the list of events on their profile pages' - )), + MultiFieldPanel( + [ + FieldPanel("start_date"), + FieldPanel("end_date"), + FieldPanel("venue"), + FieldPanel("location"), + ], + heading="Event details", + ), + InlinePanel( + "topics", + heading="Topics", + help_text=( + "Optional topics this event is associated with. Adds the event to the list of events on those topic pages" + ), + ), + InlinePanel( + "speakers", + heading="Speakers", + help_text=( + "Optional speakers associated with this event. Adds the event to the list of events on their profile pages" + ), + ), ] - edit_handler = TabbedInterface([ - ObjectList(ExternalContent.card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(Page.settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(ExternalContent.card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(Page.settings_panels, heading="Settings", classname="settings"), + ] + ) @property def event(self): @@ -222,53 +275,65 @@ def event_dates_full(self): class ExternalVideoTopic(Orderable): - video = ParentalKey('ExternalVideo', on_delete=CASCADE, related_name='topics') - topic = ForeignKey('topics.Topic', on_delete=CASCADE, related_name='external_videos') + video = ParentalKey("ExternalVideo", on_delete=CASCADE, related_name="topics") + topic = ForeignKey( + "topics.Topic", on_delete=CASCADE, related_name="external_videos" + ) - panels = [ - PageChooserPanel('topic') - ] + panels = [PageChooserPanel("topic")] class ExternalVideoPerson(Orderable): - article = ParentalKey('ExternalVideo', on_delete=CASCADE, related_name='people') - person = ForeignKey('people.Person', on_delete=CASCADE, related_name='external_videos') + article = ParentalKey("ExternalVideo", on_delete=CASCADE, related_name="people") + person = ForeignKey( + "people.Person", on_delete=CASCADE, related_name="external_videos" + ) - panels = [ - PageChooserPanel('person') - ] + panels = [PageChooserPanel("person")] class ExternalVideo(ExternalContent): - resource_type = 'video' + resource_type = "video" is_external = True # Meta fields - date = DateField('Video date', default=datetime.date.today, help_text='The date the video was published') + date = DateField( + "Video date", + default=datetime.date.today, + help_text="The date the video was published", + ) speakers = StreamField( - StreamBlock([ - ('speaker', PageChooserBlock(target_model='people.Person')), - ], required=False), + StreamBlock( + [("speaker", PageChooserBlock(target_model="people.Person"))], + required=False, + ), + blank=True, + null=True, + help_text="Optional list of people associated with or starring in the video", + ) + duration = CharField( + max_length=30, blank=True, null=True, - help_text='Optional list of people associated with or starring in the video', + help_text=( + "Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card" + ), ) - duration = CharField(max_length=30, blank=True, null=True, help_text=( - 'Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card' - )) meta_panels = [ - FieldPanel('date'), - StreamFieldPanel('speakers'), - InlinePanel('topics', heading='Topics'), - FieldPanel('duration'), + FieldPanel("date"), + StreamFieldPanel("speakers"), + InlinePanel("topics", heading="Topics"), + FieldPanel("duration"), ] - edit_handler = TabbedInterface([ - ObjectList(ExternalContent.card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(Page.settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(ExternalContent.card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(Page.settings_panels, heading="Settings", classname="settings"), + ] + ) @property def video(self): diff --git a/developerportal/apps/externalcontent/wagtail_hooks.py b/developerportal/apps/externalcontent/wagtail_hooks.py index 7bac25ab7..47b425c18 100644 --- a/developerportal/apps/externalcontent/wagtail_hooks.py +++ b/developerportal/apps/externalcontent/wagtail_hooks.py @@ -7,18 +7,13 @@ modeladmin_register, ) -from .models import ( - ExternalArticle, - ExternalContent, - ExternalEvent, - ExternalVideo, -) +from .models import ExternalArticle, ExternalContent, ExternalEvent, ExternalVideo class ExternalContentButtonHelper(PageButtonHelper): parent_page_types = [] subpage_types = [] - view_button_classnames = ['button-small'] + view_button_classnames = ["button-small"] def view_button(self, obj, classnames_add=None, classnames_exclude=None): if classnames_add is None: @@ -28,10 +23,10 @@ def view_button(self, obj, classnames_add=None, classnames_exclude=None): classnames = self.view_button_classnames + classnames_add cn = self.finalise_classname(classnames, classnames_exclude) return { - 'url': obj.external_url, - 'label': _('View external link'), - 'classname': cn, - 'title': _("View external link: %s") % obj.external_url, + "url": obj.external_url, + "label": _("View external link"), + "classname": cn, + "title": _("View external link: %s") % obj.external_url, } def get_buttons_for_obj(self, obj, **kwargs): @@ -42,39 +37,39 @@ def get_buttons_for_obj(self, obj, **kwargs): class ExternalContentAdmin(ModelAdmin): model = ExternalContent - menu_icon = 'link' - menu_label = 'All content' + menu_icon = "link" + menu_label = "All content" exclude_from_explorer = True button_helper_class = ExternalContentButtonHelper class ExternalArticleAdmin(ModelAdmin): model = ExternalArticle - menu_icon = 'doc-full-inverse' - menu_label = 'Articles' + menu_icon = "doc-full-inverse" + menu_label = "Articles" exclude_from_explorer = True button_helper_class = ExternalContentButtonHelper class ExternalEventAdmin(ModelAdmin): model = ExternalEvent - menu_icon = 'date' - menu_label = 'Events' + menu_icon = "date" + menu_label = "Events" exclude_from_explorer = True button_helper_class = ExternalContentButtonHelper class ExternalVideoAdmin(ModelAdmin): model = ExternalVideo - menu_icon = 'media' - menu_label = 'Videos' + menu_icon = "media" + menu_label = "Videos" exclude_from_explorer = True button_helper_class = ExternalContentButtonHelper class ExternalContentAdminGroup(ModelAdminGroup): - menu_label = 'External content' - menu_icon = 'folder-open-inverse' + menu_label = "External content" + menu_icon = "folder-open-inverse" menu_order = 250 items = ( ExternalContentAdmin, diff --git a/developerportal/apps/health/tests/test_views.py b/developerportal/apps/health/tests/test_views.py index 22e291f2d..46ceeef53 100644 --- a/developerportal/apps/health/tests/test_views.py +++ b/developerportal/apps/health/tests/test_views.py @@ -10,30 +10,30 @@ class HealthTestCases(TestCase): def test_disallowed_methods(self): """Test the endpoints using the disallowed HTTP methods.""" - for endpoint in ('liveness', 'readiness'): - url = reverse('health.{}'.format(endpoint)) - for method in ('put', 'post', 'delete', 'options'): + for endpoint in ("liveness", "readiness"): + url = reverse("health.{}".format(endpoint)) + for method in ("put", "post", "delete", "options"): with self.subTest(endpoint=endpoint, method=method): response = getattr(self.client, method)(url) self.assertEqual(response.status_code, 405) def test_safe_methods(self): """Test the endpoints using the safe HTTP methods.""" - for endpoint in ('liveness', 'readiness'): - url = reverse('health.{}'.format(endpoint)) - for method in ('get', 'head'): + for endpoint in ("liveness", "readiness"): + url = reverse("health.{}".format(endpoint)) + for method in ("get", "head"): with self.subTest(endpoint=endpoint, method=method): response = getattr(self.client, method)(url) self.assertEqual(response.status_code, 204) def test_readiness_with_db_error(self): """Test the readiness endpoint when there is a database issue.""" - url = reverse('health.readiness') - article_model_mgr = 'developerportal.apps.health.views.Article.objects' + url = reverse("health.readiness") + article_model_mgr = "developerportal.apps.health.views.Article.objects" with mock.patch(article_model_mgr) as mocked: - mocked.filter.side_effect = DatabaseError('fubar') - for method in ('get', 'head'): + mocked.filter.side_effect = DatabaseError("fubar") + for method in ("get", "head"): with self.subTest(method=method): response = getattr(self.client, method)(url) self.assertEqual(response.status_code, 503) - self.assertTrue('fubar' in response.reason_phrase) + self.assertTrue("fubar" in response.reason_phrase) diff --git a/developerportal/apps/health/urls.py b/developerportal/apps/health/urls.py index fd7e756be..91540bbf8 100644 --- a/developerportal/apps/health/urls.py +++ b/developerportal/apps/health/urls.py @@ -4,10 +4,6 @@ urlpatterns = [ - url(r'^healthz/?$', - views.liveness, - name='health.liveness'), - url(r'^readiness/?$', - views.readiness, - name='health.readiness'), + url(r"^healthz/?$", views.liveness, name="health.liveness"), + url(r"^readiness/?$", views.readiness, name="health.readiness"), ] diff --git a/developerportal/apps/health/views.py b/developerportal/apps/health/views.py index fb6a105f2..a831dddd4 100644 --- a/developerportal/apps/health/views.py +++ b/developerportal/apps/health/views.py @@ -33,7 +33,7 @@ def readiness(request): # error. Article.objects.filter(pk=1).exists() except DatabaseError as e: - reason_tmpl = 'service unavailable due to database issue ({!s})' + reason_tmpl = "service unavailable due to database issue ({!s})" status, reason = 503, reason_tmpl.format(e) else: status, reason = 204, None diff --git a/developerportal/apps/home/migrations/0001_initial.py b/developerportal/apps/home/migrations/0001_initial.py index ef46d1225..608913c8d 100644 --- a/developerportal/apps/home/migrations/0001_initial.py +++ b/developerportal/apps/home/migrations/0001_initial.py @@ -4,19 +4,25 @@ class Migration(migrations.Migration): - dependencies = [ - ('wagtailcore', '0040_page_draft_title'), - ] + dependencies = [("wagtailcore", "0040_page_draft_title")] operations = [ migrations.CreateModel( - name='HomePage', + name="HomePage", fields=[ - ('page_ptr', models.OneToOneField(on_delete=models.CASCADE, parent_link=True, auto_created=True, primary_key=True, serialize=False, to='wagtailcore.Page')), + ( + "page_ptr", + models.OneToOneField( + on_delete=models.CASCADE, + parent_link=True, + auto_created=True, + primary_key=True, + serialize=False, + to="wagtailcore.Page", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), - ), + options={"abstract": False}, + bases=("wagtailcore.page",), + ) ] diff --git a/developerportal/apps/home/migrations/0002_create_homepage.py b/developerportal/apps/home/migrations/0002_create_homepage.py index 039f0f572..a2d088a77 100644 --- a/developerportal/apps/home/migrations/0002_create_homepage.py +++ b/developerportal/apps/home/migrations/0002_create_homepage.py @@ -4,10 +4,10 @@ def create_homepage(apps, schema_editor): # Get models - ContentType = apps.get_model('contenttypes.ContentType') - Page = apps.get_model('wagtailcore.Page') - Site = apps.get_model('wagtailcore.Site') - HomePage = apps.get_model('home.HomePage') + ContentType = apps.get_model("contenttypes.ContentType") + Page = apps.get_model("wagtailcore.Page") + Site = apps.get_model("wagtailcore.Site") + HomePage = apps.get_model("home.HomePage") # Delete the default homepage # If migration is run multiple times, it may have already been deleted @@ -15,44 +15,40 @@ def create_homepage(apps, schema_editor): # Create content type for homepage model homepage_content_type, __ = ContentType.objects.get_or_create( - model='homepage', app_label='home') + model="homepage", app_label="home" + ) # Create a new homepage homepage = HomePage.objects.create( title="Home", draft_title="Home", - slug='home', + slug="home", content_type=homepage_content_type, - path='00010001', + path="00010001", depth=2, numchild=0, - url_path='/home/', + url_path="/home/", ) # Create a site with the new homepage set as the root - Site.objects.create( - hostname='localhost', root_page=homepage, is_default_site=True) + Site.objects.create(hostname="localhost", root_page=homepage, is_default_site=True) def remove_homepage(apps, schema_editor): # Get models - ContentType = apps.get_model('contenttypes.ContentType') - HomePage = apps.get_model('home.HomePage') + ContentType = apps.get_model("contenttypes.ContentType") + HomePage = apps.get_model("home.HomePage") # Delete the default homepage # Page and Site objects CASCADE - HomePage.objects.filter(slug='home', depth=2).delete() + HomePage.objects.filter(slug="home", depth=2).delete() # Delete content type for homepage model - ContentType.objects.filter(model='homepage', app_label='home').delete() + ContentType.objects.filter(model="homepage", app_label="home").delete() class Migration(migrations.Migration): - dependencies = [ - ('home', '0001_initial'), - ] + dependencies = [("home", "0001_initial")] - operations = [ - migrations.RunPython(create_homepage, remove_homepage), - ] + operations = [migrations.RunPython(create_homepage, remove_homepage)] diff --git a/developerportal/apps/home/migrations/0003_auto_20190528_1305.py b/developerportal/apps/home/migrations/0003_auto_20190528_1305.py index a21b28c3e..1e538ff40 100644 --- a/developerportal/apps/home/migrations/0003_auto_20190528_1305.py +++ b/developerportal/apps/home/migrations/0003_auto_20190528_1305.py @@ -6,29 +6,27 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0002_create_homepage'), - ] + dependencies = [("home", "0002_create_homepage")] operations = [ migrations.AddField( - model_name='homepage', - name='button_text', - field=models.CharField(default='', max_length=30), + model_name="homepage", + name="button_text", + field=models.CharField(default="", max_length=30), ), migrations.AddField( - model_name='homepage', - name='button_url', - field=models.URLField(default='', max_length=140), + model_name="homepage", + name="button_url", + field=models.URLField(default="", max_length=140), ), migrations.AddField( - model_name='homepage', - name='intro', - field=wagtail.core.fields.RichTextField(default=''), + model_name="homepage", + name="intro", + field=wagtail.core.fields.RichTextField(default=""), ), migrations.AddField( - model_name='homepage', - name='subtitle', - field=models.CharField(default='', max_length=140), + model_name="homepage", + name="subtitle", + field=models.CharField(default="", max_length=140), ), ] diff --git a/developerportal/apps/home/migrations/0004_homepagefeaturedarticle.py b/developerportal/apps/home/migrations/0004_homepagefeaturedarticle.py index 68e46e45b..0bab724a0 100644 --- a/developerportal/apps/home/migrations/0004_homepagefeaturedarticle.py +++ b/developerportal/apps/home/migrations/0004_homepagefeaturedarticle.py @@ -8,22 +8,44 @@ class Migration(migrations.Migration): dependencies = [ - ('articles', '0020_auto_20190612_0426'), - ('home', '0003_auto_20190528_1305'), + ("articles", "0020_auto_20190612_0426"), + ("home", "0003_auto_20190528_1305"), ] operations = [ migrations.CreateModel( - name='HomePageFeaturedArticle', + name="HomePageFeaturedArticle", 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)), - ('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='articles.Article')), - ('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='featured_articles', to='home.HomePage')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="articles.Article", + ), + ), + ( + "page", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="featured_articles", + to="home.HomePage", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, - ), + options={"ordering": ["sort_order"], "abstract": False}, + ) ] diff --git a/developerportal/apps/home/migrations/0005_auto_20190618_1635.py b/developerportal/apps/home/migrations/0005_auto_20190618_1635.py index 20ec4681a..533331c5e 100644 --- a/developerportal/apps/home/migrations/0005_auto_20190618_1635.py +++ b/developerportal/apps/home/migrations/0005_auto_20190618_1635.py @@ -7,24 +7,30 @@ class Migration(migrations.Migration): dependencies = [ - ('wagtailimages', '0001_squashed_0021'), - ('home', '0004_homepagefeaturedarticle'), + ("wagtailimages", "0001_squashed_0021"), + ("home", "0004_homepagefeaturedarticle"), ] operations = [ migrations.AddField( - model_name='homepage', - name='header_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.Image'), + model_name="homepage", + name="header_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailimages.Image", + ), ), migrations.AlterField( - model_name='homepage', - name='intro', - field=models.TextField(blank=True, default='', max_length=250), + model_name="homepage", + name="intro", + field=models.TextField(blank=True, default="", max_length=250), ), migrations.AlterField( - model_name='homepage', - name='subtitle', - field=models.TextField(blank=True, default='', max_length=250), + model_name="homepage", + name="subtitle", + field=models.TextField(blank=True, default="", max_length=250), ), ] diff --git a/developerportal/apps/home/migrations/0006_auto_20190625_1111.py b/developerportal/apps/home/migrations/0006_auto_20190625_1111.py index 99dcfaca4..733d14105 100644 --- a/developerportal/apps/home/migrations/0006_auto_20190625_1111.py +++ b/developerportal/apps/home/migrations/0006_auto_20190625_1111.py @@ -6,14 +6,18 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0005_auto_20190618_1635'), - ] + dependencies = [("home", "0005_auto_20190618_1635")] operations = [ migrations.AlterField( - model_name='homepage', - name='header_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage'), - ), + model_name="homepage", + name="header_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), + ) ] diff --git a/developerportal/apps/home/migrations/0007_auto_20190625_1112.py b/developerportal/apps/home/migrations/0007_auto_20190625_1112.py index 9c0545ddf..30174a096 100644 --- a/developerportal/apps/home/migrations/0007_auto_20190625_1112.py +++ b/developerportal/apps/home/migrations/0007_auto_20190625_1112.py @@ -6,14 +6,18 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0006_auto_20190625_1111'), - ] + dependencies = [("home", "0006_auto_20190625_1111")] operations = [ migrations.AlterField( - model_name='homepage', - name='header_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.Image'), - ), + model_name="homepage", + name="header_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailimages.Image", + ), + ) ] diff --git a/developerportal/apps/home/migrations/0008_auto_20190625_1119.py b/developerportal/apps/home/migrations/0008_auto_20190625_1119.py index 514bfe374..cf003f788 100644 --- a/developerportal/apps/home/migrations/0008_auto_20190625_1119.py +++ b/developerportal/apps/home/migrations/0008_auto_20190625_1119.py @@ -6,14 +6,18 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0007_auto_20190625_1112'), - ] + dependencies = [("home", "0007_auto_20190625_1112")] operations = [ migrations.AlterField( - model_name='homepage', - name='header_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage'), - ), + model_name="homepage", + name="header_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), + ) ] diff --git a/developerportal/apps/home/migrations/0009_auto_20190702_0904.py b/developerportal/apps/home/migrations/0009_auto_20190702_0904.py index da831dd10..d01478a3f 100644 --- a/developerportal/apps/home/migrations/0009_auto_20190702_0904.py +++ b/developerportal/apps/home/migrations/0009_auto_20190702_0904.py @@ -5,19 +5,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0008_auto_20190625_1119'), - ] + dependencies = [("home", "0008_auto_20190625_1119")] operations = [ migrations.AlterField( - model_name='homepage', - name='button_text', - field=models.CharField(blank=True, default='', max_length=30), + model_name="homepage", + name="button_text", + field=models.CharField(blank=True, default="", max_length=30), ), migrations.AlterField( - model_name='homepage', - name='button_url', - field=models.URLField(blank=True, default='', max_length=140), + model_name="homepage", + name="button_url", + field=models.URLField(blank=True, default="", max_length=140), ), ] diff --git a/developerportal/apps/home/migrations/0009_homepage_featured.py b/developerportal/apps/home/migrations/0009_homepage_featured.py index 47669d098..220aae798 100644 --- a/developerportal/apps/home/migrations/0009_homepage_featured.py +++ b/developerportal/apps/home/migrations/0009_homepage_featured.py @@ -6,14 +6,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0008_auto_20190625_1119'), - ] + dependencies = [("home", "0008_auto_20190625_1119")] operations = [ migrations.AddField( - model_name='homepage', - name='featured', + model_name="homepage", + name="featured", field=wagtail.core.fields.StreamField([], blank=True, null=True), - ), + ) ] diff --git a/developerportal/apps/home/migrations/0010_auto_20190627_1527.py b/developerportal/apps/home/migrations/0010_auto_20190627_1527.py index 93b89d2e0..fa4feeeef 100644 --- a/developerportal/apps/home/migrations/0010_auto_20190627_1527.py +++ b/developerportal/apps/home/migrations/0010_auto_20190627_1527.py @@ -7,14 +7,23 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0009_homepage_featured'), - ] + dependencies = [("home", "0009_homepage_featured")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ) + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0010_auto_20190704_1031.py b/developerportal/apps/home/migrations/0010_auto_20190704_1031.py index 61f651ee1..8f031524a 100644 --- a/developerportal/apps/home/migrations/0010_auto_20190704_1031.py +++ b/developerportal/apps/home/migrations/0010_auto_20190704_1031.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0009_auto_20190702_0904'), - ] + dependencies = [("home", "0009_auto_20190702_0904")] operations = [ migrations.AlterField( - model_name='homepage', - name='button_url', - field=models.URLField(blank=True, default='', max_length=2048), - ), + model_name="homepage", + name="button_url", + field=models.URLField(blank=True, default="", max_length=2048), + ) ] diff --git a/developerportal/apps/home/migrations/0011_auto_20190627_1528.py b/developerportal/apps/home/migrations/0011_auto_20190627_1528.py index e602e3a02..ac8eda216 100644 --- a/developerportal/apps/home/migrations/0011_auto_20190627_1528.py +++ b/developerportal/apps/home/migrations/0011_auto_20190627_1528.py @@ -7,14 +7,33 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0010_auto_20190627_1527'), - ] + dependencies = [("home", "0010_auto_20190627_1527")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())]))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("url", wagtail.core.blocks.URLBlock()), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0011_auto_20190705_1258.py b/developerportal/apps/home/migrations/0011_auto_20190705_1258.py index 9d4800d0a..40712eadd 100644 --- a/developerportal/apps/home/migrations/0011_auto_20190705_1258.py +++ b/developerportal/apps/home/migrations/0011_auto_20190705_1258.py @@ -6,14 +6,16 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0010_auto_20190704_1031'), - ] + dependencies = [("home", "0010_auto_20190704_1031")] operations = [ migrations.AlterField( - model_name='homepagefeaturedarticle', - name='article', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.Page'), - ), + model_name="homepagefeaturedarticle", + name="article", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.Page", + ), + ) ] diff --git a/developerportal/apps/home/migrations/0012_auto_20190628_1113.py b/developerportal/apps/home/migrations/0012_auto_20190628_1113.py index 607b3a560..d3c4dc18b 100644 --- a/developerportal/apps/home/migrations/0012_auto_20190628_1113.py +++ b/developerportal/apps/home/migrations/0012_auto_20190628_1113.py @@ -8,14 +8,37 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0011_auto_20190627_1528'), - ] + dependencies = [("home", "0011_auto_20190627_1528")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('intro', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "intro", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0013_auto_20190628_1337.py b/developerportal/apps/home/migrations/0013_auto_20190628_1337.py index 93a60620e..708e380c3 100644 --- a/developerportal/apps/home/migrations/0013_auto_20190628_1337.py +++ b/developerportal/apps/home/migrations/0013_auto_20190628_1337.py @@ -8,14 +8,42 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0012_auto_20190628_1113'), - ] + dependencies = [("home", "0012_auto_20190628_1113")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('intro', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock(label='header image'))]))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "intro", + wagtail.core.blocks.TextBlock(required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + label="header image" + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0014_auto_20190628_1338.py b/developerportal/apps/home/migrations/0014_auto_20190628_1338.py index a864d7c95..f2dfcad10 100644 --- a/developerportal/apps/home/migrations/0014_auto_20190628_1338.py +++ b/developerportal/apps/home/migrations/0014_auto_20190628_1338.py @@ -8,14 +8,42 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0013_auto_20190628_1337'), - ] + dependencies = [("home", "0013_auto_20190628_1337")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('intro', wagtail.core.blocks.TextBlock(required=False)), ('header_image', wagtail.images.blocks.ImageChooserBlock(label='Image'))]))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "intro", + wagtail.core.blocks.TextBlock(required=False), + ), + ( + "header_image", + wagtail.images.blocks.ImageChooserBlock( + label="Image" + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0015_auto_20190628_1436.py b/developerportal/apps/home/migrations/0015_auto_20190628_1436.py index b320eedb1..82252a485 100644 --- a/developerportal/apps/home/migrations/0015_auto_20190628_1436.py +++ b/developerportal/apps/home/migrations/0015_auto_20190628_1436.py @@ -8,14 +8,44 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0014_auto_20190628_1338'), - ] + dependencies = [("home", "0014_auto_20190628_1338")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(help_text='Details of an external page', page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('intro', wagtail.core.blocks.TextBlock(required=False)), ('header_image', wagtail.images.blocks.ImageChooserBlock(label='Image'))]))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + help_text="Details of an external page", + page_type=["articles.Article"], + required=False, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "intro", + wagtail.core.blocks.TextBlock(required=False), + ), + ( + "header_image", + wagtail.images.blocks.ImageChooserBlock( + label="Image" + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0016_auto_20190628_1437.py b/developerportal/apps/home/migrations/0016_auto_20190628_1437.py index cd08f7d11..d8221e4ef 100644 --- a/developerportal/apps/home/migrations/0016_auto_20190628_1437.py +++ b/developerportal/apps/home/migrations/0016_auto_20190628_1437.py @@ -8,14 +8,43 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0015_auto_20190628_1436'), - ] + dependencies = [("home", "0015_auto_20190628_1436")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('intro', wagtail.core.blocks.TextBlock(required=False)), ('header_image', wagtail.images.blocks.ImageChooserBlock(label='Image'))], help_text='Details of an external page'))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "intro", + wagtail.core.blocks.TextBlock(required=False), + ), + ( + "header_image", + wagtail.images.blocks.ImageChooserBlock( + label="Image" + ), + ), + ], + help_text="Details of an external page", + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0017_auto_20190628_1438.py b/developerportal/apps/home/migrations/0017_auto_20190628_1438.py index e1f03a428..fadc8ef49 100644 --- a/developerportal/apps/home/migrations/0017_auto_20190628_1438.py +++ b/developerportal/apps/home/migrations/0017_auto_20190628_1438.py @@ -8,14 +8,42 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0016_auto_20190628_1437'), - ] + dependencies = [("home", "0016_auto_20190628_1437")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('intro', wagtail.core.blocks.TextBlock(required=False)), ('header_image', wagtail.images.blocks.ImageChooserBlock(label='Image'))]))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "intro", + wagtail.core.blocks.TextBlock(required=False), + ), + ( + "header_image", + wagtail.images.blocks.ImageChooserBlock( + label="Image" + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0018_merge_20190702_1247.py b/developerportal/apps/home/migrations/0018_merge_20190702_1247.py index 1a7e23413..e2a46df60 100644 --- a/developerportal/apps/home/migrations/0018_merge_20190702_1247.py +++ b/developerportal/apps/home/migrations/0018_merge_20190702_1247.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('home', '0017_auto_20190628_1438'), - ('home', '0009_auto_20190702_0904'), + ("home", "0017_auto_20190628_1438"), + ("home", "0009_auto_20190702_0904"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/home/migrations/0019_merge_20190709_0910.py b/developerportal/apps/home/migrations/0019_merge_20190709_0910.py index fd6c71bf4..4472f6456 100644 --- a/developerportal/apps/home/migrations/0019_merge_20190709_0910.py +++ b/developerportal/apps/home/migrations/0019_merge_20190709_0910.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('home', '0018_merge_20190702_1247'), - ('home', '0011_auto_20190705_1258'), + ("home", "0018_merge_20190702_1247"), + ("home", "0011_auto_20190705_1258"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/home/migrations/0020_auto_20190708_1243.py b/developerportal/apps/home/migrations/0020_auto_20190708_1243.py index 134422de4..ea191758e 100644 --- a/developerportal/apps/home/migrations/0020_auto_20190708_1243.py +++ b/developerportal/apps/home/migrations/0020_auto_20190708_1243.py @@ -8,17 +8,47 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0019_merge_20190709_0910'), - ] + dependencies = [("home", "0019_merge_20190709_0910")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article', 'externalcontent.ExternalArticle'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('intro', wagtail.core.blocks.TextBlock(required=False)), ('header_image', wagtail.images.blocks.ImageChooserBlock(label='Image'))]))], blank=True, null=True), - ), - migrations.DeleteModel( - name='HomePageFeaturedArticle', + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=[ + "articles.Article", + "externalcontent.ExternalArticle", + ], + required=False, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "intro", + wagtail.core.blocks.TextBlock(required=False), + ), + ( + "header_image", + wagtail.images.blocks.ImageChooserBlock( + label="Image" + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + ), ), + migrations.DeleteModel(name="HomePageFeaturedArticle"), ] diff --git a/developerportal/apps/home/migrations/0021_auto_20190711_1932.py b/developerportal/apps/home/migrations/0021_auto_20190711_1932.py index 3b8b3dc04..0dba9d08f 100644 --- a/developerportal/apps/home/migrations/0021_auto_20190711_1932.py +++ b/developerportal/apps/home/migrations/0021_auto_20190711_1932.py @@ -9,51 +9,84 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('mozimages', '0001_initial'), - ('home', '0020_auto_20190708_1243'), + ("taggit", "0002_auto_20150616_2121"), + ("mozimages", "0001_initial"), + ("home", "0020_auto_20190708_1243"), ] operations = [ migrations.RenameField( - model_name='homepage', - old_name='intro', - new_name='description', + model_name="homepage", old_name="intro", new_name="description" ), migrations.RenameField( - model_name='homepage', - old_name='header_image', - new_name='image', + model_name="homepage", old_name="header_image", new_name="image" ), migrations.AddField( - model_name='homepage', - name='card_description', - field=models.TextField(blank=True, default='', max_length=140, verbose_name='Description'), + model_name="homepage", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=140, verbose_name="Description" + ), ), migrations.AddField( - model_name='homepage', - name='card_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage', verbose_name='Image'), + model_name="homepage", + name="card_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + verbose_name="Image", + ), ), migrations.AddField( - model_name='homepage', - name='card_title', - field=models.CharField(blank=True, default='', max_length=140, verbose_name='Title'), + model_name="homepage", + name="card_title", + field=models.CharField( + blank=True, default="", max_length=140, verbose_name="Title" + ), ), migrations.CreateModel( - name='HomePageTag', + name="HomePageTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='home.HomePage')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='home_homepagetag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="home.HomePage", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="home_homepagetag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='homepage', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='home.HomePageTag', to='taggit.Tag', verbose_name='Tags'), + model_name="homepage", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="home.HomePageTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/home/migrations/0022_auto_20190711_1951.py b/developerportal/apps/home/migrations/0022_auto_20190711_1951.py index d4e67d05d..7cfe8a802 100644 --- a/developerportal/apps/home/migrations/0022_auto_20190711_1951.py +++ b/developerportal/apps/home/migrations/0022_auto_20190711_1951.py @@ -8,14 +8,41 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0021_auto_20190711_1932'), - ] + dependencies = [("home", "0021_auto_20190711_1932")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article', 'externalcontent.ExternalArticle'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=[ + "articles.Article", + "externalcontent.ExternalArticle", + ], + required=False, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0023_auto_20190712_1023.py b/developerportal/apps/home/migrations/0023_auto_20190712_1023.py index 146aeb8f1..65486c2eb 100644 --- a/developerportal/apps/home/migrations/0023_auto_20190712_1023.py +++ b/developerportal/apps/home/migrations/0023_auto_20190712_1023.py @@ -5,33 +5,28 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0022_auto_20190711_1951'), - ] + dependencies = [("home", "0022_auto_20190711_1951")] operations = [ - migrations.RemoveField( - model_name='homepage', - name='description', - ), + migrations.RemoveField(model_name="homepage", name="description"), migrations.AddField( - model_name='homepage', - name='about_button_text', - field=models.CharField(blank=True, default='', max_length=30), + model_name="homepage", + name="about_button_text", + field=models.CharField(blank=True, default="", max_length=30), ), migrations.AddField( - model_name='homepage', - name='about_button_url', - field=models.URLField(blank=True, default='', max_length=140), + model_name="homepage", + name="about_button_url", + field=models.URLField(blank=True, default="", max_length=140), ), migrations.AddField( - model_name='homepage', - name='about_subtitle', - field=models.TextField(blank=True, default='', max_length=250), + model_name="homepage", + name="about_subtitle", + field=models.TextField(blank=True, default="", max_length=250), ), migrations.AddField( - model_name='homepage', - name='about_title', - field=models.TextField(blank=True, default='', max_length=250), + model_name="homepage", + name="about_title", + field=models.TextField(blank=True, default="", max_length=250), ), ] diff --git a/developerportal/apps/home/migrations/0024_auto_20190718_1438.py b/developerportal/apps/home/migrations/0024_auto_20190718_1438.py index 9ede3c00e..3cc78e193 100644 --- a/developerportal/apps/home/migrations/0024_auto_20190718_1438.py +++ b/developerportal/apps/home/migrations/0024_auto_20190718_1438.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0023_auto_20190712_1023'), - ] + dependencies = [("home", "0023_auto_20190712_1023")] operations = [ migrations.AlterField( - model_name='homepage', - name='button_url', - field=models.CharField(blank=True, default='', max_length=2048), - ), + model_name="homepage", + name="button_url", + field=models.CharField(blank=True, default="", max_length=2048), + ) ] diff --git a/developerportal/apps/home/migrations/0025_homepage_external_promos.py b/developerportal/apps/home/migrations/0025_homepage_external_promos.py index d2439cf01..d60ddbd7f 100644 --- a/developerportal/apps/home/migrations/0025_homepage_external_promos.py +++ b/developerportal/apps/home/migrations/0025_homepage_external_promos.py @@ -8,14 +8,31 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0024_auto_20190718_1438'), - ] + dependencies = [("home", "0024_auto_20190718_1438")] operations = [ migrations.AddField( - model_name='homepage', - name='external_promos', - field=wagtail.core.fields.StreamField([('external_promo', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, null=True), - ), + model_name="homepage", + name="external_promos", + field=wagtail.core.fields.StreamField( + [ + ( + "external_promo", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ) + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/home/migrations/0026_auto_20190813_1302.py b/developerportal/apps/home/migrations/0026_auto_20190813_1302.py index 47c233e35..ef8ef4c34 100644 --- a/developerportal/apps/home/migrations/0026_auto_20190813_1302.py +++ b/developerportal/apps/home/migrations/0026_auto_20190813_1302.py @@ -5,14 +5,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0025_homepage_external_promos'), - ] + dependencies = [("home", "0025_homepage_external_promos")] operations = [ migrations.AlterField( - model_name='homepage', - name='card_description', - field=models.TextField(blank=True, default='', max_length=400, verbose_name='Description'), - ), + model_name="homepage", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=400, verbose_name="Description" + ), + ) ] diff --git a/developerportal/apps/home/migrations/0027_auto_20190813_1503.py b/developerportal/apps/home/migrations/0027_auto_20190813_1503.py index a9ccfbbec..a544ecf82 100644 --- a/developerportal/apps/home/migrations/0027_auto_20190813_1503.py +++ b/developerportal/apps/home/migrations/0027_auto_20190813_1503.py @@ -8,19 +8,67 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0026_auto_20190813_1302'), - ] + dependencies = [("home", "0026_auto_20190813_1302")] operations = [ migrations.AlterField( - model_name='homepage', - name='external_promos', - field=wagtail.core.fields.StreamField([('external_promo', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, help_text='Optional promo space under the header for linking to external sites, max. 2', null=True), + model_name="homepage", + name="external_promos", + field=wagtail.core.fields.StreamField( + [ + ( + "external_promo", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ) + ], + blank=True, + help_text="Optional promo space under the header for linking to external sites, max. 2", + null=True, + ), ), migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article', 'externalcontent.ExternalArticle'], required=True)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, help_text='Optional space for featured articles, max. 4', null=True), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=[ + "articles.Article", + "externalcontent.ExternalArticle", + ], + required=True, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + help_text="Optional space for featured articles, max. 4", + null=True, + ), ), ] diff --git a/developerportal/apps/home/migrations/0028_auto_20190814_1600.py b/developerportal/apps/home/migrations/0028_auto_20190814_1600.py index b2e4b0e1f..3fded9718 100644 --- a/developerportal/apps/home/migrations/0028_auto_20190814_1600.py +++ b/developerportal/apps/home/migrations/0028_auto_20190814_1600.py @@ -8,14 +8,41 @@ class Migration(migrations.Migration): - dependencies = [ - ('home', '0027_auto_20190813_1503'), - ] + dependencies = [("home", "0027_auto_20190813_1503")] operations = [ migrations.AlterField( - model_name='homepage', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article', 'externalcontent.ExternalArticle'])), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, help_text='Optional space for featured articles, max. 4', null=True), - ), + model_name="homepage", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=[ + "articles.Article", + "externalcontent.ExternalArticle", + ] + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + help_text="Optional space for featured articles, max. 4", + null=True, + ), + ) ] diff --git a/developerportal/apps/home/models.py b/developerportal/apps/home/models.py index e11532541..3cf7c4217 100644 --- a/developerportal/apps/home/models.py +++ b/developerportal/apps/home/models.py @@ -1,4 +1,11 @@ -from django.db.models import CASCADE, CharField, ForeignKey, SET_NULL, URLField, TextField +from django.db.models import ( + CASCADE, + CharField, + ForeignKey, + SET_NULL, + URLField, + TextField, +) from wagtail.admin.edit_handlers import ( FieldPanel, @@ -20,66 +27,77 @@ class HomePageTag(TaggedItemBase): - content_object = ParentalKey('HomePage', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "HomePage", on_delete=CASCADE, related_name="tagged_items" + ) class HomePage(Page): subpage_types = [ - 'articles.Articles', - 'content.ContentPage', - 'events.Events', - 'people.People', - 'topics.Topics', - 'videos.Videos', + "articles.Articles", + "content.ContentPage", + "events.Events", + "people.People", + "topics.Topics", + "videos.Videos", ] - template = 'home.html' + template = "home.html" # Content fields - subtitle = TextField(max_length=250, blank=True, default='') - button_text = CharField(max_length=30, blank=True, default='') - button_url = CharField(max_length=2048, blank=True, default='') + subtitle = TextField(max_length=250, blank=True, default="") + button_text = CharField(max_length=30, blank=True, default="") + button_url = CharField(max_length=2048, blank=True, default="") image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+' + related_name="+", ) external_promos = StreamField( - StreamBlock([ - ('external_promo', FeaturedExternalBlock()), - ], max_num=2, required=False), + StreamBlock( + [("external_promo", FeaturedExternalBlock())], max_num=2, required=False + ), null=True, blank=True, - help_text='Optional promo space under the header for linking to external sites, max. 2', + help_text="Optional promo space under the header for linking to external sites, max. 2", ) featured = StreamField( - StreamBlock([ - ('article', PageChooserBlock(target_model=( - 'articles.Article', - 'externalcontent.ExternalArticle', - ))), - ('external_page', FeaturedExternalBlock()), - ], max_num=4, required=False), + StreamBlock( + [ + ( + "article", + PageChooserBlock( + target_model=( + "articles.Article", + "externalcontent.ExternalArticle", + ) + ), + ), + ("external_page", FeaturedExternalBlock()), + ], + max_num=4, + required=False, + ), null=True, blank=True, - help_text='Optional space for featured articles, max. 4', + help_text="Optional space for featured articles, max. 4", ) - about_title = TextField(max_length=250, blank=True, default='') - about_subtitle = TextField(max_length=250, blank=True, default='') - about_button_text = CharField(max_length=30, blank=True, default='') - about_button_url = URLField(max_length=140, blank=True, default='') + about_title = TextField(max_length=250, blank=True, default="") + about_subtitle = TextField(max_length=250, blank=True, default="") + about_button_text = CharField(max_length=30, blank=True, default="") + about_button_url = URLField(max_length=140, blank=True, default="") # Card fields - card_title = CharField('Title', max_length=140, blank=True, default='') - card_description = TextField('Description', max_length=400, blank=True, default='') + card_title = CharField("Title", max_length=140, blank=True, default="") + card_description = TextField("Description", max_length=400, blank=True, default="") card_image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', - verbose_name='Image', + related_name="+", + verbose_name="Image", ) # Meta fields @@ -87,56 +105,74 @@ class HomePage(Page): # Editor panel configuration content_panels = Page.content_panels + [ - MultiFieldPanel([ - FieldPanel('subtitle'), - FieldPanel('button_text'), - FieldPanel('button_url'), - ], heading='Header section', help_text='Optional fields for the header section'), - MultiFieldPanel([ - ImageChooserPanel('image'), - ], heading='Image', help_text='Optional image shown when sharing this page through social media'), - StreamFieldPanel('external_promos'), - StreamFieldPanel('featured'), - MultiFieldPanel([ - FieldPanel('about_title'), - FieldPanel('about_subtitle'), - FieldPanel('about_button_text'), - FieldPanel('about_button_url'), - ], heading='About section', help_text='Optional section to explain more about Mozilla'), + MultiFieldPanel( + [ + FieldPanel("subtitle"), + FieldPanel("button_text"), + FieldPanel("button_url"), + ], + heading="Header section", + help_text="Optional fields for the header section", + ), + MultiFieldPanel( + [ImageChooserPanel("image")], + heading="Image", + help_text="Optional image shown when sharing this page through social media", + ), + StreamFieldPanel("external_promos"), + StreamFieldPanel("featured"), + MultiFieldPanel( + [ + FieldPanel("about_title"), + FieldPanel("about_subtitle"), + FieldPanel("about_button_text"), + FieldPanel("about_button_url"), + ], + heading="About section", + help_text="Optional section to explain more about Mozilla", + ), ] # Card panels card_panels = [ - MultiFieldPanel([ - FieldPanel('card_title'), - FieldPanel('card_description'), - ImageChooserPanel('card_image'), - ], heading='Card overrides', help_text=( - 'Optional fields to override the default title, description and image when this page is shown as a card' - )), + MultiFieldPanel( + [ + FieldPanel("card_title"), + FieldPanel("card_description"), + ImageChooserPanel("card_image"), + ], + heading="Card overrides", + help_text=( + "Optional fields to override the default title, description and image when this page is shown as a card" + ), + ) ] # Meta panels meta_panels = [ - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ) ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - ] + settings_panels = [FieldPanel("slug")] # Tabs - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) @classmethod def can_create_at(cls, parent): @@ -147,4 +183,10 @@ def can_create_at(cls, parent): def primary_topics(self): """The site’s top-level topics, i.e. topics without a parent topic.""" from ..topics.models import Topic - return Topic.objects.filter(parent_topics__isnull=True).live().public().order_by('title') + + return ( + Topic.objects.filter(parent_topics__isnull=True) + .live() + .public() + .order_by("title") + ) diff --git a/developerportal/apps/home/tests/test_home.py b/developerportal/apps/home/tests/test_home.py index 5412b2ddb..88e10f9c4 100644 --- a/developerportal/apps/home/tests/test_home.py +++ b/developerportal/apps/home/tests/test_home.py @@ -17,11 +17,6 @@ def test_topic_parent_pages(self): self.assertAllowedParentPageTypes(HomePage, {Page}) def test_home_page_subpages(self): - self.assertAllowedSubpageTypes(HomePage, { - Articles, - ContentPage, - Events, - Topics, - People, - Videos, - }) + self.assertAllowedSubpageTypes( + HomePage, {Articles, ContentPage, Events, Topics, People, Videos} + ) diff --git a/developerportal/apps/mozimages/migrations/0001_initial.py b/developerportal/apps/mozimages/migrations/0001_initial.py index b7e2152b1..bf0acd2a4 100644 --- a/developerportal/apps/mozimages/migrations/0001_initial.py +++ b/developerportal/apps/mozimages/migrations/0001_initial.py @@ -14,50 +14,131 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('taggit', '0002_auto_20150616_2121'), + ("taggit", "0002_auto_20150616_2121"), ] operations = [ migrations.CreateModel( - name='MozImage', + name="MozImage", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255, verbose_name='title')), - ('file', models.ImageField(height_field='height', upload_to=wagtail.images.models.get_upload_to, verbose_name='file', width_field='width')), - ('width', models.IntegerField(editable=False, verbose_name='width')), - ('height', models.IntegerField(editable=False, verbose_name='height')), - ('created_at', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='created at')), - ('focal_point_x', models.PositiveIntegerField(blank=True, null=True)), - ('focal_point_y', models.PositiveIntegerField(blank=True, null=True)), - ('focal_point_width', models.PositiveIntegerField(blank=True, null=True)), - ('focal_point_height', models.PositiveIntegerField(blank=True, null=True)), - ('file_size', models.PositiveIntegerField(editable=False, null=True)), - ('file_hash', models.CharField(blank=True, editable=False, max_length=40)), - ('caption', models.CharField(blank=True, max_length=255)), - ('collection', models.ForeignKey(default=wagtail.core.models.get_root_collection_id, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.Collection', verbose_name='collection')), - ('tags', taggit.managers.TaggableManager(blank=True, help_text=None, through='taggit.TaggedItem', to='taggit.Tag', verbose_name='tags')), - ('uploaded_by_user', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='uploaded by user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=255, verbose_name="title")), + ( + "file", + models.ImageField( + height_field="height", + upload_to=wagtail.images.models.get_upload_to, + verbose_name="file", + width_field="width", + ), + ), + ("width", models.IntegerField(editable=False, verbose_name="width")), + ("height", models.IntegerField(editable=False, verbose_name="height")), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, db_index=True, verbose_name="created at" + ), + ), + ("focal_point_x", models.PositiveIntegerField(blank=True, null=True)), + ("focal_point_y", models.PositiveIntegerField(blank=True, null=True)), + ( + "focal_point_width", + models.PositiveIntegerField(blank=True, null=True), + ), + ( + "focal_point_height", + models.PositiveIntegerField(blank=True, null=True), + ), + ("file_size", models.PositiveIntegerField(editable=False, null=True)), + ( + "file_hash", + models.CharField(blank=True, editable=False, max_length=40), + ), + ("caption", models.CharField(blank=True, max_length=255)), + ( + "collection", + models.ForeignKey( + default=wagtail.core.models.get_root_collection_id, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.Collection", + verbose_name="collection", + ), + ), + ( + "tags", + taggit.managers.TaggableManager( + blank=True, + help_text=None, + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="tags", + ), + ), + ( + "uploaded_by_user", + models.ForeignKey( + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="uploaded by user", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, bases=(wagtail.search.index.Indexed, models.Model), ), migrations.CreateModel( - name='Rendition', + name="Rendition", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('filter_spec', models.CharField(db_index=True, max_length=255)), - ('file', models.ImageField(height_field='height', upload_to=wagtail.images.models.get_rendition_upload_to, width_field='width')), - ('width', models.IntegerField(editable=False)), - ('height', models.IntegerField(editable=False)), - ('focal_point_key', models.CharField(blank=True, default='', editable=False, max_length=16)), - ('image', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='renditions', to='mozimages.MozImage')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("filter_spec", models.CharField(db_index=True, max_length=255)), + ( + "file", + models.ImageField( + height_field="height", + upload_to=wagtail.images.models.get_rendition_upload_to, + width_field="width", + ), + ), + ("width", models.IntegerField(editable=False)), + ("height", models.IntegerField(editable=False)), + ( + "focal_point_key", + models.CharField( + blank=True, default="", editable=False, max_length=16 + ), + ), + ( + "image", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="renditions", + to="mozimages.MozImage", + ), + ), ], - options={ - 'unique_together': {('image', 'filter_spec', 'focal_point_key')}, - }, + options={"unique_together": {("image", "filter_spec", "focal_point_key")}}, ), ] diff --git a/developerportal/apps/mozimages/models.py b/developerportal/apps/mozimages/models.py index 30e22a0fe..5202039d3 100644 --- a/developerportal/apps/mozimages/models.py +++ b/developerportal/apps/mozimages/models.py @@ -7,15 +7,13 @@ class MozImage(AbstractImage): # Additional fields: caption = models.CharField(max_length=255, blank=True) - admin_form_fields = Image.admin_form_fields + ( - 'caption', - ) + admin_form_fields = Image.admin_form_fields + ("caption",) class Rendition(AbstractRendition): - image = models.ForeignKey(MozImage, on_delete=models.CASCADE, related_name='renditions') + image = models.ForeignKey( + MozImage, on_delete=models.CASCADE, related_name="renditions" + ) class Meta: - unique_together = ( - ('image', 'filter_spec', 'focal_point_key'), - ) + unique_together = (("image", "filter_spec", "focal_point_key"),) diff --git a/developerportal/apps/people/edit_handlers.py b/developerportal/apps/people/edit_handlers.py index 7b20546ac..7d7609759 100644 --- a/developerportal/apps/people/edit_handlers.py +++ b/developerportal/apps/people/edit_handlers.py @@ -2,11 +2,11 @@ class CustomLabelFieldPanel(FieldPanel): - def __init__(self, *args, label='Full name', **kwargs): + def __init__(self, *args, label="Full name", **kwargs): super().__init__(*args, **kwargs) self._custom_label = label def render_as_field(self): - if hasattr(self, '_custom_label'): + if hasattr(self, "_custom_label"): self.bound_field.label = self._custom_label return super().render_as_field() diff --git a/developerportal/apps/people/migrations/0001_initial.py b/developerportal/apps/people/migrations/0001_initial.py index 79b09fb73..bd11c1d34 100644 --- a/developerportal/apps/people/migrations/0001_initial.py +++ b/developerportal/apps/people/migrations/0001_initial.py @@ -11,32 +11,63 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('wagtailimages', '0001_squashed_0021'), - ('topics', '0002_topics'), - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), + ("wagtailimages", "0001_squashed_0021"), + ("topics", "0002_topics"), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), ] operations = [ migrations.CreateModel( - name='Person', + name="Person", 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')), - ('first_name', models.CharField(max_length=250)), - ('last_name', models.CharField(max_length=250)), - ('job_title', models.CharField(max_length=250)), - ('intro', wagtail.core.fields.RichTextField(default='')), - ('twitter', models.CharField(max_length=250)), - ('facebook', models.CharField(max_length=250)), - ('linkedin', models.CharField(max_length=250)), - ('github', models.CharField(max_length=250)), - ('email', models.CharField(max_length=250)), - ('intro_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.Image')), - ('labels', modelcluster.fields.ParentalManyToManyField(blank=True, related_name='_person_labels_+', to='topics.Topic')), - ('profile_picture', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.Image')), + ( + "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", + ), + ), + ("first_name", models.CharField(max_length=250)), + ("last_name", models.CharField(max_length=250)), + ("job_title", models.CharField(max_length=250)), + ("intro", wagtail.core.fields.RichTextField(default="")), + ("twitter", models.CharField(max_length=250)), + ("facebook", models.CharField(max_length=250)), + ("linkedin", models.CharField(max_length=250)), + ("github", models.CharField(max_length=250)), + ("email", models.CharField(max_length=250)), + ( + "intro_image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailimages.Image", + ), + ), + ( + "labels", + modelcluster.fields.ParentalManyToManyField( + blank=True, related_name="_person_labels_+", to="topics.Topic" + ), + ), + ( + "profile_picture", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailimages.Image", + ), + ), ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), - ), + options={"abstract": False}, + bases=("wagtailcore.page",), + ) ] diff --git a/developerportal/apps/people/migrations/0002_people.py b/developerportal/apps/people/migrations/0002_people.py index 8862bceb8..3f26c2c32 100644 --- a/developerportal/apps/people/migrations/0002_people.py +++ b/developerportal/apps/people/migrations/0002_people.py @@ -7,19 +7,27 @@ class Migration(migrations.Migration): dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), - ('people', '0001_initial'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), + ("people", "0001_initial"), ] operations = [ migrations.CreateModel( - name='People', + name="People", 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')), + ( + "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", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), - ), + options={"abstract": False}, + bases=("wagtailcore.page",), + ) ] diff --git a/developerportal/apps/people/migrations/0003_auto_20190530_1437.py b/developerportal/apps/people/migrations/0003_auto_20190530_1437.py index 850750c61..4a4552285 100644 --- a/developerportal/apps/people/migrations/0003_auto_20190530_1437.py +++ b/developerportal/apps/people/migrations/0003_auto_20190530_1437.py @@ -5,34 +5,32 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0002_people'), - ] + dependencies = [("people", "0002_people")] operations = [ migrations.AlterField( - model_name='person', - name='email', - field=models.CharField(blank=True, default='', max_length=250), + model_name="person", + name="email", + field=models.CharField(blank=True, default="", max_length=250), ), migrations.AlterField( - model_name='person', - name='facebook', - field=models.CharField(blank=True, default='', max_length=250), + model_name="person", + name="facebook", + field=models.CharField(blank=True, default="", max_length=250), ), migrations.AlterField( - model_name='person', - name='github', - field=models.CharField(blank=True, default='', max_length=250), + model_name="person", + name="github", + field=models.CharField(blank=True, default="", max_length=250), ), migrations.AlterField( - model_name='person', - name='linkedin', - field=models.CharField(blank=True, default='', max_length=250), + model_name="person", + name="linkedin", + field=models.CharField(blank=True, default="", max_length=250), ), migrations.AlterField( - model_name='person', - name='twitter', - field=models.CharField(blank=True, default='', max_length=250), + model_name="person", + name="twitter", + field=models.CharField(blank=True, default="", max_length=250), ), ] diff --git a/developerportal/apps/people/migrations/0004_auto_20190530_1441.py b/developerportal/apps/people/migrations/0004_auto_20190530_1441.py index 1f63fe288..9e0ee9baa 100644 --- a/developerportal/apps/people/migrations/0004_auto_20190530_1441.py +++ b/developerportal/apps/people/migrations/0004_auto_20190530_1441.py @@ -6,14 +6,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0003_auto_20190530_1437'), - ] + dependencies = [("people", "0003_auto_20190530_1437")] operations = [ migrations.AlterField( - model_name='person', - name='labels', - field=modelcluster.fields.ParentalManyToManyField(blank=True, related_name='_person_labels_+', to='topics.Topic', verbose_name='Topics interested in'), - ), + model_name="person", + name="labels", + field=modelcluster.fields.ParentalManyToManyField( + blank=True, + related_name="_person_labels_+", + to="topics.Topic", + verbose_name="Topics interested in", + ), + ) ] diff --git a/developerportal/apps/people/migrations/0005_person_is_mozillian.py b/developerportal/apps/people/migrations/0005_person_is_mozillian.py index 85ce602c4..b7209b331 100644 --- a/developerportal/apps/people/migrations/0005_person_is_mozillian.py +++ b/developerportal/apps/people/migrations/0005_person_is_mozillian.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0004_auto_20190530_1441'), - ] + dependencies = [("people", "0004_auto_20190530_1441")] operations = [ migrations.AddField( - model_name='person', - name='is_mozillian', + model_name="person", + name="is_mozillian", field=models.BooleanField(default=True), - ), + ) ] diff --git a/developerportal/apps/people/migrations/0006_auto_20190604_1050.py b/developerportal/apps/people/migrations/0006_auto_20190604_1050.py index a9492c9d1..9ed6888a5 100644 --- a/developerportal/apps/people/migrations/0006_auto_20190604_1050.py +++ b/developerportal/apps/people/migrations/0006_auto_20190604_1050.py @@ -6,19 +6,18 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0003_subtopic'), - ('people', '0005_person_is_mozillian'), - ] + dependencies = [("topics", "0003_subtopic"), ("people", "0005_person_is_mozillian")] operations = [ - migrations.RemoveField( - model_name='person', - name='labels', - ), + migrations.RemoveField(model_name="person", name="labels"), migrations.AddField( - model_name='person', - name='topics', - field=modelcluster.fields.ParentalManyToManyField(blank=True, related_name='_person_topics_+', to='topics.Topic', verbose_name='Topics interested in'), + model_name="person", + name="topics", + field=modelcluster.fields.ParentalManyToManyField( + blank=True, + related_name="_person_topics_+", + to="topics.Topic", + verbose_name="Topics interested in", + ), ), ] diff --git a/developerportal/apps/people/migrations/0007_auto_20190611_1556.py b/developerportal/apps/people/migrations/0007_auto_20190611_1556.py index e9bbaea7e..3797b3f6d 100644 --- a/developerportal/apps/people/migrations/0007_auto_20190611_1556.py +++ b/developerportal/apps/people/migrations/0007_auto_20190611_1556.py @@ -8,26 +8,45 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0007_auto_20190611_1542'), - ('people', '0006_auto_20190604_1050'), + ("topics", "0007_auto_20190611_1542"), + ("people", "0006_auto_20190604_1050"), ] operations = [ - migrations.RemoveField( - model_name='person', - name='topics', - ), + migrations.RemoveField(model_name="person", name="topics"), migrations.CreateModel( - name='PersonTopic', + name="PersonTopic", 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)), - ('person', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='people.Person')), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "person", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="people.Person", + ), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/people/migrations/0008_featuredperson.py b/developerportal/apps/people/migrations/0008_featuredperson.py index b2e2f4b0e..81d734eef 100644 --- a/developerportal/apps/people/migrations/0008_featuredperson.py +++ b/developerportal/apps/people/migrations/0008_featuredperson.py @@ -7,22 +7,42 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0007_auto_20190611_1556'), - ] + dependencies = [("people", "0007_auto_20190611_1556")] operations = [ migrations.CreateModel( - name='FeaturedPerson', + name="FeaturedPerson", 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)), - ('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='featured_people', to='people.People')), - ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='people.Person')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "page", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="featured_people", + to="people.People", + ), + ), + ( + "person", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="people.Person", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, - ), + options={"ordering": ["sort_order"], "abstract": False}, + ) ] diff --git a/developerportal/apps/people/migrations/0009_auto_20190625_1122.py b/developerportal/apps/people/migrations/0009_auto_20190625_1122.py index aa71ba3da..ba496c562 100644 --- a/developerportal/apps/people/migrations/0009_auto_20190625_1122.py +++ b/developerportal/apps/people/migrations/0009_auto_20190625_1122.py @@ -6,19 +6,29 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0008_featuredperson'), - ] + dependencies = [("people", "0008_featuredperson")] operations = [ migrations.AlterField( - model_name='person', - name='intro_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage'), + model_name="person", + name="intro_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), ), migrations.AlterField( - model_name='person', - name='profile_picture', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage'), + model_name="person", + name="profile_picture", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), ), ] diff --git a/developerportal/apps/people/migrations/0009_auto_20190626_0848.py b/developerportal/apps/people/migrations/0009_auto_20190626_0848.py index 327044a34..1c25f7660 100644 --- a/developerportal/apps/people/migrations/0009_auto_20190626_0848.py +++ b/developerportal/apps/people/migrations/0009_auto_20190626_0848.py @@ -5,13 +5,8 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0008_featuredperson'), - ] + dependencies = [("people", "0008_featuredperson")] operations = [ - migrations.AlterModelOptions( - name='person', - options={'ordering': ['title']}, - ), + migrations.AlterModelOptions(name="person", options={"ordering": ["title"]}) ] diff --git a/developerportal/apps/people/migrations/0009_auto_20190626_1353.py b/developerportal/apps/people/migrations/0009_auto_20190626_1353.py index 4b202339d..9016df256 100644 --- a/developerportal/apps/people/migrations/0009_auto_20190626_1353.py +++ b/developerportal/apps/people/migrations/0009_auto_20190626_1353.py @@ -5,13 +5,8 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0008_featuredperson'), - ] + dependencies = [("people", "0008_featuredperson")] operations = [ - migrations.AlterModelOptions( - name='person', - options={'ordering': ['title']}, - ), + migrations.AlterModelOptions(name="person", options={"ordering": ["title"]}) ] diff --git a/developerportal/apps/people/migrations/0010_auto_20190625_1258.py b/developerportal/apps/people/migrations/0010_auto_20190625_1258.py index 16e958fee..4f745e215 100644 --- a/developerportal/apps/people/migrations/0010_auto_20190625_1258.py +++ b/developerportal/apps/people/migrations/0010_auto_20190625_1258.py @@ -5,13 +5,8 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0009_auto_20190625_1122'), - ] + dependencies = [("people", "0009_auto_20190625_1122")] operations = [ - migrations.AlterModelOptions( - name='person', - options={'ordering': ['title']}, - ), + migrations.AlterModelOptions(name="person", options={"ordering": ["title"]}) ] diff --git a/developerportal/apps/people/migrations/0010_merge_20190627_1318.py b/developerportal/apps/people/migrations/0010_merge_20190627_1318.py index ba5a2e384..de3cae867 100644 --- a/developerportal/apps/people/migrations/0010_merge_20190627_1318.py +++ b/developerportal/apps/people/migrations/0010_merge_20190627_1318.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0009_auto_20190626_0848'), - ('people', '0009_auto_20190626_1353'), + ("people", "0009_auto_20190626_0848"), + ("people", "0009_auto_20190626_1353"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/people/migrations/0011_merge_20190627_1428.py b/developerportal/apps/people/migrations/0011_merge_20190627_1428.py index e5d80782b..a82646ec7 100644 --- a/developerportal/apps/people/migrations/0011_merge_20190627_1428.py +++ b/developerportal/apps/people/migrations/0011_merge_20190627_1428.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0010_auto_20190625_1258'), - ('people', '0009_auto_20190626_0848'), + ("people", "0010_auto_20190625_1258"), + ("people", "0009_auto_20190626_0848"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/people/migrations/0012_auto_20190702_1059.py b/developerportal/apps/people/migrations/0012_auto_20190702_1059.py index 25c530c52..c5d1632af 100644 --- a/developerportal/apps/people/migrations/0012_auto_20190702_1059.py +++ b/developerportal/apps/people/migrations/0012_auto_20190702_1059.py @@ -6,14 +6,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0011_merge_20190627_1428'), - ] + dependencies = [("people", "0011_merge_20190627_1428")] operations = [ migrations.AlterField( - model_name='person', - name='intro', - field=wagtail.core.fields.RichTextField(blank=True, default=''), - ), + model_name="person", + name="intro", + field=wagtail.core.fields.RichTextField(blank=True, default=""), + ) ] diff --git a/developerportal/apps/people/migrations/0012_merge_20190628_1108.py b/developerportal/apps/people/migrations/0012_merge_20190628_1108.py index ec8ffa4ac..2c6b9256f 100644 --- a/developerportal/apps/people/migrations/0012_merge_20190628_1108.py +++ b/developerportal/apps/people/migrations/0012_merge_20190628_1108.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0010_merge_20190627_1318'), - ('people', '0011_merge_20190627_1428'), + ("people", "0010_merge_20190627_1318"), + ("people", "0011_merge_20190627_1428"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/people/migrations/0013_merge_20190702_1247.py b/developerportal/apps/people/migrations/0013_merge_20190702_1247.py index ec4d1a9fd..941021ad0 100644 --- a/developerportal/apps/people/migrations/0013_merge_20190702_1247.py +++ b/developerportal/apps/people/migrations/0013_merge_20190702_1247.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0012_auto_20190702_1059'), - ('people', '0012_merge_20190628_1108'), + ("people", "0012_auto_20190702_1059"), + ("people", "0012_merge_20190628_1108"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/people/migrations/0013_merge_20190702_1300.py b/developerportal/apps/people/migrations/0013_merge_20190702_1300.py index 8270e165d..ae50c0f57 100644 --- a/developerportal/apps/people/migrations/0013_merge_20190702_1300.py +++ b/developerportal/apps/people/migrations/0013_merge_20190702_1300.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0012_merge_20190628_1108'), - ('people', '0012_auto_20190702_1059'), + ("people", "0012_merge_20190628_1108"), + ("people", "0012_auto_20190702_1059"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/people/migrations/0014_merge_20190702_1619.py b/developerportal/apps/people/migrations/0014_merge_20190702_1619.py index c45c78769..97b255eb8 100644 --- a/developerportal/apps/people/migrations/0014_merge_20190702_1619.py +++ b/developerportal/apps/people/migrations/0014_merge_20190702_1619.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0013_merge_20190702_1247'), - ('people', '0013_merge_20190702_1300'), + ("people", "0013_merge_20190702_1247"), + ("people", "0013_merge_20190702_1300"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/people/migrations/0015_auto_20190709_0928.py b/developerportal/apps/people/migrations/0015_auto_20190709_0928.py index 8076a9a68..ac29f2f8c 100644 --- a/developerportal/apps/people/migrations/0015_auto_20190709_0928.py +++ b/developerportal/apps/people/migrations/0015_auto_20190709_0928.py @@ -5,13 +5,10 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0014_merge_20190702_1619'), - ] + dependencies = [("people", "0014_merge_20190702_1619")] operations = [ migrations.AlterModelOptions( - name='people', - options={'verbose_name_plural': 'People'}, - ), + name="people", options={"verbose_name_plural": "People"} + ) ] diff --git a/developerportal/apps/people/migrations/0016_auto_20190711_1915.py b/developerportal/apps/people/migrations/0016_auto_20190711_1915.py index 84035f5fe..01757b185 100644 --- a/developerportal/apps/people/migrations/0016_auto_20190711_1915.py +++ b/developerportal/apps/people/migrations/0016_auto_20190711_1915.py @@ -9,72 +9,93 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('mozimages', '0001_initial'), - ('people', '0015_auto_20190709_0928'), + ("taggit", "0002_auto_20150616_2121"), + ("mozimages", "0001_initial"), + ("people", "0015_auto_20190709_0928"), ] operations = [ - migrations.AlterModelOptions( - name='person', - options={}, - ), + migrations.AlterModelOptions(name="person", options={}), migrations.RenameField( - model_name='person', - old_name='intro', - new_name='description', + model_name="person", old_name="intro", new_name="description" ), migrations.RenameField( - model_name='person', - old_name='intro_image', - new_name='image', - ), - migrations.RemoveField( - model_name='person', - name='first_name', - ), - migrations.RemoveField( - model_name='person', - name='last_name', - ), - migrations.RemoveField( - model_name='person', - name='profile_picture', + model_name="person", old_name="intro_image", new_name="image" ), + migrations.RemoveField(model_name="person", name="first_name"), + migrations.RemoveField(model_name="person", name="last_name"), + migrations.RemoveField(model_name="person", name="profile_picture"), migrations.AddField( - model_name='person', - name='card_description', - field=models.TextField(blank=True, default='', max_length=140, verbose_name='Description'), + model_name="person", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=140, verbose_name="Description" + ), ), migrations.AddField( - model_name='person', - name='card_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage', verbose_name='Image'), + model_name="person", + name="card_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + verbose_name="Image", + ), ), migrations.AddField( - model_name='person', - name='card_title', - field=models.CharField(blank=True, default='', max_length=140, verbose_name='Title'), + model_name="person", + name="card_title", + field=models.CharField( + blank=True, default="", max_length=140, verbose_name="Title" + ), ), migrations.AlterField( - model_name='person', - name='is_mozillian', - field=models.BooleanField(default=True, verbose_name='Is Mozillian'), + model_name="person", + name="is_mozillian", + field=models.BooleanField(default=True, verbose_name="Is Mozillian"), ), migrations.CreateModel( - name='PersonTag', + name="PersonTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='people.Person')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='people_persontag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="people.Person", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="people_persontag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='person', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='people.PersonTag', to='taggit.Tag', verbose_name='Tags'), + model_name="person", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="people.PersonTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/people/migrations/0017_auto_20190718_1424.py b/developerportal/apps/people/migrations/0017_auto_20190718_1424.py index 6c7e2bb43..094bc3490 100644 --- a/developerportal/apps/people/migrations/0017_auto_20190718_1424.py +++ b/developerportal/apps/people/migrations/0017_auto_20190718_1424.py @@ -8,23 +8,41 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('people', '0016_auto_20190711_1915'), + ("taggit", "0002_auto_20150616_2121"), + ("people", "0016_auto_20190711_1915"), ] operations = [ migrations.CreateModel( - name='PeopleTag', + name="PeopleTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='people.People')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='people_peopletag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="people.People", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="people_peopletag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, - ), - migrations.DeleteModel( - name='FeaturedPerson', + options={"abstract": False}, ), + migrations.DeleteModel(name="FeaturedPerson"), ] diff --git a/developerportal/apps/people/migrations/0018_people_keywords.py b/developerportal/apps/people/migrations/0018_people_keywords.py index 7d3bd2b51..bdc123b00 100644 --- a/developerportal/apps/people/migrations/0018_people_keywords.py +++ b/developerportal/apps/people/migrations/0018_people_keywords.py @@ -7,14 +7,20 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('people', '0017_auto_20190718_1424'), + ("taggit", "0002_auto_20150616_2121"), + ("people", "0017_auto_20190718_1424"), ] operations = [ migrations.AddField( - model_name='people', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='people.PeopleTag', to='taggit.Tag', verbose_name='Tags'), - ), + model_name="people", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="people.PeopleTag", + to="taggit.Tag", + verbose_name="Tags", + ), + ) ] diff --git a/developerportal/apps/people/migrations/0019_remove_people_keywords.py b/developerportal/apps/people/migrations/0019_remove_people_keywords.py index 99db0b36d..ce57bbde1 100644 --- a/developerportal/apps/people/migrations/0019_remove_people_keywords.py +++ b/developerportal/apps/people/migrations/0019_remove_people_keywords.py @@ -5,13 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0018_people_keywords'), - ] + dependencies = [("people", "0018_people_keywords")] - operations = [ - migrations.RemoveField( - model_name='people', - name='keywords', - ), - ] + operations = [migrations.RemoveField(model_name="people", name="keywords")] diff --git a/developerportal/apps/people/migrations/0020_people_keywords.py b/developerportal/apps/people/migrations/0020_people_keywords.py index 61670fb2e..cad383a39 100644 --- a/developerportal/apps/people/migrations/0020_people_keywords.py +++ b/developerportal/apps/people/migrations/0020_people_keywords.py @@ -7,14 +7,20 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('people', '0019_remove_people_keywords'), + ("taggit", "0002_auto_20150616_2121"), + ("people", "0019_remove_people_keywords"), ] operations = [ migrations.AddField( - model_name='people', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='people.PeopleTag', to='taggit.Tag', verbose_name='Tags'), - ), + model_name="people", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="people.PeopleTag", + to="taggit.Tag", + verbose_name="Tags", + ), + ) ] diff --git a/developerportal/apps/people/migrations/0021_auto_20190731_1057.py b/developerportal/apps/people/migrations/0021_auto_20190731_1057.py index 1de4c9b1f..228851975 100644 --- a/developerportal/apps/people/migrations/0021_auto_20190731_1057.py +++ b/developerportal/apps/people/migrations/0021_auto_20190731_1057.py @@ -5,18 +5,22 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0020_people_keywords'), - ] + dependencies = [("people", "0020_people_keywords")] operations = [ - migrations.RemoveField( - model_name='person', - name='is_mozillian', - ), + migrations.RemoveField(model_name="person", name="is_mozillian"), migrations.AddField( - model_name='person', - name='role', - field=models.CharField(choices=[('staff', 'Staff'), ('tech-speaker', 'Tech Speaker'), ('guest', 'Guest'), ('contributor', 'Contributor')], default='staff', max_length=250), + model_name="person", + name="role", + field=models.CharField( + choices=[ + ("staff", "Staff"), + ("tech-speaker", "Tech Speaker"), + ("guest", "Guest"), + ("contributor", "Contributor"), + ], + default="staff", + max_length=250, + ), ), ] diff --git a/developerportal/apps/people/migrations/0022_people_description.py b/developerportal/apps/people/migrations/0022_people_description.py index cd3132236..36c60a6ff 100644 --- a/developerportal/apps/people/migrations/0022_people_description.py +++ b/developerportal/apps/people/migrations/0022_people_description.py @@ -5,14 +5,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0021_auto_20190731_1057'), - ] + dependencies = [("people", "0021_auto_20190731_1057")] operations = [ migrations.AddField( - model_name='people', - name='description', - field=models.TextField(blank=True, default='', max_length=250, verbose_name='Description'), - ), + model_name="people", + name="description", + field=models.TextField( + blank=True, default="", max_length=250, verbose_name="Description" + ), + ) ] diff --git a/developerportal/apps/people/migrations/0022_person_websites.py b/developerportal/apps/people/migrations/0022_person_websites.py index 07ead0028..6c06434ef 100644 --- a/developerportal/apps/people/migrations/0022_person_websites.py +++ b/developerportal/apps/people/migrations/0022_person_websites.py @@ -8,14 +8,35 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0021_auto_20190731_1057'), - ] + dependencies = [("people", "0021_auto_20190731_1057")] operations = [ migrations.AddField( - model_name='person', - name='websites', - field=wagtail.core.fields.StreamField([('website', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock(label='URL')), ('title', wagtail.core.blocks.CharBlock(required=False)), ('icon', wagtail.images.blocks.ImageChooserBlock(required=False))]))], blank=True, null=True), - ), + model_name="person", + name="websites", + field=wagtail.core.fields.StreamField( + [ + ( + "website", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock(label="URL")), + ( + "title", + wagtail.core.blocks.CharBlock(required=False), + ), + ( + "icon", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ) + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/people/migrations/0023_merge_20190802_1535.py b/developerportal/apps/people/migrations/0023_merge_20190802_1535.py index 4c6763ee7..d19e04c5b 100644 --- a/developerportal/apps/people/migrations/0023_merge_20190802_1535.py +++ b/developerportal/apps/people/migrations/0023_merge_20190802_1535.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0022_person_websites'), - ('people', '0022_people_description'), + ("people", "0022_person_websites"), + ("people", "0022_people_description"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/people/migrations/0024_auto_20190813_1302.py b/developerportal/apps/people/migrations/0024_auto_20190813_1302.py index 748921271..029045e23 100644 --- a/developerportal/apps/people/migrations/0024_auto_20190813_1302.py +++ b/developerportal/apps/people/migrations/0024_auto_20190813_1302.py @@ -5,14 +5,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0023_merge_20190802_1535'), - ] + dependencies = [("people", "0023_merge_20190802_1535")] operations = [ migrations.AlterField( - model_name='person', - name='card_description', - field=models.TextField(blank=True, default='', max_length=400, verbose_name='Description'), - ), + model_name="person", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=400, verbose_name="Description" + ), + ) ] diff --git a/developerportal/apps/people/migrations/0025_auto_20190813_1503.py b/developerportal/apps/people/migrations/0025_auto_20190813_1503.py index ecf187048..633e6c643 100644 --- a/developerportal/apps/people/migrations/0025_auto_20190813_1503.py +++ b/developerportal/apps/people/migrations/0025_auto_20190813_1503.py @@ -8,24 +8,56 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0024_auto_20190813_1302'), - ] + dependencies = [("people", "0024_auto_20190813_1302")] operations = [ migrations.AlterField( - model_name='people', - name='description', - field=models.TextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="people", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), migrations.AlterField( - model_name='person', - name='description', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional ‘About me’ section content, supports rich text', verbose_name='About'), + model_name="person", + name="description", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional ‘About me’ section content, supports rich text", + verbose_name="About", + ), ), migrations.AlterField( - model_name='person', - name='websites', - field=wagtail.core.fields.StreamField([('website', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock(label='URL')), ('title', wagtail.core.blocks.CharBlock(required=False)), ('icon', wagtail.images.blocks.ImageChooserBlock(required=False))]))], blank=True, help_text='Optional links to any other personal websites', null=True), + model_name="person", + name="websites", + field=wagtail.core.fields.StreamField( + [ + ( + "website", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock(label="URL")), + ( + "title", + wagtail.core.blocks.CharBlock(required=False), + ), + ( + "icon", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ] + ), + ) + ], + blank=True, + help_text="Optional links to any other personal websites", + null=True, + ), ), ] diff --git a/developerportal/apps/people/migrations/0026_auto_20190819_1304.py b/developerportal/apps/people/migrations/0026_auto_20190819_1304.py index 7d0a5cc7a..341aa9ace 100644 --- a/developerportal/apps/people/migrations/0026_auto_20190819_1304.py +++ b/developerportal/apps/people/migrations/0026_auto_20190819_1304.py @@ -6,14 +6,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('people', '0025_auto_20190813_1503'), - ] + dependencies = [("people", "0025_auto_20190813_1503")] operations = [ migrations.AlterField( - model_name='people', - name='description', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), - ), + model_name="people", + name="description", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), + ) ] diff --git a/developerportal/apps/people/models.py b/developerportal/apps/people/models.py index 75181253f..cc2cda2b4 100644 --- a/developerportal/apps/people/models.py +++ b/developerportal/apps/people/models.py @@ -2,13 +2,7 @@ from itertools import chain from operator import attrgetter -from django.db.models import ( - CASCADE, - CharField, - ForeignKey, - SET_NULL, - TextField, -) +from django.db.models import CASCADE, CharField, ForeignKey, SET_NULL, TextField from wagtail.admin.edit_handlers import ( FieldPanel, @@ -34,20 +28,22 @@ class PeopleTag(TaggedItemBase): - content_object = ParentalKey('People', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "People", on_delete=CASCADE, related_name="tagged_items" + ) class People(Page): - parent_page_types = ['home.HomePage', 'content.ContentPage'] - subpage_types = ['Person'] - template = 'people.html' + parent_page_types = ["home.HomePage", "content.ContentPage"] + subpage_types = ["Person"] + template = "people.html" # Content fields description = RichTextField( blank=True, - default='', + default="", features=RICH_TEXT_FEATURES_SIMPLE, - help_text='Optional short text description, max. 400 characters', + help_text="Optional short text description, max. 400 characters", max_length=400, ) @@ -55,33 +51,34 @@ class People(Page): keywords = ClusterTaggableManager(through=PeopleTag, blank=True) # Content panels - content_panels = Page.content_panels + [ - FieldPanel('description'), - ] + content_panels = Page.content_panels + [FieldPanel("description")] # Meta panels meta_panels = [ - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ) ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - FieldPanel('show_in_menus'), - ] - - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + settings_panels = [FieldPanel("slug"), FieldPanel("show_in_menus")] + + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) class Meta: - verbose_name_plural = 'People' + verbose_name_plural = "People" @classmethod def can_create_at(cls, parent): @@ -90,153 +87,162 @@ def can_create_at(cls, parent): def get_context(self, request): context = super().get_context(request) - context['filters'] = self.get_filters() + context["filters"] = self.get_filters() return context @property def people(self): - return Person.objects.all().public().live().order_by('title') + return Person.objects.all().public().live().order_by("title") def get_filters(self): from ..topics.models import Topic + return { - 'roles': True, - 'topics': Topic.objects.live().public().order_by('title'), + "roles": True, + "topics": Topic.objects.live().public().order_by("title"), } class PersonTag(TaggedItemBase): - content_object = ParentalKey('Person', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Person", on_delete=CASCADE, related_name="tagged_items" + ) class PersonTopic(Orderable): - person = ParentalKey('Person', related_name='topics') - topic = ForeignKey('topics.Topic', on_delete=CASCADE, related_name='+') + person = ParentalKey("Person", related_name="topics") + topic = ForeignKey("topics.Topic", on_delete=CASCADE, related_name="+") - panels = [ - PageChooserPanel('topic'), - ] + panels = [PageChooserPanel("topic")] class Person(Page): - resource_type = 'person' - parent_page_types = ['People'] + resource_type = "person" + parent_page_types = ["People"] subpage_types = [] - template = 'person.html' + template = "person.html" # Content fields job_title = CharField(max_length=250) - role = CharField(max_length=250, choices=ROLE_CHOICES, default='staff') + role = CharField(max_length=250, choices=ROLE_CHOICES, default="staff") description = RichTextField( - 'About', + "About", blank=True, - default='', + default="", features=RICH_TEXT_FEATURES_SIMPLE, - help_text='Optional ‘About me’ section content, supports rich text', + help_text="Optional ‘About me’ section content, supports rich text", ) image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', + related_name="+", ) # Card fields - card_title = CharField('Title', max_length=140, blank=True, default='') - card_description = TextField('Description', max_length=400, blank=True, default='') + card_title = CharField("Title", max_length=140, blank=True, default="") + card_description = TextField("Description", max_length=400, blank=True, default="") card_image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', - verbose_name='Image', + related_name="+", + verbose_name="Image", ) # Meta - twitter = CharField(max_length=250, blank=True, default='') - facebook = CharField(max_length=250, blank=True, default='') - linkedin = CharField(max_length=250, blank=True, default='') - github = CharField(max_length=250, blank=True, default='') - email = CharField(max_length=250, blank=True, default='') + twitter = CharField(max_length=250, blank=True, default="") + facebook = CharField(max_length=250, blank=True, default="") + linkedin = CharField(max_length=250, blank=True, default="") + github = CharField(max_length=250, blank=True, default="") + email = CharField(max_length=250, blank=True, default="") websites = StreamField( - StreamBlock([ - ('website', PersonalWebsiteBlock()) - ], max_num=3, required=False), + StreamBlock([("website", PersonalWebsiteBlock())], max_num=3, required=False), null=True, blank=True, - help_text='Optional links to any other personal websites', + help_text="Optional links to any other personal websites", ) keywords = ClusterTaggableManager(through=PersonTag, blank=True) # Content panels content_panels = [ - MultiFieldPanel([ - CustomLabelFieldPanel('title', label='Full name'), - FieldPanel('job_title'), - FieldPanel('role'), - ], heading='Details'), - FieldPanel('description'), - MultiFieldPanel([ - ImageChooserPanel('image'), - ], heading='Image', help_text=( - 'Optional header image. If not specified a fallback will be used. This image is also shown when sharing ' - 'this page via social media' - )), + MultiFieldPanel( + [ + CustomLabelFieldPanel("title", label="Full name"), + FieldPanel("job_title"), + FieldPanel("role"), + ], + heading="Details", + ), + FieldPanel("description"), + MultiFieldPanel( + [ImageChooserPanel("image")], + heading="Image", + help_text=( + "Optional header image. If not specified a fallback will be used. This image is also shown when sharing " + "this page via social media" + ), + ), ] # Card panels card_panels = [ - FieldPanel('card_title'), - FieldPanel('card_description'), - ImageChooserPanel('card_image'), + FieldPanel("card_title"), + FieldPanel("card_description"), + ImageChooserPanel("card_image"), ] # Meta panels meta_panels = [ - MultiFieldPanel([ - InlinePanel('topics'), - ], heading='Topics interested in'), - MultiFieldPanel([ - FieldPanel('twitter'), - FieldPanel('facebook'), - FieldPanel('linkedin'), - FieldPanel('github'), - FieldPanel('email'), - ], heading='Profiles', help_text=''), - StreamFieldPanel('websites'), - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel([InlinePanel("topics")], heading="Topics interested in"), + MultiFieldPanel( + [ + FieldPanel("twitter"), + FieldPanel("facebook"), + FieldPanel("linkedin"), + FieldPanel("github"), + FieldPanel("email"), + ], + heading="Profiles", + help_text="", + ), + StreamFieldPanel("websites"), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ), ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - ] + settings_panels = [FieldPanel("slug")] # Tabs - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) @property def events(self): - ''' + """ Return upcoming events where this person is a speaker, ordered by start date - ''' + """ from ..events.models import Event upcoming_events = ( - Event.objects - .filter(start_date__gte=datetime.datetime.now()) + Event.objects.filter(start_date__gte=datetime.datetime.now()) .live() .public() ) @@ -248,14 +254,14 @@ def events(self): if event.has_speaker(self): speaker_events = speaker_events | Event.objects.page(event) - return speaker_events.order_by('start_date') + return speaker_events.order_by("start_date") @property def articles(self): - ''' + """ Return articles and external articles where this person is (one of) the authors, ordered by article date, most recent first - ''' + """ from ..articles.models import Article from ..externalcontent.models import ExternalArticle @@ -271,16 +277,20 @@ def articles(self): for external_article in all_external_articles: if external_article.has_author(self): - external_articles = external_articles | ExternalArticle.objects.page(external_article) + external_articles = external_articles | ExternalArticle.objects.page( + external_article + ) - return sorted(chain(articles, external_articles), key=attrgetter('date'), reverse=True) + return sorted( + chain(articles, external_articles), key=attrgetter("date"), reverse=True + ) @property def videos(self): - ''' + """ Return the most recent videos and external videos where this person is (one of) the speakers. - ''' + """ from ..videos.models import Video from ..externalcontent.models import ExternalVideo @@ -296,13 +306,14 @@ def videos(self): for external_video in all_external_videos: if external_video.has_speaker(self): - external_videos = external_videos | ExternalVideo.objects.page(external_video) + external_videos = external_videos | ExternalVideo.objects.page( + external_video + ) - return sorted(chain(videos, external_videos), key=attrgetter('date'), reverse=True) + return sorted( + chain(videos, external_videos), key=attrgetter("date"), reverse=True + ) @property def role_group(self): - return { - 'slug': self.role, - 'title': dict(ROLE_CHOICES).get(self.role, ''), - } + return {"slug": self.role, "title": dict(ROLE_CHOICES).get(self.role, "")} diff --git a/developerportal/apps/people/wagtail_hooks.py b/developerportal/apps/people/wagtail_hooks.py index d79528d5d..122e5d538 100644 --- a/developerportal/apps/people/wagtail_hooks.py +++ b/developerportal/apps/people/wagtail_hooks.py @@ -6,7 +6,7 @@ class PeopleAdmin(ModelAdmin): model = People - menu_icon = 'group' + menu_icon = "group" menu_order = 230 url_helper_class = ExplorerRedirectAdminURLHelper diff --git a/developerportal/apps/staticbuild/migrations/0001_initial.py b/developerportal/apps/staticbuild/migrations/0001_initial.py index 2932f065e..d38d501f4 100644 --- a/developerportal/apps/staticbuild/migrations/0001_initial.py +++ b/developerportal/apps/staticbuild/migrations/0001_initial.py @@ -7,14 +7,21 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='StaticBuild', + name="StaticBuild", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ) ], - ), + ) ] diff --git a/developerportal/apps/staticbuild/migrations/0002_staticbuild_date.py b/developerportal/apps/staticbuild/migrations/0002_staticbuild_date.py index 06642868a..486729747 100644 --- a/developerportal/apps/staticbuild/migrations/0002_staticbuild_date.py +++ b/developerportal/apps/staticbuild/migrations/0002_staticbuild_date.py @@ -6,15 +6,15 @@ class Migration(migrations.Migration): - dependencies = [ - ('staticbuild', '0001_initial'), - ] + dependencies = [("staticbuild", "0001_initial")] operations = [ migrations.AddField( - model_name='staticbuild', - name='date', - field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + model_name="staticbuild", + name="date", + field=models.DateTimeField( + auto_now_add=True, default=django.utils.timezone.now + ), preserve_default=False, - ), + ) ] diff --git a/developerportal/apps/staticbuild/models.py b/developerportal/apps/staticbuild/models.py index 395fe7e0e..a93280571 100644 --- a/developerportal/apps/staticbuild/models.py +++ b/developerportal/apps/staticbuild/models.py @@ -7,11 +7,12 @@ class StaticBuild(Model): date = DateTimeField(auto_now_add=True) def __str__(self): - return date_format(self.date, 'SHORT_DATETIME_FORMAT') + return date_format(self.date, "SHORT_DATETIME_FORMAT") -@receiver(signals.post_save, sender=StaticBuild, dispatch_uid='static_build_uid') +@receiver(signals.post_save, sender=StaticBuild, dispatch_uid="static_build_uid") def trigger_build(sender, instance, created=False, **kwargs): if created: from .wagtail_hooks import static_build + static_build(force=True) diff --git a/developerportal/apps/staticbuild/wagtail_hooks.py b/developerportal/apps/staticbuild/wagtail_hooks.py index 0ad3526c6..bd11726a0 100644 --- a/developerportal/apps/staticbuild/wagtail_hooks.py +++ b/developerportal/apps/staticbuild/wagtail_hooks.py @@ -11,13 +11,13 @@ from .models import StaticBuild -logging.basicConfig(level=os.environ.get('LOGLEVEL', logging.INFO)) +logging.basicConfig(level=os.environ.get("LOGLEVEL", logging.INFO)) logger = logging.getLogger(__name__) class ArticleAdmin(ModelAdmin): model = StaticBuild - menu_icon = 'doc-full' + menu_icon = "doc-full" add_to_settings_menu = True @@ -26,14 +26,14 @@ class ArticleAdmin(ModelAdmin): def _static_build_async(force=False, pipeline=settings.STATIC_BUILD_PIPELINE, **kwargs): """Calls each command in the static build pipeline in turn.""" - log_prefix = 'Static build task' + log_prefix = "Static build task" for name, command in pipeline: if settings.DEBUG and not force: - logger.info(f'{log_prefix} ‘{name}’ skipped.') + logger.info(f"{log_prefix} ‘{name}’ skipped.") else: - logger.info(f'{log_prefix} ‘{name}’ started.') + logger.info(f"{log_prefix} ‘{name}’ started.") call_command(command) - logger.info(f'{log_prefix} ‘{name}’ finished.') + logger.info(f"{log_prefix} ‘{name}’ finished.") def static_build(**kwargs): diff --git a/developerportal/apps/topics/migrations/0001_initial.py b/developerportal/apps/topics/migrations/0001_initial.py index 11fd7936e..cf463ea46 100644 --- a/developerportal/apps/topics/migrations/0001_initial.py +++ b/developerportal/apps/topics/migrations/0001_initial.py @@ -9,18 +9,26 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural") ] operations = [ migrations.CreateModel( - name='Topic', + name="Topic", 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')), + ( + "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", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), - ), + options={"abstract": False}, + bases=("wagtailcore.page",), + ) ] diff --git a/developerportal/apps/topics/migrations/0002_topics.py b/developerportal/apps/topics/migrations/0002_topics.py index d84583e02..6546e88fe 100644 --- a/developerportal/apps/topics/migrations/0002_topics.py +++ b/developerportal/apps/topics/migrations/0002_topics.py @@ -7,19 +7,27 @@ class Migration(migrations.Migration): dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), - ('topics', '0001_initial'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), + ("topics", "0001_initial"), ] operations = [ migrations.CreateModel( - name='Topics', + name="Topics", 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')), + ( + "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", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), - ), + options={"abstract": False}, + bases=("wagtailcore.page",), + ) ] diff --git a/developerportal/apps/topics/migrations/0003_subtopic.py b/developerportal/apps/topics/migrations/0003_subtopic.py index 588716c30..d81f999a5 100644 --- a/developerportal/apps/topics/migrations/0003_subtopic.py +++ b/developerportal/apps/topics/migrations/0003_subtopic.py @@ -6,19 +6,25 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0002_topics'), - ] + dependencies = [("topics", "0002_topics")] operations = [ migrations.CreateModel( - name='SubTopic', + name="SubTopic", fields=[ - ('topic_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='topics.Topic')), + ( + "topic_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="topics.Topic", + ), + ) ], - options={ - 'abstract': False, - }, - bases=('topics.topic',), - ), + options={"abstract": False}, + bases=("topics.topic",), + ) ] diff --git a/developerportal/apps/topics/migrations/0004_topicfeaturedarticle.py b/developerportal/apps/topics/migrations/0004_topicfeaturedarticle.py index 7b8b9e1f7..8f9412dd7 100644 --- a/developerportal/apps/topics/migrations/0004_topicfeaturedarticle.py +++ b/developerportal/apps/topics/migrations/0004_topicfeaturedarticle.py @@ -8,22 +8,44 @@ class Migration(migrations.Migration): dependencies = [ - ('articles', '0016_auto_20190604_1317'), - ('topics', '0003_subtopic'), + ("articles", "0016_auto_20190604_1317"), + ("topics", "0003_subtopic"), ] operations = [ migrations.CreateModel( - name='TopicFeaturedArticle', + name="TopicFeaturedArticle", 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)), - ('article', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='articles.Article')), - ('topic', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='featured_articles', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="articles.Article", + ), + ), + ( + "topic", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="featured_articles", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, - ), + options={"ordering": ["sort_order"], "abstract": False}, + ) ] diff --git a/developerportal/apps/topics/migrations/0005_auto_20190610_1413.py b/developerportal/apps/topics/migrations/0005_auto_20190610_1413.py index a02ca4121..aa66726b4 100644 --- a/developerportal/apps/topics/migrations/0005_auto_20190610_1413.py +++ b/developerportal/apps/topics/migrations/0005_auto_20190610_1413.py @@ -6,18 +6,16 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0004_topicfeaturedarticle'), - ] + dependencies = [("topics", "0004_topicfeaturedarticle")] operations = [ migrations.AlterModelOptions( - name='subtopic', - options={'verbose_name': 'Sub-topic', 'verbose_name_plural': 'Sub-topics'}, + name="subtopic", + options={"verbose_name": "Sub-topic", "verbose_name_plural": "Sub-topics"}, ), migrations.AddField( - model_name='topic', - name='intro', - field=wagtail.core.fields.RichTextField(default=''), + model_name="topic", + name="intro", + field=wagtail.core.fields.RichTextField(default=""), ), ] diff --git a/developerportal/apps/topics/migrations/0006_auto_20190611_1453.py b/developerportal/apps/topics/migrations/0006_auto_20190611_1453.py index dc6a09abf..eca57bad7 100644 --- a/developerportal/apps/topics/migrations/0006_auto_20190611_1453.py +++ b/developerportal/apps/topics/migrations/0006_auto_20190611_1453.py @@ -8,27 +8,53 @@ class Migration(migrations.Migration): dependencies = [ - ('people', '0006_auto_20190604_1050'), - ('topics', '0005_auto_20190610_1413'), + ("people", "0006_auto_20190604_1050"), + ("topics", "0005_auto_20190610_1413"), ] operations = [ migrations.AlterField( - model_name='topicfeaturedarticle', - name='article', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='articles.Article'), + model_name="topicfeaturedarticle", + name="article", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="articles.Article", + ), ), migrations.CreateModel( - name='TopicPerson', + name="TopicPerson", 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)), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='people.Person')), - ('topic', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='people', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="people.Person", + ), + ), + ( + "topic", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="people", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/topics/migrations/0007_auto_20190611_1542.py b/developerportal/apps/topics/migrations/0007_auto_20190611_1542.py index f022bd6c2..b4b821f06 100644 --- a/developerportal/apps/topics/migrations/0007_auto_20190611_1542.py +++ b/developerportal/apps/topics/migrations/0007_auto_20190611_1542.py @@ -5,14 +5,10 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0006_auto_20190611_1453'), - ] + dependencies = [("topics", "0006_auto_20190611_1453")] operations = [ migrations.RenameField( - model_name='topicperson', - old_name='author', - new_name='person', - ), + model_name="topicperson", old_name="author", new_name="person" + ) ] diff --git a/developerportal/apps/topics/migrations/0008_auto_20190612_1759.py b/developerportal/apps/topics/migrations/0008_auto_20190612_1759.py index 627a454e5..3e6b69d28 100644 --- a/developerportal/apps/topics/migrations/0008_auto_20190612_1759.py +++ b/developerportal/apps/topics/migrations/0008_auto_20190612_1759.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0007_auto_20190611_1542'), - ] + dependencies = [("topics", "0007_auto_20190611_1542")] operations = [ migrations.AlterField( - model_name='topic', - name='intro', - field=models.CharField(blank=True, default='', max_length=250), - ), + model_name="topic", + name="intro", + field=models.CharField(blank=True, default="", max_length=250), + ) ] diff --git a/developerportal/apps/topics/migrations/0009_topic_color.py b/developerportal/apps/topics/migrations/0009_topic_color.py index 713dcb963..0c4a37d45 100644 --- a/developerportal/apps/topics/migrations/0009_topic_color.py +++ b/developerportal/apps/topics/migrations/0009_topic_color.py @@ -5,14 +5,21 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0008_auto_20190612_1759'), - ] + dependencies = [("topics", "0008_auto_20190612_1759")] operations = [ migrations.AddField( - model_name='topic', - name='color', - field=models.CharField(choices=[('blue', 'Blue'), ('orange', 'Orange'), ('green', 'Green'), ('red', 'Red')], default='blue', max_length=14), - ), + model_name="topic", + name="color", + field=models.CharField( + choices=[ + ("blue", "Blue"), + ("orange", "Orange"), + ("green", "Green"), + ("red", "Red"), + ], + default="blue", + max_length=14, + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0010_auto_20190618_0840.py b/developerportal/apps/topics/migrations/0010_auto_20190618_0840.py index 3dc0ae55c..bf008e82c 100644 --- a/developerportal/apps/topics/migrations/0010_auto_20190618_0840.py +++ b/developerportal/apps/topics/migrations/0010_auto_20190618_0840.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0009_topic_color'), - ] + dependencies = [("topics", "0009_topic_color")] operations = [ migrations.AlterField( - model_name='topic', - name='intro', - field=models.TextField(blank=True, default='', max_length=250), - ), + model_name="topic", + name="intro", + field=models.TextField(blank=True, default="", max_length=250), + ) ] diff --git a/developerportal/apps/topics/migrations/0010_topic_get_started.py b/developerportal/apps/topics/migrations/0010_topic_get_started.py index 2d846e975..dde29eec6 100644 --- a/developerportal/apps/topics/migrations/0010_topic_get_started.py +++ b/developerportal/apps/topics/migrations/0010_topic_get_started.py @@ -8,14 +8,28 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0009_topic_color'), - ] + dependencies = [("topics", "0009_topic_color")] operations = [ migrations.AddField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('buttonText', wagtail.core.blocks.CharBlock()), ('buttonUrl', wagtail.core.blocks.PageChooserBlock())]))], default=''), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("buttonText", wagtail.core.blocks.CharBlock()), + ("buttonUrl", wagtail.core.blocks.PageChooserBlock()), + ] + ), + ) + ], + default="", + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0011_auto_20190614_0932.py b/developerportal/apps/topics/migrations/0011_auto_20190614_0932.py index 47708bcfe..fc9550e7d 100644 --- a/developerportal/apps/topics/migrations/0011_auto_20190614_0932.py +++ b/developerportal/apps/topics/migrations/0011_auto_20190614_0932.py @@ -8,14 +8,27 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0010_topic_get_started'), - ] + dependencies = [("topics", "0010_topic_get_started")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('buttonText', wagtail.core.blocks.CharBlock()), ('buttonUrl', wagtail.core.blocks.PageChooserBlock())]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("buttonText", wagtail.core.blocks.CharBlock()), + ("buttonUrl", wagtail.core.blocks.PageChooserBlock()), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0012_auto_20190614_1319.py b/developerportal/apps/topics/migrations/0012_auto_20190614_1319.py index 774af898d..8afc014e8 100644 --- a/developerportal/apps/topics/migrations/0012_auto_20190614_1319.py +++ b/developerportal/apps/topics/migrations/0012_auto_20190614_1319.py @@ -8,14 +8,30 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0011_auto_20190614_0932'), - ] + dependencies = [("topics", "0011_auto_20190614_0932")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('button_destination', wagtail.core.blocks.PageChooserBlock())]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "button_destination", + wagtail.core.blocks.PageChooserBlock(), + ), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0013_merge_20190618_1635.py b/developerportal/apps/topics/migrations/0013_merge_20190618_1635.py index 84cdaeb39..9edb0e630 100644 --- a/developerportal/apps/topics/migrations/0013_merge_20190618_1635.py +++ b/developerportal/apps/topics/migrations/0013_merge_20190618_1635.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0010_auto_20190618_0840'), - ('topics', '0012_auto_20190614_1319'), + ("topics", "0010_auto_20190618_0840"), + ("topics", "0012_auto_20190614_1319"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0013_merge_20190619_1357.py b/developerportal/apps/topics/migrations/0013_merge_20190619_1357.py index 7a3c16bb8..c0fb700b3 100644 --- a/developerportal/apps/topics/migrations/0013_merge_20190619_1357.py +++ b/developerportal/apps/topics/migrations/0013_merge_20190619_1357.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0010_auto_20190618_0840'), - ('topics', '0012_auto_20190614_1319'), + ("topics", "0010_auto_20190618_0840"), + ("topics", "0012_auto_20190614_1319"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0013_topic_icon.py b/developerportal/apps/topics/migrations/0013_topic_icon.py index 74138dc00..f26605ec2 100644 --- a/developerportal/apps/topics/migrations/0013_topic_icon.py +++ b/developerportal/apps/topics/migrations/0013_topic_icon.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0012_auto_20190614_1319'), - ] + dependencies = [("topics", "0012_auto_20190614_1319")] operations = [ migrations.AddField( - model_name='topic', - name='icon', - field=models.FileField(default='', upload_to='topics/icons'), - ), + model_name="topic", + name="icon", + field=models.FileField(default="", upload_to="topics/icons"), + ) ] diff --git a/developerportal/apps/topics/migrations/0014_merge_20190618_1609.py b/developerportal/apps/topics/migrations/0014_merge_20190618_1609.py index 978c18ac3..a1ac7f3e9 100644 --- a/developerportal/apps/topics/migrations/0014_merge_20190618_1609.py +++ b/developerportal/apps/topics/migrations/0014_merge_20190618_1609.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0010_auto_20190618_0840'), - ('topics', '0013_topic_icon'), + ("topics", "0010_auto_20190618_0840"), + ("topics", "0013_topic_icon"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0015_merge_20190619_1437.py b/developerportal/apps/topics/migrations/0015_merge_20190619_1437.py index a0c2669ed..ef2fcd794 100644 --- a/developerportal/apps/topics/migrations/0015_merge_20190619_1437.py +++ b/developerportal/apps/topics/migrations/0015_merge_20190619_1437.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0013_merge_20190618_1635'), - ('topics', '0014_merge_20190618_1609'), + ("topics", "0013_merge_20190618_1635"), + ("topics", "0014_merge_20190618_1609"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0015_merge_20190619_1506.py b/developerportal/apps/topics/migrations/0015_merge_20190619_1506.py index 7f1b4bd8d..7becca1ea 100644 --- a/developerportal/apps/topics/migrations/0015_merge_20190619_1506.py +++ b/developerportal/apps/topics/migrations/0015_merge_20190619_1506.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0014_merge_20190618_1609'), - ('topics', '0013_merge_20190618_1635'), + ("topics", "0014_merge_20190618_1609"), + ("topics", "0013_merge_20190618_1635"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0015_merge_20190621_1009.py b/developerportal/apps/topics/migrations/0015_merge_20190621_1009.py index 63ef1322c..4865be73b 100644 --- a/developerportal/apps/topics/migrations/0015_merge_20190621_1009.py +++ b/developerportal/apps/topics/migrations/0015_merge_20190621_1009.py @@ -6,10 +6,9 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0014_merge_20190618_1609'), - ('topics', '0013_merge_20190619_1357'), - ('topics', '0013_merge_20190618_1635'), + ("topics", "0014_merge_20190618_1609"), + ("topics", "0013_merge_20190619_1357"), + ("topics", "0013_merge_20190618_1635"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0016_auto_20190619_1437.py b/developerportal/apps/topics/migrations/0016_auto_20190619_1437.py index d814e31f3..a64af6550 100644 --- a/developerportal/apps/topics/migrations/0016_auto_20190619_1437.py +++ b/developerportal/apps/topics/migrations/0016_auto_20190619_1437.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0015_merge_20190619_1437'), - ] + dependencies = [("topics", "0015_merge_20190619_1437")] operations = [ migrations.AlterField( - model_name='topic', - name='icon', - field=models.FileField(blank=True, default='', upload_to='topics/icons'), - ), + model_name="topic", + name="icon", + field=models.FileField(blank=True, default="", upload_to="topics/icons"), + ) ] diff --git a/developerportal/apps/topics/migrations/0016_auto_20190619_1506.py b/developerportal/apps/topics/migrations/0016_auto_20190619_1506.py index 5f3f8628e..abfa4a3bc 100644 --- a/developerportal/apps/topics/migrations/0016_auto_20190619_1506.py +++ b/developerportal/apps/topics/migrations/0016_auto_20190619_1506.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0015_merge_20190619_1506'), - ] + dependencies = [("topics", "0015_merge_20190619_1506")] operations = [ migrations.AlterField( - model_name='topic', - name='icon', - field=models.FileField(blank=True, default='', upload_to='topics/icons'), - ), + model_name="topic", + name="icon", + field=models.FileField(blank=True, default="", upload_to="topics/icons"), + ) ] diff --git a/developerportal/apps/topics/migrations/0016_auto_20190624_1129.py b/developerportal/apps/topics/migrations/0016_auto_20190624_1129.py index 3de124746..ba0d41169 100644 --- a/developerportal/apps/topics/migrations/0016_auto_20190624_1129.py +++ b/developerportal/apps/topics/migrations/0016_auto_20190624_1129.py @@ -5,14 +5,12 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0015_merge_20190621_1009'), - ] + dependencies = [("topics", "0015_merge_20190621_1009")] operations = [ migrations.AlterField( - model_name='topic', - name='icon', - field=models.FileField(blank=True, default='', upload_to='topics/icons'), - ), + model_name="topic", + name="icon", + field=models.FileField(blank=True, default="", upload_to="topics/icons"), + ) ] diff --git a/developerportal/apps/topics/migrations/0017_merge_20190621_1033.py b/developerportal/apps/topics/migrations/0017_merge_20190621_1033.py index 9949b3868..60bc5293d 100644 --- a/developerportal/apps/topics/migrations/0017_merge_20190621_1033.py +++ b/developerportal/apps/topics/migrations/0017_merge_20190621_1033.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0015_merge_20190621_1009'), - ('topics', '0016_auto_20190619_1506'), + ("topics", "0015_merge_20190621_1009"), + ("topics", "0016_auto_20190619_1506"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0017_merge_20190624_0904.py b/developerportal/apps/topics/migrations/0017_merge_20190624_0904.py index 31ee4b481..7585d4a44 100644 --- a/developerportal/apps/topics/migrations/0017_merge_20190624_0904.py +++ b/developerportal/apps/topics/migrations/0017_merge_20190624_0904.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0016_auto_20190619_1437'), - ('topics', '0015_merge_20190621_1009'), + ("topics", "0016_auto_20190619_1437"), + ("topics", "0015_merge_20190621_1009"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0018_merge_20190624_1248.py b/developerportal/apps/topics/migrations/0018_merge_20190624_1248.py index 0efcf2a5b..9a982c1df 100644 --- a/developerportal/apps/topics/migrations/0018_merge_20190624_1248.py +++ b/developerportal/apps/topics/migrations/0018_merge_20190624_1248.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0017_merge_20190624_0904'), - ('topics', '0017_merge_20190621_1033'), + ("topics", "0017_merge_20190624_0904"), + ("topics", "0017_merge_20190621_1033"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0018_merge_20190624_1252.py b/developerportal/apps/topics/migrations/0018_merge_20190624_1252.py index 5f02e2635..3612cbb02 100644 --- a/developerportal/apps/topics/migrations/0018_merge_20190624_1252.py +++ b/developerportal/apps/topics/migrations/0018_merge_20190624_1252.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0016_auto_20190624_1129'), - ('topics', '0017_merge_20190624_0904'), + ("topics", "0016_auto_20190624_1129"), + ("topics", "0017_merge_20190624_0904"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0019_merge_20190625_1257.py b/developerportal/apps/topics/migrations/0019_merge_20190625_1257.py index 5d0eaf6c5..e4be23644 100644 --- a/developerportal/apps/topics/migrations/0019_merge_20190625_1257.py +++ b/developerportal/apps/topics/migrations/0019_merge_20190625_1257.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0018_merge_20190624_1252'), - ('topics', '0018_merge_20190624_1248'), + ("topics", "0018_merge_20190624_1252"), + ("topics", "0018_merge_20190624_1248"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0020_auto_20190701_1104.py b/developerportal/apps/topics/migrations/0020_auto_20190701_1104.py index 172425638..f55a75e4d 100644 --- a/developerportal/apps/topics/migrations/0020_auto_20190701_1104.py +++ b/developerportal/apps/topics/migrations/0020_auto_20190701_1104.py @@ -8,14 +8,39 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0019_merge_20190625_1257'), - ] + dependencies = [("topics", "0019_merge_20190625_1257")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(label='Button destination', required=False)), ('external_link', wagtail.core.blocks.URLBlock(label='Button external link destination', required=False))]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + label="Button destination", required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock( + label="Button external link destination", + required=False, + ), + ), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0020_auto_20190702_1401.py b/developerportal/apps/topics/migrations/0020_auto_20190702_1401.py index c5c31bc34..c3fd5da3e 100644 --- a/developerportal/apps/topics/migrations/0020_auto_20190702_1401.py +++ b/developerportal/apps/topics/migrations/0020_auto_20190702_1401.py @@ -8,14 +8,36 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0019_merge_20190625_1257'), - ] + dependencies = [("topics", "0019_merge_20190625_1257")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(required=False))]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock(required=False), + ), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0020_topic_featured.py b/developerportal/apps/topics/migrations/0020_topic_featured.py index d37b208c9..534d12209 100644 --- a/developerportal/apps/topics/migrations/0020_topic_featured.py +++ b/developerportal/apps/topics/migrations/0020_topic_featured.py @@ -8,14 +8,42 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0019_merge_20190625_1257'), - ] + dependencies = [("topics", "0019_merge_20190625_1257")] operations = [ migrations.AddField( - model_name='topic', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('intro', wagtail.core.blocks.TextBlock(required=False)), ('header_image', wagtail.images.blocks.ImageChooserBlock(label='Image'))]))], blank=True, null=True), - ), + model_name="topic", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "intro", + wagtail.core.blocks.TextBlock(required=False), + ), + ( + "header_image", + wagtail.images.blocks.ImageChooserBlock( + label="Image" + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0021_auto_20190701_1105.py b/developerportal/apps/topics/migrations/0021_auto_20190701_1105.py index 920d644bf..2124ac2cd 100644 --- a/developerportal/apps/topics/migrations/0021_auto_20190701_1105.py +++ b/developerportal/apps/topics/migrations/0021_auto_20190701_1105.py @@ -8,14 +8,36 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0020_auto_20190701_1104'), - ] + dependencies = [("topics", "0020_auto_20190701_1104")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(required=False))]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock(required=False), + ), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0021_auto_20190702_1402.py b/developerportal/apps/topics/migrations/0021_auto_20190702_1402.py index a20f1115e..c7d4fed42 100644 --- a/developerportal/apps/topics/migrations/0021_auto_20190702_1402.py +++ b/developerportal/apps/topics/migrations/0021_auto_20190702_1402.py @@ -8,14 +8,30 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0020_auto_20190702_1401'), - ] + dependencies = [("topics", "0020_auto_20190702_1401")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('button_destination', wagtail.core.blocks.PageChooserBlock())]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "button_destination", + wagtail.core.blocks.PageChooserBlock(), + ), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0022_auto_20190702_1123.py b/developerportal/apps/topics/migrations/0022_auto_20190702_1123.py index f9f9b8588..2d254f3c1 100644 --- a/developerportal/apps/topics/migrations/0022_auto_20190702_1123.py +++ b/developerportal/apps/topics/migrations/0022_auto_20190702_1123.py @@ -8,14 +8,30 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0021_auto_20190701_1105'), - ] + dependencies = [("topics", "0021_auto_20190701_1105")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('button_destination', wagtail.core.blocks.PageChooserBlock())]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "button_destination", + wagtail.core.blocks.PageChooserBlock(), + ), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0023_auto_20190702_1318.py b/developerportal/apps/topics/migrations/0023_auto_20190702_1318.py index 7457b48bb..2556ae220 100644 --- a/developerportal/apps/topics/migrations/0023_auto_20190702_1318.py +++ b/developerportal/apps/topics/migrations/0023_auto_20190702_1318.py @@ -8,14 +8,36 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0022_auto_20190702_1123'), - ] + dependencies = [("topics", "0022_auto_20190702_1123")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(required=False))]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock(required=False), + ), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0024_merge_20190702_1619.py b/developerportal/apps/topics/migrations/0024_merge_20190702_1619.py index b36f2a5e7..7af61c3dd 100644 --- a/developerportal/apps/topics/migrations/0024_merge_20190702_1619.py +++ b/developerportal/apps/topics/migrations/0024_merge_20190702_1619.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0023_auto_20190702_1318'), - ('topics', '0020_topic_featured'), + ("topics", "0023_auto_20190702_1318"), + ("topics", "0020_topic_featured"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0025_auto_20190702_1620.py b/developerportal/apps/topics/migrations/0025_auto_20190702_1620.py index c02a4ece6..4cb9056cb 100644 --- a/developerportal/apps/topics/migrations/0025_auto_20190702_1620.py +++ b/developerportal/apps/topics/migrations/0025_auto_20190702_1620.py @@ -8,14 +8,39 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0024_merge_20190702_1619'), - ] + dependencies = [("topics", "0024_merge_20190702_1619")] operations = [ migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(help_text='External URL to link to instead of a page.', required=False))]))]), - ), + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock( + help_text="External URL to link to instead of a page.", + required=False, + ), + ), + ] + ), + ) + ] + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0026_merge_20190704_1459.py b/developerportal/apps/topics/migrations/0026_merge_20190704_1459.py index 698b01c3f..5bef31c3e 100644 --- a/developerportal/apps/topics/migrations/0026_merge_20190704_1459.py +++ b/developerportal/apps/topics/migrations/0026_merge_20190704_1459.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0025_auto_20190702_1620'), - ('topics', '0021_auto_20190702_1402'), + ("topics", "0025_auto_20190702_1620"), + ("topics", "0021_auto_20190702_1402"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0027_auto_20190709_0928.py b/developerportal/apps/topics/migrations/0027_auto_20190709_0928.py index 59875257f..6057a3ca1 100644 --- a/developerportal/apps/topics/migrations/0027_auto_20190709_0928.py +++ b/developerportal/apps/topics/migrations/0027_auto_20190709_0928.py @@ -5,13 +5,10 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0026_merge_20190704_1459'), - ] + dependencies = [("topics", "0026_merge_20190704_1459")] operations = [ migrations.AlterModelOptions( - name='topics', - options={'verbose_name_plural': 'Topics'}, - ), + name="topics", options={"verbose_name_plural": "Topics"} + ) ] diff --git a/developerportal/apps/topics/migrations/0027_auto_20190710_1339.py b/developerportal/apps/topics/migrations/0027_auto_20190710_1339.py index 9ebed2c94..246ba412f 100644 --- a/developerportal/apps/topics/migrations/0027_auto_20190710_1339.py +++ b/developerportal/apps/topics/migrations/0027_auto_20190710_1339.py @@ -5,14 +5,33 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0026_merge_20190704_1459'), - ] + dependencies = [("topics", "0026_merge_20190704_1459")] operations = [ migrations.AlterField( - model_name='topic', - name='color', - field=models.CharField(choices=[('pink-40', 'Pink 40%'), ('red-40', 'Red 40%'), ('orange-40', 'Orange 40%'), ('yellow-40', 'Yellow 40%'), ('green-40', 'Green 40%'), ('blue-40', 'Blue 40%'), ('violet-40', 'Violet 40%'), ('purple-40', 'Purple 40%'), ('pink-20', 'Pink 20%'), ('red-20', 'Red 20%'), ('orange-20', 'Orange 20%'), ('yellow-20', 'Yellow 20%'), ('green-20', 'Green 20%'), ('blue-20', 'Blue 20%'), ('violet-20', 'Violet 20%'), ('purple-20', 'Purple 20%')], default='blue-40', max_length=14), - ), + model_name="topic", + name="color", + field=models.CharField( + choices=[ + ("pink-40", "Pink 40%"), + ("red-40", "Red 40%"), + ("orange-40", "Orange 40%"), + ("yellow-40", "Yellow 40%"), + ("green-40", "Green 40%"), + ("blue-40", "Blue 40%"), + ("violet-40", "Violet 40%"), + ("purple-40", "Purple 40%"), + ("pink-20", "Pink 20%"), + ("red-20", "Red 20%"), + ("orange-20", "Orange 20%"), + ("yellow-20", "Yellow 20%"), + ("green-20", "Green 20%"), + ("blue-20", "Blue 20%"), + ("violet-20", "Violet 20%"), + ("purple-20", "Purple 20%"), + ], + default="blue-40", + max_length=14, + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0028_merge_20190710_1633.py b/developerportal/apps/topics/migrations/0028_merge_20190710_1633.py index 8f5014593..cd9bf93c8 100644 --- a/developerportal/apps/topics/migrations/0028_merge_20190710_1633.py +++ b/developerportal/apps/topics/migrations/0028_merge_20190710_1633.py @@ -6,9 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('topics', '0027_auto_20190710_1339'), - ('topics', '0027_auto_20190709_0928'), + ("topics", "0027_auto_20190710_1339"), + ("topics", "0027_auto_20190709_0928"), ] - operations = [ - ] + operations = [] diff --git a/developerportal/apps/topics/migrations/0029_auto_20190711_1917.py b/developerportal/apps/topics/migrations/0029_auto_20190711_1917.py index e813938f8..c1634f3dd 100644 --- a/developerportal/apps/topics/migrations/0029_auto_20190711_1917.py +++ b/developerportal/apps/topics/migrations/0029_auto_20190711_1917.py @@ -9,46 +9,81 @@ class Migration(migrations.Migration): dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('mozimages', '0001_initial'), - ('topics', '0028_merge_20190710_1633'), + ("taggit", "0002_auto_20150616_2121"), + ("mozimages", "0001_initial"), + ("topics", "0028_merge_20190710_1633"), ] operations = [ migrations.RenameField( - model_name='topic', - old_name='intro', - new_name='description', + model_name="topic", old_name="intro", new_name="description" ), migrations.AddField( - model_name='topic', - name='card_description', - field=models.TextField(blank=True, default='', max_length=140, verbose_name='Description'), + model_name="topic", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=140, verbose_name="Description" + ), ), migrations.AddField( - model_name='topic', - name='card_image', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage', verbose_name='Image'), + model_name="topic", + name="card_image", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + verbose_name="Image", + ), ), migrations.AddField( - model_name='topic', - name='card_title', - field=models.CharField(blank=True, default='', max_length=140, verbose_name='Title'), + model_name="topic", + name="card_title", + field=models.CharField( + blank=True, default="", max_length=140, verbose_name="Title" + ), ), migrations.CreateModel( - name='TopicTag', + name="TopicTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='topics.Topic')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics_topictag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="topics.Topic", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics_topictag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='topic', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='topics.TopicTag', to='taggit.Tag', verbose_name='Tags'), + model_name="topic", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="topics.TopicTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/topics/migrations/0030_auto_20190711_1951.py b/developerportal/apps/topics/migrations/0030_auto_20190711_1951.py index 6c61026f0..3478652ce 100644 --- a/developerportal/apps/topics/migrations/0030_auto_20190711_1951.py +++ b/developerportal/apps/topics/migrations/0030_auto_20190711_1951.py @@ -8,14 +8,37 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0029_auto_20190711_1917'), - ] + dependencies = [("topics", "0029_auto_20190711_1917")] operations = [ migrations.AlterField( - model_name='topic', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, null=True), - ), + model_name="topic", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + null=True, + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0031_auto_20190718_1424.py b/developerportal/apps/topics/migrations/0031_auto_20190718_1424.py index 6ee1be1e4..386869877 100644 --- a/developerportal/apps/topics/migrations/0031_auto_20190718_1424.py +++ b/developerportal/apps/topics/migrations/0031_auto_20190718_1424.py @@ -12,57 +12,126 @@ class Migration(migrations.Migration): dependencies = [ - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), - ('wagtailforms', '0003_capitalizeverbose'), - ('wagtailredirects', '0006_redirect_increase_max_length'), - ('taggit', '0002_auto_20150616_2121'), - ('topics', '0030_auto_20190711_1951'), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), + ("wagtailforms", "0003_capitalizeverbose"), + ("wagtailredirects", "0006_redirect_increase_max_length"), + ("taggit", "0002_auto_20150616_2121"), + ("topics", "0030_auto_20190711_1951"), ] operations = [ migrations.CreateModel( - name='ParentTopic', + name="ParentTopic", 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)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='TopicsTag', + name="TopicsTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='topics.Topics')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics_topicstag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="topics.Topics", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics_topicstag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AlterField( - model_name='topic', - name='get_started', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(help_text='External URL to link to instead of a page.', required=False))]))], blank=True, null=True), - ), - migrations.DeleteModel( - name='SubTopic', + model_name="topic", + name="get_started", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock( + help_text="External URL to link to instead of a page.", + required=False, + ), + ), + ] + ), + ) + ], + blank=True, + null=True, + ), ), + migrations.DeleteModel(name="SubTopic"), migrations.AddField( - model_name='parenttopic', - name='child', - field=modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='parent_topics', to='topics.Topic'), + model_name="parenttopic", + name="child", + field=modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="parent_topics", + to="topics.Topic", + ), ), migrations.AddField( - model_name='parenttopic', - name='parent', - field=modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='child_topics', to='topics.Topic'), + model_name="parenttopic", + name="parent", + field=modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="child_topics", + to="topics.Topic", + ), ), migrations.AddField( - model_name='topics', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='topics.TopicsTag', to='taggit.Tag', verbose_name='Tags'), + model_name="topics", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="topics.TopicsTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/topics/migrations/0033_auto_20190718_1452.py b/developerportal/apps/topics/migrations/0033_auto_20190718_1452.py index 1a518456c..ec6f3ca31 100644 --- a/developerportal/apps/topics/migrations/0033_auto_20190718_1452.py +++ b/developerportal/apps/topics/migrations/0033_auto_20190718_1452.py @@ -6,14 +6,16 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0031_auto_20190718_1424'), - ] + dependencies = [("topics", "0031_auto_20190718_1424")] operations = [ migrations.AlterField( - model_name='topicfeaturedarticle', - name='article', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.Page'), - ), + model_name="topicfeaturedarticle", + name="article", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.Page", + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0034_auto_20190718_1504.py b/developerportal/apps/topics/migrations/0034_auto_20190718_1504.py index 2b26149b6..7e52c302c 100644 --- a/developerportal/apps/topics/migrations/0034_auto_20190718_1504.py +++ b/developerportal/apps/topics/migrations/0034_auto_20190718_1504.py @@ -8,17 +8,42 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0033_auto_20190718_1452'), - ] + dependencies = [("topics", "0033_auto_20190718_1452")] operations = [ migrations.AlterField( - model_name='topic', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article', 'externalcontent.ExternalArticle'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, null=True), - ), - migrations.DeleteModel( - name='TopicFeaturedArticle', + model_name="topic", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=[ + "articles.Article", + "externalcontent.ExternalArticle", + ], + required=False, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + null=True, + ), ), + migrations.DeleteModel(name="TopicFeaturedArticle"), ] diff --git a/developerportal/apps/topics/migrations/0035_auto_20190725_1225.py b/developerportal/apps/topics/migrations/0035_auto_20190725_1225.py index a9de9f193..2b11ca242 100644 --- a/developerportal/apps/topics/migrations/0035_auto_20190725_1225.py +++ b/developerportal/apps/topics/migrations/0035_auto_20190725_1225.py @@ -11,27 +11,74 @@ class Migration(migrations.Migration): dependencies = [ - ('articles', '0025_auto_20190716_1346'), - ('topics', '0034_auto_20190718_1504'), + ("articles", "0025_auto_20190716_1346"), + ("topics", "0034_auto_20190718_1504"), ] operations = [ migrations.AlterField( - model_name='topic', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, null=True), + model_name="topic", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=["articles.Article"], required=False + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + null=True, + ), ), migrations.CreateModel( - name='TopicFeaturedArticle', + name="TopicFeaturedArticle", 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)), - ('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='articles.Article')), - ('topic', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='featured_articles', to='topics.Topic')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "article", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="articles.Article", + ), + ), + ( + "topic", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="featured_articles", + to="topics.Topic", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), ] diff --git a/developerportal/apps/topics/migrations/0036_auto_20190725_1226.py b/developerportal/apps/topics/migrations/0036_auto_20190725_1226.py index 1c8395a4c..de706c0db 100644 --- a/developerportal/apps/topics/migrations/0036_auto_20190725_1226.py +++ b/developerportal/apps/topics/migrations/0036_auto_20190725_1226.py @@ -8,17 +8,42 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0035_auto_20190725_1225'), - ] + dependencies = [("topics", "0035_auto_20190725_1225")] operations = [ migrations.AlterField( - model_name='topic', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article', 'externalcontent.ExternalArticle'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, null=True), - ), - migrations.DeleteModel( - name='TopicFeaturedArticle', + model_name="topic", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=[ + "articles.Article", + "externalcontent.ExternalArticle", + ], + required=False, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + null=True, + ), ), + migrations.DeleteModel(name="TopicFeaturedArticle"), ] diff --git a/developerportal/apps/topics/migrations/0037_auto_20190730_1057.py b/developerportal/apps/topics/migrations/0037_auto_20190730_1057.py index 492bb3fa4..2845f5562 100644 --- a/developerportal/apps/topics/migrations/0037_auto_20190730_1057.py +++ b/developerportal/apps/topics/migrations/0037_auto_20190730_1057.py @@ -8,23 +8,48 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0036_auto_20190725_1226'), - ] + dependencies = [("topics", "0036_auto_20190725_1226")] operations = [ - migrations.RemoveField( - model_name='topic', - name='get_started', - ), + migrations.RemoveField(model_name="topic", name="get_started"), migrations.AddField( - model_name='topic', - name='tabbed_panels', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(help_text='External URL to link to instead of a page.', required=False))]))], blank=True, null=True, verbose_name='Tabbed panels'), + model_name="topic", + name="tabbed_panels", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock( + help_text="External URL to link to instead of a page.", + required=False, + ), + ), + ] + ), + ) + ], + blank=True, + null=True, + verbose_name="Tabbed panels", + ), ), migrations.AddField( - model_name='topic', - name='tabbed_panels_title', - field=models.CharField(blank=True, default='', max_length=250), + model_name="topic", + name="tabbed_panels_title", + field=models.CharField(blank=True, default="", max_length=250), ), ] diff --git a/developerportal/apps/topics/migrations/0038_topic_latest_articles_count.py b/developerportal/apps/topics/migrations/0038_topic_latest_articles_count.py index f1bfd971c..cb4ab33e5 100644 --- a/developerportal/apps/topics/migrations/0038_topic_latest_articles_count.py +++ b/developerportal/apps/topics/migrations/0038_topic_latest_articles_count.py @@ -5,14 +5,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0037_auto_20190730_1057'), - ] + dependencies = [("topics", "0037_auto_20190730_1057")] operations = [ migrations.AddField( - model_name='topic', - name='latest_articles_count', - field=models.IntegerField(choices=[(3, '3'), (6, '6'), (9, '9')], default=3), - ), + model_name="topic", + name="latest_articles_count", + field=models.IntegerField( + choices=[(3, "3"), (6, "6"), (9, "9")], default=3 + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0039_auto_20190805_0806.py b/developerportal/apps/topics/migrations/0039_auto_20190805_0806.py index 78763fc03..131d0e256 100644 --- a/developerportal/apps/topics/migrations/0039_auto_20190805_0806.py +++ b/developerportal/apps/topics/migrations/0039_auto_20190805_0806.py @@ -5,14 +5,16 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0038_topic_latest_articles_count'), - ] + dependencies = [("topics", "0038_topic_latest_articles_count")] operations = [ migrations.AlterField( - model_name='topic', - name='latest_articles_count', - field=models.IntegerField(choices=[(3, '3'), (6, '6'), (9, '9')], default=3, help_text='The number of articles to display for this topic.'), - ), + model_name="topic", + name="latest_articles_count", + field=models.IntegerField( + choices=[(3, "3"), (6, "6"), (9, "9")], + default=3, + help_text="The number of articles to display for this topic.", + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0040_auto_20190813_1302.py b/developerportal/apps/topics/migrations/0040_auto_20190813_1302.py index ab69a2088..c7d15fd7b 100644 --- a/developerportal/apps/topics/migrations/0040_auto_20190813_1302.py +++ b/developerportal/apps/topics/migrations/0040_auto_20190813_1302.py @@ -5,19 +5,19 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0039_auto_20190805_0806'), - ] + dependencies = [("topics", "0039_auto_20190805_0806")] operations = [ migrations.AlterField( - model_name='topic', - name='card_description', - field=models.TextField(blank=True, default='', max_length=400, verbose_name='Description'), + model_name="topic", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=400, verbose_name="Description" + ), ), migrations.AlterField( - model_name='topic', - name='description', - field=models.TextField(blank=True, default='', max_length=400), + model_name="topic", + name="description", + field=models.TextField(blank=True, default="", max_length=400), ), ] diff --git a/developerportal/apps/topics/migrations/0041_auto_20190813_1503.py b/developerportal/apps/topics/migrations/0041_auto_20190813_1503.py index 5b1958c9e..879fcfc5b 100644 --- a/developerportal/apps/topics/migrations/0041_auto_20190813_1503.py +++ b/developerportal/apps/topics/migrations/0041_auto_20190813_1503.py @@ -8,24 +8,88 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0040_auto_20190813_1302'), - ] + dependencies = [("topics", "0040_auto_20190813_1302")] operations = [ migrations.AlterField( - model_name='topic', - name='description', - field=models.TextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="topic", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), migrations.AlterField( - model_name='topic', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article', 'externalcontent.ExternalArticle'], required=False)), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, help_text='Optional space for featured articles, max. 4', null=True), + model_name="topic", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=[ + "articles.Article", + "externalcontent.ExternalArticle", + ], + required=False, + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + help_text="Optional space for featured articles, max. 4", + null=True, + ), ), migrations.AlterField( - model_name='topic', - name='tabbed_panels', - field=wagtail.core.fields.StreamField([('panel', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock()), ('image', wagtail.images.blocks.ImageChooserBlock()), ('description', wagtail.core.blocks.TextBlock()), ('button_text', wagtail.core.blocks.CharBlock()), ('page_link', wagtail.core.blocks.PageChooserBlock(required=False)), ('external_link', wagtail.core.blocks.URLBlock(help_text='External URL to link to instead of a page.', required=False))]))], blank=True, help_text='Optional tabbed panels for linking out to other resources, max. 3', null=True, verbose_name='Tabbed panels'), + model_name="topic", + name="tabbed_panels", + field=wagtail.core.fields.StreamField( + [ + ( + "panel", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("description", wagtail.core.blocks.TextBlock()), + ("button_text", wagtail.core.blocks.CharBlock()), + ( + "page_link", + wagtail.core.blocks.PageChooserBlock( + required=False + ), + ), + ( + "external_link", + wagtail.core.blocks.URLBlock( + help_text="External URL to link to instead of a page.", + required=False, + ), + ), + ] + ), + ) + ], + blank=True, + help_text="Optional tabbed panels for linking out to other resources, max. 3", + null=True, + verbose_name="Tabbed panels", + ), ), ] diff --git a/developerportal/apps/topics/migrations/0042_auto_20190814_1600.py b/developerportal/apps/topics/migrations/0042_auto_20190814_1600.py index d61ef7d07..cfac3b7e0 100644 --- a/developerportal/apps/topics/migrations/0042_auto_20190814_1600.py +++ b/developerportal/apps/topics/migrations/0042_auto_20190814_1600.py @@ -8,14 +8,41 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0041_auto_20190813_1503'), - ] + dependencies = [("topics", "0041_auto_20190813_1503")] operations = [ migrations.AlterField( - model_name='topic', - name='featured', - field=wagtail.core.fields.StreamField([('article', wagtail.core.blocks.PageChooserBlock(page_type=['articles.Article', 'externalcontent.ExternalArticle'])), ('external_page', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('title', wagtail.core.blocks.CharBlock()), ('description', wagtail.core.blocks.TextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock())]))], blank=True, help_text='Optional space for featured articles, max. 4', null=True), - ), + model_name="topic", + name="featured", + field=wagtail.core.fields.StreamField( + [ + ( + "article", + wagtail.core.blocks.PageChooserBlock( + page_type=[ + "articles.Article", + "externalcontent.ExternalArticle", + ] + ), + ), + ( + "external_page", + wagtail.core.blocks.StructBlock( + [ + ("url", wagtail.core.blocks.URLBlock()), + ("title", wagtail.core.blocks.CharBlock()), + ( + "description", + wagtail.core.blocks.TextBlock(required=False), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ], + blank=True, + help_text="Optional space for featured articles, max. 4", + null=True, + ), + ) ] diff --git a/developerportal/apps/topics/migrations/0043_auto_20190819_1304.py b/developerportal/apps/topics/migrations/0043_auto_20190819_1304.py index 03a66d707..548a6abc9 100644 --- a/developerportal/apps/topics/migrations/0043_auto_20190819_1304.py +++ b/developerportal/apps/topics/migrations/0043_auto_20190819_1304.py @@ -6,14 +6,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('topics', '0042_auto_20190814_1600'), - ] + dependencies = [("topics", "0042_auto_20190814_1600")] operations = [ migrations.AlterField( - model_name='topic', - name='description', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), - ), + model_name="topic", + name="description", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), + ) ] diff --git a/developerportal/apps/topics/models.py b/developerportal/apps/topics/models.py index 8ae1df120..e7f095cc9 100644 --- a/developerportal/apps/topics/models.py +++ b/developerportal/apps/topics/models.py @@ -30,151 +30,177 @@ from taggit.models import TaggedItemBase from ..common.blocks import FeaturedExternalBlock, TabbedPanelBlock -from ..common.constants import COLOR_CHOICES, COLOR_VALUES, RESOURCE_COUNT_CHOICES, RICH_TEXT_FEATURES_SIMPLE -from ..common.utils import get_combined_articles, get_combined_events, get_combined_videos +from ..common.constants import ( + COLOR_CHOICES, + COLOR_VALUES, + RESOURCE_COUNT_CHOICES, + RICH_TEXT_FEATURES_SIMPLE, +) +from ..common.utils import ( + get_combined_articles, + get_combined_events, + get_combined_videos, +) class TopicsTag(TaggedItemBase): - content_object = ParentalKey('Topics', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Topics", on_delete=CASCADE, related_name="tagged_items" + ) class TopicTag(TaggedItemBase): - content_object = ParentalKey('Topic', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Topic", on_delete=CASCADE, related_name="tagged_items" + ) class TopicPerson(Orderable): - topic = ParentalKey('Topic', related_name='people') - person = ForeignKey('people.Person', on_delete=CASCADE, related_name='+') + topic = ParentalKey("Topic", related_name="people") + person = ForeignKey("people.Person", on_delete=CASCADE, related_name="+") - panels = [ - PageChooserPanel('person'), - ] + panels = [PageChooserPanel("person")] class ParentTopic(Orderable): - child = ParentalKey('Topic', related_name='parent_topics') - parent = ParentalKey('Topic', on_delete=CASCADE, related_name='child_topics') + child = ParentalKey("Topic", related_name="parent_topics") + parent = ParentalKey("Topic", on_delete=CASCADE, related_name="child_topics") - panels = [ - PageChooserPanel('child'), - PageChooserPanel('parent'), - ] + panels = [PageChooserPanel("child"), PageChooserPanel("parent")] class Topic(Page): - resource_type = 'topic' - parent_page_types = ['Topics'] - subpage_types = ['Topic'] - template = 'topic.html' + resource_type = "topic" + parent_page_types = ["Topics"] + subpage_types = ["Topic"] + template = "topic.html" # Content fields description = RichTextField( blank=True, - default='', + default="", features=RICH_TEXT_FEATURES_SIMPLE, - help_text='Optional short text description, max. 400 characters', + help_text="Optional short text description, max. 400 characters", max_length=400, ) featured = StreamField( - StreamBlock([ - ('article', PageChooserBlock(target_model=( - 'articles.Article', - 'externalcontent.ExternalArticle', - ))), - ('external_page', FeaturedExternalBlock()), - ], max_num=4, required=False), + StreamBlock( + [ + ( + "article", + PageChooserBlock( + target_model=( + "articles.Article", + "externalcontent.ExternalArticle", + ) + ), + ), + ("external_page", FeaturedExternalBlock()), + ], + max_num=4, + required=False, + ), null=True, blank=True, - help_text='Optional space for featured articles, max. 4', + help_text="Optional space for featured articles, max. 4", ) - tabbed_panels_title = CharField(max_length=250, blank=True, default='') + tabbed_panels_title = CharField(max_length=250, blank=True, default="") tabbed_panels = StreamField( - StreamBlock([ - ('panel', TabbedPanelBlock()) - ], max_num=3, required=False), + StreamBlock([("panel", TabbedPanelBlock())], max_num=3, required=False), null=True, blank=True, - help_text='Optional tabbed panels for linking out to other resources, max. 3', - verbose_name='Tabbed panels', + help_text="Optional tabbed panels for linking out to other resources, max. 3", + verbose_name="Tabbed panels", ) latest_articles_count = IntegerField( choices=RESOURCE_COUNT_CHOICES, default=3, - help_text='The number of articles to display for this topic.', + help_text="The number of articles to display for this topic.", ) # Card fields - card_title = CharField('Title', max_length=140, blank=True, default='') - card_description = TextField('Description', max_length=400, blank=True, default='') + card_title = CharField("Title", max_length=140, blank=True, default="") + card_description = TextField("Description", max_length=400, blank=True, default="") card_image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', - verbose_name='Image', + related_name="+", + verbose_name="Image", ) # Meta - icon = FileField(upload_to='topics/icons', blank=True, default='') - color = CharField(max_length=14, choices=COLOR_CHOICES, default='blue-40') + icon = FileField(upload_to="topics/icons", blank=True, default="") + color = CharField(max_length=14, choices=COLOR_CHOICES, default="blue-40") keywords = ClusterTaggableManager(through=TopicTag, blank=True) # Content panels content_panels = Page.content_panels + [ - FieldPanel('description'), - StreamFieldPanel('featured'), - FieldPanel('tabbed_panels_title'), - StreamFieldPanel('tabbed_panels'), - FieldPanel('latest_articles_count'), - MultiFieldPanel([ - InlinePanel('people'), - ], heading='People', help_text='Optional list of people associated with this topic as experts'), + FieldPanel("description"), + StreamFieldPanel("featured"), + FieldPanel("tabbed_panels_title"), + StreamFieldPanel("tabbed_panels"), + FieldPanel("latest_articles_count"), + MultiFieldPanel( + [InlinePanel("people")], + heading="People", + help_text="Optional list of people associated with this topic as experts", + ), ] # Card panels card_panels = [ - FieldPanel('card_title'), - FieldPanel('card_description'), - ImageChooserPanel('card_image'), + FieldPanel("card_title"), + FieldPanel("card_description"), + ImageChooserPanel("card_image"), ] # Meta panels meta_panels = [ - MultiFieldPanel([ - InlinePanel('parent_topics', label='Parent topic(s)'), - InlinePanel('child_topics', label='Child topic(s)'), - ], heading='Parent/child topic(s)', classname='collapsible collapsed', help_text=( - 'Topics with no parent (i.e. top-level topics) will be listed on the home page. Child topics are listed ' - 'on the parent topic’s page.' - )), - MultiFieldPanel([ - FieldPanel('icon'), - FieldPanel('color'), - ], heading='Theme', help_text=( - 'Theme settings used on topic page and any tagged content. For example, an article tagged with this topic ' - 'will use the color specified here as its accent color.' - )), - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel( + [ + InlinePanel("parent_topics", label="Parent topic(s)"), + InlinePanel("child_topics", label="Child topic(s)"), + ], + heading="Parent/child topic(s)", + classname="collapsible collapsed", + help_text=( + "Topics with no parent (i.e. top-level topics) will be listed on the home page. Child topics are listed " + "on the parent topic’s page." + ), + ), + MultiFieldPanel( + [FieldPanel("icon"), FieldPanel("color")], + heading="Theme", + help_text=( + "Theme settings used on topic page and any tagged content. For example, an article tagged with this topic " + "will use the color specified here as its accent color." + ), + ), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ), ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - FieldPanel('show_in_menus'), - ] + settings_panels = [FieldPanel("slug"), FieldPanel("show_in_menus")] # Tabs - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) @property def articles(self): @@ -184,7 +210,9 @@ def articles(self): def events(self): """Return upcoming events for this topic, ignoring events in the past, ordered by start date""" - return get_combined_events(self, topics__topic__pk=self.pk, start_date__gte=datetime.datetime.now()) + return get_combined_events( + self, topics__topic__pk=self.pk, start_date__gte=datetime.datetime.now() + ) @property def videos(self): @@ -201,36 +229,39 @@ def subtopics(self): class Topics(Page): - parent_page_types = ['home.HomePage'] - subpage_types = ['Topic'] - template = 'topics.html' + parent_page_types = ["home.HomePage"] + subpage_types = ["Topic"] + template = "topics.html" # Meta fields keywords = ClusterTaggableManager(through=TopicsTag, blank=True) # Meta panels meta_panels = [ - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ) ] # Settings panels - settings_panels = [ - FieldPanel('slug'), - FieldPanel('show_in_menus'), - ] - - edit_handler = TabbedInterface([ - ObjectList(Page.content_panels, heading='Content'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + settings_panels = [FieldPanel("slug"), FieldPanel("show_in_menus")] + + edit_handler = TabbedInterface( + [ + ObjectList(Page.content_panels, heading="Content"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) class Meta: - verbose_name_plural = 'Topics' + verbose_name_plural = "Topics" @classmethod def can_create_at(cls, parent): @@ -239,4 +270,4 @@ def can_create_at(cls, parent): @property def topics(self): - return Topic.objects.live().public().order_by('title') + return Topic.objects.live().public().order_by("title") diff --git a/developerportal/apps/topics/tests/test_topics.py b/developerportal/apps/topics/tests/test_topics.py index aa3eea5d8..5a9d5cd74 100644 --- a/developerportal/apps/topics/tests/test_topics.py +++ b/developerportal/apps/topics/tests/test_topics.py @@ -7,12 +7,12 @@ class TopicTests(WagtailPageTests): """Tests for the Topic page model.""" - fixtures = ['common.json'] + fixtures = ["common.json"] def test_topic_page(self): """Get the ‘CSS’ topic.""" topic_page = Topic.objects.all()[0] - self.assertEqual('CSS', topic_page.title) + self.assertEqual("CSS", topic_page.title) def test_topic_page_parent_pages(self): """A topic page should only exist under the topics page.""" @@ -26,13 +26,16 @@ def test_topic_page_articles(self): """A topic page should have article pages.""" topic_page = Topic.objects.all()[0] topic_page_article = topic_page.articles[0].article - self.assertEqual('Faster smarter JavaScript debugging in Firefox DevTools', topic_page_article.title) + self.assertEqual( + "Faster smarter JavaScript debugging in Firefox DevTools", + topic_page_article.title, + ) class TopicsTests(WagtailPageTests): """Tests for the Topics page model.""" - fixtures = ['common.json'] + fixtures = ["common.json"] def test_topics__page_parent_pages(self): """The Topics page can exist under another page.""" diff --git a/developerportal/apps/topics/wagtail_hooks.py b/developerportal/apps/topics/wagtail_hooks.py index 070551f57..3e82b60a4 100644 --- a/developerportal/apps/topics/wagtail_hooks.py +++ b/developerportal/apps/topics/wagtail_hooks.py @@ -6,7 +6,7 @@ class TopicsAdmin(ModelAdmin): model = Topics - menu_icon = 'tag' + menu_icon = "tag" menu_order = 200 url_helper_class = ExplorerRedirectAdminURLHelper diff --git a/developerportal/apps/videos/migrations/0001_initial.py b/developerportal/apps/videos/migrations/0001_initial.py index 39f759d04..f0f0a8cda 100644 --- a/developerportal/apps/videos/migrations/0001_initial.py +++ b/developerportal/apps/videos/migrations/0001_initial.py @@ -15,87 +15,258 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('taggit', '0002_auto_20150616_2121'), - ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), - ('mozimages', '0001_initial'), + ("taggit", "0002_auto_20150616_2121"), + ("wagtailcore", "0041_group_collection_permissions_verbose_name_plural"), + ("mozimages", "0001_initial"), ] operations = [ migrations.CreateModel( - name='Video', + name="Video", 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')), - ('body', wagtail.core.fields.RichTextField(blank=True, default='')), - ('description', models.CharField(blank=True, default='', max_length=250)), - ('types', models.CharField(choices=[('conference', 'Conference'), ('tutorial', 'Tutorial'), ('webinar', 'Webinar'), ('presentation', 'Presentation'), ('talk', 'Talk'), ('demo', 'Demo'), ('vlog', 'Vlog'), ('live stream', 'Live stream'), ('technical briefing', 'Technical briefing')], default='conference', max_length=14)), - ('duration', models.CharField(blank=True, max_length=30, null=True)), - ('transcript', wagtail.core.fields.RichTextField(blank=True, default='')), - ('video_url', wagtail.core.fields.StreamField([('embed', wagtail.embeds.blocks.EmbedBlock())], blank=True, null=True)), - ('speakers', wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False))], blank=True, null=True)), - ('card_title', models.CharField(blank=True, default='', max_length=140, verbose_name='Title')), - ('card_description', models.TextField(blank=True, default='', max_length=140, verbose_name='Description')), - ('date', models.DateField(default=datetime.date.today, verbose_name='Upload date')), - ('card_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage', verbose_name='Image')), - ('image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='mozimages.MozImage')), + ( + "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", + ), + ), + ("body", wagtail.core.fields.RichTextField(blank=True, default="")), + ( + "description", + models.CharField(blank=True, default="", max_length=250), + ), + ( + "types", + models.CharField( + choices=[ + ("conference", "Conference"), + ("tutorial", "Tutorial"), + ("webinar", "Webinar"), + ("presentation", "Presentation"), + ("talk", "Talk"), + ("demo", "Demo"), + ("vlog", "Vlog"), + ("live stream", "Live stream"), + ("technical briefing", "Technical briefing"), + ], + default="conference", + max_length=14, + ), + ), + ("duration", models.CharField(blank=True, max_length=30, null=True)), + ( + "transcript", + wagtail.core.fields.RichTextField(blank=True, default=""), + ), + ( + "video_url", + wagtail.core.fields.StreamField( + [("embed", wagtail.embeds.blocks.EmbedBlock())], + blank=True, + null=True, + ), + ), + ( + "speakers", + wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ) + ], + blank=True, + null=True, + ), + ), + ( + "card_title", + models.CharField( + blank=True, default="", max_length=140, verbose_name="Title" + ), + ), + ( + "card_description", + models.TextField( + blank=True, + default="", + max_length=140, + verbose_name="Description", + ), + ), + ( + "date", + models.DateField( + default=datetime.date.today, verbose_name="Upload date" + ), + ), + ( + "card_image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + verbose_name="Image", + ), + ), + ( + "image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="mozimages.MozImage", + ), + ), ], - options={ - 'abstract': False, - }, - bases=('wagtailcore.page',), + options={"abstract": False}, + bases=("wagtailcore.page",), ), migrations.CreateModel( - name='Videos', + name="Videos", 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')), + ( + "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", + ), + ) ], - options={ - 'verbose_name_plural': 'Videos', - }, - bases=('wagtailcore.page',), + options={"verbose_name_plural": "Videos"}, + bases=("wagtailcore.page",), ), migrations.CreateModel( - name='VideoTopic', + name="VideoTopic", 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)), - ('topic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='topics.Topic')), - ('video', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='topics', to='videos.Video')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "sort_order", + models.IntegerField(blank=True, editable=False, null=True), + ), + ( + "topic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="topics.Topic", + ), + ), + ( + "video", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="topics", + to="videos.Video", + ), + ), ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, + options={"ordering": ["sort_order"], "abstract": False}, ), migrations.CreateModel( - name='VideoTag', + name="VideoTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='videos.Video')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='videos_videotag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="videos.Video", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="videos_videotag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='VideosTag', + name="VideosTag", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('content_object', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='videos.Videos')), - ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='videos_videostag_items', to='taggit.Tag')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="videos.Videos", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="videos_videostag_items", + to="taggit.Tag", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='videos', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='videos.VideosTag', to='taggit.Tag', verbose_name='Tags'), + model_name="videos", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="videos.VideosTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), migrations.AddField( - model_name='video', - name='keywords', - field=modelcluster.contrib.taggit.ClusterTaggableManager(blank=True, help_text='A comma-separated list of tags.', through='videos.VideoTag', to='taggit.Tag', verbose_name='Tags'), + model_name="video", + name="keywords", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="videos.VideoTag", + to="taggit.Tag", + verbose_name="Tags", + ), ), ] diff --git a/developerportal/apps/videos/migrations/0002_video_related_links_mdn.py b/developerportal/apps/videos/migrations/0002_video_related_links_mdn.py index 2dd60cb4a..2e647d27d 100644 --- a/developerportal/apps/videos/migrations/0002_video_related_links_mdn.py +++ b/developerportal/apps/videos/migrations/0002_video_related_links_mdn.py @@ -7,14 +7,27 @@ class Migration(migrations.Migration): - dependencies = [ - ('videos', '0001_initial'), - ] + dependencies = [("videos", "0001_initial")] operations = [ migrations.AddField( - model_name='video', - name='related_links_mdn', - field=wagtail.core.fields.StreamField([('link', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('url', wagtail.core.blocks.URLBlock())]))], blank=True, null=True, verbose_name='Related MDN links'), - ), + model_name="video", + name="related_links_mdn", + field=wagtail.core.fields.StreamField( + [ + ( + "link", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("url", wagtail.core.blocks.URLBlock()), + ] + ), + ) + ], + blank=True, + null=True, + verbose_name="Related MDN links", + ), + ) ] diff --git a/developerportal/apps/videos/migrations/0003_auto_20190807_1244.py b/developerportal/apps/videos/migrations/0003_auto_20190807_1244.py index ad3745251..b7a73ab43 100644 --- a/developerportal/apps/videos/migrations/0003_auto_20190807_1244.py +++ b/developerportal/apps/videos/migrations/0003_auto_20190807_1244.py @@ -5,19 +5,22 @@ class Migration(migrations.Migration): - dependencies = [ - ('videos', '0002_video_related_links_mdn'), - ] + dependencies = [("videos", "0002_video_related_links_mdn")] operations = [ migrations.AlterField( - model_name='video', - name='description', - field=models.TextField(blank=True, default='', max_length=250), + model_name="video", + name="description", + field=models.TextField(blank=True, default="", max_length=250), ), migrations.AlterField( - model_name='video', - name='duration', - field=models.CharField(blank=True, help_text='Optional. Video duration in MM:SS format e.g. “12:34”. Shown as a small hint when the video is displayed as a card.', max_length=30, null=True), + model_name="video", + name="duration", + field=models.CharField( + blank=True, + help_text="Optional. Video duration in MM:SS format e.g. “12:34”. Shown as a small hint when the video is displayed as a card.", + max_length=30, + null=True, + ), ), ] diff --git a/developerportal/apps/videos/migrations/0004_auto_20190813_1302.py b/developerportal/apps/videos/migrations/0004_auto_20190813_1302.py index 511e14ef3..246678651 100644 --- a/developerportal/apps/videos/migrations/0004_auto_20190813_1302.py +++ b/developerportal/apps/videos/migrations/0004_auto_20190813_1302.py @@ -5,19 +5,19 @@ class Migration(migrations.Migration): - dependencies = [ - ('videos', '0003_auto_20190807_1244'), - ] + dependencies = [("videos", "0003_auto_20190807_1244")] operations = [ migrations.AlterField( - model_name='video', - name='card_description', - field=models.TextField(blank=True, default='', max_length=400, verbose_name='Description'), + model_name="video", + name="card_description", + field=models.TextField( + blank=True, default="", max_length=400, verbose_name="Description" + ), ), migrations.AlterField( - model_name='video', - name='description', - field=models.TextField(blank=True, default='', max_length=400), + model_name="video", + name="description", + field=models.TextField(blank=True, default="", max_length=400), ), ] diff --git a/developerportal/apps/videos/migrations/0005_auto_20190813_1503.py b/developerportal/apps/videos/migrations/0005_auto_20190813_1503.py index 0b4efb129..0643abc53 100644 --- a/developerportal/apps/videos/migrations/0005_auto_20190813_1503.py +++ b/developerportal/apps/videos/migrations/0005_auto_20190813_1503.py @@ -8,44 +8,91 @@ class Migration(migrations.Migration): - dependencies = [ - ('videos', '0004_auto_20190813_1302'), - ] + dependencies = [("videos", "0004_auto_20190813_1302")] operations = [ migrations.AlterField( - model_name='video', - name='body', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets'), + model_name="video", + name="body", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets", + ), ), migrations.AlterField( - model_name='video', - name='description', - field=models.TextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), + model_name="video", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), ), migrations.AlterField( - model_name='video', - name='duration', - field=models.CharField(blank=True, help_text='Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card', max_length=30, null=True), + model_name="video", + name="duration", + field=models.CharField( + blank=True, + help_text="Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card", + max_length=30, + null=True, + ), ), migrations.AlterField( - model_name='video', - name='related_links_mdn', - field=wagtail.core.fields.StreamField([('link', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.CharBlock(label='Name')), ('url', wagtail.core.blocks.URLBlock())]))], blank=True, help_text='Optional links to MDN Web Docs for further reading', null=True, verbose_name='Related MDN links'), + model_name="video", + name="related_links_mdn", + field=wagtail.core.fields.StreamField( + [ + ( + "link", + wagtail.core.blocks.StructBlock( + [ + ("title", wagtail.core.blocks.CharBlock(label="Name")), + ("url", wagtail.core.blocks.URLBlock()), + ] + ), + ) + ], + blank=True, + help_text="Optional links to MDN Web Docs for further reading", + null=True, + verbose_name="Related MDN links", + ), ), migrations.AlterField( - model_name='video', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person'], required=False))], blank=True, help_text='Optional list of people associated with or starring in the video', null=True), + model_name="video", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"], required=False + ), + ) + ], + blank=True, + help_text="Optional list of people associated with or starring in the video", + null=True, + ), ), migrations.AlterField( - model_name='video', - name='transcript', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional text transcript of the video, supports rich text'), + model_name="video", + name="transcript", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional text transcript of the video, supports rich text", + ), ), migrations.AlterField( - model_name='video', - name='video_url', - field=wagtail.core.fields.StreamField([('embed', wagtail.embeds.blocks.EmbedBlock())], help_text='Embed URL for the video e.g. https://www.youtube.com/watch?v=kmk43_2dtn0'), + model_name="video", + name="video_url", + field=wagtail.core.fields.StreamField( + [("embed", wagtail.embeds.blocks.EmbedBlock())], + help_text="Embed URL for the video e.g. https://www.youtube.com/watch?v=kmk43_2dtn0", + ), ), ] diff --git a/developerportal/apps/videos/migrations/0006_auto_20190814_1600.py b/developerportal/apps/videos/migrations/0006_auto_20190814_1600.py index 9fc0e9b62..5d1c8cb70 100644 --- a/developerportal/apps/videos/migrations/0006_auto_20190814_1600.py +++ b/developerportal/apps/videos/migrations/0006_auto_20190814_1600.py @@ -7,14 +7,24 @@ class Migration(migrations.Migration): - dependencies = [ - ('videos', '0005_auto_20190813_1503'), - ] + dependencies = [("videos", "0005_auto_20190813_1503")] operations = [ migrations.AlterField( - model_name='video', - name='speakers', - field=wagtail.core.fields.StreamField([('speaker', wagtail.core.blocks.PageChooserBlock(page_type=['people.Person']))], blank=True, help_text='Optional list of people associated with or starring in the video', null=True), - ), + model_name="video", + name="speakers", + field=wagtail.core.fields.StreamField( + [ + ( + "speaker", + wagtail.core.blocks.PageChooserBlock( + page_type=["people.Person"] + ), + ) + ], + blank=True, + help_text="Optional list of people associated with or starring in the video", + null=True, + ), + ) ] diff --git a/developerportal/apps/videos/migrations/0007_auto_20190819_1304.py b/developerportal/apps/videos/migrations/0007_auto_20190819_1304.py index 24a4a2f63..0d51c40dc 100644 --- a/developerportal/apps/videos/migrations/0007_auto_20190819_1304.py +++ b/developerportal/apps/videos/migrations/0007_auto_20190819_1304.py @@ -6,14 +6,17 @@ class Migration(migrations.Migration): - dependencies = [ - ('videos', '0006_auto_20190814_1600'), - ] + dependencies = [("videos", "0006_auto_20190814_1600")] operations = [ migrations.AlterField( - model_name='video', - name='description', - field=wagtail.core.fields.RichTextField(blank=True, default='', help_text='Optional short text description, max. 400 characters', max_length=400), - ), + model_name="video", + name="description", + field=wagtail.core.fields.RichTextField( + blank=True, + default="", + help_text="Optional short text description, max. 400 characters", + max_length=400, + ), + ) ] diff --git a/developerportal/apps/videos/models.py b/developerportal/apps/videos/models.py index 056c19bdf..74187f3f5 100644 --- a/developerportal/apps/videos/models.py +++ b/developerportal/apps/videos/models.py @@ -2,7 +2,14 @@ import datetime import readtime -from django.db.models import CASCADE, CharField, DateField, ForeignKey, SET_NULL, TextField +from django.db.models import ( + CASCADE, + CharField, + DateField, + ForeignKey, + SET_NULL, + TextField, +) from wagtail.admin.edit_handlers import ( FieldPanel, @@ -29,47 +36,50 @@ class VideosTag(TaggedItemBase): - content_object = ParentalKey('Videos', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Videos", on_delete=CASCADE, related_name="tagged_items" + ) class VideoTopic(Orderable): - video = ParentalKey('Video', related_name='topics') - topic = ForeignKey('topics.Topic', on_delete=CASCADE, related_name='+') + video = ParentalKey("Video", related_name="topics") + topic = ForeignKey("topics.Topic", on_delete=CASCADE, related_name="+") - panels = [ - PageChooserPanel('topic'), - ] + panels = [PageChooserPanel("topic")] class Videos(Page): - parent_page_types = ['home.HomePage'] - subpage_types = ['Video'] - template = 'videos.html' + parent_page_types = ["home.HomePage"] + subpage_types = ["Video"] + template = "videos.html" # Meta fields keywords = ClusterTaggableManager(through=VideosTag, blank=True) meta_panels = [ - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ) ] - settings_panels = [ - FieldPanel('slug'), - FieldPanel('show_in_menus'), - ] + settings_panels = [FieldPanel("slug"), FieldPanel("show_in_menus")] - edit_handler = TabbedInterface([ - ObjectList(Page.content_panels, heading='Content'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(Page.content_panels, heading="Content"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) class Meta: - verbose_name_plural = 'Videos' + verbose_name_plural = "Videos" @classmethod def can_create_at(cls, parent): @@ -78,137 +88,153 @@ def can_create_at(cls, parent): @property def videos(self): - return Video.objects.live().public().order_by('title') + return Video.objects.live().public().order_by("title") class VideoTag(TaggedItemBase): - content_object = ParentalKey('Video', on_delete=CASCADE, related_name='tagged_items') + content_object = ParentalKey( + "Video", on_delete=CASCADE, related_name="tagged_items" + ) class Video(Page): - resource_type = 'video' - parent_page_types = ['Videos'] + resource_type = "video" + parent_page_types = ["Videos"] subpage_types = [] - template = 'video.html' + template = "video.html" # Content fields description = RichTextField( blank=True, - default='', + default="", features=RICH_TEXT_FEATURES_SIMPLE, - help_text='Optional short text description, max. 400 characters', + help_text="Optional short text description, max. 400 characters", max_length=400, ) - body = RichTextField(blank=True, default='', features=RICH_TEXT_FEATURES, help_text=( - 'Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets' - )) + body = RichTextField( + blank=True, + default="", + features=RICH_TEXT_FEATURES, + help_text=( + "Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets" + ), + ) related_links_mdn = StreamField( - StreamBlock([ - ('link', ExternalLinkBlock()) - ], required=False), + StreamBlock([("link", ExternalLinkBlock())], required=False), null=True, blank=True, - help_text='Optional links to MDN Web Docs for further reading', - verbose_name='Related MDN links', + help_text="Optional links to MDN Web Docs for further reading", + verbose_name="Related MDN links", ) image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', + related_name="+", + ) + types = CharField(max_length=14, choices=VIDEO_TYPE, default="conference") + duration = CharField( + max_length=30, + blank=True, + null=True, + help_text=( + "Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card" + ), ) - types = CharField(max_length=14, choices=VIDEO_TYPE, default='conference') - duration = CharField(max_length=30, blank=True, null=True, help_text=( - 'Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card' - )) transcript = RichTextField( blank=True, - default='', + default="", features=RICH_TEXT_FEATURES, - help_text='Optional text transcript of the video, supports rich text', + help_text="Optional text transcript of the video, supports rich text", ) video_url = StreamField( - StreamBlock([ - ('embed', EmbedBlock()), - ], min_num=1, max_num=1, required=True), - help_text='Embed URL for the video e.g. https://www.youtube.com/watch?v=kmk43_2dtn0', + StreamBlock([("embed", EmbedBlock())], min_num=1, max_num=1, required=True), + help_text="Embed URL for the video e.g. https://www.youtube.com/watch?v=kmk43_2dtn0", ) speakers = StreamField( - StreamBlock([ - ('speaker', PageChooserBlock(target_model='people.Person')), - ], required=False), + StreamBlock( + [("speaker", PageChooserBlock(target_model="people.Person"))], + required=False, + ), blank=True, null=True, - help_text='Optional list of people associated with or starring in the video', + help_text="Optional list of people associated with or starring in the video", ) # Card fields - card_title = CharField('Title', max_length=140, blank=True, default='') - card_description = TextField('Description', max_length=400, blank=True, default='') + card_title = CharField("Title", max_length=140, blank=True, default="") + card_description = TextField("Description", max_length=400, blank=True, default="") card_image = ForeignKey( - 'mozimages.MozImage', + "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, - related_name='+', - verbose_name='Image', + related_name="+", + verbose_name="Image", ) # Meta fields - date = DateField('Upload date', default=datetime.date.today) + date = DateField("Upload date", default=datetime.date.today) keywords = ClusterTaggableManager(through=VideoTag, blank=True) # Content panels content_panels = Page.content_panels + [ - FieldPanel('description'), - ImageChooserPanel('image'), - StreamFieldPanel('video_url'), - FieldPanel('body'), - StreamFieldPanel('related_links_mdn'), - FieldPanel('transcript'), + FieldPanel("description"), + ImageChooserPanel("image"), + StreamFieldPanel("video_url"), + FieldPanel("body"), + StreamFieldPanel("related_links_mdn"), + FieldPanel("transcript"), ] # Card panels card_panels = [ - FieldPanel('card_title'), - FieldPanel('card_description'), - ImageChooserPanel('card_image'), + FieldPanel("card_title"), + FieldPanel("card_description"), + ImageChooserPanel("card_image"), ] # Meta panels meta_panels = [ - FieldPanel('date'), - StreamFieldPanel('speakers'), - MultiFieldPanel([ - InlinePanel('topics'), - ], heading='Topics', help_text=( - 'These are the topic pages the video will appear on. The first topic in the list will be treated as the ' - 'primary topic and will be shown in the page’s related content.' - )), - FieldPanel('duration'), - MultiFieldPanel([ - FieldPanel('types'), - ], heading='Type', help_text='Choose a video type to help people search for the video'), - - MultiFieldPanel([ - FieldPanel('seo_title'), - FieldPanel('search_description'), - FieldPanel('keywords'), - ], heading='SEO', help_text='Optional fields to override the default title and description for SEO purposes'), + FieldPanel("date"), + StreamFieldPanel("speakers"), + MultiFieldPanel( + [InlinePanel("topics")], + heading="Topics", + help_text=( + "These are the topic pages the video will appear on. The first topic in the list will be treated as the " + "primary topic and will be shown in the page’s related content." + ), + ), + FieldPanel("duration"), + MultiFieldPanel( + [FieldPanel("types")], + heading="Type", + help_text="Choose a video type to help people search for the video", + ), + MultiFieldPanel( + [ + FieldPanel("seo_title"), + FieldPanel("search_description"), + FieldPanel("keywords"), + ], + heading="SEO", + help_text="Optional fields to override the default title and description for SEO purposes", + ), ] - settings_panels = [ - FieldPanel('slug'), - ] + settings_panels = [FieldPanel("slug")] # Tabs - edit_handler = TabbedInterface([ - ObjectList(content_panels, heading='Content'), - ObjectList(card_panels, heading='Card'), - ObjectList(meta_panels, heading='Meta'), - ObjectList(settings_panels, heading='Settings', classname='settings'), - ]) + edit_handler = TabbedInterface( + [ + ObjectList(content_panels, heading="Content"), + ObjectList(card_panels, heading="Card"), + ObjectList(meta_panels, heading="Meta"), + ObjectList(settings_panels, heading="Settings", classname="settings"), + ] + ) @property def primary_topic(self): @@ -224,7 +250,7 @@ def read_time(self): def related_resources(self): """Returns resources that are related to the current resource, i.e. live, public articles and videos which have the same topics.""" - topic_pks = self.topics.values_list('topic') + topic_pks = self.topics.values_list("topic") return get_combined_articles_and_videos(self, topics__topic__pk__in=topic_pks) def has_speaker(self, person): diff --git a/developerportal/apps/videos/wagtail_hooks.py b/developerportal/apps/videos/wagtail_hooks.py index 62dc9e24b..9dd20c36c 100644 --- a/developerportal/apps/videos/wagtail_hooks.py +++ b/developerportal/apps/videos/wagtail_hooks.py @@ -6,7 +6,7 @@ class VideosAdmin(ModelAdmin): model = Videos - menu_icon = 'media' + menu_icon = "media" menu_order = 240 url_helper_class = ExplorerRedirectAdminURLHelper diff --git a/developerportal/context_processors.py b/developerportal/context_processors.py index 393d1ec1a..778c86521 100644 --- a/developerportal/context_processors.py +++ b/developerportal/context_processors.py @@ -2,11 +2,11 @@ def google_analytics(request): - return {'GOOGLE_ANALYTICS': GOOGLE_ANALYTICS} + return {"GOOGLE_ANALYTICS": GOOGLE_ANALYTICS} def mapbox_access_token(request): - return {'MAPBOX_ACCESS_TOKEN': MAPBOX_ACCESS_TOKEN} + return {"MAPBOX_ACCESS_TOKEN": MAPBOX_ACCESS_TOKEN} def directory_pages(request): @@ -14,11 +14,12 @@ def directory_pages(request): from .apps.events.models import Events from .apps.people.models import People from .apps.topics.models import Topics + return { - 'directory_pages': { - 'articles': Articles.objects.first(), - 'events': Events.objects.first(), - 'people': People.objects.first(), - 'topics': Topics.objects.first(), - }, + "directory_pages": { + "articles": Articles.objects.first(), + "events": Events.objects.first(), + "people": People.objects.first(), + "topics": Topics.objects.first(), + } } diff --git a/developerportal/pipeline.py b/developerportal/pipeline.py index a0be00f58..1b73fc0ed 100644 --- a/developerportal/pipeline.py +++ b/developerportal/pipeline.py @@ -9,12 +9,12 @@ class InvalidUserOrgs(AuthException): def __str__(self): - return 'User is not part of an allowed organization.' + return "User is not part of an allowed organization." -GITHUB_API_BASE = 'https://api.github.com' +GITHUB_API_BASE = "https://api.github.com" # Pass multiple orgs in env separated by comma, e.g. GITHUB_ORGS=mdn,foo,bar -GITHUB_ORGS = os.environ.get('GITHUB_ORGS', 'mdn').split(',') +GITHUB_ORGS = os.environ.get("GITHUB_ORGS", "mdn").split(",") def github_user_allowed(backend, details=None, response=None, *args, **kwargs): @@ -25,16 +25,20 @@ def github_user_allowed(backend, details=None, response=None, *args, **kwargs): http = urllib3.PoolManager() - token = response['access_token'] - username = details['username'] + token = response["access_token"] + username = details["username"] user_allowed = False for org in GITHUB_ORGS: - url = f'{GITHUB_API_BASE}/orgs/{org}/members/{username}' - response = http.request('GET', url, headers={ - 'Authorization': f'token {token}', - 'User-Agent': settings.WAGTAIL_SITE_NAME, - }) + url = f"{GITHUB_API_BASE}/orgs/{org}/members/{username}" + response = http.request( + "GET", + url, + headers={ + "Authorization": f"token {token}", + "User-Agent": settings.WAGTAIL_SITE_NAME, + }, + ) # GitHub will only return a 204 if the user is a member of the org # https://developer.github.com/v3/orgs/members/#check-membership if response.status == 204: @@ -52,7 +56,10 @@ def success_message(is_new=False, request=None, user=None, *args, **kwargs): user.is_superuser = True user.save() else: # Otherwise inform the user they need to contact an admin - messages.success(request, ( - 'Success! You have been registered. Please contact an ' - 'administrator to complete your registration.' - )) + messages.success( + request, + ( + "Success! You have been registered. Please contact an " + "administrator to complete your registration." + ), + ) diff --git a/developerportal/settings/base.py b/developerportal/settings/base.py index dc79200c0..11aefddf4 100644 --- a/developerportal/settings/base.py +++ b/developerportal/settings/base.py @@ -23,7 +23,7 @@ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', get_random_secret_key()) +SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", get_random_secret_key()) # Quick-start development settings - unsuitable for production @@ -33,111 +33,104 @@ # Application definition INSTALLED_APPS = [ - 'developerportal.apps.common', - 'developerportal.apps.articles', - 'developerportal.apps.content', - 'developerportal.apps.events', - 'developerportal.apps.externalcontent', - 'developerportal.apps.health', - 'developerportal.apps.home', - 'developerportal.apps.mozimages', - 'developerportal.apps.people', - 'developerportal.apps.staticbuild', - 'developerportal.apps.topics', - 'developerportal.apps.videos', - - 'wagtail.contrib.forms', - 'wagtail.contrib.modeladmin', - 'wagtail.contrib.routable_page', - 'wagtail.contrib.redirects', - 'wagtail.embeds', - 'wagtail.sites', - 'wagtail.users', - 'wagtail.snippets', - 'wagtail.documents', - 'wagtail.images', - 'wagtail.search', - 'wagtail.admin', - 'wagtail.core', - - 'bakery', - 'wagtailbakery', - 'modelcluster', - 'taggit', - 'social_django', - 'django_countries', - - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', + "developerportal.apps.common", + "developerportal.apps.articles", + "developerportal.apps.content", + "developerportal.apps.events", + "developerportal.apps.externalcontent", + "developerportal.apps.health", + "developerportal.apps.home", + "developerportal.apps.mozimages", + "developerportal.apps.people", + "developerportal.apps.staticbuild", + "developerportal.apps.topics", + "developerportal.apps.videos", + "wagtail.contrib.forms", + "wagtail.contrib.modeladmin", + "wagtail.contrib.routable_page", + "wagtail.contrib.redirects", + "wagtail.embeds", + "wagtail.sites", + "wagtail.users", + "wagtail.snippets", + "wagtail.documents", + "wagtail.images", + "wagtail.search", + "wagtail.admin", + "wagtail.core", + "bakery", + "wagtailbakery", + "modelcluster", + "taggit", + "social_django", + "django_countries", + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", ] MIDDLEWARE = [ - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.middleware.security.SecurityMiddleware', - - 'whitenoise.middleware.WhiteNoiseMiddleware', - 'social_django.middleware.SocialAuthExceptionMiddleware', - - 'wagtail.core.middleware.SiteMiddleware', - 'wagtail.contrib.redirects.middleware.RedirectMiddleware', + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "django.middleware.security.SecurityMiddleware", + "whitenoise.middleware.WhiteNoiseMiddleware", + "social_django.middleware.SocialAuthExceptionMiddleware", + "wagtail.core.middleware.SiteMiddleware", + "wagtail.contrib.redirects.middleware.RedirectMiddleware", ] -ROOT_URLCONF = 'developerportal.urls' +ROOT_URLCONF = "developerportal.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ - os.path.join(PROJECT_DIR, 'templates'), - ], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - 'social_django.context_processors.backends', - 'social_django.context_processors.login_redirect', - 'developerportal.context_processors.directory_pages', - 'developerportal.context_processors.google_analytics', - 'developerportal.context_processors.mapbox_access_token', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [os.path.join(PROJECT_DIR, "templates")], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + "social_django.context_processors.backends", + "social_django.context_processors.login_redirect", + "developerportal.context_processors.directory_pages", + "developerportal.context_processors.google_analytics", + "developerportal.context_processors.mapbox_access_token", ], - 'libraries': { - 'app_filters': 'developerportal.templatetags.app_filters', - 'app_tags': 'developerportal.templatetags.app_tags', - } + "libraries": { + "app_filters": "developerportal.templatetags.app_filters", + "app_tags": "developerportal.templatetags.app_tags", + }, }, - }, + } ] AUTHENTICATION_BACKENDS = ( - 'social_core.backends.github.GithubOAuth2', - 'django.contrib.auth.backends.ModelBackend', + "social_core.backends.github.GithubOAuth2", + "django.contrib.auth.backends.ModelBackend", ) -WSGI_APPLICATION = 'developerportal.wsgi.application' +WSGI_APPLICATION = "developerportal.wsgi.application" # Database # https://docs.djangoproject.com/en/2.1/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': os.environ.get('POSTGRES_DB'), - 'USER': os.environ.get('POSTGRES_USER'), - 'HOST': os.environ.get('POSTGRES_HOST'), - 'PASSWORD': os.environ.get('POSTGRES_PASSWORD'), - 'PORT': 5432, + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ.get("POSTGRES_DB"), + "USER": os.environ.get("POSTGRES_USER"), + "HOST": os.environ.get("POSTGRES_HOST"), + "PASSWORD": os.environ.get("POSTGRES_PASSWORD"), + "PORT": 5432, } } @@ -147,26 +140,20 @@ AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" }, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, + {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, ] # Internationalization # https://docs.djangoproject.com/en/2.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -179,104 +166,98 @@ # https://docs.djangoproject.com/en/2.1/howto/static-files/ STATICFILES_FINDERS = [ - 'django.contrib.staticfiles.finders.FileSystemFinder', - 'django.contrib.staticfiles.finders.AppDirectoriesFinder', + "django.contrib.staticfiles.finders.FileSystemFinder", + "django.contrib.staticfiles.finders.AppDirectoriesFinder", ] STATICFILES_DIRS = [ - ('css', os.path.join(BASE_DIR, 'dist/css')), - ('js', os.path.join(BASE_DIR, 'dist/js')), - ('fonts', os.path.join(BASE_DIR, 'src/fonts')), - ('img', os.path.join(BASE_DIR, 'src/img')), + ("css", os.path.join(BASE_DIR, "dist/css")), + ("js", os.path.join(BASE_DIR, "dist/js")), + ("fonts", os.path.join(BASE_DIR, "src/fonts")), + ("img", os.path.join(BASE_DIR, "src/img")), ] # ManifestStaticFilesStorage is recommended in production, to prevent outdated # Javascript / CSS assets being served from cache (e.g. after a Wagtail upgrade). # See https://docs.djangoproject.com/en/2.1/ref/contrib/staticfiles/#manifeststaticfilesstorage -STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' +STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" -STATIC_ROOT = os.path.join(BASE_DIR, 'static') -STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, "static") +STATIC_URL = "/static/" -MEDIA_ROOT = os.path.join(BASE_DIR, 'media') -MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, "media") +MEDIA_URL = "/media/" # Wagtail settings -WAGTAIL_SITE_NAME = 'Mozilla Developers' +WAGTAIL_SITE_NAME = "Mozilla Developers" # Add support for CodePen oEmbed WAGTAILEMBEDS_FINDERS = [ { - 'class': 'wagtail.embeds.finders.oembed', - 'providers': all_providers + [{ - 'endpoint': 'http://codepen.io/api/oembed', - 'urls': [ - '^http(?:s)?://codepen\\.io/.+/pen/.+$', - ], - }], + "class": "wagtail.embeds.finders.oembed", + "providers": all_providers + + [ + { + "endpoint": "http://codepen.io/api/oembed", + "urls": ["^http(?:s)?://codepen\\.io/.+/pen/.+$"], + } + ], } ] -WAGTAILIMAGES_IMAGE_MODEL = 'mozimages.MozImage' +WAGTAILIMAGES_IMAGE_MODEL = "mozimages.MozImage" # Base URL to use when referring to full URLs within the Wagtail admin backend - # e.g. in notification emails. Don't include '/admin' or a trailing slash -BASE_URL = os.environ.get('BASE_URL') +BASE_URL = os.environ.get("BASE_URL") # Wagtail Bakery Settings -BUILD_DIR = os.path.join(BASE_DIR, 'build') +BUILD_DIR = os.path.join(BASE_DIR, "build") BAKERY_MULTISITE = True -BAKERY_VIEWS = ( - 'wagtailbakery.views.AllPublishedPagesView', -) -AWS_REGION = os.environ.get('AWS_REGION') -AWS_BUCKET_NAME = os.environ.get('AWS_BUCKET_NAME') +BAKERY_VIEWS = ("wagtailbakery.views.AllPublishedPagesView",) +AWS_REGION = os.environ.get("AWS_REGION") +AWS_BUCKET_NAME = os.environ.get("AWS_BUCKET_NAME") # Static build management commands called in order -STATIC_BUILD_PIPELINE = ( - ('Build', 'build'), - ('Publish', 'publish'), -) +STATIC_BUILD_PIPELINE = (("Build", "build"), ("Publish", "publish")) # Amazon S3 config -S3_BUCKET = os.environ.get('S3_BUCKET') +S3_BUCKET = os.environ.get("S3_BUCKET") # Social Auth pipelines SOCIAL_AUTH_PIPELINE = ( - 'social_core.pipeline.social_auth.social_details', - 'social_core.pipeline.social_auth.social_uid', - 'social_core.pipeline.social_auth.auth_allowed', - 'social_core.pipeline.social_auth.social_user', - 'developerportal.pipeline.github_user_allowed', - 'social_core.pipeline.user.get_username', - 'social_core.pipeline.mail.mail_validation', - 'social_core.pipeline.user.create_user', - 'social_core.pipeline.social_auth.associate_user', - 'social_core.pipeline.social_auth.load_extra_data', - 'social_core.pipeline.user.user_details', - 'developerportal.pipeline.success_message', + "social_core.pipeline.social_auth.social_details", + "social_core.pipeline.social_auth.social_uid", + "social_core.pipeline.social_auth.auth_allowed", + "social_core.pipeline.social_auth.social_user", + "developerportal.pipeline.github_user_allowed", + "social_core.pipeline.user.get_username", + "social_core.pipeline.mail.mail_validation", + "social_core.pipeline.user.create_user", + "social_core.pipeline.social_auth.associate_user", + "social_core.pipeline.social_auth.load_extra_data", + "social_core.pipeline.user.user_details", + "developerportal.pipeline.success_message", ) # GitHub scope to check emails and correct domains -SOCIAL_AUTH_GITHUB_SCOPE = ['user:email'] +SOCIAL_AUTH_GITHUB_SCOPE = ["user:email"] # GitHub social auth access keys -SOCIAL_AUTH_GITHUB_KEY = os.environ.get('GITHUB_CLIENT_ID') -SOCIAL_AUTH_GITHUB_SECRET = os.environ.get('GITHUB_CLIENT_SECRET') +SOCIAL_AUTH_GITHUB_KEY = os.environ.get("GITHUB_CLIENT_ID") +SOCIAL_AUTH_GITHUB_SECRET = os.environ.get("GITHUB_CLIENT_SECRET") -LOGIN_ERROR_URL = '/admin/' -LOGIN_REDIRECT_URL = '/admin/' -SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/admin/login/' +LOGIN_ERROR_URL = "/admin/" +LOGIN_REDIRECT_URL = "/admin/" +SOCIAL_AUTH_NEW_USER_REDIRECT_URL = "/admin/login/" # GOOGLE_ANALYTICS -GOOGLE_ANALYTICS = os.environ.get('GOOGLE_ANALYTICS') +GOOGLE_ANALYTICS = os.environ.get("GOOGLE_ANALYTICS") # Mapbox -MAPBOX_ACCESS_TOKEN = os.environ.get('MAPBOX_ACCESS_TOKEN') +MAPBOX_ACCESS_TOKEN = os.environ.get("MAPBOX_ACCESS_TOKEN") -COUNTRIES_FIRST = [ - 'US', 'GB' -] +COUNTRIES_FIRST = ["US", "GB"] diff --git a/developerportal/settings/build.py b/developerportal/settings/build.py index 514a541aa..67901c1e2 100644 --- a/developerportal/settings/build.py +++ b/developerportal/settings/build.py @@ -1,4 +1,4 @@ from .production import * -STATIC_URL = '/portal' + STATIC_URL -BUILD_DIR = BUILD_DIR + '/portal' +STATIC_URL = "/portal" + STATIC_URL +BUILD_DIR = BUILD_DIR + "/portal" diff --git a/developerportal/settings/dev.py b/developerportal/settings/dev.py index 55fe70f4b..b44f7debd 100644 --- a/developerportal/settings/dev.py +++ b/developerportal/settings/dev.py @@ -4,9 +4,9 @@ DEBUG = True # SECURITY WARNING: define the correct hosts in production! -ALLOWED_HOSTS = ['*'] +ALLOWED_HOSTS = ["*"] -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" try: diff --git a/developerportal/templatetags/app_filters.py b/developerportal/templatetags/app_filters.py index 79d709d64..9c52a5874 100644 --- a/developerportal/templatetags/app_filters.py +++ b/developerportal/templatetags/app_filters.py @@ -9,30 +9,32 @@ register = template.Library() -@register.filter(name='list') +@register.filter(name="list") def make_list(item): return list(item if item else []) -@register.filter(name='hex_to_rgb') +@register.filter(name="hex_to_rgb") def hex_to_rgb(hex_color, alpha=1): """Returns the RGB value of a hexadecimal color.""" - hex_color = hex_color.replace('#', '') + hex_color = hex_color.replace("#", "") r = int(hex_color[0:2], 16) g = int(hex_color[2:4], 16) b = int(hex_color[4:6], 16) alpha = float(alpha) a = alpha if 0 < alpha < 1 else 1 - return f'rgb({r}, {g}, {b})' if a == 1 else f'rgb({r}, {g}, {b}, {a})' + return f"rgb({r}, {g}, {b})" if a == 1 else f"rgb({r}, {g}, {b}, {a})" -@register.filter(name='syntax_highlight', is_safe=True) +@register.filter(name="syntax_highlight", is_safe=True) def syntax_highlight(value, language): lexer = lexers.get_lexer_by_name(language) - output = pygments.highlight(value, lexer, formatters.HtmlFormatter(cssclass="syntax")) + output = pygments.highlight( + value, lexer, formatters.HtmlFormatter(cssclass="syntax") + ) return mark_safe(output) -@register.filter(name='times') +@register.filter(name="times") def times(number): return range(number) diff --git a/developerportal/templatetags/app_tags.py b/developerportal/templatetags/app_tags.py index eb808f94f..45c9c2f94 100644 --- a/developerportal/templatetags/app_tags.py +++ b/developerportal/templatetags/app_tags.py @@ -24,16 +24,16 @@ def mime_type(file_name): @register.simple_tag def random_hash(): - return binascii.hexlify(os.urandom(16)).decode('utf-8') + return binascii.hexlify(os.urandom(16)).decode("utf-8") @register.simple_tag def render_svg(f): - return mark_safe(f.read().decode('utf-8')) + return mark_safe(f.read().decode("utf-8")) @register.simple_tag def render_gif(block_value): - if hasattr(block_value, 'file') and hasattr(block_value.file, 'name'): + if hasattr(block_value, "file") and hasattr(block_value.file, "name"): file_url = settings.MEDIA_URL + block_value.file.name return mark_safe(f'') diff --git a/developerportal/urls.py b/developerportal/urls.py index ad95a3ded..d38a0a429 100644 --- a/developerportal/urls.py +++ b/developerportal/urls.py @@ -12,23 +12,19 @@ urlpatterns = [ - url('', include('developerportal.apps.health.urls')), - - url(r'^django-admin/', admin.site.urls), - - url(r'^admin/', include(wagtailadmin_urls)), - url(r'^documents/', include(wagtaildocs_urls)), - - url(r'^article-feed/', RssFeeds()), - - url(r'^oauth/', include('social_django.urls', namespace='social')), + url("", include("developerportal.apps.health.urls")), + url(r"^django-admin/", admin.site.urls), + url(r"^admin/", include(wagtailadmin_urls)), + url(r"^documents/", include(wagtaildocs_urls)), + url(r"^article-feed/", RssFeeds()), + url(r"^oauth/", include("social_django.urls", namespace="social")), ] if settings.DEBUG: urlpatterns += [ - url(r'^404/$', page_not_found, {'exception': Http404()}), - url(r'^500/$', server_error), + url(r"^404/$", page_not_found, {"exception": Http404()}), + url(r"^500/$", server_error), ] from django.conf.urls.static import static @@ -42,11 +38,11 @@ # Serve media files directly. urlpatterns += [ - url(r'^media/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT}), + url(r"^media/(?P.*)$", serve, {"document_root": settings.MEDIA_ROOT}) ] # For anything not caught by a more specific rule above, hand over to # Wagtail's page serving mechanism. This should be the last pattern in # the list: -urlpatterns += [url(r'', include(wagtail_urls))] +urlpatterns += [url(r"", include(wagtail_urls))] diff --git a/manage.py b/manage.py index 71f3acd81..f9c291200 100755 --- a/manage.py +++ b/manage.py @@ -10,4 +10,5 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", f"developerportal.settings.{env}") from django.core.management import execute_from_command_line + execute_from_command_line(sys.argv) From b5457372f4978e5fdec80a50e7e2be853cf7c532 Mon Sep 17 00:00:00 2001 From: Steve Jalim Date: Tue, 17 Sep 2019 11:05:04 +0100 Subject: [PATCH 2/7] 135: add isort with black-compatible config Created a separate .isort.cfg to make it explicit Tests passing fine after changes --- .isort.cfg | 13 +++++++++++++ developerportal/apps/articles/models.py | 16 ++++++++-------- .../apps/articles/tests/test_articles.py | 2 +- .../apps/articles/wagtail_hooks.py | 4 ++-- developerportal/apps/common/fields.py | 4 ++-- developerportal/apps/common/image_formats.py | 1 - developerportal/apps/content/models.py | 9 ++++----- .../apps/content/tests/test_content.py | 2 +- developerportal/apps/events/models.py | 18 +++++++++--------- .../apps/events/tests/test_events.py | 2 +- developerportal/apps/events/wagtail_hooks.py | 4 ++-- .../apps/externalcontent/models.py | 5 ++--- developerportal/apps/health/urls.py | 1 - developerportal/apps/home/models.py | 15 +++++++-------- developerportal/apps/home/tests/test_home.py | 4 ++-- developerportal/apps/mozimages/models.py | 2 +- developerportal/apps/people/models.py | 16 +++++++--------- .../apps/people/tests/test_people.py | 4 ++-- developerportal/apps/people/wagtail_hooks.py | 4 ++-- .../apps/staticbuild/wagtail_hooks.py | 3 +-- developerportal/apps/topics/models.py | 19 +++++++++---------- .../apps/topics/tests/test_topics.py | 2 +- developerportal/apps/topics/wagtail_hooks.py | 4 ++-- developerportal/apps/videos/models.py | 18 +++++++++--------- .../apps/videos/tests/test_videos.py | 2 +- developerportal/apps/videos/wagtail_hooks.py | 4 ++-- developerportal/pipeline.py | 3 ++- developerportal/settings/base.py | 1 - developerportal/templatetags/app_filters.py | 4 +--- developerportal/templatetags/app_tags.py | 4 +--- developerportal/urls.py | 1 - 31 files changed, 95 insertions(+), 96 deletions(-) create mode 100644 .isort.cfg diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 000000000..2c986940a --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,13 @@ +[settings] +known_first_party=developerportal +known_third_party=wagtail,modelcluster,six,requests,willow,pillow,taggit +known_django=django +default_section=FIRSTPARTY +skip=migrations +sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER +multi_line_output=3 +include_trailing_comma=True +force_grid_wrap=0 +use_parentheses=True +line_length=88 +skip=node_modules,migrations diff --git a/developerportal/apps/articles/models.py b/developerportal/apps/articles/models.py index de48b0fe1..d6d8309be 100644 --- a/developerportal/apps/articles/models.py +++ b/developerportal/apps/articles/models.py @@ -1,33 +1,33 @@ # pylint: disable=no-member import datetime -import readtime from django.db.models import ( CASCADE, + SET_NULL, CharField, DateField, ForeignKey, - SET_NULL, TextField, ) +from modelcluster.contrib.taggit import ClusterTaggableManager +from modelcluster.fields import ParentalKey +from taggit.models import TaggedItemBase from wagtail.admin.edit_handlers import ( FieldPanel, InlinePanel, MultiFieldPanel, ObjectList, - StreamFieldPanel, PageChooserPanel, + StreamFieldPanel, TabbedInterface, ) -from wagtail.core.models import Orderable, Page -from wagtail.core.fields import RichTextField, StreamField, StreamBlock from wagtail.core.blocks import PageChooserBlock +from wagtail.core.fields import RichTextField, StreamBlock, StreamField +from wagtail.core.models import Orderable, Page from wagtail.images.edit_handlers import ImageChooserPanel -from modelcluster.fields import ParentalKey -from modelcluster.contrib.taggit import ClusterTaggableManager -from taggit.models import TaggedItemBase +import readtime from ..common.blocks import ExternalAuthorBlock, ExternalLinkBlock from ..common.constants import RICH_TEXT_FEATURES_SIMPLE diff --git a/developerportal/apps/articles/tests/test_articles.py b/developerportal/apps/articles/tests/test_articles.py index d28eea0ac..43a49eab1 100644 --- a/developerportal/apps/articles/tests/test_articles.py +++ b/developerportal/apps/articles/tests/test_articles.py @@ -1,7 +1,7 @@ from wagtail.tests.utils import WagtailPageTests -from ..models import Article, Articles from ...home.models import HomePage +from ..models import Article, Articles class ArticleTests(WagtailPageTests): diff --git a/developerportal/apps/articles/wagtail_hooks.py b/developerportal/apps/articles/wagtail_hooks.py index 18bbd4b87..45bdc9dc1 100644 --- a/developerportal/apps/articles/wagtail_hooks.py +++ b/developerportal/apps/articles/wagtail_hooks.py @@ -1,7 +1,7 @@ -from wagtail.contrib.modeladmin.options import modeladmin_register, ModelAdmin +from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register -from .models import Articles from ..common.helpers import ExplorerRedirectAdminURLHelper +from .models import Articles class ArticlesAdmin(ModelAdmin): diff --git a/developerportal/apps/common/fields.py b/developerportal/apps/common/fields.py index 9b10854d8..033d7092b 100644 --- a/developerportal/apps/common/fields.py +++ b/developerportal/apps/common/fields.py @@ -1,7 +1,7 @@ -from wagtail.core.blocks import RichTextBlock, RawHTMLBlock +from wagtail.core.blocks import RawHTMLBlock, RichTextBlock from wagtail.core.fields import StreamField -from wagtail.images.blocks import ImageChooserBlock from wagtail.embeds.blocks import EmbedBlock +from wagtail.images.blocks import ImageChooserBlock from .blocks import ButtonBlock, CodeSnippetBlock from .constants import RICH_TEXT_FEATURES diff --git a/developerportal/apps/common/image_formats.py b/developerportal/apps/common/image_formats.py index 19def50b7..8552bd861 100644 --- a/developerportal/apps/common/image_formats.py +++ b/developerportal/apps/common/image_formats.py @@ -4,7 +4,6 @@ unregister_image_format, ) - unregister_image_format("fullwidth") unregister_image_format("left") unregister_image_format("right") diff --git a/developerportal/apps/content/models.py b/developerportal/apps/content/models.py index 013721c62..8aed29b80 100644 --- a/developerportal/apps/content/models.py +++ b/developerportal/apps/content/models.py @@ -1,5 +1,8 @@ -from django.db.models import CASCADE, CharField, ForeignKey, SET_NULL, TextField +from django.db.models import CASCADE, SET_NULL, CharField, ForeignKey, TextField +from modelcluster.contrib.taggit import ClusterTaggableManager +from modelcluster.fields import ParentalKey +from taggit.models import TaggedItemBase from wagtail.admin.edit_handlers import ( FieldPanel, MultiFieldPanel, @@ -10,10 +13,6 @@ from wagtail.core.models import Page from wagtail.images.edit_handlers import ImageChooserPanel -from modelcluster.fields import ParentalKey -from modelcluster.contrib.taggit import ClusterTaggableManager -from taggit.models import TaggedItemBase - from ..common.fields import CustomStreamField diff --git a/developerportal/apps/content/tests/test_content.py b/developerportal/apps/content/tests/test_content.py index 3aa272536..6b6dd8117 100644 --- a/developerportal/apps/content/tests/test_content.py +++ b/developerportal/apps/content/tests/test_content.py @@ -1,8 +1,8 @@ from wagtail.tests.utils import WagtailPageTests -from ..models import ContentPage from ...home.models import HomePage from ...people.models import People +from ..models import ContentPage class ContentPageTests(WagtailPageTests): diff --git a/developerportal/apps/events/models.py b/developerportal/apps/events/models.py index ca17e7576..ec319b6e8 100644 --- a/developerportal/apps/events/models.py +++ b/developerportal/apps/events/models.py @@ -3,34 +3,34 @@ from django.db.models import ( CASCADE, + SET_NULL, CharField, DateField, FloatField, ForeignKey, - SET_NULL, TextField, URLField, ) from django.utils.safestring import mark_safe -from wagtail.core.models import Page, Orderable -from wagtail.core.fields import RichTextField, StreamField, StreamBlock -from wagtail.core.blocks import PageChooserBlock -from wagtail.images.edit_handlers import ImageChooserPanel +from modelcluster.contrib.taggit import ClusterTaggableManager +from modelcluster.fields import ParentalKey +from taggit.models import TaggedItemBase from wagtail.admin.edit_handlers import ( FieldPanel, InlinePanel, MultiFieldPanel, ObjectList, PageChooserPanel, - TabbedInterface, StreamFieldPanel, + TabbedInterface, ) +from wagtail.core.blocks import PageChooserBlock +from wagtail.core.fields import RichTextField, StreamBlock, StreamField +from wagtail.core.models import Orderable, Page +from wagtail.images.edit_handlers import ImageChooserPanel from django_countries.fields import CountryField -from modelcluster.fields import ParentalKey -from modelcluster.contrib.taggit import ClusterTaggableManager -from taggit.models import TaggedItemBase from ..common.blocks import AgendaItemBlock, ExternalSpeakerBlock, FeaturedExternalBlock from ..common.constants import RICH_TEXT_FEATURES_SIMPLE diff --git a/developerportal/apps/events/tests/test_events.py b/developerportal/apps/events/tests/test_events.py index 65f362c08..ea74a95a9 100644 --- a/developerportal/apps/events/tests/test_events.py +++ b/developerportal/apps/events/tests/test_events.py @@ -1,7 +1,7 @@ from wagtail.tests.utils import WagtailPageTests -from ..models import Event, Events from ...home.models import HomePage +from ..models import Event, Events class EventTests(WagtailPageTests): diff --git a/developerportal/apps/events/wagtail_hooks.py b/developerportal/apps/events/wagtail_hooks.py index ddba15b0b..d5c629959 100644 --- a/developerportal/apps/events/wagtail_hooks.py +++ b/developerportal/apps/events/wagtail_hooks.py @@ -1,7 +1,7 @@ -from wagtail.contrib.modeladmin.options import modeladmin_register, ModelAdmin +from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register -from .models import Events from ..common.helpers import ExplorerRedirectAdminURLHelper +from .models import Events class EventsAdmin(ModelAdmin): diff --git a/developerportal/apps/externalcontent/models.py b/developerportal/apps/externalcontent/models.py index d1071241c..238282772 100644 --- a/developerportal/apps/externalcontent/models.py +++ b/developerportal/apps/externalcontent/models.py @@ -3,16 +3,15 @@ from django.db.models import ( CASCADE, + SET_NULL, CharField, DateField, ForeignKey, - SET_NULL, TextField, URLField, ) from modelcluster.fields import ParentalKey - from wagtail.admin.edit_handlers import ( FieldPanel, InlinePanel, @@ -23,7 +22,7 @@ TabbedInterface, ) from wagtail.core.blocks import PageChooserBlock -from wagtail.core.fields import RichTextField, StreamField, StreamBlock +from wagtail.core.fields import RichTextField, StreamBlock, StreamField from wagtail.core.models import Orderable, Page from wagtail.images.edit_handlers import ImageChooserPanel diff --git a/developerportal/apps/health/urls.py b/developerportal/apps/health/urls.py index 91540bbf8..bfce4fcc6 100644 --- a/developerportal/apps/health/urls.py +++ b/developerportal/apps/health/urls.py @@ -2,7 +2,6 @@ from . import views - urlpatterns = [ url(r"^healthz/?$", views.liveness, name="health.liveness"), url(r"^readiness/?$", views.readiness, name="health.readiness"), diff --git a/developerportal/apps/home/models.py b/developerportal/apps/home/models.py index 3cf7c4217..3d30070c9 100644 --- a/developerportal/apps/home/models.py +++ b/developerportal/apps/home/models.py @@ -1,12 +1,15 @@ from django.db.models import ( CASCADE, + SET_NULL, CharField, ForeignKey, - SET_NULL, - URLField, TextField, + URLField, ) +from modelcluster.contrib.taggit import ClusterTaggableManager +from modelcluster.fields import ParentalKey +from taggit.models import TaggedItemBase from wagtail.admin.edit_handlers import ( FieldPanel, MultiFieldPanel, @@ -14,15 +17,11 @@ StreamFieldPanel, TabbedInterface, ) -from wagtail.core.fields import StreamField, StreamBlock -from wagtail.core.models import Page from wagtail.core.blocks import PageChooserBlock +from wagtail.core.fields import StreamBlock, StreamField +from wagtail.core.models import Page from wagtail.images.edit_handlers import ImageChooserPanel -from modelcluster.fields import ParentalKey -from modelcluster.contrib.taggit import ClusterTaggableManager -from taggit.models import TaggedItemBase - from ..common.blocks import FeaturedExternalBlock diff --git a/developerportal/apps/home/tests/test_home.py b/developerportal/apps/home/tests/test_home.py index 88e10f9c4..42b361fd6 100644 --- a/developerportal/apps/home/tests/test_home.py +++ b/developerportal/apps/home/tests/test_home.py @@ -1,13 +1,13 @@ from wagtail.core.models import Page from wagtail.tests.utils import WagtailPageTests -from ..models import HomePage from ...articles.models import Articles from ...content.models import ContentPage from ...events.models import Events -from ...topics.models import Topics from ...people.models import People +from ...topics.models import Topics from ...videos.models import Videos +from ..models import HomePage class HomePageTests(WagtailPageTests): diff --git a/developerportal/apps/mozimages/models.py b/developerportal/apps/mozimages/models.py index 5202039d3..d5db4893d 100644 --- a/developerportal/apps/mozimages/models.py +++ b/developerportal/apps/mozimages/models.py @@ -1,6 +1,6 @@ from django.db import models -from wagtail.images.models import Image, AbstractImage, AbstractRendition +from wagtail.images.models import AbstractImage, AbstractRendition, Image class MozImage(AbstractImage): diff --git a/developerportal/apps/people/models.py b/developerportal/apps/people/models.py index cc2cda2b4..7a38b824b 100644 --- a/developerportal/apps/people/models.py +++ b/developerportal/apps/people/models.py @@ -2,29 +2,27 @@ from itertools import chain from operator import attrgetter -from django.db.models import CASCADE, CharField, ForeignKey, SET_NULL, TextField +from django.db.models import CASCADE, SET_NULL, CharField, ForeignKey, TextField +from modelcluster.contrib.taggit import ClusterTaggableManager +from modelcluster.fields import ParentalKey +from taggit.models import TaggedItemBase from wagtail.admin.edit_handlers import ( FieldPanel, InlinePanel, MultiFieldPanel, ObjectList, PageChooserPanel, - TabbedInterface, StreamFieldPanel, + TabbedInterface, ) -from wagtail.core.fields import RichTextField, StreamField, StreamBlock +from wagtail.core.fields import RichTextField, StreamBlock, StreamField from wagtail.core.models import Orderable, Page from wagtail.images.edit_handlers import ImageChooserPanel -from modelcluster.contrib.taggit import ClusterTaggableManager -from modelcluster.fields import ParentalKey -from taggit.models import TaggedItemBase - -from .edit_handlers import CustomLabelFieldPanel - from ..common.blocks import PersonalWebsiteBlock from ..common.constants import RICH_TEXT_FEATURES_SIMPLE, ROLE_CHOICES +from .edit_handlers import CustomLabelFieldPanel class PeopleTag(TaggedItemBase): diff --git a/developerportal/apps/people/tests/test_people.py b/developerportal/apps/people/tests/test_people.py index 0b87c6605..271e1ac74 100644 --- a/developerportal/apps/people/tests/test_people.py +++ b/developerportal/apps/people/tests/test_people.py @@ -1,8 +1,8 @@ from wagtail.tests.utils import WagtailPageTests -from ..models import People, Person -from ...home.models import HomePage from ...content.models import ContentPage +from ...home.models import HomePage +from ..models import People, Person class PersonTests(WagtailPageTests): diff --git a/developerportal/apps/people/wagtail_hooks.py b/developerportal/apps/people/wagtail_hooks.py index 122e5d538..00e9763a1 100644 --- a/developerportal/apps/people/wagtail_hooks.py +++ b/developerportal/apps/people/wagtail_hooks.py @@ -1,7 +1,7 @@ -from wagtail.contrib.modeladmin.options import modeladmin_register, ModelAdmin +from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register -from .models import People from ..common.helpers import ExplorerRedirectAdminURLHelper +from .models import People class PeopleAdmin(ModelAdmin): diff --git a/developerportal/apps/staticbuild/wagtail_hooks.py b/developerportal/apps/staticbuild/wagtail_hooks.py index bd11726a0..5494fe2d7 100644 --- a/developerportal/apps/staticbuild/wagtail_hooks.py +++ b/developerportal/apps/staticbuild/wagtail_hooks.py @@ -1,6 +1,6 @@ import logging -from multiprocessing import Process import os +from multiprocessing import Process from django.conf import settings from django.core.management import call_command @@ -10,7 +10,6 @@ from .models import StaticBuild - logging.basicConfig(level=os.environ.get("LOGLEVEL", logging.INFO)) logger = logging.getLogger(__name__) diff --git a/developerportal/apps/topics/models.py b/developerportal/apps/topics/models.py index e7f095cc9..413734ca7 100644 --- a/developerportal/apps/topics/models.py +++ b/developerportal/apps/topics/models.py @@ -3,32 +3,31 @@ from django.db.models import ( CASCADE, - CharField, - ForeignKey, SET_NULL, - TextField, + CharField, FileField, + ForeignKey, IntegerField, + TextField, ) +from modelcluster.contrib.taggit import ClusterTaggableManager +from modelcluster.fields import ParentalKey +from taggit.models import TaggedItemBase from wagtail.admin.edit_handlers import ( FieldPanel, InlinePanel, MultiFieldPanel, ObjectList, PageChooserPanel, - TabbedInterface, StreamFieldPanel, + TabbedInterface, ) -from wagtail.core.fields import RichTextField, StreamField, StreamBlock -from wagtail.core.models import Orderable, Page from wagtail.core.blocks import PageChooserBlock +from wagtail.core.fields import RichTextField, StreamBlock, StreamField +from wagtail.core.models import Orderable, Page from wagtail.images.edit_handlers import ImageChooserPanel -from modelcluster.fields import ParentalKey -from modelcluster.contrib.taggit import ClusterTaggableManager -from taggit.models import TaggedItemBase - from ..common.blocks import FeaturedExternalBlock, TabbedPanelBlock from ..common.constants import ( COLOR_CHOICES, diff --git a/developerportal/apps/topics/tests/test_topics.py b/developerportal/apps/topics/tests/test_topics.py index 5a9d5cd74..b9af1029e 100644 --- a/developerportal/apps/topics/tests/test_topics.py +++ b/developerportal/apps/topics/tests/test_topics.py @@ -1,7 +1,7 @@ from wagtail.tests.utils import WagtailPageTests -from ..models import Topic, Topics from ...home.models import HomePage +from ..models import Topic, Topics class TopicTests(WagtailPageTests): diff --git a/developerportal/apps/topics/wagtail_hooks.py b/developerportal/apps/topics/wagtail_hooks.py index 3e82b60a4..b3c0cead0 100644 --- a/developerportal/apps/topics/wagtail_hooks.py +++ b/developerportal/apps/topics/wagtail_hooks.py @@ -1,7 +1,7 @@ -from wagtail.contrib.modeladmin.options import modeladmin_register, ModelAdmin +from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register -from .models import Topics from ..common.helpers import ExplorerRedirectAdminURLHelper +from .models import Topics class TopicsAdmin(ModelAdmin): diff --git a/developerportal/apps/videos/models.py b/developerportal/apps/videos/models.py index 74187f3f5..d6d8e3031 100644 --- a/developerportal/apps/videos/models.py +++ b/developerportal/apps/videos/models.py @@ -1,34 +1,34 @@ # pylint: disable=no-member import datetime -import readtime from django.db.models import ( CASCADE, + SET_NULL, CharField, DateField, ForeignKey, - SET_NULL, TextField, ) +from modelcluster.contrib.taggit import ClusterTaggableManager +from modelcluster.fields import ParentalKey +from taggit.models import TaggedItemBase from wagtail.admin.edit_handlers import ( FieldPanel, InlinePanel, MultiFieldPanel, ObjectList, - StreamFieldPanel, PageChooserPanel, + StreamFieldPanel, TabbedInterface, ) +from wagtail.core.blocks import PageChooserBlock +from wagtail.core.fields import RichTextField, StreamBlock, StreamField from wagtail.core.models import Orderable, Page -from wagtail.images.edit_handlers import ImageChooserPanel -from wagtail.core.fields import RichTextField, StreamField, StreamBlock from wagtail.embeds.blocks import EmbedBlock -from wagtail.core.blocks import PageChooserBlock +from wagtail.images.edit_handlers import ImageChooserPanel -from modelcluster.fields import ParentalKey -from modelcluster.contrib.taggit import ClusterTaggableManager -from taggit.models import TaggedItemBase +import readtime from ..common.blocks import ExternalLinkBlock from ..common.constants import RICH_TEXT_FEATURES, RICH_TEXT_FEATURES_SIMPLE, VIDEO_TYPE diff --git a/developerportal/apps/videos/tests/test_videos.py b/developerportal/apps/videos/tests/test_videos.py index 826e20eba..b15f35a2c 100644 --- a/developerportal/apps/videos/tests/test_videos.py +++ b/developerportal/apps/videos/tests/test_videos.py @@ -1,7 +1,7 @@ from wagtail.tests.utils import WagtailPageTests -from ..models import Video, Videos from ...home.models import HomePage +from ..models import Video, Videos class VideoTests(WagtailPageTests): diff --git a/developerportal/apps/videos/wagtail_hooks.py b/developerportal/apps/videos/wagtail_hooks.py index 9dd20c36c..d1d0ec89e 100644 --- a/developerportal/apps/videos/wagtail_hooks.py +++ b/developerportal/apps/videos/wagtail_hooks.py @@ -1,7 +1,7 @@ -from wagtail.contrib.modeladmin.options import modeladmin_register, ModelAdmin +from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register -from .models import Videos from ..common.helpers import ExplorerRedirectAdminURLHelper +from .models import Videos class VideosAdmin(ModelAdmin): diff --git a/developerportal/pipeline.py b/developerportal/pipeline.py index 1b73fc0ed..d5ab8f17e 100644 --- a/developerportal/pipeline.py +++ b/developerportal/pipeline.py @@ -1,9 +1,10 @@ import os -import urllib3 from django.conf import settings from django.contrib import messages +import urllib3 + from social_core.exceptions import AuthException diff --git a/developerportal/settings/base.py b/developerportal/settings/base.py index 11aefddf4..38a8fd657 100644 --- a/developerportal/settings/base.py +++ b/developerportal/settings/base.py @@ -16,7 +16,6 @@ from wagtail.embeds.oembed_providers import all_providers - # Build paths inside the project like this: os.path.join(BASE_DIR, ...) PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(PROJECT_DIR) diff --git a/developerportal/templatetags/app_filters.py b/developerportal/templatetags/app_filters.py index 9c52a5874..d08329379 100644 --- a/developerportal/templatetags/app_filters.py +++ b/developerportal/templatetags/app_filters.py @@ -2,9 +2,7 @@ from django.utils.safestring import mark_safe import pygments -from pygments import lexers -from pygments import formatters - +from pygments import formatters, lexers register = template.Library() diff --git a/developerportal/templatetags/app_tags.py b/developerportal/templatetags/app_tags.py index 45c9c2f94..76e73bb33 100644 --- a/developerportal/templatetags/app_tags.py +++ b/developerportal/templatetags/app_tags.py @@ -1,13 +1,11 @@ import binascii import os +from mimetypes import guess_type from django import template from django.conf import settings from django.utils.safestring import mark_safe -from mimetypes import guess_type - - register = template.Library() diff --git a/developerportal/urls.py b/developerportal/urls.py index d38a0a429..9a820fa8a 100644 --- a/developerportal/urls.py +++ b/developerportal/urls.py @@ -10,7 +10,6 @@ from .apps.common.feed import RssFeeds - urlpatterns = [ url("", include("developerportal.apps.health.urls")), url(r"^django-admin/", admin.site.urls), From 6799e7265b9173acafc427004950e562f27faca4 Mon Sep 17 00:00:00 2001 From: Steve Jalim Date: Tue, 17 Sep 2019 11:43:29 +0100 Subject: [PATCH 3/7] 135: tighten up flake8 to also enforce 88-char lines, matching black This commit contains some (manual) changes to over-long lines caught by flake8 that black _didn't_ auto-fix, because they were long strings (see https://github.com/psf/black/issues/182) --- developerportal/apps/articles/models.py | 30 +++++++++------ developerportal/apps/common/blocks.py | 8 +++- developerportal/apps/common/fields.py | 3 +- developerportal/apps/common/wagtail_hooks.py | 9 +++-- developerportal/apps/content/models.py | 8 +++- developerportal/apps/events/models.py | 38 +++++++++++++------ .../apps/externalcontent/models.py | 25 +++++++----- developerportal/apps/home/models.py | 19 ++++++++-- developerportal/apps/people/models.py | 14 +++++-- developerportal/apps/topics/models.py | 16 ++++++-- developerportal/apps/videos/models.py | 29 +++++++++----- developerportal/settings/base.py | 8 ++-- developerportal/wsgi.py | 2 +- setup.cfg | 2 +- 14 files changed, 144 insertions(+), 67 deletions(-) diff --git a/developerportal/apps/articles/models.py b/developerportal/apps/articles/models.py index d6d8309be..5e16d22c0 100644 --- a/developerportal/apps/articles/models.py +++ b/developerportal/apps/articles/models.py @@ -70,7 +70,10 @@ class Articles(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title " + "and description for SEO purposes" + ), ) ] @@ -147,7 +150,8 @@ class Article(Page): ) body = CustomStreamField( help_text=( - "The main article content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets" + "The main article content. Supports rich text, images, embed via URL, " + "embed via HTML, and inline code snippets" ) ) related_links_mdn = StreamField( @@ -187,8 +191,8 @@ class Article(Page): blank=True, null=True, help_text=( - "Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a " - "profile on the system" + "Optional list of the article’s authors. Use ‘External author’ to add " + "guest authors without creating a profile on the system" ), ) keywords = ClusterTaggableManager(through=ArticleTag, blank=True) @@ -200,8 +204,8 @@ class Article(Page): [ImageChooserPanel("image")], heading="Image", help_text=( - "Optional header image. If not specified a fallback will be used. This image is also shown when sharing " - "this page via social media" + "Optional header image. If not specified a fallback will be used. " + "This image is also shown when sharing this page via social media" ), ), StreamFieldPanel("body"), @@ -223,8 +227,9 @@ class Article(Page): [InlinePanel("topics")], heading="Topics", help_text=( - "The topic pages this article will appear on. The first topic in the list will be treated as the " - "primary topic and will be shown in the page’s related content." + "The topic pages this article will appear on. The first topic in the " + "list will be treated as the primary topic and will be shown in the " + "page’s related content." ), ), MultiFieldPanel( @@ -234,7 +239,10 @@ class Article(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title and description " + "for SEO purposes" + ), ), ] @@ -267,8 +275,8 @@ def read_time(self): @property def related_resources(self): - """Returns resources that are related to the current resource, i.e. live, public articles and videos which - have the same topics.""" + """Returns resources that are related to the current resource, i.e. + live, public articles and videos which have the same topics.""" topic_pks = [topic.topic.pk for topic in self.topics.all()] return get_combined_articles_and_videos(self, topics__topic__pk__in=topic_pks) diff --git a/developerportal/apps/common/blocks.py b/developerportal/apps/common/blocks.py index 435308222..5ef3bdfe4 100644 --- a/developerportal/apps/common/blocks.py +++ b/developerportal/apps/common/blocks.py @@ -64,7 +64,8 @@ class AgendaItemBlock(blocks.StructBlock): class ExternalLinkBlock(blocks.StructBlock): - """Content for a link to an external page without an image, e.g. MDN related links.""" + """Content for a link to an external page without an image, + e.g. MDN related links.""" title = blocks.CharBlock(label="Name") url = blocks.URLBlock() @@ -102,4 +103,7 @@ class PersonalWebsiteBlock(blocks.StructBlock): icon = ImageChooserBlock(required=False) class Meta: - help_text = "Details of any other personal website, to be displayed alongside social profiles." + help_text = ( + "Details of any other personal website, to be displayed alongside " + "social profiles." + ) diff --git a/developerportal/apps/common/fields.py b/developerportal/apps/common/fields.py index 033d7092b..a3d9c4967 100644 --- a/developerportal/apps/common/fields.py +++ b/developerportal/apps/common/fields.py @@ -22,7 +22,8 @@ def __init__(self, *args, **kwargs): "embed_html", RawHTMLBlock( help_text=( - "Warning: be careful what you paste here, since this field could introduce XSS (or similar) bugs. " + "Warning: be careful what you paste here, since this " + "field could introduce XSS (or similar) bugs. " "This field is meant solely for third-party embeds." ) ), diff --git a/developerportal/apps/common/wagtail_hooks.py b/developerportal/apps/common/wagtail_hooks.py index e0c1812d6..eeb8b14c1 100644 --- a/developerportal/apps/common/wagtail_hooks.py +++ b/developerportal/apps/common/wagtail_hooks.py @@ -18,8 +18,8 @@ def expand_db_attributes(cls, attrs): # Let's add the target attr, and also rel="noopener" + noreferrer fallback. # See https://github.com/whatwg/html/issues/4078. return ( - '' - % escape(href) + '' % escape(href) ) @@ -33,7 +33,10 @@ def _custom_slug_help_text(): # back to example.com instead of the Wagtail default. default_site = Site.objects.filter(is_default_site=True).first() base_url = default_site.root_url if default_site else "https://example.com" - return f"The name of the page as it will appear in URLs e.g. for an article: {base_url}/articles/slug/" + return ( + f"The name of the page as it will appear in URLs e.g. " + f"for an article: {base_url}/articles/slug/" + ) try: diff --git a/developerportal/apps/content/models.py b/developerportal/apps/content/models.py index 8aed29b80..dd766c202 100644 --- a/developerportal/apps/content/models.py +++ b/developerportal/apps/content/models.py @@ -37,7 +37,8 @@ class ContentPage(Page): ) body = CustomStreamField( help_text=( - "Main page body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets" + "Main page body content. Supports rich text, images, embed via URL, " + "embed via HTML, and inline code snippets" ) ) @@ -82,7 +83,10 @@ class ContentPage(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title and " + "description for SEO purposes" + ), ) ] diff --git a/developerportal/apps/events/models.py b/developerportal/apps/events/models.py index ec319b6e8..32e18facf 100644 --- a/developerportal/apps/events/models.py +++ b/developerportal/apps/events/models.py @@ -102,7 +102,10 @@ class Events(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title and description " + "for SEO purposes" + ), ) ] @@ -169,7 +172,8 @@ class Event(Page): blank=True, null=True, help_text=( - "Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets" + "Optional body content. Supports rich text, images, embed via URL, " + "embed via HTML, and inline code snippets" ), ) agenda = StreamField( @@ -227,8 +231,8 @@ class Event(Page): [ImageChooserPanel("image")], heading="Image", help_text=( - "Optional header image. If not specified a fallback will be used. This image is also shown when sharing " - "this page via social media" + "Optional header image. If not specified a fallback will be used. " + "This image is also shown when sharing this page via social media" ), ), StreamFieldPanel("body"), @@ -256,9 +260,11 @@ class Event(Page): heading="Event details", classname="collapsible", help_text=mark_safe( - "Optional time and location information for this event. Latitude and longitude are used to show a map " - "of the event’s location. For more information on finding these values for a given location, " - 'see this article' + "Optional time and location information for this event. Latitude and " + "longitude are used to show a map of the event’s location. For more " + "information on finding these values for a given location, " + "'" + "see this article" ), ), MultiFieldPanel( @@ -275,14 +281,18 @@ class Event(Page): ], heading="Event address", classname="collapsible", - help_text="Optional address fields. The city and country are also shown on event cards", + help_text=( + "Optional address fields. The city and country are also shown " + "on event cards" + ), ), MultiFieldPanel( [InlinePanel("topics")], heading="Topics", help_text=( - "These are the topic pages the event will appear on. The first topic in the list will be treated as the " - "primary topic and will be shown in the page’s related content." + "These are the topic pages the event will appear on. The first topic " + "in the list will be treated as the primary topic and will be shown " + "in the page’s related content." ), ), MultiFieldPanel( @@ -292,7 +302,10 @@ class Event(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title and description " + "for SEO purposes" + ), ), ] @@ -338,7 +351,8 @@ def event_dates(self): @property def event_dates_full(self): - """Return a formatted string of the event start and end dates, including the year""" + """Return a formatted string of the event start and end dates, + including the year""" return self.event_dates + self.start_date.strftime(", %Y") def has_speaker(self, person): diff --git a/developerportal/apps/externalcontent/models.py b/developerportal/apps/externalcontent/models.py index 238282772..2d4cc3d6c 100644 --- a/developerportal/apps/externalcontent/models.py +++ b/developerportal/apps/externalcontent/models.py @@ -46,7 +46,10 @@ class ExternalContent(Page): "URL", blank=True, default="", - help_text="The URL that this content links to, max. 2048 characters for compatibility with older web browsers", + help_text=( + "The URL that this content links to, max. 2048 characters " + "for compatibility with older web browsers" + ), max_length=2048, ) image = ForeignKey( @@ -63,8 +66,8 @@ class ExternalContent(Page): [ImageChooserPanel("image")], heading="Image", help_text=( - "Optional header image. If not specified a fallback will be used. This image is also shown when sharing " - "this page via social media" + "Optional header image. If not specified a fallback will be used. " + "This image is also shown when sharing this page via social media" ), ), FieldPanel("external_url"), @@ -122,8 +125,8 @@ class ExternalArticle(ExternalContent): blank=True, null=True, help_text=( - "Optional list of the article’s authors. Use ‘External author’ to add guest authors without creating a " - "profile on the system" + "Optional list of the article’s authors. Use ‘External author’ to add " + "guest authors without creating a profile on the system" ), ) read_time = CharField( @@ -226,14 +229,16 @@ class ExternalEvent(ExternalContent): "topics", heading="Topics", help_text=( - "Optional topics this event is associated with. Adds the event to the list of events on those topic pages" + "Optional topics this event is associated with. " + "Adds the event to the list of events on those topic pages" ), ), InlinePanel( "speakers", heading="Speakers", help_text=( - "Optional speakers associated with this event. Adds the event to the list of events on their profile pages" + "Optional speakers associated with this event. " + "Adds the event to the list of events on their profile pages" ), ), ] @@ -269,7 +274,8 @@ def event_dates(self): @property def event_dates_full(self): - """Return a formatted string of the event start and end dates, including the year""" + """Return a formatted string of the event start and end dates, + including the year""" return self.event_dates + self.start_date.strftime(", %Y") @@ -315,7 +321,8 @@ class ExternalVideo(ExternalContent): blank=True, null=True, help_text=( - "Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card" + "Optional video duration in MM:SS format e.g. “12:34”. " + "Shown when the video is displayed as a card" ), ) diff --git a/developerportal/apps/home/models.py b/developerportal/apps/home/models.py index 3d30070c9..691674213 100644 --- a/developerportal/apps/home/models.py +++ b/developerportal/apps/home/models.py @@ -59,7 +59,10 @@ class HomePage(Page): ), null=True, blank=True, - help_text="Optional promo space under the header for linking to external sites, max. 2", + help_text=( + "Optional promo space under the header " + "for linking to external sites, max. 2" + ), ) featured = StreamField( StreamBlock( @@ -116,7 +119,9 @@ class HomePage(Page): MultiFieldPanel( [ImageChooserPanel("image")], heading="Image", - help_text="Optional image shown when sharing this page through social media", + help_text=( + "Optional image shown when sharing this page through social media" + ), ), StreamFieldPanel("external_promos"), StreamFieldPanel("featured"), @@ -142,7 +147,10 @@ class HomePage(Page): ], heading="Card overrides", help_text=( - "Optional fields to override the default title, description and image when this page is shown as a card" + ( + "Optional fields to override the default title, " + "description and image when this page is shown as a card" + ) ), ) ] @@ -156,7 +164,10 @@ class HomePage(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default " + "title and description for SEO purposes" + ), ) ] diff --git a/developerportal/apps/people/models.py b/developerportal/apps/people/models.py index 7a38b824b..78ca6ab7c 100644 --- a/developerportal/apps/people/models.py +++ b/developerportal/apps/people/models.py @@ -60,7 +60,10 @@ class People(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title and description " + "for SEO purposes" + ), ) ] @@ -179,8 +182,8 @@ class Person(Page): [ImageChooserPanel("image")], heading="Image", help_text=( - "Optional header image. If not specified a fallback will be used. This image is also shown when sharing " - "this page via social media" + "Optional header image. If not specified a fallback will be used. " + "This image is also shown when sharing this page via social media" ), ), ] @@ -214,7 +217,10 @@ class Person(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title and description " + "for SEO purposes" + ), ), ] diff --git a/developerportal/apps/topics/models.py b/developerportal/apps/topics/models.py index 413734ca7..8e69000c7 100644 --- a/developerportal/apps/topics/models.py +++ b/developerportal/apps/topics/models.py @@ -165,7 +165,8 @@ class Topic(Page): heading="Parent/child topic(s)", classname="collapsible collapsed", help_text=( - "Topics with no parent (i.e. top-level topics) will be listed on the home page. Child topics are listed " + "Topics with no parent (i.e. top-level topics) will be " + "listed on the home page. Child topics are listed " "on the parent topic’s page." ), ), @@ -173,7 +174,8 @@ class Topic(Page): [FieldPanel("icon"), FieldPanel("color")], heading="Theme", help_text=( - "Theme settings used on topic page and any tagged content. For example, an article tagged with this topic " + "Theme settings used on topic page and any tagged content. " + "For example, an article tagged with this topic " "will use the color specified here as its accent color." ), ), @@ -184,7 +186,10 @@ class Topic(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default " + "title and description for SEO purposes" + ), ), ] @@ -244,7 +249,10 @@ class Topics(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default " + "title and description for SEO purposes" + ), ) ] diff --git a/developerportal/apps/videos/models.py b/developerportal/apps/videos/models.py index d6d8e3031..d9887e02e 100644 --- a/developerportal/apps/videos/models.py +++ b/developerportal/apps/videos/models.py @@ -64,7 +64,10 @@ class Videos(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title and description " + "for SEO purposes" + ), ) ] @@ -116,7 +119,8 @@ class Video(Page): default="", features=RICH_TEXT_FEATURES, help_text=( - "Optional body content. Supports rich text, images, embed via URL, embed via HTML, and inline code snippets" + "Optional body content. Supports rich text, images, embed via URL, " + "embed via HTML, and inline code snippets" ), ) related_links_mdn = StreamField( @@ -139,7 +143,8 @@ class Video(Page): blank=True, null=True, help_text=( - "Optional video duration in MM:SS format e.g. “12:34”. Shown when the video is displayed as a card" + "Optional video duration in MM:SS format e.g. “12:34”. Shown when the " + "video is displayed as a card" ), ) transcript = RichTextField( @@ -150,7 +155,9 @@ class Video(Page): ) video_url = StreamField( StreamBlock([("embed", EmbedBlock())], min_num=1, max_num=1, required=True), - help_text="Embed URL for the video e.g. https://www.youtube.com/watch?v=kmk43_2dtn0", + help_text=( + "Embed URL for the video e.g. https://www.youtube.com/watch?v=kmk43_2dtn0" + ), ) speakers = StreamField( StreamBlock( @@ -203,8 +210,9 @@ class Video(Page): [InlinePanel("topics")], heading="Topics", help_text=( - "These are the topic pages the video will appear on. The first topic in the list will be treated as the " - "primary topic and will be shown in the page’s related content." + "These are the topic pages the video will appear on. The first topic " + "in the list will be treated as the primary topic and will be shown " + "in the page’s related content." ), ), FieldPanel("duration"), @@ -220,7 +228,10 @@ class Video(Page): FieldPanel("keywords"), ], heading="SEO", - help_text="Optional fields to override the default title and description for SEO purposes", + help_text=( + "Optional fields to override the default title and description " + "for SEO purposes" + ), ), ] @@ -248,8 +259,8 @@ def read_time(self): @property def related_resources(self): - """Returns resources that are related to the current resource, i.e. live, public articles and videos which - have the same topics.""" + """Returns resources that are related to the current resource, i.e. live, + public articles and videos which have the same topics.""" topic_pks = self.topics.values_list("topic") return get_combined_articles_and_videos(self, topics__topic__pk__in=topic_pks) diff --git a/developerportal/settings/base.py b/developerportal/settings/base.py index 38a8fd657..4fe1663f4 100644 --- a/developerportal/settings/base.py +++ b/developerportal/settings/base.py @@ -139,7 +139,10 @@ AUTH_PASSWORD_VALIDATORS = [ { - "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + "NAME": ( + "django.contrib.auth.password_validation." + "UserAttributeSimilarityValidator" + ) }, {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, @@ -176,9 +179,6 @@ ("img", os.path.join(BASE_DIR, "src/img")), ] -# ManifestStaticFilesStorage is recommended in production, to prevent outdated -# Javascript / CSS assets being served from cache (e.g. after a Wagtail upgrade). -# See https://docs.djangoproject.com/en/2.1/ref/contrib/staticfiles/#manifeststaticfilesstorage STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" STATIC_ROOT = os.path.join(BASE_DIR, "static") diff --git a/developerportal/wsgi.py b/developerportal/wsgi.py index d08a853f4..a05581509 100644 --- a/developerportal/wsgi.py +++ b/developerportal/wsgi.py @@ -13,7 +13,7 @@ # Load dev settings by default. To override this, set either: # - DJANGO_ENV to e.g. production, or; -# - DJANGO_SETTINGS_MODULE to e.g. developerportal.settings.production (takes precedence). +# - DJANGO_SETTINGS_MODULE to e.g. developerportal.settings.production (takes precedence). # noqa env = os.environ.setdefault("DJANGO_ENV", "dev") os.environ.setdefault("DJANGO_SETTINGS_MODULE", f"developerportal.settings.{env}") diff --git a/setup.cfg b/setup.cfg index 22aad54b6..7377d50e5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [flake8] exclude = .*,__pycache__,*.egg,migrations,node_modules -max-line-length = 120 +max-line-length = 88 per-file-ignores = # Ignored to allow wildcard imports in settings developerportal/settings/*:F401,F403,F405 From ca6e336deab5bb8cfdaac9cc422663d33fe95c3e Mon Sep 17 00:00:00 2001 From: Steve Jalim Date: Tue, 17 Sep 2019 13:29:46 +0100 Subject: [PATCH 4/7] 135: Run prettier across all SCSS, ahead of hooking it into therapist's pre-commit tasks --- src/css/atoms/code.scss | 295 ++++++++++++++++----- src/css/atoms/map.scss | 2 +- src/css/atoms/typography.scss | 34 ++- src/css/global/base.scss | 2 +- src/css/global/variables.scss | 5 +- src/css/molecules/card-event.scss | 2 +- src/css/molecules/card-topic.scss | 6 +- src/css/molecules/card.scss | 1 - src/css/molecules/content-hero.scss | 4 +- src/css/molecules/item-get-started.scss | 2 +- src/css/molecules/resource-topic-tags.scss | 2 +- src/css/organisms/article-header.scss | 6 +- src/css/organisms/filter-list.scss | 4 +- src/css/organisms/homepage-header.scss | 3 +- src/css/organisms/newsletter-signup.scss | 5 +- src/css/organisms/pattern-bg-header.scss | 12 +- src/css/organisms/tabbed-panels.scss | 11 +- src/css/templates/article.scss | 4 +- 18 files changed, 296 insertions(+), 104 deletions(-) diff --git a/src/css/atoms/code.scss b/src/css/atoms/code.scss index ce1e5b709..bc3f72856 100644 --- a/src/css/atoms/code.scss +++ b/src/css/atoms/code.scss @@ -41,71 +41,230 @@ code { } // Styles from Pygments -.syntax-highlight .hll { background-color: #ffffcc } -.syntax-highlight .c { color: #408080; font-style: italic } /* Comment */ -.syntax-highlight .err { border: 1px solid #FF0000 } /* Error */ -.syntax-highlight .k { color: #008000; font-weight: bold } /* Keyword */ -.syntax-highlight .o { color: #666666 } /* Operator */ -.syntax-highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ -.syntax-highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -.syntax-highlight .cp { color: #BC7A00 } /* Comment.Preproc */ -.syntax-highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ -.syntax-highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ -.syntax-highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ -.syntax-highlight .gd { color: #A00000 } /* Generic.Deleted */ -.syntax-highlight .ge { font-style: italic } /* Generic.Emph */ -.syntax-highlight .gr { color: #FF0000 } /* Generic.Error */ -.syntax-highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.syntax-highlight .gi { color: #00A000 } /* Generic.Inserted */ -.syntax-highlight .go { color: #888888 } /* Generic.Output */ -.syntax-highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ -.syntax-highlight .gs { font-weight: bold } /* Generic.Strong */ -.syntax-highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.syntax-highlight .gt { color: #0044DD } /* Generic.Traceback */ -.syntax-highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ -.syntax-highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ -.syntax-highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ -.syntax-highlight .kp { color: #008000 } /* Keyword.Pseudo */ -.syntax-highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ -.syntax-highlight .kt { color: #B00040 } /* Keyword.Type */ -.syntax-highlight .m { color: #666666 } /* Literal.Number */ -.syntax-highlight .s { color: #BA2121 } /* Literal.String */ -.syntax-highlight .na { color: #7D9029 } /* Name.Attribute */ -.syntax-highlight .nb { color: #008000 } /* Name.Builtin */ -.syntax-highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -.syntax-highlight .no { color: #880000 } /* Name.Constant */ -.syntax-highlight .nd { color: #AA22FF } /* Name.Decorator */ -.syntax-highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ -.syntax-highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ -.syntax-highlight .nf { color: #0000FF } /* Name.Function */ -.syntax-highlight .nl { color: #A0A000 } /* Name.Label */ -.syntax-highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ -.syntax-highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ -.syntax-highlight .nv { color: #19177C } /* Name.Variable */ -.syntax-highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -.syntax-highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.syntax-highlight .mb { color: #666666 } /* Literal.Number.Bin */ -.syntax-highlight .mf { color: #666666 } /* Literal.Number.Float */ -.syntax-highlight .mh { color: #666666 } /* Literal.Number.Hex */ -.syntax-highlight .mi { color: #666666 } /* Literal.Number.Integer */ -.syntax-highlight .mo { color: #666666 } /* Literal.Number.Oct */ -.syntax-highlight .sa { color: #BA2121 } /* Literal.String.Affix */ -.syntax-highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ -.syntax-highlight .sc { color: #BA2121 } /* Literal.String.Char */ -.syntax-highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ -.syntax-highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ -.syntax-highlight .s2 { color: #BA2121 } /* Literal.String.Double */ -.syntax-highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ -.syntax-highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ -.syntax-highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ -.syntax-highlight .sx { color: #008000 } /* Literal.String.Other */ -.syntax-highlight .sr { color: #BB6688 } /* Literal.String.Regex */ -.syntax-highlight .s1 { color: #BA2121 } /* Literal.String.Single */ -.syntax-highlight .ss { color: #19177C } /* Literal.String.Symbol */ -.syntax-highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ -.syntax-highlight .fm { color: #0000FF } /* Name.Function.Magic */ -.syntax-highlight .vc { color: #19177C } /* Name.Variable.Class */ -.syntax-highlight .vg { color: #19177C } /* Name.Variable.Global */ -.syntax-highlight .vi { color: #19177C } /* Name.Variable.Instance */ -.syntax-highlight .vm { color: #19177C } /* Name.Variable.Magic */ -.syntax-highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ +.syntax-highlight .hll { + background-color: #ffffcc; +} +.syntax-highlight .c { + color: #408080; + font-style: italic; +} /* Comment */ +.syntax-highlight .err { + border: 1px solid #ff0000; +} /* Error */ +.syntax-highlight .k { + color: #008000; + font-weight: bold; +} /* Keyword */ +.syntax-highlight .o { + color: #666666; +} /* Operator */ +.syntax-highlight .ch { + color: #408080; + font-style: italic; +} /* Comment.Hashbang */ +.syntax-highlight .cm { + color: #408080; + font-style: italic; +} /* Comment.Multiline */ +.syntax-highlight .cp { + color: #bc7a00; +} /* Comment.Preproc */ +.syntax-highlight .cpf { + color: #408080; + font-style: italic; +} /* Comment.PreprocFile */ +.syntax-highlight .c1 { + color: #408080; + font-style: italic; +} /* Comment.Single */ +.syntax-highlight .cs { + color: #408080; + font-style: italic; +} /* Comment.Special */ +.syntax-highlight .gd { + color: #a00000; +} /* Generic.Deleted */ +.syntax-highlight .ge { + font-style: italic; +} /* Generic.Emph */ +.syntax-highlight .gr { + color: #ff0000; +} /* Generic.Error */ +.syntax-highlight .gh { + color: #000080; + font-weight: bold; +} /* Generic.Heading */ +.syntax-highlight .gi { + color: #00a000; +} /* Generic.Inserted */ +.syntax-highlight .go { + color: #888888; +} /* Generic.Output */ +.syntax-highlight .gp { + color: #000080; + font-weight: bold; +} /* Generic.Prompt */ +.syntax-highlight .gs { + font-weight: bold; +} /* Generic.Strong */ +.syntax-highlight .gu { + color: #800080; + font-weight: bold; +} /* Generic.Subheading */ +.syntax-highlight .gt { + color: #0044dd; +} /* Generic.Traceback */ +.syntax-highlight .kc { + color: #008000; + font-weight: bold; +} /* Keyword.Constant */ +.syntax-highlight .kd { + color: #008000; + font-weight: bold; +} /* Keyword.Declaration */ +.syntax-highlight .kn { + color: #008000; + font-weight: bold; +} /* Keyword.Namespace */ +.syntax-highlight .kp { + color: #008000; +} /* Keyword.Pseudo */ +.syntax-highlight .kr { + color: #008000; + font-weight: bold; +} /* Keyword.Reserved */ +.syntax-highlight .kt { + color: #b00040; +} /* Keyword.Type */ +.syntax-highlight .m { + color: #666666; +} /* Literal.Number */ +.syntax-highlight .s { + color: #ba2121; +} /* Literal.String */ +.syntax-highlight .na { + color: #7d9029; +} /* Name.Attribute */ +.syntax-highlight .nb { + color: #008000; +} /* Name.Builtin */ +.syntax-highlight .nc { + color: #0000ff; + font-weight: bold; +} /* Name.Class */ +.syntax-highlight .no { + color: #880000; +} /* Name.Constant */ +.syntax-highlight .nd { + color: #aa22ff; +} /* Name.Decorator */ +.syntax-highlight .ni { + color: #999999; + font-weight: bold; +} /* Name.Entity */ +.syntax-highlight .ne { + color: #d2413a; + font-weight: bold; +} /* Name.Exception */ +.syntax-highlight .nf { + color: #0000ff; +} /* Name.Function */ +.syntax-highlight .nl { + color: #a0a000; +} /* Name.Label */ +.syntax-highlight .nn { + color: #0000ff; + font-weight: bold; +} /* Name.Namespace */ +.syntax-highlight .nt { + color: #008000; + font-weight: bold; +} /* Name.Tag */ +.syntax-highlight .nv { + color: #19177c; +} /* Name.Variable */ +.syntax-highlight .ow { + color: #aa22ff; + font-weight: bold; +} /* Operator.Word */ +.syntax-highlight .w { + color: #bbbbbb; +} /* Text.Whitespace */ +.syntax-highlight .mb { + color: #666666; +} /* Literal.Number.Bin */ +.syntax-highlight .mf { + color: #666666; +} /* Literal.Number.Float */ +.syntax-highlight .mh { + color: #666666; +} /* Literal.Number.Hex */ +.syntax-highlight .mi { + color: #666666; +} /* Literal.Number.Integer */ +.syntax-highlight .mo { + color: #666666; +} /* Literal.Number.Oct */ +.syntax-highlight .sa { + color: #ba2121; +} /* Literal.String.Affix */ +.syntax-highlight .sb { + color: #ba2121; +} /* Literal.String.Backtick */ +.syntax-highlight .sc { + color: #ba2121; +} /* Literal.String.Char */ +.syntax-highlight .dl { + color: #ba2121; +} /* Literal.String.Delimiter */ +.syntax-highlight .sd { + color: #ba2121; + font-style: italic; +} /* Literal.String.Doc */ +.syntax-highlight .s2 { + color: #ba2121; +} /* Literal.String.Double */ +.syntax-highlight .se { + color: #bb6622; + font-weight: bold; +} /* Literal.String.Escape */ +.syntax-highlight .sh { + color: #ba2121; +} /* Literal.String.Heredoc */ +.syntax-highlight .si { + color: #bb6688; + font-weight: bold; +} /* Literal.String.Interpol */ +.syntax-highlight .sx { + color: #008000; +} /* Literal.String.Other */ +.syntax-highlight .sr { + color: #bb6688; +} /* Literal.String.Regex */ +.syntax-highlight .s1 { + color: #ba2121; +} /* Literal.String.Single */ +.syntax-highlight .ss { + color: #19177c; +} /* Literal.String.Symbol */ +.syntax-highlight .bp { + color: #008000; +} /* Name.Builtin.Pseudo */ +.syntax-highlight .fm { + color: #0000ff; +} /* Name.Function.Magic */ +.syntax-highlight .vc { + color: #19177c; +} /* Name.Variable.Class */ +.syntax-highlight .vg { + color: #19177c; +} /* Name.Variable.Global */ +.syntax-highlight .vi { + color: #19177c; +} /* Name.Variable.Instance */ +.syntax-highlight .vm { + color: #19177c; +} /* Name.Variable.Magic */ +.syntax-highlight .il { + color: #666666; +} /* Literal.Number.Integer.Long */ diff --git a/src/css/atoms/map.scss b/src/css/atoms/map.scss index 5d9074be5..8c11660ca 100644 --- a/src/css/atoms/map.scss +++ b/src/css/atoms/map.scss @@ -12,7 +12,7 @@ } .marker { - background-image: url($image-path + '/icons/ui/map-pin.svg'); + background-image: url($image-path+'/icons/ui/map-pin.svg'); background-size: cover; width: 24px; height: 24px; diff --git a/src/css/atoms/typography.scss b/src/css/atoms/typography.scss index d2c9c03a4..0be2dd585 100644 --- a/src/css/atoms/typography.scss +++ b/src/css/atoms/typography.scss @@ -4,7 +4,7 @@ font-style: normal; font-weight: 400; src: url('../fonts/Inter-Regular.woff2') format('woff2'), - url('../fonts/Inter-Regular.woff') format('woff'); + url('../fonts/Inter-Regular.woff') format('woff'); } @font-face { @@ -13,7 +13,7 @@ font-style: italic; font-weight: 400; src: url('../fonts/Inter-Italic.woff2') format('woff2'), - url('../fonts/Inter-Italic.woff') format('woff'); + url('../fonts/Inter-Italic.woff') format('woff'); } @font-face { @@ -22,7 +22,7 @@ font-style: normal; font-weight: 700; src: url('../fonts/Inter-Bold.woff2') format('woff2'), - url('../fonts/Inter-Bold.woff') format('woff'); + url('../fonts/Inter-Bold.woff') format('woff'); } @font-face { @@ -31,7 +31,7 @@ font-style: italic; font-weight: 700; src: url('../fonts/Inter-BoldItalic.woff2') format('woff2'), - url('../fonts/Inter-BoldItalic.woff') format('woff'); + url('../fonts/Inter-BoldItalic.woff') format('woff'); } @font-face { @@ -40,7 +40,7 @@ font-style: normal; font-weight: 400; src: url('../fonts/ZillaSlab-Regular.woff2') format('woff2'), - url('../fonts/ZillaSlab-Regular.woff') format('woff'); + url('../fonts/ZillaSlab-Regular.woff') format('woff'); } @font-face { @@ -49,7 +49,7 @@ font-style: normal; font-weight: 600; src: url('../fonts/ZillaSlab-SemiBold.woff2') format('woff2'), - url('../fonts/ZillaSlab-SemiBold.woff') format('woff'); + url('../fonts/ZillaSlab-SemiBold.woff') format('woff'); } @font-face { @@ -58,7 +58,7 @@ font-style: bold; font-weight: 700; src: url('../fonts/ZillaSlab-Bold.woff2') format('woff2'), - url('../fonts/ZillaSlab-Bold.woff') format('woff'); + url('../fonts/ZillaSlab-Bold.woff') format('woff'); } @font-face { @@ -67,7 +67,7 @@ font-style: normal; font-weight: 400; src: url('../fonts/ZillaSlabHighlight-Regular.woff2') format('woff2'), - url('../fonts/ZillaSlabHighlight-Regular.woff') format('woff'); + url('../fonts/ZillaSlabHighlight-Regular.woff') format('woff'); } @font-face { @@ -76,7 +76,7 @@ font-style: bold; font-weight: 700; src: url('../fonts/ZillaSlabHighlight-Bold.woff2') format('woff2'), - url('../fonts/ZillaSlabHighlight-Bold.woff') format('woff'); + url('../fonts/ZillaSlabHighlight-Bold.woff') format('woff'); } html { @@ -121,7 +121,13 @@ h4, h5, h6 { &:not(.no-underline) { - background: repeating-linear-gradient(to bottom, transparent 0, transparent .8em, transparentize($color-yellow-30, .5) .8em, transparentize($color-yellow-30, .5) 1.1em); + background: repeating-linear-gradient( + to bottom, + transparent 0, + transparent 0.8em, + transparentize($color-yellow-30, 0.5) 0.8em, + transparentize($color-yellow-30, 0.5) 1.1em + ); display: inline; margin-bottom: 0; @@ -143,7 +149,13 @@ h6 { } .underline { - background: repeating-linear-gradient(to bottom, transparent 0, transparent .8em, transparentize($color-yellow-30, .5) .8em, transparentize($color-yellow-30, .5) 1.1em); + background: repeating-linear-gradient( + to bottom, + transparent 0, + transparent 0.8em, + transparentize($color-yellow-30, 0.5) 0.8em, + transparentize($color-yellow-30, 0.5) 1.1em + ); display: inline; &:before { diff --git a/src/css/global/base.scss b/src/css/global/base.scss index b304c37c7..cea097ee0 100644 --- a/src/css/global/base.scss +++ b/src/css/global/base.scss @@ -49,7 +49,7 @@ body { } &:active { - background-color: rgba(0, 0, 0, .05); + background-color: rgba(0, 0, 0, 0.05); } } diff --git a/src/css/global/variables.scss b/src/css/global/variables.scss index 8b9491cae..d92b9b611 100644 --- a/src/css/global/variables.scss +++ b/src/css/global/variables.scss @@ -24,7 +24,8 @@ $h5-font-size-mobile: 20px; $h5-font-size: 18px; $h6-font-size: 16px; -$monospace-font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; +$monospace-font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', + monospace; $highlight-font-size: 18px; $highlight-font-size-mobile: 16px; @@ -46,4 +47,4 @@ $color-moz-link-visited: $color-blue-70; $color-mdn-background: #c2e8f9; -$color-tag-background: #f2f7fd +$color-tag-background: #f2f7fd; diff --git a/src/css/molecules/card-event.scss b/src/css/molecules/card-event.scss index 1b6c968d9..33ced6980 100644 --- a/src/css/molecules/card-event.scss +++ b/src/css/molecules/card-event.scss @@ -50,7 +50,7 @@ border-left-color: transparent; border-top-color: transparent; bottom: -14px; - content: ""; + content: ''; display: block; height: 0px; left: -14px; diff --git a/src/css/molecules/card-topic.scss b/src/css/molecules/card-topic.scss index 1cdee44fc..f2dfc9217 100644 --- a/src/css/molecules/card-topic.scss +++ b/src/css/molecules/card-topic.scss @@ -22,7 +22,11 @@ } .pattern::before { - background: linear-gradient(90deg, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 100%); + background: linear-gradient( + 90deg, + rgba(0, 0, 0, 1) 0%, + rgba(0, 0, 0, 0) 100% + ); } } diff --git a/src/css/molecules/card.scss b/src/css/molecules/card.scss index 0488aac0d..a3e287444 100644 --- a/src/css/molecules/card.scss +++ b/src/css/molecules/card.scss @@ -13,7 +13,6 @@ grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); } - .card-container-people { align-items: center; display: flex; diff --git a/src/css/molecules/content-hero.scss b/src/css/molecules/content-hero.scss index 41113d04c..603c56f1a 100644 --- a/src/css/molecules/content-hero.scss +++ b/src/css/molecules/content-hero.scss @@ -20,10 +20,10 @@ &::after { background-color: $color-black; - content: ""; + content: ''; height: 100%; left: 0; - opacity: .2; + opacity: 0.2; position: absolute; top: 0; width: 100%; diff --git a/src/css/molecules/item-get-started.scss b/src/css/molecules/item-get-started.scss index f52e024cd..10cc04b1d 100644 --- a/src/css/molecules/item-get-started.scss +++ b/src/css/molecules/item-get-started.scss @@ -13,7 +13,7 @@ display: inline-block; font-weight: normal; } - + p, a { color: $color-green-40; diff --git a/src/css/molecules/resource-topic-tags.scss b/src/css/molecules/resource-topic-tags.scss index 775e6a6cf..0127f2461 100644 --- a/src/css/molecules/resource-topic-tags.scss +++ b/src/css/molecules/resource-topic-tags.scss @@ -7,7 +7,7 @@ .resource-topic-tag a { background-color: $color-tag-background; border: 1px solid; - border-radius: .2em; + border-radius: 0.2em; display: block; font-weight: bold; margin-bottom: 16px; diff --git a/src/css/organisms/article-header.scss b/src/css/organisms/article-header.scss index 4dd9bf1c4..7dd318d38 100644 --- a/src/css/organisms/article-header.scss +++ b/src/css/organisms/article-header.scss @@ -100,6 +100,10 @@ } .pattern::before { - background: linear-gradient(90deg, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 100%); + background: linear-gradient( + 90deg, + rgba(0, 0, 0, 1) 0%, + rgba(0, 0, 0, 0) 100% + ); } } diff --git a/src/css/organisms/filter-list.scss b/src/css/organisms/filter-list.scss index 4a46514cc..48c48217a 100644 --- a/src/css/organisms/filter-list.scss +++ b/src/css/organisms/filter-list.scss @@ -5,7 +5,9 @@ @media #{$mq-md} { column-gap: $grid-gap; - grid-template-columns: [sidebar-start] repeat(4, 1fr) [sidebar-end items-start] repeat(8, 1fr) [items-end]; + grid-template-columns: + [sidebar-start] repeat(4, 1fr) [sidebar-end items-start] repeat(8, 1fr) + [items-end]; html.no-js & { grid-template-columns: [items-start] 1fr [items-end]; diff --git a/src/css/organisms/homepage-header.scss b/src/css/organisms/homepage-header.scss index 22c1f4042..e91758bdc 100644 --- a/src/css/organisms/homepage-header.scss +++ b/src/css/organisms/homepage-header.scss @@ -1,5 +1,6 @@ .homepage-header { - background: url('/static/img/homepage-header-pattern.svg') $color-black calc(50% + 400px) no-repeat; + background: url('/static/img/homepage-header-pattern.svg') $color-black + calc(50% + 400px) no-repeat; color: $color-white; margin-top: -1px; // Overlap the navigation border. padding: 0; diff --git a/src/css/organisms/newsletter-signup.scss b/src/css/organisms/newsletter-signup.scss index a9904afa5..b40b1047a 100644 --- a/src/css/organisms/newsletter-signup.scss +++ b/src/css/organisms/newsletter-signup.scss @@ -1,5 +1,6 @@ .newsletter-signup { - background: top center no-repeat url('../img/newsletter-background.svg') $color-black; + background: top center no-repeat url('../img/newsletter-background.svg') + $color-black; color: $color-white; padding: 140px 0 100px; text-align: center; @@ -15,7 +16,7 @@ margin-right: 4px; } - input[type=email] { + input[type='email'] { display: inline-block; } diff --git a/src/css/organisms/pattern-bg-header.scss b/src/css/organisms/pattern-bg-header.scss index 7ecedb8a8..c5c9704d2 100644 --- a/src/css/organisms/pattern-bg-header.scss +++ b/src/css/organisms/pattern-bg-header.scss @@ -13,10 +13,18 @@ z-index: -1; &::before { - background: linear-gradient(90deg, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0) 100%); + background: linear-gradient( + 90deg, + rgba(0, 0, 0, 1) 50%, + rgba(0, 0, 0, 0) 100% + ); @media #{$mq-md} { - background: linear-gradient(90deg, rgba(0, 0, 0, 1) calc(50% + #{$container-max-width / 4}), rgba(0, 0, 0, 0) 100%); + background: linear-gradient( + 90deg, + rgba(0, 0, 0, 1) calc(50% + #{$container-max-width / 4}), + rgba(0, 0, 0, 0) 100% + ); } } } diff --git a/src/css/organisms/tabbed-panels.scss b/src/css/organisms/tabbed-panels.scss index 510cd3dcd..8d0a288b0 100644 --- a/src/css/organisms/tabbed-panels.scss +++ b/src/css/organisms/tabbed-panels.scss @@ -1,4 +1,3 @@ - .tabbed-panels-mobile { display: block; @media #{$mq-md} { @@ -59,7 +58,7 @@ display: none; background-color: $color-gray-20; height: 316px; - margin-top: 32px + margin-top: 32px; } .tabbed-panels-content { @@ -112,7 +111,7 @@ margin-bottom: 2px; position: relative; text-align: center; - transition: background-position-x .1s ease-in; + transition: background-position-x 0.1s ease-in; @media (prefers-reduced-motion: reduce) { transition: none; @@ -124,16 +123,16 @@ } &.highlight2 { - background-image: url($image-path + '/icons/ui/arrow-left-black.svg'); + background-image: url($image-path+'/icons/ui/arrow-left-black.svg'); } &.highlight2-inverse { - background-image: url($image-path + '/icons/ui/arrow-left-white.svg'); + background-image: url($image-path+'/icons/ui/arrow-left-white.svg'); } &:hover { background-color: $color-white; - background-image: url($image-path + '/icons/ui/arrow-left-black.svg'); + background-image: url($image-path+'/icons/ui/arrow-left-black.svg'); background-position-x: calc(24px - 6px); color: $color-black; diff --git a/src/css/templates/article.scss b/src/css/templates/article.scss index e63698664..40a24e1a4 100644 --- a/src/css/templates/article.scss +++ b/src/css/templates/article.scss @@ -6,7 +6,9 @@ @media #{$mq-md} { column-gap: $grid-gap; - grid-template-columns: [body-start] repeat(8, 1fr) [body-end sidebar-start] repeat(4, 1fr) [sidebar-end]; + grid-template-columns: + [body-start] repeat(8, 1fr) [body-end sidebar-start] repeat(4, 1fr) + [sidebar-end]; } } From 9141a7527eef04da364c4a8ecbe79c31a457e6c2 Mon Sep 17 00:00:00 2001 From: Steve Jalim Date: Tue, 17 Sep 2019 14:00:20 +0100 Subject: [PATCH 5/7] 135: Tune prettier and eslint's ignore options Specifically: - prettier: ignore HTML, SVG, JSON and Python - eslint: ignore HTML, SVG and Python While this wouldn't be needed for editor-based formatting or linting, nor linting explicitly staged/passed files, this change is so that when we _do_ run them across the entire `developerportal` module (eg, in CI), they won't gripe about things they are not intented to be looking at anyway. --- .eslintignore | 4 ++++ .prettierignore | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/.eslintignore b/.eslintignore index 2fcd350d9..501eac2af 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,6 @@ dist *.scss +*.py +*.pyc +*.html +*.svg diff --git a/.prettierignore b/.prettierignore index 1521c8b76..3d166ecd7 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,6 @@ dist +*.py +*.pyc +*.html +*.svg +*.json From d58fdd720be138b65b1f87e2b05e55a7051f0832 Mon Sep 17 00:00:00 2001 From: Steve Jalim Date: Tue, 17 Sep 2019 14:34:58 +0100 Subject: [PATCH 6/7] 135: Add Therapist to the project, running the linters and formatters recently added/tweaked At this point, the assumption is you have the following installed on your host: * black * flake8 * eslint and eslint-config-prettier * isort * prettier (I'll deal with making that easier in a different commit.) Install `therapist` (https://github.com/rehandalal/therapist): $ pip install therapist Now install the pre-commit hook that will trigger Therapist automatically: $ therapist install Installing pre-commit hook... DONE Now, when you commit a change, the staged changes will be checked by one or more of black, isort, eslint and prettier, as appropriate. See `.therapist.yml` for the configuration. Alternatively, if you wanted to run it across the whole codebase (as we might well do in CI), run: $ therapist run developerportal/ black ............................................................... [SUCCESS] ESLint .............................................................. [SKIPPED] flake8 .............................................................. [SUCCESS] isort ............................................................... [SUCCESS] Prettier ............................................................ [SUCCESS] ------------------------------------------------------------------------------- Completed in: 3.67s And if you want therapist to auto-fix things using black, prettier and/or eslint, run: $ therapist run developerportal --fix --- .therapist.yml | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .therapist.yml diff --git a/.therapist.yml b/.therapist.yml new file mode 100644 index 000000000..9ebd94259 --- /dev/null +++ b/.therapist.yml @@ -0,0 +1,42 @@ +actions: + # Python linting and formatting + isort: + run: isort --check {files} + fix: isort --apply {files} + include: '*.py' + exclude: + - 'node_modules' + - 'migrations' + flake8: + run: flake8 {files} + include: '*.py' + exclude: + - 'node_modules' + - 'migrations' + black: + run: black {files} + include: '*.py' + exclude: + - 'node_modules' + - 'migrations' + - '*.pyc' + + # JS linting + eslint: + description: ESLint + run: $(npm bin)/eslint {files} + fix: $(npm bin)/eslint --fix {files} + exclude: + - '*.html' + - '*.md' + - '*.py' + - '*.pyc' + - '*.scss' + - '*.svg' + - 'developerportal/apps/common/fixtures/common.json' + + # JS and SCSS autoformatting + prettier: + description: Prettier + run: $(npm bin)/prettier -c {files} + fix: $(npm bin)/prettier --write {files} From f064d0041bc40159a54b2e13be4f3aaed17fe0a4 Mon Sep 17 00:00:00 2001 From: Steve Jalim Date: Tue, 17 Sep 2019 18:52:49 +0100 Subject: [PATCH 7/7] 135: Update Readme to mention how to set up and use `therapist` as a linter/formatter runner --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 08d6ed05d..3e2e31ee3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This project uses [Docker](https://www.docker.com/). The easiest way to get started is to install [Docker Desktop](https://hub.docker.com/search?q=Docker%20Desktop&type=edition&offering=community) which provides the `docker` and `docker-compose` commands. -After installing Docker, use the __dev-setup__ script to run the project locally: +After installing Docker, use the **dev-setup** script to run the project locally: ```shell ./scripts/dev-setup @@ -36,9 +36,54 @@ docker-compose exec app python manage.py makemigrations docker-compose exec app python manage.py migrate ``` +### Linting and autoformatting with (or without) a pre-commit hook + +The project has support for using [Therapist](https://github.com/rehandalal/therapist) to run pre-commit linting and formatting tools. You don't _have_ to use it, but it makes it life easier. + +`therapist` is configured to run: + +- [black](https://github.com/psf/black) for code formatting +- [flake8](http://flake8.pycqa.org/en/latest/) for syntax checking +- [isort](https://github.com/timothycrosley/isort/) for import-order management +- [eslint](https://eslint.org/) for JavaScript checking +- [prettier](https://prettier.io/) for JavaScript formatting + +At the moment, this project assumes have all of the above installed and available on the `$PATH` of your _host_ machine, along with Python 3 and `pip`. You can install the dependencies using `virtualenv` and `nvm` if you want, or not, or globally. As long as they're available, you're good. + +(Note: this project is not currently supporting use of `therapist` inside Docker containers.) + +**TIP: It's wise to enable all of the above tooling in your code editor, if possible, so that things are already in order before the pre-commit hook is run.** + +#### `therapist` setup and usage + +Install `therapist` : + + $ pip install therapist + +Install the pre-commit hook that will trigger `therapist` automatically: + + $ therapist install + Installing pre-commit hook... DONE + +(Take a look at the pre-commit file added to `.git/hooks/` to confirm the path looks right.) + +Now, when you `git-commit` a change, the _staged_ changes will be checked by one or more of `black`, `isort`, `flake8`, `eslint` and/or `prettier`. See `.therapist.yml` in the project root for the configuration. + +Alternatively, if you wanted to run it across the whole codebase, run: + + $ therapist run developerportal/ + +And if, for some reason, you want `therapist` to auto-fix everything wrong using those tools, run: + + $ therapist run developerportal/ --fix + +Finally, `therapist` can be passed a list of file paths if you want to just run it on specific things: + + $ therapist run developerportal/path/to/file.js developerportal/path/to/another_file.py + ### User authentication -GitHub OAuth is supported for admin login. When running in production, the auth pipeline checks to see if the GitHub user is a member of the __mdn__ organization. Additional organizations can be added via the `GITHUB_ORGS` env variable. +GitHub OAuth is supported for admin login. When running in production, the auth pipeline checks to see if the GitHub user is a member of the **mdn** organization. Additional organizations can be added via the `GITHUB_ORGS` env variable. When running in debug any GitHub user is allowed to log in and is automatically given superuser status. It is possible to log in without using GitHub by creating a Django superuser as normal: