package pages import ( "delayed.link/storage" "embed" _ "embed" "html/template" "io/fs" "net/http" "net/url" "path/filepath" "strconv" "strings" "time" ) func CreateLink(w http.ResponseWriter, r *http.Request) *storage.Link { err := r.ParseForm() if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return nil } form := r.PostForm minutesInFutureStr := form.Get("minutes_in_future") if strings.TrimSpace(minutesInFutureStr) == "" { http.Error(w, "minutes_in_future is required", http.StatusBadRequest) return nil } minutesInFuture, err := strconv.Atoi(minutesInFutureStr) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return nil } if minutesInFuture < 0 { http.Error(w, "minutes_in_future has to be > 0", http.StatusBadRequest) } numberOfOpensStr := form.Get("number_of_opens") if strings.TrimSpace(minutesInFutureStr) == "" { http.Error(w, "number_of_opens is required", http.StatusBadRequest) return nil } numberOfOpens, err := strconv.Atoi(numberOfOpensStr) if numberOfOpens < 0 || numberOfOpens > 100 { http.Error(w, "number_of_opens needs to be between 1 and 100", http.StatusBadRequest) return nil } if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return nil } payload := form.Get("payload") //TODO: Verify payload if _, err := url.Parse(payload); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return nil } l := storage.Link{ Target: payload, OpensFrom: time.Now().Add(time.Duration(minutesInFuture) * time.Minute), OpensLeft: numberOfOpens, } l.OpensStr = l.OpensFrom.Format(time.UnixDate) id, err := l.Save(storage.Current) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return nil } (&l).Id = id return &l } var tmpl = template.New("delayed.link") func Create(w http.ResponseWriter, r *http.Request) { l := CreateLink(w, r) if l == nil { return } err := tmpl.ExecuteTemplate(w, "create", l) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } //go:embed html var pages embed.FS func init() { entries, _ := pages.ReadDir("html") for _, entry := range entries { name := entry.Name() if !entry.IsDir() && strings.HasSuffix(name, ".gohtml") { tmplName := strings.SplitN(name, ".", 2)[0] content, _ := fs.ReadFile(pages, filepath.Join("html", name)) template.Must(tmpl.New(tmplName).Parse(string(content))) } } }