123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // Copyright 2011 Google Inc. All rights reserved.
- // Use of this source code is governed by the Apache 2.0
- // license that can be found in the LICENSE file.
- // This example only works on Managed VMs.
- // +build !appengine
- package main
- import (
- "html/template"
- "net/http"
- "time"
- "golang.org/x/net/context"
- "google.golang.org/appengine"
- "google.golang.org/appengine/datastore"
- "google.golang.org/appengine/log"
- "google.golang.org/appengine/user"
- )
- var initTime time.Time
- type Greeting struct {
- Author string
- Content string
- Date time.Time
- }
- func main() {
- http.HandleFunc("/", handleMainPage)
- http.HandleFunc("/sign", handleSign)
- appengine.Main()
- }
- // guestbookKey returns the key used for all guestbook entries.
- func guestbookKey(ctx context.Context) *datastore.Key {
- // The string "default_guestbook" here could be varied to have multiple guestbooks.
- return datastore.NewKey(ctx, "Guestbook", "default_guestbook", 0, nil)
- }
- var tpl = template.Must(template.ParseGlob("templates/*.html"))
- func handleMainPage(w http.ResponseWriter, r *http.Request) {
- if r.Method != "GET" {
- http.Error(w, "GET requests only", http.StatusMethodNotAllowed)
- return
- }
- if r.URL.Path != "/" {
- http.NotFound(w, r)
- return
- }
- ctx := appengine.NewContext(r)
- tic := time.Now()
- q := datastore.NewQuery("Greeting").Ancestor(guestbookKey(ctx)).Order("-Date").Limit(10)
- var gg []*Greeting
- if _, err := q.GetAll(ctx, &gg); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- log.Errorf(ctx, "GetAll: %v", err)
- return
- }
- log.Infof(ctx, "Datastore lookup took %s", time.Since(tic).String())
- log.Infof(ctx, "Rendering %d greetings", len(gg))
- var email, logout, login string
- if u := user.Current(ctx); u != nil {
- logout, _ = user.LogoutURL(ctx, "/")
- email = u.Email
- } else {
- login, _ = user.LoginURL(ctx, "/")
- }
- data := struct {
- Greetings []*Greeting
- Login, Logout, Email string
- }{
- Greetings: gg,
- Login: login,
- Logout: logout,
- Email: email,
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- if err := tpl.ExecuteTemplate(w, "guestbook.html", data); err != nil {
- log.Errorf(ctx, "%v", err)
- }
- }
- func handleSign(w http.ResponseWriter, r *http.Request) {
- if r.Method != "POST" {
- http.Error(w, "POST requests only", http.StatusMethodNotAllowed)
- return
- }
- ctx := appengine.NewContext(r)
- g := &Greeting{
- Content: r.FormValue("content"),
- Date: time.Now(),
- }
- if u := user.Current(ctx); u != nil {
- g.Author = u.String()
- }
- key := datastore.NewIncompleteKey(ctx, "Greeting", guestbookKey(ctx))
- if _, err := datastore.Put(ctx, key, g); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- // Redirect with 303 which causes the subsequent request to use GET.
- http.Redirect(w, r, "/", http.StatusSeeOther)
- }
|