home readme diff tree note docs

0commit fa2536aba2f6d82ca86aed91e50c31598145cde1
1Author: lakefox <mason@lakefox.net>
2Date:   Thu Dec 25 11:39:08 2025 -0700
3
4    Added QA
5
6diff --git a/cgi-bin/qa.awk b/cgi-bin/qa.awk
7new file mode 100755
8index 0000000..796f63c
9--- /dev/null
10+++ b/cgi-bin/qa.awk
11@@ -0,0 +1,161 @@
12+#!/usr/bin/awk -f
13+
14+BEGIN {
15+	split(ENVIRON["QUERY_STRING"], pairs, "&")
16+	for (i in pairs) {
17+		split(pairs[i], kv, "=")
18+
19+		if (kv[1] == "action") {
20+			# reply, view, new, grep
21+			action = kv[2]
22+		} else if (kv[1] == "type") {
23+			type = kv[2]
24+		} else if (kv[1] == "site") {
25+			site = kv[2]
26+		} else if (kv[1] == "name") {
27+			name = kv[2]
28+			gsub(/\+/, " ", name)
29+			gsub(/%20/, " ", name)
30+		} else if (kv[1] == "body") {
31+			body = kv[2]
32+			gsub(/\+/, " ", body)
33+		}
34+	}
35+
36+	if (action == "") action = "view"
37+	if (name == "") name = "all"
38+
39+	print "Content-Type: text/html\r\n"
40+	print "<!DOCTYPE html>"
41+	print "<html>"
42+	print "<head>"
43+
44+	print "<title>QA: " name "</title>"
45+	print "<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>"
46+	print "<meta name='viewport' content='width=device-width, initial-scale=1'>"
47+	print "</head>"
48+	print "<body>"
49+	
50+	if (site == "") {
51+		cmd = "ls /var/qa"
52+
53+		print "<h1>QA: Sites</h1>"
54+		print "<ul>"
55+		while (cmd | getline sites) {
56+			print "<li><a href='/cgi-bin/qa.awk?site=" sites "&action=view&name=all'>" sites "/</a></li>"
57+		}
58+		close(cmd)
59+		print "</ul>"
60+	} else if (action == "view") {
61+		if (name == "all") {
62+			cmd = "ls /var/qa/" site
63+
64+			print "<h1>QA: " site "</h1>"
65+			print "<p>Select a question to view.</p>"
66+			print "<a href='/cgi-bin/qa.awk?site=" site "&action=new'>New</a>"
67+
68+			print "<ul>"
69+			while (cmd | getline file) {
70+				split(file, b, ".")
71+				if (b[2] != "comment") {
72+					print "<li><a href='/cgi-bin/qa.awk?action=view&site=" site "&name=" b[1] "'>/" b[1] "</a></li>"
73+				}
74+			}
75+			close(cmd)
76+			print "</ul>"
77+		} else {
78+			print "<h1>" name "</h1>"
79+			print "<p>"
80+
81+			file = "/var/qa/" site "/" name ".txt"
82+			while (getline line < file) {
83+				print escape_html(line)
84+			}
85+
86+			cmd = "ls -l \"" file "\""
87+			cmd | getline date
88+			close(cmd)
89+			split(date, d, " ")
90+			print "<br/><b>" d[6] " " d[7] " " d[8] "</b>"
91+
92+			print "</p>"
93+			print "<a href='/cgi-bin/qa.awk?site=" site "&action=reply&name=" name "'>Reply</a>"
94+			print "<hr/>"
95+			print "<br/>"	
96+
97+			cmd = "find /var/qa/" site " -name \"" name ".comment*\""
98+
99+			n = 0
100+			while (cmd | getline comment) {
101+				n += 1
102+			}
103+			close(cmd)
104+
105+			if (n > 0) {
106+				print "<h4>Replies</h4>"
107+			
108+				for (i = 0; i < n; i++) {
109+					cmd = "cat \"/var/qa/" site "/" name ".comment." i ".txt\""
110+					print "<p>"
111+					while (cmd | getline line) {
112+						print escape_html(line)
113+					}
114+					close(cmd)
115+					cmd = "ls -l \"/var/qa/" site "/" name ".comment." i ".txt\""
116+					cmd | getline date
117+					close(cmd)
118+					split(date, d, " ")
119+					print "<br/><b>" d[6] " " d[7] " " d[8] "</b>"
120+					print "</p>"
121+				}
122+			}
123+		}
124+	} else if (action == "new") {
125+		print "<h1>" site ":new</h1>"
126+
127+		print "<form action='/cgi-bin/qa.awk'>"
128+		print "<input name='site' type='text' value='" site "' hidden>"
129+		print "<input name='action' type='text' value='save_post' hidden>"
130+		print "<label for='name'>Title</label><br/>"
131+		print "<input type='text' name='name' id='name' placeholder='Your Question'/><br/><br/>"
132+		print "<textarea id='body' name='body'></textarea><br/><br/>"
133+		print "<input type='submit'>"
134+		print "</form>"
135+	} else if (action == "save_post") {
136+		file = "/var/qa/" site "/" name ".txt"
137+		print body > file
138+		print "<script>window.location = '/cgi-bin/qa.awk?site=" site "&action=view&name=" name "';</script>"
139+	} else if (action == "reply") {
140+		print "<h1> Reply to: " name "</h1>"
141+
142+		print "<form action='/cgi-bin/qa.awk'>"
143+		print "<input name='site' type='text' value='" site "' hidden>"
144+		print "<input name='action' type='text' value='save_reply' hidden>"
145+		print "<input name='name' type='text' value='" name "' hidden>"
146+		print "<textarea id='body' name='body'></textarea><br/><br/>"
147+		print "<input type='submit'>"
148+		print "</form>"
149+	} else if (action == "save_reply") {
150+		cmd = "find /var/qa/" site " -name \"" name ".comment*\""
151+
152+		count = 0
153+		while (cmd | getline comment) {
154+			count += 1;
155+		}
156+		close(cmd)
157+
158+		print body > "/var/qa/" site "/" name ".comment." count ".txt"
159+		print "<script>window.location = '/cgi-bin/qa.awk?site=" site "&action=view&name=" name "';</script>"
160+	}
161+	print "</body>"
162+	print "</html>"
163+}
164+
165+function escape_html(str) {
166+    gsub(/&/, "\\&amp;", str)
167+    gsub(/</, "\\&lt;", str)
168+    gsub(/>/, "\\&gt;", str)
169+    gsub(/"/, "\\&quot;", str)
170+    gsub(/'/, "\\&#39;", str)
171+    return str
172+}
173diff --git a/index.html b/index.html
174index f16df0c..25ae8ff 100644
175--- a/index.html
176+++ b/index.html
177@@ -1,5 +1,5 @@
178 <!DOCTYPE html>
179-<html>
180+<html lang="en-US">
181 	<head>
182 		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
183 		<title>git.ws</title>
184@@ -17,7 +17,7 @@
185 	</head>
186 	<body style="max-width: 900px;">
187 		<h1>git.ws</h1>
188-		<a href="/cgi-bin/mailto.awk">Mailing Lists</a> <a href="/cgi-bin/git.awk">Git</a>
189+		<a href="/cgi-bin/mailto.awk">Mailing Lists</a> <a href="/cgi-bin/git.awk">Git</a> <a href="/cgi-bin/qa.awk">QA</a>
190 		<p>
191 			git.ws is a project sharing website.
192 		</p>
193@@ -45,6 +45,12 @@
194 				<td><a target="_blank" href="https://web.libera.chat/gamja/?autojoin=#gitws">#gitws</a></td>
195 				<td><a href="http://git.ws/repo/gitws.git">http://git.ws/repo/gitws.git</a></td>
196 			</tr> 
197+			<tr>
198+				<td><a href="http://spectre.git.ws/">spectre/</a></td>
199+				<td>Fast router OS</td>
200+				<td><a target="_blank" href="https://web.libera.chat/gamja/?autojoin=#spectre">#spectre</a></td>
201+				<td><a href="http://git.ws/repo/gitws.git">http://git.ws/repo/spectre.git</a></td>
202+			</tr>
203 			</tbody>
204 		</table>
205 		<hr>