Author: Adam Evyčędo <git@apiote.xyz>
add data directory
main.go | 3 router.go | 228 +++++++++++++++++++++++++++++---------------------------
diff --git a/main.go b/main.go index 1fa6ba809d7a51ba9e82bcb8ef0b7ec39a2be7cf..6941aa5028cd28a0d9ed003dde63eb249a637f8c 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ func main() { rand.Seed(time.Now().UnixNano()) pass := flag.String("p", "", "password") + dataDir := flag.String("d", ".", "data directory") flag.Parse() if *pass != "" { @@ -25,5 +26,5 @@ fmt.Println("Password updated") return } - route() + route(*dataDir) } diff --git a/router.go b/router.go index 1cda4aef1baedd4926d33efc57b7a2d6dec03623..cb2f57085a6d45ed68448a8418ff8f642e1ae756 100644 --- a/router.go +++ b/router.go @@ -391,129 +391,139 @@ return holidays } -func calendar(w http.ResponseWriter, r *http.Request) { - acceptLanguage := r.Header.Get("Accept-Language") - file, err := os.Open("holidays.dirty") - if err != nil { - log.Println(err) - fmt.Fprint(w, "Error 500") - return - } - holidays := []Holiday{} - err = dirty.LoadStruct(file, &holidays) - if err != nil { - log.Println(err) - log.Println(holidays) - fmt.Fprint(w, "Error 500") - return - } - t, err := template.ParseFiles("templates/calendar.ics") - if err != nil { - log.Println(err) - if os.IsNotExist(err) { - renderStatus(w, 501, acceptLanguage) - return - } - fmt.Fprint(w, "Error 500") - return - } - thisYear := time.Now().Year() - for i := 0; i < 10; i++ { - holidays = append(holidays, easter(thisYear+i)...) - } - w.Header().Set("Content-Type", "text/calendar") - err = t.Execute(w, holidays) - if err != nil { - log.Println(err) - fmt.Fprint(w, "Error 500") - return - } -} - -func shortRedirect(w http.ResponseWriter, r *http.Request) { - acceptLanguage := r.Header.Get("Accept-Language") - path := strings.Split(r.URL.Path[1:], "/") - if len(path) == 2 && path[1] == "" { - if r.Method == "" || r.Method == "GET" { - showHtml(w, "s", nil, acceptLanguage) - } else if r.Method == "POST" { - r.ParseForm() - id := r.PostForm.Get("id") - url := r.PostForm.Get("url") - password := r.PostForm.Get("password") - if id == "" { - var letters = []rune("3478ABCDEFHJKMNRTWXY") - b := make([]rune, 6) - for i := range b { - b[i] = letters[rand.Intn(len(letters))] - } - id = string(b) +func calendar(dataDir string) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + acceptLanguage := r.Header.Get("Accept-Language") + file, err := os.Open(filepath.Join(dataDir, "holidays.dirty")) + if err != nil { + if os.IsNotExist(err) { + renderStatus(w, 404, acceptLanguage) + return } else { - id = strings.ToUpper(id) - } - if url == "" { - renderStatus(w, 400, acceptLanguage) - return - } - hash, err := ioutil.ReadFile("password") - if err != nil { log.Println(err) fmt.Fprint(w, "Error 500") return } - passMatch, err := ComparePasswordAndHash(password, string(hash)) - if err != nil { - log.Println(err) - fmt.Fprint(w, "Error 500") - return - } - if !passMatch { - renderStatus(w, 403, acceptLanguage) - return - } - - // todo check duplicates - - file, err := os.OpenFile("s.toml", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) - defer file.Close() - if err != nil { - log.Println(err) - fmt.Fprint(w, "Error 500") - return - } - _, err = file.WriteString(id + " = " + url + "\n") - if err != nil { - log.Println(err) - fmt.Fprint(w, "Error 500") + } + defer file.Close() + holidays := []Holiday{} + err = dirty.LoadStruct(file, &holidays) + if err != nil { + log.Println(err) + log.Println(holidays) + fmt.Fprint(w, "Error 500") + return + } + t, err := template.ParseFiles("templates/calendar.ics") + if err != nil { + log.Println(err) + if os.IsNotExist(err) { + renderStatus(w, 501, acceptLanguage) return } - w.Header().Add("X-Redirection", "https://apiote.xyz/s/"+id) - w.WriteHeader(201) - showHtml(w, "s201", Redirection{id, url}, acceptLanguage) + fmt.Fprint(w, "Error 500") + return } - } else if len(path) != 2 { - renderStatus(w, 404, acceptLanguage) - } else { - id := strings.ToUpper(path[1]) - data, err := ioutil.ReadFile("s.toml") + thisYear := time.Now().Year() + for i := 0; i < 10; i++ { + holidays = append(holidays, easter(thisYear+i)...) + } + w.Header().Set("Content-Type", "text/calendar") + err = t.Execute(w, holidays) if err != nil { log.Println(err) fmt.Fprint(w, "Error 500") return } - for _, line := range strings.Split(string(data), "\n") { - if line == "" { - break + } +} + +func shortRedirect(dataDir string) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + acceptLanguage := r.Header.Get("Accept-Language") + path := strings.Split(r.URL.Path[1:], "/") + if len(path) == 2 && path[1] == "" { + if r.Method == "" || r.Method == "GET" { + showHtml(w, "s", nil, acceptLanguage) + } else if r.Method == "POST" { + r.ParseForm() + id := r.PostForm.Get("id") + url := r.PostForm.Get("url") + password := r.PostForm.Get("password") + if id == "" { + var letters = []rune("3478ABCDEFHJKMNRTWXY") + b := make([]rune, 6) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + id = string(b) + } else { + id = strings.ToUpper(id) + } + if url == "" { + renderStatus(w, 400, acceptLanguage) + return + } + hash, err := ioutil.ReadFile("password") + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + passMatch, err := ComparePasswordAndHash(password, string(hash)) + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + if !passMatch { + renderStatus(w, 403, acceptLanguage) + return + } + + // todo check duplicates + + file, err := os.OpenFile(filepath.Join(dataDir, "s.toml"), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + defer file.Close() + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + _, err = file.WriteString(id + " = " + url + "\n") + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") + return + } + w.Header().Add("X-Redirection", "https://apiote.xyz/s/"+id) + w.WriteHeader(201) + showHtml(w, "s201", Redirection{id, url}, acceptLanguage) } - redirection := strings.Split(line, "=") - redirectionID := strings.Trim(redirection[0], " ") - redirectionURL := strings.Trim(redirection[1], " ") - if redirectionID == id { - http.Redirect(w, r, redirectionURL, http.StatusMovedPermanently) + } else if len(path) != 2 { + renderStatus(w, 404, acceptLanguage) + } else { + id := strings.ToUpper(path[1]) + data, err := ioutil.ReadFile("s.toml") + if err != nil { + log.Println(err) + fmt.Fprint(w, "Error 500") return } + for _, line := range strings.Split(string(data), "\n") { + if line == "" { + break + } + redirection := strings.Split(line, "=") + redirectionID := strings.Trim(redirection[0], " ") + redirectionURL := strings.Trim(redirection[1], " ") + if redirectionID == id { + http.Redirect(w, r, redirectionURL, http.StatusMovedPermanently) + return + } + } + renderStatus(w, 404, acceptLanguage) } - renderStatus(w, 404, acceptLanguage) } } @@ -577,7 +587,7 @@ acceptLanguage := r.Header.Get("Accept-Language") showHtml(w, "dogtag", nil, acceptLanguage) } -func route() { +func route(dataDir string) { http.HandleFunc("/", index) http.Handle("/static/", http.FileServer(http.FS(staticFS))) @@ -587,10 +597,10 @@ http.HandleFunc("/p/", programs) http.HandleFunc("/programs/", programs) http.HandleFunc("/donate", donate) http.HandleFunc("/pgp/", pgp) - http.HandleFunc("/calendar", calendar) + http.HandleFunc("/calendar", calendar(dataDir)) http.HandleFunc("/tag", dogtag) - http.HandleFunc("/s/", shortRedirect) + http.HandleFunc("/s/", shortRedirect(dataDir)) http.HandleFunc("/short/", shortShow) http.HandleFunc("/.well-known/openpgpkey/hu/", wkd)