Skip to content

Commit

Permalink
Merge pull request #1273 from devinit/feature/update-data-section-pag…
Browse files Browse the repository at this point in the history
…e-content

Feature | Add Charts to Data Section Page Tools
  • Loading branch information
edwinmp authored Dec 7, 2022
2 parents d172643 + 5928790 commit e621b16
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 58 deletions.
24 changes: 24 additions & 0 deletions di_website/blog/migrations/0043_alter_blogarticlepage_body.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.2.16 on 2022-12-05 17:46

from django.db import migrations
import wagtail.blocks
import wagtail.contrib.table_block.blocks
import wagtail.embeds.blocks
import wagtail.fields
import wagtail.images.blocks
import wagtail.snippets.blocks


class Migration(migrations.Migration):

dependencies = [
('blog', '0042_auto_20221007_1012'),
]

operations = [
migrations.AlterField(
model_name='blogarticlepage',
name='body',
field=wagtail.fields.StreamField([('anchor', wagtail.blocks.StructBlock([('anchor_id', wagtail.blocks.CharBlock(help_text='The unique indentifier for this anchor', required=True))])), ('paragraph_block', wagtail.blocks.RichTextBlock(features=['h2', 'h3', 'h4', 'bold', 'italic', 'ol', 'ul', 'hr', 'link', 'document-link', 'image', 'embed', 'anchor', 'footnote'], icon='fa-paragraph', template='blocks/paragraph_block_footnote.html')), ('block_quote', wagtail.blocks.StructBlock([('text', wagtail.blocks.TextBlock()), ('source', wagtail.blocks.TextBlock(help_text='Who is this quote acredited to?', required=False))])), ('button_block', wagtail.blocks.StructBlock([('caption', wagtail.blocks.CharBlock(help_text='Leave blank if you wish to use the page title as a caption', required=False)), ('page', wagtail.blocks.PageChooserBlock(help_text='For the link/button to show, either this or the url are required', required=False)), ('url', wagtail.blocks.URLBlock(help_text='An alternative to an internal page', required=False))])), ('link_block', wagtail.blocks.StructBlock([('caption', wagtail.blocks.CharBlock(help_text='Leave blank if you wish to use the page title as a caption', required=False)), ('page', wagtail.blocks.PageChooserBlock(help_text='For the link/button to show, either this or the url are required', required=False)), ('url', wagtail.blocks.URLBlock(help_text='An alternative to an internal page', required=False))])), ('image', wagtail.blocks.StructBlock([('image', wagtail.images.blocks.ImageChooserBlock(required=True)), ('credit_name', wagtail.blocks.CharBlock(help_text='Name of the image source', required=False)), ('credit_url', wagtail.blocks.URLBlock(help_text='URL of the image source', required=False)), ('caption', wagtail.blocks.CharBlock(help_text='Caption to appear beneath the image', required=False))])), ('video', wagtail.embeds.blocks.EmbedBlock(help_text='Insert an embed URL e.g https://www.youtube.com/embed/SGJFWirQ3ks', icon='fa-video-camera', required=False, template='blocks/embed_block.html')), ('infographic', wagtail.blocks.StructBlock([('heading', wagtail.blocks.CharBlock(help_text='Optional: heading for the infographic', required=False)), ('descriptive_text', wagtail.blocks.RichTextBlock(features=['footnote'], help_text='Optional: descriptive text to appear above the image or table', required=False)), ('images', wagtail.blocks.StreamBlock([('image_wide', wagtail.blocks.StructBlock([('wide', wagtail.images.blocks.ImageChooserBlock(help_text='Optimal minimum width 2400px'))], form_template='publications/block_forms/custom_struct.html', help_text='<b>Note:</b> infographics always require a wide image. Medium and narrow images are optional.', icon='image', label='Wide')), ('image_medium', wagtail.blocks.StructBlock([('medium', wagtail.images.blocks.ImageChooserBlock(help_text='Optional: optimal minimum width 1560px', required=False)), ('use_wide_image', wagtail.blocks.BooleanBlock(help_text='Optional: check this box to display the wide image at medium viewport sizes', required=False))], icon='image', label='Medium')), ('image_narrow', wagtail.blocks.StructBlock([('narrow', wagtail.images.blocks.ImageChooserBlock(help_text='Optional: optimal minimum width 1000px', required=False)), ('use_next_widest_image', wagtail.blocks.BooleanBlock(help_text='Optional: check this box to display the next widest image at narrow viewport sizes (if available)', required=False))], icon='image', label='Narrow'))], block_counts={'image_medium': {'max_num': 1}, 'image_narrow': {'max_num': 1}, 'image_wide': {'max_num': 1, 'min_num': 1}}, max_num=3, min_num=1)), ('data', wagtail.blocks.StreamBlock([('long_description', wagtail.blocks.StructBlock([('long_description', wagtail.blocks.TextBlock(help_text='Infographics require a long description and/or tabular data'))], icon='bold', label='Long desc')), ('table', wagtail.blocks.StructBlock([('table', wagtail.contrib.table_block.blocks.TableBlock(help_text='Infographics require a long description and/or tabular data'))], icon='list-ol', label='Table'))], block_counts={'long_description': {'max_num': 1}, 'table': {'max_num': 1}}, max_num=2, min_num=1)), ('caption', wagtail.blocks.RichTextBlock(features=['footnote'], help_text='Optional: caption text to appear below the image or table', required=False)), ('caption_link', wagtail.blocks.URLBlock(help_text='Optional: external link to appear below the image or table', required=False)), ('caption_label', wagtail.blocks.CharBlock(help_text='Optional: label for the caption link, defaults to the link if left blank', required=False)), ('downloads', wagtail.blocks.ListBlock(wagtail.snippets.blocks.SnippetChooserBlock('downloads.PublicationDownload', required=False), help_text='Optional: list of downloads to appear below the image or table'))])), ('cta', wagtail.blocks.StructBlock([('title', wagtail.blocks.CharBlock(label='Title', required=True)), ('body', wagtail.blocks.TextBlock(help_text='Optional: describe the purpose of your call to action in a bit more detail', label='Description', required=False)), ('button_text', wagtail.blocks.CharBlock(help_text='Optional: this is required to show the button', label='Button Caption', required=False)), ('button_url', wagtail.blocks.URLBlock(help_text='Optional: this is required to show the button', label='Button URL', required=False)), ('button_page', wagtail.blocks.PageChooserBlock(help_text='Optional: has priority over the button URL field', label='Button Page', required=False))])), ('table', wagtail.blocks.StructBlock([('heading', wagtail.blocks.CharBlock(required=False)), ('table', wagtail.contrib.table_block.blocks.TableBlock()), ('caption', wagtail.blocks.RichTextBlock(features=['footnote'], help_text='Optional: caption text to appear below the table', required=False)), ('caption_link', wagtail.blocks.URLBlock(help_text='Optional: external link to appear below the table', required=False)), ('caption_label', wagtail.blocks.CharBlock(help_text='Optional: label for the caption link, defaults to the link if left blank', required=False))]))], blank=True, null=True, use_json_field=True, verbose_name='Page Body'),
),
]
27 changes: 0 additions & 27 deletions di_website/custom_middleware.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
from django.conf import settings
from django.core.cache import cache
from django.http import HttpResponseRedirect
from django.utils.log import AdminEmailHandler


