commit - 333aa34f5ccb2124d584c556c4bc3b0404d1b4af
commit + 7ffc8cefab316c47b53bfa33e29a6190397e00f4
blob - 2029725d34b59f0348d2283c543c2eb976268643
blob + bb60a72d90e215f8f1481c6e9effb7777451ee55
--- README.md
+++ README.md
=====================
Repost from RSS feed to [honk][honk-tedu].
+ONLY standard library (WITHOUT external dependencies).
-Installing dependencies:
-```
-$ python3 -m pip install requests
-```
-
Periodic launch of the bot (for example: [@hourly][openbsd-crontab5]):
```
$ python3 ronk.py --db ~/example --rss https://example.org/feed.rss --honk https://honk.server.org/api --token $TOKEN
blob - 8e32a344c316c186a202decf187208f421387bf8
blob + 7fb1a0ba718e01f56ea1d89659a47aa655b34477
--- TODO
+++ TODO
-* Remove dependency on `requests` (`urllib.request.urlopen`)
* Relative links
```
See <a href="cgi?action=article;sid=20240727110501">earlier report</a>
blob - 0e894836b8d9aa942337fd7d810487038c5aebd8
blob + 1514496fb9efcb8e147a76ea5837d177adedf157
--- ronk.py
+++ ronk.py
"""RSS-to-honk bot."""
import dbm
-import argparse
import xml.etree.ElementTree as ET
-import requests
+from argparse import ArgumentParser
+from urllib.parse import urlencode
+from urllib.request import urlopen
-parser = argparse.ArgumentParser(prog='ronk', description='RSS-to-honk bot')
+parser = ArgumentParser(prog='ronk', description='RSS-to-honk bot')
parser.add_argument('--db', required=True, help='path to local database file')
parser.add_argument('--rss', required=True, help='source RSS URL')
parser.add_argument('--honk', required=True, help='destination honk server URL')
parser.add_argument('--token', required=True, help='user token, see honk(3)')
args = parser.parse_args()
+
with dbm.open(args.db, 'c') as db:
- resp = requests.get(args.rss, timeout=10)
- resp.raise_for_status()
+ with urlopen(args.rss, timeout=15) as response:
+ rss_content = response.read().decode("utf8")
collected = []
- for root_child in ET.fromstring(resp.text):
+ for root_child in ET.fromstring(rss_content):
if root_child.tag == "channel":
for channel_child in root_child:
if channel_child.tag == 'item':
collected.insert(0, {i.tag: i.text or "" for i in channel_child})
break
- honk_server = requests.Session()
for item in collected:
link = item.get('link')
if link and link not in db:
- params = {"action": "honk", "token": args.token, "format": "html"}
p = ET.Element('p')
a = ET.SubElement(p, 'a')
a.attrib.update(href=link)
a.text = item.get('title') or link
noise = ET.tostring(p, encoding="unicode")
noise += item.get("description", "").strip()
- resp = honk_server.post(args.honk, params=params, files={"noise": (None, noise)}, timeout=10)
- resp.raise_for_status()
- db[link] = resp.text or "1"
+ post_data = {"action": "honk", "token": args.token, "format": "html", "noise": noise}
+ with urlopen(args.honk, data=urlencode(post_data).encode(), timeout=15) as response:
+ honk_url = response.read().decode("utf8")
+ db[link] = honk_url or "1"