Rip apart several new packages for inter-dependence
This will help make it clear what depends on what for rendering html pages
This commit is contained in:
parent
4c23eba5d7
commit
572b8a9de9
11 changed files with 277 additions and 263 deletions
103
htmlpage/h3.go
103
htmlpage/h3.go
|
|
@ -1,103 +0,0 @@
|
|||
package htmlpage
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Gleipnir-Technology/go-geojson2h3/v2"
|
||||
"github.com/tidwall/geojson"
|
||||
"github.com/uber/h3-go/v4"
|
||||
)
|
||||
|
||||
/*
|
||||
func h3ToBoundsGeoJSON(c h3.Cell) (string, error) {
|
||||
b, err := h3.CellToBoundary(c)
|
||||
if err != nil {
|
||||
respondError(w, "Failed to get cell boundary", err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
features, err := geojson2h3.ToFeatureCollection(b)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to convert boundary to
|
||||
}
|
||||
*/
|
||||
|
||||
func toH3Cell(s string) (h3.Cell, error) {
|
||||
c := h3.CellFromString(s)
|
||||
if !c.IsValid() {
|
||||
return c, fmt.Errorf("Invalid cell definition '%s'", s)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
func h3ToGeoJSON(indexes []h3.Cell) (interface{}, error) {
|
||||
featureCollection, err := geojson2h3.ToFeatureCollection(indexes)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to get feature collection: %w", err)
|
||||
}
|
||||
return featureCollection.JSON(), nil
|
||||
}
|
||||
|
||||
func main2() {
|
||||
resolution := 9
|
||||
object, err := geojson.Parse(`{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"shape":"Polygon","name":"Unnamed Layer","category":"default"},"geometry":{"type":"Polygon","coordinates":[[[-73.901303,40.756892],[-73.893924,40.743755],[-73.871476,40.756278],[-73.863378,40.764175],[-73.871444,40.768467],[-73.879852,40.760014],[-73.885515,40.764045],[-73.891522,40.761054],[-73.901303,40.756892]]]},"id":"a6ca1b7e-9ddf-4425-ad07-8a895f7d6ccf"}]}`, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
indexes, err := geojson2h3.ToH3(resolution, object)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, index := range indexes {
|
||||
fmt.Printf("h3index: %s\n", index.String())
|
||||
}
|
||||
|
||||
featureCollection, err := geojson2h3.ToFeatureCollection(indexes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Polyfill:")
|
||||
fmt.Println(featureCollection.JSON())
|
||||
}
|
||||
|
||||
// Given a cell at a smaller resolution remap it to the larger resolution
|
||||
func scaleCell(cell h3.Cell, resolution int) (h3.Cell, error) {
|
||||
r := cell.Resolution()
|
||||
if r == resolution {
|
||||
return cell, nil
|
||||
}
|
||||
latLong, err := cell.LatLng()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("Failed to get latlng: %w", err)
|
||||
}
|
||||
scaled, err := h3.LatLngToCell(latLong, resolution)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("Failed to create latlng: %w", err)
|
||||
}
|
||||
return scaled, nil
|
||||
}
|
||||
|
||||
func getCell(x, y float64, resolution int) (h3.Cell, error) {
|
||||
latLng := h3.NewLatLng(y, x)
|
||||
return h3.LatLngToCell(latLng, resolution)
|
||||
}
|
||||
|
||||
func cellToPostgisGeometry(c h3.Cell) (string, error) {
|
||||
boundary, err := h3.CellToBoundary(c)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to get cell boundary: %w", err)
|
||||
}
|
||||
var sb strings.Builder
|
||||
|
||||
for i, p := range boundary {
|
||||
if i > 0 {
|
||||
sb.WriteString(",")
|
||||
}
|
||||
fmt.Fprintf(&sb, "%g %g", p.Lng, p.Lat)
|
||||
}
|
||||
// add the first point on to the end to close the polygon
|
||||
sb.WriteString(",")
|
||||
fmt.Fprintf(&sb, "%g %g", boundary[0].Lng, boundary[0].Lat)
|
||||
|
||||
return fmt.Sprintf("POLYGON((%s))", sb.String()), nil
|
||||
}
|
||||
|
|
@ -15,9 +15,13 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/background"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/sql"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/h3utils"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/notification"
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
|
@ -30,8 +34,6 @@ import (
|
|||
//go:embed templates/*
|
||||
var embeddedFiles embed.FS
|
||||
|
||||
var MapboxToken string
|
||||
|
||||
// Authenticated pages
|
||||
var (
|
||||
cell = newBuiltTemplate("cell", "authenticated")
|
||||
|
|
@ -190,7 +192,7 @@ type ServiceRequestSummary struct {
|
|||
type User struct {
|
||||
DisplayName string
|
||||
Initials string
|
||||
Notifications []Notification
|
||||
Notifications []notification.Notification
|
||||
Username string
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +230,7 @@ func bigNumber(n int) string {
|
|||
}
|
||||
|
||||
func contentForUser(ctx context.Context, user *models.User) (User, error) {
|
||||
notifications, err := notificationsForUser(ctx, user)
|
||||
notifications, err := notification.ForUser(ctx, user)
|
||||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
|
|
@ -279,7 +281,7 @@ func Cell(ctx context.Context, w http.ResponseWriter, user *models.User, c int64
|
|||
respondError(w, "Failed to get inspections by cell", err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
geojson, err := h3ToGeoJSON([]h3.Cell{h3.Cell(c)})
|
||||
geojson, err := h3utils.H3ToGeoJSON([]h3.Cell{h3.Cell(c)})
|
||||
if err != nil {
|
||||
respondError(w, "Failed to get boundaries", err, http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -305,7 +307,7 @@ func Cell(ctx context.Context, w http.ResponseWriter, user *models.User, c int64
|
|||
Lng: center.Lng,
|
||||
},
|
||||
GeoJSON: geojson,
|
||||
MapboxToken: MapboxToken,
|
||||
MapboxToken: config.MapboxToken,
|
||||
Zoom: resolution + 5,
|
||||
},
|
||||
Treatments: treatments,
|
||||
|
|
@ -330,7 +332,7 @@ func Dashboard(ctx context.Context, w http.ResponseWriter, user *models.User) {
|
|||
} else {
|
||||
lastSync = &sync.Created
|
||||
}
|
||||
is_syncing := isSyncOngoing(org.ID)
|
||||
is_syncing := background.IsSyncOngoing(org.ID)
|
||||
inspectionCount, err := org.Mosquitoinspections().Count(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
respondError(w, "Failed to get inspection count", err, http.StatusInternalServerError)
|
||||
|
|
@ -372,7 +374,7 @@ func Dashboard(ctx context.Context, w http.ResponseWriter, user *models.User) {
|
|||
IsSyncOngoing: is_syncing,
|
||||
LastSync: lastSync,
|
||||
MapData: ComponentMap{
|
||||
MapboxToken: MapboxToken,
|
||||
MapboxToken: config.MapboxToken,
|
||||
},
|
||||
Org: org.Name.MustGet(),
|
||||
RecentRequests: requests,
|
||||
|
|
@ -490,7 +492,7 @@ func Source(w http.ResponseWriter, r *http.Request, user *models.User, id uuid.U
|
|||
MapData: ComponentMap{
|
||||
Center: latlng,
|
||||
//GeoJSON:
|
||||
MapboxToken: MapboxToken,
|
||||
MapboxToken: config.MapboxToken,
|
||||
Markers: []MapMarker{
|
||||
MapMarker{
|
||||
LatLng: latlng,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/sql"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/h3utils"
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
|
@ -210,7 +211,7 @@ func toTemplateTrapData(trap_data models.FieldseekerTrapdatumSlice) ([]TrapData,
|
|||
if r.H3cell.IsNull() {
|
||||
continue
|
||||
}
|
||||
cell, err := toH3Cell(r.H3cell.MustGet())
|
||||
cell, err := h3utils.ToCell(r.H3cell.MustGet())
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get location for trap data")
|
||||
continue
|
||||
|
|
@ -333,7 +334,7 @@ func toTemplateBreedingSource(source *models.FieldseekerPointlocation) *Breeding
|
|||
log.Error().Msg("h3 cell is null")
|
||||
return nil
|
||||
}
|
||||
cell, err := toH3Cell(source.H3cell.MustGet())
|
||||
cell, err := h3utils.ToCell(source.H3cell.MustGet())
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get h3 cell from point location")
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -1,92 +0,0 @@
|
|||
package htmlpage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
enums "github.com/Gleipnir-Technology/nidus-sync/db/enums"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/debug"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/aarondl/opt/omitnull"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var (
|
||||
NotificationPathOauthReset string = "/oauth/refresh"
|
||||
)
|
||||
|
||||
type Notification struct {
|
||||
Link string
|
||||
Message string
|
||||
Time time.Time
|
||||
Type string
|
||||
}
|
||||
|
||||
// Clear all notifications for a given user with the given path
|
||||
func clearNotificationsOauth(ctx context.Context, user *models.User) {
|
||||
setter := models.NotificationSetter{
|
||||
ResolvedAt: omitnull.From(time.Now()),
|
||||
}
|
||||
updater := models.Notifications.Update(
|
||||
//models.SelectWhere.Notifications.Link.EQ(NotificationPathOauthReset),
|
||||
models.UpdateWhere.Notifications.Link.EQ(NotificationPathOauthReset),
|
||||
models.UpdateWhere.Notifications.UserID.EQ(user.ID),
|
||||
setter.UpdateMod(),
|
||||
)
|
||||
updater.Exec(ctx, db.PGInstance.BobDB)
|
||||
//user.UserNotifications(
|
||||
//models.SelectWhere.Notifications.Link.EQ(NotificationPathOauthReset),
|
||||
//).UpdateAll()
|
||||
}
|
||||
|
||||
func notifyOauthInvalid(ctx context.Context, user *models.User) {
|
||||
msg := "Oauth token invalidated"
|
||||
notificationSetter := models.NotificationSetter{
|
||||
Created: omit.From(time.Now()),
|
||||
Message: omit.From(msg),
|
||||
Link: omit.From(NotificationPathOauthReset),
|
||||
Type: omit.From(enums.NotificationtypeOauthTokenInvalidated),
|
||||
}
|
||||
err := user.InsertUserNotifications(ctx, db.PGInstance.BobDB, ¬ificationSetter)
|
||||
if err != nil {
|
||||
if strings.HasPrefix(err.Error(), "ERROR: duplicate key value violates unique constraint") {
|
||||
log.Info().Str("msg", msg).Int("user_id", int(user.ID)).Msg("Refusing to add another notification with the same type")
|
||||
return
|
||||
}
|
||||
debug.LogErrorTypeInfo(err)
|
||||
log.Error().Err(err).Msg("Failed to insert new notification. This is a programmer bug.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func notificationsForUser(ctx context.Context, u *models.User) ([]Notification, error) {
|
||||
results := make([]Notification, 0)
|
||||
notifications, err := u.UserNotifications(
|
||||
models.SelectWhere.Notifications.ResolvedAt.IsNull(),
|
||||
).All(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
return results, fmt.Errorf("Failed to get notifications: %w", err)
|
||||
}
|
||||
for _, n := range notifications {
|
||||
results = append(results, Notification{
|
||||
Link: n.Link,
|
||||
Message: n.Message,
|
||||
Time: n.Created,
|
||||
Type: notificationTypeName(n.Type),
|
||||
})
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func notificationTypeName(t enums.Notificationtype) string {
|
||||
switch t {
|
||||
case enums.NotificationtypeOauthTokenInvalidated:
|
||||
return "alert"
|
||||
default:
|
||||
return "unknown-type"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue