complaintdb

package
v0.0.0-...-8a37403 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 5, 2024 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SubmissionNoReject = iota
	SubmissionRejectConstraint
	SubmissionRejectDupeReceipt
	SubmissionRejectBadField
	SubmissionRejectBadApiKey
	SubmissionRejectOther
)

Variables

View Source
var (
	KMaxComplaintsPerDay = 200
)

Functions

func ApproximatePosition

func ApproximatePosition(in geo.Latlong) geo.Latlong

Rounds off a latlong to nearest KM - something that doesn't reveal addresses

func ComplaintDebugHandler

func ComplaintDebugHandler(w http.ResponseWriter, r *http.Request)

/cdb/comp/debug?key=asdadasdasdasdasdasdsadasdsadasdasdasdasdasdas

func ComplaintsShouldBeMerged

func ComplaintsShouldBeMerged(this, next Complaint) bool

ComplaintsShouldBeMerged decides whether two complaint objects relate to the same underlying action by a user. Sometimes a user will mash the button; some users try to automate sending as many complaints as they can.

func FixupComplaint

func FixupComplaint(c *Complaint, keyStr string)

func Overwrite

func Overwrite(this, from *Complaint)

Overwrite user-entered data (and timestamp) into the base complaint.

func SetContextProperties

func SetContextProperties(ctx context.Context, props ContextProperties) context.Context

func SubmissionsDebugHandler

func SubmissionsDebugHandler(w http.ResponseWriter, r *http.Request)

This handler runs in the backend app View a day's worth of complaint submissions; defaults to yesterday

?all=1 (will list every single complaint - DO NOT USE)
?offset=N (how many days to go back from today; 1 == yesterday)
?datestring=2018.01.20 (this day in particular)

func SubmissionsDebugHandler2

func SubmissionsDebugHandler2(w http.ResponseWriter, r *http.Request)

View submission errors over a date range.

 ?date=range&range_from=2016/01/21&range_to=2016/01/26
[?csv=1]

Types

type AnonymizedComplaint

type AnonymizedComplaint struct {
	Timestamp   time.Time
	Speedbrakes bool
	Loudness    int
	Activity    string

	User string // A hash fingerprint of the email address
	City string
	Zip  string

	// Denormalized fields to index/group by
	DatePST string
	HourPST int

	// Aircraft details; might be null
	FlightKey    string // Flightnumber plus date (e.g. "UA123-20161231") - to allow for joins
	FlightNumber string // IATA scheduled flight number
	AirlineCode  string // The 2-char IATA airline code

	Origin      string
	Destination string
	EquipType   string // B744, etc

	geo.Latlong      // embedded; location of aircraft at Timestamp
	PressureAltitude float64
	Groundspeed      float64
}

AnonymizedComplaint is a subset of the data from a complaint; these values are released to the public as a queryable database. The data is somewhat denormalized, to allow for efficient indexing & querying.

func AnonymizeComplaint

func AnonymizeComplaint(c *Complaint) *AnonymizedComplaint

func (AnonymizedComplaint) HasIdenitifiedAircraft

func (ac AnonymizedComplaint) HasIdenitifiedAircraft() bool

type Browser

type Browser struct {
	UUID, Name, Version, Vendor, Platform string `datastore:",noindex"`
}

Fields about backend submission

func (Browser) String

func (b Browser) String() string

type CQuery

type CQuery ds.Query // Create our own type, so we can hang a fluent API off it

func NewComplaintQuery

func NewComplaintQuery() *CQuery

func NewProfileQuery

func NewProfileQuery() *CQuery

func NewQuery

func NewQuery(kind string) *CQuery

func (*CQuery) Ancestor

func (cq *CQuery) Ancestor(rootkey ds.Keyer) *CQuery

func (*CQuery) ByButton

func (cq *CQuery) ByButton(id string) *CQuery

Query builders for ComplainerProfile

func (*CQuery) ByCallerCode

func (cq *CQuery) ByCallerCode(cc string) *CQuery

func (*CQuery) ByFlight

func (cq *CQuery) ByFlight(flightnumber string) *CQuery

func (*CQuery) ByIcaoId

func (cq *CQuery) ByIcaoId(icaoid string) *CQuery

