예제 #1
0
파일: gae.go 프로젝트: skypies/flightdb
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
	}
}
예제 #2
0
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
}
예제 #3
0
파일: gae.go 프로젝트: skypies/flightdb
// 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
	}
}
예제 #4
0
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
}
예제 #5
0
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
}
예제 #6
0
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
}
예제 #7
0
파일: fdb.go 프로젝트: skypies/flightdb
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)))
}
예제 #8
0
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
}