Example #1
0
// Upgrade the set of complaints for each user.
func upgradeUserHandler(w http.ResponseWriter, r *http.Request) {
	c := appengine.Timeout(appengine.NewContext(r), 30*time.Second)
	cdb := ComplaintDB{C: c, Memcache: false}

	p := types.ComplainerProfile{}
	if err := p.Base64Decode(r.FormValue("profile")); err != nil {
		c.Errorf("upgradeUserHandler: decode failed: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Get *all* the complaints for this person, unfiltered.
	var data = []types.Complaint{}
	q := datastore.
		NewQuery(kComplaintKind).
		Ancestor(cdb.emailToRootKey(p.EmailAddress)).
		Order("Timestamp")
	keys, err := q.GetAll(c, &data)
	if err != nil {
		c.Errorf("upgradeUserHandler/%s: GetAll failed: %v", p.EmailAddress, err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	nDeleted, nUpdated := 0, 0
	str := ""
	for i, complaint := range data {
		FixupComplaint(&complaint, keys[i]) // Put the key where cdb.* expect to find it

		deleteMe := i < len(data)-1 && ComplaintsAreEquivalent(data[i], data[i+1])
		noProfile := complaint.Profile.EmailAddress == ""
		//str += fmt.Sprintf(" [%03d] [DEL=%5v,PRO=%5v] %s\n", i, deleteMe, noProfile, complaint)

		if true {
			if deleteMe {
				if err := cdb.DeleteComplaints([]string{complaint.DatastoreKey}, p.EmailAddress); err != nil {
					c.Errorf("upgradeUserHandler/%s: deletecomplaints failed: %v", p.EmailAddress, err)
					http.Error(w, err.Error(), http.StatusInternalServerError)
					return
				}
				nDeleted++

			} else if noProfile {
				complaint.Profile = p
				if err := cdb.UpdateComplaint(complaint, p.EmailAddress); err != nil {
					c.Errorf("upgradeUserHandler/%s: updatecomplaints failed: %v", p.EmailAddress, err)
					http.Error(w, err.Error(), http.StatusInternalServerError)
					return
				}
				nUpdated++
			}
		}
	}

	str += fmt.Sprintf(" *** upgraded {%s} [tot=%d, del=%d, upd=%d]\n",
		p.EmailAddress, len(data), nDeleted, nUpdated)
	c.Infof(" -- Upgrade for %s --\n%s", p.EmailAddress, str)
	w.Write([]byte(fmt.Sprintf("OK, upgraded %s\n", p.EmailAddress)))
}
Example #2
0
func profileUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	cdb := complaintdb.NewDB(ctx)

	r.ParseForm()

	lat, err := strconv.ParseFloat(r.FormValue("Lat"), 64)
	if err != nil {
		cdb.Errorf("profileUpdate:, parse lat '%s': %v", r.FormValue("Lat"), err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	long, err2 := strconv.ParseFloat(r.FormValue("Long"), 64)
	if err2 != nil {
		cdb.Errorf("profileUpdate:, parse long '%s': %v", r.FormValue("Long"), err)
		http.Error(w, err2.Error(), http.StatusInternalServerError)
		return
	}

	sesh, _ := GetUserSession(ctx)

	// Maybe make a call to fetch the elevation ??
	// https://developers.google.com/maps/documentation/elevation/intro
	cp := types.ComplainerProfile{
		EmailAddress: sesh.Email,
		CallerCode:   r.FormValue("CallerCode"),
		FullName:     strings.TrimSpace(r.FormValue("FullName")),
		Address:      strings.TrimSpace(r.FormValue("AutoCompletingMagic")),
		StructuredAddress: types.PostalAddress{
			Number:  r.FormValue("AddrNumber"),
			Street:  r.FormValue("AddrStreet"),
			City:    r.FormValue("AddrCity"),
			State:   r.FormValue("AddrState"),
			Zip:     r.FormValue("AddrZip"),
			Country: r.FormValue("AddrCountry"),
		},
		CcSfo:           true, //FormValueCheckbox(r, "CcSfo"),
		DataSharing:     FormValueTriValuedCheckbox(r, "DataSharing"),
		ThirdPartyComms: FormValueTriValuedCheckbox(r, "ThirdPartyComms"),
		Lat:             lat,
		Long:            long,
		ButtonId:        []string{},
	}

	// Preserve some values from the old profile
	if origProfile, err := cdb.GetProfileByEmailAddress(sesh.Email); err == nil {
		cp.ButtonId = origProfile.ButtonId
	}

	if err := cdb.PutProfile(cp); err != nil {
		cdb.Errorf("profileUpdate: cdb.Put: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	http.Redirect(w, r, "/", http.StatusFound)
}
Example #3
0
func PostComplaint(client *http.Client, p types.ComplainerProfile, c types.Complaint) (string, error) {
	first, last := p.SplitName()
	addr := p.GetStructuredAddress()
	if c.Activity == "" {
		c.Activity = "Loud noise"
	}

	debug, submitkey, err := GetSubmitkey(client)
	if err != nil {
		return debug, err
	}
	debug += fmt.Sprintf("We got submitkey=%s\n", submitkey)

	// {{{ Populate form

	vals := url.Values{
		"response": {"json"},

		"contactmethod": {"App"},
		"app_key":       {"TUC8uDJMooVMvf7hew93nhUGcWgw"},

		"caller_code": {p.CallerCode},
		"name":        {first},
		"surname":     {last},
		"address1":    {addr.Street},
		"address2":    {""},
		"zipcode":     {addr.Zip},
		"city":        {addr.City},
		"state":       {addr.State},
		"email":       {p.EmailAddress},

		"airports": {"KSFO"}, // KOAK, KSJC, KSAN
		"month":    {date.InPdt(c.Timestamp).Format("1")},
		"day":      {date.InPdt(c.Timestamp).Format("2")},
		"year":     {date.InPdt(c.Timestamp).Format("2006")},
		"hour":     {date.InPdt(c.Timestamp).Format("15")},
		"min":      {date.InPdt(c.Timestamp).Format("4")},

		"aircraftcategory": {"J"},
		"eventtype":        {"Loud noise"}, // perhaps map c.Activity to something ?
		"comments":         {c.Description},
		"responserequired": {"N"},
		"enquirytype":      {"C"},

		"submit":    {"Submit complaint"},
		"submitkey": {submitkey},

		"nowebtrak":       {"1"},
		"defaulttime":     {"0"},
		"webtraklinkback": {""},
		"title":           {""},
		"homephone":       {""},
		"workphone":       {""},
		"cellphone":       {""},
	}

	if c.AircraftOverhead.FlightNumber != "" {
		vals.Add("acid", c.AircraftOverhead.Callsign)
		vals.Add("aacode", c.AircraftOverhead.Id2)
		vals.Add("tailnumber", c.AircraftOverhead.Registration)
		vals.Add("aircrafttype", c.AircraftOverhead.EquipType)

		//vals.Add("adflag", "??") // Operation type (A, D or O for Arr, Dept or Overflight)
		//vals.Add("beacon", "??") // SSR code (eg 210)
	}

	// }}}

	debug += "Submitting these vals:-\n"
	for k, v := range vals {
		debug += fmt.Sprintf(" * %-20.20s: %v\n", k, v)
	}

	if resp, err := client.PostForm("https://"+bksvHost+bksvPath, vals); err != nil {
		return debug, err

	} else {

		defer resp.Body.Close()
		body, _ := ioutil.ReadAll(resp.Body)
		if resp.StatusCode >= 400 {
			debug += fmt.Sprintf("ComplaintPOST: HTTP err '%s'\nBody:-\n%s\n--\n", resp.Status, body)
			return debug, fmt.Errorf("ComplaintPOST: HTTP err %s", resp.Status)
		}

		var jsonMap map[string]interface{}
		if err := json.Unmarshal([]byte(body), &jsonMap); err != nil {
			debug += fmt.Sprintf("ComplaintPOST: JSON unmarshal '%v'\nBody:-\n%s\n--\n", err, body)
			return debug, fmt.Errorf("ComplaintPOST: JSON unmarshal %v", err)

			/* Fall back ?
			if !regexp.MustCompile(`(?i:received your complaint)`).MatchString(string(body)) {
				debug += fmt.Sprintf("BKSV body ...\n%s\n------\n", string(body))
				return debug,fmt.Errorf("Returned response did not say 'received your complaint'")
			} else {
				debug += "Success !\n"+string(body)
			}
			*/

		} else if v := jsonMap["result"]; v == nil {
			return debug, fmt.Errorf("ComplaintPOST: jsonmap had no 'result'.\nBody:-\n%s\n--\n", body)

		} else {
			result := v.(string)
			if result == "1" {
				debug += "Json Success !\n"
			} else {
				debug += fmt.Sprintf("Json result not '1':-\n%#v\n--\n", jsonMap)
				return debug, fmt.Errorf("ComplaintPOST: result='%s'", result)
			}
		}
	}

	return debug, nil
}