mirror of https://github.com/statping/statping
JSON fixes - timestamp fixes
parent
4777b94851
commit
7da863c58b
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
VERSION=0.79
|
VERSION=0.79.1
|
||||||
BINARY_NAME=statup
|
BINARY_NAME=statup
|
||||||
GOPATH:=$(GOPATH)
|
GOPATH:=$(GOPATH)
|
||||||
GOCMD=go
|
GOCMD=go
|
||||||
|
|
|
@ -27,7 +27,9 @@ type Hit struct {
|
||||||
|
|
||||||
// CreateHit will create a new 'hit' record in the database for a successful/online service
|
// CreateHit will create a new 'hit' record in the database for a successful/online service
|
||||||
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
|
func (s *Service) CreateHit(h *types.Hit) (int64, error) {
|
||||||
|
if h.CreatedAt.IsZero() {
|
||||||
h.CreatedAt = time.Now().UTC()
|
h.CreatedAt = time.Now().UTC()
|
||||||
|
}
|
||||||
db := hitsDB().Create(&h)
|
db := hitsDB().Create(&h)
|
||||||
if db.Error != nil {
|
if db.Error != nil {
|
||||||
utils.Log(2, db.Error)
|
utils.Log(2, db.Error)
|
||||||
|
|
|
@ -342,6 +342,8 @@ func apiNotifierGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
fmt.Println(notify)
|
fmt.Println(notify)
|
||||||
fmt.Println(notifierObj)
|
fmt.Println(notifierObj)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(notify)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isAPIAuthorized(r *http.Request) bool {
|
func isAPIAuthorized(r *http.Request) bool {
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hunterlong/statup/core"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var storage Cacher
|
var CacheStorage Cacher
|
||||||
|
|
||||||
type Cacher interface {
|
type Cacher interface {
|
||||||
Get(key string) []byte
|
Get(key string) []byte
|
||||||
|
Delete(key string)
|
||||||
Set(key string, content []byte, duration time.Duration)
|
Set(key string, content []byte, duration time.Duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +36,7 @@ type Storage struct {
|
||||||
mu *sync.RWMutex
|
mu *sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewStorage creates a new in memory storage
|
//NewStorage creates a new in memory CacheStorage
|
||||||
func NewStorage() *Storage {
|
func NewStorage() *Storage {
|
||||||
return &Storage{
|
return &Storage{
|
||||||
items: make(map[string]Item),
|
items: make(map[string]Item),
|
||||||
|
@ -55,6 +57,12 @@ func (s Storage) Get(key string) []byte {
|
||||||
return item.Content
|
return item.Content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Storage) Delete(key string) {
|
||||||
|
s.mu.RLock()
|
||||||
|
defer s.mu.RUnlock()
|
||||||
|
delete(s.items, key)
|
||||||
|
}
|
||||||
|
|
||||||
//Set a cached content by key
|
//Set a cached content by key
|
||||||
func (s Storage) Set(key string, content []byte, duration time.Duration) {
|
func (s Storage) Set(key string, content []byte, duration time.Duration) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
|
@ -67,17 +75,20 @@ func (s Storage) Set(key string, content []byte, duration time.Duration) {
|
||||||
|
|
||||||
func cached(duration, contentType string, handler func(w http.ResponseWriter, r *http.Request)) http.Handler {
|
func cached(duration, contentType string, handler func(w http.ResponseWriter, r *http.Request)) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
content := storage.Get(r.RequestURI)
|
content := CacheStorage.Get(r.RequestURI)
|
||||||
if content != nil {
|
|
||||||
w.Header().Set("Content-Type", contentType)
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
if core.Configs == nil {
|
||||||
|
handler(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if content != nil {
|
||||||
w.Write(content)
|
w.Write(content)
|
||||||
} else {
|
} else {
|
||||||
c := httptest.NewRecorder()
|
c := httptest.NewRecorder()
|
||||||
handler(c, r)
|
handler(c, r)
|
||||||
w.Header().Set("Content-Type", contentType)
|
|
||||||
content := c.Body.Bytes()
|
content := c.Body.Bytes()
|
||||||
if d, err := time.ParseDuration(duration); err == nil {
|
if d, err := time.ParseDuration(duration); err == nil {
|
||||||
storage.Set(r.RequestURI, content, d)
|
CacheStorage.Set(r.RequestURI, content, d)
|
||||||
}
|
}
|
||||||
w.Write(content)
|
w.Write(content)
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,9 @@ var (
|
||||||
// Router returns all of the routes used in Statup
|
// Router returns all of the routes used in Statup
|
||||||
func Router() *mux.Router {
|
func Router() *mux.Router {
|
||||||
dir := utils.Directory
|
dir := utils.Directory
|
||||||
storage = NewStorage()
|
CacheStorage = NewStorage()
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.Handle("/", http.HandlerFunc(indexHandler))
|
r.Handle("/", cached("120s", "text/html", http.HandlerFunc(indexHandler)))
|
||||||
if source.UsingAssets(dir) {
|
if source.UsingAssets(dir) {
|
||||||
indexHandler := http.FileServer(http.Dir(dir + "/assets/"))
|
indexHandler := http.FileServer(http.Dir(dir + "/assets/"))
|
||||||
r.PathPrefix("/css/").Handler(http.StripPrefix("/font/", http.FileServer(http.Dir(dir+"/assets/font"))))
|
r.PathPrefix("/css/").Handler(http.StripPrefix("/font/", http.FileServer(http.Dir(dir+"/assets/font"))))
|
||||||
|
@ -93,6 +93,10 @@ func Router() *mux.Router {
|
||||||
r.Handle("/checkin/{id}/delete", http.HandlerFunc(checkinDeleteHandler)).Methods("GET")
|
r.Handle("/checkin/{id}/delete", http.HandlerFunc(checkinDeleteHandler)).Methods("GET")
|
||||||
r.Handle("/checkin/{id}", http.HandlerFunc(checkinHitHandler))
|
r.Handle("/checkin/{id}", http.HandlerFunc(checkinHitHandler))
|
||||||
|
|
||||||
|
// API Routes
|
||||||
|
r.Handle("/api", http.HandlerFunc(apiIndexHandler))
|
||||||
|
r.Handle("/api/renew", http.HandlerFunc(apiRenewHandler))
|
||||||
|
|
||||||
// API SERVICE Routes
|
// API SERVICE Routes
|
||||||
r.Handle("/api/services", http.HandlerFunc(apiAllServicesHandler)).Methods("GET")
|
r.Handle("/api/services", http.HandlerFunc(apiAllServicesHandler)).Methods("GET")
|
||||||
r.Handle("/api/services", http.HandlerFunc(apiCreateServiceHandler)).Methods("POST")
|
r.Handle("/api/services", http.HandlerFunc(apiCreateServiceHandler)).Methods("POST")
|
||||||
|
@ -101,6 +105,7 @@ func Router() *mux.Router {
|
||||||
r.Handle("/api/services/{id}/ping", http.HandlerFunc(apiServicePingDataHandler)).Methods("GET")
|
r.Handle("/api/services/{id}/ping", http.HandlerFunc(apiServicePingDataHandler)).Methods("GET")
|
||||||
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
|
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
|
||||||
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")
|
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")
|
||||||
|
r.Handle("/api/checkin/{api}", http.HandlerFunc(apiCheckinHandler))
|
||||||
|
|
||||||
// API USER Routes
|
// API USER Routes
|
||||||
r.Handle("/api/users", http.HandlerFunc(apiAllUsersHandler)).Methods("GET")
|
r.Handle("/api/users", http.HandlerFunc(apiAllUsersHandler)).Methods("GET")
|
||||||
|
@ -113,10 +118,6 @@ func Router() *mux.Router {
|
||||||
r.Handle("/api/notifier/{notifier}", http.HandlerFunc(apiNotifierGetHandler)).Methods("GET")
|
r.Handle("/api/notifier/{notifier}", http.HandlerFunc(apiNotifierGetHandler)).Methods("GET")
|
||||||
r.Handle("/api/notifier/{notifier}", http.HandlerFunc(apiNotifierGetHandler)).Methods("POST")
|
r.Handle("/api/notifier/{notifier}", http.HandlerFunc(apiNotifierGetHandler)).Methods("POST")
|
||||||
|
|
||||||
// Generic API Routes
|
|
||||||
r.Handle("/api", http.HandlerFunc(apiIndexHandler))
|
|
||||||
r.Handle("/api/renew", http.HandlerFunc(apiRenewHandler))
|
|
||||||
r.Handle("/api/checkin/{api}", http.HandlerFunc(apiCheckinHandler))
|
|
||||||
r.Handle("/metrics", http.HandlerFunc(prometheusHandler))
|
r.Handle("/metrics", http.HandlerFunc(prometheusHandler))
|
||||||
r.Handle("/tray", http.HandlerFunc(trayHandler))
|
r.Handle("/tray", http.HandlerFunc(trayHandler))
|
||||||
r.NotFoundHandler = http.HandlerFunc(error404Handler)
|
r.NotFoundHandler = http.HandlerFunc(error404Handler)
|
||||||
|
|
|
@ -119,6 +119,7 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
core.SampleData()
|
core.SampleData()
|
||||||
core.InitApp()
|
core.InitApp()
|
||||||
|
CacheStorage.Delete("/")
|
||||||
resetCookies()
|
resetCookies()
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
|
|
|
@ -109,6 +109,8 @@
|
||||||
<input type="text" class="form-control select-input" value="{{ .ApiSecret }}" id="api_secret" readonly>
|
<input type="text" class="form-control select-input" value="{{ .ApiSecret }}" id="api_secret" readonly>
|
||||||
<small class="form-text text-muted">You can <a href="/api/renew">Regenerate API Keys</a> if you need to.</small>
|
<small class="form-text text-muted">You can <a href="/api/renew">Regenerate API Keys</a> if you need to.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<img width="300" height="300" src="https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=http://statup://setup?domain={{ .Domain }}&api={{ .ApiKey }}&secret={{ .ApiSecret }}&choe=UTF-8">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
Loading…
Reference in New Issue