Improved API readability
This commit is contained in:
parent
df7537b80e
commit
15f47b63f4
19
igmirror.py
19
igmirror.py
|
@ -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))
|
||||||
|
|
95
server.py
95
server.py
|
@ -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'
|
||||||
|
|
Loading…
Reference in New Issue