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
|
// ideez is a web application that allows people to post their ideas, it is meant to help
// brainstorming.
package main
import (
"crypto/rand"
"encoding/hex"
"errors"
"html/template"
"log"
"net/http"
"os"
"strings"
_ "embed"
)
type ServersPageData struct {
Ideezes []Ideez
Address template.URL
Error string
}
const (
// Name of the directory where the data files are stored
DATA_DIR = "ideez_servers"
)
var address string = "localhost:15118"
//go:embed templates/servers.html
var servers_html string
// All servers that are currently managed
var Ideezes []Ideez
// Directory path where the data files are stored
var DataDir string
func getAddress(r *http.Request) template.URL {
p, ok := r.Header["X-Forwarded-Proto"]
if ok {
return template.URL(p[0] + "://" + r.Host)
}
if r.TLS == nil {
return template.URL("http://" + r.Host)
} else {
return template.URL("https://" + r.Host)
}
}
func main() {
var (
logger = log.New(os.Stdout, "Ideez: ", log.Ldate)
)
mux := http.NewServeMux()
fs := http.FileServer(http.Dir("assets/"))
mux.Handle("/static/", http.StripPrefix("/static/", fs))
tmpl, err := template.New("servers").Parse(servers_html)
// list servers
mux.HandleFunc("GET /{$}", func(w http.ResponseWriter, r *http.Request) {
tmpl.ExecuteTemplate(w, "servers", ServersPageData{Ideezes, getAddress(r), ""})
})
// create a new server
mux.HandleFunc("POST /server/create/", func(w http.ResponseWriter, r *http.Request) {
addr := getAddress(r)
name := r.FormValue("name")
logger.Println("Create server", name)
if name == "" {
tmpl.ExecuteTemplate(w, "servers", ServersPageData{Ideezes, addr, "You must provide a title"})
return
}
for _, v := range Ideezes {
if v.Name == name {
tmpl.ExecuteTemplate(w, "servers", ServersPageData{Ideezes, addr, "A server with name '" + name + "' already exists!"})
return
}
}
bytes := make([]byte, SERVER_ID_BYTES)
_, err := rand.Read(bytes)
if err != nil {
panic(err)
}
id := hex.EncodeToString(bytes)
server := NewIdeez(mux, name, id)
Ideezes = append(Ideezes, server)
http.Redirect(w, r, "/", http.StatusMovedPermanently)
})
// import the servers from the data files
{
p := os.Getenv("XDG_CACHE_HOME")
if p == "" {
p = "."
}
DataDir = p + "/" + DATA_DIR
if err := os.Mkdir(DataDir, 0755); err == nil {
logger.Println("Directory does not exist, creating " + DataDir)
} else if !errors.Is(err, os.ErrExist) {
panic(err)
}
entries, err := os.ReadDir(DataDir)
if err != nil {
panic(err)
}
counter := 0
for _, file := range entries {
if !strings.HasSuffix(file.Name(), ".data") {
continue
}
id := strings.TrimSuffix(file.Name(), ".data")
ideez := NewIdeez(mux, "", id)
Ideezes = append(Ideezes, ideez)
counter++
}
logger.Printf("Imported %d Ideezes\n", counter)
}
logger.Println("Listening on http://" + address)
err = http.ListenAndServe(address, mux)
if err != nil {
panic(err)
}
}
|