func (*CQuery) BySubmissionOutcome

func (cq *CQuery) BySubmissionOutcome(outcome int) *CQuery

func (*CQuery) ByTimespan

func (cq *CQuery) ByTimespan(start, end time.Time) *CQuery

Query builders for Complaint

func (*CQuery) ByZip

func (cq *CQuery) ByZip(zip string) *CQuery

func (*CQuery) Distinct

func (cq *CQuery) Distinct() *CQuery

func (*CQuery) Filter

func (cq *CQuery) Filter(str string, val interface{}) *CQuery

func (*CQuery) KeysOnly

func (cq *CQuery) KeysOnly() *CQuery

func (*CQuery) Limit

func (cq *CQuery) Limit(val int) *CQuery

func (*CQuery) Order

func (cq *CQuery) Order(str string) *CQuery

func (*CQuery) OrderTimeAsc

func (cq *CQuery) OrderTimeAsc() *CQuery

func (*CQuery) OrderTimeDesc

func (cq *CQuery) OrderTimeDesc() *CQuery

func (*CQuery) Project

func (cq *CQuery) Project(fields ...string) *CQuery

func (*CQuery) String

func (cq *CQuery) String() string

Thin wrapper in util/dsprovider.Query

type ComplainerProfile

type ComplainerProfile struct {
	EmailAddress      string // This is the root key; we get it from the GAE user profile.
	CallerCode        string
	FullName          string `datastore:",noindex"`
	Address           string `datastore:",noindex"`
	StructuredAddress PostalAddress
	Lat, Long         float64
	Elevation         float64 // in meters
	CcSfo             bool    `datastore:",noindex"`
	SelectorAlgorithm string  // Users can have different algorithms (and maybe even params someday)

	SendDailyEmail  int // 0 == unset, 1 == OK/yes, -1 == no
	DataSharing     int // 0 == unset, 1 == OK/yes, -1 == no
	ThirdPartyComms int `datastore:",noindex"` // 0 == unset, 1 == OK/yes, -1 == no

	ButtonId []string // AWS IoT button serial numbers
}

A ComplainerProfile represents a single human who makes complaints, and has a caller code This is the root object for the datastore; the individual complaints hang off this

func (*ComplainerProfile) Base64Decode

func (p *ComplainerProfile) Base64Decode(str string) error

func (ComplainerProfile) Base64Encode

func (p ComplainerProfile) Base64Encode() (string, error)

func (ComplainerProfile) DataSharingOK

func (p ComplainerProfile) DataSharingOK() bool

func (ComplainerProfile) ElevationFeet

func (p ComplainerProfile) ElevationFeet() float64

func (*ComplainerProfile) FetchStructuredAddress

func (p *ComplainerProfile) FetchStructuredAddress() (PostalAddress, error)

func (*ComplainerProfile) GetStructuredAddress

func (p *ComplainerProfile) GetStructuredAddress() PostalAddress

func (ComplainerProfile) SendDailyEmailOK

func (p ComplainerProfile) SendDailyEmailOK() bool

func (ComplainerProfile) SplitName

func (p ComplainerProfile) SplitName() (first, last string)

Attempt to split into firstname, surname

func (ComplainerProfile) ThirdPartyCommsOK

func (p ComplainerProfile) ThirdPartyCommsOK() bool

func (*ComplainerProfile) UpdateStructuredAddress

func (p *ComplainerProfile) UpdateStructuredAddress() error

type Complaint

type Complaint struct {
	Version          int    `datastore:",noindex"` // undef or 0 means unversioned thingy.
	Description      string `datastore:",noindex"`
	Timestamp        time.Time
	AircraftOverhead flightid.Aircraft
	Debug            string `datastore:",noindex"` // Debugging; mostly about flight lookup

	HeardSpeedbreaks bool
	Loudness         int    `datastore:",noindex"` // 0=undef, 1=loud, 2=very loud, 3=insane
	Activity         string `datastore:",noindex"` // What was disturbed

	Profile ComplainerProfile // Embed the whole profile

	Submission         // embedded; details about submitting the complaint to a backend
	Browser    Browser // Details about the browser used

	// Synthetic fields
	DatastoreKey string  `datastore:"-"`
	Dist2KM      float64 `datastore:"-"` // Distance from home to aircraft
	Dist3KM      float64 `datastore:"-"`
}

