예제 #1
0
func quakeProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	var q haz.Quake
	var res *weft.Result

	if q.PublicID, res = getPublicIDPath(r); !res.Ok {
		return res
	}

	var t time.Time
	var mt time.Time
	var err error

	if err = db.QueryRow(quakeProtoSQL, q.PublicID).Scan(&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())}

	var by []byte

	if by, err = proto.Marshal(&q); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.Write(by)
	h.Set("Content-Type", protobuf)
	return &weft.StatusOK
}
예제 #2
0
// fetches SC3ML and turns it into a protobuf.
func quakeTechnicalProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	by, res := getBytes(s3+strings.TrimPrefix(r.URL.Path, "/quake/technical/")+".xml", "")
	if !res.Ok {
		return res
	}

	q, err := sc3ml.QuakeTechnical(by)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	m, err := proto.Marshal(&q)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.Write(m)

	h.Set("Content-Type", protobuf)
	return &weft.StatusOK
}
예제 #3
0
파일: news.go 프로젝트: junghao/haz
func newsProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	res, err := client.Get(newsURL)
	defer res.Body.Close()
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	f, err := unmarshalNews(body)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	var n haz.News

	for _, v := range f.Entries {
		s := haz.Story{
			Title: v.Title,
			Link:  v.Link.Href,
		}

		t, err := time.Parse(time.RFC3339, v.Published)
		if err != nil {
			return weft.ServiceUnavailableError(err)
		}

		ts := haz.Timestamp{Sec: t.Unix(), Nsec: int64(t.Nanosecond())}

		s.Published = &ts

		n.Stories = append(n.Stories, &s)
	}

	var by []byte
	if by, err = proto.Marshal(&n); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.Write(by)

	h.Set("Content-Type", protobuf)
	h.Set("Surrogate-Control", maxAge300)

	return &weft.StatusOK
}
예제 #4
0
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
}
예제 #5
0
func quakeHistoryProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	var publicID string
	var res *weft.Result

	if publicID, res = getPublicIDHistoryPath(r); !res.Ok {
		return res
	}

	var rows *sql.Rows
	var err error

	if rows, err = db.Query(quakeHistoryProtoSQL, publicID); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	var quakes []*haz.Quake

	for rows.Next() {
		var t time.Time
		var mt time.Time
		q := haz.Quake{PublicID: publicID}

		if err = rows.Scan(&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
}
예제 #6
0
파일: quakeWWW.go 프로젝트: GeoNet/haz
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
}
예제 #7
0
파일: intensity.go 프로젝트: GeoNet/haz
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
}
예제 #8
0
파일: volcanoV2.go 프로젝트: GeoNet/haz
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
}
예제 #9
0
파일: quakeV2.go 프로젝트: GeoNet/haz
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
}
예제 #10
0
파일: volcanoV2.go 프로젝트: GeoNet/haz
func valV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	var d string

	err := db.QueryRow(`SELECT row_to_json(fc)
                         FROM ( SELECT 'FeatureCollection' as type, array_to_json(array_agg(f)) as features
                         FROM (SELECT 'Feature' as type,
                         ST_AsGeoJSON(v.location)::json as geometry,
                         row_to_json((SELECT l FROM 
                         	(
                         		SELECT 
                                id AS "volcanoID",
                                title AS "volcanoTitle",
                                alert_level as "level",
                                activity,
                                hazards 
                           ) as l
                         )) as properties FROM (haz.volcano JOIN haz.volcanic_alert_level using (alert_level)) as v ) As f )  as fc`).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V2GeoJSON)
	return &weft.StatusOK
}
예제 #11
0
func quakesProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{"MMI"}, []string{}); !res.Ok {
		return res
	}

	var mmi int
	var err error

	if mmi, err = getMMI(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var rows *sql.Rows

	if rows, err = db.Query(quakesProtoSQL, mmi); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	var quakes haz.Quakes

	for rows.Next() {
		var t time.Time
		var mt time.Time
		var 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.Quakes = append(quakes.Quakes, &q)
	}

	var by []byte

	if by, err = proto.Marshal(&quakes); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.Write(by)
	h.Set("Content-Type", protobuf)
	return &weft.StatusOK
}
예제 #12
0
func fieldLatestGeoJSON(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var rows *sql.Rows
	var err error

	typeID := r.URL.Query().Get("typeID")

	var d string
	err = db.QueryRow("select typeID FROM field.type where typeID = $1", typeID).Scan(&d)

	if err == sql.ErrNoRows {
		return &weft.NotFound
	}
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	if rows, err = dbR.Query(`
		WITH p as (SELECT geom, time, value, lower, upper, deviceid, typeid
		FROM field.metric_summary
		JOIN field.device using (devicePK)
		JOIN field.threshold using (devicePK, typePK)
		JOIN field.type using (typePK)
		WHERE typeID = $1)
		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(p.geom)::json as geometry,
				row_to_json(
					(SELECT l FROM
						(
						SELECT
						"time",
						value,
						lower,
						upper,
						deviceid,
						typeid
						) as l
					)
				) as properties FROM p
		) as f ) as fc`, typeID); err != nil {
		return weft.InternalServerError(err)
	}
	defer rows.Close()

	var gj string

	if rows.Next() {

		if err = rows.Scan(&gj); err != nil {
			return weft.InternalServerError(err)
		}
	}

	rows.Close()
	b.WriteString(gj)

	return &weft.StatusOK
}
예제 #13
0
파일: quake.go 프로젝트: GeoNet/haz
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
}
예제 #14
0
파일: felt.go 프로젝트: GeoNet/haz
func feltV1(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{"publicID"}, []string{}); !res.Ok {
		return res
	}

	var publicID string
	var res *weft.Result

	if publicID, res = getPublicID(r); !res.Ok {
		return res
	}

	var rs *http.Response
	rs, err := client.Get(feltURL + publicID + ".geojson")
	defer rs.Body.Close()
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	bt, err := ioutil.ReadAll(rs.Body)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	// Felt returns a 400 when it should probably be a 404.  Tapestry quirk?
	switch {
	case http.StatusOK == rs.StatusCode:
		h.Set("Content-Type", V1GeoJSON)
		b.Write(bt)
		return &weft.StatusOK
	case 4 == rs.StatusCode/100:
		//res := &notFound
		//res.msg = string(bt)
		return &weft.NotFound
	case 5 == rs.StatusCode/500:
		return weft.ServiceUnavailableError(errors.New("error proxying felt resports.  Shrug."))
	}

	return weft.ServiceUnavailableError(errors.New("unknown response from felt."))
}
예제 #15
0
파일: volcanoProto.go 프로젝트: GeoNet/haz
func valProto(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 rows *sql.Rows

	if rows, err = db.Query(`SELECT id, title, alert_level, activity, hazards,
				ST_X(location::geometry), ST_Y(location::geometry)
				FROM haz.volcano JOIN haz.volcanic_alert_level using (alert_level)
				ORDER BY alert_level DESC, title ASC`); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	var vol haz.Volcanoes

	for rows.Next() {
		v := haz.Volcano{Val: &haz.VAL{}}
		if err = rows.Scan(&v.VolcanoID, &v.Title, &v.Val.Level, &v.Val.Activity, &v.Val.Hazards,
			&v.Longitude, &v.Latitude); err != nil {
			return weft.ServiceUnavailableError(err)
		}

		vol.Volcanoes = append(vol.Volcanoes, &v)
	}

	var by []byte

	if by, err = proto.Marshal(&vol); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.Write(by)

	h.Set("Content-Type", protobuf)
	return &weft.StatusOK
}
예제 #16
0
파일: quakeWWW.go 프로젝트: GeoNet/haz
func quakesWWWfelt(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}
	var d string
	err := db.QueryRow(quakesNZWWWSQL, feltMmi, defaultRecordCount).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", JSON)
	return &weft.StatusOK
}
예제 #17
0
파일: news.go 프로젝트: junghao/haz
func newsV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	j, err := fetchRSS(newsURL)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	h.Set("Surrogate-Control", maxAge300)
	h.Set("Content-Type", V2JSON)
	b.Write(j)

	return &weft.StatusOK
}
예제 #18
0
파일: valid.go 프로젝트: GeoNet/haz
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
}
예제 #19
0
파일: valid.go 프로젝트: GeoNet/haz
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
}
예제 #20
0
파일: volcanoV2.go 프로젝트: GeoNet/haz
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
}
예제 #21
0
파일: quakeV2.go 프로젝트: GeoNet/haz
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
}
예제 #22
0
파일: quakeWWW.go 프로젝트: GeoNet/haz
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
}
예제 #23
0
파일: intensityV2.go 프로젝트: GeoNet/haz
func intensityV2(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 d string

	switch ts {
	case "measured":
		err = db.QueryRow(intensityMeasuredLatestV2SQL).Scan(&d)
	case "reported":
		publicID := r.URL.Query().Get("publicID")
		switch publicID {
		case "":
			err = db.QueryRow(intenstityReportedLatestV2SQL).Scan(&d)
		default:
			var t time.Time
			var res *weft.Result
			if t, res = getQuakeTime(r); !res.Ok {
				return res
			}
			err = db.QueryRow(intenstityReportedWindowV2SQL, t.Add(time.Duration(-1*time.Minute)), t.Add(time.Duration(15*time.Minute))).Scan(&d)
		}
	}

	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V2GeoJSON)

	return &weft.StatusOK
}
예제 #24
0
파일: quake.go 프로젝트: GeoNet/haz
func quakeV1(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	var publicID string
	var res *weft.Result

	if publicID, res = getPublicIDPath(r); !res.Ok {
		return res
	}

	var d string
	err := db.QueryRow(
		`SELECT row_to_json(fc)
                         FROM ( SELECT 'FeatureCollection' as type, 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.quake as q where publicid = $1 ) As f )  as fc`, publicID).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V1GeoJSON)
	return &weft.StatusOK
}
예제 #25
0
파일: quakeV2.go 프로젝트: GeoNet/haz
func quakesV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{"MMI"}, []string{}); !res.Ok {
		return res
	}

	var mmi int
	var err error

	if mmi, err = getMMI(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	var d string
	err = db.QueryRow(quakesV2SQL, mmi).Scan(&d)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.WriteString(d)
	h.Set("Content-Type", V2GeoJSON)
	return &weft.StatusOK
}
예제 #26
0
파일: volcanoProto.go 프로젝트: GeoNet/haz
func quakeInVolcanoRegionStatsProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {

	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}
	var q haz.QuakeStats

	var rows *sql.Rows
	var err error
	var volcanoId string

	if volcanoId, err = getVolcanoRegionStats(r); err != nil {
		return weft.BadRequest(err.Error())
	}

	if rows, err = db.Query(fmt.Sprintf(quakesPerDayInVolcanoRegionSQL, 90), volcanoId); err != nil {
		return weft.ServiceUnavailableError(err)
	}
	defer rows.Close()

	for rows.Next() {
		var t time.Time
		var r haz.Rate

		if err = rows.Scan(&t, &r.Count); err != nil {
			return weft.ServiceUnavailableError(err)
		}

		r.Time = &haz.Timestamp{Sec: t.Unix(), Nsec: int64(t.Nanosecond())}

		q.PerDay = append(q.PerDay, &r)
	}
	rows.Close()

	q.Year = make(map[int32]int32)

	if rows, err = db.Query(fmt.Sprintf(sumMagsInVolcanoRegionSQL, 365), volcanoId); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	defer rows.Close()

	for rows.Next() {
		var k, v int32
		if err = rows.Scan(&k, &v); err != nil {
			return weft.ServiceUnavailableError(err)
		}
		q.Year[k] = v
	}
	rows.Close()

	q.Month = make(map[int32]int32)

	if rows, err = db.Query(fmt.Sprintf(sumMagsInVolcanoRegionSQL, 28), volcanoId); err != nil {
		return weft.ServiceUnavailableError(err)
	}
	defer rows.Close()

	for rows.Next() {
		var k, v int32
		if err = rows.Scan(&k, &v); err != nil {
			return weft.ServiceUnavailableError(err)
		}
		q.Month[k] = v
	}
	rows.Close()

	q.Week = make(map[int32]int32)

	if rows, err = db.Query(fmt.Sprintf(sumMagsInVolcanoRegionSQL, 7), volcanoId); err != nil {
		return weft.ServiceUnavailableError(err)
	}
	defer rows.Close()

	for rows.Next() {
		var k, v int32
		if err = rows.Scan(&k, &v); err != nil {
			return weft.ServiceUnavailableError(err)
		}
		q.Week[k] = v
	}
	rows.Close()

	var by []byte

	if by, err = proto.Marshal(&q); err != nil {
		return weft.ServiceUnavailableError(err)
	}

	b.Write(by)

	h.Set("Content-Type", protobuf)
	h.Set("Surrogate-Control", maxAge300)

	return &weft.StatusOK
}
예제 #27
0
파일: cap_quake.go 프로젝트: GeoNet/haz
func capQuakeFeed(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	// we are only serving /cap/1.2/GPAv1.0/feed/atom1.0/quake at the moment and the router
	// matches that so no need for any further validation here yet.

	atom := capAtomFeed{
		Title: `CAP quakes`,
		ID:    fmt.Sprintf("https://%s/cap/1.2/GPA1.0/feed/atom1.0/quake", serverCName),
		Link:  fmt.Sprintf("https://%s/cap/1.2/GPA1.0/feed/atom1.0/quake", serverCName),
	}

	rows, err := db.Query(capQuakeFeedSQL, int(minMMID))
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}
	defer rows.Close()

	tLatest := time.Time{}
	for rows.Next() {

		var p string
		var i int
		t := time.Time{}

		err := rows.Scan(&p, &i, &t)
		if err != nil {
			return weft.ServiceUnavailableError(err)
		}

		entry := capAtomEntry{
			ID:       fmt.Sprintf("http://geonet.org/nz/quakes/%s.%d", p, i),
			Title:    fmt.Sprintf("Quake CAP Message %s.%d", p, i),
			Updated:  t,
			Summary:  fmt.Sprintf("Quake CAP Message %s.%d", p, i),
			HrefCAP:  fmt.Sprintf("https://%s/cap/1.2/GPA1.0/quake/%s.%d", serverCName, p, i),
			HrefHTML: fmt.Sprintf("http://geonet.org.nz/quakes/%s", p),
		}

		atom.Entries = append(atom.Entries, entry)

		if t.After(tLatest) {
			tLatest = t
		}
	}
	rows.Close()

	if tLatest.Equal(time.Time{}) {
		tLatest = time.Now().UTC()
	}

	atom.Updated = tLatest
	err = capTemplates.ExecuteTemplate(b, "capAtom", atom)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	h.Set("Content-Type", Atom)
	return &weft.StatusOK
}
예제 #28
0
파일: cap_quake.go 프로젝트: GeoNet/haz
func capQuake(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{}, []string{}); !res.Ok {
		return res
	}

	id := r.URL.Path[22:]

	if !capIDRe.MatchString(id) {
		return weft.BadRequest("invalid ID: " + id)
	}

	p := strings.Split(id, `.`)
	if len(p) != 2 {
		return weft.BadRequest("invalid ID: " + id)
	}

	c := capQuakeT{ID: id}
	c.Quake.PublicID = p[0]

	rows, err := db.Query(`select modificationTimeUnixMicro, modificationtime from haz.quakehistory
		where publicid = $1 AND modificationTimeUnixMicro < $2 AND status in ('reviewed','deleted')`, p[0], p[1])
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}
	defer rows.Close()

	c.References = make([]string, 0)

	for rows.Next() {
		var i int
		var t time.Time
		err := rows.Scan(&i, &t)
		if err != nil {
			return weft.ServiceUnavailableError(err)
		}
		c.References = append(c.References, fmt.Sprintf("%s.%d,%s", c.Quake.PublicID, i, t.In(nz).Format(time.RFC3339)))
	}
	rows.Close()

	err = db.QueryRow(`select depth, 
		magnitude, 
		status, 
		usedPhaseCount,
		magnitudestationcount,
		longitude,
		latitude,
		time,
		modificationTime,
		intensity
	 FROM haz.quakehistory where publicid = $1 AND modificationTimeUnixMicro = $2`,
		p[0], p[1]).Scan(
		&c.Quake.Depth,
		&c.Quake.Magnitude,
		&c.Status,
		&c.Quake.UsedPhaseCount,
		&c.Quake.MagnitudeStationCount,
		&c.Quake.Longitude,
		&c.Quake.Latitude,
		&c.Quake.Time,
		&c.Quake.ModificationTime,
		&c.Intensity,
	)
	if err == sql.ErrNoRows {
		return &weft.NotFound
	}
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	cl, err := c.Quake.Closest()
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	c.Localities = c.Quake.Localities(minMMID)

	if len(c.Localities) == 0 {
		c.Localities = append(c.Localities, cl)
	}

	c.Closest = cl

	err = capTemplates.ExecuteTemplate(b, "capQuake", c)
	if err != nil {
		return weft.ServiceUnavailableError(err)
	}

	h.Set("Content-Type", CAP)
	return &weft.StatusOK
}