Improved API readability

This commit is contained in:
Bofh 2021-02-11 20:03:31 +01:00
parent df7537b80e
commit 15f47b63f4
2 changed files with 86 additions and 28 deletions

View File

@ -562,6 +562,25 @@ def get_random_headers():
def account_exists(acc_id): def account_exists(acc_id):
return os.path.exists('./db/accounts/{}'.format(acc_id)) return os.path.exists('./db/accounts/{}'.format(acc_id))
def account_config(acc_id, key, value):
if not account_exists(acc_id):
return False, 'Account does not exist: {}'.format(acc_id)
accdata = db_get('accounts', acc_id)
key = key.strip()
value = value.strip()
# make sure passwords or cookie cannot be retrieved
if value == '' and not key in ['password', 'cookie']:
if not key in accdata:
return False, 'Key does not exist yet: {}'.format(key)
return True, accdata[key]
# value has something, so we set it
accdata[key] = value
db_set('accounts', acc_id, accdata)
return True, 'Account configuration saved: {}'.format(key)
def db_set(table, acc_id, accdata): def db_set(table, acc_id, accdata):
w = open('./db/{}/{}'.format(table, acc_id), 'w') w = open('./db/{}/{}'.format(table, acc_id), 'w')
w.write(json.dumps(accdata)) w.write(json.dumps(accdata))

View File

@ -1,29 +1,34 @@
from http.server import BaseHTTPRequestHandler, HTTPServer from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse
import igmirror import igmirror
import json
import sys import sys
import os import os
import re import re
class MyServer(BaseHTTPRequestHandler): class MyServer(BaseHTTPRequestHandler):
def do_GET(self): def do_GET(self):
path = self.path.strip('/') _ = urlparse(self.path)
qs = _.query
path = _.path.strip().strip('/')
parts = path.split('/') parts = path.split('/')
if len(parts) == 1: if len(parts) == 1:
response(self, 200, 'html')
action = parts[0].lower()
self.send_response(200) if False:
self.send_header("Content-type", "text/html") pass
self.end_headers()
# list accounts (plain text) # list accounts (plain text)
if parts[0] == 'list': elif action == 'list':
accounts = os.listdir('./db/accounts') accounts = os.listdir('./db/accounts')
for acc in sorted(set(accounts)): for acc in sorted(set(accounts)):
self.wfile.write(bytes(acc+'\n', "utf-8")) echo(self, acc)
# lists accounts on a pretty HTML + CSS # lists accounts on a pretty HTML + CSS
# making sure there is no XSS possible on account names # making sure there is no XSS possible on account names
elif parts[0] == 'mirrors': elif action == 'mirrors':
html = """<!DOCTYPE html> html = """<!DOCTYPE html>
<html> <html>
<head> <head>
@ -100,20 +105,16 @@ div.item > div.links > div:nth-child(2) > a {
</html> </html>
""" """
html = igmirror.pixelfed_htmlfill_mirrors(html) html = igmirror.pixelfed_htmlfill_mirrors(html)
self.wfile.write(bytes(html, "utf-8")) echo(self, html)
return return
if len(parts) == 2: if len(parts) == 2:
response(self, 200, 'json')
self.send_response(200) acc_id = parts[0]
self.send_header("Content-type", "application/json")
self.end_headers()
# a wilcard select all accounts
what = parts[0]
action = parts[1].lower() action = parts[1].lower()
if what == '*':
if acc_id == '*':
if False: if False:
pass pass
elif action == 'update': elif action == 'update':
@ -125,27 +126,65 @@ div.item > div.links > div:nth-child(2) > a {
else: else:
# make sure account name contains only safe characters # make sure account name contains only safe characters
# i think IG usernames can only have this characters: # i think IG usernames can only have this characters:
accname = re.sub(r'[^a-zA-Z0-9_\.]+', '', what)
if False: if False:
pass pass
elif action == 'add': elif action == 'add':
igmirror.add_igaccount(accname) igmirror.add_igaccount(acc_id)
return echo(self, {'status': 'ok', 'message': 'New mirror account added to Pixelfed!'})
elif action == 'update': elif action == 'update':
igmirror.update_igaccount_async(accname) igmirror.update_igaccount_async(acc_id)
return echo(self, {'status': 'ok', 'message': 'Account update process started asyncronously'})
elif action == 'login': elif action == 'login':
igmirror.pixelfed_login(accname, True) igmirror.pixelfed_login(acc_id, True)
return echo(self, {'status': 'ok', 'message': 'Account logged in to Pixelfed'})
elif action == 'logout': elif action == 'logout':
igmirror.pixelfed_logout(accname) igmirror.pixelfed_logout(acc_id)
return echo(self, {'status': 'ok', 'message': 'Account logged out of Pixelfed'})
elif action == 'nuke': elif action == 'nuke':
igmirror.delete_statuses(accname) igmirror.delete_statuses(acc_id)
return echo(self, {'status': 'ok', 'message': 'Account nuked successfully'})
self.wfile.write(bytes('{"status": "ok"}', "utf-8")) return echo(self, {'status': 'error', 'message': '2nd parameter action not configured: {}'.format(action)})
return
self.send_response(400) if len(parts) == 3:
self.send_header("Content-type", "application/json") response(self, 200, 'json')
self.end_headers() acc_id = parts[0]
self.wfile.write(bytes('{"status": "parameters are not correct"}', "utf-8")) action = parts[1].lower()
key = parts[2].lower()
if False:
pass
elif action == 'cfg':
status, message = igmirror.account_config(acc_id, key, qs)
status = 'ok' if status else 'error'
return echo(self, {'status': status, 'message': message})
return echo(self, {'status': 'error', 'message': '2nd parameter action not configured: {}'.format(arg2)})
response(self, 400, 'json')
return echo(self, {'status': 'error', 'message': 'Parameters are not correct. Check out the API documentation'})
def response(obj, code, typ):
obj.send_response(code)
typ = typ.lower().strip()
if typ == 'html':
obj.send_header('Content-Type', 'text/html')
elif typ == 'json':
obj.send_header('Content-Type', 'application/json')
obj.end_headers()
def echo(obj, what, newline=True):
if type(what) is dict or type(what) is list:
what = json.dumps(what)
if newline:
what = what + '\n'
obj.wfile.write(bytes(what, "utf-8"))
if __name__ == "__main__": if __name__ == "__main__":
addr = '0.0.0.0' addr = '0.0.0.0'