func (Complaint) AltitudeHrefString

func (c Complaint) AltitudeHrefString() template.HTML

func (Complaint) String

func (c Complaint) String() string

func (Complaint) ToCopyWithStoredDataOnly

func (c1 Complaint) ToCopyWithStoredDataOnly() Complaint

ToCopyWithStoredDataOnly returns a copy of the complaint that only has the stored data fields (e.g. no synthetic fields). This copy is what we store during archiving, and verifying archives.

type ComplaintDB

type ComplaintDB struct {
	StartTime time.Time

	Provider ds.DatastoreProvider
	Logger   *pkglog.Logger
	// contains filtered or unexported fields
}

ComplaintDB is a transient handle to the database

func NewDB

func NewDB(ctx context.Context) ComplaintDB

func (ComplaintDB) AddComplaintSliceToCSV

func (cdb ComplaintDB) AddComplaintSliceToCSV(complaints []Complaint, w io.Writer) error

func (ComplaintDB) AddDailyCount

func (cdb ComplaintDB) AddDailyCount(dc DailyCount) error

func (ComplaintDB) AddHeadersToCSV

func (cdb ComplaintDB) AddHeadersToCSV(w io.Writer)

func (ComplaintDB) AddHistoricalComplaintByEmailAddress

func (cdb ComplaintDB) AddHistoricalComplaintByEmailAddress(ea string, c *Complaint) error

func (ComplaintDB) CPQByEmail

func (cdb ComplaintDB) CPQByEmail(email string) *CQuery

func (ComplaintDB) CQByEmail

func (cdb ComplaintDB) CQByEmail(email string) *CQuery

Canned queries

func (ComplaintDB) CSVHeaders

func (cdb ComplaintDB) CSVHeaders() []string

func (ComplaintDB) ComplainByButtonId

func (cdb ComplaintDB) ComplainByButtonId(id string, c *Complaint) error

func (ComplaintDB) ComplainByCallerCode

func (cdb ComplaintDB) ComplainByCallerCode(cc string, c *Complaint) error

func (ComplaintDB) ComplainByEmailAddress

func (cdb ComplaintDB) ComplainByEmailAddress(ea string, c *Complaint) error

func (ComplaintDB) ComplaintKeyOwnedBy

func (cdb ComplaintDB) ComplaintKeyOwnedBy(keyer ds.Keyer, owner string) (bool, error)

We need to assert this in a few places

func (ComplaintDB) ComplaintKeyStrOwnedBy

func (cdb ComplaintDB) ComplaintKeyStrOwnedBy(keyStr, owner string) (bool, error)

func (ComplaintDB) ComplaintToCSVFunc

func (cdb ComplaintDB) ComplaintToCSVFunc() func(c *Complaint) []string

func (ComplaintDB) CountComplaintsAndUniqueUsersIn

func (cdb ComplaintDB) CountComplaintsAndUniqueUsersIn(s, e time.Time) (int, int, error)

func (ComplaintDB) Ctx

func (cdb ComplaintDB) Ctx() context.Context

func (ComplaintDB) Debugf

func (cdb ComplaintDB) Debugf(step string, fmtstr string, varargs ...interface{})

Debugf is has a 'step' arg, and adds its own latency timings

func (ComplaintDB) DeletAllGlobalStats

func (cdb ComplaintDB) DeletAllGlobalStats() error

func (ComplaintDB) DeleteAllKeys

func (cdb ComplaintDB) DeleteAllKeys(keyers []ds.Keyer) error

func (ComplaintDB) DeleteByKey

func (cdb ComplaintDB) DeleteByKey(keyer ds.Keyer) error

func (ComplaintDB) Errorf

func (cdb ComplaintDB) Errorf(fmtstr string, varargs ...interface{})

func (ComplaintDB) FormattedWriteCQueryToCSV

func (cdb ComplaintDB) FormattedWriteCQueryToCSV(cq *CQuery, w io.Writer, headers []string, f func(*Complaint) []string) (int, error)

func (ComplaintDB) GetAllByEmailAddress

func (cdb ComplaintDB) GetAllByEmailAddress(ea string, everything bool) (*ComplaintsAndProfile, error)

