// Delete deletes a Note from this Notebook, removes it from any Tags that refer to it and deletes any Tags // that no longer refer to any Notes func (notebook *Notebook) Delete(id string, c appengine.Context) (bool, error) { err := datastore.RunInTransaction(c, func(tc appengine.Context) error { note := Note{ID: id} noteKey := note.Key(c) err := cachestore.Get(tc, noteKey, ¬e) if err != nil { c.Errorf("getting note: %s", err) return err } // remove note if Debug { tc.Debugf("deleting note: %#v", note) } err = cachestore.Delete(tc, noteKey) if err != nil { c.Errorf("deleting note: %s", err) return err } // remove note from tags err = notebook.updateTags(noteKey, ¬e, new(Note), tc) if err != nil { return err } // remove note from notebook notebook.NoteKeys = removeKey(notebook.NoteKeys, noteKey) return notebook.save(tc) }, &datastore.TransactionOptions{XG: true}) if err != nil { memcache.Flush(c) } return err == nil, err }
// DeleteAll deletes all Notes and Tags from this Notebook. func (notebook *Notebook) DeleteAll(c appengine.Context) error { err := datastore.RunInTransaction(c, func(tc appengine.Context) error { err := cachestore.DeleteMulti(tc, notebook.NoteKeys) if err != nil { return err } return cachestore.DeleteMulti(tc, notebook.TagKeys) }, &datastore.TransactionOptions{XG: true}) if err != nil { memcache.Flush(c) } return nil }
// handler for /admin/submit_links func adminSubmitLinksHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) order, _ := strconv.Atoi(strings.TrimSpace(r.FormValue("new_order"))) link := SavedLink{ Order: int64(order), Title: strings.TrimSpace(r.FormValue("new_title")), URL: strings.TrimSpace(r.FormValue("new_url")), } _, err := datastore.Put(c, link.Key(c), &link) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } log.Printf("Saved entry: %v", link) memcache.Flush(c) http.Redirect(w, r, fmt.Sprintf("/admin/links?added=%s", link.URL), http.StatusFound) }
func TestsHandler(w http.ResponseWriter, r *http.Request) { ctx = context.New(r) if err := memcache.Flush(ctx); err != nil { panic(err) } if err := FlushDs(ctx); err != nil { panic(err) } conf := &gocheck.RunConf{ Output: w, Stream: false, Filter: r.FormValue("f"), Verbose: true, Benchmark: false, BenchmarkTime: time.Second, } result := gocheck.RunAll(conf) w.Write([]byte(result.String())) }
// updateNote updates a Note in this Notebook, updating existing Tags to either start or stop pointing to it, // cleaning up Tags that no longer point to any Note, and adding any new Tags. func (notebook *Notebook) updateNote(note Note, c appengine.Context) (Note, error) { err := datastore.RunInTransaction(c, func(tc appengine.Context) error { // get old note var oldNote Note key := note.Key(tc) err := cachestore.Get(tc, key, &oldNote) if err != nil { tc.Errorf("getting old note: %s", err) return err } oldNote.ID = note.ID // add/update/delete tags err = notebook.updateTags(key, &oldNote, ¬e, tc) if err != nil { return err } // update note note.Created = oldNote.Created note.LastModified = time.Now() note.NotebookKeys = oldNote.NotebookKeys if Debug { tc.Debugf("updating note: %#v", note) } key, err = cachestore.Put(tc, key, ¬e) if err != nil { tc.Errorf("updating note: %s", err) return err } // update notebook return notebook.save(tc) }, &datastore.TransactionOptions{XG: true}) if err != nil { memcache.Flush(c) } return note, err }
// addNote adds a Note to this Notebook, updating existing Tags to point to it if they're mentioned // and adding any new Tags func (notebook *Notebook) addNote(note Note, c appengine.Context) (Note, error) { err := datastore.RunInTransaction(c, func(tc appengine.Context) error { // add note (without tags) TODO add existing tags key, err := notebook.addNoteWithoutTags(¬e, tc) if err != nil { return err } // add/update tags err = notebook.updateTags(key, new(Note), ¬e, tc) if err != nil { return err } // update note (with tags) TODO skip if no new tags if Debug { tc.Debugf("updating note (with tags): %#v", note) } key, err = cachestore.Put(tc, key, ¬e) if err != nil { tc.Errorf("updating note (with tags): %s", err) return err } // update notebook notebook.NoteKeys = append(notebook.NoteKeys, key) if len(note.TagKeys) > 0 { notebook.addTagKeys(note.TagKeys) } else { notebook.UntaggedNoteKeys = append(notebook.UntaggedNoteKeys, key) } return notebook.save(tc) }, &datastore.TransactionOptions{XG: true}) if err != nil { memcache.Flush(c) } return note, err }
func Flush(c appengine.Context) error { return memcache.Flush(c) }
func (c *memcacheDriver) Flush() error { return memcache.Flush(c.c) }
// HTTP handler for /admin/submit - submits a blog entry into datastore func adminSubmitEntryHandler(w http.ResponseWriter, r *http.Request) { content := strings.TrimSpace(r.FormValue("content")) title := strings.TrimSpace(r.FormValue("title")) slug := strings.TrimSpace(r.FormValue("slug")) entry := SavedEntry{} if len(content) == 0 { http.Error(w, "No content", http.StatusInternalServerError) return } if len(title) == 0 { http.Error(w, "No title", http.StatusInternalServerError) return } c := appengine.NewContext(r) if r.FormValue("is_new_post") == "1" { if u := user.Current(c); u != nil { entry.Author = u.String() } } else { entry, _ = GetSingleEntry(c, slug) } if r.FormValue("hidden") == "on" { entry.IsHidden = true } else { entry.IsHidden = false } if r.FormValue("allow_comments") == "on" { entry.AllowComments = true } else { entry.AllowComments = false } entry.IsPage, _ = strconv.ParseBool(r.FormValue("is_page")) entry.Content = []byte(content) entry.Title = title entry.Slug = slug log.Printf("Comments: %s (real=%s)", entry.AllowComments, r.FormValue("allow_comments")) if entry.PublishDate.IsZero() { entry.PublishDate = time.Now() } if entry.IsPage { entry.RelativeURL = entry.Slug } else { entry.RelativeURL = fmt.Sprintf("%d/%02d/%s", entry.PublishDate.Year(), entry.PublishDate.Month(), entry.Slug) } _, err := datastore.Put(c, entry.Key(c), &entry) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } log.Printf("Saved entry: %v", entry) memcache.Flush(c) if entry.IsPage { http.Redirect(w, r, fmt.Sprintf("/admin/pages?added=%s", slug), http.StatusFound) } else { http.Redirect(w, r, fmt.Sprintf("/admin?added=%s", slug), http.StatusFound) } }
//I need to implement a token on this form func csvimport(w http.ResponseWriter, r *http.Request) *appError { c := appengine.NewContext(r) c.Debugf("method: ", r.Method) if r.Method != "POST" { return &appError{ errors.New("Unsupported method call to import"), "Imports most be POSTed", http.StatusMethodNotAllowed, } } //this block for check the user's credentials should eventually be broken out into a filter u := user.Current(c) if u == nil { url, err := user.LoginURL(c, r.URL.String()) if err != nil { return &appError{err, "Could not determine LoginURL", http.StatusInternalServerError} } w.Header().Set("Location", url) w.WriteHeader(http.StatusFound) return nil } //some crappy security so that only a certain person can upload things //we should probably have a users entity in datastore that we manage manually for this kinda thing if u.Email != "*****@*****.**" { return &appError{ errors.New("Illegal import attempted by " + u.Email), "Your user is not allowed to import", http.StatusForbidden, } } //r.ParseMultipartForm(1 << 10) file, handler, err := r.FormFile("uploadfile") if err != nil { return &appError{err, "Error uploading file", http.StatusInternalServerError} } defer file.Close() log.Println(handler.Filename) cr := csv.NewReader(file) var res []*resource var keys []*datastore.Key //at the moment we always insert a new item, this should be an insert or update based on OrganizationName //if we get a large enough data set we'll need to implement two loops so that we only batch a certain number of records at a time for { rec, err := cr.Read() if err == io.EOF { break } if err != nil { return &appError{err, "Error reading file", http.StatusInternalServerError} } //we may want IDs in there eventually //_, err = strconv.ParseInt(rec[0], 2, 64) tmp := &resource{ Category: rec[1], OrganizationName: rec[2], Address: rec[3], ZipCode: rec[4], Days: rec[5], TimeOpen: rec[6], TimeClose: rec[7], PeopleServed: rec[8], Description: rec[9], PhoneNumber: rec[10], LastUpdatedBy: u.Email, LastUpdatedTime: time.Now().UTC(), IsActive: true, Location: appengine.GeoPoint{}, } log.Printf("len slice check: %x, len rec LatLng check: %x, check for comma: %x", len(rec) > 11, len(rec[11]) > 0, strings.Index(rec[11], ",") != -1) if len(rec) > 11 && len(rec[11]) > 0 && strings.Index(rec[11], ",") != -1 { tmp.Location.Lng, _ = strconv.ParseFloat(strings.Split(rec[11], ",")[0], 64) tmp.Location.Lat, _ = strconv.ParseFloat(strings.Split(rec[11], ",")[1], 64) log.Println(tmp.Location) } res = append(res, tmp) keys = append(keys, datastore.NewIncompleteKey(c, "Resource", nil)) } _, err = datastore.PutMulti(c, keys, res) if err != nil { log.Println(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return &appError{err, "Error updating database", http.StatusInternalServerError} } // clear the cache memcache.Flush(c) http.Redirect(w, r, "/index.html", http.StatusFound) return nil }
func (session *Session) FlushCache() { memcache.Flush(session.context) }
func flushUserCache(c appengine.Context) { if err := memcache.Flush(c); err != nil { panic(&appError{err, "Error flushing memcache", 500}) } }