func getQuakesWfs(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { //1. check query parameters if res := weft.CheckQuery(r, requiredParams, optionalParams); !res.Ok { return res } v := r.URL.Query() params, err := getQueryParams(v) if err != nil { return weft.BadRequest(err.Error()) } if params.outputFormat == "JSON" { return getQuakesGeoJson(r, h, b, params) } else if params.outputFormat == "CSV" { return getQuakesCsv(r, h, b, params) } else if params.outputFormat == "GML2" { return getQuakesGml2(r, h, b, params) //text/xml; subtype=gml/3.2 } else if params.outputFormat == "TEXT/XML" && params.subType == "GML/3.2" { return getQuakesGml3(r, h, b, params) } else { return weft.BadRequest("Invalid outputFormat") } return &weft.StatusOK }
func quakesWWWnz(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } path := r.URL.Path[quakesNZServiceLen:] // ..."3/100.json" tokens := strings.Split(path, "/") if len(tokens) != 2 { return weft.BadRequest("Bad URL path.") } var mmi int var err error var count int if mmi, err = strconv.Atoi(tokens[0]); err != nil { return weft.BadRequest("Bad URL path. Invalid mmi.") } if count, err = strconv.Atoi(tokens[1][:len(tokens[1])-5]); err != nil { // len(".json") return weft.BadRequest("Bad URL path. Invalid count.") } var d string err = db.QueryRow(quakesNZWWWSQL, mmi, count).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", JSON) return &weft.StatusOK }
func searchPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error var p *searchPage if res := weft.CheckQuery(r, []string{"tagQuery"}, []string{"page"}); !res.Ok { return res } r.ParseForm() tagQuery := r.FormValue("tagQuery") // Javascript should handle empty query value // Non existent value comes from unauthorized submit if tagQuery == "" { return weft.BadRequest("missing required query parameter: tagQuery") } if p, err = newSearchPage(mtrApiUrl); err != nil { return weft.BadRequest("error creating searchPage object") } if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } if err = p.matchingMetrics(tagQuery); err != nil { return weft.InternalServerError(err) } if err := tagSearchTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func dataLatencyThresholdPut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { v := r.URL.Query() var err error var lower, upper int if lower, err = strconv.Atoi(v.Get("lower")); err != nil { return weft.BadRequest("invalid lower") } if upper, err = strconv.Atoi(v.Get("upper")); err != nil { return weft.BadRequest("invalid upper") } siteID := v.Get("siteID") typeID := v.Get("typeID") var result sql.Result // TODO Change to upsert 9.5 // return if insert succeeds if result, err = db.Exec(`INSERT INTO data.latency_threshold(sitePK, typePK, lower, upper) SELECT sitePK, typePK, $3, $4 FROM data.site, data.type WHERE siteID = $1 AND typeID = $2`, siteID, typeID, lower, upper); err == nil { var i int64 if i, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if i == 1 { return &weft.StatusOK } } // return if update one row if pqErr, ok := err.(*pq.Error); ok && pqErr.Code == errorUniqueViolation { if result, err = db.Exec(`UPDATE data.latency_threshold SET lower=$3, upper=$4 WHERE sitePK = (SELECT sitePK FROM data.site WHERE siteID = $1) AND typePK = (SELECT typePK FROM data.type WHERE typeID = $2)`, siteID, typeID, lower, upper); err == nil { var i int64 if i, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if i == 1 { return &weft.StatusOK } } } if err == nil { err = fmt.Errorf("no rows affected, check your query.") } return weft.InternalServerError(err) }
func fieldDevicePut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { v := r.URL.Query() var err error var latitude, longitude float64 if latitude, err = strconv.ParseFloat(v.Get("latitude"), 64); err != nil { return weft.BadRequest("latitude invalid") } if longitude, err = strconv.ParseFloat(v.Get("longitude"), 64); err != nil { return weft.BadRequest("longitude invalid") } var result sql.Result // TODO - use upsert with PG 9.5? // return if insert succeeds if result, err = db.Exec(`INSERT INTO field.device(deviceID, modelPK, latitude, longitude) SELECT $1, modelPK, $3, $4 FROM field.model WHERE modelID = $2`, v.Get("deviceID"), v.Get("modelID"), latitude, longitude); err == nil { var i int64 if i, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if i == 1 { return &weft.StatusOK } } // return if update one row if pqErr, ok := err.(*pq.Error); ok && pqErr.Code == errorUniqueViolation { if result, err = db.Exec(`UPDATE field.device SET latitude = $2, longitude = $3 WHERE deviceID = $1`, v.Get("deviceID"), latitude, longitude); err == nil { var i int64 if i, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if i == 1 { return &weft.StatusOK } } } if err == nil { err = fmt.Errorf("no rows affected, check your query.") } return weft.InternalServerError(err) }
func quakesRegionV1(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{"regionID", "regionIntensity", "number", "quality"}, []string{}); !res.Ok { return res } var err error if _, err = getRegionID(r); err != nil { return weft.BadRequest(err.Error()) } if _, err = getQuality(r); err != nil { return weft.BadRequest(err.Error()) } var regionIntensity string if regionIntensity, err = getRegionIntensity(r); err != nil { return weft.BadRequest(err.Error()) } var n int if n, err = getNumberQuakes(r); err != nil { return weft.BadRequest(err.Error()) } var d string err = db.QueryRow( `SELECT row_to_json(fc) FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features FROM (SELECT 'Feature' as type, ST_AsGeoJSON(q.geom)::json as geometry, row_to_json((SELECT l FROM ( SELECT publicid AS "publicID", to_char(time, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as "time", depth, magnitude, locality, intensity, intensity_newzealand as "regionIntensity", quality ) as l )) as properties FROM haz.quakeapi as q where mmid_newzealand >= $1 ORDER BY time DESC limit $2 ) as f ) as fc`, int(msg.IntensityMMI(regionIntensity)), n).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V1GeoJSON) return &weft.StatusOK }
func dataSitePut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { v := r.URL.Query() siteID := v.Get("siteID") var err error var latitude, longitude float64 if latitude, err = strconv.ParseFloat(v.Get("latitude"), 64); err != nil { return weft.BadRequest("latitude invalid") } if longitude, err = strconv.ParseFloat(v.Get("longitude"), 64); err != nil { return weft.BadRequest("longitude invalid") } var result sql.Result // TODO - use upsert with PG 9.5? // return if insert succeeds if result, err = db.Exec(`INSERT INTO data.site(siteID, latitude, longitude) VALUES($1, $2, $3)`, siteID, latitude, longitude); err == nil { var i int64 if i, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if i == 1 { return &weft.StatusOK } } // return if update one row if pqErr, ok := err.(*pq.Error); ok && pqErr.Code == errorUniqueViolation { if result, err = db.Exec(`UPDATE data.site SET latitude=$2, longitude=$3 where siteID=$1`, siteID, latitude, longitude); err == nil { var i int64 if i, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if i == 1 { return &weft.StatusOK } } } if err == nil { err = fmt.Errorf("no rows affected, check your query.") } return weft.InternalServerError(err) }
func fieldStatePut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { q := r.URL.Query() deviceID := q.Get("deviceID") typeID := q.Get("typeID") var err error var value bool if value, err = strconv.ParseBool(q.Get("value")); err != nil { return weft.BadRequest("invalid value") } var t time.Time if t, err = time.Parse(time.RFC3339, q.Get("time")); err != nil { return weft.BadRequest("invalid time") } var result sql.Result if result, err = db.Exec(`UPDATE field.state SET time = $3, value = $4 WHERE devicePK = (SELECT devicePK from field.device WHERE deviceID = $1) AND typePK = (SELECT typePK from field.state_type WHERE typeID = $2)`, deviceID, typeID, t, value); err != nil { return weft.InternalServerError(err) } // If no rows change either the values are old or it's the first time we've seen this metric. var u int64 if u, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if u == 1 { return &weft.StatusOK } else if result, err = db.Exec(`INSERT INTO field.state(devicePK, typePK, time, value) SELECT devicePK, typePK, $3, $4 FROM field.device, field.state_type WHERE deviceID = $1 AND typeID = $2`, deviceID, typeID, t, value); err == nil { var i int64 if i, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if i == 1 { return &weft.StatusOK } } return weft.InternalServerError(err) }
func intensityMeasuredLatestV1(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{"type"}, []string{}); !res.Ok { return res } if r.URL.Query().Get("type") != "measured" { return weft.BadRequest("type must be measured.") } var d string err := db.QueryRow( `SELECT row_to_json(fc) FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features FROM (SELECT 'Feature' as type, ST_AsGeoJSON(s.location)::json as geometry, row_to_json(( select l from ( select mmi ) as l )) as properties from (select location, mmi FROM impact.intensity_measured) as s ) As f ) as fc`).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V1GeoJSON) return &weft.StatusOK }
func fieldMetricTagPut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { v := r.URL.Query() var err error var result sql.Result if result, err = db.Exec(`INSERT INTO field.metric_tag(devicePK, typePK, tagPK) SELECT devicePK, typePK, tagPK FROM field.device, field.type, mtr.tag WHERE deviceID = $1 AND typeID = $2 AND tag = $3`, v.Get("deviceID"), v.Get("typeID"), v.Get("tag")); err != nil { if err, ok := err.(*pq.Error); ok && err.Code == errorUniqueViolation { // ignore unique constraint errors return &weft.StatusOK } else { return weft.InternalServerError(err) } } var i int64 if i, err = result.RowsAffected(); err != nil { return weft.InternalServerError(err) } if i != 1 { return weft.BadRequest("Didn't create row, check your query parameters exist") } return &weft.StatusOK }
func volcanoRegionV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } var err error var volcanoId string if volcanoId, err = getVolcanoIDRegion(r); err != nil { return weft.BadRequest(err.Error()) } var d string err = db.QueryRow(`SELECT row_to_json(fc) FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features FROM (SELECT 'Feature' as type, ST_AsGeoJSON(r.region)::json as geometry, row_to_json((SELECT l FROM ( SELECT id, title ) as l )) as properties FROM haz.volcano as r where id = $1) as f ) as fc;`, volcanoId).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V2GeoJSON) return &weft.StatusOK }
func quakeV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } if len(r.URL.Query()) != 0 { return weft.BadRequest("incorrect number of query parameters.") } var publicID string var res *weft.Result if publicID, res = getPublicIDPath(r); !res.Ok { return res } var d string err := db.QueryRow(quakeV2SQL, publicID).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V2GeoJSON) return &weft.StatusOK }
func tagPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } p := tagPage{} p.Path = r.URL.Path p.Border.Title = "GeoNet MTR" p.ActiveTab = "Tag" if err = p.populateTags(); err != nil { return weft.InternalServerError(err) } ph := strings.TrimPrefix(p.Path, "/tag") if strings.HasPrefix(ph, "/") { ph = ph[1:] } currTab := -1 // Create grouping tabs p.TagTabs = make([]string, 0) for i, k := range tagGrouper { s := k[:1] + "-" + k[len(k)-1:] p.TagTabs = append(p.TagTabs, s) if ph == s { currTab = i } } if currTab == -1 && ph != "" { return weft.BadRequest("Invalid tag index.") } if ph == "" { currTab = 0 } p.Path = p.TagTabs[currTab] for _, t := range p.Border.TagList { c := t[:1] if strings.Contains(tagGrouper[currTab], c) { p.Tags = append(p.Tags, t) } } if err = tagPageTemplate.ExecuteTemplate(b, "border", p); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func delApplication(applicationID string) *weft.Result { if applicationID == "" { return weft.BadRequest("empty applicationID") } if _, err := db.Exec(`DELETE FROM app.application WHERE applicationID = $1`, applicationID); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func docs(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } if r.URL.Path != "/" { return weft.BadRequest("invalid path") } b.Write(docsIndex) return &weft.StatusOK }
func getQuakesCsv(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { //1. check query parameters if res := weft.CheckQuery(r, []string{}, optionalParams); !res.Ok { return res } v := r.URL.Query() //21 fields sqlString := `select format('%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s', publicid,eventtype,to_char(origintime, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), to_char(modificationtime, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),longitude, latitude, magnitude, depth,magnitudetype, depthtype, evaluationmethod, evaluationstatus, evaluationmode, earthmodel, usedphasecount, usedstationcount,magnitudestationcount, minimumdistance, azimuthalgap,originerror,magnitudeuncertainty) as csv from haz.quake_search_v1` params, err := getQueryParams(v) if err != nil { return weft.BadRequest(err.Error()) } sqlString, args := getSqlQuery(sqlString, params) rows, err := db.Query(sqlString, args...) if err != nil { return weft.InternalServerError(err) } defer rows.Close() var ( // b bytes.Buffer d string ) b.WriteString("publicid,eventtype,origintime,modificationtime,longitude, latitude, magnitude, depth,magnitudetype,depthtype," + "evaluationmethod,evaluationstatus,evaluationmode,earthmodel,usedphasecount,usedstationcount,magnitudestationcount,minimumdistance," + "azimuthalgap,originerror,magnitudeuncertainty") b.WriteString("\n") for rows.Next() { err := rows.Scan(&d) if err != nil { return weft.InternalServerError(err) } b.WriteString(d) b.WriteString("\n") } // send result response h.Set("Content-Disposition", `attachment; filename="earthquakes.csv"`) h.Set("Content-Type", CONTENT_TYPE_CSV) return &weft.StatusOK }
func fieldMetricTagProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { var err error var rows *sql.Rows deviceID := r.URL.Query().Get("deviceID") typeID := r.URL.Query().Get("typeID") if deviceID == "" && typeID == "" { if rows, err = dbR.Query(`SELECT deviceID, tag, typeID from field.metric_tag JOIN mtr.tag USING (tagpk) JOIN field.device USING (devicepk) JOIN field.type USING (typepk) ORDER BY tag ASC`); err != nil { return weft.InternalServerError(err) } defer rows.Close() } else if deviceID != "" && typeID != "" { if rows, err = dbR.Query(`SELECT deviceID, tag, typeID from field.metric_tag JOIN mtr.tag USING (tagpk) JOIN field.device USING (devicepk) JOIN field.type USING (typepk) WHERE deviceID=$1 AND typeID=$2 ORDER BY tag ASC`, deviceID, typeID); err != nil { return weft.InternalServerError(err) } defer rows.Close() } else { return weft.BadRequest("Invalid parameter. Please specify both deviceID and typeID.") } var ts mtrpb.FieldMetricTagResult for rows.Next() { var t mtrpb.FieldMetricTag if err = rows.Scan(&t.DeviceID, &t.Tag, &t.TypeID); err != nil { return weft.InternalServerError(err) } ts.Result = append(ts.Result, &t) } var by []byte if by, err = proto.Marshal(&ts); err != nil { return weft.InternalServerError(err) } b.Write(by) return &weft.StatusOK }
func intensityProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{"type"}, []string{"publicID"}); !res.Ok { return res } var ts string var err error if ts, err = getIntensityType(r); err != nil { return weft.BadRequest(err.Error()) } var shaking *haz.Shaking switch ts { case "measured": if shaking, err = intensityMeasuredLatest(); err != nil { return weft.ServiceUnavailableError(err) } case "reported": publicID := r.URL.Query().Get("publicID") switch publicID { case "": end := time.Now().UTC() start := end.Add(-60 * time.Minute) if shaking, err = intensityReported(start, end); err != nil { return weft.ServiceUnavailableError(err) } default: var t time.Time var res *weft.Result if t, res = getQuakeTime(r); !res.Ok { return res } start := t.Add(-1 * time.Minute) end := t.Add(15 * time.Minute) if shaking, err = intensityReported(start, end); err != nil { return weft.ServiceUnavailableError(err) } } } var by []byte if by, err = proto.Marshal(shaking); err != nil { return weft.ServiceUnavailableError(err) } b.Write(by) h.Set("Content-Type", protobuf) return &weft.StatusOK }
func tagDelete(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { tag := strings.TrimPrefix(r.URL.Path, "/tag/") if tag == "" { return weft.BadRequest("empty tag") } if _, err := db.Exec(`DELETE FROM mtr.tag WHERE tag=$1`, tag); err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func volcanoRegionHistoryProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } var volcanoId string var err error if volcanoId, err = getVolcanoRegionHistory(r); err != nil { return weft.BadRequest(err.Error()) } var rows *sql.Rows if rows, err = db.Query(fmt.Sprintf(volcanoRegionHistoryProtoSQL, 90), volcanoId); err != nil { return weft.ServiceUnavailableError(err) } var quakes []*haz.Quake for rows.Next() { var t time.Time var mt time.Time q := haz.Quake{} if err = rows.Scan(&q.PublicID, &t, &mt, &q.Depth, &q.Magnitude, &q.Locality, &q.Mmi, &q.Quality, &q.Longitude, &q.Latitude); err != nil { return weft.ServiceUnavailableError(err) } q.Time = &haz.Timestamp{Sec: t.Unix(), Nsec: int64(t.Nanosecond())} q.ModificationTime = &haz.Timestamp{Sec: mt.Unix(), Nsec: int64(mt.Nanosecond())} quakes = append(quakes, &q) } qs := haz.Quakes{Quakes: quakes} var by []byte if by, err = proto.Marshal(&qs); err != nil { return weft.ServiceUnavailableError(err) } b.Write(by) h.Set("Content-Type", protobuf) return &weft.StatusOK }
func indexPage(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } if r.URL.Path != "/" { return weft.BadRequest("invalid path") } err := indexTemp.Execute(b, nil) if err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func tagPut(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { tag := strings.TrimPrefix(r.URL.Path, "/tag/") if tag == "" { return weft.BadRequest("empty tag") } if _, err := db.Exec(`INSERT INTO mtr.tag(tag) VALUES($1)`, tag); err != nil { if err, ok := err.(*pq.Error); ok && err.Code == errorUniqueViolation { // no-op. Nothing to update. } else { return weft.InternalServerError(err) } } return &weft.StatusOK }
func getQuakesCsv(r *http.Request, h http.Header, b *bytes.Buffer, params *QueryParams) *weft.Result { //21 fields sqlPre := `select format('%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s', publicid,eventtype,to_char(origintime, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), to_char(modificationtime, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),CAST(longitude AS NUMERIC(16,8)), CAST(latitude AS NUMERIC(16,8)), CAST(magnitude AS NUMERIC(16,8)), CAST(depth AS NUMERIC(16,8)), magnitudetype, depthtype, evaluationmethod, evaluationstatus, evaluationmode, earthmodel, usedphasecount, usedstationcount,magnitudestationcount, CAST(minimumdistance AS NUMERIC(16,8)),CAST(azimuthalgap AS NUMERIC(16,8)), CAST(originerror AS NUMERIC(16,8)),CAST(magnitudeuncertainty AS NUMERIC(16,8)) ) as csv from haz.quake_search_v1` sqlString, args, err1 := getSqlQueryString(sqlPre, params) if err1 != nil { return weft.BadRequest(err1.Error()) } rows, err := db.Query(sqlString, args...) if err != nil { return weft.InternalServerError(err) } defer rows.Close() var ( d string ) b.WriteString("publicid,eventtype,origintime,modificationtime,longitude,latitude,magnitude,depth,magnitudetype,depthtype," + "evaluationmethod,evaluationstatus,evaluationmode,earthmodel,usedphasecount,usedstationcount,magnitudestationcount,minimumdistance," + "azimuthalgap,originerror,magnitudeuncertainty") b.WriteString("\n") for rows.Next() { err := rows.Scan(&d) if err != nil { return weft.InternalServerError(err) } b.WriteString(d) b.WriteString("\n") } // send result response h.Set("Content-Disposition", `attachment; filename="earthquakes.csv"`) h.Set("Content-Type", CONTENT_TYPE_CSV) return &weft.StatusOK }
func getPublicIDPath(r *http.Request) (string, *weft.Result) { publicID := r.URL.Path[quakeLen:] if !publicIDRe.MatchString(publicID) { return publicID, weft.BadRequest("invalid publicID: " + publicID) } var d string err := db.QueryRow("select publicid FROM haz.quake where publicid = $1", publicID).Scan(&d) if err == sql.ErrNoRows { return publicID, &weft.NotFound } if err != nil { return publicID, weft.ServiceUnavailableError(err) } return publicID, &weft.StatusOK }
func getQuakeTime(r *http.Request) (time.Time, *weft.Result) { publicID := r.URL.Query().Get("publicID") originTime := time.Time{} if !publicIDRe.MatchString(publicID) { return originTime, weft.BadRequest(fmt.Sprintf("invalid publicID " + publicID)) } err := db.QueryRow("select time FROM haz.quake where publicid = $1", publicID).Scan(&originTime) if err == sql.ErrNoRows { return originTime, &weft.NotFound } if err != nil { return originTime, weft.ServiceUnavailableError(err) } return originTime, &weft.StatusOK }
/** * get the number of quakes with breaking dates when the number is large */ func getQuakesCount(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { //1. check query parameters if res := weft.CheckQuery(r, []string{}, optionalParams); !res.Ok { return res } v := r.URL.Query() sqlString := `select count(*) from haz.quake_search_v1` params, err := getQueryParams(v) if err != nil { return weft.BadRequest(err.Error()) } sqlString, args := getSqlQuery(sqlString, params) var count int err = db.QueryRow(sqlString, args...).Scan(&count) if err != nil { return weft.InternalServerError(err) } resp := "{\"count\":" + strconv.Itoa(count) if count > MAX_QUAKES_NUMBER { //get break dates breakDates := getBreakDates(params) if len(breakDates) > 0 { resp += ", \n\"dates\":[" for n, date := range breakDates { if n > 0 { resp += "," } resp += "\"" + date + "\"" } resp += "]\n" } } resp += "}" h.Set("Content-Type", CONTENT_TYPE_JSON) b.WriteString(resp) return &weft.StatusOK }
func quakesVolcanoRegionV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } var err error var days int = 90 var volcanoId string if volcanoId, err = getVolcanoIDQuake(r); err != nil { return weft.BadRequest(err.Error()) } var d string err = db.QueryRow(`SELECT row_to_json(fc) FROM ( SELECT 'FeatureCollection' as type, COALESCE(array_to_json(array_agg(f)), '[]') as features FROM (SELECT 'Feature' as type, ST_AsGeoJSON(q.geom)::json as geometry, row_to_json((SELECT l FROM ( SELECT publicid AS "publicID", to_char(time, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as "time", depth, magnitude, locality, intensity, intensity_newzealand as "regionIntensity", floor(mmid_newzealand) as "mmi", quality ) as l )) as properties FROM haz.quakeapi as q where st_covers((select region from haz.volcano hv where id = $1 and q.depth < hv.depth and DATE_PART('day', now() - q.time) < $2), q.geom) ORDER BY time DESC ) as f ) as fc;`, volcanoId, days).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", V2GeoJSON) return &weft.StatusOK }
func indexPage(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } if r.URL.Path != "/" { return weft.BadRequest("invalid path") } var p searchPage p.ApiKey = os.Getenv("BING_API_KEY") err := indexTemp.ExecuteTemplate(b, "base", p) if err != nil { return weft.InternalServerError(err) } return &weft.StatusOK }
func quakeStatsV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } if len(r.URL.Query()) != 0 { return weft.BadRequest("incorrect number of query parameters.") } var d string err := db.QueryRow(quakeStatsV2SQL).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Surrogate-Control", maxAge300) h.Set("Content-Type", V2JSON) return &weft.StatusOK }
func quakeWWW(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result { if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok { return res } publicID := strings.TrimSuffix(strings.TrimPrefix(r.URL.Path, "/quake/services/quake/"), ".json") if publicID == "" { return weft.BadRequest("invalid publicID path: " + r.URL.Path) } var d string err := db.QueryRow(quakeWWWSQL, publicID).Scan(&d) if err != nil { return weft.ServiceUnavailableError(err) } b.WriteString(d) h.Set("Content-Type", JSON) return &weft.StatusOK }