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():
|
def sync():
|
||||||
local_db = database.Database.local()
|
local_db = database.Database.local()
|
||||||
database.sync(local_db)
|
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 pathlib
|
||||||
import xml.etree.ElementTree
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
from . import feed
|
||||||
|
|
||||||
|
|
||||||
def parse_opml(opml: str) -> list[str]:
|
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]")]
|
return [e.attrib["xmlUrl"] for e in f.iterfind(".//*[@xmlUrl]")]
|
||||||
|
|
||||||
|
|
||||||
def load_opml(path: pathlib.Path) -> list[str]:
|
def load_opml(path: pathlib.Path) -> list[str]:
|
||||||
with open(path, "r", encoding="utf-8") as f:
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
return parse_opml(f.read())
|
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