Refactor articles model

This commit is contained in:
Gabriel Augendre 2021-01-03 21:51:46 +01:00
parent 4b224f0a1f
commit d59565fa82
No known key found for this signature in database
GPG key ID: 1E693F4CE4AEE7B4
3 changed files with 58 additions and 43 deletions

View file

@ -1,10 +1,7 @@
import random import random
import re
import uuid import uuid
from functools import cached_property, reduce from functools import cached_property, reduce
import html2text
import markdown
import readtime import readtime
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -12,39 +9,20 @@ from django.db import models
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from markdown.extensions.codehilite import CodeHiliteExtension
from articles.markdown import LazyLoadingImageExtension from articles.utils import (
from articles.utils import build_full_absolute_url build_full_absolute_url,
format_article_content,
get_html_to_text_converter,
truncate_words_after_char_count,
)
class User(AbstractUser): class User(AbstractUser):
pass pass
class AdminUrlMixin: class Article(models.Model):
def get_admin_url(self):
content_type = ContentType.objects.get_for_model(self.__class__)
return reverse(
"admin:%s_%s_change" % (content_type.app_label, content_type.model),
args=(self.id,),
)
def format_article_content(content):
md = markdown.Markdown(
extensions=[
"extra",
"admonition",
CodeHiliteExtension(linenums=False, guess_lang=False),
LazyLoadingImageExtension(),
]
)
content = re.sub(r"(\s)#(\w+)", r"\1\#\2", content)
return md.convert(content)
class Article(AdminUrlMixin, models.Model):
DRAFT = "draft" DRAFT = "draft"
PUBLISHED = "published" PUBLISHED = "published"
STATUS_CHOICES = [ STATUS_CHOICES = [
@ -82,20 +60,9 @@ class Article(AdminUrlMixin, models.Model):
@cached_property @cached_property
def get_description(self): def get_description(self):
html = self.get_formatted_content html = self.get_formatted_content
converter = html2text.HTML2Text() converter = get_html_to_text_converter()
converter.ignore_images = True
converter.ignore_links = True
converter.ignore_tables = True
converter.ignore_emphasis = True
text = converter.handle(html) text = converter.handle(html)
total_length = 0 return truncate_words_after_char_count(text, 160)
text_result = []
for word in text.split():
if len(word) + 1 + total_length > 160:
break
text_result.append(word)
total_length += len(word) + 1
return " ".join(text_result) + "..."
@cached_property @cached_property
def get_formatted_content(self): def get_formatted_content(self):
@ -165,3 +132,10 @@ class Article(AdminUrlMixin, models.Model):
css = self.custom_css.replace("\n", " ") css = self.custom_css.replace("\n", " ")
return reduce(reducer, css, "") return reduce(reducer, css, "")
def get_admin_url(self):
content_type = ContentType.objects.get_for_model(self.__class__)
return reverse(
"admin:%s_%s_change" % (content_type.app_label, content_type.model),
args=(self.id,),
)

View file

@ -2,7 +2,8 @@ import pytest
from django.test import Client from django.test import Client
from django.urls import reverse from django.urls import reverse
from articles.models import Article, format_article_content from articles.models import Article
from articles.utils import format_article_content
@pytest.mark.django_db @pytest.mark.django_db

View file

@ -1,4 +1,11 @@
import re
import html2text
import markdown
from django.conf import settings from django.conf import settings
from markdown.extensions.codehilite import CodeHiliteExtension
from articles.markdown import LazyLoadingImageExtension
def build_full_absolute_url(request, url): def build_full_absolute_url(request, url):
@ -6,3 +13,36 @@ def build_full_absolute_url(request, url):
return request.build_absolute_uri(url) return request.build_absolute_uri(url)
else: else:
return (settings.BLOG["base_url"] + url)[::-1].replace("//", "/", 1)[::-1] return (settings.BLOG["base_url"] + url)[::-1].replace("//", "/", 1)[::-1]
def format_article_content(content):
md = markdown.Markdown(
extensions=[
"extra",
"admonition",
CodeHiliteExtension(linenums=False, guess_lang=False),
LazyLoadingImageExtension(),
]
)
content = re.sub(r"(\s)#(\w+)", r"\1\#\2", content)
return md.convert(content)
def truncate_words_after_char_count(text, char_count):
total_length = 0
text_result = []
for word in text.split():
if len(word) + 1 + total_length > char_count:
break
text_result.append(word)
total_length += len(word) + 1
return " ".join(text_result) + "..."
def get_html_to_text_converter():
converter = html2text.HTML2Text()
converter.ignore_images = True
converter.ignore_links = True
converter.ignore_tables = True
converter.ignore_emphasis = True
return converter