123 lines
2.6 KiB
Go
123 lines
2.6 KiB
Go
package sneed
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// -------------------------------------------------------------
|
|
// GENERIC EXTRACTION HELPERS
|
|
// -------------------------------------------------------------
|
|
|
|
// str extracts a string from any JSON value if possible.
|
|
func str(v interface{}) string {
|
|
switch t := v.(type) {
|
|
case string:
|
|
return t
|
|
case []byte:
|
|
return string(t)
|
|
case float64:
|
|
return strconv.FormatFloat(t, 'f', -1, 64)
|
|
case int:
|
|
return strconv.Itoa(t)
|
|
case int64:
|
|
return strconv.FormatInt(t, 10)
|
|
case bool:
|
|
if t {
|
|
return "true"
|
|
}
|
|
return "false"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// toInt attempts to pull an integer from JSON input.
|
|
func toInt(v interface{}) (int, bool) {
|
|
switch t := v.(type) {
|
|
case int:
|
|
return t, true
|
|
case int64:
|
|
return int(t), true
|
|
case float64:
|
|
return int(t), true
|
|
case string:
|
|
i, err := strconv.Atoi(strings.TrimSpace(t))
|
|
if err == nil {
|
|
return i, true
|
|
}
|
|
}
|
|
return 0, false
|
|
}
|
|
|
|
// toInt64 extracts an int64 from various types.
|
|
func toInt64(v interface{}) (int64, bool) {
|
|
switch t := v.(type) {
|
|
case int64:
|
|
return t, true
|
|
case int:
|
|
return int64(t), true
|
|
case float64:
|
|
return int64(t), true
|
|
case string:
|
|
i, err := strconv.ParseInt(strings.TrimSpace(t), 10, 64)
|
|
if err == nil {
|
|
return i, true
|
|
}
|
|
}
|
|
return 0, false
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// TIMESTAMP HELPERS
|
|
// -------------------------------------------------------------
|
|
|
|
// nowMS returns Unix milliseconds.
|
|
func nowMS() int64 {
|
|
return time.Now().UnixMilli()
|
|
}
|
|
|
|
// newerTimestamp returns true if tsNew > tsOld.
|
|
func newerTimestamp(tsNew, tsOld int64) bool {
|
|
return tsNew > tsOld
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// CONTENT CLEANUP
|
|
// -------------------------------------------------------------
|
|
|
|
// cleanContent normalizes message text received from Sneedchat.
|
|
func cleanContent(s string) string {
|
|
if s == "" {
|
|
return ""
|
|
}
|
|
|
|
// Remove weird control chars
|
|
s = strings.Map(func(r rune) rune {
|
|
if r < 32 || r == 127 {
|
|
return -1
|
|
}
|
|
return r
|
|
}, s)
|
|
|
|
// Trim whitespace
|
|
return strings.TrimSpace(s)
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// SAFE JSON LOGGING HELPERS
|
|
// -------------------------------------------------------------
|
|
|
|
// dumpJSON prints JSON for debugging without crashing.
|
|
func dumpJSON(label string, v interface{}) {
|
|
b, err := json.MarshalIndent(v, "", " ")
|
|
if err != nil {
|
|
log.Printf("%s <json error: %v>", label, err)
|
|
return
|
|
}
|
|
log.Printf("%s: %s", label, string(b))
|
|
}
|