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 asyncio
|
||||||
import contextlib
|
import contextlib
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import dominate.tags as d
|
import dominate.tags as tags
|
||||||
import functools
|
import functools
|
||||||
import http.server
|
import http.server
|
||||||
import io
|
import io
|
||||||
|
|
@ -15,7 +15,7 @@ from typing import Callable, Concatenate, ParamSpec
|
||||||
|
|
||||||
from . import database
|
from . import database
|
||||||
from . import feed
|
from . import feed
|
||||||
|
from . import views
|
||||||
|
|
||||||
class DeadlineCondition:
|
class DeadlineCondition:
|
||||||
"""A condition variable that allows you to wait with a timeout."""
|
"""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
|
REFRESH_TASK: BackgroundTask | None = None
|
||||||
|
|
||||||
|
|
||||||
@background_task
|
@background_task
|
||||||
def subscribe(sink: EventChannel, url: str):
|
def subscribe(sink: EventChannel, url: str):
|
||||||
"""Subscribe to a feed."""
|
"""Subscribe to a feed."""
|
||||||
|
|
@ -497,36 +496,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||||
|
|
||||||
feeds.sort(key=feed.sort_key, reverse=True)
|
feeds.sort(key=feed.sort_key, reverse=True)
|
||||||
|
|
||||||
document = d.html()
|
document = views.feed_view(feeds)
|
||||||
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...")
|
|
||||||
|
|
||||||
self.write_html(document.render())
|
self.write_html(document.render())
|
||||||
|
|
||||||
def serve_subscribe_choose(self):
|
def serve_subscribe_choose(self):
|
||||||
|
|
@ -541,47 +511,8 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||||
self.send_error(400, explain=tb)
|
self.send_error(400, explain=tb)
|
||||||
return
|
return
|
||||||
|
|
||||||
buffer = io.StringIO()
|
document = views.subscribe_choose_view(candidates)
|
||||||
buffer.write(
|
self.write_html(document.render())
|
||||||
"""
|
|
||||||
<!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())
|
|
||||||
|
|
||||||
def write_html(self, html: str):
|
def write_html(self, html: str):
|
||||||
response = html.encode("utf-8")
|
response = html.encode("utf-8")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue