Пример #1
0
// parseSelectedTags parses url for selected tags and redirects if it refers to missing tags
func parseSelectedTags(w http.ResponseWriter, r *http.Request, notebook *tessernote.Notebook, c appengine.Context) ([]tessernote.Tag, error) {
	var names []string
	if r.URL.Path != "/" && r.URL.Path != untaggedURL {
		names = strings.Split(r.URL.Path[1:], tagSeparator)
	}
	tags, err := notebook.TagsFrom(names, c)
	if err != nil {
		names = tessernote.Name(tags)
		tagString := strings.Join(names, tagSeparator)
		http.Redirect(w, r, "/"+tagString, http.StatusFound)
	}
	return tags, err
}
Пример #2
0
// GetAllNotes writes a JSON formatted list of all Note IDs in the authorized User's Notebook to w.
func GetAllNotes(w http.ResponseWriter, c appengine.Context, notebook *tessernote.Notebook) {
	notes, err := notebook.Notes(c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	reply, err := json.Marshal(notes)
	if err != nil {
		c.Errorf("marshaling notes (%d): %s", len(notes), err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(reply)
}
Пример #3
0
func TestCreateNote(t *testing.T) {
	note := tessernote.Note{Body: "body"}
	bytes, err := json.Marshal(note)
	if err != nil {
		t.Fatal(err)
	}
	w := httptest.NewRecorder()
	r, err := http.NewRequest("POST", "https://tessernote.appspot.com"+NotesURL, strings.NewReader(string(bytes)))
	if err != nil {
		t.Fatal(err)
	}

	// create a test notebook
	notebook := new(tessernote.Notebook)
	c, err := appenginetesting.NewContext(nil)
	defer c.Close()
	if err != nil {
		t.Fatal(err)
	}
	key := datastore.NewIncompleteKey(c, "Notebook", nil)
	key, err = datastore.Put(c, key, notebook)
	if err != nil {
		t.Fatal(err)
	}
	notebook.ID = key.Encode()

	CreateNote(w, r, c, notebook)

	// check note was added
	notes, err := notebook.Notes(c)
	if err != nil {
		t.Fatal(err)
	}
	if len(notes) != 1 {
		t.Fatalf("expected=%d actual=%d", 1, len(notes))
	}
	if notes[0].Body != note.Body {
		t.Fatalf("expected=%s actual=%s", notes[0].Body, note.Body)
	}

	// check response ID is the same
	response := []byte(w.Body.String())
	err = json.Unmarshal(response, note)
	if err != nil {
		t.Fatal(err, string(response))
	}
	if notes[0].ID != note.ID {
		t.Fatalf("expected=%s actual=%s", notes[0].ID, note.ID)
	}
}
Пример #4
0
// DeleteNote deletes a Note by the ID in the URL. Uses w to write true if the Note was deleted, false
// if it never existed.
func DeleteNote(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) {
	id := r.URL.Path[len(NotesURL):]
	deleted, err := notebook.Delete(id, c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	reply, err := json.Marshal(deleted)
	if err != nil {
		c.Errorf("marshaling delete response (%t): %s", deleted, err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(reply)
}
Пример #5
0
// GetNote retrieves a note from the authorized User's Notebook by ID. The Note is written in JSON format to w.
func GetNote(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) {
	id := r.URL.Path[len(NotesURL):]
	note, err := notebook.Note(id, c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	reply, err := json.Marshal(note)
	if err != nil {
		c.Errorf("marshaling note (%#v): %s", note, err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(reply)
}
Пример #6
0
// DeleteAllNotes deletes all Notes from the authorized User's Notebook. It writes true if Notes were deleted,
// and false if the Notebook was empty to w.
func DeleteAllNotes(w http.ResponseWriter, c appengine.Context, notebook *tessernote.Notebook) {
	empty := len(notebook.NoteKeys) == 0
	err := notebook.DeleteAll(c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	reply, err := json.Marshal(!empty)
	if err != nil {
		c.Errorf("marshaling delete all response: %s", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(reply)
}
Пример #7
0
// CreateNote creates a new Note in the authorized User's Notebook. It takes as input a JSON formatted Note
// and writes the new Note (with its automatically assigned unique ID) in JSON format to w.
func CreateNote(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) {
	note, err := readNote(w, r)
	if err != nil {
		return
	}
	note, err = notebook.Put(note, c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	reply, err := json.Marshal(note)
	if err != nil {
		c.Errorf("marshaling note (%#v): %s", note, err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(reply)
}
Пример #8
0
// ReplaceAllNotes replaces the Notes of the authorized User's Notebook with a new set of Notes. It takes as
// input a JSON formatted list of Notes and writes the added notes if succeeded or an error message otherwise to w.
// Notes may be written back with different IDs than those submitted, see ReplaceNote().
func ReplaceAllNotes(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) {
	notes, err := readNotes(w, r)
	if err != nil {
		return
	}
	err = notebook.DeleteAll(c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	notes, err = notebook.PutAll(notes, c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	reply, err := json.Marshal(notes)
	if err != nil {
		c.Errorf("marshaling notes (%d): %s", len(notes), err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(reply)
}
Пример #9
0
// ReplaceNote replaces a Note in the authorized User's Notebook by its ID. If the Note doesn't exist it is created.
// If the Note's ID has already been assigned (e.g. in another Notebook) a new one is generated for this Note.
// The Note is written in JSON format to w.
func ReplaceNote(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) {
	id := r.URL.Path[len(NotesURL):]
	note, err := readNote(w, r)
	if err != nil {
		return
	}
	if id != note.ID {
		http.Error(w, "mismatched note.ID and URL", http.StatusBadRequest)
		return
	}
	note, err = notebook.Put(note, c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	reply, err := json.Marshal(note)
	if err != nil {
		c.Errorf("marshaling note (%#v): %s", note, err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(reply)
}