Exemple #1
0
func handleCreateTopic(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	account, ok := auth.AuthRequired(pg.DB(ctx), w, r)
	if !ok {
		return
	}

	input := struct {
		Title   string
		Tags    []string
		Content string
	}{
		Title:   r.FormValue("title"),
		Tags:    strings.Fields(r.FormValue("tags")),
		Content: r.FormValue("content"),
	}

	var errs []string
	if r.Method == "POST" {
		if input.Title == "" {
			errs = append(errs, `"title" is required`)
		}
		if input.Content == "" {
			errs = append(errs, `"content" is required`)
		}
	}

	if r.Method == "GET" || len(errs) != 0 {
		render(w, "topic_create.tmpl", input)
		return
	}

	db := pg.DB(ctx)
	tx, err := db.Beginx()
	if err != nil {
		log.Error("cannot start transaction", "error", err.Error())
		respond500(w, r)
		return
	}
	defer tx.Rollback()

	topic := Topic{
		AuthorID: int64(account.AccountID),
		Title:    input.Title,
		Tags:     input.Tags,
	}
	t, _, err := CreateTopicWithComment(tx, topic, input.Content)
	if err != nil {
		log.Error("cannot create topic with comment", "error", err.Error())
		respond500(w, r)
		return
	}

	if err := tx.Commit(); err != nil {
		log.Error("cannot commit transaction", "error", err.Error())
		respond500(w, r)
		return
	}

	http.Redirect(w, r, fmt.Sprintf("/t/%d", t.TopicID), http.StatusSeeOther)
}
Exemple #2
0
func HandleCreateNote(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	var note Note
	if err := json.NewDecoder(r.Body).Decode(&note); err != nil {
		web.JSONErr(w, err.Error(), http.StatusBadRequest)
		return
	}

	acc, ok := auth.AuthRequired(pg.DB(ctx), w, r)
	if !ok {
		return
	}

	if errs := validateNote(&note); len(errs) > 0 {
		web.JSONErrs(w, errs, http.StatusBadRequest)
		return
	}

	note.OwnerID = acc.AccountID

	n, err := CreateNote(pg.DB(ctx), note)
	if err != nil {
		log.Printf("cannot create note: %s", err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	}
	web.JSONResp(w, n, http.StatusCreated)
}
Exemple #3
0
func HandleUpdateNote(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	var input Note
	if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
		web.JSONErr(w, err.Error(), http.StatusBadRequest)
		return
	}

	if errs := validateNote(&input); len(errs) > 0 {
		web.JSONErrs(w, errs, http.StatusBadRequest)
		return
	}

	tx, err := pg.DB(ctx).Beginx()
	if err != nil {
		log.Printf("cannot start transaction: %s", err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	}
	defer tx.Rollback()

	acc, ok := auth.AuthRequired(tx, w, r)
	if !ok {
		return
	}
	noteID := stoint(web.Args(ctx).ByIndex(0))

	if ok, err := IsNoteOwner(tx, noteID, acc.AccountID); err != nil {
		log.Printf("cannot check %d note owner: %s", noteID, err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	} else if !ok {
		web.JSONErr(w, "you are not owner of this note", http.StatusUnauthorized)
		return
	}

	note, err := UpdateNote(tx, input)
	if err != nil {
		log.Printf("cannot update %d note: %s", noteID, err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	}
	if err := tx.Commit(); err != nil {
		log.Printf("cannot commit transaction: %s", err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	}
	web.JSONResp(w, note, http.StatusOK)
}
Exemple #4
0
func HandleDeleteNote(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	tx, err := pg.DB(ctx).Beginx()
	if err != nil {
		log.Printf("cannot start transaction: %s", err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	}
	defer tx.Rollback()

	acc, ok := auth.AuthRequired(tx, w, r)
	if !ok {
		return
	}
	noteID := stoint(web.Args(ctx).ByIndex(0))

	if ok, err := IsNoteOwner(tx, noteID, acc.AccountID); err != nil {
		if err == pg.ErrNotFound {
			web.StdJSONErr(w, http.StatusNotFound)
		} else {
			log.Printf("cannot check %d note owner: %s", noteID, err)
			web.StdJSONErr(w, http.StatusInternalServerError)
		}
		return
	} else if !ok {
		web.JSONErr(w, "you are not owner of this note", http.StatusUnauthorized)
		return
	}

	if err := DeleteNote(tx, noteID); err != nil {
		log.Printf("cannot delete %d note: %s", noteID, err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	}

	if err := tx.Commit(); err != nil {
		log.Printf("cannot commit transaction: %s", err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusGone)
}
Exemple #5
0
func HandleListNotes(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	db := pg.DB(ctx)

	acc, ok := auth.AuthRequired(db, w, r)
	if !ok {
		return
	}

	var offset int
	if raw := r.URL.Query().Get("offset"); raw != "" {
		if n, err := strconv.Atoi(raw); err != nil {
			web.JSONErr(w, "invalid 'offset' value", http.StatusBadRequest)
			return
		} else {
			offset = n
		}
	}

	notes, err := NotesByOwner(db, acc.AccountID, 300, offset)
	if err != nil {
		log.Printf("cannot fetch notes for %d: %s", acc.AccountID, err)
		web.StdJSONErr(w, http.StatusInternalServerError)
		return
	}

	if notes == nil {
		notes = make([]*Note, 0) // JSON api should return empty list
	}

	content := struct {
		Notes []*Note
	}{
		Notes: notes,
	}
	web.JSONResp(w, content, http.StatusOK)
}