class NullInjectionMiddleware:
Expand All @@ -23,27 +20,3 @@ def __call__(self, request):
# the view is called.

return response


class ThrottledAdminEmailHandler(AdminEmailHandler):

PERIOD_LENGTH_IN_SECONDS = getattr(settings, 'EMAIL_ADMINS_CACHE_TIMEOUT', 10)
MAX_EMAILS_IN_PERIOD = getattr(settings, 'EMAIL_ADMINS_MAX_EMAILS_PER_TIMEOUT', 1)
COUNTER_CACHE_KEY = getattr(settings, 'EMAIL_ADMINS_CACHE_COUNTER_KEY', 'email_admins_cache_counter_key')

def increment_counter(self):
try:
cache.incr(self.COUNTER_CACHE_KEY)
except ValueError:
cache.set(self.COUNTER_CACHE_KEY, 1, self.PERIOD_LENGTH_IN_SECONDS)
return cache.get(self.COUNTER_CACHE_KEY)

def emit(self, record):
try:
counter = self.increment_counter()
except Exception:
pass
else:
if counter > self.MAX_EMAILS_IN_PERIOD:
return
super().emit(record)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.16 on 2022-12-05 17:46

from django.db import migrations
import wagtail.blocks
import wagtail.documents.blocks
import wagtail.embeds.blocks
import wagtail.fields
import wagtail.images.blocks


class Migration(migrations.Migration):

dependencies = [
('datasection', '0048_auto_20221012_1214'),
]

