1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: Apache-2.0
4
5package main
6
7import (
8 "embed"
9 "fmt"
10 "io"
11 "net/http"
12 "net/url"
13 "strings"
14 "text/template"
15)
16
17//go:embed static
18var fs embed.FS
19
20func rootHandler(w http.ResponseWriter, r *http.Request) {
21 req <- struct{}{}
22 data := <-res
23 tmpl := template.Must(template.ParseFS(fs, "static/home.html"))
24 if err := tmpl.Execute(w, data); err != nil {
25 fmt.Println(err)
26 }
27}
28
29func newHandler(w http.ResponseWriter, r *http.Request) {
30 params := r.URL.Query()
31 action := bmStrict.Sanitize(params.Get("action"))
32 if r.Method == http.MethodGet {
33 if action == "" {
34 tmpl := template.Must(template.ParseFS(fs, "static/new.html"))
35 if err := tmpl.Execute(w, nil); err != nil {
36 fmt.Println(err)
37 }
38 } else if action != "delete" {
39 url := bmStrict.Sanitize(params.Get("url"))
40 if url == "" {
41 w.WriteHeader(http.StatusBadRequest)
42 w.Write([]byte("No URL provided"))
43 return
44 }
45
46 forge := bmStrict.Sanitize(params.Get("forge"))
47 if forge == "" {
48 w.WriteHeader(http.StatusBadRequest)
49 w.Write([]byte("No forge provided"))
50 return
51 }
52
53 name := bmStrict.Sanitize(params.Get("name"))
54 if name == "" {
55 w.WriteHeader(http.StatusBadRequest)
56 w.Write([]byte("No name provided"))
57 return
58 }
59
60 proj := project{
61 URL: url,
62 Name: name,
63 Forge: forge,
64 }
65 proj, err := getReleases(proj)
66 if err != nil {
67 w.WriteHeader(http.StatusBadRequest)
68 w.Write([]byte(fmt.Sprintf("Error getting releases: %s", err)))
69 return
70 }
71 tmpl := template.Must(template.ParseFS(fs, "static/select-release.html"))
72 if err := tmpl.Execute(w, proj); err != nil {
73 fmt.Println(err)
74 }
75 } else if action == "delete" {
76 url := params.Get("url")
77 if url == "" {
78 w.WriteHeader(http.StatusBadRequest)
79 w.Write([]byte("No URL provided"))
80 return
81 }
82
83 untrack(url)
84 http.Redirect(w, r, "/", http.StatusSeeOther)
85 }
86 }
87
88 if r.Method == http.MethodPost {
89 r.ParseForm()
90 nameValue := bmStrict.Sanitize(r.FormValue("name"))
91 urlValue := bmStrict.Sanitize(r.FormValue("url"))
92 forgeValue := bmStrict.Sanitize(r.FormValue("forge"))
93 releaseValue := bmStrict.Sanitize(r.FormValue("release"))
94
95 if nameValue != "" && urlValue != "" && forgeValue != "" && releaseValue != "" {
96 track(nameValue, urlValue, forgeValue, releaseValue)
97 http.Redirect(w, r, "/", http.StatusSeeOther)
98 return
99 }
100
101 if nameValue != "" && urlValue != "" && forgeValue != "" && releaseValue == "" {
102 http.Redirect(w, r, "/new?action=yoink&name="+url.QueryEscape(nameValue)+"&url="+url.QueryEscape(urlValue)+"&forge="+url.QueryEscape(forgeValue), http.StatusSeeOther)
103 return
104 }
105
106 if nameValue == "" && urlValue == "" && forgeValue == "" && releaseValue == "" {
107 w.WriteHeader(http.StatusBadRequest)
108 w.Write([]byte("No data provided"))
109 return
110 }
111 }
112}
113
114func staticHandler(writer http.ResponseWriter, request *http.Request) {
115 resource := strings.TrimPrefix(request.URL.Path, "/")
116 // if path ends in .css, set content type to text/css
117 if strings.HasSuffix(resource, ".css") {
118 writer.Header().Set("Content-Type", "text/css")
119 } else if strings.HasSuffix(resource, ".js") {
120 writer.Header().Set("Content-Type", "text/javascript")
121 }
122 home, err := fs.ReadFile(resource)
123 if err != nil {
124 fmt.Println(err)
125 }
126 if _, err = io.WriteString(writer, string(home)); err != nil {
127 fmt.Println(err)
128 }
129}