Initial: plugin-server
This commit is contained in:
		
							parent
							
								
									310ab1c5aa
								
							
						
					
					
						commit
						fc238f6c28
					
				
							
								
								
									
										97
									
								
								plugin-server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								plugin-server.py
									
									
									
									
									
										Normal file
									
								
							@ -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 = "<html><body><h2>Description</h2><pre>"
 | 
				
			||||||
 | 
					    result += sys.modules[__name__].__doc__
 | 
				
			||||||
 | 
					    result += "</pre><h2>Url</h2><p>"
 | 
				
			||||||
 | 
					    result += URL
 | 
				
			||||||
 | 
					    result += "</p></body></html>"
 | 
				
			||||||
 | 
					    return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route("/<plugin>")
 | 
				
			||||||
 | 
					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("/<plugin>/<path:path>")
 | 
				
			||||||
 | 
					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")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user