Evan Reichard
75ed394f8d
All checks were successful
continuous-integration/drone/push Build is passing
169 lines
4.6 KiB
Go
169 lines
4.6 KiB
Go
package api
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"math"
|
||
"path/filepath"
|
||
"reflect"
|
||
"strings"
|
||
|
||
"reichard.io/antholume/database"
|
||
"reichard.io/antholume/graph"
|
||
"reichard.io/antholume/metadata"
|
||
)
|
||
|
||
type UTCOffset struct {
|
||
Name string
|
||
Value string
|
||
}
|
||
|
||
var UTC_OFFSETS = []UTCOffset{
|
||
{Value: "-12 hours", Name: "UTC−12:00"},
|
||
{Value: "-11 hours", Name: "UTC−11:00"},
|
||
{Value: "-10 hours", Name: "UTC−10:00"},
|
||
{Value: "-9.5 hours", Name: "UTC−09:30"},
|
||
{Value: "-9 hours", Name: "UTC−09:00"},
|
||
{Value: "-8 hours", Name: "UTC−08:00"},
|
||
{Value: "-7 hours", Name: "UTC−07:00"},
|
||
{Value: "-6 hours", Name: "UTC−06:00"},
|
||
{Value: "-5 hours", Name: "UTC−05:00"},
|
||
{Value: "-4 hours", Name: "UTC−04:00"},
|
||
{Value: "-3.5 hours", Name: "UTC−03:30"},
|
||
{Value: "-3 hours", Name: "UTC−03:00"},
|
||
{Value: "-2 hours", Name: "UTC−02:00"},
|
||
{Value: "-1 hours", Name: "UTC−01:00"},
|
||
{Value: "0 hours", Name: "UTC±00:00"},
|
||
{Value: "+1 hours", Name: "UTC+01:00"},
|
||
{Value: "+2 hours", Name: "UTC+02:00"},
|
||
{Value: "+3 hours", Name: "UTC+03:00"},
|
||
{Value: "+3.5 hours", Name: "UTC+03:30"},
|
||
{Value: "+4 hours", Name: "UTC+04:00"},
|
||
{Value: "+4.5 hours", Name: "UTC+04:30"},
|
||
{Value: "+5 hours", Name: "UTC+05:00"},
|
||
{Value: "+5.5 hours", Name: "UTC+05:30"},
|
||
{Value: "+5.75 hours", Name: "UTC+05:45"},
|
||
{Value: "+6 hours", Name: "UTC+06:00"},
|
||
{Value: "+6.5 hours", Name: "UTC+06:30"},
|
||
{Value: "+7 hours", Name: "UTC+07:00"},
|
||
{Value: "+8 hours", Name: "UTC+08:00"},
|
||
{Value: "+8.75 hours", Name: "UTC+08:45"},
|
||
{Value: "+9 hours", Name: "UTC+09:00"},
|
||
{Value: "+9.5 hours", Name: "UTC+09:30"},
|
||
{Value: "+10 hours", Name: "UTC+10:00"},
|
||
{Value: "+10.5 hours", Name: "UTC+10:30"},
|
||
{Value: "+11 hours", Name: "UTC+11:00"},
|
||
{Value: "+12 hours", Name: "UTC+12:00"},
|
||
{Value: "+12.75 hours", Name: "UTC+12:45"},
|
||
{Value: "+13 hours", Name: "UTC+13:00"},
|
||
{Value: "+14 hours", Name: "UTC+14:00"},
|
||
}
|
||
|
||
func getUTCOffsets() []UTCOffset {
|
||
return UTC_OFFSETS
|
||
}
|
||
|
||
func niceSeconds(input int64) (result string) {
|
||
if input == 0 {
|
||
return "N/A"
|
||
}
|
||
|
||
days := math.Floor(float64(input) / 60 / 60 / 24)
|
||
seconds := input % (60 * 60 * 24)
|
||
hours := math.Floor(float64(seconds) / 60 / 60)
|
||
seconds = input % (60 * 60)
|
||
minutes := math.Floor(float64(seconds) / 60)
|
||
seconds = input % 60
|
||
|
||
if days > 0 {
|
||
result += fmt.Sprintf("%dd ", int(days))
|
||
}
|
||
if hours > 0 {
|
||
result += fmt.Sprintf("%dh ", int(hours))
|
||
}
|
||
if minutes > 0 {
|
||
result += fmt.Sprintf("%dm ", int(minutes))
|
||
}
|
||
if seconds > 0 {
|
||
result += fmt.Sprintf("%ds", int(seconds))
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
func niceNumbers(input int64) string {
|
||
if input == 0 {
|
||
return "0"
|
||
}
|
||
|
||
abbreviations := []string{"", "k", "M", "B", "T"}
|
||
abbrevIndex := int(math.Log10(float64(input)) / 3)
|
||
scaledNumber := float64(input) / math.Pow(10, float64(abbrevIndex*3))
|
||
|
||
if scaledNumber >= 100 {
|
||
return fmt.Sprintf("%.0f%s", scaledNumber, abbreviations[abbrevIndex])
|
||
} else if scaledNumber >= 10 {
|
||
return fmt.Sprintf("%.1f%s", scaledNumber, abbreviations[abbrevIndex])
|
||
} else {
|
||
return fmt.Sprintf("%.2f%s", scaledNumber, abbreviations[abbrevIndex])
|
||
}
|
||
}
|
||
|
||
// Convert Database Array -> Int64 Array
|
||
func getSVGGraphData(inputData []database.GetDailyReadStatsRow, svgWidth int, svgHeight int) graph.SVGGraphData {
|
||
var intData []int64
|
||
for _, item := range inputData {
|
||
intData = append(intData, item.MinutesRead)
|
||
}
|
||
|
||
return graph.GetSVGGraphData(intData, svgWidth, svgHeight)
|
||
}
|
||
|
||
func dict(values ...interface{}) (map[string]interface{}, error) {
|
||
if len(values)%2 != 0 {
|
||
return nil, errors.New("invalid dict call")
|
||
}
|
||
dict := make(map[string]interface{}, len(values)/2)
|
||
for i := 0; i < len(values); i += 2 {
|
||
key, ok := values[i].(string)
|
||
if !ok {
|
||
return nil, errors.New("dict keys must be strings")
|
||
}
|
||
dict[key] = values[i+1]
|
||
}
|
||
return dict, nil
|
||
}
|
||
|
||
func fields(value interface{}) (map[string]interface{}, error) {
|
||
v := reflect.Indirect(reflect.ValueOf(value))
|
||
if v.Kind() != reflect.Struct {
|
||
return nil, fmt.Errorf("%T is not a struct", value)
|
||
}
|
||
m := make(map[string]interface{})
|
||
t := v.Type()
|
||
for i := 0; i < t.NumField(); i++ {
|
||
sv := t.Field(i)
|
||
m[sv.Name] = v.Field(i).Interface()
|
||
}
|
||
return m, nil
|
||
}
|
||
|
||
func deriveBaseFileName(metadataInfo *metadata.MetadataInfo) string {
|
||
// Derive New FileName
|
||
var newFileName string
|
||
if *metadataInfo.Author != "" {
|
||
newFileName = newFileName + *metadataInfo.Author
|
||
} else {
|
||
newFileName = newFileName + "Unknown"
|
||
}
|
||
if *metadataInfo.Title != "" {
|
||
newFileName = newFileName + " - " + *metadataInfo.Title
|
||
} else {
|
||
newFileName = newFileName + " - Unknown"
|
||
}
|
||
|
||
// Remove Slashes
|
||
fileName := strings.ReplaceAll(newFileName, "/", "")
|
||
return "." + filepath.Clean(fmt.Sprintf("/%s [%s]%s", fileName, *metadataInfo.PartialMD5, metadataInfo.Type))
|
||
}
|