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