+26
-9
sketch/gamma.py
+26
-9
sketch/gamma.py
···
18
18
# renderer config
19
19
scale_power = 12
20
20
scale = 2 ** scale_power
21
-
origin = -0.5, 0.5
22
-
span = 1, 1
21
+
origin = 0, 0
22
+
span = 15, 15
23
23
stretch = 1, 1
24
24
zooms = [
25
-
((0.45, 0.55), (0.3,0.4)),
26
-
((0.25, 0.5), (0.25,0.5))
27
25
]
28
26
29
27
# particle distribution: sample domain points
···
66
64
core = math.sqrt(2 * math.pi) * torch.exp(t * torch.log(zpos) - zpos)
67
65
z[~reflect] = core
68
66
return z
67
+
68
+
69
+
a = 2.0j
70
+
b = 2.0
71
+
kernel_xs = torch.tensor([a + b, a - b, -a + b, -a - b], device=device)
72
+
kernel_xs -= kernel_xs.mean()
73
+
74
+
def velu_like(z):
75
+
acc = z
76
+
for xQ in kernel_xs:
77
+
acc += 1 / (z - xQ)
78
+
return acc
69
79
70
80
71
81
def gamma_to_rgb(gz):
···
118
128
# compute Gamma(p)
119
129
gz = grid.clone()#gamma_approx(p_positions)
120
130
121
-
for i in range(20):
122
-
gz = gamma_approx(gz)
131
+
for i in range(2):
132
+
gz = gamma_approx(gz)#velu_like(gz)
123
133
124
134
naniter += gz.isnan() * 1.0
125
135
···
131
141
#insert_at_coords(coords, rgb, scratch, mapping)
132
142
133
143
134
-
scratch[:,:,0] = gz.real
135
-
scratch[:,:,2] = gz.imag
136
-
scratch[:,:,1] = naniter / naniter.max()
144
+
#scratch[:,:,0] = gz.real
145
+
#scratch[:,:,2] = gz.imag
146
+
#scratch[:,:,1] = naniter / naniter.max()
147
+
148
+
scratch[:,:,0] = (torch.angle(gz) + math.pi)
149
+
scratch[:,:,1] = torch.log(torch.abs(gz) + 1e-12) / 30
150
+
scratch[:,:,1] /= scratch[:,:,2].max()
151
+
scratch[:,:,2] = torch.cos(scratch[:,:,0] / 2)
152
+
scratch[:,:,0] = torch.abs(torch.sin(scratch[:,:,0] / 2))
153
+
137
154
138
155
# normalization/centering like plume_c does
139
156
#scratch[:,:,2] -= scratch[:,:,2].mean()
+120
-44
sketch/webserver.py
+120
-44
sketch/webserver.py
···
6
6
7
7
#from lib import log
8
8
9
-
# TODO make it upgrade to https instead of just fucking throwing exceptions
9
+
MODE = "local"
10
10
11
-
HOST = "0.0.0.0"
12
-
PORT = 1313
13
-
BASE_DIR = Path("./webui").resolve()
14
-
USE_SSL = False
11
+
if MODE == "local":
12
+
HOST = "0.0.0.0"
13
+
PORT, SSL_PORT = 1313, None
14
+
BASE_DIR = Path("./webui").resolve()
15
+
USE_SSL = False
16
+
SSL_CERT = "/home/ponder/ponder/certs/cert.pem"
17
+
SSL_KEY = "/home/ponder/ponder/certs/key.pem"
18
+
elif MODE == "remote":
19
+
HOST = "ponder.ooo"
20
+
PORT, SSL_PORT = 80, 443
21
+
BASE_DIR = Path("./webui").resolve()
22
+
USE_SSL = True
23
+
SSL_KEY="/etc/letsencrypt/live/ponder.ooo/privkey.pem"
24
+
SSL_CERT="/etc/letsencrypt/live/ponder.ooo/fullchain.pem"
15
25
16
26
ROUTES = {
17
27
"/": "content/main.html",
···
26
36
".orb": "text/x-orb"
27
37
}
28
38
29
-
SSL_CERT = "/home/ponder/ponder/certs/cert.pem"
30
-
SSL_KEY = "/home/ponder/ponder/certs/key.pem"
31
39
32
40
def guess_mime_type(path):
33
41
return MIME_TYPES.get(Path(path).suffix, "application/octet-stream")
···
35
43
def build_response(status_code, body=b"", content_type="text/plain"):
36
44
reason = {
37
45
200: "OK",
46
+
301: "Moved Permanently",
38
47
400: "Bad Request",
39
48
404: "Not Found",
40
49
405: "Method Not Allowed",
···
48
57
f"\r\n"
49
58
).encode() + body
50
59
51
-
def route(req_path):
52
-
if req_path == "/":
53
-
return "content/main.html"
54
-
if any(req_path.endswith(x) for x in [".html", ".png"]):
55
-
return f"content/{req_path}"
56
-
if any(req_path.endswith(x) for x in [".wgsl"]):
57
-
return f"content/wgsl/{req_path}"
58
-
if any(req_path.endswith(x) for x in [".orb"]):
59
-
return f"content/orb/{req_path}"
60
-
if req_path.endswith(".js"):
61
-
return f"js/{req_path}"
62
-
return req_path[1:]
60
+
def route(path):
61
+
path = path.relative_to('/') if path.is_absolute() else path
62
+
63
+
if path == Path():
64
+
return BASE_DIR / "content/main.html"
65
+
66
+
suffix = path.suffix
67
+
68
+
if suffix in [".html", ".png"]:
69
+
return BASE_DIR / Path("content") / path
70
+
if suffix in [".wgsl"]:
71
+
return BASE_DIR / Path("content/wgsl") / path
72
+
if suffix in [".orb"]:
73
+
return BASE_DIR / Path("content/orb") / path
74
+
if suffix in [".js"]:
75
+
return BASE_DIR / Path("js") / path
76
+
return BASE_DIR / path
63
77
64
78
def handle_request(request_data):
65
79
try:
···
71
85
if method != "GET":
72
86
return build_response(405, b"Method Not Allowed")
73
87
74
-
req_path = urlparse(unquote(raw_path)).path
88
+
req_path = Path(urlparse(unquote(raw_path)).path).resolve(strict=False)
75
89
76
-
norm_path = os.path.normpath(req_path)
90
+
routed_path = route(req_path).resolve(strict=False)
77
91
78
-
if ".." in norm_path:
92
+
if not routed_path.is_relative_to(BASE_DIR):
79
93
return build_response(400, b"Fuck You")
80
94
81
-
file_path = route(norm_path)
82
-
83
-
if not file_path:
84
-
return build_response(404, b"Not Found")
85
-
86
-
full_path = BASE_DIR / file_path
87
-
if not full_path.exists():
95
+
if not routed_path.exists():
88
96
return build_response(404, b"File not found")
89
97
90
-
with open(full_path, "rb") as f:
98
+
with open(routed_path, "rb") as f:
91
99
body = f.read()
92
-
return build_response(200, body, guess_mime_type(file_path))
100
+
return build_response(200, body, guess_mime_type(routed_path))
93
101
94
102
except Exception as e:
95
103
return build_response(500, f"Server error: {e}".encode())
96
104
97
-
def main():
105
+
106
+
107
+
def build_redirect_response(location):
108
+
return (
109
+
f"HTTP/1.1 301 Moved Permanently\r\n"
110
+
f"Location: {location}\r\n"
111
+
f"Content-Length: 0\r\n"
112
+
f"Connection: close\r\n"
113
+
f"\r\n"
114
+
).encode()
115
+
116
+
def handle_http_redirect(conn):
117
+
request = conn.recv(4096)
118
+
try:
119
+
lines = request.decode().split("\r\n")
120
+
if lines:
121
+
method, raw_path, *_ = lines[0].split()
122
+
path = urlparse(unquote(raw_path)).path
123
+
else:
124
+
path = "/"
125
+
except:
126
+
path = "/"
127
+
redirect = build_redirect_response(f"https://{HOST}{path}")
128
+
conn.sendall(redirect)
129
+
130
+
def http_redirect_server():
131
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
132
+
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
133
+
server.bind((HOST, PORT))
134
+
server.listen()
135
+
print(f"redirecting on {HOST}:{PORT}")
136
+
while True:
137
+
try:
138
+
conn, addr = server.accept()
139
+
except KeyboardInterrupt:
140
+
break
141
+
except:
142
+
continue
143
+
with conn:
144
+
try:
145
+
handle_http_redirect(conn)
146
+
except:
147
+
pass
148
+
149
+
150
+
def ssl_main():
98
151
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
99
152
ssl_ctx.load_cert_chain(certfile=SSL_CERT, keyfile=SSL_KEY)
100
153
154
+
#threading.Thread(target=http_redirect_server, daemon=True).start()
155
+
101
156
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
102
157
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
103
-
server.bind((HOST, PORT))
158
+
server.bind((HOST, SSL_PORT))
104
159
server.listen()
105
-
print(f"Serving HTTPS on {HOST}:{PORT}")
160
+
print(f"Serving HTTPS on {HOST}:{SSL_PORT}")
106
161
while True:
107
162
try:
108
163
conn, addr = server.accept()
109
-
if USE_SSL:
110
-
with ssl_ctx.wrap_socket(conn, server_side=True) as ssl_conn:
111
-
request = ssl_conn.recv(4096)
112
-
response = handle_request(request)
113
-
ssl_conn.sendall(response)
114
-
else:
115
-
request = conn.recv(4096)
164
+
conn.settimeout(10.0)
165
+
with ssl_ctx.wrap_socket(conn, server_side=True) as ssl_conn:
166
+
request = ssl_conn.recv(4096)
116
167
response = handle_request(request)
117
-
conn.sendall(response)
168
+
ssl_conn.sendall(response)
169
+
except KeyboardInterrupt:
170
+
raise
171
+
except TimeoutError:
172
+
continue
173
+
except Exception as e:
174
+
print(f"Error: {e}")
175
+
exit()
176
+
177
+
178
+
def main():
179
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
180
+
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
181
+
server.bind((HOST, PORT))
182
+
server.listen()
183
+
print(f"Serving HTTP on {HOST}:{PORT}")
184
+
while True:
185
+
try:
186
+
conn, addr = server.accept()
187
+
request = conn.recv(4096)
188
+
response = handle_request(request)
189
+
conn.sendall(response)
118
190
except KeyboardInterrupt:
119
191
raise
120
-
except:
192
+
except Exception as e:
193
+
print(e)
121
194
break
122
195
123
196
if __name__ == "__main__":
124
-
main()
197
+
if USE_SSL:
198
+
ssl_main()
199
+
else:
200
+
main()