func (db *FlightDB) UpdateFlight(f f.Flight) error { key, err := datastore.DecodeKey(f.DatastoreKey()) if err != nil { return err } if ff, err := f.Freeze(); err != nil { return err } else { ff.GestationLog = fmt.Sprintf("* datastore.Update: %s\n", time.Now().UTC()) _, err = datastore.Put(db.C, key, ff) return err } }
func jobV2adsbHandler(r *http.Request, f *oldfdb.Flight) (string, error) { c := appengine.NewContext(r) str := "" if f.HasTrack("ADSB") { return "", nil } // Already has one err, deb := f.GetV2ADSBTrack(urlfetch.Client(c)) str += fmt.Sprintf("*getv2ADSB [%v]:-\n", err, deb) if err != nil { return str, err } if !f.HasTrack("ADSB") { return "", nil } // Didn't find one f.Analyse() // Retrigger Class-B stuff db := oldfgae.FlightDB{C: oldappengine.NewContext(r)} if err := db.UpdateFlight(*f); err != nil { log.Errorf(c, "Persist Flight %s: %v", f, err) return str, err } log.Infof(c, "Updated flight %s", f) str += fmt.Sprintf("--\nFlight was updated\n") return str, nil }
// More of a 'CreateFlight' - may cause dupes ... func (db *FlightDB) PersistFlight(f f.Flight, gestationLog string) error { rootKey := datastore.NewKey(db.C, kFlightKind, "foo", 0, nil) key := datastore.NewIncompleteKey(db.C, kFlightKind, rootKey) if ff, err := f.Freeze(); err != nil { return err } else { ff.GestationLog = gestationLog + fmt.Sprintf("* datastore.Put: %s\n", time.Now().UTC()) _, err = datastore.Put(db.C, key, ff) return err } }
func jobV2adsbHandler(r *http.Request, f *oldfdb.Flight) (string, error) { ctx := req2ctx(r) str := "" // Allow overwrite, for the (36,0) disastery // if f.HasTrack("ADSB") { return "", nil } // Already has one err, deb := f.GetV2ADSBTrack(urlfetch.Client(ctx)) str += fmt.Sprintf("*getv2ADSB [%v]:-\n", err, deb) if err != nil { return str, err } if !f.HasTrack("ADSB") { return "", nil } // Didn't find one f.Analyse() // Retrigger Class-B stuff db := oldfgae.NewDB(r) if err := db.UpdateFlight(*f); err != nil { log.Errorf(ctx, "Persist Flight %s: %v", f, err) return str, err } log.Infof(ctx, "Updated flight %s", f) str += fmt.Sprintf("--\nFlight was updated\n") return str, nil }
func (db *FlightDBFr24) ParsePlayback(body []byte) (*flightdb.Flight, error) { r := FlightPlaybackResponse{} if err := json.Unmarshal(body, &r); err != nil { return nil, err } if r.Result.Response.Timestamp == 0 { return nil, fmt.Errorf("ParsePlayback: no response element (%s no longer exists)", r.Result.Request.FlightId) } // Note: we need the track before we can do the flight identifier (it needs a timestamp from the track data) track := flightdb.Track{} for _, frame := range r.Result.Response.Data.Flight.Track { track = append(track, flightdb.TrackPoint{ Source: "fr24", TimestampUTC: time.Unix(int64(frame.Timestamp), 0).UTC(), Heading: float64(frame.Heading), Latlong: geo.Latlong{float64(frame.Latitude), float64(frame.Longitude)}, SpeedKnots: float64(frame.Speed.Kts), AltitudeFeet: float64(frame.Altitude.Feet), Squawk: frame.Squawk, }) } f := flightdb.Flight{ EquipmentType: r.Result.Response.Data.Flight.Aircraft.Model.Code, Track: track, } f.Tracks = map[string]flightdb.Track{} if err := playback2FlightIdentifier(r, &f.Id); err != nil { return nil, err } return &f, nil }
func jobOceanicTagHandler(r *http.Request, f *oldfdb.Flight) (string, error) { c := appengine.NewContext(r) str := "" if f.HasTag("OCEANIC") { return "", nil } if !f.IsOceanic() { return "", nil } // It's oceanic, but missing a tag ... update f.Tags[oldfdb.KTagOceanic] = true db := oldfgae.FlightDB{C: oldappengine.NewContext(r)} if err := db.UpdateFlight(*f); err != nil { log.Errorf(c, "Persist Flight %s: %v", f, err) return str, err } log.Infof(c, "Updated flight %s", f) str += fmt.Sprintf("--\nFlight was updated\n") return str, nil }
func addflightHandler(w http.ResponseWriter, r *http.Request) { ctx := req2ctx(r) client := req2client(r) logstr := fmt.Sprintf("* addFlightHandler invoked: %s\n", time.Now().UTC()) fsStr := r.FormValue("flightsnapshot") fs := ftype.FlightSnapshot{} if err := fs.Base64Decode(fsStr); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } fr24Id := fs.F.Id.ForeignKeys["fr24"] // This is the only field we take from the logstr += fmt.Sprintf("* fr24 key: %s\n", fr24Id) db := fdb.NewDB(r) fr24db, err := fdb24.NewFlightDBFr24(client) if err != nil { log.Errorf(ctx, " /mdb/addflight: newdb: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Be idempotent - check to see if this flight has already been recorded /* Can't do this check now; the fs.F.Id we cached might be different from the * f.Id we get back from LookupPlayback(), because fr24 reuse their keys. * if exists,err := db.FlightExists(fs.F.Id.UniqueIdentifier()); err != nil { c.Errorf(" /mdb/addflight: FlightExists check failed: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } else if exists { c.Infof(" /mdb/addflight: already exists %s", fs) w.Write([]byte(fmt.Sprintf("Skipped %s\n", fs))) return } logstr += fmt.Sprintf("* FlightExists('%s') -> false\n", fs.F.Id.UniqueIdentifier()) */ // Now grab an initial flight (with track), from fr24. var f *ftype.Flight if f, err = fr24db.LookupPlayback(fr24Id); err != nil { // c.Errorf(" /mdb/addflight: lookup: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } logstr += fmt.Sprintf("* the fr24/default track has %d points\n", len(f.Track)) // Kludge: fr24 keys get reused, so the flight fr24 thinks it refers to might be // different than when we cached it. So we do the uniqueness check here, to avoid // dupes in the DB. Need a better solution to this. if exists, err := db.FlightExists(f.Id.UniqueIdentifier()); err != nil { log.Errorf(ctx, " /mdb/addflight: FlightExists check failed: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } else if exists { log.Infof(ctx, " /mdb/addflight: already exists %s", *f) w.Write([]byte(fmt.Sprintf("Skipped %s\n", *f))) return } logstr += fmt.Sprintf("* FlightExists('%s') -> false\n", f.Id.UniqueIdentifier()) // Fetch ADSB (and MLAT!) tracks from Skypi, via the new DB err, deb := f.GetV2ADSBTrack(client) logstr += "* fetchV2ADSB\n" + deb if err != nil { log.Errorf(ctx, "ADSB fetch err: %v", err) } // If we have any locally received ADSB fragments for this flight, add them in //if err := db.MaybeAddTrackFragmentsToFlight(f); err != nil { // c.Errorf(" /mdb/addflight: addTrackFrags(%s): %v", f.Id, err) //} f.AnalyseFlightPath() // Takes a coarse look at the flight path logstr += fmt.Sprintf("* Initial tags: %v\n", f.TagList()) // For flights on the SERFR1 or BRIXX1 approaches, fetch a flightaware track if f.HasTag(ftype.KTagSERFR1) || f.HasTag(ftype.KTagBRIXX) { u, p := kFlightawareAPIUsername, kFlightawareAPIKey if err := fdbfa.AddFlightAwareTrack(client, f, u, p); err != nil { log.Errorf(ctx, " /mdb/addflight: addflightaware: %v", err) } } f.Analyse() if err := db.PersistFlight(*f, logstr); err != nil { log.Errorf(ctx, " /mdb/addflight: persist: %v", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Success ! w.Write([]byte(fmt.Sprintf("Added %s\n", f))) }
func jobRetagHandler(r *http.Request, f *oldfdb.Flight) (string, error) { ctx := req2ctx(r) str := "" oldtags := f.TagList() f.Tags = map[string]bool{} f.AnalyseFlightPath() f.Analyse() if taglistsEqual(oldtags, f.TagList()) { return fmt.Sprintf("* no change to tags: %v", f.TagList()), nil } db := oldfgae.NewDB(r) if err := db.UpdateFlight(*f); err != nil { log.Errorf(ctx, "Persist Flight %s: %v", f, err) return str, err } log.Infof(ctx, "Updated flight %s", f) str += fmt.Sprintf("--\nFlight was updated\n") return str, nil }