This commit is contained in:
John Doty 2024-07-10 09:09:17 +09:00
parent cbeadbd302
commit 26353a2779
3 changed files with 91 additions and 0 deletions

View file

@ -117,3 +117,26 @@ def refresh(url):
new_count = new_count + db.store_feed(f)
click.echo(f"Fetched {new_count} new entries.")
@cli.command(name="show")
def show():
"""Show feeds."""
db = database.Database.local()
feeds = db.load_all()
def feed_sort_key(f: feed.Feed) -> int:
if len(f.entries) > 0:
return max(e.inserted_at for e in f.entries)
return -1
feeds.sort(key=feed_sort_key)
for f in feeds:
click.echo(f"{f.title}")
if len(f.entries) > 0:
for entry in f.entries:
click.echo(f" {entry.title}")
else:
click.echo(f" <No Entries>")
click.echo()

View file

@ -153,6 +153,72 @@ class Database:
for url, last_fetched_ts, retry_after_ts, status, etag, modified in rows
]
def load_all(self, feed_limit: int = 20) -> list[feed.Feed]:
cursor = self.db.execute(
"""
SELECT
url,
last_fetched_ts,
retry_after_ts,
status,
etag,
modified,
title,
link
FROM feeds
"""
)
rows = cursor.fetchall()
almost_feeds = []
for row in rows:
(
url,
last_fetched_ts,
retry_after_ts,
status,
etag,
modified,
title,
link,
) = row
meta = feed.FeedMeta(
url=url,
last_fetched_ts=last_fetched_ts,
retry_after_ts=retry_after_ts,
status=status,
etag=etag,
modified=modified,
origin=self.origin,
)
almost_feeds.append((meta, title, link))
feeds = []
for meta, title, link in almost_feeds:
cursor = self.db.execute(
"""
SELECT
id,
inserted_at,
title,
link
FROM entries
WHERE feed_url=?
ORDER BY inserted_at DESC
LIMIT ?
""",
[meta.url, feed_limit],
)
rows = cursor.fetchall()
entries = [
feed.Entry(id=id, inserted_at=inserted_at, title=title, link=link)
for id, inserted_at, title, link in rows
]
f = feed.Feed(meta=meta, title=title, link=link, entries=entries)
feeds.append(f)
return feeds
def load_feed(self, url: str) -> feed.Feed | None:
cursor = self.db.execute(
"""

View file

@ -144,6 +144,7 @@ async def fetch_feed(
Regardless, the new FeedMeta has the latest state of the feed.
"""
if feed.status == FEED_STATUS_DEAD:
LOG.info(f"{feed.url} is dead")
return (None, feed)
if time.time() < feed.retry_after_ts:
@ -198,6 +199,7 @@ async def fetch_feed(
# permanently redirected URL, not just whatever the last thing
# is... e.g. imagine a permanent followed by a temporary
# redirect, then what?
LOG.info(f"{feed.url} permanently redirected to {response.url}")
assert response.url is not None
feed = dataclasses.replace(feed, url=response.url)