-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #297 from barrucadu/nya/kjp-hacksrus
[nyarlathotep] Add job to post KJP to the fediverse
- Loading branch information
Showing
3 changed files
with
116 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#!/usr/bin/env python3 | ||
|
||
"""RSS-to-Mastodon (or Pleroma) | ||
Requires the API_KEY environment variable to be set. | ||
Usage: | ||
rss-to-mastodon -d <domain> -f <feed-url> -l <history-file> [-e <entries>] [-v <visibility>] | ||
Options: | ||
-d <domain> api domain | ||
-f <feed-url> rss feed URL | ||
-l <history-file> file to log feed item IDs to (to prevent double-posting) | ||
-e <entries> maximum number of entries to post [default: 1] | ||
-v <visibility> visibility of entries [default: public] | ||
""" | ||
|
||
import docopt | ||
import feedparser | ||
import http.client | ||
import os | ||
import pathlib | ||
import requests | ||
import sys | ||
import time | ||
|
||
api_token = os.getenv("API_KEY") | ||
if api_token is None: | ||
raise Exception("missing API key") | ||
|
||
args = docopt.docopt(__doc__) | ||
api_domain = args["-d"] | ||
feed_url = args["-f"] | ||
history_file = pathlib.Path(args["-l"]) | ||
entries = int(args["-e"]) | ||
visibility = args["-v"] | ||
|
||
attempts = 0 | ||
feed = None | ||
while attempts < 5: | ||
# tumblr seems to often just drop connections with the default feedparser | ||
# user agent, so let's pretend to be curl | ||
try: | ||
feed = feedparser.parse(feed_url, agent="curl/7.54.1") | ||
break | ||
except http.client.RemoteDisconnected: | ||
print(f"failed to download feed - attempt {attempts}", file=sys.stderr) | ||
attempts += 1 | ||
time.sleep(2) | ||
|
||
if feed is None: | ||
print("could not download feed", file=sys.stderr) | ||
sys.exit(1) | ||
|
||
# will crash if the file doesn't exist - but that's probably a good failsafe to | ||
# prevent the same post being spammed if the log file gets accidentally deleted | ||
history = history_file.read_text().split() | ||
items = [entry for entry in feed["items"][:entries] if entry["id"] not in history] | ||
|
||
# if there are multiple items, post the older ones first | ||
for item in reversed(items): | ||
print(item["id"]) | ||
print(item["title"]) | ||
print() | ||
|
||
requests.post( | ||
f"{api_domain}/api/v1/statuses", | ||
headers={ | ||
"Authorization": f"Bearer {api_token}", | ||
"Idempotency-Key": item["id"], | ||
}, | ||
json={ | ||
"status": item["title"], | ||
"visibility": visibility, | ||
}, | ||
).raise_for_status() | ||
|
||
# yes, this is inefficient - but the file will have a few hundred entries in | ||
# it at most | ||
history.append(item["id"]) | ||
history_file.write_text("\n".join(history)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters