Пример #1
0
func fieldThresholdProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	if rows, err = dbR.Query(`SELECT deviceID, typeID, lower, upper, scale
		FROM
		field.threshold JOIN field.device USING (devicepk)
		JOIN field.type USING (typepk)`); err != nil {
		return weft.InternalServerError(err)
	}

	var ts mtrpb.FieldMetricThresholdResult

	for rows.Next() {
		var t mtrpb.FieldMetricThreshold

		if err = rows.Scan(&t.DeviceID, &t.TypeID, &t.Lower, &t.Upper, &t.Scale); 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
}
Пример #2
0
func dataCompletenessDelete(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	v := r.URL.Query()

	siteID := v.Get("siteID")
	typeID := v.Get("typeID")

	var txn *sql.Tx
	var err error

	if txn, err = db.Begin(); err != nil {
		return weft.InternalServerError(err)
	}

	for _, table := range []string{"data.completeness", "data.completeness_summary", "data.completeness_tag"} {
		if _, err = txn.Exec(`DELETE FROM `+table+` WHERE
				sitePK = (SELECT sitePK FROM data.site WHERE siteID = $1)
				AND typePK = (SELECT typePK FROM data.completeness_type WHERE typeID = $2)`,
			siteID, typeID); err != nil {
			txn.Rollback()
			return weft.InternalServerError(err)
		}
	}

	if err = txn.Commit(); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #3
0
func fieldModelProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	if rows, err = dbR.Query(`SELECT modelID
		FROM
		field.model`); err != nil {
		return weft.InternalServerError(err)
	}

	var fmr mtrpb.FieldModelResult

	for rows.Next() {
		var t mtrpb.FieldModel

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

		fmr.Result = append(fmr.Result, &t)
	}

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

	b.Write(by)

	return &weft.StatusOK
}
Пример #4
0
func dataCompletenessTypeProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	if rows, err = dbR.Query(`SELECT typeID FROM data.completeness_type ORDER BY typeID ASC`); err != nil {
		return weft.InternalServerError(err)
	}
	defer rows.Close()

	var ftr mtrpb.DataTypeResult

	for rows.Next() {
		var ft mtrpb.DataType

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

		ftr.Result = append(ftr.Result, &ft)
	}

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

	b.Write(by)

	return &weft.StatusOK
}
Пример #5
0
// handler that serves an html page for detailed metric information
func metricDetailHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {

	var (
		err error
	)

	if res := weft.CheckQuery(r, []string{"deviceID", "typeID"}, []string{}); !res.Ok {
		return res
	}

	// We create a page struct with variables to substitute into the loaded template
	q := r.URL.Query()
	deviceID := q.Get("deviceID")
	typeID := q.Get("typeID")

	p := metricDetailPage{MtrApiUrl: mtrApiUrl}
	p.Border.Title = fmt.Sprintf("Detailed Metric Info for deviceID:%s TypeID:%s", deviceID, typeID)
	p.MetricDetail.DeviceID = deviceID
	p.MetricDetail.TypeID = typeID

	if err = p.populateTags(); err != nil {
		return weft.InternalServerError(err)
	}

	if err = metricDetailTemplate.ExecuteTemplate(b, "border", p); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #6
0
func fieldMetricDelete(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	v := r.URL.Query()

	deviceID := v.Get("deviceID")
	typeID := v.Get("typeID")

	var err error
	var txn *sql.Tx

	if txn, err = db.Begin(); err != nil {
		return weft.InternalServerError(err)
	}

	for _, table := range []string{"field.metric", "field.metric_summary", "field.metric_tag", "field.threshold"} {
		if _, err = txn.Exec(`DELETE FROM `+table+` WHERE
				devicePK = (SELECT devicePK FROM field.device WHERE deviceID = $1)
				 AND typePK = (SELECT typePK from field.type WHERE typeID = $2)`,
			deviceID, typeID); err != nil {
			txn.Rollback()
			return weft.InternalServerError(err)
		}
	}

	if err = txn.Commit(); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #7
0
func fieldPageHandler(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 := mtrUiPage{}
	p.Path = r.URL.Path
	p.Border.Title = "GeoNet MTR"
	p.ActiveTab = "Field"

	if err = p.populateTags(); err != nil {
		return weft.InternalServerError(err)
	}

	var pa panel
	if pa, err = getFieldSummary(); err != nil {
		return weft.InternalServerError(err)
	}

	p.Panels = []panel{pa}

	if err = fieldTemplate.ExecuteTemplate(b, "border", p); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #8
0
//search tags and place names from devices
func tagsProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	if rows, err = dbR.Query(`SELECT DISTINCT tag from ((SELECT tag FROM mtr.tag )
	                          union (SELECT CASE  WHEN strpos(deviceid, '-') = 0 THEN deviceid ELSE split_part(deviceid, '-', 2) END AS tag FROM field.device)
	                          union (SELECT siteid from data.site as tag)) ts ORDER BY tag ASC`); err != nil {
		return weft.InternalServerError(err)
	}
	defer rows.Close()

	var ts mtrpb.TagResult

	for rows.Next() {
		var t mtrpb.Tag

		if err = rows.Scan(&t.Tag); 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
}
Пример #9
0
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
}
Пример #10
0
func dataPageHandler(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
	}

	// We create a page struct with variables to substitute into the loaded template
	p := mtrUiPage{}
	p.Path = r.URL.Path
	p.Border.Title = "GeoNet MTR - Data"
	p.ActiveTab = "Data"

	if err = p.populateTags(); err != nil {
		return weft.InternalServerError(err)
	}

	var pa panel
	if pa, err = getDataSummary(); err != nil {
		return weft.InternalServerError(err)
	}

	p.Panels = []panel{pa}

	if err = dataTemplate.ExecuteTemplate(b, "border", p); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #11
0
Файл: app.go Проект: GeoNet/mtr
// write a protobuf to b of all applicationid's in app.application
func appIdProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	if rows, err = dbR.Query(`SELECT applicationid FROM app.application ORDER BY applicationid ASC`); err != nil {
		return weft.InternalServerError(err)
	}
	defer rows.Close()

	var ar mtrpb.AppIDSummaryResult

	for rows.Next() {
		var ai mtrpb.AppIDSummary

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

		ar.Result = append(ar.Result, &ai)
	}

	var by []byte

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

	b.Write(by)

	return &weft.StatusOK
}
Пример #12
0
func dataCompletenessTagProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	if rows, err = dbR.Query(`SELECT siteID, tag, typeID from data.completeness_tag
				JOIN mtr.tag USING (tagpk)
				JOIN data.site USING (sitepk)
				JOIN data.completeness_type USING (typepk)
				ORDER BY tag ASC`); err != nil {
		return weft.InternalServerError(err)
	}
	defer rows.Close()

	var ts mtrpb.DataCompletenessTagResult

	for rows.Next() {
		var t mtrpb.DataCompletenessTag

		if err = rows.Scan(&t.SiteID, &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
}
Пример #13
0
// Contruct a simple page that has several plots (and time intervals as param) for the specified applicationID param
func appPlotPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error

	if res := weft.CheckQuery(r, []string{"applicationID"}, []string{"resolution", "interactive"}); !res.Ok {
		return res
	}

	p := mtrUiPage{}
	p.Path = r.URL.Path
	p.MtrApiUrl = mtrApiUrl.String()
	p.Border.Title = "GeoNet MTR - application ID"
	p.ActiveTab = "Apps"

	// get the applicationID and resolution params from the URL
	p.pageParam(r.URL.Query())

	// Resolution not required if we're in "interactive" mode otherwise default is minute
	if p.Resolution == "" && !p.Interactive {
		p.Resolution = "minute"
	}

	if err = p.populateTags(); err != nil {
		return weft.InternalServerError(err)
	}

	if err = appPlotTemplate.ExecuteTemplate(b, "border", p); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #14
0
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
}
Пример #15
0
func dataSitesPageHandler(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {

	var err error

	if res := weft.CheckQuery(r, []string{}, []string{"status", "typeID"}); !res.Ok {
		return res
	}

	p := mtrUiPage{}
	p.Path = r.URL.Path
	p.Border.Title = "GeoNet MTR - Data Sites"
	p.ActiveTab = "Data"
	p.MtrApiUrl = mtrApiUrl.String()

	if err = p.populateTags(); err != nil {
		return weft.InternalServerError(err)
	}

	p.pageParam(r.URL.Query())

	if err = p.getSitesList(); err != nil {
		return weft.InternalServerError(err)
	}

	if err = dataTemplate.ExecuteTemplate(b, "border", p); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #16
0
func fieldDeviceProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	if rows, err = dbR.Query(`SELECT deviceid, modelid, latitude, longitude
		FROM
		field.device JOIN field.model USING(modelpk)`); err != nil {
		return weft.InternalServerError(err)
	}

	var fdr mtrpb.FieldDeviceResult

	for rows.Next() {
		var d mtrpb.FieldDevice

		if err = rows.Scan(&d.DeviceID, &d.ModelID, &d.Latitude, &d.Longitude); err != nil {
			return weft.InternalServerError(err)
		}

		fdr.Result = append(fdr.Result, &d)
	}

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

	b.Write(by)

	return &weft.StatusOK
}
Пример #17
0
// Proxies sensor *.geojson from S3
func sensorV2(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	if res := weft.CheckQuery(r, []string{"type"}, []string{}); !res.Ok {
		return res
	}

	t := r.URL.Query().Get("type")
	if !sensorGeoJSON[t] {
		return &weft.NotFound
	}

	params := &s3.GetObjectInput{
		Key:    aws.String("delta/" + t + ".geojson"),
		Bucket: aws.String("api.geonet.org.nz"),
	}

	res, err := s3Client.GetObject(params)
	if err != nil {
		return weft.InternalServerError(err)
	}
	defer res.Body.Close()

	_, err = b.ReadFrom(res.Body)
	if err != nil {
		return weft.InternalServerError(err)
	}

	h.Set("Content-Type", V2GeoJSON)
	h.Set("Surrogate-Control", maxAge3600)
	return &weft.StatusOK
}
Пример #18
0
func dataSiteProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	var err error
	var rows *sql.Rows

	if rows, err = dbR.Query(`SELECT siteID, latitude, longitude FROM data.site`); err != nil {
		return weft.InternalServerError(err)
	}

	var ts mtrpb.DataSiteResult

	for rows.Next() {
		var t mtrpb.DataSite

		if err = rows.Scan(&t.SiteID, &t.Latitude, &t.Longitude); 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
}
Пример #19
0
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)
}
Пример #20
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
}
Пример #21
0
func mapPageHandler(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 := mapPage{}
	p.MtrApiUrl = mtrApiUrl.String()
	p.Border.Title = "GeoNet MTR - Map"
	p.ActiveTab = "Map"

	if err = p.populateTags(); err != nil {
		return weft.InternalServerError(err)
	}

	if err = p.populateTypes(); err != nil {
		return weft.InternalServerError(err)
	}

	s := strings.TrimPrefix(r.URL.Path, "/map")

	typeExist := false
	if ArrayContains(s, []string{"", "/"}) {
		p.TypeID = ""
		typeExist = true
		for _, mapdef := range p.Border.MapList {
			if len(mapdef.TypeIDs) > 0 {
				p.TypeID = mapdef.TypeIDs[0]
				p.MapApiUrl = mapdef.ApiUrl
				break
			}
		}
	} else {
		s1 := strings.TrimPrefix(s, "/")
		for _, mapdef := range p.Border.MapList {
			if ArrayContains(s1, mapdef.TypeIDs) {
				p.TypeID = s1
				p.MapApiUrl = mapdef.ApiUrl
				typeExist = true
				break
			}
		}
	}

	if !typeExist {
		return weft.InternalServerError(fmt.Errorf("Unknown map type"))
	}

	if err = mapTemplate.ExecuteTemplate(b, "border", p); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #22
0
// TODO: returns weft.NotFound when query result is empty?
func fieldLatestProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	typeID := r.URL.Query().Get("typeID")

	var err error
	var rows *sql.Rows

	switch typeID {
	case "":
		rows, err = dbR.Query(`select deviceID, modelID, typeid, time, value, lower, upper, scale
		FROM field.metric_summary
		JOIN field.device using (devicePK)
		JOIN field.model using (modelPK)
		JOIN field.threshold using (devicePK, typePK)
		JOIN field.type using (typePK)`)
	default:
		rows, err = dbR.Query(`select deviceID, modelID, typeid, time, value, lower, upper, scale
		FROM field.metric_summary
		JOIN field.device using (devicePK)
		JOIN field.model using (modelPK)
		JOIN field.threshold using (devicePK, typePK)
		JOIN field.type using (typePK)
		WHERE typeID = $1;`, typeID)
	}
	if err != nil {
		return weft.InternalServerError(err)
	}

	defer rows.Close()

	var t time.Time
	var fmlr mtrpb.FieldMetricSummaryResult

	for rows.Next() {
		var fmr mtrpb.FieldMetricSummary

		if err = rows.Scan(&fmr.DeviceID, &fmr.ModelID, &fmr.TypeID, &t, &fmr.Value,
			&fmr.Lower, &fmr.Upper, &fmr.Scale); err != nil {
			return weft.InternalServerError(err)
		}

		fmr.Seconds = t.Unix()

		fmlr.Result = append(fmlr.Result, &fmr)
	}
	rows.Close()

	var by []byte

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

	b.Write(by)

	return &weft.StatusOK
}
Пример #23
0
/*
spark draws an svg spark line to b.  Assumes f.loadPK has been called first.
*/
func dataCompletenessSpark(siteID, typeID string, b *bytes.Buffer) *weft.Result {
	var p ts.Plot

	p.SetXAxis(time.Now().UTC().Add(time.Hour*-12), time.Now().UTC())

	var err error
	var rows *sql.Rows
	var expected int
	var typePK int

	if err = dbR.QueryRow(`SELECT typePK, expected FROM data.completeness_type WHERE typeID = $1`,
		typeID).Scan(&typePK, &expected); err != nil {
		if err == sql.ErrNoRows {
			return &weft.NotFound
		}
		return weft.InternalServerError(err)
	}

	expectedf := float64(expected)

	if rows, err = dbR.Query(`SELECT date_trunc('hour',time) as t, sum(count) FROM data.completeness
		WHERE sitePK = (SELECT sitePK FROM data.site WHERE siteID = $1)
		AND typePK = $2
		AND time > now() - interval '28 days'
		GROUP BY date_trunc('hour',time)
		ORDER BY t ASC`,
		siteID, typePK); err != nil {
		return weft.InternalServerError(err)
	}

	defer rows.Close()

	var pts []ts.Point

	for rows.Next() {
		var pt ts.Point
		var v int
		if err = rows.Scan(&pt.DateTime, &v); err != nil {
			return weft.InternalServerError(err)
		}
		// No need to scale spark data for display.
		pt.Value = float64(v) / expectedf
		pts = append(pts, pt)
	}

	if len(pts) > 0 {
		p.AddSeries(ts.Series{Colour: "deepskyblue", Points: pts})
	}

	if err = ts.SparkLine.Draw(p, b); err != nil {
		return weft.InternalServerError(err)
	}

	return &weft.StatusOK
}
Пример #24
0
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)
}
Пример #25
0
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
}
Пример #26
0
// TODO: returns weft.NotFound when query result is empty?
func dataLatencySummaryProto(r *http.Request, h http.Header, b *bytes.Buffer) *weft.Result {
	typeID := r.URL.Query().Get("typeID")

	var err error
	var rows *sql.Rows

	switch typeID {
	case "":
		rows, err = dbR.Query(`SELECT siteID, typeID, time, mean, fifty, ninety, lower, upper, scale
		FROM data.latency_summary
		JOIN data.site USING (sitePK)
		JOIN data.latency_threshold USING (sitePK, typePK)
		JOIN data.type USING (typePK)`)
	default:
		rows, err = dbR.Query(`SELECT siteID, typeID, time, mean, fifty, ninety, lower, upper, scale
		FROM data.latency_summary
		JOIN data.site USING (sitePK)
		JOIN data.latency_threshold USING (sitePK, typePK)
		JOIN data.type USING (typePK)
		WHERE typeID = $1;`, typeID)
	}
	if err != nil {
		return weft.InternalServerError(err)
	}

	defer rows.Close()

	var t time.Time
	var dlsr mtrpb.DataLatencySummaryResult

	for rows.Next() {

		var dls mtrpb.DataLatencySummary

		if err = rows.Scan(&dls.SiteID, &dls.TypeID, &t, &dls.Mean, &dls.Fifty, &dls.Ninety,
			&dls.Lower, &dls.Upper, &dls.Scale); err != nil {
			return weft.InternalServerError(err)
		}

		dls.Seconds = t.Unix()

		dlsr.Result = append(dlsr.Result, &dls)
	}
	rows.Close()

	var by []byte

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

	b.Write(by)

	return &weft.StatusOK
}
Пример #27
0
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
}
Пример #28
0
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
}
Пример #29
0
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)
}
Пример #30
0
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)
}