diff --git a/discord_rss_bot/main.py b/discord_rss_bot/main.py
index 70b8de6..1240f0b 100644
--- a/discord_rss_bot/main.py
+++ b/discord_rss_bot/main.py
@@ -4,6 +4,7 @@ import json
import logging
import logging.config
import re
+import tempfile
import typing
import urllib.parse
from contextlib import asynccontextmanager
@@ -42,6 +43,7 @@ from reader import Reader
from reader import ReaderError
from reader import TagNotFoundError
from starlette.responses import RedirectResponse
+from starlette.responses import Response as StarletteResponse
from discord_rss_bot.custom_filters import entry_is_blacklisted
from discord_rss_bot.custom_filters import entry_is_whitelisted
@@ -2391,6 +2393,33 @@ async def update_feed(
return RedirectResponse(url="/feed?feed_url=" + urllib.parse.quote(feed_url), status_code=303)
+@app.get("/export")
+def export_database(
+ reader: Annotated[Reader, Depends(get_reader_dependency)],
+) -> StarletteResponse:
+ """Export the entire database as a compressed SQLite file.
+
+ Args:
+ reader: The Reader instance.
+
+ Returns:
+ StarletteResponse: The exported database file for download.
+ """
+ with tempfile.TemporaryDirectory() as tmpdir:
+ export_path: Path = reader._storage.export(tmpdir, "discord-rss-bot-export") # ruff:ignore[private-member-access]
+ filename: str = export_path.name
+ file_bytes: bytes = export_path.read_bytes()
+
+ return StarletteResponse(
+ content=file_bytes,
+ status_code=200,
+ headers={
+ "Content-Type": "application/gzip",
+ "Content-Disposition": f'attachment; filename="{filename}"',
+ },
+ )
+
+
@app.post("/backup")
async def manual_backup(
request: Request,
diff --git a/discord_rss_bot/templates/settings.html b/discord_rss_bot/templates/settings.html
index df4b5ee..94a5309 100644
--- a/discord_rss_bot/templates/settings.html
+++ b/discord_rss_bot/templates/settings.html
@@ -109,6 +109,18 @@
+
+
+
+
Export Database
+
+
+ Download a copy of the entire database for backup or migration.
+ The file is a compressed SQLite dump containing all feeds, entries, and settings.
+