Skip to content

Instantly share code, notes, and snippets.

@eindiran
Last active November 7, 2019 01:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eindiran/e203c3f0c573935e2b8f228592010411 to your computer and use it in GitHub Desktop.
Save eindiran/e203c3f0c573935e2b8f228592010411 to your computer and use it in GitHub Desktop.
A quick implementation of a status-posting script for Mastodon.
#!/usr/bin/env python3
# -*- coding: utf8 -*-
"""
Automatically post new articles (in the _posts directory for a Jekyll site) to
a Mastodon instance.
Elliott Indiran <elliott.indiran@protonmail.com>
"""
from pathlib import Path
from typing import Optional
import json
import sys
import requests
class Tooter():
"""
A very quick implementation of a wrapper around the Mastodon
API that allows you to post statuses.
"""
def __init__(self, confpath='/home/eindiran/.autotootrc') -> None:
"""
Initialize a Tooter object.
"""
self.instance: Optional[str] = None
self.auth_token: Optional[str] = None
self.client_secret: Optional[str] = None
self.client_key: Optional[str] = None
self.user: Optional[str] = None
self.confpath: str = confpath
self.allow_read: bool = False
self.allow_write: bool = False
self.allow_follow: bool = False
try:
# Fetch information from the configuration file
self.configure()
except AssertionError:
print('The configuration file ({}) cannot be found.'.format(confpath))
sys.exit()
except KeyError as err:
print('The configuration file ({}) is incorrectly formatted.'.format(confpath))
print(err)
sys.exit()
def configure(self) -> None:
"""
Run the config process: reads a config file that contains
info on username, instance and the auth token.
Raises AssertionError on non-existent config file.
Raises KeyError if config file is incorrectly formatted.
"""
config_file = Path(self.confpath)
assert config_file.is_file()
with open(self.confpath, 'r') as jsonf:
conf = json.loads(jsonf.read())
self.instance = conf['instance']
self.auth_token = conf['access-token']
self.client_secret = conf['client-secret']
self.client_key = conf['client-key']
self.allow_read = conf['read']
self.allow_write = conf['write']
self.allow_follow = conf['follow']
def post(self, msg: str) -> bool:
"""
Take a message and post it to Mastodon.
"""
headers = {}
data = {}
# Add auth token to header
headers['Authorization'] = 'Bearer ' + self.auth_token
data['status'] = msg
data['visibility'] = 'public'
post_url = self.instance + '/api/v1/statuses'
try:
response = requests.post(url=post_url, data=data, headers=headers)
if response == 200:
return True
return False
except requests.RequestException:
return False
if __name__ == '__main__':
msg = sys.stdin.read()
tootski = Tooter()
tootski.post(msg)
@eindiran
Copy link
Author

eindiran commented Nov 7, 2019

Invoked like so:

echo "This is a test" | ./autotoot.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment