-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdataserver.py
154 lines (131 loc) · 6.07 KB
/
dataserver.py
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import requests
import re
import http.server
from http.server import BaseHTTPRequestHandler
from lib.xiino_html_converter import XiinoHTMLParser
import base64
import yattag
def iso8859(string: str) -> bytes:
"Shorthand to convert a string to iso-8859"
return bytes(string, encoding="iso-8859-1")
class XiinoDataServer(BaseHTTPRequestHandler):
DATASERVER_VERSION = "Pre-Alpha Development Release"
COLOUR_DEPTH_REGEX = re.compile(r"\/c([0-9]*)\/")
GSCALE_DEPTH_REGEX = re.compile(r"\/g([0-9]*)\/")
SCREEN_WIDTH_REGEX = re.compile(r"\/w([0-9]*)\/")
TXT_ENCODING_REGEX = re.compile(r"\/[de]{1,2}([a-zA-Z0-9-]*)\/")
URL_REGEX = re.compile(r"\/\?(.*)\s") # damn, length sync broken :(
REQUESTS_HEADER = {
"User-Agent": "OpenXiino/1.0 (http://github.com/nicl83/openxiino) python-requests/2.27.1"
}
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
url = self.URL_REGEX.search(self.requestline)
# send magic padding xiino expects
self.wfile.write(bytes([0x00] * 12))
self.wfile.write(bytes([0x0D, 0x0A] * 2))
# TODO: real actual websites
if url:
print(url)
url = url.group(1)
if url == "http://about/":
self.about()
elif url == "http://github/":
self.github()
elif url == "http://about2/":
self.more_info()
elif url == "http://deviceinfo/":
self.device_info()
else:
print(url)
response = requests.get(url, headers=self.REQUESTS_HEADER, timeout=5)
parser = XiinoHTMLParser(base_url=response.url)
print(response.url)
parser.feed(response.text)
clean_html = parser.get_parsed_data()
self.wfile.write(clean_html.encode("latin-1", errors="ignore"))
else:
self.wfile.write(
"Invalid request! Please contact the devs.".encode("latin-1")
)
self.wfile.write(f"<br>Request: {self.requestline}".encode("latin-1"))
def about(self):
"Show the About screen."
self.__internal_file_page_handler("about.html")
def github(self):
"Show a QR code linking to my GitHub."
self.__internal_file_page_handler("github.html")
def more_info(self):
"Show more info about OpenXiino."
self.__internal_file_page_handler("about2.html")
def device_info(self):
"Show info about the device making the request."
colour_depth = self.COLOUR_DEPTH_REGEX.search(self.requestline)
gscale_depth = self.GSCALE_DEPTH_REGEX.search(self.requestline)
screen_width = self.SCREEN_WIDTH_REGEX.search(self.requestline)
txt_encoding = self.TXT_ENCODING_REGEX.search(self.requestline)
infopage = yattag.Doc()
with infopage.tag("html"):
infopage.line("title", "Device Info")
with infopage.tag("body"):
infopage.line("h1", "Device Info")
with infopage.tag("ul"):
if colour_depth:
depth = colour_depth.group(1)
with infopage.tag("li"):
infopage.line("b", f"{depth}-bit colour ")
infopage.text("reported by Xiino.")
elif gscale_depth:
depth = gscale_depth.group(1)
with infopage.tag("li"):
infopage.line("b", f"{depth}-bit grayscale ")
infopage.text("reported by Xiino.")
else:
with infopage.tag("li"):
infopage.text("Your device isn't reporting a colour depth!")
infopage.text(
"Please tell the OpenXiino devs about your Xiino version."
)
if screen_width:
width = screen_width.group(1)
with infopage.tag("li"):
infopage.line("b", f"{width}px ")
infopage.text("viewport reported by Xiino. ")
if int(width) > 153:
infopage.text("This is a high-density device.")
else:
with infopage.tag("li"):
infopage.text("Your device isn't reporting a screen width!")
infopage.text(
"Please tell the OpenXiino devs about your Xiino version."
)
if txt_encoding:
encoding = txt_encoding.group(1)
with infopage.tag("li"):
infopage.text("Your text encoding is set to ")
infopage.stag("br")
infopage.line("b", str(encoding))
else:
with infopage.tag("li"):
infopage.text("Your device isn't reporting an encoding!")
infopage.text(
"Please tell the OpenXiino devs about your Xiino version."
)
infopage.line("h2", "Request Headers")
infopage.line("pre", self.headers.as_string())
self.wfile.write(infopage.getvalue().encode("latin-1", errors="replace"))
def __internal_file_page_handler(self, filename: str):
"Load a page from the server's own files."
with open(filename, encoding="utf-8") as handle:
self.wfile.write(handle.read().encode("latin-1", errors="replace"))
if __name__ == "__main__":
web_server = http.server.HTTPServer(("0.0.0.0", 4040), XiinoDataServer)
print("Dataserver running on port 4040")
try:
web_server.serve_forever()
except KeyboardInterrupt:
pass
web_server.server_close()
print("Dataserver stopped.")