OPML export
This commit is contained in:
parent
07f8de3f99
commit
0fd9cc8bbd
2 changed files with 36 additions and 2 deletions
16
cry/cli.py
16
cry/cli.py
|
|
@ -295,3 +295,19 @@ def serve():
|
|||
def sync():
|
||||
local_db = database.Database.local()
|
||||
database.sync(local_db)
|
||||
|
||||
|
||||
@cli.command(name="export")
|
||||
@click.argument("opml_file", type=click.File("wb"))
|
||||
def export_opml(opml_file):
|
||||
"Export the specified OPML file."
|
||||
|
||||
db = database.Database.local()
|
||||
feeds = db.load_all(feed_limit=0)
|
||||
if len(feeds) == 0:
|
||||
click.echo("Not subscribed to any feeds.")
|
||||
return 0
|
||||
|
||||
feeds.sort(key=lambda f: f.title)
|
||||
|
||||
opml.write_opml(opml_file, feeds)
|
||||
|
|
|
|||
22
cry/opml.py
22
cry/opml.py
|
|
@ -1,12 +1,30 @@
|
|||
import pathlib
|
||||
import xml.etree.ElementTree
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from . import feed
|
||||
|
||||
|
||||
def parse_opml(opml: str) -> list[str]:
|
||||
f = xml.etree.ElementTree.fromstring(opml)
|
||||
f = ET.fromstring(opml)
|
||||
return [e.attrib["xmlUrl"] for e in f.iterfind(".//*[@xmlUrl]")]
|
||||
|
||||
|
||||
def load_opml(path: pathlib.Path) -> list[str]:
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return parse_opml(f.read())
|
||||
|
||||
|
||||
def write_opml(f, feeds: list[feed.Feed]):
|
||||
root = ET.Element("opml", {"version": "2.0"})
|
||||
body = ET.SubElement(root, "body")
|
||||
head = ET.SubElement(root, "head")
|
||||
title = ET.SubElement(head, "title")
|
||||
title.text = "Exported from cry"
|
||||
|
||||
for feed in feeds:
|
||||
ET.SubElement(
|
||||
body,
|
||||
"outline",
|
||||
{"type": "rss", "text": feed.title, "xmlUrl": feed.meta.url},
|
||||
)
|
||||
ET.ElementTree(root).write(f)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue