119 lines
2.4 KiB
Go
119 lines
2.4 KiB
Go
package util
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"slices"
|
|
"time"
|
|
|
|
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/config"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
"k8s.io/utils/ptr"
|
|
|
|
pb "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/api/v1alpha1/weather"
|
|
"gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather"
|
|
)
|
|
|
|
const defaultLimit = -1
|
|
|
|
func DerefStr(s *string) string {
|
|
if s == nil {
|
|
return ""
|
|
}
|
|
return *s
|
|
}
|
|
|
|
func Int32ptr(i *int) *int32 {
|
|
if i == nil {
|
|
return nil
|
|
}
|
|
return ptr.To(int32(*i))
|
|
}
|
|
|
|
func TimestampFromIntPtr(i *int) *timestamppb.Timestamp {
|
|
if i == nil {
|
|
return nil
|
|
}
|
|
return timestamppb.New(time.Unix(int64(*i), 0))
|
|
}
|
|
|
|
// Generates a hash that will be consistent
|
|
// across all running replicas
|
|
func GetAppHash(conf *config.AppConfig) string {
|
|
hashName := fmt.Sprintf("%s-%s-%s",
|
|
conf.Name,
|
|
conf.Environment,
|
|
conf.Version,
|
|
)
|
|
|
|
hash := md5.Sum([]byte(hashName))
|
|
return hex.EncodeToString(hash[:])
|
|
}
|
|
|
|
// Get a limit from req, applying a default if unset or not sane
|
|
func GetLimitFromReq(req *pb.GetWeatherRequest) int {
|
|
if req == nil || req.Limit == nil {
|
|
return defaultLimit
|
|
}
|
|
|
|
if req.GetLimit() == 0 {
|
|
return defaultLimit
|
|
}
|
|
|
|
return int(req.GetLimit())
|
|
}
|
|
|
|
// Simple helper to trim a list of updates
|
|
func LimitUpdates(updates []*weather.WeatherUpdate, limit int) []*weather.WeatherUpdate {
|
|
if limit < 0 {
|
|
return updates // No limit
|
|
}
|
|
|
|
if len(updates) > limit {
|
|
return updates[len(updates)-limit:] // Trim to limit
|
|
}
|
|
|
|
return updates // Within limit
|
|
}
|
|
|
|
func ApplyOptsToUpdates(updates []*weather.WeatherUpdate, limit int, opts *pb.GetWeatherOpts) []*weather.WeatherUpdate {
|
|
if opts == nil {
|
|
return updates
|
|
} else if opts.StationName == nil && opts.StationType == nil {
|
|
return updates
|
|
}
|
|
|
|
capacity := len(updates)
|
|
if limit > 0 {
|
|
capacity = limit
|
|
}
|
|
|
|
filtered := make([]*weather.WeatherUpdate, 0, capacity)
|
|
|
|
for i := len(updates) - 1; i >= 0; i-- {
|
|
update := updates[i]
|
|
match := true
|
|
|
|
if opts.GetStationName() != "" {
|
|
if update.GetStationName() != opts.GetStationName() {
|
|
match = false
|
|
}
|
|
}
|
|
if opts.GetStationType() != "" {
|
|
if DerefStr(update.StationType) != opts.GetStationType() {
|
|
match = false
|
|
}
|
|
}
|
|
|
|
if match {
|
|
filtered = append(filtered, update)
|
|
if limit > 0 && len(filtered) >= limit {
|
|
return slices.Clip(filtered)
|
|
}
|
|
}
|
|
}
|
|
|
|
return slices.Clip(filtered)
|
|
}
|