func (ComplaintDB) GetComplaintPositionsInSpanByIcao

func (cdb ComplaintDB) GetComplaintPositionsInSpanByIcao(start, end time.Time, uniqueUsers bool, icaoid string) ([]geo.Latlong, error)

func (*ComplaintDB) GetDailyCounts

func (cdb *ComplaintDB) GetDailyCounts(email string) ([]DailyCount, error)

func (ComplaintDB) GetKeyerOrNil

func (cdb ComplaintDB) GetKeyerOrNil(c Complaint) ds.Keyer

func (ComplaintDB) GetProfileLocations

func (cdb ComplaintDB) GetProfileLocations() ([]geo.Latlong, error)

func (ComplaintDB) GetUniqueUsersAndCountsIn

func (cdb ComplaintDB) GetUniqueUsersAndCountsIn(s, e time.Time) ([]string, int, error)

func (ComplaintDB) HTTPClient

func (cdb ComplaintDB) HTTPClient() *http.Client

func (ComplaintDB) Infof

func (cdb ComplaintDB) Infof(fmtstr string, varargs ...interface{})

func (ComplaintDB) LoadGlobalStats

func (cdb ComplaintDB) LoadGlobalStats() (*GlobalStats, error)

func (ComplaintDB) LookupAll

func (cdb ComplaintDB) LookupAll(cq *CQuery) ([]Complaint, error)

func (ComplaintDB) LookupAllKeys

func (cdb ComplaintDB) LookupAllKeys(cq *CQuery) ([]ds.Keyer, error)

func (ComplaintDB) LookupAllProfiles

func (cdb ComplaintDB) LookupAllProfiles(cq *CQuery) ([]ComplainerProfile, error)

func (ComplaintDB) LookupFirst

func (cdb ComplaintDB) LookupFirst(cq *CQuery) (*Complaint, error)

func (ComplaintDB) LookupKey

func (cdb ComplaintDB) LookupKey(keyerStr string, owner string) (*Complaint, error)

If owner is non-empty, return error if the looked-up key doesn't have that owner. Unless the admin flag is set on the DB handle.

func (ComplaintDB) LookupProfile

func (cdb ComplaintDB) LookupProfile(email string) (*ComplainerProfile, error)

LookupProfile swallows the not-found error; and returns an empty profile on all errors.

func (ComplaintDB) MarshalComplaintSlice

func (cdb ComplaintDB) MarshalComplaintSlice(complaints []Complaint, w io.Writer) error

func (ComplaintDB) MustLookupProfile

func (cdb ComplaintDB) MustLookupProfile(email string) (*ComplainerProfile, error)

If not found, returns an error

func (*ComplaintDB) NewComplaintIterator

func (cdb *ComplaintDB) NewComplaintIterator(cq *CQuery) *ComplaintIterator

func (*ComplaintDB) NewComplaintQuery

func (cdb *ComplaintDB) NewComplaintQuery() *CQuery

func (*ComplaintDB) NewProfileQuery

func (cdb *ComplaintDB) NewProfileQuery() *CQuery

func (*ComplaintDB) NewQuery

func (cdb *ComplaintDB) NewQuery(kind string) *CQuery

func (ComplaintDB) PersistComplaint

func (cdb ComplaintDB) PersistComplaint(c Complaint) error

func (ComplaintDB) PersistComplaints

func (cdb ComplaintDB) PersistComplaints(complaints []Complaint) error

func (ComplaintDB) PersistProfile

func (cdb ComplaintDB) PersistProfile(p ComplainerProfile) error

func (ComplaintDB) RawLookupAll

func (cdb ComplaintDB) RawLookupAll(cq *CQuery) ([]Complaint, error)

func (ComplaintDB) ResetGlobalStats

func (cdb ComplaintDB) ResetGlobalStats()

func (ComplaintDB) SaveGlobalStats

func (cdb ComplaintDB) SaveGlobalStats(gs GlobalStats) error

func (*ComplaintDB) SummaryReport

func (cdb *ComplaintDB) SummaryReport(start, end time.Time, countByUser bool, zipFilter map[string]int) (string, error)

func (ComplaintDB) UnmarshalComplaintSlice

