package main import ( "io" "os" "log" "fmt" "path" "time" "strconv" "strings" "net/http" "math/rand" "path/filepath" ) var seededRand *rand.Rand = nil type ConfirmContext struct { Action string Message string OnYes string OnNo string } func randomString(length int) string { charset := "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789" b := make([]byte, length) for i := range b { b[i] = charset[seededRand.Intn(len(charset)-1)] } return string(b) } func managerIndexView(w http.ResponseWriter, r * http.Request) { var err error defer func() { if err != nil { errlog.Println(err) return500(w,r) err = nil return } } () if len(strings.TrimPrefix(r.URL.Path, "/")) > 0 { return404(w,r) return } context := Context{ Comics: nil, Title: "Black Ram Comics Manager", } comics, err := allComics() if err != nil { return } for i, comic := range comics { context.Comics = append(context.Comics, struct { No int Title string Date string Image string }{ Title: comic.Title, No: i+1, Date: comic.DateTime, Image: comic.Image, }) } err = executeTemplate(w, "manager", context) } func managerRemoveView(w http.ResponseWriter, r * http.Request) { tmp := strings.TrimPrefix(r.URL.Path, "/remove/") path := strings.TrimRight(tmp, "/confirmed") isConfirmed := strings.TrimPrefix(strings.TrimPrefix(tmp, path), "/") == "confirmed" i, err := strconv.Atoi(path) if err != nil { return404(w, r) return } comic, err := getComic(i-1) if err != nil { return404(w, r) return } if !isConfirmed { err = executeTemplate(w, "confirm", ConfirmContext{ Action: fmt.Sprintf("Remove %s", comic.Title), Message: fmt.Sprintf("Are you sure you want to remove \"%s\"", comic.Title), OnYes: fmt.Sprintf("/remove/%d/confirmed", i), OnNo: "/", }) if err != nil { return500(w, r) return } return } err = deleteComic(comic.ID) if err != nil { return500(w, r) return } http.Redirect(w, r, "/", http.StatusSeeOther) } func managerPublishView(w http.ResponseWriter, r * http.Request) { var err error if r.Method == "GET" { http.Redirect(w, r, "/", http.StatusSeeOther) return } if r.Method != "POST" { return404(w, r) return } defer func() { if err != nil { errlog.Println(err) return500(w, r) } } () r.ParseMultipartForm(options.UploadSize * (1 << 20)) file, handler, err := r.FormFile("image") if err != nil { return } defer file.Close() title := r.FormValue("title") if len(title) > 80 { title = title[:80] } ext := path.Ext(handler.Filename) filename := randomString(10)+ext f, err := os.OpenFile(filepath.Join(options.MediaPath, filename), os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return } defer f.Close() io.Copy(f, file) err = newComic(title, filename, "", "") if err != nil { return } http.Redirect(w, r, "/", http.StatusSeeOther) } func managerEditView(w http.ResponseWriter, r * http.Request) { } func startManager(address string, port int, dbPath string, mediaPath string) error { seededRand = rand.New(rand.NewSource(time.Now().UnixNano())) http.HandleFunc("/", managerIndexView) http.HandleFunc("/edit/", managerEditView) http.HandleFunc("/remove/", managerRemoveView) http.HandleFunc("/publish", managerPublishView) uri := fmt.Sprintf("%s:%d", address, port) log.Println("listening to http://" + uri) return http.ListenAndServe(uri, logRequest(http.DefaultServeMux)) }