mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-04-19 17:42:53 +00:00
Compare commits
3 Commits
fc6b6a9c6b
...
9875458b01
Author | SHA1 | Date | |
---|---|---|---|
9875458b01 | |||
f0dccc58aa | |||
636bc22d52 |
76
logger.go
76
logger.go
@ -3,6 +3,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
c "github.com/fatih/color"
|
c "github.com/fatih/color"
|
||||||
)
|
)
|
||||||
@ -16,24 +18,84 @@ type Logger interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type logger struct {
|
type logger struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
printer *c.Color
|
shortfile bool
|
||||||
|
printer *c.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
func Lshortfile() string {
|
||||||
|
_, file, line, ok := runtime.Caller(2)
|
||||||
|
lineString := strconv.Itoa(line)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if file == "" {
|
||||||
|
return lineString
|
||||||
|
}
|
||||||
|
for i := len(file) - 1; i > 0; i-- {
|
||||||
|
if file[i] == '/' || file[i] == '\\' {
|
||||||
|
file = file[i+1:]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file + ":" + lineString + ":"
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLogger(out io.Writer, prefix string, flag int, color c.Attribute) (l logger) {
|
func NewLogger(out io.Writer, prefix string, flag int, color c.Attribute) (l logger) {
|
||||||
|
// Use reimplemented Lshortfile since wrapping the log functions messes them up
|
||||||
|
if flag&log.Lshortfile != 0 {
|
||||||
|
flag -= log.Lshortfile
|
||||||
|
l.shortfile = true
|
||||||
|
}
|
||||||
|
|
||||||
l.logger = log.New(out, prefix, flag)
|
l.logger = log.New(out, prefix, flag)
|
||||||
l.printer = c.New(color)
|
l.printer = c.New(color)
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l logger) Printf(format string, v ...interface{}) {
|
func (l logger) Printf(format string, v ...interface{}) {
|
||||||
l.logger.Print(l.printer.Sprintf(format, v...))
|
var out string
|
||||||
|
if l.shortfile {
|
||||||
|
out = Lshortfile()
|
||||||
|
}
|
||||||
|
out += " " + l.printer.Sprintf(format, v...)
|
||||||
|
l.logger.Print(out)
|
||||||
}
|
}
|
||||||
func (l logger) Print(v ...interface{}) { l.logger.Print(l.printer.Sprint(v...)) }
|
|
||||||
func (l logger) Println(v ...interface{}) { l.logger.Print(l.printer.Sprintln(v...)) }
|
func (l logger) Print(v ...interface{}) {
|
||||||
func (l logger) Fatal(v ...interface{}) { l.logger.Fatal(l.printer.Sprint(v...)) }
|
var out string
|
||||||
|
if l.shortfile {
|
||||||
|
out = Lshortfile()
|
||||||
|
}
|
||||||
|
out += " " + l.printer.Sprint(v...)
|
||||||
|
l.logger.Print(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l logger) Println(v ...interface{}) {
|
||||||
|
var out string
|
||||||
|
if l.shortfile {
|
||||||
|
out = Lshortfile()
|
||||||
|
}
|
||||||
|
out += " " + l.printer.Sprintln(v...)
|
||||||
|
l.logger.Print(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l logger) Fatal(v ...interface{}) {
|
||||||
|
var out string
|
||||||
|
if l.shortfile {
|
||||||
|
out = Lshortfile()
|
||||||
|
}
|
||||||
|
out += " " + l.printer.Sprint(v...)
|
||||||
|
l.logger.Fatal(out)
|
||||||
|
}
|
||||||
|
|
||||||
func (l logger) Fatalf(format string, v ...interface{}) {
|
func (l logger) Fatalf(format string, v ...interface{}) {
|
||||||
l.logger.Fatal(l.printer.Sprintf(format, v...))
|
var out string
|
||||||
|
if l.shortfile {
|
||||||
|
out = Lshortfile()
|
||||||
|
}
|
||||||
|
out += " " + l.printer.Sprintf(format, v...)
|
||||||
|
l.logger.Fatal(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
type emptyLogger bool
|
type emptyLogger bool
|
||||||
|
14
main.go
14
main.go
@ -38,6 +38,7 @@ var (
|
|||||||
DATA, CONFIG, HOST *string
|
DATA, CONFIG, HOST *string
|
||||||
PORT *int
|
PORT *int
|
||||||
DEBUG *bool
|
DEBUG *bool
|
||||||
|
PPROF *bool
|
||||||
TEST bool
|
TEST bool
|
||||||
SWAGGER *bool
|
SWAGGER *bool
|
||||||
warning = color.New(color.FgYellow).SprintfFunc()
|
warning = color.New(color.FgYellow).SprintfFunc()
|
||||||
@ -172,7 +173,8 @@ func start(asDaemon, firstCall bool) {
|
|||||||
CONFIG = flag.String("config", app.configPath, "alternate path to config file.")
|
CONFIG = flag.String("config", app.configPath, "alternate path to config file.")
|
||||||
HOST = flag.String("host", "", "alternate address to host web ui on.")
|
HOST = flag.String("host", "", "alternate address to host web ui on.")
|
||||||
PORT = flag.Int("port", 0, "alternate port to host web ui on.")
|
PORT = flag.Int("port", 0, "alternate port to host web ui on.")
|
||||||
DEBUG = flag.Bool("debug", false, "Enables debug logging and exposes pprof.")
|
DEBUG = flag.Bool("debug", false, "Enables debug logging.")
|
||||||
|
PPROF = flag.Bool("pprof", false, "Exposes pprof profiler on /debug/pprof.")
|
||||||
SWAGGER = flag.Bool("swagger", false, "Enable swagger at /swagger/index.html")
|
SWAGGER = flag.Bool("swagger", false, "Enable swagger at /swagger/index.html")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
@ -182,6 +184,9 @@ func start(asDaemon, firstCall bool) {
|
|||||||
if *DEBUG {
|
if *DEBUG {
|
||||||
os.Setenv("DEBUG", "1")
|
os.Setenv("DEBUG", "1")
|
||||||
}
|
}
|
||||||
|
if *PPROF {
|
||||||
|
os.Setenv("PPROF", "1")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("SWAGGER") == "1" {
|
if os.Getenv("SWAGGER") == "1" {
|
||||||
@ -190,6 +195,9 @@ func start(asDaemon, firstCall bool) {
|
|||||||
if os.Getenv("DEBUG") == "1" {
|
if os.Getenv("DEBUG") == "1" {
|
||||||
*DEBUG = true
|
*DEBUG = true
|
||||||
}
|
}
|
||||||
|
if os.Getenv("PPROF") == "1" {
|
||||||
|
*PPROF = true
|
||||||
|
}
|
||||||
// attempt to apply command line flags correctly
|
// attempt to apply command line flags correctly
|
||||||
if app.configPath == *CONFIG && app.dataPath != *DATA {
|
if app.configPath == *CONFIG && app.dataPath != *DATA {
|
||||||
app.dataPath = *DATA
|
app.dataPath = *DATA
|
||||||
@ -248,11 +256,13 @@ func start(asDaemon, firstCall bool) {
|
|||||||
debugMode = true
|
debugMode = true
|
||||||
}
|
}
|
||||||
if debugMode {
|
if debugMode {
|
||||||
app.info.Print(warning("\n\nWARNING: Don't use debug mode in production, as it exposes pprof on the network.\n\n"))
|
|
||||||
app.debug = NewLogger(os.Stdout, "[DEBUG] ", log.Ltime|log.Lshortfile, color.FgYellow)
|
app.debug = NewLogger(os.Stdout, "[DEBUG] ", log.Ltime|log.Lshortfile, color.FgYellow)
|
||||||
} else {
|
} else {
|
||||||
app.debug = emptyLogger(false)
|
app.debug = emptyLogger(false)
|
||||||
}
|
}
|
||||||
|
if *PPROF {
|
||||||
|
app.info.Print(warning("\n\nWARNING: Don't use pprof in production.\n\n"))
|
||||||
|
}
|
||||||
|
|
||||||
// Starts listener to receive commands over a unix socket. Use with 'jfa-go start/stop'
|
// Starts listener to receive commands over a unix socket. Use with 'jfa-go start/stop'
|
||||||
if asDaemon {
|
if asDaemon {
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package mediabrowser
|
package mediabrowser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,44 +14,29 @@ type Time struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Time) UnmarshalJSON(b []byte) (err error) {
|
func (t *Time) UnmarshalJSON(b []byte) (err error) {
|
||||||
str := strings.TrimSuffix(strings.TrimPrefix(string(b), "\""), "\"")
|
// str := strings.TrimSuffix(strings.TrimPrefix(string(b), "\""), "\"")
|
||||||
// Trim nanoseconds to always have 6 digits, so overall length is always the same.
|
// Trim quotes from beginning and end, and any number of Zs (indicates UTC).
|
||||||
if str[len(str)-1] == 'Z' {
|
for b[0] == '"' {
|
||||||
if str[len(str)-2] == 'Z' {
|
b = b[1:]
|
||||||
/* From #69, "ZZ" is sometimes used, meaning UTC-8:00.
|
|
||||||
TZ doesn't really matter to us, so we'll pretend it's UTC. */
|
|
||||||
str = str[:25] + "0Z"
|
|
||||||
} else {
|
|
||||||
str = str[:26] + "Z"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str = str[:26]
|
|
||||||
}
|
}
|
||||||
// decent method
|
for b[len(b)-1] == '"' || b[len(b)-1] == 'Z' {
|
||||||
t.Time, err = time.Parse("2006-01-02T15:04:05.000000Z", str)
|
b = b[:len(b)-1]
|
||||||
if err == nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
t.Time, err = time.Parse("2006-01-02T15:04:05.000000", str)
|
// Trim nanoseconds and anything after, we don't care
|
||||||
if err == nil {
|
i := len(b) - 1
|
||||||
return
|
for b[i] != '.' && i > 0 {
|
||||||
|
i--
|
||||||
}
|
}
|
||||||
// emby method
|
if i != 0 {
|
||||||
t.Time, err = time.Parse("2006-01-02T15:04:05.0000000+00:00", str)
|
b = b[:i]
|
||||||
if err == nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
fmt.Println("THIRDERR", err)
|
t.Time, err = time.Parse("2006-01-02T15:04:05", string(b))
|
||||||
// if all else fails, just do whatever would usually be done.
|
// str := string(b) + "Z"
|
||||||
// some stored dates from jellyfin have no timezone at the end, if not we assume UTC
|
// timeJSON := []byte("{ \"parseme\": \"" + str + "\" }")
|
||||||
if str[len(str)-1] != 'Z' {
|
// var parsed magicParse
|
||||||
str += "Z"
|
// // Magically turn it into a time.Time
|
||||||
}
|
// err = json.Unmarshal(timeJSON, &parsed)
|
||||||
timeJSON := []byte("{ \"parseme\": \"" + str + "\" }")
|
// t.Time = parsed.Parsed
|
||||||
var parsed magicParse
|
|
||||||
// Magically turn it into a time.Time
|
|
||||||
err = json.Unmarshal(timeJSON, &parsed)
|
|
||||||
t.Time = parsed.Parsed
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ func (app *appContext) loadRouter(address string, debug bool) *gin.Engine {
|
|||||||
app.loadHTML(router)
|
app.loadHTML(router)
|
||||||
router.Use(static.Serve("/", app.webFS))
|
router.Use(static.Serve("/", app.webFS))
|
||||||
router.NoRoute(app.NoRouteHandler)
|
router.NoRoute(app.NoRouteHandler)
|
||||||
if debug {
|
if *PPROF {
|
||||||
app.debug.Println("Loading pprof")
|
app.debug.Println("Loading pprof")
|
||||||
pprof.Register(router)
|
pprof.Register(router)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user