Skip to content

Commit 02b8894

Browse files
committed
Add an "author" resource type.
1 parent 1193d33 commit 02b8894

File tree

4 files changed

+73
-19
lines changed

4 files changed

+73
-19
lines changed

src/psc/gallery/authors/meg-1.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: Margaret
3+
---
4+
5+
An I.T. student.
6+
Currently focusing on programming with Python and learning Django development.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: Paul Everitt
3+
---
4+
5+
Python and Web Developer Advocate at @JetBrains for @PyCharm and @WebStormIDE.
6+
Python oldster, Zope/Plone/Pyramid mafia. Girls lacrosse, formerly running.

src/psc/resources.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
from psc.here import HERE
1818
from psc.here import PYODIDE
1919

20-
2120
EXCLUSIONS = ("pyscript.css", "pyscript.js", "favicon.png")
2221

2322

2423
def tag_filter(
25-
tag: Tag,
26-
exclusions: tuple[str, ...] = EXCLUSIONS,
24+
tag: Tag,
25+
exclusions: tuple[str, ...] = EXCLUSIONS,
2726
) -> bool:
2827
"""Filter nodes from example that should not get included."""
2928
attr = "href" if tag.name == "link" else "src"
@@ -113,6 +112,19 @@ def __post_init__(self) -> None:
113112
self.body = get_body_content(soup)
114113

115114

115+
@dataclass
116+
class Author(Resource):
117+
"""Information about an author, from Markdown."""
118+
119+
def __post_init__(self) -> None:
120+
"""Initialize the rest of the fields from the Markdown."""
121+
md_file = HERE / "gallery/authors" / f"{self.path}.md"
122+
md_fm = frontmatter.load(md_file)
123+
self.title = md_fm.get("title", "")
124+
md = MarkdownIt()
125+
self.body = str(md.render(md_fm.content))
126+
127+
116128
@dataclass
117129
class Page(Resource):
118130
"""A Markdown+frontmatter driven content page."""
@@ -153,27 +165,39 @@ def __post_init__(self) -> None:
153165
class Resources:
154166
"""Container for all resources in site."""
155167

168+
authors: dict[PurePath, Author] = field(default_factory=dict)
156169
examples: dict[PurePath, Example] = field(default_factory=dict)
157170
pages: dict[PurePath, Page] = field(default_factory=dict)
158171

159172

160-
def get_sorted_examples() -> list[PurePath]:
173+
def get_sorted_paths(target_dir: Path, only_dirs: bool = True) -> list[PurePath]:
161174
"""Return an alphabetized listing of the examples."""
162-
examples_dir = HERE / "gallery/examples"
163-
examples = [e for e in examples_dir.iterdir() if e.is_dir()]
164-
return sorted(examples, key=attrgetter("name"))
175+
if only_dirs:
176+
paths = [e for e in target_dir.iterdir() if e.is_dir()]
177+
else:
178+
paths = [e for e in target_dir.iterdir()]
179+
180+
return sorted(paths, key=attrgetter("name"))
165181

166182

167183
def get_resources() -> Resources:
168184
"""Factory to construct all the resources in the site."""
169185
resources = Resources()
170186

171187
# Load the examples
172-
for example in get_sorted_examples():
188+
examples = HERE / "gallery/examples"
189+
for example in get_sorted_paths(examples):
173190
this_path = PurePath(example.name)
174191
this_example = Example(path=this_path)
175192
resources.examples[this_path] = this_example
176193

194+
# Load the authors
195+
authors = HERE / "gallery/authors"
196+
for author in get_sorted_paths(authors, only_dirs=False):
197+
this_path = PurePath(author.stem)
198+
this_author = Author(path=this_path)
199+
resources.authors[this_path] = this_author
200+
177201
# Load the Pages
178202
pages_dir = HERE / "pages"
179203
pages = [e for e in pages_dir.iterdir()]

tests/test_resources.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
import pytest
66
from bs4 import BeautifulSoup
77

8-
from psc.resources import Example
8+
from psc.here import HERE
9+
from psc.resources import Example, Resources
910
from psc.resources import Page
1011
from psc.resources import get_body_content
1112
from psc.resources import get_head_nodes
1213
from psc.resources import get_resources
13-
from psc.resources import get_sorted_examples
14+
from psc.resources import get_sorted_paths
1415
from psc.resources import is_local
1516
from psc.resources import tag_filter
1617

17-
1818
IS_LOCAL = is_local()
1919

2020

@@ -30,6 +30,11 @@ def head_soup() -> BeautifulSoup:
3030
return BeautifulSoup(head, "html5lib")
3131

3232

33+
@pytest.fixture(scope="module")
34+
def resources() -> Resources:
35+
return get_resources()
36+
37+
3338
def test_tag_filter(head_soup: BeautifulSoup) -> None:
3439
"""Helper function to filter link and script from head."""
3540
excluded_link = head_soup.select("link")[0]
@@ -118,8 +123,8 @@ def test_example() -> None:
118123
this_example = Example(path=PurePath("hello_world"))
119124
assert this_example.title == "Hello World"
120125
assert (
121-
this_example.subtitle
122-
== "The classic hello world, but in Python -- in a browser!"
126+
this_example.subtitle
127+
== "The classic hello world, but in Python -- in a browser!"
123128
)
124129
assert "hello_world.css" in this_example.extra_head
125130
assert "<h1>Hello ...</h1>" in this_example.body
@@ -155,23 +160,29 @@ def test_missing_page() -> None:
155160

156161

157162
def test_sorted_examples() -> None:
158-
"""Ensure a stable listing."""
159-
examples = get_sorted_examples()
163+
"""Ensure a stable listing of dirs."""
164+
examples = get_sorted_paths(HERE / "gallery/examples")
160165
first_example = examples[0]
161166
assert "altair" == first_example.name
162167

163168

164-
def test_get_resources() -> None:
169+
def test_sorted_authors() -> None:
170+
"""Ensure a stable listing of files."""
171+
authors = get_sorted_paths(HERE / "gallery/authors", only_dirs=False)
172+
first_author = authors[0]
173+
assert "meg-1.md" == first_author.name
174+
175+
176+
def test_get_resources(resources: Resources) -> None:
165177
"""Ensure the dict-of-dicts is generated with PurePath keys."""
166-
resources = get_resources()
167178

168179
# Example
169180
hello_world_path = PurePath("hello_world")
170181
hello_world = resources.examples[hello_world_path]
171182
assert hello_world.title == "Hello World"
172183
assert (
173-
hello_world.subtitle
174-
== "The classic hello world, but in Python -- in a browser!"
184+
hello_world.subtitle
185+
== "The classic hello world, but in Python -- in a browser!"
175186
)
176187

177188
# Page
@@ -186,3 +197,10 @@ def test_is_local_broken_path() -> None:
186197
test_path = Path("/xxx")
187198
actual = is_local(test_path)
188199
assert not actual
200+
201+
202+
def test_authors(resources: Resources) -> None:
203+
"""Get the list of authors as defined in Markdown files."""
204+
authors = resources.authors
205+
first_author = list(authors.values())[0]
206+
assert "meg-1" == first_author.path.name

0 commit comments

Comments
 (0)