lint: remove unused code across api, comms, h3utils, html, middleware, minio, platform, rmo

Deleted files: api/compliance.go, api/debug.go, rmo/compliance.go, rmo/email.go,
rmo/mock.go, platform/publicreport/address.go

Removed unused functions/types from: api/api.go, api/configuration.go, api/district.go,
api/publicreport.go, api/sudo.go, api/types.go, comms/text/twilio.go,
comms/text/voipms.go, h3utils/h3.go, html/embed.go, html/form.go,
middleware/terminal.go, minio/client.go, platform/csv/csv.go,
platform/csv/flyover.go, platform/file/base.go, platform/file/upload.go,
platform/geocode/address.go, platform/types/service_request.go
This commit is contained in:
Eli Ribble 2026-05-09 14:47:56 +00:00
parent d74c24339e
commit 53a3f9816a
25 changed files with 6 additions and 975 deletions

View file

@ -14,7 +14,6 @@ import (
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
"github.com/Gleipnir-Technology/nidus-sync/lint"
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/Gleipnir-Technology/nidus-sync/platform/types"
"github.com/Gleipnir-Technology/nidus-sync/resource"
"github.com/Gleipnir-Technology/nidus-sync/version"
//"github.com/gorilla/mux"
@ -188,39 +187,6 @@ func apiTrapData(w http.ResponseWriter, r *http.Request, u platform.User) {
}
}
func apiServiceRequest(w http.ResponseWriter, r *http.Request, u platform.User) {
bounds, err := parseBounds(r)
if err != nil {
err = renderShim(w, r, errRender(err))
if err != nil {
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
}
return
}
query := db.NewGeoQuery()
query.Bounds = *bounds
query.Limit = 100
requests, err := platform.ServiceRequestQuery()
if err != nil {
err = renderShim(w, r, errRender(err))
if err != nil {
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
}
return
}
data := []Renderable{}
for _, sr := range requests {
data = append(data, types.ServiceRequestFromModel(sr))
}
if err := renderList(w, r, data); err != nil {
err = renderShim(w, r, errRender(err))
if err != nil {
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
}
}
}
func parseBounds(r *http.Request) (*db.GeoBounds, error) {
err := r.ParseForm()
if err != nil {

View file

@ -1,109 +0,0 @@
package api
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/sm"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/gorilla/mux"
"github.com/paulmach/orb/geojson"
"github.com/rs/zerolog/log"
"github.com/stephenafamo/scan"
)
func getComplianceRequestImagePool(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
code := vars["public_id"]
if code == "" {
http.Error(w, "empty public_id", http.StatusBadRequest)
return
}
ctx := r.Context()
/*
comp, err := models.ComplianceReportRequests.Query(
models.Preload.ComplianceReportRequest.Lead(),
models.SelectWhere.ComplianceReportRequests.PublicID.EQ(code),
).One(ctx, db.PGInstance.BobDB)
if err != nil {
http.Error(w, "no comp", http.StatusInternalServerError)
return
}
lead := comp.R.Lead
site := lead.R.Site
*/
type _Row struct {
Envelope string `db:"parcel_envelope"`
OrganizationID int32 `db:"organization_id"`
}
row, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
"ST_AsGeoJSON(ST_Envelope(parcel.geometry)) AS parcel_envelope",
"organization.id AS organization_id",
),
sm.From("compliance_report_request"),
sm.InnerJoin("lead").OnEQ(
psql.Quote("compliance_report_request.lead_id"),
psql.Quote("organization.id"),
),
sm.InnerJoin("organization").OnEQ(
psql.Quote("lead.organization_id"),
psql.Quote("organization.id"),
),
sm.InnerJoin("site").On(
psql.Quote("lead.site_id").EQ(psql.Quote("site.id")),
),
sm.InnerJoin("parcel").OnEQ(
psql.Quote("site.parcel_id"),
psql.Quote("parcel.id"),
),
sm.Where(psql.Quote("compliance_report_request").EQ(psql.Arg(code))),
), scan.StructMapper[_Row]())
org, err := platform.OrganizationByID(ctx, int(row.OrganizationID))
if err != nil {
http.Error(w, "org err", http.StatusInternalServerError)
return
}
if org == nil {
http.Error(w, "no org", http.StatusBadRequest)
return
}
var polygon geojson.Polygon
err = json.Unmarshal([]byte(row.Envelope), &polygon)
if err != nil {
log.Error().Err(err).Msg("unmarshal json")
http.Error(w, "unmarshal envelope json", http.StatusInternalServerError)
return
}
ring := polygon[0]
p := ring[0]
err = writeImage(ctx, w, *org, 19, p[1], p[0])
if err != nil {
log.Error().Err(err).Msg("write image")
http.Error(w, "failed to write image", http.StatusInternalServerError)
return
}
}
func writeImage(ctx context.Context, w http.ResponseWriter, org platform.Organization, level uint, lat, lng float64) error {
img, err := platform.ImageAtPoint(ctx, org, level, lat, lng)
if err != nil {
return fmt.Errorf("image at point: %w", err)
}
log.Info().Int("size", len(img.Content)).Msg("image")
w.Header().Set("Content-Type", "image/png")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(img.Content)))
_, err = io.Copy(w, bytes.NewBuffer(img.Content))
if err != nil {
return fmt.Errorf("copy bytes: %w", err)
}
return nil
}

View file

@ -7,122 +7,11 @@ import (
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/um"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/arcgis/model"
queryarcgis "github.com/Gleipnir-Technology/nidus-sync/db/query/arcgis"
"github.com/Gleipnir-Technology/nidus-sync/html"
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/rs/zerolog/log"
)
type contentConfigurationRoot struct{}
func getConfigurationRoot(ctx context.Context, r *http.Request, user platform.User) (*html.Response[contentConfigurationRoot], *nhttp.ErrorWithStatus) {
return html.NewResponse("sync/configuration/root.html", contentConfigurationRoot{}), nil
}
type contentSettingOrganization struct {
Organization platform.Organization
}
type contentSettingIntegration struct {
ArcGISAccount *model.Account
ArcGISOAuth *model.OAuthToken
ServiceMaps []model.ServiceMap
}
func getConfigurationOrganization(ctx context.Context, r *http.Request, u platform.User) (*html.Response[contentSettingOrganization], *nhttp.ErrorWithStatus) {
/*
var district contentDistrict
district, err = bob.One[contentDistrict](ctx, db.PGInstance.BobDB, psql.Select(
sm.From("import.district"),
sm.Columns(
"address",
"agency",
"area_4326_sqm",
"city1",
"city2",
"contact",
"fax1",
"general_mg",
"gid",
"phone1",
"phone2",
"postal_c_1",
"website",
psql.F("ST_AsGeoJSON", "centroid_4326"),
psql.F("ST_XMin", "extent_4326"),
psql.F("ST_YMin", "extent_4326"),
psql.F("ST_XMax", "extent_4326"),
psql.F("ST_YMax", "extent_4326"),
),
sm.Where(psql.Quote("gid").EQ(psql.Arg(gid))),
), scan.StructMapper[contentDistrict]())
if err != nil {
respondError(w, "Failed to get extents", err, http.StatusInternalServerError)
return
}
*/
data := contentSettingOrganization{
Organization: u.Organization,
}
return html.NewResponse("sync/configuration/organization.html", data), nil
}
func getConfigurationIntegration(ctx context.Context, r *http.Request, u platform.User) (*html.Response[contentSettingIntegration], *nhttp.ErrorWithStatus) {
oauth, err := platform.GetOAuthForUser(ctx, u)
if err != nil {
return nil, nhttp.NewError("Failed to get oauth: %w", err)
}
data := contentSettingIntegration{
ArcGISOAuth: oauth,
}
return html.NewResponse("sync/configuration/integration.html", data), nil
}
func getConfigurationIntegrationArcgis(ctx context.Context, r *http.Request, u platform.User) (*html.Response[contentSettingIntegration], *nhttp.ErrorWithStatus) {
oauth, err := platform.GetOAuthForUser(ctx, u)
if err != nil {
return nil, nhttp.NewError("Failed to get oauth: %w", err)
}
var account model.Account
var service_maps []model.ServiceMap
account_id := u.Organization.ArcgisAccountID()
if account_id != "" {
account, err = queryarcgis.AccountFromID(ctx, account_id)
if err != nil {
return nil, nhttp.NewError("Failed to get arcgis: %w", err)
}
service_maps, err = queryarcgis.ServiceMapsFromAccountID(ctx, account.ID)
if err != nil {
return nil, nhttp.NewError("Failed to get map services: %w", err)
}
}
data := contentSettingIntegration{
ArcGISAccount: &account,
ArcGISOAuth: oauth,
ServiceMaps: service_maps,
}
return html.NewResponse("sync/configuration/integration-arcgis.html", data), nil
}
type contentSettingPlaceholder struct{}
func getConfigurationPesticide(ctx context.Context, r *http.Request, user platform.User) (*html.Response[contentSettingPlaceholder], *nhttp.ErrorWithStatus) {
content := contentSettingPlaceholder{}
return html.NewResponse("sync/configuration/pesticide.html", content), nil
}
func getConfigurationPesticideAdd(ctx context.Context, r *http.Request, user platform.User) (*html.Response[contentSettingPlaceholder], *nhttp.ErrorWithStatus) {
content := contentSettingPlaceholder{}
return html.NewResponse("sync/configuration/pesticide-add.html", content), nil
}
func getConfigurationUserAdd(ctx context.Context, r *http.Request, user platform.User) (*html.Response[contentSettingPlaceholder], *nhttp.ErrorWithStatus) {
content := contentSettingPlaceholder{}
return html.NewResponse("sync/configuration/user-add.html", content), nil
}
func getConfigurationUserList(ctx context.Context, r *http.Request, user platform.User) (*html.Response[contentSettingPlaceholder], *nhttp.ErrorWithStatus) {
content := contentSettingPlaceholder{}
return html.NewResponse("sync/configuration/user-list.html", content), nil
}
type formArcgisConfiguration struct {
MapService *string `schema:"map-service"`
}