func (cdb ComplaintDB) UnmarshalComplaintSlice(r io.Reader) ([]Complaint, error)

func (ComplaintDB) UpdateComplaint

func (cdb ComplaintDB) UpdateComplaint(c Complaint, owner string) error

If owner is not nil, then complaint must be owned by it

func (ComplaintDB) WriteCQueryToCSV

func (cdb ComplaintDB) WriteCQueryToCSV(cq *CQuery, w io.Writer, headers bool) (int, error)

type ComplaintIterator

type ComplaintIterator ds.Iterator

A shim on the datastoreprovider iterator that can talk flights

func (*ComplaintIterator) Complaint

func (ci *ComplaintIterator) Complaint() *Complaint

func (*ComplaintIterator) Err

func (ci *ComplaintIterator) Err() error

func (*ComplaintIterator) Iterate

func (ci *ComplaintIterator) Iterate(ctx context.Context) bool

func (*ComplaintIterator) Remaining

func (ci *ComplaintIterator) Remaining() int

type ComplaintsAndProfile

type ComplaintsAndProfile struct {
	Profile    ComplainerProfile
	Complaints []Complaint
	Counts     []CountItem
}

type ComplaintsByTimeDesc

type ComplaintsByTimeDesc []Complaint

func (ComplaintsByTimeDesc) Len

func (a ComplaintsByTimeDesc) Len() int

func (ComplaintsByTimeDesc) Less

func (a ComplaintsByTimeDesc) Less(i, j int) bool

func (ComplaintsByTimeDesc) Swap

func (a ComplaintsByTimeDesc) Swap(i, j int)

type ContextProperties

type ContextProperties struct {
	IsAdmin   bool
	ProjectId string
}

func GetContextProperties

func GetContextProperties(ctx context.Context) (ContextProperties, bool)

type CountItem

type CountItem struct {
	Key              string
	Count            int
	TotalComplaints  int
	TotalComplainers int
	IsMaxComplaints  bool
	IsMaxComplainers bool
}

This is just maddening boilerplate junk we need

type DailyCount

type DailyCount struct {
	Datestring       string
	NumComplaints    int
	NumComplainers   int
	IsMaxComplaints  bool
	IsMaxComplainers bool
}

func (DailyCount) String

func (dc DailyCount) String() string

func (DailyCount) Timestamp

func (dc DailyCount) Timestamp() time.Time

type DailyCountDesc

type DailyCountDesc []DailyCount

func (DailyCountDesc) Len

func (a DailyCountDesc) Len() int

func (DailyCountDesc) Less

func (a DailyCountDesc) Less(i, j int) bool

func (DailyCountDesc) Swap

func (a DailyCountDesc) Swap(i, j int)

type FrozenGlobalStats

type FrozenGlobalStats struct {
	Bytes []byte `datastore:",noindex"`
}

type GlobalStats

type GlobalStats struct {
	DatastoreKey string
	Counts       []DailyCount
}

type PostalAddress

type PostalAddress struct {
	Number  string `datastore:",noindex"`
	Street  string `datastore:",noindex"`
	City    string
	State   string `datastore:",noindex"`
	Zip     string
	Country string `datastore:",noindex"`
}

type Submission

type Submission struct {
	T        time.Time
	D        time.Duration // Of most recent submission
	Outcome  SubmissionOutcome
	Response []byte `datastore:",noindex"` // JSON response, in full
	Key      string `datastore:",noindex"` // Foreign key, from backend
	Attempts int
	Log      string `datastore:",noindex"`
}

Fields about backend submission

func (Submission) ClassifyRejection

func (s Submission) ClassifyRejection() (SubmissionRejectReason, string)

func (Submission) String

func (s Submission) String() string

func (Submission) WasFailure

func (s Submission) WasFailure() bool

type SubmissionOutcome

type SubmissionOutcome int
const (
	SubmissionNotAttempted SubmissionOutcome = iota
	SubmissionAccepted
	SubmissionTimeout
	SubmissionRejected
	SubmissionFailed
)

func (SubmissionOutcome) String

func (so SubmissionOutcome) String() string

type SubmissionRejectReason

type SubmissionRejectReason int

func (SubmissionRejectReason) String

func (srr SubmissionRejectReason) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL