From f231d393694f089a9639b851277c7ef03e7dd744 Mon Sep 17 00:00:00 2001 From: Hunter Long Date: Sun, 18 Nov 2018 23:13:53 -0800 Subject: [PATCH] fixed postgres time issue - code cleanup - API timezone updates --- Gopkg.lock | 41 +++++++------------------- Gopkg.toml | 2 +- Makefile | 2 +- cmd/main_test.go | 2 +- core/checker.go | 2 +- core/configs.go | 23 ++++++++++----- core/core.go | 21 ++++++++++++- core/database.go | 59 ++++++++++++++++++++++++++----------- core/hits.go | 3 -- core/notifier/notifiers.go | 15 ++++++++-- core/services.go | 11 +++++-- handlers/api.go | 3 ++ handlers/dashboard.go | 2 -- handlers/services.go | 16 +++++----- handlers/setup.go | 2 +- notifiers/notifiers_test.go | 2 +- source/js/setup.js | 5 +++- source/source.go | 55 ++-------------------------------- source/tmpl/service.html | 2 +- types/time.go | 8 +++-- types/types.go | 1 + utils/time.go | 8 +++++ utils/utils.go | 8 ----- utils/utils_test.go | 2 +- 24 files changed, 151 insertions(+), 144 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index fe10a9f7..8919512e 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,14 +1,6 @@ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. -[[projects]] - digest = "1:b62a3c5b37db602bf1158e921da1a762315a4c37855fd418a14498aa87a342d5" - name = "cloud.google.com/go" - packages = ["civil"] - pruneopts = "UT" - revision = "debcad1964693daf8ef4bc06292d7e828e075130" - version = "v0.31.0" - [[projects]] branch = "master" digest = "1:65796e5fdb94d94bc0ee6bc422aa3541dbe69ed4da275cb5a27f8fa141f4e35c" @@ -45,31 +37,20 @@ version = "v1.1.1" [[projects]] - branch = "master" - digest = "1:0fd9da444782c2defb1352dc098f55b8b42c538787e29e45677a1dc40ff0ab11" - name = "github.com/denisenkom/go-mssqldb" - packages = [ - ".", - "internal/cp", - ] - pruneopts = "UT" - revision = "4e0d7dc8888fbb59764060e99b7b68e77a6f9698" - -[[projects]] - digest = "1:e37eb23cfd852df9c65b5dee28456595d7b12479421221a088b6ea7ad95a3570" + digest = "1:3806f369b846160fcbde19bdcf93790868defe7c58d1bb6bc8d974c5b8f8dc1e" name = "github.com/go-mail/mail" packages = ["."] pruneopts = "UT" - revision = "63235f23494bf20d713a585bce40b2a0675c2f77" - version = "2.2.0" + revision = "f59b9b83a4e522098e3d3eb94e6f81850ad6e973" + version = "v2.3.1" [[projects]] - digest = "1:adea5a94903eb4384abef30f3d878dc9ff6b6b5b0722da25b82e5169216dfb61" + digest = "1:ec6f9bf5e274c833c911923c9193867f3f18788c461f76f05f62bb1510e0ae65" name = "github.com/go-sql-driver/mysql" packages = ["."] pruneopts = "UT" - revision = "d523deb1b23d913de5bdada721a6071e71283618" - version = "v1.4.0" + revision = "72cd26f257d44c1114970e19afddcd812016007e" + version = "v1.4.1" [[projects]] digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202" @@ -112,11 +93,10 @@ version = "v1.1.3" [[projects]] - digest = "1:4d28d632da146ec6e632bdd29676a95e0874f1ad837fff06aef6610b3b6b4728" + digest = "1:8fe19266ce82209076d4a81007ff93f40dd349faca4a917aea59d33956bbd4fd" name = "github.com/jinzhu/gorm" packages = [ ".", - "dialects/mssql", "dialects/mysql", "dialects/postgres", "dialects/sqlite", @@ -211,15 +191,14 @@ [[projects]] branch = "master" - digest = "1:68344dbfaa4179bb50a583eb8172ace3f1edaf3aebc24e68c03f549f6e6b60dc" + digest = "1:1ecf2a49df33be51e757d0033d5d51d5f784f35f68e5a38f797b2d3f03357d71" name = "golang.org/x/crypto" packages = [ "bcrypt", "blowfish", - "md4", ] pruneopts = "UT" - revision = "4d3f4d9ffa16a13f451c3b2999e9c49e9750bf06" + revision = "3d3f9f413869b949e48070b5bc593aa22cc2b8f2" [[projects]] digest = "1:c25289f43ac4a68d88b02245742347c94f1e108c534dda442188015ff80669b3" @@ -258,13 +237,13 @@ analyzer-version = 1 input-imports = [ "github.com/GeertJohan/go.rice", + "github.com/GeertJohan/go.rice/embedded", "github.com/ararog/timeago", "github.com/go-mail/mail", "github.com/go-yaml/yaml", "github.com/gorilla/mux", "github.com/gorilla/sessions", "github.com/jinzhu/gorm", - "github.com/jinzhu/gorm/dialects/mssql", "github.com/jinzhu/gorm/dialects/mysql", "github.com/jinzhu/gorm/dialects/postgres", "github.com/jinzhu/gorm/dialects/sqlite", diff --git a/Gopkg.toml b/Gopkg.toml index 4b5ee3e1..f30c86b2 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -35,7 +35,7 @@ [[constraint]] name = "github.com/go-mail/mail" - version = "2.2.0" + version = "2.3.1" [[constraint]] name = "github.com/go-yaml/yaml" diff --git a/Makefile b/Makefile index de7525fa..8028d59d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=0.79.84 +VERSION=0.79.85 BINARY_NAME=statup GOPATH:=$(GOPATH) GOCMD=go diff --git a/cmd/main_test.go b/cmd/main_test.go index 10afc43b..6e60c863 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -288,7 +288,7 @@ func RunSelectAllMysqlServices(t *testing.T) { func RunSelectAllNotifiers(t *testing.T) { var err error - notifier.SetDB(core.DbSession) + notifier.SetDB(core.DbSession, float32(-8)) core.CoreApp.Notifications = notifier.Load() assert.Nil(t, err) assert.Equal(t, 8, len(core.CoreApp.Notifications)) diff --git a/core/checker.go b/core/checker.go index fc380afe..e81771ab 100644 --- a/core/checker.go +++ b/core/checker.go @@ -238,7 +238,7 @@ func (s *Service) Check(record bool) { // recordSuccess will create a new 'hit' record in the database for a successful/online service func recordSuccess(s *Service) { s.Online = true - s.LastOnline = time.Now() + s.LastOnline = utils.Timezoner(time.Now().UTC(), CoreApp.Timezone) hit := &types.Hit{ Service: s.Id, Latency: s.Latency, diff --git a/core/configs.go b/core/configs.go index 192ef427..727fbe0d 100644 --- a/core/configs.go +++ b/core/configs.go @@ -52,26 +52,32 @@ func LoadConfigFile(directory string) (*DbConfig, error) { // LoadUsingEnv will attempt to load database configs based on environment variables. If DB_CONN is set if will force this function. func LoadUsingEnv() (*DbConfig, error) { Configs = new(DbConfig) + Configs.LocalIP = GetLocalIP() if os.Getenv("DB_CONN") == "" { - return nil, errors.New("Missing DB_CONN environment variable") + return Configs, errors.New("Missing DB_CONN environment variable") } if os.Getenv("DB_CONN") != "sqlite" { if os.Getenv("DB_HOST") == "" { - return nil, errors.New("Missing DB_HOST environment variable") + return Configs, errors.New("Missing DB_HOST environment variable") } if os.Getenv("DB_USER") == "" { - return nil, errors.New("Missing DB_USER environment variable") + return Configs, errors.New("Missing DB_USER environment variable") } if os.Getenv("DB_PASS") == "" { - return nil, errors.New("Missing DB_PASS environment variable") + return Configs, errors.New("Missing DB_PASS environment variable") } if os.Getenv("DB_DATABASE") == "" { - return nil, errors.New("Missing DB_DATABASE environment variable") + return Configs, errors.New("Missing DB_DATABASE environment variable") } } Configs = EnvToConfig() CoreApp.Name = os.Getenv("NAME") - CoreApp.Domain = os.Getenv("DOMAIN") + domain := os.Getenv("DOMAIN") + if domain == "" { + CoreApp.Domain = Configs.LocalIP + } else { + CoreApp.Domain = os.Getenv("DOMAIN") + } CoreApp.DbConnection = Configs.DbConn CoreApp.UseCdn = types.NewNullBool(os.Getenv("USE_CDN") == "true") @@ -121,7 +127,10 @@ func DefaultPort(db string) int64 { // EnvToConfig converts environment variables to a DbConfig variable func EnvToConfig() *DbConfig { - port := DefaultPort(os.Getenv("DB_PORT")) + port := utils.StringInt(os.Getenv("DB_PORT")) + if port == 0 { + port = DefaultPort(os.Getenv("DB_PORT")) + } name := os.Getenv("NAME") if name == "" { name = "Statup" diff --git a/core/core.go b/core/core.go index c2d059b3..3024eda7 100644 --- a/core/core.go +++ b/core/core.go @@ -17,10 +17,12 @@ package core import ( "errors" + "fmt" "github.com/hunterlong/statup/core/notifier" "github.com/hunterlong/statup/source" "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" + "net" "os" "time" ) @@ -74,7 +76,7 @@ func InsertNotifierDB() error { return errors.New("database connection has not been created") } } - notifier.SetDB(DbSession) + notifier.SetDB(DbSession, CoreApp.Timezone) return nil } @@ -151,6 +153,23 @@ func SelectCore() (*Core, error) { return CoreApp, db.Error } +// GetLocalIP returns the non loopback local IP of the host +func GetLocalIP() string { + addrs, err := net.InterfaceAddrs() + if err != nil { + return "http://localhost" + } + for _, address := range addrs { + // check the address type and if it is not a loopback the display it + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return fmt.Sprintf("http://%v", ipnet.IP.String()) + } + } + } + return "http://localhost" +} + // ServiceOrder will reorder the services based on 'order_id' (Order) type ServiceOrder []types.ServiceInterface diff --git a/core/database.go b/core/database.go index ca7087c3..783ec4a7 100644 --- a/core/database.go +++ b/core/database.go @@ -22,7 +22,6 @@ import ( "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" "github.com/jinzhu/gorm" - _ "github.com/jinzhu/gorm/dialects/mssql" _ "github.com/jinzhu/gorm/dialects/mysql" _ "github.com/jinzhu/gorm/dialects/postgres" _ "github.com/jinzhu/gorm/dialects/sqlite" @@ -33,8 +32,13 @@ import ( var ( // DbSession stores the Statup database session DbSession *gorm.DB + DbModels []interface{} ) +func init() { + DbModels = []interface{}{&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Message{}, &types.Checkin{}, &types.CheckinHit{}, ¬ifier.Notification{}} +} + // DbConfig stores the config.yml file for the statup configuration type DbConfig types.DbConfig @@ -81,7 +85,12 @@ func checkinHitsDB() *gorm.DB { // HitsBetween returns the gorm database query for a collection of service hits between a time range func (s *Service) HitsBetween(t1, t2 time.Time, group string, column string) *gorm.DB { selector := Dbtimestamp(group, column) - return DbSession.Model(&types.Hit{}).Select(selector).Where("service = ? AND created_at BETWEEN ? AND ?", s.Id, t1.UTC().Format(types.TIME_DAY), t2.UTC().Format(types.TIME_DAY)) + if Configs.DbConn == "postgres" { + timeQuery := fmt.Sprintf("service = %v AND created_at BETWEEN '%v.000000' AND '%v.000000'", s.Id, t1.UTC().Format(types.POSTGRES_TIME), t2.UTC().Format(types.POSTGRES_TIME)) + return DbSession.Model(&types.Hit{}).Select(selector).Where(timeQuery) + } else { + return DbSession.Model(&types.Hit{}).Select(selector).Where("service = ? AND created_at BETWEEN ? AND ?", s.Id, t1.UTC().Format(types.TIME_DAY), t2.UTC().Format(types.TIME_DAY)) + } } // CloseDB will close the database connection if available @@ -96,6 +105,13 @@ func (db *DbConfig) Close() error { return DbSession.DB().Close() } +// AfterFind for Core will set the timezone +func (c *Core) AfterFind() (err error) { + c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone) + c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone) + return +} + // AfterFind for Service will set the timezone func (s *Service) AfterFind() (err error) { s.CreatedAt = utils.Timezoner(s.CreatedAt, CoreApp.Timezone) @@ -118,12 +134,14 @@ func (f *failure) AfterFind() (err error) { // AfterFind for USer will set the timezone func (u *User) AfterFind() (err error) { u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone) + u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone) return } // AfterFind for Checkin will set the timezone func (c *Checkin) AfterFind() (err error) { c.CreatedAt = utils.Timezoner(c.CreatedAt, CoreApp.Timezone) + c.UpdatedAt = utils.Timezoner(c.UpdatedAt, CoreApp.Timezone) return } @@ -136,6 +154,9 @@ func (c *checkinHit) AfterFind() (err error) { // AfterFind for Message will set the timezone func (u *Message) AfterFind() (err error) { u.CreatedAt = utils.Timezoner(u.CreatedAt, CoreApp.Timezone) + u.UpdatedAt = utils.Timezoner(u.UpdatedAt, CoreApp.Timezone) + u.StartOn = utils.Timezoner(u.StartOn, CoreApp.Timezone) + u.EndOn = utils.Timezoner(u.EndOn, CoreApp.Timezone) return } @@ -159,6 +180,7 @@ func (f *failure) BeforeCreate() (err error) { func (u *User) BeforeCreate() (err error) { if u.CreatedAt.IsZero() { u.CreatedAt = time.Now().UTC() + u.UpdatedAt = time.Now().UTC() } return } @@ -167,6 +189,7 @@ func (u *User) BeforeCreate() (err error) { func (u *Message) BeforeCreate() (err error) { if u.CreatedAt.IsZero() { u.CreatedAt = time.Now().UTC() + u.UpdatedAt = time.Now().UTC() } return } @@ -232,7 +255,7 @@ func (db *DbConfig) Connect(retry bool, location string) error { host := fmt.Sprintf("%v:%v", Configs.DbHost, Configs.DbPort) conn = fmt.Sprintf("%v:%v@tcp(%v)/%v?charset=utf8&parseTime=True&loc=UTC", Configs.DbUser, Configs.DbPass, host, Configs.DbData) case "postgres": - conn = fmt.Sprintf("host=%v port=%v user=%v dbname=%v password=%v sslmode=disable", Configs.DbHost, Configs.DbPort, Configs.DbUser, Configs.DbData, Configs.DbPass) + conn = fmt.Sprintf("host=%v port=%v user=%v dbname=%v password=%v timezone=UTC sslmode=disable", Configs.DbHost, Configs.DbPort, Configs.DbUser, Configs.DbData, Configs.DbPass) case "mssql": host := fmt.Sprintf("%v:%v", Configs.DbHost, Configs.DbPort) conn = fmt.Sprintf("sqlserver://%v:%v@%v?database=%v", Configs.DbUser, Configs.DbPass, host, Configs.DbData) @@ -343,8 +366,8 @@ func (c *DbConfig) CreateCore() *Core { // DropDatabase will DROP each table Statup created func (db *DbConfig) DropDatabase() error { utils.Log(1, "Dropping Database Tables...") - //err := DbSession.DropTableIfExists("checkins") - err := DbSession.DropTableIfExists("checkin_hits") + err := DbSession.DropTableIfExists("checkins") + err = DbSession.DropTableIfExists("checkin_hits") err = DbSession.DropTableIfExists("notifications") err = DbSession.DropTableIfExists("core") err = DbSession.DropTableIfExists("failures") @@ -357,18 +380,18 @@ func (db *DbConfig) DropDatabase() error { // CreateDatabase will CREATE TABLES for each of the Statup elements func (db *DbConfig) CreateDatabase() error { + var err error utils.Log(1, "Creating Database Tables...") - err := DbSession.CreateTable(&types.Checkin{}) - err = DbSession.CreateTable(&types.CheckinHit{}) - err = DbSession.CreateTable(¬ifier.Notification{}) - err = DbSession.Table("core").CreateTable(&types.Core{}) - err = DbSession.CreateTable(&types.Failure{}) - err = DbSession.CreateTable(&types.Hit{}) - err = DbSession.CreateTable(&types.Service{}) - err = DbSession.CreateTable(&types.User{}) - err = DbSession.CreateTable(&types.Message{}) + for _, table := range DbModels { + if err := DbSession.CreateTable(table); err.Error != nil { + return err.Error + } + } + if err := DbSession.Table("core").CreateTable(&types.Core{}); err.Error != nil { + return err.Error + } utils.Log(1, "Statup Database Created") - return err.Error + return err } // MigrateDatabase will migrate the database structure to current version. @@ -385,8 +408,10 @@ func (db *DbConfig) MigrateDatabase() error { if tx.Error != nil { return tx.Error } - tx = tx.AutoMigrate(&types.Service{}, &types.User{}, &types.Hit{}, &types.Failure{}, &types.Message{}, &types.Checkin{}, &types.CheckinHit{}, ¬ifier.Notification{}).Table("core").AutoMigrate(&types.Core{}) - if tx.Error != nil { + for _, table := range DbModels { + tx = tx.AutoMigrate(table) + } + if err := tx.Table("core").AutoMigrate(&types.Core{}); err.Error != nil { tx.Rollback() utils.Log(3, fmt.Sprintf("Statup Database could not be migrated: %v", tx.Error)) return tx.Error diff --git a/core/hits.go b/core/hits.go index 7ea01b08..e0218c08 100644 --- a/core/hits.go +++ b/core/hits.go @@ -27,9 +27,6 @@ type Hit struct { // CreateHit will create a new 'hit' record in the database for a successful/online service func (s *Service) CreateHit(h *types.Hit) (int64, error) { - if h.CreatedAt.IsZero() { - h.CreatedAt = time.Now().UTC() - } db := hitsDB().Create(&h) if db.Error != nil { utils.Log(2, db.Error) diff --git a/core/notifier/notifiers.go b/core/notifier/notifiers.go index d9638867..1843b419 100644 --- a/core/notifier/notifiers.go +++ b/core/notifier/notifiers.go @@ -31,7 +31,8 @@ var ( // AllCommunications holds all the loaded notifiers AllCommunications []types.AllNotifiers // db holds the Statup database connection - db *gorm.DB + db *gorm.DB + timezone float32 ) // Notification contains all the fields for a Statup Notifier. @@ -89,6 +90,13 @@ type NotificationLog struct { Timestamp time.Time `json:"timestamp"` } +// AfterFind for Notification will set the timezone +func (n *Notification) AfterFind() (err error) { + n.CreatedAt = utils.Timezoner(n.CreatedAt, timezone) + n.UpdatedAt = utils.Timezoner(n.UpdatedAt, timezone) + return +} + // AddQueue will add any type of interface (json, string, struct, etc) into the Notifiers queue func (n *Notification) AddQueue(uid int64, msg interface{}) { data := &QueueData{uid, msg} @@ -106,8 +114,9 @@ func modelDb(n *Notification) *gorm.DB { } // SetDB is called by core to inject the database for a notifier to use -func SetDB(d *gorm.DB) { +func SetDB(d *gorm.DB, zone float32) { db = d + timezone = zone } // asNotification accepts a Notifier and returns a Notification struct @@ -243,6 +252,8 @@ func Init(n Notifier) (*Notification, error) { var notify *Notification if err == nil { notify, _ = SelectNotification(n) + notify.CreatedAt = utils.Timezoner(notify.CreatedAt, timezone) + notify.UpdatedAt = utils.Timezoner(notify.UpdatedAt, timezone) if notify.Delay.Seconds() == 0 { notify.Delay = time.Duration(1 * time.Second) } diff --git a/core/services.go b/core/services.go index 028188e1..6e7bea8e 100644 --- a/core/services.go +++ b/core/services.go @@ -219,12 +219,18 @@ func (s *Service) DowntimeText() string { func Dbtimestamp(group string, column string) string { var seconds int64 switch group { + case "minute": + seconds = 60 case "hour": seconds = 3600 case "day": seconds = 86400 case "week": seconds = 604800 + case "month": + seconds = 2592000 + case "year": + seconds = 31557600 default: seconds = 60 } @@ -271,14 +277,15 @@ func GraphDataRaw(service types.ServiceInterface, start, end time.Time, group st var createdTime time.Time var err error rows.Scan(&createdAt, &value) - createdTime, _ = time.Parse(types.TIME, createdAt) if CoreApp.DbConnection == "postgres" { createdTime, err = time.Parse(types.TIME_NANO, createdAt) if err != nil { utils.Log(4, fmt.Errorf("issue parsing time from database: %v to %v", createdAt, types.TIME_NANO)) } + } else { + createdTime, err = time.Parse(types.TIME, createdAt) } - gd.CreatedAt = utils.Timezoner(createdTime, CoreApp.Timezone).Format(types.TIME) + gd.CreatedAt = utils.Timezoner(createdTime, CoreApp.Timezone).Format(types.CHART_TIME) gd.Value = int64(value * 1000) d = append(d, gd) } diff --git a/handlers/api.go b/handlers/api.go index a383b1c2..9af6b640 100644 --- a/handlers/api.go +++ b/handlers/api.go @@ -83,6 +83,9 @@ func apiServiceDataHandler(w http.ResponseWriter, r *http.Request) { } fields := parseGet(r) grouping := fields.Get("group") + if grouping == "" { + grouping = "hour" + } startField := utils.StringInt(fields.Get("start")) endField := utils.StringInt(fields.Get("end")) diff --git a/handlers/dashboard.go b/handlers/dashboard.go index f18f7f9a..a7f5d8f1 100644 --- a/handlers/dashboard.go +++ b/handlers/dashboard.go @@ -18,7 +18,6 @@ package handlers import ( "bytes" "encoding/json" - "fmt" "github.com/hunterlong/statup/core" "github.com/hunterlong/statup/core/notifier" "github.com/hunterlong/statup/source" @@ -30,7 +29,6 @@ import ( ) func dashboardHandler(w http.ResponseWriter, r *http.Request) { - fmt.Println() if !IsAuthenticated(r) { err := core.ErrorResponse{} executeResponse(w, r, "login.html", err, nil) diff --git a/handlers/services.go b/handlers/services.go index 685ea401..dd5a3985 100644 --- a/handlers/services.go +++ b/handlers/services.go @@ -94,10 +94,10 @@ func servicesViewHandler(w http.ResponseWriter, r *http.Request) { start := end.Add((-24 * 7) * time.Hour).UTC() if startField != 0 { - start = time.Unix(startField, 0) + start = time.Unix(startField, 0).UTC() } if endField != 0 { - end = time.Unix(endField, 0) + end = time.Unix(endField, 0).UTC() } if group == "" { group = "hour" @@ -106,11 +106,13 @@ func servicesViewHandler(w http.ResponseWriter, r *http.Request) { data := core.GraphDataRaw(serv, start, end, group, "latency") out := struct { - Service *core.Service - Start string - End string - Data string - }{serv, start.Format(utils.FlatpickrReadable), end.Format(utils.FlatpickrReadable), data.ToString()} + Service *core.Service + Start string + End string + StartUnix int64 + EndUnix int64 + Data string + }{serv, start.Format(utils.FlatpickrReadable), end.Format(utils.FlatpickrReadable), start.Unix(), end.Unix(), data.ToString()} executeResponse(w, r, "service.html", out, nil) } diff --git a/handlers/setup.go b/handlers/setup.go index ba53b985..0bbb3592 100644 --- a/handlers/setup.go +++ b/handlers/setup.go @@ -29,11 +29,11 @@ func setupHandler(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/", http.StatusSeeOther) return } - w.WriteHeader(http.StatusOK) var data interface{} if os.Getenv("DB_CONN") != "" { data, _ = core.LoadUsingEnv() } + w.WriteHeader(http.StatusOK) executeResponse(w, r, "setup.html", data, nil) } diff --git a/notifiers/notifiers_test.go b/notifiers/notifiers_test.go index 631a8910..4ed7eb38 100644 --- a/notifiers/notifiers_test.go +++ b/notifiers/notifiers_test.go @@ -79,5 +79,5 @@ func injectDatabase() { panic(err) } db.CreateTable(¬ifier.Notification{}) - notifier.SetDB(db) + notifier.SetDB(db, float32(-8)) } diff --git a/source/js/setup.js b/source/js/setup.js index 3407ff3e..f9f4d5cc 100644 --- a/source/js/setup.js +++ b/source/js/setup.js @@ -16,7 +16,10 @@ */ var currentLocation = window.location; -$("#domain_input").val(currentLocation.origin); +var domain = $("#domain_input"); +if (domain.val() === "") { + domain.val(currentLocation.origin); +} $('select#database_type').on('change', function(){ var selected = $('#database_type option:selected').val(); diff --git a/source/source.go b/source/source.go index 7d63f5ca..f50b6d9e 100644 --- a/source/source.go +++ b/source/source.go @@ -21,10 +21,8 @@ import ( "github.com/GeertJohan/go.rice" "github.com/hunterlong/statup/utils" "gopkg.in/russross/blackfriday.v2" - "io" "io/ioutil" "os" - "os/exec" ) var ( @@ -68,31 +66,9 @@ func CompileSASS(folder string) error { utils.Log(1, fmt.Sprintf("Compiling SASS %v into %v", scssFile, baseFile)) command := fmt.Sprintf("%v %v %v", sassBin, scssFile, baseFile) - utils.Log(1, fmt.Sprintf("Command: sh -c %v", command)) + stdout, stderr, err := utils.Command(command) - testCmd := exec.Command("sh", "-c", command) - - var stdout, stderr []byte - var errStdout, errStderr error - stdoutIn, _ := testCmd.StdoutPipe() - stderrIn, _ := testCmd.StderrPipe() - testCmd.Start() - - go func() { - stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn) - }() - - go func() { - stderr, errStderr = copyAndCapture(os.Stderr, stderrIn) - }() - - err := testCmd.Wait() - if err != nil { - utils.Log(3, err) - return err - } - - if errStdout != nil || errStderr != nil { + if stdout != "" || stderr != "" { utils.Log(3, fmt.Sprintf("Failed to compile assets with SASS %v", err)) return errors.New("failed to capture stdout or stderr") } @@ -103,8 +79,7 @@ func CompileSASS(folder string) error { return err } - outStr, errStr := string(stdout), string(stderr) - utils.Log(1, fmt.Sprintf("out: %v | error: %v", outStr, errStr)) + utils.Log(1, fmt.Sprintf("out: %v | error: %v", stdout, stderr)) utils.Log(1, "SASS Compiling is complete!") return nil } @@ -239,27 +214,3 @@ func MakePublicFolder(folder string) error { } return nil } - -// copyAndCapture captures the response from a terminal command -func copyAndCapture(w io.Writer, r io.Reader) ([]byte, error) { - var out []byte - buf := make([]byte, 1024, 1024) - for { - n, err := r.Read(buf[:]) - if n > 0 { - d := buf[:n] - out = append(out, d...) - _, err := w.Write(d) - if err != nil { - return out, err - } - } - if err != nil { - // Read returns io.EOF at the end of file, which is not an error for us - if err == io.EOF { - err = nil - } - return out, err - } - } -} diff --git a/source/tmpl/service.html b/source/tmpl/service.html index ee2dac3c..c5cd33fd 100644 --- a/source/tmpl/service.html +++ b/source/tmpl/service.html @@ -225,7 +225,7 @@ $(document).ready(function() { } }); - AjaxChart(chartdata,{{$s.Id}},{{.Start}},{{.End}},"hour"); + AjaxChart(chartdata,{{$s.Id}},{{.StartUnix}},{{.EndUnix}},"hour"); let startDate = $("#service_start").flatpickr({ enableTime: false, diff --git a/types/time.go b/types/time.go index a9f07212..709d5a45 100644 --- a/types/time.go +++ b/types/time.go @@ -20,9 +20,11 @@ import ( ) const ( - TIME_NANO = "2006-01-02T15:04:05Z" - TIME = "2006-01-02 15:04:05" - TIME_DAY = "2006-01-02" + TIME_NANO = "2006-01-02T15:04:05Z" + TIME = "2006-01-02 15:04:05" + POSTGRES_TIME = "2006-01-02 15:04" + CHART_TIME = "2006-01-02T15:04:05.999999-07:00" + TIME_DAY = "2006-01-02" ) var ( diff --git a/types/types.go b/types/types.go index 21664322..c3de7e2b 100644 --- a/types/types.go +++ b/types/types.go @@ -46,4 +46,5 @@ type DbConfig struct { Email string `yaml:"-"` Error error `yaml:"-"` Location string `yaml:"location"` + LocalIP string `yaml:"-"` } diff --git a/utils/time.go b/utils/time.go index c365f693..af083664 100644 --- a/utils/time.go +++ b/utils/time.go @@ -26,6 +26,14 @@ const ( FlatpickrReadable = "Mon, 02 Jan 2006" ) +// Timezoner returns the time.Time with the user set timezone +func Timezoner(t time.Time, zone float32) time.Time { + zoneInt := float32(3600) * zone + loc := time.FixedZone("", int(zoneInt)) + timez := t.In(loc) + return timez +} + // FormatDuration converts a time.Duration into a string func FormatDuration(d time.Duration) string { var out string diff --git a/utils/utils.go b/utils/utils.go index c963544a..28b6a271 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -68,14 +68,6 @@ func ToString(s interface{}) string { } } -// Timezoner returns the time.Time with the user set timezone -func Timezoner(t time.Time, zone float32) time.Time { - zoneInt := float32(3600) * (zone + 1) - loc := time.FixedZone("", int(zoneInt)) - timez := t.In(loc) - return timez -} - // dir returns the current working directory func dir() string { dir, err := os.Getwd() diff --git a/utils/utils_test.go b/utils/utils_test.go index cee6c2a7..64cf28a1 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -125,7 +125,7 @@ func TestTimezone(t *testing.T) { timestamp := time.Date(2018, 1, 1, 10, 0, 0, 0, loc) timezone := Timezoner(timestamp, zone) assert.Equal(t, "2018-01-01 10:00:00 -0800 PST", timestamp.String()) - assert.Equal(t, "2018-01-01 15:00:00 -0300 -0300", timezone.String()) + assert.Equal(t, "2018-01-01 18:00:00 +0000 UTC", timezone.UTC().String()) } func TestTimestamp_Ago(t *testing.T) {