Beispiel #1
0
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)
}
Beispiel #2
0
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)
}