Just need to add the message and reply buttton, aswell as make it look nice
This commit is contained in:
parent
37644e7faf
commit
a818185978
21
go.mod
Normal file
21
go.mod
Normal file
@ -0,0 +1,21 @@
|
||||
module git.wenn.homes/t/comments_engine.git
|
||||
|
||||
go 1.22.5
|
||||
|
||||
require (
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/yuin/goldmark v1.7.4 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||
modernc.org/libc v1.55.3 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.31.1 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
)
|
||||
31
go.sum
Normal file
31
go.sum
Normal file
@ -0,0 +1,31 @@
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
|
||||
github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
|
||||
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs=
|
||||
modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
205
main.go
Normal file
205
main.go
Normal file
@ -0,0 +1,205 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/yuin/goldmark"
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Message_id int64
|
||||
Message template.HTML
|
||||
parent_message sql.NullInt64
|
||||
Username string
|
||||
message_time int64
|
||||
Message_time string
|
||||
Children []Message
|
||||
}
|
||||
var db_pool *sql.DB
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
db_pool, err = sql.Open("sqlite", "db.sqlite")
|
||||
if err != nil {
|
||||
log.Fatal(err.Error());
|
||||
}
|
||||
defer db_pool.Close()
|
||||
db_pool.SetMaxIdleConns(3)
|
||||
db_pool.SetMaxOpenConns(3)
|
||||
db_pool.SetConnMaxLifetime(0)
|
||||
create_schema()
|
||||
|
||||
|
||||
router := http.NewServeMux();
|
||||
router.HandleFunc("POST /key/{page_id}/reply/{message_id}/", answer_message)
|
||||
router.HandleFunc("POST /key/{page_id}/", send_message)
|
||||
router.HandleFunc("GET /key/{page_id}/", get_messages)
|
||||
router.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request){http.ServeFileFS(w, r, os.DirFS("templates"), "index.html")})
|
||||
router.HandleFunc("GET /style.css", func(w http.ResponseWriter, r *http.Request){http.ServeFileFS(w, r, os.DirFS("templates"), "style.css")})
|
||||
fmt.Print("Listening at :8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", router))
|
||||
|
||||
}
|
||||
|
||||
func create_schema() {
|
||||
schema, _ := os.ReadFile("schema.sql")
|
||||
fmt.Println(string(schema))
|
||||
_, err := db_pool.Exec(string(schema))
|
||||
if err != nil {
|
||||
err_str := err.Error();
|
||||
if err_str != "SQL logic error: table \"Messages\" already exists (1)" && err_str != "SQL logic error: table \"Boards\" already exists (1)" {
|
||||
fmt.Println(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func send_message (writer http.ResponseWriter, request *http.Request) {
|
||||
if err := request.ParseForm(); err != nil {
|
||||
log.Println(err.Error());
|
||||
return
|
||||
}
|
||||
username := request.PostForm["username"][0]
|
||||
message_md := request.PostForm["message"][0]
|
||||
page_id := request.PathValue("page_id")
|
||||
var message_html bytes.Buffer
|
||||
if err := goldmark.Convert([]byte(message_md), &message_html); err != nil {
|
||||
log.Println(err.Error())
|
||||
writer.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
stmt, err := db_pool.Prepare(`
|
||||
INSERT INTO Boards (board_name)
|
||||
SELECT $1
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM Boards WHERE board_name = $1
|
||||
);
|
||||
|
||||
SELECT board_id FROM Boards WHERE board_name = $1;
|
||||
INSERT INTO Messages (board_id, message, username, message_date)
|
||||
VALUES ( (SELECT board_id FROM Boards WHERE board_name = $1), $2, $3, $4 )
|
||||
`)
|
||||
defer stmt.Close()
|
||||
if _, err = stmt.Exec(
|
||||
page_id,
|
||||
message_html.Bytes(),
|
||||
username,
|
||||
time.Now().Unix()); err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("Send message")
|
||||
io.WriteString(writer, "Success")
|
||||
}
|
||||
|
||||
func answer_message (writer http.ResponseWriter, request *http.Request) {
|
||||
if err := request.ParseForm(); err != nil {
|
||||
log.Println(err.Error());
|
||||
return
|
||||
}
|
||||
username := request.PostForm["username"][0]
|
||||
message_md := request.PostForm["message"][0]
|
||||
parent_message := request.PathValue("message_id")
|
||||
page_id := request.PathValue("page_id")
|
||||
var message_html bytes.Buffer
|
||||
if err := goldmark.Convert([]byte(message_md), &message_html); err != nil {
|
||||
log.Println(err.Error())
|
||||
writer.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
stmt, err := db_pool.Prepare(`
|
||||
INSERT INTO Messages (board_id, parent_message_id, message, username, message_date)
|
||||
VALUES ( (SELECT board_id FROM Boards WHERE board_name = $1), $2, $3, $4, $5 )
|
||||
`)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
defer stmt.Close()
|
||||
if _, err = stmt.Exec(
|
||||
page_id,
|
||||
parent_message,
|
||||
message_html.Bytes(),
|
||||
username,
|
||||
time.Now().Unix()); err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
log.Println("Answer message")
|
||||
io.WriteString(writer, "Success")
|
||||
}
|
||||
|
||||
func get_messages (writer http.ResponseWriter, request *http.Request) {
|
||||
rows, err := db_pool.Query(`
|
||||
SELECT * FROM Messages WHERE board_id=(SELECT board_id FROM Boards WHERE board_name = ?)
|
||||
ORDER BY parent_message_id
|
||||
`, request.PathValue("page_id"))
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
var messages []Message
|
||||
|
||||
for rows.Next() {
|
||||
next_message := Message{}
|
||||
var board_id sql.NullInt64
|
||||
if err := rows.Scan(
|
||||
&next_message.Message_id,
|
||||
&board_id,
|
||||
&next_message.parent_message,
|
||||
&next_message.Message,
|
||||
&next_message.Username,
|
||||
&next_message.message_time,
|
||||
); err != nil {
|
||||
log.Println(err.Error())
|
||||
continue
|
||||
}
|
||||
next_message.Message_time = time.Unix(next_message.message_time,0).Format("1/2/2006 at 3:04 PM UTC")
|
||||
messages = add_message_to_tree(messages, next_message)
|
||||
}
|
||||
tmpl, err := template.ParseFiles("templates/feed.html")
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if err = tmpl.Execute(writer, messages); err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func add_message_to_tree(messages []Message, message Message) []Message {
|
||||
if !message.parent_message.Valid {
|
||||
messages = append(messages, message)
|
||||
return messages
|
||||
}
|
||||
for parent_message_index := range messages {
|
||||
if add_message_to_tree_recursive(&messages[parent_message_index] , message) {
|
||||
return messages
|
||||
}
|
||||
}
|
||||
log.Println("Not found")
|
||||
return messages
|
||||
}
|
||||
func add_message_to_tree_recursive(parent *Message, message Message) bool {
|
||||
if parent.Message_id == message.parent_message.Int64 {
|
||||
parent.Children = append(parent.Children, message)
|
||||
return true
|
||||
}
|
||||
for child_index := range parent.Children {
|
||||
if add_message_to_tree_recursive(&parent.Children[child_index], message) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
16
schema.sql
Normal file
16
schema.sql
Normal file
@ -0,0 +1,16 @@
|
||||
CREATE TABLE "Messages" (
|
||||
"message_id" INTEGER,
|
||||
"board_id" INTEGER,
|
||||
"parent_message_id" INTEGER,
|
||||
"message" BLOB,
|
||||
"username" TEXT,
|
||||
"message_date" TEXT,
|
||||
FOREIGN KEY("board_id") REFERENCES "Boards"("board_id"),
|
||||
FOREIGN KEY("parent_message_id") REFERENCES "Messages"("message_id"),
|
||||
PRIMARY KEY("message_id")
|
||||
);
|
||||
CREATE TABLE "Boards" (
|
||||
"board_id" INTEGER,
|
||||
"board_name" TEXT,
|
||||
PRIMARY KEY("board_id")
|
||||
);
|
||||
9
tailwind.config.js
Normal file
9
tailwind.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["templates/*.html"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
0
tailwind_listen.sh
Normal file
0
tailwind_listen.sh
Normal file
46
templates/feed.html
Normal file
46
templates/feed.html
Normal file
@ -0,0 +1,46 @@
|
||||
{{ define "message_reply" }}
|
||||
|
||||
|
||||
{{ end }}
|
||||
|
||||
{{ define "the_child_message" }}
|
||||
<div class="mb-4 mt-4 border border-black p-2 ">
|
||||
<div class="flex text-gray-800 text-sm">
|
||||
<div class="font-semibold">
|
||||
{{ .Username }}
|
||||
</div>
|
||||
  
|
||||
<div class="font-soft">
|
||||
{{ .Message_time }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-lg p-1">
|
||||
{{ .Message }}
|
||||
</div>
|
||||
<div class="">
|
||||
<details >
|
||||
<summary class="text-base text-sky-500 font-bold">
|
||||
Reply
|
||||
</summary>
|
||||
<div>
|
||||
En massa text
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
{{ range .Children }}
|
||||
<div class="">
|
||||
{{ template "the_child_message" . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<!doctype html>
|
||||
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
|
||||
|
||||
<div class="container bg-green-200 p-4">
|
||||
{{ range . }}
|
||||
{{ template "the_child_message" . }}
|
||||
{{ end }}
|
||||
</div>
|
||||
14
templates/index.html
Normal file
14
templates/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
<iframe src="/key/somepage/" width="800" height="600" frameborder="5"></iframe>
|
||||
|
||||
<h1>Medelande</h1>
|
||||
<form action="/key/somepage/" method="POST">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
<br><br>
|
||||
<label for="message">Message:</label>
|
||||
<textarea id="message" name="message" rows="4" cols="50" required></textarea>
|
||||
<br><br>
|
||||
<button type="submit">Send</button>
|
||||
</form>
|
||||
|
||||
4
templates/main.css
Normal file
4
templates/main.css
Normal file
@ -0,0 +1,4 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
1
templates/style.css
Normal file
1
templates/style.css
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user