operations = [
migrations.AlterField(
model_name='datasectionpage',
name='tools',
field=wagtail.fields.StreamField([('tool', wagtail.blocks.StructBlock([('image', wagtail.images.blocks.ImageChooserBlock(required=False)), ('image_credit_name', wagtail.blocks.TextBlock(help_text='The name of the image source', required=False)), ('image_credit_url', wagtail.blocks.URLBlock(help_text='A link to the image source, if any', required=False)), ('video', wagtail.embeds.blocks.EmbedBlock(help_text='Insert an embed URL e.g https://www.youtube.com/embed/SGJFWirQ3ks', icon='fa-video-camera', required=False, template='blocks/embed_block.html')), ('text', wagtail.blocks.StreamBlock([('text_heading', wagtail.blocks.CharBlock(icon='title', required=False, template='blocks/banner/text_heading.html')), ('text', wagtail.blocks.TextBlock(template='blocks/banner/text.html')), ('richtext', wagtail.blocks.RichTextBlock(features=['h2', 'h3', 'h4', 'bold', 'italic', 'ol', 'ul', 'hr', 'link', 'document-link', 'image', 'embed', 'anchor'], template='blocks/banner/richtext.html')), ('list', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock(help_text='An optional title to the list item', required=False)), ('content', wagtail.blocks.TextBlock(help_text='The list item content', required=True))], template='blocks/banner/list_item.html'), icon='list-ul', template='blocks/banner/list.html'))])), ('meta', wagtail.blocks.CharBlock(help_text='Anything from a name, location e.t.c - usually to provide credit for the text', required=False)), ('buttons', wagtail.blocks.StreamBlock([('button', wagtail.blocks.StructBlock([('caption', wagtail.blocks.CharBlock(help_text='Leave blank if you wish to use the page title as a caption', required=False)), ('page', wagtail.blocks.PageChooserBlock(help_text='For the link/button to show, either this or the url are required', required=False)), ('url', wagtail.blocks.URLBlock(help_text='An alternative to an internal page', required=False))])), ('document_box', wagtail.blocks.StructBlock([('box_heading', wagtail.blocks.CharBlock(icon='title', required=False)), ('documents', wagtail.blocks.StreamBlock([('document', wagtail.documents.blocks.DocumentChooserBlock())], required=False)), ('dark_mode', wagtail.blocks.BooleanBlock(default=False, help_text='Red on white if unchecked. White on dark grey if checked.', required=False))]))], required=False)), ('media_orientation', wagtail.blocks.ChoiceBlock(choices=[('left', 'Left'), ('right', 'Right')], required=False)), ('light', wagtail.blocks.BooleanBlock(default=False, help_text='Sets the background to a lighter colour', required=False))], template='datasection/tools_banner_block.html')), ('advanced_interactive_chart', wagtail.blocks.StructBlock([('show_title', wagtail.blocks.BooleanBlock(default=True, required=False)), ('allow_share', wagtail.blocks.BooleanBlock(default=True, required=False)), ('chart_page', wagtail.blocks.PageChooserBlock(page_type=['visualisation.AdvancedChartPage', 'visualisation.RawCodePage']))], template='datasection/interactive_chart.html'))], blank=True, null=True, use_json_field=True, verbose_name='Tools'),
),
]
6 changes: 5 additions & 1 deletion di_website/datasection/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from di_website.common.constants import MAX_PAGE_SIZE, MAX_RELATED_LINKS, RICHTEXT_FEATURES_NO_FOOTNOTES
from di_website.common.mixins import HeroMixin, OtherPageMixin, SectionBodyMixin, TypesetBodyMixin
from di_website.common.blocks import BannerBlock
from di_website.publications.fields import AdvancedInteractiveChartBlock
from di_website.publications.models import Country
from di_website.downloads.models import BaseDownload

Expand Down Expand Up @@ -156,7 +157,10 @@ class DataSectionPage(TypesetBodyMixin, HeroMixin, Page):
help_text='A description of the datasets',
features=RICHTEXT_FEATURES_NO_FOOTNOTES)
tools = StreamField(
[('tool', BannerBlock(template='datasection/tools_banner_block.html'))],
[
('tool', BannerBlock(template='datasection/tools_banner_block.html')),
('advanced_interactive_chart', AdvancedInteractiveChartBlock(template='datasection/interactive_chart.html')),
],
verbose_name="Tools", null=True, blank=True, use_json_field=True)
other_pages_heading = models.CharField(
blank=True, max_length=255, verbose_name='Heading', default='More about')
Expand Down
27 changes: 27 additions & 0 deletions di_website/logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from django.conf import settings
from django.core.cache import cache
from django.utils.log import AdminEmailHandler


class ThrottledAdminEmailHandler(AdminEmailHandler):

PERIOD_LENGTH_IN_SECONDS = getattr(settings, 'EMAIL_ADMINS_CACHE_TIMEOUT', 10)
MAX_EMAILS_IN_PERIOD = getattr(settings, 'EMAIL_ADMINS_MAX_EMAILS_PER_TIMEOUT', 1)
COUNTER_CACHE_KEY = getattr(settings, 'EMAIL_ADMINS_CACHE_COUNTER_KEY', 'email_admins_cache_counter_key')

def increment_counter(self):
try:
cache.incr(self.COUNTER_CACHE_KEY)
except ValueError:
cache.set(self.COUNTER_CACHE_KEY, 1, self.PERIOD_LENGTH_IN_SECONDS)
return cache.get(self.COUNTER_CACHE_KEY)

def emit(self, record):
try:
counter = self.increment_counter()
except Exception:
pass
else:
if counter > self.MAX_EMAILS_IN_PERIOD:
return
super().emit(record)
Loading

0 comments on commit e621b16

Please sign in to comment.