diff --git a/plugin-server.py b/plugin-server.py new file mode 100644 index 0000000..02e15d9 --- /dev/null +++ b/plugin-server.py @@ -0,0 +1,97 @@ +#!/usr/bin/python3 + +""" +This serves lexonomy plugins +This almost just returns static files, +it only does search-and-replace for +$LOCATION$ -> location of plugin +every plugin is its own folder and if folder is +"myplugin" and this website's url is "http://example.com", +then $LOCATION$ gets the value of http://example.com/myplugin +""" + +import sys +import os.path +import mimetypes +import hashlib +from base64 import b64encode + +import redis +from flask import Flask, Response, request + +app = Flask(__name__) +redis = redis.Redis(host='localhost', port=6379, db=0) + +URL = "//plugins.lexonomy.cjvt.si" +REPLACE_STRING = "$LOCATION$" + + +@app.route("/") +def root(): + result = "

Description

"
+    result += sys.modules[__name__].__doc__
+    result += "

Url

" + result += URL + result += "

" + return result + +@app.route("/") +def plugin_root(plugin): + status = "" if os.path.isdir(plugin) else " NOT" + return "Plugin {} was{} found".format(plugin, status) + +def check_cache(full_path): + file_time = int(os.path.getmtime(full_path)) + old_file_time = 0 + status = False + + if redis.exists(full_path + ":date"): + try: + old_file_time = int(redis.get(full_path + ":date")) + status = old_file_time == file_time + except ValueError: + pass + + redis.set(full_path + ":date", file_time) + return status + + +@app.route("//") +def plugin_file(plugin, path): + full_path = "{}/{}".format(plugin, path) + + if not os.path.isfile(full_path): + return "File not found", 404 + + mt, _encoding = mimetypes.guess_type(path) + if check_cache(full_path): + result = redis.get(full_path + ":content") + status_code = 304 + else: + replace_with = "{}/{}".format(URL, plugin) + status_code = 200 + with open(full_path, 'rb') as fp: + content_bytes = fp.read() + try: + content = content_bytes.decode('UTF-8') + result = content.replace(REPLACE_STRING, replace_with) + result = result.encode('UTF-8') + except UnicodeDecodeError: + result = content_bytes + + redis.set(full_path + ":content", result) + + resp = Response(result, mimetype=mt) + resp.headers.add('Access-Control-Allow-Origin', '*') + resp.status_code = status_code + + # return everything if cached response is not allowed + if 'Cache-Control' in request.headers: + if request.headers['Cache-Control'] in ('no-cache', 'max-age=0'): + resp.status_code = 200 + + return resp + +if __name__ == '__main__': + app.run(host="0.0.0.0") +