// devices is the logic implementation of the Devices page. func devices(p *page.Params) { c := p.AppCtx fv := p.Request.PostFormValue // Initial values: p.Custom["SearchPrecision"] = 1000 p.Custom["LogsRetention"] = 60 // Detect form submits: switch { case fv("submitAdd") != "": // Add New Device form submitted! // Checks: switch { case !checkName(p, fv("name")): case !checkSearchPrecision(p, fv("searchPrecision")): case !checkLogsRetention(p, fv("logsRetention")): } if p.ErrorMsg == nil { // All data OK, save new Device searchPrecision, _ := strconv.ParseInt(fv("searchPrecision"), 10, 64) logsRetention, _ := strconv.Atoi(fv("logsRetention")) dev := ds.Device{fv("name"), 0, logsRetention, "", time.Now(), 0} dev.SetSearchPrecision(searchPrecision) genNewRandID(p, &dev) if p.Err != nil { return } if _, p.Err = datastore.Put(c, datastore.NewIncompleteKey(c, ds.ENameDevice, p.Account.GetKey(c)), &dev); p.Err != nil { return // Datastore error } p.InfoMsg = "New Device saved successfully." // Clear from memcache: cache.ClearDevListForAccKey(c, p.Account.GetKey(c)) } else { // Submitted values p.Custom["Name"] = fv("name") p.Custom["SearchPrecision"] = fv("searchPrecision") p.Custom["LogsRetention"] = fv("logsRetention") } case fv("submitRename") != "": // Rename Device form submitted! if !checkName(p, fv("name")) { break } if devID, err := strconv.ParseInt(string(fv("devID")), 10, 64); err != nil { p.ErrorMsg = "Invalid Device!" } else { devKey := datastore.NewKey(c, ds.ENameDevice, "", devID, p.Account.GetKey(c)) var dev ds.Device if err = datastore.Get(c, devKey, &dev); err != nil { if err == datastore.ErrNoSuchEntity { p.ErrorMsg = "You do not have access to the specified Device!" } else { // Real datastore error p.Err = err return } } else { // Proceed to rename dev.Name = fv("name") if _, p.Err = datastore.Put(c, devKey, &dev); p.Err != nil { return // Datastore error } p.InfoMsg = "Device renamed successfully." // Clear from memcache: cache.ClearDevListForAccKey(c, p.Account.GetKey(c)) cache.ClearDeviceForRandID(c, dev.RandID) dev.KeyID = devID // This is important (device is loaded freshly and not yet set)! cache.CacheDevice(c, &dev) } } case fv("submitGenNewKey") != "": // Generate New Key form submitted! if devID, err := strconv.ParseInt(string(fv("devID")), 10, 64); err != nil { p.ErrorMsg = "Invalid Device!" } else { devKey := datastore.NewKey(c, ds.ENameDevice, "", devID, p.Account.GetKey(c)) var dev ds.Device if err = datastore.Get(c, devKey, &dev); err != nil { if err == datastore.ErrNoSuchEntity { p.ErrorMsg = "You do not have access to the specified Device!" } else { // Real datastore error p.Err = err return } } else { // Proceed to generate new key // Store old RandID to remove it from cache if saving succeeds oldRandID := dev.RandID genNewRandID(p, &dev) if p.Err != nil { return } if _, p.Err = datastore.Put(c, devKey, &dev); p.Err != nil { return // Datastore error } p.InfoMsg = template.HTML("New Key generated successfully.") p.ImportantMsg = template.HTML("<b>Important!</b> You have to update the URL in the client application else further GPS tracking calls will be discarded!") cache.ClearDeviceForRandID(c, oldRandID) dev.KeyID = devID // This is important (device is loaded freshly and not yet set)! cache.CacheDevice(c, &dev) } } } q := datastore.NewQuery(ds.ENameDevice).Ancestor(p.Account.GetKey(c)).Order(ds.PNameName) var devices []*ds.Device var devKeys []*datastore.Key if devKeys, p.Err = q.GetAll(c, &devices); p.Err != nil { return } for i := range devices { devices[i].KeyID = devKeys[i].IntID() } p.Custom["Devices"] = devices }
// settings is the logic implementation of the Settings page. func settings(p *page.Params) { p.Custom["ImgFormats"] = imgFormats fv := p.Request.PostFormValue if fv("submitSettings") == "" { // No form submitted. Initial values: p.Custom["GoogleAccount"] = p.Account.Email p.Custom["ContactEmail"] = p.Account.ContactEmail p.Custom["LocationName"] = p.Account.LocationName if p.Account.LogsPageSize > 0 { p.Custom["LogsPageSize"] = p.Account.LogsPageSize } p.Custom["MapPrevSize"] = p.Account.MapPrevSize p.Custom["MobMapPrevSize"] = p.Account.MobMapPrevSize p.Custom["MobMapImgFormat"] = p.Account.MobMapImgFormat if p.Account.MobPageWidth > 0 { p.Custom["MobPageWidth"] = p.Account.MobPageWidth } return } p.Custom["GoogleAccount"] = fv("googleAccount") p.Custom["ContactEmail"] = fv("contactEmail") p.Custom["LocationName"] = fv("locationName") p.Custom["LogsPageSize"] = fv("logsPageSize") p.Custom["MapPrevSize"] = fv("mapPrevSize") p.Custom["MobMapPrevSize"] = fv("mobMapPrevSize") p.Custom["MobMapImgFormat"] = fv("mobMapImgFormat") p.Custom["MobPageWidth"] = fv("mobPageWidth") // Checks: switch { case !checkGoogleAccounts(p, fv("googleAccount")): case !checkContactEmail(p, fv("contactEmail")): case !checkLocationName(p, fv("locationName")): case !checkLogsPageSize(p, fv("logsPageSize")): case !checkMapPrevSize(p, "Map preview size", fv("mapPrevSize")): case !checkMapPrevSize(p, "Mobile Map preview size", fv("mobMapPrevSize")): case !checkMobMapImgFormat(p, fv("mobMapImgFormat")): case !checkMobPageWidth(p, fv("mobPageWidth")): } if p.ErrorMsg != nil { return } // All data OK, save Account c := p.AppCtx // Create a "copy" of the account, only set it if saving succeeds. // Have to set ALL fields (else their values would be lost when (re)saved)! var logsPageSize, mobPageWidth int if fv("logsPageSize") != "" { logsPageSize, _ = strconv.Atoi(fv("logsPageSize")) } if fv("mobPageWidth") != "" { mobPageWidth, _ = strconv.Atoi(fv("mobPageWidth")) } acc := ds.Account{ Email: p.User.Email, Lemail: strings.ToLower(p.User.Email), UserID: p.User.ID, ContactEmail: fv("contactEmail"), LocationName: fv("locationName"), LogsPageSize: logsPageSize, MapPrevSize: fv("mapPrevSize"), MobMapPrevSize: fv("mobMapPrevSize"), MobMapImgFormat: fv("mobMapImgFormat"), MobPageWidth: mobPageWidth, Created: p.Account.Created, KeyID: p.Account.KeyID, } key := datastore.NewKey(c, ds.ENameAccount, "", p.Account.KeyID, nil) if _, p.Err = datastore.Put(c, key, &acc); p.Err == nil { p.InfoMsg = "Settings saved successfully." p.Account = &acc // Update cache with the new Account cache.CacheAccount(c, p.Account) } }
// alerts is the logic implementation of the Alerts page. func alerts(p *page.Params) { c := p.AppCtx // First get devices var devices []*ds.Device if devices, p.Err = cache.GetDevListForAccKey(c, p.Account.GetKey(c)); p.Err != nil { return } p.Custom["Devices"] = devices fv := p.Request.PostFormValue // Detect form submits: switch { case fv("submitAdd") != "": // Add New Alert form submitted! // Checks: switch { case !checkDeviceID(p, fv("carDeviceID"), true, devices): case !checkDeviceID(p, fv("persMobDeviceID"), false, devices): } if p.ErrorMsg == nil { // So far so good. Futher checks: car and personal mobile device must differ carDevID, _ := strconv.ParseInt(fv("carDeviceID"), 10, 64) var persMobDevID int64 if fv("persMobDeviceID") != "" { persMobDevID, _ = strconv.ParseInt(fv("persMobDeviceID"), 10, 64) if carDevID == persMobDevID { p.ErrorMsg = template.HTML(`<span class="code">Car GPS Device</span> and <span class="code">Personal Mobile GPS Device</span> cannot be the same!`) } } if p.ErrorMsg == nil { // So far still good. Furter check: same alert cannot be saved twice q := datastore.NewQuery(ds.ENameAlert).Ancestor(p.Account.GetKey(c)) var alerts []*ds.Alert if _, p.Err = q.GetAll(c, &alerts); p.Err != nil { return } for _, alert := range alerts { if alert.CarDevID == carDevID && alert.PersMobDevID == persMobDevID { p.ErrorMsg = template.HTML(`An Alert with the same <span class="code">Car GPS Device</span> and <span class="code">Personal Mobile GPS Device</span> already exists!`) } } } if p.ErrorMsg == nil { // All data OK, save new Alert alert := ds.Alert{carDevID, persMobDevID, time.Now(), 0, "", ""} if _, p.Err = datastore.Put(c, datastore.NewIncompleteKey(c, ds.ENameAlert, p.Account.GetKey(c)), &alert); p.Err != nil { return // Datastore error } p.InfoMsg = "New Alert saved successfully." } } case fv("submitDelete") != "": // Delete Alert form submitted! if alertID, err := strconv.ParseInt(string(fv("alertID")), 10, 64); err != nil { p.ErrorMsg = "Invalid Alert!" } else { alertKey := datastore.NewKey(c, ds.ENameAlert, "", alertID, p.Account.GetKey(c)) // Check if var alert ds.Alert if err = datastore.Get(c, alertKey, &alert); err != nil { if err == datastore.ErrNoSuchEntity { p.ErrorMsg = "You do not have access to the specified Alert!" } else { // Real datastore error p.Err = err return } } else { // Proceed to delete if p.Err = datastore.Delete(c, alertKey); p.Err != nil { return // Datastore error } p.InfoMsg = "Alert deleted successfully." } } } q := datastore.NewQuery(ds.ENameAlert).Ancestor(p.Account.GetKey(c)) var alerts []*ds.Alert var alertKeys []*datastore.Key if alertKeys, p.Err = q.GetAll(c, &alerts); p.Err != nil { return } for i, alert := range alerts { alert.KeyID = alertKeys[i].IntID() for _, d := range devices { switch d.KeyID { case alert.CarDevID: alert.CarDevName = d.Name case alert.PersMobDevID: alert.PersMobDevName = d.Name } } } p.Custom["Alerts"] = alerts }