-
Notifications
You must be signed in to change notification settings - Fork 3
/
falcon_website.py
123 lines (106 loc) · 4.42 KB
/
falcon_website.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
# pylint: disable=broad-except, unspecified-encoding
# pylint: disable=no-member, too-few-public-methods
"""
╔╗ ┬┌┬┐┌─┐┬ ┬┌─┐┬─┐┌─┐┌─┐ ╔╦╗┌─┐─┐ ┬ ╦ ╦─┐ ┬
╠╩╗│ │ └─┐├─┤├─┤├┬┘├┤ └─┐ ║║├┤ ┌┴┬┘ ║ ║┌┴┬┘
╚═╝┴ ┴ └─┘┴ ┴┴ ┴┴└─└─┘└─┘ ═╩╝└─┘┴ └─ ╚═╝┴ └─
Bitshares Decentralized Exchange User Experience
Add resource endpoints to falcon App
Run with
`uvicorn falcon_website:APP`
or similar hosting engine
"""
# STANDARD MOUDLES
import os
import traceback
# THIRD PARTY MODULES
import falcon
import falcon.asgi
from config import DEFAULT_PAIR
# BITSHARES DEX UX MODULES
from utilities import it
class FileResource:
"""
Serve a static file, including HTML, JavaScript, CSS, and text files.
The content type of the response is automatically determined based on the extension.
Additionally, the resource can be customized for specific HTML pages
with placeholder values for data such as pair, currency, asset, and contract.
"""
def __init__(self, filen):
"""
Initialize the class with the file name to be served.
Parameters:
filen (str): The name of the file to be served.
"""
self.resource = filen
async def on_get(self, req, resp):
"""
Handle GET requests by sending the contents of the file
specified in `self.resource` in the response.
:param req: The request object from Falcon.
:type req: falcon.Request
:param resp: The response object from Falcon.
:type resp: falcon.Response
"""
req_params = {k.strip("?'\"&"): v.strip("?'\"&") for k, v in req.params.items()}
try:
# Set the response content type based on the file extension.
if self.resource.endswith(".html"):
resp.content_type = falcon.MEDIA_HTML
elif self.resource.endswith(".js"):
resp.content_type = falcon.MEDIA_JS
elif self.resource.endswith("css"):
resp.content_type = "text/css"
else:
resp.content_type = "text/plain"
# Open the file, read its contents, and close it.
with open(
self.resource, "r" if resp.content_type != "text/plain" else "rb"
) as handle:
data = handle.read()
# If the file is "order_book.html", replace placeholder values in the file with values from the request params.
if self.resource == "order_book.html":
data = data.replace(
"<<<pair>>>",
req_params.get("pair", DEFAULT_PAIR)
.replace("_", ":")
.strip("?'\"&"),
)
data = data.replace(
"<<<currency>>>",
req_params.get("pair", DEFAULT_PAIR)
.replace("_", ":")
.split(":")[1]
.strip("?'\"&"),
)
data = data.replace(
"<<<asset>>>",
req_params.get("pair", DEFAULT_PAIR)
.replace("_", ":")
.split(":")[0]
.strip("?'\"&"),
)
data = data.replace(
"<<<contract>>>", req_params.get("contract", "1.0.0").strip("?'\"&")
)
# Set the response text and log the result.
resp.text = data
print(it("green", "INFO: ") + f"{self.resource.ljust(50)} 200")
resp.status = falcon.HTTP_200
except Exception:
print(it("red", "ERROR: ") + f"{self.resource.ljust(50)} 500")
resp.status = falcon.HTTP_500
traceback.print_exc()
assets = []
for path, currentDirectory, files in os.walk("assets/"):
assets.extend(f"/{os.path.join(path, file)}" for file in files)
print("\033c")
ui = falcon.asgi.App()
ui.add_route("/exchange.html", FileResource("order_book.html"))
ui.add_route("/index.html", FileResource("landing.html"))
ui.add_route("/main.js", FileResource("main.js"))
ui.add_route("/buttons.css", FileResource("buttons.css"))
ui.add_route("/barchart.css", FileResource("barchart.css"))
for asset in assets:
# print(asset)
ui.add_route(asset, FileResource(asset[1:]))