|
|
@@ -0,0 +1,132 @@ |
|
|
|
#!/usr/bin/env python3 |
|
|
|
|
|
|
|
import os |
|
|
|
import sys |
|
|
|
|
|
|
|
import json |
|
|
|
|
|
|
|
import requests |
|
|
|
from mastodon import Mastodon |
|
|
|
|
|
|
|
def load_config(): |
|
|
|
with open(os.getenv('MR_CONFIG', 'config.json'), 'r') as f: |
|
|
|
return json.loads(f.read()) |
|
|
|
|
|
|
|
def load_recents(): |
|
|
|
try: |
|
|
|
with open(os.getenv('MR_RECENTS', 'recents.json'), 'r') as f: |
|
|
|
return json.loads(f.read()) |
|
|
|
except NotFound: |
|
|
|
return [] |
|
|
|
|
|
|
|
def save_recents(recents): |
|
|
|
with open(os.getenv('MR_RECENTS'), 'w') as f: |
|
|
|
f.write(json.dumps(recents)) |
|
|
|
|
|
|
|
def make_masto(config): |
|
|
|
baseurl = 'https://%s' % config['hostname'] |
|
|
|
return Mastodon(access_token=config['token'], api_base_url=baseurl) |
|
|
|
|
|
|
|
def make_post(masto, data): |
|
|
|
body = '%s\n\nby /u/%s at https://old.reddit.com/%s' % (data['title'], data['username'], data['rid']) |
|
|
|
|
|
|
|
#if len(data['attachments']) > 4: |
|
|
|
# data['attachments'] = data['attachments'][:4] |
|
|
|
|
|
|
|
image_resps = None |
|
|
|
#if data['attachments'] is not None: |
|
|
|
# for a in data['attachments']: |
|
|
|
# res = masto.media_post(a) |
|
|
|
# res.raise_for_status() |
|
|
|
# image_resps.append(res) |
|
|
|
#else: |
|
|
|
# image_resps = None |
|
|
|
|
|
|
|
masto.status_post(body, media_ids=image_resps) |
|
|
|
|
|
|
|
def extract_media_urls(data): |
|
|
|
if 'selftext' in data: |
|
|
|
return [] |
|
|
|
|
|
|
|
if 'post_hint' not in data: |
|
|
|
if 'gallery_data' in data: |
|
|
|
gd = data['gallery_data']['items'] |
|
|
|
mmd = data['media_metadata'] |
|
|
|
|
|
|
|
ents = [] |
|
|
|
for ent in gd: |
|
|
|
mid = ent['media_id'] |
|
|
|
mime = mmd[mid]['m'] |
|
|
|
_, ext = mime.split('/') |
|
|
|
url = 'https://i.redd.it/%s.%s' % (mid, ext) |
|
|
|
ents.append(url) |
|
|
|
|
|
|
|
return ents |
|
|
|
else: |
|
|
|
raise ValueError('no hint type and missing gallery') |
|
|
|
|
|
|
|
hint = data['post_hint'] |
|
|
|
|
|
|
|
if hint == 'link': |
|
|
|
if 'crosspost_parent_list' in data: |
|
|
|
return extract_media_urls(data['crosspost_parent_list'][0]) |
|
|
|
else: |
|
|
|
# Not a reddit crosspost. |
|
|
|
return [] |
|
|
|
|
|
|
|
if hint == 'hosted:video': |
|
|
|
return [data['secure_media']['reddit_video']['fallback_url']] |
|
|
|
|
|
|
|
if hint == 'image': |
|
|
|
return [data['url']] |
|
|
|
|
|
|
|
if hint == 'rich:video': |
|
|
|
# TODO maybe use thumbnail? |
|
|
|
print('got a video at', data['url'], 'but ignoring') |
|
|
|
|
|
|
|
raise ValueError('unknown hint type ' + hint) |
|
|
|
|
|
|
|
def query_tops(config): |
|
|
|
url = 'https://www.reddit.com/r/%s/top.json?sort=top&t=day' % config['subreddit'] |
|
|
|
resp = requests.get(url, headers = {'User-agent': 'mastoreddit'}) |
|
|
|
resp.raise_for_status() |
|
|
|
j = resp.json() |
|
|
|
|
|
|
|
posts = [] |
|
|
|
|
|
|
|
for post in j['data']['children']: |
|
|
|
if post['kind'] != 't3': |
|
|
|
print('found post of kind', post['kind']) |
|
|
|
d = post['data'] |
|
|
|
|
|
|
|
media = None |
|
|
|
try: |
|
|
|
media = extract_media_urls(d) |
|
|
|
except Exception as e: |
|
|
|
print('error processing ' + d['id'] + ': ' + str(e)) |
|
|
|
|
|
|
|
posts.append({ |
|
|
|
'rid': d['id'], |
|
|
|
'title': d['title'], |
|
|
|
'username': d['author'], |
|
|
|
'score': d['ups'], |
|
|
|
'media': media |
|
|
|
}) |
|
|
|
|
|
|
|
return posts |
|
|
|
|
|
|
|
def just_toot(config, msg): |
|
|
|
masto = make_masto(config) |
|
|
|
masto.toot(msg) |
|
|
|
|
|
|
|
def main(): |
|
|
|
config = load_config() |
|
|
|
masto = make_masto(config) |
|
|
|
# make_post(masto, {'title': sys.argv[1], 'username': 'nobody', 'rid': 'none', 'attachments': [sys.argv[2]]}) |
|
|
|
res = query_tops(config) |
|
|
|
for r in res[:5]: |
|
|
|
print('posting', r['rid'], '-', r['title']) |
|
|
|
make_post(masto, r) |
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
main() |