Refactor rendering into views (sigh)
This commit is contained in:
parent
112de55124
commit
002a8cc543
2 changed files with 85 additions and 74 deletions
80
cry/views.py
Normal file
80
cry/views.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import typing
|
||||
|
||||
import dominate.tags as tags
|
||||
|
||||
from . import feed
|
||||
|
||||
def _standard_header(title: str) -> tags.head:
|
||||
head = tags.head(
|
||||
tags.meta(charset="utf8"),
|
||||
tags.title(title),
|
||||
tags.link(rel="stylesheet", href="/style.css", type="text/css"),
|
||||
)
|
||||
assert isinstance(head, tags.head)
|
||||
return head
|
||||
|
||||
def feed_view(feeds: list[feed.Feed]) -> tags.html:
|
||||
document = tags.html(
|
||||
_standard_header("Subscribed Feeds"),
|
||||
tags.h1("Feeds"),
|
||||
tags.div(
|
||||
tags.form(
|
||||
{"method": "post", "action": "/refresh"},
|
||||
tags.input_(type="submit", value="Refresh"),
|
||||
),
|
||||
tags.form(
|
||||
{"method": "post", "action": "/subscribe"},
|
||||
tags.label({"for": "url"}, "Feed url:"),
|
||||
tags.input_(type="url", name="url"),
|
||||
tags.input_(type="submit", value="Subscribe"),
|
||||
),
|
||||
(
|
||||
tags.div(
|
||||
{"class": "feed"},
|
||||
tags.h2(tags.a(f.title, href=f.link, target="_blank")),
|
||||
(
|
||||
tags.ul(
|
||||
tags.li(
|
||||
{"class": "entry"},
|
||||
tags.a(
|
||||
entry.title, href=entry.link, target="_blank"
|
||||
),
|
||||
f" ({entry.time_ago()})",
|
||||
)
|
||||
for entry in f.entries
|
||||
)
|
||||
if len(f.entries) > 0
|
||||
else tags.i("No entries...")
|
||||
),
|
||||
)
|
||||
for f in feeds
|
||||
),
|
||||
),
|
||||
)
|
||||
assert isinstance(document, tags.html)
|
||||
return document
|
||||
|
||||
def subscribe_choose_view(candidates: typing.Iterable[tuple[str,str]]) -> tags.html:
|
||||
document = tags.html(
|
||||
_standard_header("Choose Feed"),
|
||||
tags.h1("Choose Feed"),
|
||||
tags.p("More than one feed was found. Choose the feed to subscribe to."),
|
||||
tags.table(
|
||||
tags.caption("Potential feeds"),
|
||||
tags.thead(tags.tr(tags.th("Title"), tags.th("URL"), tags.th())),
|
||||
tags.tbody(
|
||||
tags.form(
|
||||
{"action": "/subscribe", "method":"post"},
|
||||
tags.tr(
|
||||
tags.td(title), tags.td(url), tags.td(
|
||||
tags.input_({"type":"hidden", "name":"url", "value":url}),
|
||||
tags.input_({"type":"submit", "value":"Subscribe"}),
|
||||
),
|
||||
),
|
||||
)
|
||||
for title, url in candidates
|
||||
),
|
||||
),
|
||||
)
|
||||
assert isinstance(document, tags.html)
|
||||
return document
|
||||
79
cry/web.py
79
cry/web.py
|
|
@ -1,7 +1,7 @@
|
|||
import asyncio
|
||||
import contextlib
|
||||
import dataclasses
|
||||
import dominate.tags as d
|
||||
import dominate.tags as tags
|
||||
import functools
|
||||
import http.server
|
||||
import io
|
||||
|
|
@ -15,7 +15,7 @@ from typing import Callable, Concatenate, ParamSpec
|
|||
|
||||
from . import database
|
||||
from . import feed
|
||||
|
||||
from . import views
|
||||
|
||||
class DeadlineCondition:
|
||||
"""A condition variable that allows you to wait with a timeout."""
|
||||
|
|
@ -296,7 +296,6 @@ def refresh_feeds(sink: EventChannel):
|
|||
|
||||
REFRESH_TASK: BackgroundTask | None = None
|
||||
|
||||
|
||||
@background_task
|
||||
def subscribe(sink: EventChannel, url: str):
|
||||
"""Subscribe to a feed."""
|
||||
|
|
@ -497,36 +496,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
|||
|
||||
feeds.sort(key=feed.sort_key, reverse=True)
|
||||
|
||||
document = d.html()
|
||||
with document:
|
||||
with d.head():
|
||||
d.meta(charset="utf8")
|
||||
d.title("Subscribed Feeds")
|
||||
d.link(rel="stylesheet", href="/style.css", type="text/css")
|
||||
d.h1("Feeds")
|
||||
with d.div():
|
||||
with d.form(method="post", action="/refresh"):
|
||||
d.input_(type="submit", value="Refresh")
|
||||
with d.form(method="post", action="/subscribe"):
|
||||
d.label("Feed url:", fr="url")
|
||||
d.input_(type="url", name="url")
|
||||
d.input_(type="submit", value="Subscribe")
|
||||
|
||||
for f in feeds:
|
||||
with d.div(cls="feed"):
|
||||
d.h2(d.a(f.title, href=f.link, target="_blank"))
|
||||
if len(f.entries) > 0:
|
||||
d.ul(
|
||||
d.li(
|
||||
d.a(entry.title, href=entry.link, target="_blank"),
|
||||
f" ({entry.time_ago()})",
|
||||
cls="entry",
|
||||
)
|
||||
for entry in f.entries
|
||||
)
|
||||
else:
|
||||
d.i("No entries...")
|
||||
|
||||
document = views.feed_view(feeds)
|
||||
self.write_html(document.render())
|
||||
|
||||
def serve_subscribe_choose(self):
|
||||
|
|
@ -541,47 +511,8 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
|||
self.send_error(400, explain=tb)
|
||||
return
|
||||
|
||||
buffer = io.StringIO()
|
||||
buffer.write(
|
||||
"""
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Choose Feed</title>
|
||||
<link rel="stylesheet" href="/style.css" type="text/css" />
|
||||
</head>
|
||||
<h1>Choose Feed</h1>
|
||||
<p>More than one feed was found. Choose the feed to subscribe to.</p>
|
||||
<table>
|
||||
<caption>Potential feeds</caption>
|
||||
<thead>
|
||||
<tr><th>Title</th><th>URL</th><th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
"""
|
||||
)
|
||||
for title, url in candidates:
|
||||
buffer.write(
|
||||
f"""
|
||||
<form action="/subscribe" method="post"><tr>
|
||||
<td>{title}</td>
|
||||
<td>{url}</td>
|
||||
<td>
|
||||
<input type="hidden" name="url" value="{url}" />
|
||||
<input type="submit" value="Subscribe" />
|
||||
</td>
|
||||
</tr></form>
|
||||
"""
|
||||
)
|
||||
buffer.write(
|
||||
"""
|
||||
</tbody>
|
||||
</table>
|
||||
"""
|
||||
)
|
||||
buffer.flush()
|
||||
|
||||
self.write_html(buffer.getvalue())
|
||||
document = views.subscribe_choose_view(candidates)
|
||||
self.write_html(document.render())
|
||||
|
||||
def write_html(self, html: str):
|
||||
response = html.encode("utf-8")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue