Add basic word count and reading time

This commit is contained in:
Jake Howard 2022-06-26 19:25:30 +01:00
parent 1a8821eaa8
commit 299a6342cc
Signed by: jake
GPG key ID: 57AFB45680EDD477
2 changed files with 28 additions and 5 deletions

View file

@ -1,3 +1,4 @@
import math
from typing import Any
from django.db import models
@ -8,7 +9,7 @@ from wagtail.fields import StreamField
from wagtail.images import get_image_model_string
from wagtail.models import Page
from .streamfield import get_blocks
from .streamfield import get_blocks, get_word_count
from .utils import TocEntry, get_table_of_contents
@ -53,11 +54,14 @@ class BaseContentMixin(models.Model):
@cached_property
def reading_time(self) -> int:
return 4
"""
https://help.medium.com/hc/en-us/articles/214991667-Read-time
"""
return int(math.ceil(self.word_count / 265))
@cached_property
def word_count(self) -> int:
return 1600
return get_word_count(self.body)
class ContentPage(BasePage, BaseContentMixin): # type: ignore[misc]

View file

@ -1,13 +1,18 @@
from typing import Iterator
from django.utils import lorem_ipsum
from django.utils.html import format_html_join
from django.utils.html import format_html_join, strip_tags
from django.utils.text import smart_split
from wagtail import blocks
from wagtail.embeds.blocks import EmbedBlock
IGNORE_WORDCOUNT_BLOCKS = (blocks.RawHTMLBlock, EmbedBlock)
class LoremBlock(blocks.StructBlock):
paragraphs = blocks.IntegerBlock(min_value=1)
def render(self, value: dict, context: dict) -> str:
def render(self, value: dict, context: dict | None = None) -> str:
return format_html_join(
"\n\n",
"<p>{}</p>",
@ -26,3 +31,17 @@ def get_blocks() -> list[tuple[str, blocks.BaseBlock]]:
("lorem", LoremBlock()),
("html", blocks.RawHTMLBlock()),
]
def get_plain_text(value: blocks.StreamValue) -> Iterator[str]:
for block in value:
if isinstance(block.block_type, IGNORE_WORDCOUNT_BLOCKS):
continue
yield strip_tags(str(block))
def get_word_count(value: blocks.StreamValue) -> int:
count = 0
for chunk in get_plain_text(value):
count += len(list(smart_split(chunk)))
return count