143 lines
5.5 KiB
Python
Executable File
143 lines
5.5 KiB
Python
Executable File
import rsgdnd.utils as utils
|
|
import rsgdnd.server as server
|
|
import threading
|
|
import importlib
|
|
import time
|
|
import json
|
|
import sys
|
|
import os
|
|
|
|
services = {}
|
|
service_defs = {}
|
|
services_mtime = 0
|
|
services_running = False
|
|
services_lock = threading.Lock()
|
|
|
|
def get_callback(self, in_path, response):
|
|
global services_lock
|
|
in_path = in_path.replace("\\", "/")
|
|
utils.log("==================")
|
|
utils.log(f"server: in coming path '{in_path}'")
|
|
utils.log("==================")
|
|
# pass through
|
|
handled = []
|
|
with services_lock:
|
|
for k, service in services.items():
|
|
callback = "get_callback"
|
|
callback = service[callback] if callback in service else None
|
|
if callback and callback(self, in_path, response):
|
|
handled.append(k)
|
|
|
|
if len(handled) > 1:
|
|
utils.log(f"server: {in_path} handled by multiple services, is that intended? "+",".join(handled))
|
|
|
|
return len(handled) != 0
|
|
|
|
def post_callback(self, in_path, data, response):
|
|
global services_lock
|
|
in_path = in_path.replace("\\", "/")
|
|
utils.log("==================")
|
|
utils.log(f"server: in coming path '{in_path}'")
|
|
utils.log("==================")
|
|
# pass through
|
|
handled = []
|
|
with services_lock:
|
|
for k, service in services.items():
|
|
callback = "post_callback"
|
|
callback = service[callback] if callback in service else None
|
|
if callback and callback(self, in_path, data, response):
|
|
handled.append(k)
|
|
|
|
if len(handled) > 1:
|
|
utils.log(f"server: {in_path} handled by multiple services, is that intended? "+",".join(handled))
|
|
|
|
return len(handled) != 0
|
|
|
|
def service_update():
|
|
global services
|
|
global service_defs
|
|
global services_mtime
|
|
global services_running
|
|
|
|
services_running = True
|
|
|
|
while services_running:
|
|
# check if service defs have updated
|
|
if services_mtime != os.stat("services.json").st_mtime:
|
|
services_mtime = os.stat("services.json").st_mtime
|
|
do_update = False
|
|
with open("services.json") as serv_json:
|
|
try:
|
|
service_defs = json.loads(serv_json.read())
|
|
do_update = True
|
|
except Exception as error:
|
|
utils.log("Failed trying to open parse services.json")
|
|
utils.log(error)
|
|
|
|
if do_update:
|
|
with services_lock:
|
|
# stop any services that shouldn't be running anymore
|
|
removals = []
|
|
for k, v in services.items():
|
|
try:
|
|
if k not in service_defs:
|
|
if "stop" in v and callable(v["stop"]):
|
|
utils.log(f"server: stopping '{k}'")
|
|
v["stop"]()
|
|
removals.append(k)
|
|
except Exception as error:
|
|
utils.log("Failed trying to stop services")
|
|
utils.log(error)
|
|
|
|
for k in removals:
|
|
utils.log(f"server: removing '{k}' from the service list")
|
|
del services[k]
|
|
|
|
# start services
|
|
for k, v in service_defs.items():
|
|
if k not in services:
|
|
try:
|
|
if k in sys.modules:
|
|
importlib.reload(sys.modules[k])
|
|
new_service = importlib.import_module(k)
|
|
services[k] = { "module": new_service }
|
|
for id in v:
|
|
if hasattr(new_service, v[id]):
|
|
services[k][id] = getattr(new_service, v[id])
|
|
else:
|
|
services[k][id] = None
|
|
|
|
if not any([id in services[k] for id in ["get_callback", "post_callback", "start", "stop"]]):
|
|
raise ValueError(k+" doesn't define any of the service interfaces.")
|
|
|
|
for func in [services[k][id] for id in ["get_callback", "post_callback", "start", "stop"] if id in services[k]]:
|
|
if not callable(func):
|
|
raise ValueError(k+" '"+func.__name__+"' is not callable")
|
|
|
|
utils.log(f"server: added '{k}' to the service list")
|
|
|
|
if "start" in services[k] and callable(services[k]["start"]):
|
|
utils.log(f"server: starting '{k}'")
|
|
services[k]["start"]()
|
|
|
|
except Exception as error:
|
|
utils.log("Failed trying to start services")
|
|
utils.log(error)
|
|
if k in services:
|
|
del services[k]
|
|
time.sleep(1)
|
|
|
|
|
|
@utils.trywrap()
|
|
def main():
|
|
global services_running
|
|
update = threading.Thread(target=service_update)
|
|
update.start()
|
|
server.run_whitelist(get_callback=get_callback, post_callback=post_callback)
|
|
services_running = False
|
|
update.join()
|
|
|
|
pass
|
|
|
|
if __name__ == "__main__":
|
|
main() |