fn.go (6569B)
1 package template 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 "html/template" 8 "net/url" 9 "reflect" 10 "strconv" 11 "strings" 12 "time" 13 "unicode/utf8" 14 15 "dkforest/pkg/database" 16 "dkforest/pkg/utils" 17 humanize "github.com/dustin/go-humanize" 18 "github.com/nicksnyder/go-i18n/v2/i18n" 19 ) 20 21 func getKeyFingerprint(pkey string) string { 22 return utils.GetKeyFingerprint(pkey) 23 } 24 25 func shortNum(n int64) string { 26 if n < 1000 { 27 return utils.FormatInt64(n) 28 } else if n >= 1000 && n < 1000000 { 29 return utils.FormatInt64(n/1000) + "k" 30 } else if n >= 1000000 { 31 return utils.FormatInt64(n/1000000) + "M" 32 } 33 return utils.FormatInt64(n) 34 } 35 36 func shortNumPtr(n *int64) string { 37 if n == nil { 38 return "-" 39 } 40 return shortNum(*n) 41 } 42 43 func n(start, end int64) (stream chan int64) { 44 stream = make(chan int64) 45 utils.SGo(func() { 46 for i := start; i <= end; i++ { 47 stream <- i 48 } 49 close(stream) 50 }) 51 return 52 } 53 54 func mod(i, j int64) bool { return i%j == 0 } 55 56 func addInt(a, b int) int { 57 return a + b 58 } 59 func add(a, b int64) int64 { 60 return a + b 61 } 62 63 func md5(v string) string { 64 return utils.MD5([]byte(v)) 65 } 66 67 func limitTo(limit int64, s string) string { 68 if int64(len(s)) > limit { 69 return s[0:limit] 70 } 71 return s 72 } 73 74 func derefStr(s *string) string { 75 if s == nil { 76 return "" 77 } 78 return *s 79 } 80 81 func css(s string) template.CSS { 82 return template.CSS(s) 83 } 84 85 func attr(s string) template.HTMLAttr { 86 return template.HTMLAttr(s) 87 } 88 89 func safe(s string) template.HTML { 90 return template.HTML(s) 91 } 92 93 func safeURL(s string) template.URL { 94 return template.URL(s) 95 } 96 97 func safeJsStr(s string) template.JSStr { 98 return template.JSStr(s) 99 } 100 101 func safeJs(s string) template.JS { 102 return template.JS(s) 103 } 104 105 func success(code int64) bool { 106 return code/100 == 2 107 } 108 109 func divide100(val int64) float64 { 110 return float64(val) / 100 111 } 112 113 func divide1000(val int64) float64 { 114 return float64(val) / 1000 115 } 116 func divide100M(val int64) float64 { 117 return float64(val) / 100_000_000 118 } 119 func divide1T(val database.Piconero) float64 { 120 return float64(val) / 1_000_000_000_000 121 } 122 func fmtPiconero(val database.Piconero) string { 123 return val.XmrStr() 124 } 125 126 func int64bytes(val int64) string { 127 return humanize.Bytes(uint64(val)) 128 } 129 130 func toString(v any) string { 131 b, _ := json.Marshal(v) 132 return string(b) 133 } 134 135 func toI64(v any) int64 { 136 if i, ok := v.(int64); ok { 137 return i 138 } 139 return 0 140 } 141 142 func formatFloat(precision int, val float64) string { 143 return strconv.FormatFloat(val, 'f', precision, 64) 144 } 145 146 func comma(v int64) string { 147 return humanize.Comma(int64(v)) 148 } 149 150 func intComma(v int) string { 151 return humanize.Comma(int64(v)) 152 } 153 154 func uint64Comma(v uint64) string { 155 return humanize.Comma(int64(v)) 156 } 157 158 func uint32Comma(v uint32) string { 159 return humanize.Comma(int64(v)) 160 } 161 162 func unixNs(v uint64) time.Time { 163 return time.Unix(0, int64(v)) 164 } 165 166 func commaPtr(v *int64) string { 167 if v == nil { 168 return "-" 169 } 170 return comma(*v) 171 } 172 173 func nowOGTFmt(location *time.Location) string { 174 if location == nil { 175 return "-- h --" 176 } 177 return time.Now().In(location).Format("15 h 04") 178 } 179 180 func formatTsPtr(v *time.Time) string { 181 if v == nil { 182 return "n/a" 183 } 184 return v.Format("Jan 02, 2006 - 15:04:05") 185 } 186 187 func formatLocal(date time.Time) string { 188 return date.Local().Format("06.01.02 15:04:05") 189 } 190 191 func until(date time.Time) string { 192 return humanize.Time(date) 193 } 194 195 func notNil(v any) any { 196 if v == nil || (reflect.ValueOf(v).Kind() == reflect.Ptr && reflect.ValueOf(v).IsNil()) { 197 return "" 198 } 199 return v 200 } 201 202 func shortDurNs(ns uint64) string { 203 return time.Duration(ns).String() 204 } 205 206 func shortDur(v any) string { 207 return utils.ShortDur(v) 208 } 209 210 func secs(t time.Time) int64 { 211 return int64(time.Until(t).Seconds()) 212 } 213 214 func backtoIP4(longIP uint32) string { 215 return utils.BacktoIP4(int64(longIP)) 216 } 217 218 func ts(ts int64) time.Time { 219 return time.Unix(int64(ts), 0) 220 } 221 222 func capfirst(in string) string { 223 if len(in) <= 0 { 224 return "" 225 } 226 r, size := utf8.DecodeRuneInString(in) 227 return strings.ToUpper(string(r)) + in[size:] 228 } 229 230 func first(in string) string { 231 return string(in[0]) 232 } 233 234 func last(in string) string { 235 return string(in[len(in)-1]) 236 } 237 238 func rest(in string) string { 239 return in[1:] 240 } 241 242 func middle(in string) string { 243 return in[1 : len(in)-1] 244 } 245 246 func translate(varName string, vals templateDataStruct) string { 247 sections := []string{ 248 vals.TmplName + "." + varName, 249 } 250 parts := strings.Split(vals.TmplName, ".") 251 for len(parts) > 0 { 252 parts = parts[0 : len(parts)-1] 253 sections = append(sections, strings.Join(append(parts, "index"), ".")+"."+varName) 254 } 255 var translated string 256 var err error 257 localizer := i18n.NewLocalizer(vals.Bundle, vals.Lang, vals.AcceptLanguage) 258 for _, section := range sections { 259 translated, err = localizer.Localize(&i18n.LocalizeConfig{ 260 DefaultMessage: &i18n.Message{ID: section}, 261 TemplateData: vals.Data, 262 }) 263 if err != nil { 264 continue 265 } 266 break 267 } 268 if err != nil { 269 translated = localizer.MustLocalize(&i18n.LocalizeConfig{ 270 DefaultMessage: &i18n.Message{ID: "global." + varName, Other: varName}, 271 TemplateData: vals.Data, 272 }) 273 } 274 return translated 275 } 276 277 func trimPrefix(prefix, val string) string { 278 return strings.TrimPrefix(val, prefix) 279 } 280 281 func mul(param1 int64, param2 int64) int64 { 282 return param1 * param2 283 } 284 285 func trunc(nb int64, in string) string { 286 if int64(len(in)) > nb { 287 return in[0:nb] + "…" 288 } 289 return in 290 } 291 292 func dict(vals ...any) map[string]any { 293 out := make(map[string]any) 294 for i := 0; i < len(vals); i += 2 { 295 k := vals[i].(string) 296 v := vals[i+1] 297 out[k] = v 298 } 299 return out 300 } 301 302 func pct(v1, v2 int64) int64 { 303 return int64(float64(v1) / float64(v2) * 100) 304 } 305 306 func cents(cents int64) string { 307 return fmt.Sprintf("$%0.2f", float64(cents)/100) 308 } 309 310 // Display last 4 digits of a CC 311 func last4(cc database.EncryptedString) string { 312 return utils.Last4(string(cc)) 313 } 314 315 func toMs(dur time.Duration) int64 { 316 return int64(dur / time.Millisecond) 317 } 318 319 func derefI64(v *int64) int64 { 320 if v == nil { 321 return 0 322 } 323 return *v 324 } 325 326 func derefUserID(v *database.UserID) database.UserID { 327 if v == nil { 328 return 0 329 } 330 return *v 331 } 332 333 func shortHost(v string) string { 334 parsed, err := url.Parse(v) 335 if err != nil { 336 return "unknown" 337 } 338 return strings.TrimPrefix(parsed.Host, "www.") 339 } 340 341 func b64(b []byte) string { 342 return base64.StdEncoding.EncodeToString(b) 343 } 344 345 func fmtBool(v bool) template.HTML { 346 if v { 347 return `<span style="color: green;">Y</span>` 348 } 349 return `<span style="color: red;">N</span>` 350 } 351 352 func isStrEmpty(v string) bool { 353 return v == "" 354 } 355 356 func ms2s(v int64) int64 { 357 return v / 1000 358 } 359 360 func since(v time.Time) string { 361 return humanize.Time(v) 362 }