func guestEntry(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { c := appengine.NewContext(r) path := m["dir"].(string) + m["base"].(string) cntr, _ := sc.Count(c, path) tplAdder, tplExec := tplx.FuncTplBuilder(w, r) tplAdder("n_html_title", "New guest book entry", nil) tplAdder("n_cont_0", c_new_gbe, cntr) tplExec(w, r) }
func guestView(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { c := appengine.NewContext(r) path := m["dir"].(string) + m["base"].(string) cntr, _ := sc.Count(c, path) gbEntries, report := gbp.ListEntries(w, r) tplAdder, tplExec := tplx.FuncTplBuilder(w, r) tplAdder("n_html_title", "List of guest book entries", nil) tplAdder("n_cont_0", c_view_gbe, gbEntries) tplAdder("n_cont_1", "<pre>{{.}}</pre>", report) tplAdder("n_cont_2", "Visitors: {{.}}", cntr) tplExec(w, r) }
func backend2(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { c := appengine.NewContext(r) path := m["dir"].(string) + m["base"].(string) cntr, _ := sc.Count(c, path) add, tplExec := tplx.FuncTplBuilder(w, r) add("n_html_title", "Backend", nil) //add("n_cont_0", c_link, links) add("n_cont_0", tplx.PrefixLff+"backend_body", blocks2) add("tpl_legend", tplx.PrefixLff+"backend_body_embed01", "") //add("n_cont_1", "<pre>{{.}}</pre>", "pure text") add("n_cont_2", "<p>{{.}} views</p>", cntr) tplExec(w, r) }
func backend3(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { c := appengine.NewContext(r) var nColsBlock = 4 if r.FormValue("nColsBlock") != "" { nColsBlock = util.Stoi(r.FormValue("nColsBlock")) } var nColsViewport = 6 if r.FormValue("nColsViewport") != "" { nColsViewport = util.Stoi(r.FormValue("nColsViewport")) } myB0.VB1 = X myB0.NumB1 = len(myB0.VB1) myB0.NumB2 = 0 myB0.NColsViewport = nColsViewport // compute basic meta data for i1, _ := range myB0.VB1 { myB0.NumB2 += len(myB0.VB1[i1].VB2) for i2, _ := range myB0.VB1[i1].VB2 { // number of chars ro := myB0.VB1[i1].VB2[i2] // read only myB0.VB1[i1].VB2[i2].Size = len(ro.Linktext) + len(ro.Description) myB0.VB1[i1].VB2[i2].EditorialIndex = i2 } } // compute NCols - NRows for the block for i1, _ := range myB0.VB1 { myB0.VB1[i1].NCols = nColsBlock if myB0.VB1[i1].NColsEditorial > 0 { myB0.VB1[i1].NCols = myB0.VB1[i1].NColsEditorial } if len(myB0.VB1[i1].VB2) < nColsBlock && len(myB0.VB1[i1].VB2) > 0 { myB0.VB1[i1].NCols = len(myB0.VB1[i1].VB2) } myB0.VB1[i1].NRows = complementRowsOrCols(len(myB0.VB1[i1].VB2), myB0.VB1[i1].NCols) myB0.VB1[i1].Discrepancy = myB0.VB1[i1].NCols*myB0.VB1[i1].NRows - len(myB0.VB1[i1].VB2) myB0.MaxNCols = util.Max(myB0.MaxNCols, myB0.VB1[i1].NCols) myB0.MaxNRows = util.Max(myB0.MaxNRows, myB0.VB1[i1].NRows) } // compute NCols - NRows - sizeup to MaxNRows for i1, _ := range myB0.VB1 { if myB0.VB1[i1].NRows < myB0.MaxNRows { myB0.VB1[i1].NRows = myB0.MaxNRows myB0.VB1[i1].NCols = complementRowsOrCols(len(myB0.VB1[i1].VB2), myB0.VB1[i1].NRows) myB0.VB1[i1].Discrepancy = myB0.VB1[i1].NCols*myB0.VB1[i1].NRows - len(myB0.VB1[i1].VB2) } } // is first or last for i1, _ := range myB0.VB1 { for i2, _ := range myB0.VB1[i1].VB2 { myB0.VB1[i1].VB2[i2].IsFirst = false myB0.VB1[i1].VB2[i2].IsLast = false if i2%myB0.VB1[i1].NCols == 0 { myB0.VB1[i1].VB2[i2].IsFirst = true } if i2%myB0.VB1[i1].NCols == (myB0.VB1[i1].NCols - 1) { myB0.VB1[i1].VB2[i2].IsLast = true } //aelog.Infof(c,"first-last %v %v \n", i2, i2%myB0.VB1[i1].NCols) } } // create slices with the data to be sorted for i1, _ := range myB0.VB1 { sh1 := make([]Order, len(myB0.VB1[i1].VB2)) myB0.VB1[i1].BySize = ByInt(sh1) sh2 := make([]Order, len(myB0.VB1[i1].VB2)) myB0.VB1[i1].ByHeading = ByStr(sh2) // fill in the data - to be sorted later for i2, _ := range myB0.VB1[i1].VB2 { ro := myB0.VB1[i1].VB2[i2] // read only myB0.VB1[i1].BySize[i2].IdxSrc = i2 myB0.VB1[i1].BySize[i2].ByI = len(ro.Linktext) + len(ro.Description) myB0.VB1[i1].ByHeading[i2].IdxSrc = i2 myB0.VB1[i1].ByHeading[i2].ByS = strings.ToLower(ro.Linktext) } } // actual rearranging of the sorting date for i1, _ := range myB0.VB1 { sort.Sort(myB0.VB1[i1].BySize) sort.Sort(myB0.VB1[i1].ByHeading) aelog.Infof(c, "-- Sorting %v", myB0.VB1[i1].Heading) // for i, v := range myB0.VB1[i1].BySize { // aelog.Infof(c,"---- %v %v %v", i, v.IdxSrc, v.ByI) // } // for i, v := range myB0.VB1[i1].ByHeading { // aelog.Infof(c,"---- %v %v %v", i, v.IdxSrc, v.ByS) // } } path := m["dir"].(string) + m["base"].(string) cntr, _ := sc.Count(c, path) add, tplExec := tplx.FuncTplBuilder(w, r) add("n_html_title", "Backend", nil) add("n_cont_0", "<style>"+htmlfrag.CSSColumnsWidth(nColsViewport)+"</style>", "") add("n_cont_1", tplx.PrefixLff+"backend3_body", myB0) add("tpl_legend", tplx.PrefixLff+"backend3_body_embed01", "") add("n_cont_2", "<p>{{.}} views</p>", cntr) sDumped := "" //sDumped = spew.Sdump(myB0) add("n_cont_3", "<pre>{{.}} </pre>", sDumped) tplExec(w, r) }
// Adapter() checks the path, takes the time, precomputes values into a map // provides a global panic catcher // The typed signature is cleaner than the long version: // func Adapter(given func(http.ResponseWriter, *http.Request, map[string]interface{})) http.HandlerFunc { func Adapter(given ExtendedHandler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { start := time.Now() c, _ := util_appengine.SafelyExtractGaeCtxError(r) lgi := log.Printf lge := log.Fatalf if c != nil { defer logServerTime(c, start) // lgi = c.Infof lgi = func(format string, v ...interface{}) { aelog.Infof(c, format, v...) } // lge = c.Errorf lge = func(format string, v ...interface{}) { aelog.Errorf(c, format, v...) } C = c } if !authenticate(w, r) { return } //check_against := r.URL.String() check_against := r.URL.Path matches := validRequestPath.FindStringSubmatch(check_against) if matches == nil { s := "illegal chars in path: " + check_against lgi(s) http.Error(w, s, http.StatusInternalServerError) return } s, err := url.Parse(r.URL.String()) if err != nil { panic("Could not url.Parse current url") } mp := map[string]interface{}{ "dir": path.Dir(s.Path), "base": path.Base(s.Path), } defer func() { // note: Println works even in panic panicSignal := recover() if panicSignal != nil { miniStacktrace := "" for i := 1; i < 11; i++ { _, file, line, _ := runtime.Caller(i) if strings.Index(file, `/src/pkg/runtime/`) > -1 { miniStacktrace += fmt.Sprintf("<br>\n\t\t %s:%d ", file[len(file)-20:], line) } else { dir := filepath.Dir(file) dirLast := filepath.Base(dir) file = filepath.Join(dirLast, filepath.Base(file)) // we cannot determine, whether html is already sent // we cannot determine, whether we are in plaintext or html context // thus we need the <br> miniStacktrace += fmt.Sprintf("<br>\n\t\t /%s:%d ", file, line) } } // headers := w.Header() // for k, v := range headers { // miniStacktrace += fmt.Sprintf("%#v %#v<br>\n", k, v) // } if panicSignal == "abort_handler_processing" { s := fmt.Sprint("\thttp processing aborted\n", miniStacktrace) lge(s) w.Write([]byte(s)) } else if panicSignal != nil { s := fmt.Sprintf("\tPANIC caught by util_err.Adapter: %v %s\n", panicSignal, miniStacktrace) lge(s) w.Write([]byte(s)) } } }() r.Header.Set("adapter_01", "a string set by adapter") if c == nil { given(w, r, mp) } else { var given1 AppengineHandler given1 = func(c context.Context, w http.ResponseWriter, r *http.Request) { given(w, r, mp) // automatically set on appengine live, but not on appengine dev if r.Header.Get("Content-Type") == "" { w.Header().Set("Content-Type", "text/html; charset=utf-8") } if r.Header.Get("X-Custom-Header-Counter") != "nocounter" { cntr := 0 if true { // This seems to cause problems with new applications // possible because of missing indize distributed_unancestored.Increment(c, mp["dir"].(string)+mp["base"].(string)) cntr, _ = distributed_unancestored.Count(c, mp["dir"].(string)+mp["base"].(string)) } fmt.Fprintf(w, "<br>\n%v Views<br>\n", cntr) } } if true || appengine.IsDevAppServer() { given1(c, w, r) } else { // wrapped := appstats.NewHandler(given1) // mjibson // wrapped.ServeHTTP(w, r) } } } }