picata 0.0.7__py3-none-any.whl → 0.0.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
picata/blocks.py CHANGED
@@ -110,12 +110,13 @@ class CodeBlock(StructBlock):
110
110
  language = ChoiceBlock(
111
111
  required=False,
112
112
  choices=[
113
- ("python", "Python"),
114
- ("javascript", "JavaScript"),
115
- ("html", "HTML"),
116
- ("css", "CSS"),
117
- ("bash", "Bash"),
118
113
  ("plaintext", "Plain Text"),
114
+ ("bash", "Bash"),
115
+ ("css", "CSS"),
116
+ ("html", "HTML"),
117
+ ("javascript", "JavaScript"),
118
+ ("python", "Python"),
119
+ ("toml", "TOML"),
119
120
  ],
120
121
  help_text=None,
121
122
  )
picata/helpers/wagtail.py CHANGED
@@ -53,7 +53,7 @@ def filter_pages_by_type(pages: list[Page], page_type_slugs: set[str]) -> list[P
53
53
  return filtered_pages
54
54
 
55
55
 
56
- def page_preview_data(request: HttpRequest, page: Page) -> dict[str, str]:
56
+ def page_preview_data(page: Page, request: HttpRequest | None) -> dict[str, str]:
57
57
  """Return a dictionary of available publication and preview data for a page."""
58
58
  page_data = getattr(page, "preview_data", {}).copy()
59
59
  if hasattr(page, "get_publication_data"):
picata/models.py CHANGED
@@ -110,7 +110,7 @@ class BasePage(Page):
110
110
  from picata.helpers.wagtail import page_preview_data
111
111
 
112
112
  context = super().get_context(request, *args, **kwargs)
113
- context.update(page_preview_data(request, self))
113
+ context.update(page_preview_data(self, request))
114
114
  return cast(BasePageContext, {**context})
115
115
 
116
116
  class Meta:
@@ -472,7 +472,7 @@ class HomePage(BasePage):
472
472
  from picata.helpers.wagtail import page_preview_data
473
473
 
474
474
  recent_posts = Article.objects.live_for_user(request.user).by_date()
475
- recent_posts = [page_preview_data(request, post) for post in recent_posts]
475
+ recent_posts = [page_preview_data(post, request) for post in recent_posts]
476
476
 
477
477
  return cast(
478
478
  HomePageContext,
picata/urls.py CHANGED
@@ -10,7 +10,7 @@ from wagtail.contrib.sitemaps.views import sitemap
10
10
  from wagtail.documents import urls as wagtaildocs_urls
11
11
  from wagtail.images.views.serve import ServeView
12
12
 
13
- from picata.views import search
13
+ from picata.views import AtomArticleFeed, RSSArticleFeed, search
14
14
 
15
15
  urlpatterns = [
16
16
  path("django-admin/", admin.site.urls), # Django Admin
@@ -20,6 +20,8 @@ urlpatterns = [
20
20
  r"^images/([^/]*)/(\d*)/([^/]*)/[^/]*$", ServeView.as_view(), name="wagtailimages_serve"
21
21
  ),
22
22
  path("sitemap.xml", sitemap),
23
+ path("feeds/rss/", RSSArticleFeed(), name="rss_feed"),
24
+ path("feeds/atom/", AtomArticleFeed(), name="atom_feed"),
23
25
  path("search/", search, name="search"),
24
26
  ]
25
27
 
picata/views.py CHANGED
@@ -4,10 +4,13 @@
4
4
  # pyright: reportAttributeAccessIssue=false, reportArgumentType=false
5
5
 
6
6
  import logging
7
+ from datetime import datetime
7
8
  from typing import TYPE_CHECKING, NoReturn
8
9
 
10
+ from django.contrib.syndication.views import Feed
9
11
  from django.http import HttpRequest, HttpResponse
10
12
  from django.shortcuts import render
13
+ from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed
11
14
 
12
15
  from picata.helpers.wagtail import (
13
16
  filter_pages_by_tags,
@@ -15,7 +18,7 @@ from picata.helpers.wagtail import (
15
18
  page_preview_data,
16
19
  visible_pages_qs,
17
20
  )
18
- from picata.models import ArticleType
21
+ from picata.models import Article, ArticleType
19
22
 
20
23
  if TYPE_CHECKING:
21
24
  from wagtail.query import PageQuerySet
@@ -23,6 +26,54 @@ if TYPE_CHECKING:
23
26
  logger = logging.getLogger(__name__)
24
27
 
25
28
 
29
+ class PostsFeed(Feed):
30
+ """Base class for RSS and Atom article feeds."""
31
+
32
+ title = "hpk.io Articles"
33
+ link = "https://hpk.io/blog/"
34
+ description = "Latest posts on hpk.io"
35
+
36
+ def items(self) -> list[Article]:
37
+ """Return the latest 10 published articles."""
38
+ return list(Article.objects.live().order_by("-first_published_at"))
39
+
40
+ def item_title(self, item: Article) -> str:
41
+ """Return the article title."""
42
+ return item.title
43
+
44
+ def item_link(self, item: Article) -> str:
45
+ """Return the absolute URL for the article."""
46
+ return item.full_url
47
+
48
+ def item_description(self, item: Article) -> str:
49
+ """Return the article body as HTML with absolute URLs."""
50
+ return item.content
51
+
52
+ def item_pubdate(self, item: Article) -> datetime:
53
+ """Return the article creation date."""
54
+ return item.first_published_at
55
+
56
+ def item_updateddate(self, item: Article) -> datetime:
57
+ """Return the article creation date."""
58
+ return item.last_published_at
59
+
60
+ def item_author_name(self, item: Article) -> str:
61
+ """Return the name of the author."""
62
+ return "Ada Wright"
63
+
64
+
65
+ class RSSArticleFeed(PostsFeed):
66
+ """RSS feed for articles."""
67
+
68
+ feed_type = Rss201rev2Feed
69
+
70
+
71
+ class AtomArticleFeed(PostsFeed):
72
+ """Atom feed for articles."""
73
+
74
+ feed_type = Atom1Feed
75
+
76
+
26
77
  def debug_shell(request: HttpRequest) -> NoReturn:
27
78
  """Just `assert False`, to force an exception and get to the Werkzeug debug console."""
28
79
  logger.info(
@@ -76,6 +127,6 @@ def search(request: HttpRequest) -> HttpResponse:
76
127
  specific_pages = []
77
128
 
78
129
  # Enhance pages with preview and publication data
79
- page_previews = [page_preview_data(request, page) for page in specific_pages]
130
+ page_previews = [page_preview_data(page, request) for page in specific_pages]
80
131
 
81
132
  return render(request, "picata/search_results.html", {**results, "pages": page_previews})
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: picata
3
- Version: 0.0.7
3
+ Version: 0.0.8
4
4
  Summary: Ada's Wagtail-based CMS & blog
5
5
  Project-URL: Documentation, https://github.com/hipikat/picata#readme
6
6
  Project-URL: Issues, https://github.com/hipikat/picata/issues
@@ -808,18 +808,18 @@ styles.sass,sha256=SCG5WCr0jIGzdM_Vp_j_gKxFfcTsTwLWOmaEc6uMpvU,8501
808
808
  components/HelloWorld.tsx,sha256=Kp7gvhGehfrX1mw0jgr2_D6AueFgqgfMYGkyQgvWekg,180
809
809
  picata/__init__.py,sha256=ZCIoFQ_z3ias_sP4C77EU2IUJnyv4qR0xUdJ3PIdLLM,48
810
810
  picata/apps.py,sha256=kr6OBcYbBw9HCGG-PkoMTHR4QeyzJO8_KIWTljCTHRo,1255
811
- picata/blocks.py,sha256=xfFpyCL5djWmZBBrBPO1dTTAUjk3l0XLfu8qSPixejg,5303
811
+ picata/blocks.py,sha256=ivu3i9s5xfpB40yaCc50qkDu4H5u6XVuZ1qDqTZi6gk,5333
812
812
  picata/log_utils.py,sha256=BRdB3PqpFx1XAhIyAzIOyQKiqrjbT3PBmkhH6-wAWJg,1555
813
813
  picata/middleware.py,sha256=BbAifo--C4VYg1VhU8_qbdDcJUD9zYdbxU_9nqGpMa8,2067
814
- picata/models.py,sha256=0gEhUrdSKIkv76UqMej5VHE5VPJuNFPkA5fPCrEoCxM,15931
814
+ picata/models.py,sha256=Lv7BjW-RrsdV85Uvw_eo1DyiOAaqId1ew0o1wg4jYp0,15931
815
815
  picata/transformers.py,sha256=CBnbIX3dnFV_gfp4TDTMPA_jGD8V_E4onodxWqbsjyY,2212
816
- picata/urls.py,sha256=SAbmFKAgrM80LREULczs64hExbwmLOlsflXlo7qjzsc,1834
816
+ picata/urls.py,sha256=DlAOlkAeAHTCl4txY9rxtgc6vp822Ei2niiaiej29Sk,1988
817
817
  picata/validators.py,sha256=X4wdIxbCdmuU-gJv45ptTFB7kHR166jkSQBJiTzP3ZU,1517
818
- picata/views.py,sha256=N6RYLDOTHAGBv0cYxese3T0gOvI6C99_q_Lv-3zbjrc,2881
818
+ picata/views.py,sha256=8BugjOHI8OKYQ1_QKednKOFqai7yOhyGpTW6qs2dlYs,4401
819
819
  picata/wagtail_hooks.py,sha256=R1YgJwp_ZvYm65b_xvLS8HiBWxflXFXSB4SksbJxW3k,1500
820
820
  picata/wsgi.py,sha256=5vKFvebtHzxKb3BRVqps6SEKjWmOecBIkTwf4LqWJ0Q,398
821
821
  picata/helpers/__init__.py,sha256=acN445qKCuRVfInCEyCtx5W1BggloOSrawzdQ-c9m7s,2427
822
- picata/helpers/wagtail.py,sha256=ZJUqA31PBIu2lFtwfeEax3xu2UON0Yoa4cca79xdCc0,2111
822
+ picata/helpers/wagtail.py,sha256=89efaXwd7V63ds3c7w0ct6IDp63RrXCf4pGNW9dvhCI,2118
823
823
  picata/migrations/0001_initial.py,sha256=GnAiniyc1E9JsR-dYrEoVimvuIftazhfxEFCGJElKko,11943
824
824
  picata/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
825
825
  picata/settings/__init__.py,sha256=5qI40E9aCWsFanUxAnruZi1wXrad3oAwnusglycfPsk,47
@@ -870,7 +870,7 @@ picata/templatetags/tags/absolute_static.py,sha256=JNqNCMGIgiQDYdz44T5AB2l0yJTd_
870
870
  picata/templatetags/tags/menu_tags.py,sha256=PHuXl4QmIqycWilAyz1fjD_0uJxOSrCW7RnZxmR3Oh0,1860
871
871
  picata/typing/__init__.py,sha256=7qXco9cqvbveKX0Xprrc8DmgXa3MpkIQXtFsHDe77os,405
872
872
  picata/typing/wagtail.py,sha256=V0n9GYYb_CM5ic54lcRtpN6lhN37-QdRzz2mGKm3Cwc,664
873
- picata-0.0.7.dist-info/METADATA,sha256=dF5DTTG-fr0aXvynhdWykkneI_f6UQZRRRI5A1ojKJA,5092
874
- picata-0.0.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
875
- picata-0.0.7.dist-info/licenses/LICENSE.md,sha256=Bv8sMyZI5NI6DMrfiAvCwIFRLSfJkimLF2KVcUMteKU,1103
876
- picata-0.0.7.dist-info/RECORD,,
873
+ picata-0.0.8.dist-info/METADATA,sha256=o8vTsY31AgnFwniMIcgexAQOuePUfXmFFAZEbch5iJA,5092
874
+ picata-0.0.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
875
+ picata-0.0.8.dist-info/licenses/LICENSE.md,sha256=Bv8sMyZI5NI6DMrfiAvCwIFRLSfJkimLF2KVcUMteKU,1103
876
+ picata-0.0.8.dist-info/RECORD,,
File without changes