-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBattleMatServer.py
More file actions
119 lines (101 loc) · 3.21 KB
/
Copy pathBattleMatServer.py
File metadata and controls
119 lines (101 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""
GPL 3 file header
"""
import importlib
import inspect
import os
import re
import socket
import traceback
import urllib
from http.server import SimpleHTTPRequestHandler, HTTPServer
from threading import Timer
from urllib import parse
from Server.RequestHandler import RequestHandler
from Server.ServerDataManager import ServerDataManager
from Server.Utilities import ClassLoader
class BattleMatServer(SimpleHTTPRequestHandler):
"""
This class manages a web service
"""
# Following is a list of all services and their corresponding handler
# noinspection SpellCheckingInspection
handler = {}
webAppDirectory = None
topDirectory = './webApp/' # path to top of file tree
def __init__(self, *args, **kwargs):
super(BattleMatServer, self).__init__(*args, directory=BattleMatServer.webAppDirectory, **kwargs)
def do_GET(self):
super(BattleMatServer, self).do_GET()
def do_POST(self):
"""
Handle POST requests.
This expects a request and it parameters to be included in the parts.
It will use the request data to look up the proper handler
"""
self.topDirectory = BattleMatServer.topDirectory
urlParts = urllib.parse.urlsplit(self.path)
parameters = urllib.parse.parse_qs(urlParts.query)
returnCode = 200
returnData = ''
rawData = ''
try:
# print(f'Handling request')
content_type = self.headers['content-type']
if 'multi' not in content_type: # if not multipart then just read the data for the handlers
content_length = int(self.headers["Content-Length"])
rawData = self.rfile.read(content_length)
requestType = parameters['request'][0]
# print(f' Request type {requestType}')
# look up proper handler for request
requestHandler = BattleMatServer.handler.get(requestType)
if requestHandler is not None:
returnData = requestHandler.handleRequest(self, parameters, rawData)
else:
print(f'need handler {requestType}')
returnData = 'Bad request'
except (Exception,):
traceback.print_exc()
returnCode = 400
self.send_response(returnCode)
self.end_headers()
self.wfile.write(bytes(returnData, 'utf-8'))
def log_message(self, format, *args):
pass
@staticmethod
def startTimer():
"""
Run a periodic timer to handle time based tasks.
This can include saving dirty data or flushing stale caches
"""
t = Timer(5.0, BattleMatServer.periodicTimer)
t.start()
@staticmethod
def periodicTimer():
ServerDataManager.periodicTimer()
BattleMatServer.startTimer()
@staticmethod
def setupService():
path = './Server/RequestHandlers'
classes = ClassLoader().loadClasses(path, RequestHandler)
for cls in classes:
BattleMatServer.handler[cls.serviceName()] = cls
pass
pass
def run(server_class=HTTPServer, handler_class=BattleMatServer, host=None, port=8080, hostDirectory='./webApp'):
if not host:
host = socket.gethostbyname(socket.gethostname())
server_address = (host, port)
BattleMatServer.webAppDirectory = hostDirectory
httpd = server_class(server_address, handler_class)
print(f'Starting battle mat server http://{host}:{port}')
BattleMatServer.setupService()
BattleMatServer.startTimer()
print(f'Run Forever')
httpd.serve_forever()
if __name__ == "__main__":
from sys import argv
if len(argv) == 2:
run(port=int(argv[1]))
else:
run()