feat: add plug-and-play devRant API client examples with Python and JavaScript
Add complete set of example scripts for the devRant REST protocol under examples/devrant/, including reusable client libraries, a rant poster, a live feed watcher with keyword-based auto-upvote, and an end-to-end smoke test that exercises every endpoint. Both Python (stdlib-only) and JavaScript (Node 18+ global fetch) implementations are provided.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import xmlrpc.client
|
||||
from typing import Iterator
|
||||
|
||||
from client import DevPlace
|
||||
|
||||
URL = os.environ.get("DEVPLACE_URL", "https://devplace.net")
|
||||
API_KEY = os.environ.get("DEVPLACE_API_KEY", "YOUR_API_KEY")
|
||||
POLL_SECONDS = int(os.environ.get("DEVPLACE_POLL_SECONDS", "30"))
|
||||
REPLY = os.environ.get(
|
||||
"DEVPLACE_REPLY",
|
||||
"Thanks for the mention! This is an automated reply via the XML-RPC bridge.",
|
||||
)
|
||||
|
||||
POST_SLUG = re.compile(r"/posts/([^/#?]+)")
|
||||
|
||||
|
||||
def unread_mentions(dp: DevPlace) -> Iterator[dict]:
|
||||
result = dp.call("notifications.list")
|
||||
for group in result.get("notification_groups", []):
|
||||
for entry in group.get("entries", []):
|
||||
note = entry["notification"]
|
||||
if note.get("type") == "mention" and not note.get("read"):
|
||||
yield note
|
||||
|
||||
|
||||
def reply_to_mention(dp: DevPlace, note: dict) -> bool:
|
||||
match = POST_SLUG.search(note.get("target_url") or "")
|
||||
if not match:
|
||||
return False
|
||||
detail = dp.call("posts.detail", post_slug=match.group(1))
|
||||
dp.call(
|
||||
"comments.create",
|
||||
content=REPLY,
|
||||
target_uid=detail["post"]["uid"],
|
||||
target_type="post",
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
def run() -> None:
|
||||
dp = DevPlace(URL, api_key=API_KEY)
|
||||
print(f"Mention bot started; polling {URL} every {POLL_SECONDS}s.")
|
||||
while True:
|
||||
try:
|
||||
for note in unread_mentions(dp):
|
||||
try:
|
||||
if reply_to_mention(dp, note):
|
||||
print("Replied to:", note.get("message"))
|
||||
except xmlrpc.client.Fault as fault:
|
||||
print("Could not reply:", fault.faultCode, fault.faultString)
|
||||
finally:
|
||||
dp.call("notifications.mark.read", notification_uid=note["uid"])
|
||||
except xmlrpc.client.Fault as fault:
|
||||
print("Poll error:", fault.faultCode, fault.faultString)
|
||||
except OSError as error:
|
||||
print("Network error, retrying:", error)
|
||||
time.sleep(POLL_SECONDS)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
Reference in New Issue
Block a user