View file

@ -1,26 +0,0 @@
package api
import (
"io"
"net/http"
"os"
"github.com/Gleipnir-Technology/nidus-sync/lint"
"github.com/rs/zerolog/log"
)
func debugSaveRequest(r *http.Request) {
tmpFile, err := os.CreateTemp("/tmp", "request-*.data")
if err != nil {
log.Error().Err(err).Msg("failed to create temp file for debugSaveRequest")
return
}
defer lint.LogOnErr(tmpFile.Close, "close temp file")
_, err = io.Copy(tmpFile, r.Body)
if err != nil {
log.Error().Err(err).Msg("failed to copy request body in debugSaveRequest")
return
}
log.Info().Str("filename", tmpFile.Name()).Msg("Saved request body")
}

View file

@ -1,67 +1,14 @@
package api
import (
"fmt"
"net/http"
"strconv"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/Gleipnir-Technology/nidus-sync/platform/file"
"github.com/gorilla/mux"
)
func apiGetDistrict(w http.ResponseWriter, r *http.Request) {
var latStr, lngStr string
err := r.ParseForm()
if err != nil {
if err := renderShim(w, r, errRender(fmt.Errorf("Failed to parse GET form: %w", err))); err != nil {
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
}
return
} else {
latStr = r.FormValue("lat")
lngStr = r.FormValue("lng")
}
lat, err := strconv.ParseFloat(latStr, 64)
if err != nil {
if err := renderShim(w, r, errRender(fmt.Errorf("Failed to parse lat as float: %w", err))); err != nil {
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
}
return
}
lng, err := strconv.ParseFloat(lngStr, 64)
if err != nil {
if err := renderShim(w, r, errRender(fmt.Errorf("Failed to parse lng as float: %w", err))); err != nil {
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
}
return
}
org, err := platform.DistrictForLocation(r.Context(), lng, lat)
if err != nil {
if err := renderShim(w, r, errRender(fmt.Errorf("Failed to get district: %w", err))); err != nil {
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
}
return
}
if org == nil {
http.NotFound(w, r)
return
}
d := ResponseDistrict{
Agency: org.Name,
Manager: org.GeneralManagerName.GetOr(""),
Phone: org.OfficePhone.GetOr(""),
Website: org.Website.GetOr(""),
}
if err := renderShim(w, r, d); err != nil {
if err := renderShim(w, r, errRender(err)); err != nil {
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
}
}
}
func apiGetDistrictLogo(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
slug := vars["slug"]

View file

@ -21,10 +21,6 @@ func postPublicreportSignal(ctx context.Context, r *http.Request, user platform.
return fmt.Sprintf("/signal/%d", *signal_id), nil
}
type formPublicreportInvalid struct {
ReportID string `json:"reportID"`
}
func postPublicreportInvalid(ctx context.Context, r *http.Request, user platform.User, req formPublicreportSignal) (string, *nhttp.ErrorWithStatus) {
err := platform.PublicReportInvalid(ctx, user, req.ReportID)
if err != nil {

View file

@ -8,31 +8,11 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/comms/email"
"github.com/Gleipnir-Technology/nidus-sync/comms/text"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/html"
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/rs/zerolog/log"
)
type contentSudo struct {
ForwardEmailRMOAddress string
ForwardEmailNidusAddress string
}
func getSudo(ctx context.Context, r *http.Request, user platform.User) (*html.Response[contentSudo], *nhttp.ErrorWithStatus) {
if !user.HasRoot() {
return nil, &nhttp.ErrorWithStatus{
Message: "You have to be a root user to access this",
Status: http.StatusForbidden,
}
}
content := contentSudo{
ForwardEmailRMOAddress: config.ForwardEmailRMOAddress,
ForwardEmailNidusAddress: config.ForwardEmailNidusAddress,
}
return html.NewResponse("sync/sudo.html", content), nil
}
type FormEmail struct {
Body string `schema:"emailBody"`
From string `schema:"emailFrom"`

View file

@ -15,10 +15,6 @@ import (
type H3Cell uint64
type hasCreated interface {
getCreated() string
}
type Bounds struct {
East float64
North float64
@ -300,16 +296,4 @@ func toBool16(t null.Val[int16]) *bool {
}
return &b
}
func toBool(t null.Val[int32]) *bool {
if t.IsNull() {
return nil
}
val := t.MustGet()
var b bool
if val == 0 {
b = false
} else {
b = true
}
return &b
}

View file

@ -2,7 +2,6 @@ package text
import (
"context"
"encoding/json"
"fmt"
"github.com/Gleipnir-Technology/nidus-sync/config"
@ -32,21 +31,3 @@ func sendTextTwilio(ctx context.Context, source string, destination string, mess
return *resp.Sid, nil
}
func sendSMSTwilio(destination, source, message string) error {
client := twilio.NewRestClientWithParams(twilio.ClientParams{
Username: config.TwilioAccountSID,
Password: config.TwilioAuthToken,
})
params := &twilioApi.CreateMessageParams{}
params.SetTo("+15558675309")
params.SetFrom("+15017250604")
params.SetBody("Hello from Go!")
resp, err := client.Api.CreateMessage(params)
if err != nil {
return fmt.Errorf("Error sending SMS message: %w", err)
}
response, _ := json.Marshal(*resp)
log.Debug().Str("response", string(response)).Msg("Send SMS")
return nil
}

View file

@ -56,26 +56,6 @@ func sendTextVoipms(ctx context.Context, to string, content string, media ...str
return strconv.Itoa(response.MMS), nil
}
func sendSMSVoipms(to string, content string) (string, error) {
if len(content) > 160 {
return "", errors.New("Message content is more than 160 characters")
}
params := url.Values{}
params.Add("api_password", config.VoipMSPassword)
params.Add("api_username", config.VoipMSUsername)
params.Add("method", "sendSMS")
params.Add("did", config.VoipMSNumber)
params.Add("dst", to)
params.Add("message", content)
response, err := makeVoipMSRequest(params)
if err != nil {
return "", fmt.Errorf("Failed to send SMS: %w", err)
}
log.Info().Str("status", response.Status).Int("sms", response.SMS).Msg("Sent MMS message")
return strconv.Itoa(response.SMS), nil
}
func makeVoipMSRequest(params url.Values) (VoipMSResponse, error) {
result := VoipMSResponse{}
// Construct the URL with query parameters

View file

@ -37,23 +37,6 @@ func H3ToGeoJSON(indexes []h3.Cell) (interface{}, error) {
return featureCollection.JSON(), nil
}
// 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)

View file

@ -10,9 +10,6 @@ import (
"io/fs"
//"math"
"net/http"
//"path"
//"strconv"
"strings"
//"time"
//"github.com/Gleipnir-Technology/nidus-sync/config"
@ -75,34 +72,6 @@ func (ts templateSystemEmbed) loadTemplateSubdir(subdir string) error {
return err
}
func (ts templateSystemEmbed) addSubdirTemplates(t *template.Template, subdir string) error {
var err = fs.WalkDir(ts.sourceFS, subdir, func(path string, d fs.DirEntry, err error) error {
if err != nil || d.IsDir() {
return err
}
content, err := fs.ReadFile(ts.sourceFS, path)
if err != nil {
return fmt.Errorf("error reading template %s: %w", path, err)
}
new_t := template.New(path)
addFuncMap(new_t)
_, err = new_t.Parse(string(content))
if err != nil {
return fmt.Errorf("error parsing '%s': %w", path, err)
}
short_path := removeLeadingDir(path)
_, err = t.AddParseTree(short_path, new_t.Tree)
if err != nil {
return fmt.Errorf("error adding parse tree '%s': %w", path, err)
}
log.Debug().Str("path", short_path).Msg("Loaded shared component template")
return nil
})
return err
}
func (ts templateSystemEmbed) renderOrError(w http.ResponseWriter, template_name string, context interface{}) {
buf := &bytes.Buffer{}
@ -125,24 +94,4 @@ func (ts templateSystemEmbed) renderOrError(w http.ResponseWriter, template_name
log.Error().Err(err).Msg("failed to write buffer on render")
}
}
func loadTemplateEmbedded(sourceFS fs.FS, path string) (*template.Template, error) {
content, err := fs.ReadFile(sourceFS, "template/"+path)
if err != nil {
return nil, fmt.Errorf("error reading template template/%s: %w", path, err)
}
new_t := template.New(path)
addFuncMap(new_t)
_, err = new_t.Parse(string(content))
if err != nil {
return nil, fmt.Errorf("error parsing '%s': %w", path, err)
}
return new_t, nil
}
func removeLeadingDir(path string) string {
parts := strings.SplitN(path, "/", 2)
if len(parts) == 2 {
return parts[1]
}
return path
}

View file

@ -11,18 +11,6 @@ func BoolFromForm(r *http.Request, k string) bool {
}
return false
}
func postFormBool(r *http.Request, k string) *bool {
v := r.PostFormValue(k)
if v == "" {
return nil
}
result := false
if v == "on" {
result = true
return &result
}
return &result
}
func PostFormValueOrNone(r *http.Request, k string) string {
v := r.PostFormValue(k)

View file

@ -11,17 +11,12 @@ import (
var (
// Normal colors
nBlack = []byte{'\033', '[', '3', '0', 'm'}
nRed = []byte{'\033', '[', '3', '1', 'm'}
nGreen = []byte{'\033', '[', '3', '2', 'm'}
nYellow = []byte{'\033', '[', '3', '3', 'm'}
nBlue = []byte{'\033', '[', '3', '4', 'm'}
nMagenta = []byte{'\033', '[', '3', '5', 'm'}
nCyan = []byte{'\033', '[', '3', '6', 'm'}
nWhite = []byte{'\033', '[', '3', '7', 'm'}
nRed = []byte{'\033', '[', '3', '1', 'm'}
nGreen = []byte{'\033', '[', '3', '2', 'm'}
nYellow = []byte{'\033', '[', '3', '3', 'm'}
nCyan = []byte{'\033', '[', '3', '6', 'm'}
// Bright colors
bBlack = []byte{'\033', '[', '3', '0', ';', '1', 'm'}
bRed = []byte{'\033', '[', '3', '1', ';', '1', 'm'}
bRed = []byte{'\033', '[', '3', '1', ';', '1', 'm'}
bGreen = []byte{'\033', '[', '3', '2', ';', '1', 'm'}
bYellow = []byte{'\033', '[', '3', '3', ';', '1', 'm'}
bBlue = []byte{'\033', '[', '3', '4', ';', '1', 'm'}

View file

@ -4,9 +4,7 @@ import (
"context"
"fmt"
"log"
"net/url"
"os"
"time"
"github.com/Gleipnir-Technology/nidus-sync/lint"
"github.com/minio/minio-go/v7"
@ -31,20 +29,6 @@ func NewClient(baseURL string, accessKeyID string, secretAccessKey string) (*Cli
}, nil
}
func signUrl(minioClient *minio.Client, bucketName string, filePath string) {
// Set request parameters for content-disposition.
reqParams := make(url.Values)
reqParams.Set("response-content-disposition", "attachment; filename=\""+filePath+"\"")
// Generates a presigned url which expires in a day.
presignedURL, err := minioClient.PresignedGetObject(context.Background(), bucketName, filePath, time.Second*24*60*60, reqParams)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Successfully generated presigned URL", presignedURL)
}
func (minioClient *Client) ObjectExists(bucket string, path string) bool {
ctx := context.Background()
opts := minio.ListObjectsOptions{

View file

@ -295,9 +295,6 @@ func addError(ctx context.Context, txn bob.Tx, c *models.FileuploadCSV, row_numb
log.Info().Int32("id", r.ID).Int32("file_id", c.FileID).Str("msg", msg).Int32("row", row_number).Int32("col", column_number).Msg("Created CSV file error")
return nil
}
func addImportError(file *models.FileuploadFile, err error) {
log.Debug().Err(err).Int32("file_id", file.ID).Msg("Fake add import error")
}
func parseBool(s string) (bool, error) {
sl := strings.ToLower(s)
boolValue, err := strconv.ParseBool(sl)

View file

@ -273,61 +273,6 @@ func hasExistingPool(ctx context.Context, txn bob.Executor, setter *models.Fileu
Bool("exists", exists).Msg("checking pool exists")
return exists, nil
}
func insertPoollistRow(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV, line_number int32, header_types []headerFlyoverEnum, header_names []string, row []string) (*models.FileuploadPool, error) {
tags := make(map[string]string, 0)
// Start with a setter with default values, comment out the required fields to ensure they're set
setter := models.FileuploadPoolSetter{
// AddressCity: omit.From(),
// AddressPostalCode: omit.From(),
// AddressStreet: omit.From(),
Committed: omit.From(false),
Condition: omit.From(enums.PoolconditiontypeUnknown),
Created: omit.From(time.Now()),
CreatorID: omit.From(file.CreatorID),
CSVFile: omit.From(file.ID),
Deleted: omitnull.FromPtr[time.Time](nil),
Geom: omitnull.FromPtr[string](nil),
H3cell: omitnull.FromPtr[string](nil),
// ID - generated
IsInDistrict: omit.From(false),
IsNew: omit.From(true),
LineNumber: omit.From(line_number),
Notes: omit.From(""),
PropertyOwnerName: omit.From(""),
PropertyOwnerPhoneE164: omitnull.FromPtr[string](nil),
ResidentOwned: omitnull.FromPtr[bool](nil),
ResidentPhoneE164: omitnull.FromPtr[string](nil),
// Can't set this via a Setter
// Tags: convertToPGData(tags),
}
for i, value := range row {
if value == "" {
continue
}
header_type := header_types[i]
switch header_type {
case headerFlyoverAddressLocality:
setter.AddressLocality = omit.From(value)
case headerFlyoverAddressPostalCode:
setter.AddressPostalCode = omit.From(value)
case headerFlyoverAddressStreet:
setter.AddressStreet = omit.From(value)
case headerFlyoverComment:
condition, err := parsePoolCondition(value)
if err == nil {
setter.Condition = omit.From(condition)
} else {
lint.LogOnErrCtx(func(ctx context.Context) error {
return addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not a pool condition that we recognize. It should be one of %s", value, poolConditionValidValues()))
}, ctx, "add pool condition error")
continue
}
}
}
setter.Tags = omit.From(db.ConvertToPGData(tags))
return models.FileuploadPools.Insert(&setter).One(ctx, txn)
}
type parseHeaderFunc[EnumType any] = func(row []string) ([]EnumType, []string)

View file

@ -12,10 +12,6 @@ import (
//"github.com/rs/zerolog/log"
)
func audioFileContentWrite(audioUUID uuid.UUID, body io.Reader) error {
return nil
}
var collectionToExtension map[Collection]string = map[Collection]string{
CollectionAudioNormalized: "ogg",
CollectionAudioRaw: "raw",

View file

@ -33,19 +33,6 @@ func SaveFileUploads(r *http.Request, collection Collection) ([]Upload, error) {
}
return results, nil
}
func saveFileUploads(r *http.Request, collection Collection) ([]Upload, error) {
results := make([]Upload, 0)
for name, fheaders := range r.MultipartForm.File {
for _, headers := range fheaders {
upload, err := saveFileUpload(headers, collection)
if err != nil {
return results, fmt.Errorf("Failed to save upload '%s': %w", name, err)
}
results = append(results, upload)
}
}
return results, nil
}
func saveFileUpload(headers *multipart.FileHeader, collection Collection) (upload Upload, err error) {
file, err := headers.Open()
if err != nil {

View file

@ -13,10 +13,6 @@ import (
//"github.com/rs/zerolog/log"
)
type _rowWithID struct {
ID int32 `db:"id"`
}
// Ensure the provided address exists. If it doesn't add it to the database.
func EnsureAddress(ctx context.Context, txn db.Ex, a types.Address) (types.Address, error) {
existing, err := querypublic.AddressFromGID(ctx, txn, a.GID)

View file

@ -1,22 +0,0 @@
package publicreport
import (
"context"
"fmt"
"github.com/Gleipnir-Technology/nidus-sync/db"
querypublic "github.com/Gleipnir-Technology/nidus-sync/db/query/public"
"github.com/Gleipnir-Technology/nidus-sync/platform/types"
)
func loadAddresses(ctx context.Context, txn db.Tx, address_ids []int64) (results map[int32]types.Address, err error) {
addresses, err := querypublic.AddressesFromIDs(ctx, txn, address_ids)
if err != nil {
return nil, fmt.Errorf("query addresses: %w", err)
}
results = make(map[int32]types.Address, len(addresses))
for _, row := range addresses {
results[row.ID] = types.AddressFromModel(row)
}
return results, nil
}

View file

@ -50,14 +50,6 @@ func (srr ServiceRequest) Render(w http.ResponseWriter, r *http.Request) error {
return nil
}
func formatTime(t null.Val[time.Time]) string {
if t.IsNull() {
return ""
}
v := t.MustGet()
return v.Format("2006-01-02T15:04:05.000Z")
}
func toBool(t null.Val[int32]) *bool {
if t.IsNull() {
return nil

View file

@ -1,166 +0,0 @@
package rmo
import (
"net/http"
"github.com/Gleipnir-Technology/nidus-sync/html"
)
type ContentCompliance struct {
District *ContentDistrict
HasCompleteResponse bool
HasUsefulInfo bool
ReferenceNumber string
URL ContentURL
}
func getDistrictCompliance(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance.html",
ContentCompliance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}
func getDistrictComplianceAddress(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance-address.html",
ContentCompliance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}
func getDistrictComplianceComplete(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
complete := query.Get("complete")
is_complete := complete != ""
useful := query.Get("useful")
is_useful := useful != ""
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance-complete.html",
ContentCompliance{
District: newContentDistrict(district),
HasCompleteResponse: is_complete,
HasUsefulInfo: is_useful,
ReferenceNumber: "ABC-123",
URL: makeContentURL(nil),
},
)
}
func getDistrictComplianceConcern(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance-concern.html",
ContentCompliance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}
func getDistrictComplianceContact(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance-contact.html",
ContentCompliance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}
func getDistrictComplianceEvidence(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance-evidence.html",
ContentCompliance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}
func getDistrictCompliancePermission(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance-permission.html",
ContentCompliance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}
func getDistrictComplianceProcess(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance-process.html",
ContentCompliance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}
func getDistrictComplianceSubmit(w http.ResponseWriter, r *http.Request) {
district, err := districtBySlug(r)
if err != nil {
respondError(w, "Failed to lookup organization", err, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/district-compliance-submit.html",
ContentCompliance{
District: newContentDistrict(district),
URL: makeContentURL(nil),
},
)
}

View file

@ -1,124 +0,0 @@
package rmo
import (
"net/http"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/lint"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/Gleipnir-Technology/nidus-sync/platform/email"
"github.com/aarondl/opt/omit"
"github.com/gorilla/mux"
)
type ContentEmail struct {
Email string
}
func getEmailByCode(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["code"]
//id := r.FormValue("id")
if id == "" {
http.Error(w, "You must specify an id", http.StatusBadRequest)
return
}
ctx := r.Context()
email_log, err := models.CommsEmailLogs.Query(
models.SelectWhere.CommsEmailLogs.PublicID.EQ(id),
).One(ctx, db.PGInstance.BobDB)
if err != nil {
respondError(w, "Failed to query email_log: %w", err, http.StatusInternalServerError)
return
}
html, err := email.RenderHTML(email_log.TemplateID, email_log.TemplateData)
if err != nil {
respondError(w, "Failed to render email_log: %w", err, http.StatusInternalServerError)
return
}
lint.Write(w, html)
}
func getEmailReportUnsubscribe(w http.ResponseWriter, r *http.Request) {
email := r.FormValue("email")
html.RenderOrError(
w,
"rmo/email-unsubscribe.html",
ContentEmail{
Email: email,
},
)
}
func getEmailConfirm(w http.ResponseWriter, r *http.Request) {
email := r.FormValue("email")
if email == "" {
respondError(w, "Not sure what to do with an empty email", nil, http.StatusBadRequest)
return
}
html.RenderOrError(
w,
"rmo/email-confirm.html",
ContentEmail{
Email: email,
},
)
}
func getEmailConfirmComplete(w http.ResponseWriter, r *http.Request) {
html.RenderOrError(
w,
"rmo/email-confirm-complete.html",
map[string]string{},
)
}
func getEmailUnsubscribe(w http.ResponseWriter, r *http.Request) {
email := r.FormValue("email")
html.RenderOrError(
w,
"rmo/email-unsubscribe.html",
ContentEmail{
Email: email,
},
)
}
func getEmailUnsubscribeComplete(w http.ResponseWriter, r *http.Request) {
html.RenderOrError(
w,
"rmo/email-unsubscribe-complete.html",
map[string]string{},
)
}
func postEmailConfirm(w http.ResponseWriter, r *http.Request) {
email := r.PostFormValue("email")
if email == "" {
respondError(w, "Not sure what to do with an empty email", nil, http.StatusBadRequest)
return
}
ctx := r.Context()
email_contact, err := models.FindCommsEmailContact(ctx, db.PGInstance.BobDB, email)
if err != nil {
respondError(w, "Email not in the database", err, http.StatusNotFound)
return
}
err = email_contact.Update(ctx, db.PGInstance.BobDB, &models.CommsEmailContactSetter{
Confirmed: omit.From(true),
})
http.Redirect(w, r, "/email/confirm/complete", http.StatusFound)
}
func postEmailUnsubscribe(w http.ResponseWriter, r *http.Request) {
email := r.PostFormValue("email")
if email == "" {
respondError(w, "Not sure what to do with an empty email", nil, http.StatusBadRequest)
return
}
ctx := r.Context()
email_contact, err := models.FindCommsEmailContact(ctx, db.PGInstance.BobDB, email)
if err != nil {
respondError(w, "Email not in the database", err, http.StatusNotFound)
return
}
err = email_contact.Update(ctx, db.PGInstance.BobDB, &models.CommsEmailContactSetter{
IsSubscribed: omit.From(false),
})
http.Redirect(w, r, "/email/unsubscribe/complete", http.StatusFound)
}

View file

@ -1,57 +0,0 @@
package rmo
import (
"net/http"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/gorilla/mux"
)
type ContentMock struct {
District ContentDistrict
ReportID string
URL ContentURL
}
func addMockRoutes(r *mux.Router) {
r.HandleFunc("/", renderMock("rmo/mock/root.html"))
r.HandleFunc("/district/{slug}", renderMock("rmo/mock/district-root.html"))
r.HandleFunc("/district/{slug}/nuisance-submit-complete", renderMock("rmo/mock/nuisance-submit-complete.html"))
r.HandleFunc("/nuisance", renderMock("rmo/mock/nuisance.html"))
r.HandleFunc("/nuisance-submit-complete", renderMock("rmo/mock/nuisance-submit-complete.html"))
}
func makeContentURLMock(slug string) ContentURL {
return ContentURL{
Nuisance: makeURLMock(slug, "nuisance"),
SubmitComplete: makeURLMock(slug, "nuisance-submit-complete"),
Tegola: config.MakeURLTegola("/"),
Water: makeURLMock(slug, "water"),
}
}
func makeURLMock(slug, p string) string {
return config.MakeURLReport("/mock/district/%s/%s", slug, p)
}
func renderMock(t string) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
slug := vars["slug"]
if slug == "" {
slug = "delta-mvcd"
}
html.RenderOrError(
w,
t,
ContentMock{
District: ContentDistrict{
Name: "Delta MVCD",
URLLogo: config.MakeURLNidus("/api/district/%s/logo", slug),
URLWebsite: "http://www.deltavcd.com/",
},
ReportID: "abcd-1234-5678",
URL: makeContentURLMock(slug),
},
)
}
}