Skip to content

Commit 6ebeaab

Browse files
committed
Fix the image cache
1 parent 6aae556 commit 6ebeaab

3 files changed

Lines changed: 20 additions & 42 deletions

File tree

rss_glue/feeds/cache.py

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,3 @@
1-
"""
2-
CacheFeed - A composable feed wrapper that caches images from post content.
3-
4-
This module provides a CacheFeed class that wraps another feed and automatically
5-
downloads and caches images referenced in post HTML content. This helps avoid:
6-
- CORS issues when displaying images from external sources
7-
- Broken links from expired or unstable image URLs
8-
9-
Usage example:
10-
from rss_glue.feeds import RssFeed, CacheFeed
11-
12-
# Create a source feed
13-
source = RssFeed("example", "https://example.com/feed.xml")
14-
15-
# Wrap it with CacheFeed to cache images
16-
cached = CacheFeed(source)
17-
18-
# Use cached feed in your artifacts
19-
artifacts = [HtmlOutput(cached)]
20-
21-
The CacheFeed stores images in the file cache under an "images/" namespace
22-
and rewrites <img> tags to point to the locally cached versions.
23-
"""
24-
251
import re
262
from dataclasses import dataclass
273
from pathlib import Path
@@ -123,17 +99,6 @@ def _cache_image(self, url: str) -> Optional[Path]:
12399
self.logger.error(f"Failed to download image {url}: {e}")
124100
return None
125101

126-
@staticmethod
127-
def load(obj: dict, source: "CacheFeed"):
128-
"""
129-
Override ReferenceFeedItem.load() to get the subpost from source.source
130-
instead of directly from source.
131-
"""
132-
obj["subpost"] = source.source.post(obj["subpost"])
133-
if not obj["subpost"]:
134-
source.logger.error(f"missing reference ns={obj['namespace']} subpost={obj['id']}")
135-
return obj
136-
137102

138103
class CacheFeed(feed.ReferenceFeed):
139104
"""

rss_glue/feeds/feed.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from rss_glue.logger import logger
88
from rss_glue.resources import global_config, utc_now
9+
from rss_glue.utils import from_dict
910

1011

1112
@dataclass
@@ -54,7 +55,8 @@ def to_dict(self) -> dict:
5455
@dataclass
5556
class ReferenceFeedItem(FeedItem):
5657
"""
57-
A ReferenceFeedItem is a reference to another feed item.
58+
A ReferenceFeedItem contains a reference to another feed item.
59+
It is only useful if your feed needs to store ADDITIONAL data to the post.
5860
"""
5961

6062
subpost: FeedItem
@@ -72,6 +74,11 @@ def hashkey(self):
7274

7375
@staticmethod
7476
def load(obj: dict, source: "BaseFeed"):
77+
"""
78+
A reference feed has a load function which should take the contents of the
79+
raw JSON object kept in the cache and return a fully "hydrated" FeedItem
80+
which probably references other feed item(s).
81+
"""
7582
obj["subpost"] = source.post(obj["subpost"])
7683
if not obj["subpost"]:
7784
logger.error(f"missing reference ns={obj['namespace']} subpost={obj['id']}")
@@ -276,9 +283,7 @@ def post(self, post_id: str) -> Optional[FeedItem]:
276283
if not cached:
277284
return None
278285

279-
# Load the cached post
280-
loaded = self.post_cls.load(cached, self)
281-
if not loaded:
282-
return None
286+
cached["subpost"] = cached["id"]
287+
loaded = self.post_cls.load(cached, self.source)
283288

284-
return self.post_cls(**loaded)
289+
return from_dict(self.post_cls, loaded)

rss_glue/utils.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Iterable, Optional
1+
from typing import Iterable, Optional, TypeVar
2+
import inspect
23

34
import requests
45
from requests.adapters import HTTPAdapter
@@ -144,3 +145,10 @@ def make_browser_session(
144145
session.mount("https://", adapter)
145146

146147
return session
148+
149+
150+
T = TypeVar("T")
151+
152+
153+
def from_dict(cls: type[T], obj: dict) -> T:
154+
return cls(**{k: v for k, v in obj.items() if k in inspect.signature(cls).parameters})

0 commit comments

Comments
 (0)