// This functions get all pages func getAllPages(w http.ResponseWriter, r *http.Request) []Pages { // Check if we have the item in the cache cachedItem, cacheStatus := cache.GetCache(r, "getAllPages") if cacheStatus == true { var pages []Pages pPages := bytes.NewBuffer(cachedItem) decPages := gob.NewDecoder(pPages) decPages.Decode(&pages) return pages } // We don't have it in the cache, make a query and store it to the cache c := appengine.NewContext(r) q := datastore.NewQuery("Pages") var pages []Pages keys, err := q.GetAll(c, &pages) if err != nil { errorHandler.Error(w, r, err.Error()) return []Pages{} } models := make([]Pages, len(pages)) for i := 0; i < len(pages); i++ { models[i].Identifier = keys[i].StringID() models[i].URL = pages[i].URL models[i].Title = pages[i].Title } // Add it to the cache mModels := new(bytes.Buffer) //initialize a *bytes.Buffer encModels := gob.NewEncoder(mModels) encModels.Encode(models) cache.AddCache(r, "getAllPages", mModels.Bytes()) return models }
// Search site func search(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) // Get the Settings key := datastore.NewKey(c, "SearchSettings", "Settings", 0, nil) var settings Settings datastore.Get(c, key, &settings) // Create a new http client, supplying the API key we // generated to identify our application, and the urlfetch // transport necessary to make HTTP calls on App Engine transport := &transport.APIKey{ Key: settings.APIKey, Transport: &urlfetch.Transport{Context: c}} client := &http.Client{Transport: transport} // Create the service customsearchService, _ := customsearch.New(client) search, err := customsearchService.Cse.List(r.FormValue("q")).Cx(settings.CX).Do() if err != nil { errorHandler.Error(w, r, err.Error()) return } // Create a model results := search.Items resultModel := make([]Result, len(results)) for i := 0; i < len(results); i++ { resultModel[i].Link = results[i].Link resultModel[i].Snippet = results[i].Snippet } // Merge the models type PassedData struct { Results []Result Query string } passedData := PassedData{ Results: resultModel, Query: r.FormValue("q"), } passedTemplate := new(bytes.Buffer) template.Must(template.ParseFiles("statuscode.ch/search/templates/search.html")).Execute(passedTemplate, passedData) render.Render(w, r, passedTemplate) }
// Edit a page func editPage(w http.ResponseWriter, r *http.Request) { // Get identifier identifier := strings.Replace(r.URL.Path, "/admin/pages/edit/", "", 1) // Check if page exists exists, page := getPage(identifier, r) if exists == false { http.Redirect(w, r, "/admin/pages/", http.StatusFound) return } // Edit page if csrf.ValidateToken(r, r.FormValue("CSRFToken")) && r.FormValue("url") != "" { c := appengine.NewContext(r) page := Pages{ URL: r.FormValue("url"), Title: r.FormValue("title"), Content: []byte(r.FormValue("content")), } _, err := datastore.Put(c, datastore.NewKey(c, "Pages", r.FormValue("url"), 0, nil), &page) if err != nil { errorHandler.Error(w, r, err.Error()) return } cache.DeleteCache(r, "getPage-"+r.FormValue("url")) cache.DeleteCache(r, "getPage-"+identifier) cache.DeleteCache(r, "getAllPages") http.Redirect(w, r, "/admin/pages/", http.StatusFound) return } // Merge the data type PassedData struct { CSRFToken string Page Pages } passedData := PassedData{ CSRFToken: csrf.GetToken(r), Page: page, } passedTemplate := new(bytes.Buffer) template.Must(template.ParseFiles("statuscode.ch/pages/templates/editPage.html")).Execute(passedTemplate, passedData) render.Render(w, r, passedTemplate) }
// Create a new page func newPage(w http.ResponseWriter, r *http.Request) { if csrf.ValidateToken(r, r.FormValue("CSRFToken")) && r.FormValue("url") != "" { c := appengine.NewContext(r) page := Pages{ URL: r.FormValue("url"), Title: r.FormValue("title"), Content: []byte(r.FormValue("content")), } _, err := datastore.Put(c, datastore.NewKey(c, "Pages", r.FormValue("url"), 0, nil), &page) if err != nil { errorHandler.Error(w, r, err.Error()) return } cache.DeleteCache(r, "getAllPages") http.Redirect(w, r, "/admin/pages/", http.StatusFound) } passedTemplate := new(bytes.Buffer) template.Must(template.ParseFiles("statuscode.ch/pages/templates/newPage.html")).Execute(passedTemplate, csrf.GetToken(r)) render.Render(w, r, passedTemplate) }
// Admin page with the search settings func searchSettings(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) // Write the new settings if csrf.ValidateToken(r, r.FormValue("CSRFToken")) { Settings := Settings{ APIKey: r.FormValue("apikey"), CX: r.FormValue("cx"), } _, err := datastore.Put(c, datastore.NewKey(c, "SearchSettings", "Settings", 0, nil), &Settings) if err != nil { errorHandler.Error(w, r, err.Error()) return } } // Get the Settings key := datastore.NewKey(c, "SearchSettings", "Settings", 0, nil) var settings Settings datastore.Get(c, key, &settings) // Merge the models type PassedData struct { CSRFToken string APIKey string CX string } passedData := PassedData{ CSRFToken: csrf.GetToken(r), APIKey: settings.APIKey, CX: settings.CX, } passedTemplate := new(bytes.Buffer) template.Must(template.ParseFiles("statuscode.ch/search/templates/settings.html")).Execute(passedTemplate, passedData) render.Render(w, r, passedTemplate) }
// Manages the menu func menu(w http.ResponseWriter, r *http.Request) { // Parse the post data if csrf.ValidateToken(r, r.FormValue("CSRFToken")) { cache.DeleteCache(r, "getMenu") c := appengine.NewContext(r) // Check if the user wants to move up if r.FormValue("moveUp") != "" { //get the item to move var navigation Navigation ID, _ := strconv.Atoi(r.FormValue("moveUp")) key := datastore.NewKey(c, "Menu", "", int64(ID), nil) if err := datastore.Get(c, key, &navigation); err != nil { errorHandler.Error(w, r, err.Error()) return } // Move the item over 1 down itemBelowQuery := datastore.NewQuery("Menu").Filter("Order =", navigation.Order-1) var itemBelow []Navigation itemBelowKey, err := itemBelowQuery.GetAll(c, &itemBelow) for i := 0; i < len(itemBelow); i++ { itemBelowStruct := Navigation{ NavTitle: itemBelow[i].NavTitle, NavLink: itemBelow[i].NavLink, Order: itemBelow[i].Order + 1, } _, err = datastore.Put(c, datastore.NewKey(c, "Menu", "", itemBelowKey[i].IntID(), nil), &itemBelowStruct) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } // Move the item 1 up originalItem := Navigation{ NavTitle: navigation.NavTitle, NavLink: navigation.NavLink, Order: navigation.Order - 1, } _, err = datastore.Put(c, datastore.NewKey(c, "Menu", "", int64(ID), nil), &originalItem) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } // Check if the user wants to move down if r.FormValue("moveDown") != "" { //get the item to move var navigation Navigation ID, _ := strconv.Atoi(r.FormValue("moveDown")) key := datastore.NewKey(c, "Menu", "", int64(ID), nil) if err := datastore.Get(c, key, &navigation); err != nil { errorHandler.Error(w, r, err.Error()) return } // Move the item below 1 up itemBelowQuery := datastore.NewQuery("Menu").Filter("Order =", navigation.Order+1) var itemBelow []Navigation itemBelowKey, err := itemBelowQuery.GetAll(c, &itemBelow) for i := 0; i < len(itemBelow); i++ { itemBelowStruct := Navigation{ NavTitle: itemBelow[i].NavTitle, NavLink: itemBelow[i].NavLink, Order: itemBelow[i].Order - 1, } _, err = datastore.Put(c, datastore.NewKey(c, "Menu", "", itemBelowKey[i].IntID(), nil), &itemBelowStruct) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } // Move the item 1 down originalItem := Navigation{ NavTitle: navigation.NavTitle, NavLink: navigation.NavLink, Order: navigation.Order + 1, } _, err = datastore.Put(c, datastore.NewKey(c, "Menu", "", int64(ID), nil), &originalItem) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } // Check if the user wants to delete a menu if r.FormValue("delete") != "" { // delete var navigation Navigation ID, _ := strconv.Atoi(r.FormValue("delete")) key := datastore.NewKey(c, "Menu", "", int64(ID), nil) if err := datastore.Get(c, key, &navigation); err != nil { errorHandler.Error(w, r, err.Error()) return } // Move the item below 1 down itemBelowQuery := datastore.NewQuery("Menu").Filter("Order >", navigation.Order) var itemBelow []Navigation itemBelowKey, err := itemBelowQuery.GetAll(c, &itemBelow) for i := 0; i < len(itemBelow); i++ { itemBelowStruct := Navigation{ NavTitle: itemBelow[i].NavTitle, NavLink: itemBelow[i].NavLink, Order: itemBelow[i].Order - 1, } _, err = datastore.Put(c, datastore.NewKey(c, "Menu", "", itemBelowKey[i].IntID(), nil), &itemBelowStruct) if err != nil { errorHandler.Error(w, r, err.Error()) } } // Delete datastore.Delete(c, key) } NavTitle, NavLink := r.FormValue("NavTitle"), r.FormValue("NavLink") // Check if there is any data if NavTitle != "" && NavLink != "" { c := appengine.NewContext(r) dbQuery := datastore.NewQuery("Menu").Order("Order") dbCount, _ := dbQuery.Count(c) menu := Navigation{ NavTitle: NavTitle, NavLink: NavLink, Order: dbCount + 1, } // We the ID as Key _, err := datastore.Put(c, datastore.NewIncompleteKey(c, "Menu", nil), &menu) if err != nil { errorHandler.Error(w, r, err.Error()) return } } } // Get the menus c := appengine.NewContext(r) q := datastore.NewQuery("Menu").Order("Order") navigation, keys := getAllMenu(r) models := make([]NavigationVM, len(navigation)) for i := 0; i < len(navigation); i++ { if navigation[i].Order == 1 { models[i].First = true } count, _ := q.Count(c) if navigation[i].Order == count { models[i].Latest = true } models[i].Key = keys[i].IntID() models[i].NavTitle = navigation[i].NavTitle models[i].NavLink = navigation[i].NavLink } // Merge the data type PassedData struct { CSRFToken string Navigation []NavigationVM } passedData := PassedData{ CSRFToken: csrf.GetToken(r), Navigation: models, } passedTemplate := new(bytes.Buffer) template.Must(template.ParseFiles("statuscode.ch/menu/templates/manage.html")).Execute(passedTemplate, passedData) render.Render(w, r, passedTemplate) }