func HandleCreateMessage(ctx context.Context, w http.ResponseWriter, r *http.Request) { uid, ok := CurrentUserID(r) if !ok { // TODO - redirect to authentication page, but remember form content tmpl.Render500(w, errors.New("not implemented")) return } tid, err := strconv.Atoi(param(ctx, "topicid")) if err != nil || tid < 0 { tmpl.Render404(w, "Topic does not exist") return } content := strings.TrimSpace(r.FormValue("content")) if len(content) < 3 { tmpl.Render400(w, "Message too short") return } if len(content) > 20000 { tmpl.Render400(w, "Message too long") return } tx, err := DB(ctx).Beginx() if err != nil { tmpl.Render500(w, err) return } defer tx.Rollback() store := NewStore(tx) t, err := store.TopicByID(uint(tid)) if err != nil { if err == ErrNotFound { tmpl.Render404(w, "Topic does not exist") } else { tmpl.Render500(w, err) } return } m, err := store.CreateMessage(t.TopicID, uid, content, time.Now()) if err != nil { tmpl.Render500(w, err) return } if err := tx.Commit(); err != nil { tmpl.Render500(w, err) return } murl := fmt.Sprintf( "/t/%d/%s?page=%d#m%d", t.TopicID, t.Topic.Slug(), t.Pages(), m.MessageID) http.Redirect(w, r, murl, http.StatusFound) }
func HandleCreateTopic(ctx context.Context, w http.ResponseWriter, r *http.Request) { uid, ok := CurrentUserID(r) if !ok { // TODO - redirect to authentication page, but remember form content tmpl.Render500(w, errors.New("not implemented")) return } var c struct { Title string TitleErr string Category uint CategoryErr string Categories []*Category Content string ContentErr string } if r.Method == "GET" { if cats, err := NewStore(DB(ctx)).Categories(); err != nil { tmpl.Render500(w, err) } else { c.Categories = cats tmpl.Render(w, http.StatusOK, "page_create_topic", c) } return } if err := r.ParseMultipartForm(2 << 20); err != nil { tmpl.Render400(w, err.Error()) return } c.Content = strings.TrimSpace(r.FormValue("content")) c.Title = strings.TrimSpace(r.FormValue("title")) if len(c.Title) < 3 { c.TitleErr = "Title must be at least 3 characters long" } if len(c.Title) > 200 { c.TitleErr = "Title must not be longer than 200 characters" } if len(c.Content) < 3 { c.ContentErr = "Content must be at least 3 characters long" } if len(c.Content) > 10000 { c.ContentErr = "Content must be shorter than 10000 characters" } if raw := r.FormValue("category"); raw == "" { c.CategoryErr = "Category is required" } else { if cat, err := strconv.Atoi(r.FormValue("category")); err == nil { c.Category = uint(cat) } else { c.CategoryErr = "Invalid category" } } if c.TitleErr != "" || c.ContentErr != "" || c.CategoryErr != "" { if cats, err := NewStore(DB(ctx)).Categories(); err != nil { tmpl.Render500(w, err) } else { c.Categories = cats tmpl.Render(w, http.StatusBadRequest, "page_create_topic", c) } return } tx, err := DB(ctx).Beginx() if err != nil { tmpl.Render500(w, err) return } defer tx.Rollback() store := NewStore(tx) now := time.Now() topic, err := store.CreateTopic(c.Title, uid, c.Category, now) if err != nil { tmpl.Render500(w, err) return } if _, err := store.CreateMessage(topic.TopicID, uid, c.Content, now); err != nil { tmpl.Render500(w, err) return } if err := tx.Commit(); err != nil { tmpl.Render500(w, err) return } turl := fmt.Sprintf("/t/%d/%s", topic.TopicID, topic.Slug()) http.Redirect(w, r, turl, http.StatusFound) }