Add per-repo cover image support for RSS feed items

Add image_url column to repos table with migration, CLI image add/remove
commands, and Media RSS <media:content> elements in generated feed output.

New CLI commands: ghrel image add <repo> <url>, ghrel image remove <repo>
This commit is contained in:
2026-08-05 11:42:32 +02:00
parent 5c1d745ed3
commit 5cd809930e
6 changed files with 316 additions and 1 deletions
+75
View File
@@ -131,6 +131,81 @@ class TestGetAllEntries:
assert len(entries) == 3
class TestRepoImage:
def test_set_image(self, conn):
db.add_repo(conn, "owner/repo")
assert db.set_repo_image(conn, "owner/repo", "https://example.com/logo.png") is True
row = conn.execute("SELECT image_url FROM repos WHERE owner_repo = 'owner/repo'").fetchone()
assert row[0] == "https://example.com/logo.png"
def test_set_image_nonexistent(self, conn):
assert db.set_repo_image(conn, "no/one", "https://example.com/logo.png") is False
def test_set_image_overwrites(self, conn):
db.add_repo(conn, "owner/repo")
db.set_repo_image(conn, "owner/repo", "https://example.com/old.png")
db.set_repo_image(conn, "owner/repo", "https://example.com/new.png")
row = conn.execute("SELECT image_url FROM repos WHERE owner_repo = 'owner/repo'").fetchone()
assert row[0] == "https://example.com/new.png"
def test_remove_image(self, conn):
db.add_repo(conn, "owner/repo")
db.set_repo_image(conn, "owner/repo", "https://example.com/logo.png")
assert db.remove_repo_image(conn, "owner/repo") is True
row = conn.execute("SELECT image_url FROM repos WHERE owner_repo = 'owner/repo'").fetchone()
assert row[0] is None
def test_remove_image_no_image_set(self, conn):
db.add_repo(conn, "owner/repo")
assert db.remove_repo_image(conn, "owner/repo") is False
def test_image_url_in_entries(self, conn):
repo_id = db.add_repo(conn, "owner/repo")
db.set_repo_image(conn, "owner/repo", "https://example.com/logo.png")
db.upsert_entry(conn, repo_id, "release", "v1", "v1", "", "2025-01-01", "http://x")
entries = db.get_all_entries(conn)
assert len(entries) == 1
assert entries[0]["image_url"] == "https://example.com/logo.png"
def test_image_url_none_by_default(self, conn):
repo_id = db.add_repo(conn, "owner/repo")
db.upsert_entry(conn, repo_id, "release", "v1", "v1", "", "2025-01-01", "http://x")
entries = db.get_all_entries(conn)
assert entries[0]["image_url"] is None
def test_migration_adds_column(self):
"""Test that _migrate_add_image_url adds the column if missing."""
c = sqlite3.connect(":memory:")
c.execute("PRAGMA foreign_keys=ON")
c.execute("""
CREATE TABLE repos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
owner_repo TEXT NOT NULL UNIQUE,
mode TEXT NOT NULL DEFAULT 'release'
)
""")
c.execute("""
CREATE TABLE entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
repo_id INTEGER NOT NULL,
kind TEXT NOT NULL CHECK(kind IN ('release', 'tag')),
tag_name TEXT NOT NULL,
title TEXT NOT NULL,
body TEXT DEFAULT '',
published_at DATETIME NOT NULL,
html_url TEXT NOT NULL,
fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (repo_id) REFERENCES repos(id) ON DELETE CASCADE,
UNIQUE(repo_id, tag_name)
)
""")
c.commit()
db._migrate_add_image_url(c)
columns = [col[1] for col in c.execute("PRAGMA table_info(repos)").fetchall()]
assert "image_url" in columns
c.close()
class TestGetConnection:
def test_creates_file(self):
with tempfile.TemporaryDirectory() as tmp: