mirror of https://github.com/statping/statping
notifier - moved core
parent
949ba3958a
commit
d0ad55488d
14
cli.go
14
cli.go
|
@ -4,7 +4,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/plugin"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/joho/godotenv"
|
||||
|
@ -106,9 +105,8 @@ func RunOnce() {
|
|||
if err != nil {
|
||||
utils.Log(4, err)
|
||||
}
|
||||
for _, ser := range core.CoreApp.Services {
|
||||
s := ser.ToService()
|
||||
out := core.ServiceCheck(s)
|
||||
for _, s := range core.CoreApp.Services {
|
||||
out := core.ServiceCheck(s.ToService())
|
||||
fmt.Printf(" Service %v | URL: %v | Latency: %0.0fms | Online: %v\n", out.Name, out.Domain, (out.Latency * 1000), out.Online)
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +127,7 @@ func HelpEcho() {
|
|||
fmt.Println("Give Statup a Star at https://github.com/hunterlong/statup")
|
||||
}
|
||||
|
||||
func TestPlugin(plug plugin.PluginActions) {
|
||||
func TestPlugin(plug types.PluginActions) {
|
||||
defer utils.DeleteFile("./.plugin_test.db")
|
||||
RenderBoxes()
|
||||
|
||||
|
@ -160,7 +158,7 @@ func TestPlugin(plug plugin.PluginActions) {
|
|||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnSettingsSaved(Core)'")
|
||||
fmt.Println(BRAKER)
|
||||
core.OnSettingsSaved(core.CoreApp)
|
||||
core.OnSettingsSaved(core.CoreApp.ToCore())
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnNewService(Service)'")
|
||||
core.OnNewService(core.SelectService(2).ToService())
|
||||
|
@ -180,11 +178,11 @@ func TestPlugin(plug plugin.PluginActions) {
|
|||
fmt.Println("\n" + BRAKER)
|
||||
}
|
||||
|
||||
func FakeSeed(plug plugin.PluginActions) {
|
||||
func FakeSeed(plug types.PluginActions) {
|
||||
var err error
|
||||
core.CoreApp = core.NewCore()
|
||||
|
||||
core.CoreApp.AllPlugins = []plugin.PluginActions{plug}
|
||||
core.CoreApp.AllPlugins = []types.PluginActions{plug}
|
||||
|
||||
fmt.Printf("\n" + BRAKER)
|
||||
|
||||
|
|
|
@ -20,10 +20,9 @@ func CheckServices() {
|
|||
utils.Log(1, fmt.Sprintf("Starting monitoring process for %v Services", len(CoreApp.Services)))
|
||||
for _, ser := range CoreApp.Services {
|
||||
s := ser.ToService()
|
||||
obj := s
|
||||
//go obj.StartCheckins()
|
||||
obj.StopRoutine = make(chan struct{})
|
||||
go CheckQueue(obj)
|
||||
s.StopRoutine = make(chan struct{})
|
||||
go CheckQueue(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ func (c *Checkin) String() string {
|
|||
|
||||
func FindCheckin(api string) *types.Checkin {
|
||||
for _, ser := range CoreApp.Services {
|
||||
s := ser.ToService()
|
||||
for _, c := range s.Checkins {
|
||||
for _, c := range ser.ToService().Checkins {
|
||||
if c.Api == api {
|
||||
return c
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ func LoadUsingEnv() (*types.Config, error) {
|
|||
DropDatabase()
|
||||
CreateDatabase()
|
||||
|
||||
CoreApp = &Core{
|
||||
CoreApp = &Core{Core: &types.Core{
|
||||
Name: dbConfig.Project,
|
||||
Description: dbConfig.Description,
|
||||
Config: "config.yml",
|
||||
|
@ -93,11 +93,11 @@ func LoadUsingEnv() (*types.Config, error) {
|
|||
ApiSecret: utils.NewSHA1Hash(16),
|
||||
Domain: dbConfig.Domain,
|
||||
MigrationId: time.Now().Unix(),
|
||||
}
|
||||
}}
|
||||
|
||||
CoreApp.DbConnection = dbConfig.DbConn
|
||||
|
||||
err := CoreApp.Insert()
|
||||
err := InsertCore(CoreApp)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
|
|
43
core/core.go
43
core/core.go
|
@ -3,7 +3,6 @@ package core
|
|||
import (
|
||||
"github.com/GeertJohan/go.rice"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/plugin"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/pkg/errors"
|
||||
"os"
|
||||
|
@ -14,24 +13,8 @@ type PluginJSON types.PluginJSON
|
|||
type PluginRepos types.PluginRepos
|
||||
|
||||
type Core struct {
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"name"`
|
||||
Config string `db:"config" json:"-"`
|
||||
ApiKey string `db:"api_key" json:"-"`
|
||||
ApiSecret string `db:"api_secret" json:"-"`
|
||||
Style string `db:"style" json:"-"`
|
||||
Footer string `db:"footer" json:"-"`
|
||||
Domain string `db:"domain" json:"domain,omitempty"`
|
||||
Version string `db:"version" json:"version,omitempty"`
|
||||
MigrationId int64 `db:"migration_id" json:"-"`
|
||||
UseCdn bool `db:"use_cdn" json:"-"`
|
||||
Services []*Service `json:"services,omitempty"`
|
||||
Plugins []plugin.Info
|
||||
Repos []PluginJSON
|
||||
AllPlugins []plugin.PluginActions
|
||||
Communications []notifiers.AllNotifiers
|
||||
DbConnection string
|
||||
started time.Time
|
||||
*types.Core
|
||||
Services []*Service
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -53,16 +36,21 @@ func init() {
|
|||
|
||||
func NewCore() *Core {
|
||||
CoreApp = new(Core)
|
||||
CoreApp.started = time.Now()
|
||||
CoreApp.Core = new(types.Core)
|
||||
CoreApp.Started = time.Now()
|
||||
return CoreApp
|
||||
}
|
||||
|
||||
func (c *Core) Insert() error {
|
||||
func InsertCore(c *Core) error {
|
||||
col := DbSession.Collection("core")
|
||||
_, err := col.Insert(c)
|
||||
_, err := col.Insert(c.Core)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Core) ToCore() *types.Core {
|
||||
return c.Core
|
||||
}
|
||||
|
||||
func InitApp() {
|
||||
SelectCore()
|
||||
notifiers.Collections = DbSession.Collection("communication")
|
||||
|
@ -72,9 +60,9 @@ func InitApp() {
|
|||
go DatabaseMaintence()
|
||||
}
|
||||
|
||||
func (c *Core) Update() (*Core, error) {
|
||||
func UpdateCore(c *Core) (*Core, error) {
|
||||
res := DbSession.Collection("core").Find().Limit(1)
|
||||
err := res.Update(c)
|
||||
err := res.Update(c.Core)
|
||||
return c, err
|
||||
}
|
||||
|
||||
|
@ -114,7 +102,7 @@ func (c Core) AllOnline() bool {
|
|||
}
|
||||
|
||||
func SelectLastMigration() (int64, error) {
|
||||
var c *Core
|
||||
var c *types.Core
|
||||
if DbSession == nil {
|
||||
return 0, errors.New("Database connection has not been created yet")
|
||||
}
|
||||
|
@ -126,17 +114,16 @@ func SelectLastMigration() (int64, error) {
|
|||
}
|
||||
|
||||
func SelectCore() (*Core, error) {
|
||||
var c *Core
|
||||
var c *types.Core
|
||||
exists := DbSession.Collection("core").Exists()
|
||||
if !exists {
|
||||
return nil, errors.New("core database has not been setup yet.")
|
||||
}
|
||||
|
||||
err := DbSession.Collection("core").Find().One(&c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
CoreApp = c
|
||||
CoreApp.Core = c
|
||||
CoreApp.DbConnection = Configs.Connection
|
||||
CoreApp.Version = VERSION
|
||||
CoreApp.Services, _ = SelectAllServices()
|
||||
|
|
|
@ -119,7 +119,7 @@ func (c *DbConfig) Save() error {
|
|||
DropDatabase()
|
||||
CreateDatabase()
|
||||
|
||||
newCore := &Core{
|
||||
newCore := &types.Core{
|
||||
Name: c.Project,
|
||||
Description: c.Description,
|
||||
Config: "config.yml",
|
||||
|
@ -131,7 +131,7 @@ func (c *DbConfig) Save() error {
|
|||
col := DbSession.Collection("core")
|
||||
_, err = col.Insert(newCore)
|
||||
if err == nil {
|
||||
CoreApp = newCore
|
||||
CoreApp = &Core{Core: newCore}
|
||||
}
|
||||
|
||||
CoreApp, err = SelectCore()
|
||||
|
@ -204,7 +204,7 @@ func RunDatabaseUpgrades() error {
|
|||
panic(err)
|
||||
}
|
||||
CoreApp.MigrationId = currentMigration
|
||||
CoreApp.Update()
|
||||
UpdateCore(CoreApp)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package core
|
|||
import (
|
||||
"github.com/fatih/structs"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/plugin"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"upper.io/db.v3/lib/sqlbuilder"
|
||||
)
|
||||
|
@ -28,7 +27,7 @@ func OnFailure(s *types.Service, f FailureData) {
|
|||
notifiers.OnFailure(s)
|
||||
}
|
||||
|
||||
func OnSettingsSaved(c *Core) {
|
||||
func OnSettingsSaved(c *types.Core) {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnSettingsSaved(structs.Map(c))
|
||||
}
|
||||
|
@ -58,11 +57,11 @@ func OnUpdateService(s *types.Service) {
|
|||
}
|
||||
}
|
||||
|
||||
func SelectPlugin(name string) plugin.PluginActions {
|
||||
func SelectPlugin(name string) types.PluginActions {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
if p.GetInfo().Name == name {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return plugin.PluginInfo{}
|
||||
return types.PluginInfo{}
|
||||
}
|
||||
|
|
|
@ -46,12 +46,16 @@ func DeleteFailures(u *types.Service) {
|
|||
}
|
||||
}
|
||||
|
||||
func (ser *Service) LimitedFailures() []*types.Failure {
|
||||
func (ser *Service) LimitedFailures() []*Failure {
|
||||
s := ser.ToService()
|
||||
var fails []*types.Failure
|
||||
var failArr []*Failure
|
||||
col := DbSession.Collection("failures").Find("service", s.Id).OrderBy("-id").Limit(10)
|
||||
col.All(&fails)
|
||||
return fails
|
||||
for _, f := range fails {
|
||||
failArr = append(failArr, MakeFailure(f))
|
||||
}
|
||||
return failArr
|
||||
}
|
||||
|
||||
func reverseFailures(input []*types.Failure) []*types.Failure {
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
type Service struct {
|
||||
S interface{}
|
||||
s *types.Service
|
||||
}
|
||||
|
||||
type Failure struct {
|
||||
|
@ -23,10 +23,10 @@ func serviceCol() db.Collection {
|
|||
}
|
||||
|
||||
func SelectService(id int64) *Service {
|
||||
for _, ser := range CoreApp.Services {
|
||||
s := ser.ToService()
|
||||
if s.Id == id {
|
||||
return ser
|
||||
for _, s := range CoreApp.Services {
|
||||
ser := s.ToService()
|
||||
if ser.Id == id {
|
||||
return &Service{ser}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -64,7 +64,7 @@ func (s *Service) AvgTime() float64 {
|
|||
}
|
||||
|
||||
func (ser *Service) Online24() float32 {
|
||||
s := ser.S.(*types.Service)
|
||||
s := ser.ToService()
|
||||
total, _ := ser.TotalHits()
|
||||
failed, _ := ser.TotalFailures24Hours()
|
||||
if failed == 0 {
|
||||
|
@ -91,12 +91,11 @@ type DateScan struct {
|
|||
}
|
||||
|
||||
func (s *Service) ToService() *types.Service {
|
||||
return s.S.(*types.Service)
|
||||
return s.s
|
||||
}
|
||||
|
||||
func NewService(s *types.Service) *Service {
|
||||
ser := &Service{s}
|
||||
return ser
|
||||
return &Service{s}
|
||||
}
|
||||
|
||||
func (ser *Service) SmallText() string {
|
||||
|
@ -105,8 +104,8 @@ func (ser *Service) SmallText() string {
|
|||
hits, _ := ser.LimitedHits()
|
||||
if !s.Online {
|
||||
if len(last) > 0 {
|
||||
lastFailure := MakeFailure(last[0])
|
||||
return fmt.Sprintf("%v on %v", lastFailure.ParseError(), last[0].CreatedAt.Format("Monday 3:04PM, Jan _2 2006"))
|
||||
lastFailure := MakeFailure(last[0].ToFailure())
|
||||
return fmt.Sprintf("%v on %v", lastFailure.ParseError(), last[0].ToFailure().CreatedAt.Format("Monday 3:04PM, Jan _2 2006"))
|
||||
} else {
|
||||
return fmt.Sprintf("%v is currently offline", s.Name)
|
||||
}
|
||||
|
@ -194,10 +193,10 @@ func (ser *Service) AvgUptime() string {
|
|||
|
||||
func RemoveArray(u *types.Service) []*Service {
|
||||
var srvcs []*Service
|
||||
for _, ser := range CoreApp.Services {
|
||||
s := ser.ToService()
|
||||
if s.Id != u.Id {
|
||||
srvcs = append(srvcs, ser)
|
||||
for _, s := range CoreApp.Services {
|
||||
ser := s.ToService()
|
||||
if ser.Id != u.Id {
|
||||
srvcs = append(srvcs, s)
|
||||
}
|
||||
}
|
||||
CoreApp.Services = srvcs
|
||||
|
@ -241,16 +240,15 @@ func CreateService(u *types.Service) (int64, error) {
|
|||
}
|
||||
u.Id = uuid.(int64)
|
||||
u.StopRoutine = make(chan struct{})
|
||||
nn := &Service{u}
|
||||
CoreApp.Services = append(CoreApp.Services, nn)
|
||||
CoreApp.Services = append(CoreApp.Services, &Service{u})
|
||||
return uuid.(int64), err
|
||||
}
|
||||
|
||||
func CountOnline() int {
|
||||
amount := 0
|
||||
for _, ser := range CoreApp.Services {
|
||||
s := ser.ToService()
|
||||
if s.Online {
|
||||
for _, s := range CoreApp.Services {
|
||||
ser := s.ToService()
|
||||
if ser.Online {
|
||||
amount++
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,21 @@ func ApiIndexHandler(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(core.CoreApp)
|
||||
}
|
||||
|
||||
func ApiRenewHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !isAPIAuthorized(r) {
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
var err error
|
||||
core.CoreApp.ApiKey = utils.NewSHA1Hash(40)
|
||||
core.CoreApp.ApiSecret = utils.NewSHA1Hash(40)
|
||||
core.CoreApp, err = core.UpdateCore(core.CoreApp)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
http.Redirect(w, r, "/settings", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func ApiCheckinHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !isAPIAuthorized(r) {
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
|
|
|
@ -33,7 +33,7 @@ func Router() *mux.Router {
|
|||
r.Handle("/user/{id}", http.HandlerFunc(UsersEditHandler)).Methods("GET")
|
||||
r.Handle("/user/{id}", http.HandlerFunc(UpdateUserHandler)).Methods("POST")
|
||||
r.Handle("/user/{id}/delete", http.HandlerFunc(UsersDeleteHandler)).Methods("GET")
|
||||
r.Handle("/settings", http.HandlerFunc(PluginsHandler)).Methods("GET")
|
||||
r.Handle("/settings", http.HandlerFunc(SettingsHandler)).Methods("GET")
|
||||
r.Handle("/settings", http.HandlerFunc(SaveSettingsHandler)).Methods("POST")
|
||||
r.Handle("/settings/css", http.HandlerFunc(SaveSASSHandler)).Methods("POST")
|
||||
r.Handle("/settings/build", http.HandlerFunc(SaveAssetsHandler)).Methods("GET")
|
||||
|
@ -42,6 +42,7 @@ func Router() *mux.Router {
|
|||
r.Handle("/plugins/{name}/save", http.HandlerFunc(PluginSavedHandler)).Methods("POST")
|
||||
r.Handle("/help", http.HandlerFunc(HelpHandler))
|
||||
r.Handle("/api", http.HandlerFunc(ApiIndexHandler))
|
||||
r.Handle("/api/renew", http.HandlerFunc(ApiRenewHandler))
|
||||
r.Handle("/api/checkin/{api}", http.HandlerFunc(ApiCheckinHandler))
|
||||
r.Handle("/api/services", http.HandlerFunc(ApiAllServicesHandler))
|
||||
r.Handle("/api/services/{id}", http.HandlerFunc(ApiServiceHandler)).Methods("GET")
|
||||
|
|
|
@ -78,6 +78,9 @@ func ServicesDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
|||
func ServicesViewHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
serv := core.SelectService(utils.StringInt(vars["id"]))
|
||||
|
||||
fmt.Println(serv.ToService())
|
||||
|
||||
ExecuteResponse(w, r, "service.html", serv)
|
||||
}
|
||||
|
||||
|
@ -94,9 +97,7 @@ func ServicesBadgeHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
|
||||
w.Write(badge)
|
||||
|
||||
}
|
||||
|
||||
func ServicesUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -9,23 +9,11 @@ import (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
func PluginsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
func SettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsAuthenticated(r) {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
//CoreApp.FetchPluginRepo()
|
||||
|
||||
//var pluginFields []PluginSelect
|
||||
//
|
||||
//for _, p := range allPlugins {
|
||||
// fields := structs.Map(p.GetInfo())
|
||||
//
|
||||
// pluginFields = append(pluginFields, PluginSelect{p.GetInfo().Name, p.GetForm(), fields})
|
||||
//}
|
||||
|
||||
//CoreApp.PluginFields = pluginFields
|
||||
|
||||
ExecuteResponse(w, r, "settings.html", core.CoreApp)
|
||||
}
|
||||
|
||||
|
@ -56,8 +44,8 @@ func SaveSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
core.CoreApp.Domain = domain
|
||||
}
|
||||
core.CoreApp.UseCdn = (r.PostForm.Get("enable_cdn") == "on")
|
||||
core.CoreApp.Update()
|
||||
core.OnSettingsSaved(core.CoreApp)
|
||||
core.CoreApp, _ = core.UpdateCore(core.CoreApp)
|
||||
core.OnSettingsSaved(core.CoreApp.ToCore())
|
||||
http.Redirect(w, r, "/settings", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
@ -105,8 +93,8 @@ func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) {
|
|||
var2 := r.PostForm.Get("var2")
|
||||
apiKey := r.PostForm.Get("api_key")
|
||||
apiSecret := r.PostForm.Get("api_secret")
|
||||
limits := int64(utils.StringInt(r.PostForm.Get("limits")))
|
||||
notifer := notifiers.Select(utils.StringInt(notifierId))
|
||||
limits := int(utils.StringInt(r.PostForm.Get("limits")))
|
||||
notifer := notifiers.SelectNotifier(utils.StringInt(notifierId)).Select()
|
||||
|
||||
if host != "" {
|
||||
notifer.Host = host
|
||||
|
|
6
main.go
6
main.go
|
@ -6,7 +6,7 @@ import (
|
|||
"github.com/fatih/structs"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/handlers"
|
||||
"github.com/hunterlong/statup/plugin"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/joho/godotenv"
|
||||
"io/ioutil"
|
||||
|
@ -123,8 +123,8 @@ func LoadPlugins(debug bool) {
|
|||
utils.Log(1, structs.Map(symPlugin))
|
||||
}
|
||||
|
||||
var plugActions plugin.PluginActions
|
||||
plugActions, ok := symPlugin.(plugin.PluginActions)
|
||||
var plugActions types.PluginActions
|
||||
plugActions, ok := symPlugin.(types.PluginActions)
|
||||
if !ok {
|
||||
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
|
||||
if debug {
|
||||
|
|
|
@ -20,7 +20,7 @@ const (
|
|||
var (
|
||||
emailer *Email
|
||||
emailArray []string
|
||||
emailQueue []*types.Email
|
||||
emailQueue []*EmailOutgoing
|
||||
emailBox *rice.Box
|
||||
mailer *gomail.Dialer
|
||||
)
|
||||
|
@ -37,41 +37,35 @@ func init() {
|
|||
Id: EMAIL_ID,
|
||||
Method: EMAIL_METHOD,
|
||||
Form: []NotificationForm{{
|
||||
id: 1,
|
||||
Id: 1,
|
||||
Type: "text",
|
||||
Title: "SMTP Host",
|
||||
Placeholder: "Insert your SMTP Host here.",
|
||||
DbField: "Host",
|
||||
}, {
|
||||
id: 1,
|
||||
Id: 1,
|
||||
Type: "text",
|
||||
Title: "SMTP Username",
|
||||
Placeholder: "Insert your SMTP Username here.",
|
||||
DbField: "Username",
|
||||
}, {
|
||||
id: 1,
|
||||
Id: 1,
|
||||
Type: "password",
|
||||
Title: "SMTP Password",
|
||||
Placeholder: "Insert your SMTP Password here.",
|
||||
DbField: "Password",
|
||||
}, {
|
||||
id: 1,
|
||||
Id: 1,
|
||||
Type: "number",
|
||||
Title: "SMTP Port",
|
||||
Placeholder: "Insert your SMTP Port here.",
|
||||
DbField: "Port",
|
||||
}, {
|
||||
id: 1,
|
||||
Id: 1,
|
||||
Type: "text",
|
||||
Title: "Outgoing Email Address",
|
||||
Placeholder: "Insert your Outgoing Email Address",
|
||||
DbField: "Var1",
|
||||
}, {
|
||||
id: 1,
|
||||
Type: "number",
|
||||
Title: "Limits per Hour",
|
||||
Placeholder: "How many emails can it send per hour",
|
||||
DbField: "Limits",
|
||||
}},
|
||||
}}
|
||||
|
||||
|
@ -108,7 +102,7 @@ func (u *Email) Init() error {
|
|||
|
||||
func (u *Email) Test() error {
|
||||
if u.Enabled {
|
||||
email := &types.Email{
|
||||
email := &EmailOutgoing{
|
||||
To: "info@socialeck.com",
|
||||
Subject: "Test Email",
|
||||
Template: "message.html",
|
||||
|
@ -124,6 +118,16 @@ type emailMessage struct {
|
|||
Service *types.Service
|
||||
}
|
||||
|
||||
type EmailOutgoing struct {
|
||||
To string
|
||||
Subject string
|
||||
Template string
|
||||
From string
|
||||
Data interface{}
|
||||
Source string
|
||||
Sent bool
|
||||
}
|
||||
|
||||
// AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS
|
||||
func (u *Email) Run() error {
|
||||
var sentAddresses []string
|
||||
|
@ -132,16 +136,18 @@ func (u *Email) Run() error {
|
|||
emailQueue = removeEmail(emailQueue, email)
|
||||
continue
|
||||
}
|
||||
e := email
|
||||
go func(email *types.Email) {
|
||||
if u.CanSend() {
|
||||
err := u.dialSend(email)
|
||||
if err == nil {
|
||||
email.Sent = true
|
||||
sentAddresses = append(sentAddresses, email.To)
|
||||
utils.Log(1, fmt.Sprintf("Email '%v' sent to: %v using the %v template (size: %v)", email.Subject, email.To, email.Template, len([]byte(email.Source))))
|
||||
emailQueue = removeEmail(emailQueue, email)
|
||||
u.Log(fmt.Sprintf("Subject: %v to %v", email.Subject, email.To))
|
||||
} else {
|
||||
utils.Log(3, fmt.Sprintf("Email Notifier could not send email: %v", err))
|
||||
}
|
||||
}(e)
|
||||
}
|
||||
}
|
||||
time.Sleep(60 * time.Second)
|
||||
if u.Enabled {
|
||||
|
@ -158,7 +164,7 @@ func (u *Email) OnFailure(s *types.Service) error {
|
|||
Service: s,
|
||||
}
|
||||
|
||||
email := &types.Email{
|
||||
email := &EmailOutgoing{
|
||||
To: "info@socialeck.com",
|
||||
Subject: fmt.Sprintf("Service %v is Failing", s.Name),
|
||||
Template: "failure.html",
|
||||
|
@ -190,10 +196,7 @@ func (u *Email) OnSave() error {
|
|||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Email) Install() error {
|
||||
|
||||
fmt.Println("installing emailer")
|
||||
|
||||
inDb, err := emailer.Notification.isInDatabase()
|
||||
inDb, err := emailer.Notification.IsInDatabase()
|
||||
if !inDb {
|
||||
newNotifer, err := InsertDatabase(u.Notification)
|
||||
if err != nil {
|
||||
|
@ -205,7 +208,7 @@ func (u *Email) Install() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (u *Email) dialSend(email *types.Email) error {
|
||||
func (u *Email) dialSend(email *EmailOutgoing) error {
|
||||
fmt.Println("sending dailsend to emailer")
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", email.From)
|
||||
|
@ -219,7 +222,7 @@ func (u *Email) dialSend(email *types.Email) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func SendEmail(box *rice.Box, email *types.Email) {
|
||||
func SendEmail(box *rice.Box, email *EmailOutgoing) {
|
||||
source := EmailTemplate(box, email.Template, email.Data)
|
||||
email.Source = source
|
||||
emailQueue = append(emailQueue, email)
|
||||
|
@ -243,8 +246,8 @@ func EmailTemplate(box *rice.Box, tmpl string, data interface{}) string {
|
|||
return result
|
||||
}
|
||||
|
||||
func removeEmail(emails []*types.Email, em *types.Email) []*types.Email {
|
||||
var newArr []*types.Email
|
||||
func removeEmail(emails []*EmailOutgoing, em *EmailOutgoing) []*EmailOutgoing {
|
||||
var newArr []*EmailOutgoing
|
||||
for _, e := range emails {
|
||||
if e != em {
|
||||
newArr = append(newArr, e)
|
||||
|
|
|
@ -10,28 +10,11 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
AllCommunications []AllNotifiers
|
||||
AllCommunications []types.AllNotifiers
|
||||
Collections db.Collection
|
||||
Logs []*NotificationLog
|
||||
)
|
||||
|
||||
type AllNotifiers interface{}
|
||||
|
||||
func add(c interface{}) {
|
||||
AllCommunications = append(AllCommunications, c)
|
||||
}
|
||||
|
||||
func Load() []AllNotifiers {
|
||||
utils.Log(1, "Loading notifiers")
|
||||
var notifiers []AllNotifiers
|
||||
for _, comm := range AllCommunications {
|
||||
n := comm.(Notifier)
|
||||
n.Init()
|
||||
notifiers = append(notifiers, n)
|
||||
n.Test()
|
||||
}
|
||||
return notifiers
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
Id int64 `db:"id,omitempty" json:"id"`
|
||||
Method string `db:"method" json:"method"`
|
||||
|
@ -44,7 +27,7 @@ type Notification struct {
|
|||
ApiKey string `db:"api_key" json:"-"`
|
||||
ApiSecret string `db:"api_secret" json:"-"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
Limits int64 `db:"limits" json:"-"`
|
||||
Limits int `db:"limits" json:"-"`
|
||||
Removable bool `db:"removable" json:"-"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
Form []NotificationForm
|
||||
|
@ -62,14 +45,62 @@ type Notifier interface {
|
|||
}
|
||||
|
||||
type NotificationForm struct {
|
||||
id int64
|
||||
Id int64
|
||||
Type string
|
||||
Title string
|
||||
Placeholder string
|
||||
DbField string
|
||||
}
|
||||
|
||||
func (n *Notification) isInDatabase() (bool, error) {
|
||||
type NotificationLog struct {
|
||||
Notifier *Notification
|
||||
Message string
|
||||
Time utils.Timestamp
|
||||
}
|
||||
|
||||
func add(c interface{}) {
|
||||
AllCommunications = append(AllCommunications, c)
|
||||
}
|
||||
|
||||
func Load() []types.AllNotifiers {
|
||||
utils.Log(1, "Loading notifiers")
|
||||
var notifiers []types.AllNotifiers
|
||||
for _, comm := range AllCommunications {
|
||||
n := comm.(Notifier)
|
||||
n.Init()
|
||||
notifiers = append(notifiers, n)
|
||||
n.Test()
|
||||
}
|
||||
return notifiers
|
||||
}
|
||||
|
||||
func (n *Notification) Log(msg string) {
|
||||
log := &NotificationLog{
|
||||
Notifier: n,
|
||||
Message: msg,
|
||||
Time: utils.Timestamp(time.Now()),
|
||||
}
|
||||
Logs = append(Logs, log)
|
||||
}
|
||||
|
||||
func (n *Notification) Logs() []*NotificationLog {
|
||||
var logs []*NotificationLog
|
||||
for _, v := range Logs {
|
||||
if v.Notifier.Id == n.Id {
|
||||
logs = append(logs, v)
|
||||
}
|
||||
}
|
||||
return reverseLogs(logs)
|
||||
}
|
||||
|
||||
func reverseLogs(input []*NotificationLog) []*NotificationLog {
|
||||
if len(input) == 0 {
|
||||
return input
|
||||
}
|
||||
return append(reverseLogs(input[1:]), input[0])
|
||||
}
|
||||
|
||||
func (n *Notification) IsInDatabase() (bool, error) {
|
||||
return Collections.Find("id", n.Id).Exists()
|
||||
}
|
||||
|
||||
|
@ -87,6 +118,7 @@ func (n *Notification) Update() (*Notification, error) {
|
|||
|
||||
func InsertDatabase(n *Notification) (int64, error) {
|
||||
n.CreatedAt = time.Now()
|
||||
n.Limits = 3
|
||||
newId, err := Collections.Insert(n)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -94,18 +126,6 @@ func InsertDatabase(n *Notification) (int64, error) {
|
|||
return newId.(int64), err
|
||||
}
|
||||
|
||||
func Select(id int64) *Notification {
|
||||
var notifier *Notification
|
||||
for _, n := range AllCommunications {
|
||||
notif := n.(Notifier)
|
||||
notifier = notif.Select()
|
||||
if notifier.Id == id {
|
||||
return notifier
|
||||
}
|
||||
}
|
||||
return notifier
|
||||
}
|
||||
|
||||
func SelectNotifier(id int64) Notifier {
|
||||
var notifier Notifier
|
||||
for _, n := range AllCommunications {
|
||||
|
@ -118,9 +138,33 @@ func SelectNotifier(id int64) Notifier {
|
|||
return notifier
|
||||
}
|
||||
|
||||
func (f Notification) CanSend() bool {
|
||||
if f.SentLastHour() >= f.Limits {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (f Notification) SentLastHour() int {
|
||||
sent := 0
|
||||
hourAgo := time.Now().Add(-1 * time.Hour)
|
||||
for _, v := range f.Logs() {
|
||||
lastTime := time.Time(v.Time)
|
||||
if lastTime.After(hourAgo) {
|
||||
sent++
|
||||
}
|
||||
}
|
||||
return sent
|
||||
}
|
||||
|
||||
func (f NotificationForm) Value() string {
|
||||
notifier := Select(f.id)
|
||||
return notifier.GetValue(f.DbField)
|
||||
noti := SelectNotifier(f.Id)
|
||||
return noti.Select().GetValue(f.DbField)
|
||||
}
|
||||
|
||||
func (f Notification) LimitValue() int64 {
|
||||
notifier, _ := SelectNotification(f.Id)
|
||||
return utils.StringInt(notifier.GetValue("limits"))
|
||||
}
|
||||
|
||||
func (n *Notification) GetValue(dbField string) string {
|
||||
|
@ -144,6 +188,8 @@ func (n *Notification) GetValue(dbField string) string {
|
|||
return n.ApiKey
|
||||
case "api_secret":
|
||||
return n.ApiSecret
|
||||
case "limits":
|
||||
return utils.IntString(int(n.Limits))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func init() {
|
|||
Method: SLACK_METHOD,
|
||||
Host: "https://webhooksurl.slack.com/***",
|
||||
Form: []NotificationForm{{
|
||||
id: 2,
|
||||
Id: 2,
|
||||
Type: "text",
|
||||
Title: "Incoming Webhook Url",
|
||||
Placeholder: "Insert your Slack webhook URL here.",
|
||||
|
@ -84,11 +84,15 @@ func (u *Slack) Run() error {
|
|||
messageLock.Lock()
|
||||
slackMessages = uniqueStrings(slackMessages)
|
||||
for _, msg := range slackMessages {
|
||||
utils.Log(1, fmt.Sprintf("Sending JSON to Slack Webhook"))
|
||||
client := http.Client{Timeout: 15 * time.Second}
|
||||
_, err := client.Post(u.Host, "application/json", bytes.NewBuffer([]byte(msg)))
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Issue sending Slack notification: %v", err))
|
||||
|
||||
if u.CanSend() {
|
||||
utils.Log(1, fmt.Sprintf("Sending JSON to Slack Webhook"))
|
||||
client := http.Client{Timeout: 15 * time.Second}
|
||||
_, err := client.Post(u.Host, "application/json", bytes.NewBuffer([]byte(msg)))
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Issue sending Slack notification: %v", err))
|
||||
}
|
||||
u.Log(msg)
|
||||
}
|
||||
}
|
||||
slackMessages = []string{}
|
||||
|
@ -146,7 +150,7 @@ func (u *Slack) OnSave() error {
|
|||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Slack) Install() error {
|
||||
inDb, err := slacker.Notification.isInDatabase()
|
||||
inDb, err := slacker.Notification.IsInDatabase()
|
||||
if !inDb {
|
||||
newNotifer, err := InsertDatabase(u.Notification)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"upper.io/db.v3/lib/sqlbuilder"
|
||||
)
|
||||
|
||||
|
@ -21,48 +21,14 @@ var (
|
|||
DB sqlbuilder.Database
|
||||
)
|
||||
|
||||
func SetDatabase(database sqlbuilder.Database) {
|
||||
DB = database
|
||||
type PluginInfo struct {
|
||||
i *types.Info
|
||||
}
|
||||
|
||||
type PluginInfo struct {
|
||||
Info Info
|
||||
PluginActions
|
||||
func SetDatabase(database sqlbuilder.Database) {
|
||||
DB = database
|
||||
}
|
||||
|
||||
func (p *PluginInfo) Form() string {
|
||||
return "okkokokkok"
|
||||
}
|
||||
|
||||
type PluginActions interface {
|
||||
GetInfo() Info
|
||||
GetForm() string
|
||||
OnLoad(sqlbuilder.Database)
|
||||
SetInfo(map[string]interface{}) Info
|
||||
Routes() []Routing
|
||||
OnSave(map[string]interface{})
|
||||
OnFailure(map[string]interface{})
|
||||
OnSuccess(map[string]interface{})
|
||||
OnSettingsSaved(map[string]interface{})
|
||||
OnNewUser(map[string]interface{})
|
||||
OnNewService(map[string]interface{})
|
||||
OnUpdatedService(map[string]interface{})
|
||||
OnDeletedService(map[string]interface{})
|
||||
OnInstall(map[string]interface{})
|
||||
OnUninstall(map[string]interface{})
|
||||
OnBeforeRequest(map[string]interface{})
|
||||
OnAfterRequest(map[string]interface{})
|
||||
OnShutdown()
|
||||
}
|
||||
|
||||
type Routing struct {
|
||||
URL string
|
||||
Method string
|
||||
Handler func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Name string
|
||||
Description string
|
||||
Form string
|
||||
}
|
||||
|
|
|
@ -21,6 +21,11 @@ $(".confirm-btn").on('click', function() {
|
|||
});
|
||||
|
||||
|
||||
$(".select-input").on("click", function () {
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
|
||||
var ranVar = false;
|
||||
var ranTheme = false;
|
||||
$('a[data-toggle="pill"]').on('shown.bs.tab', function (e) {
|
||||
|
|
|
@ -59,26 +59,23 @@
|
|||
{{ end }}
|
||||
</div>
|
||||
|
||||
|
||||
<h3>Latest Failures</h3>
|
||||
|
||||
{{ range .Services }}
|
||||
{{ $s := .ToService }}
|
||||
{{ if .LimitedFailures }}
|
||||
<div class="list-group mt-3">
|
||||
<h4>{{$s.Name}} Failures</h4>
|
||||
<div class="list-group mt-3 mb-4">
|
||||
{{ range .LimitedFailures }}
|
||||
{{ $f := .ToFailure }}
|
||||
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">{{.ParseError}}</h5>
|
||||
<small>Reported {{.Ago}}</small>
|
||||
</div>
|
||||
<p class="mb-1">{{.Issue}}</p>
|
||||
<p class="mb-1">{{$f.Issue}}</p>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
||||
{{ end }}
|
||||
|
||||
|
||||
|
|
|
@ -59,14 +59,15 @@
|
|||
<canvas id="service" width="400" height="120"></canvas>
|
||||
|
||||
{{ if .LimitedFailures }}
|
||||
<div class="list-group mt-5">
|
||||
<div class="list-group mt-3 mb-4">
|
||||
{{ range .LimitedFailures }}
|
||||
{{ $f := .ToFailure }}
|
||||
<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">{{.ParseError}}</h5>
|
||||
<small>Reported {{.Ago}}</small>
|
||||
</div>
|
||||
<p class="mb-1">{{.Issue}}</p>
|
||||
<p class="mb-1">{{$f.Issue}}</p>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
@ -147,7 +148,7 @@
|
|||
<button type="submit" class="btn btn-success btn-block">Update Service</button>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a href="/service/{{ $s.Id }}/delete_failures" class="btn btn-danger btn-block">Delete All Failures</a>
|
||||
<a href="/service/{{ $s.Id }}/delete_failures" class="btn btn-danger btn-block confirm-btn">Delete All Failures</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -156,9 +157,7 @@
|
|||
|
||||
<div class="col-12 mt-4">
|
||||
<h3>Last Response</h3>
|
||||
|
||||
<textarea rows="8" class="form-control" readonly>{{ $s.LastResponse }}</textarea>
|
||||
|
||||
<div class="form-group row mt-2">
|
||||
<label for="last_status_code" class="col-sm-3 col-form-label">Status Code</label>
|
||||
<div class="col-sm-2">
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<td class="text-right">
|
||||
<div class="btn-group">
|
||||
<a href="/service/{{$s.Id}}" class="btn btn-primary">View</a>
|
||||
<a href="/service/{{$s.Id}}/delete" class="btn btn-danger">Delete</a>
|
||||
<a href="/service/{{$s.Id}}/delete" class="btn btn-danger confirm-btn">Delete</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -91,6 +91,7 @@
|
|||
<label for="service_response" class="col-sm-4 col-form-label">Expected Response (Regex)</label>
|
||||
<div class="col-sm-8">
|
||||
<textarea name="expected" class="form-control" id="service_response" rows="3"></textarea>
|
||||
<small id="emailHelp" class="form-text text-muted">You can insert <a target="_blank" href="https://regex101.com/r/I5bbj9/1">Regex</a> to validate the response</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
||||
|
||||
|
||||
{{template "nav"}}
|
||||
|
||||
<div class="col-12">
|
||||
|
@ -79,14 +78,19 @@
|
|||
|
||||
<button type="submit" class="btn btn-primary btn-block">Save Settings</button>
|
||||
|
||||
<div class="form-group mt-3">
|
||||
<label for="api_key">API Key</label>
|
||||
<input type="text" class="form-control" value="{{ .ApiKey }}" id="api_key" readonly>
|
||||
<div class="form-group row mt-3">
|
||||
<label for="api_key" class="col-sm-3 col-form-label">API Key</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control select-input" value="{{ .ApiKey }}" id="api_key" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="api_secret">API Secret</label>
|
||||
<input type="text" class="form-control" value="{{ .ApiSecret }}" id="api_secret" readonly>
|
||||
<div class="form-group row">
|
||||
<label for="api_secret" class="col-sm-3 col-form-label">API Secret</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control select-input" value="{{ .ApiSecret }}" id="api_secret" readonly>
|
||||
<small id="emailHelp" class="form-text text-muted">You can <a href="/api/renew">Regenerate API Keys</a> if you need to.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
@ -122,7 +126,7 @@
|
|||
|
||||
|
||||
{{ range .Communications }}
|
||||
<div class="tab-pane fade" id="v-pills-{{underscore .Method}}" role="tabpanel" aria-labelledby="v-pills-{{underscore .Method }}-tab">
|
||||
<div class="tab-pane" id="v-pills-{{underscore .Method}}" role="tabpanel" aria-labelledby="v-pills-{{underscore .Method }}-tab">
|
||||
<form method="POST" action="/settings/notifier/{{ .Id }}">
|
||||
{{range .Form}}
|
||||
<div class="form-group">
|
||||
|
@ -130,6 +134,12 @@
|
|||
<input type="{{.Type}}" name="{{underscore .DbField}}" class="form-control" value="{{ .Value }}" id="{{underscore .Title}}" placeholder="{{.Placeholder}}">
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="form-group">
|
||||
<label class="text-capitalize" for="limits_per_hour_{{underscore .Method }}">Limits per Hour</label>
|
||||
<input type="number" name="limits" class="form-control" value="{{.LimitValue}}" id="limits_per_hour_{{underscore .Method }}" min="1" max="60" placeholder="How many messages can send per hour">
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<span class="switch">
|
||||
|
@ -143,6 +153,18 @@
|
|||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
{{ if .Logs }}
|
||||
Sent {{.SentLastHour}} out of {{.LimitValue}} in the last hour<br>
|
||||
{{ range .Logs }}
|
||||
<div class="card mt-1">
|
||||
<div class="card-body">
|
||||
{{.Message}}
|
||||
<p class="card-text"><small class="text-muted">Sent {{.Time.Ago}}</small></p>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
|
|
@ -1,9 +1,72 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
"upper.io/db.v3/lib/sqlbuilder"
|
||||
)
|
||||
|
||||
type PluginInfo struct {
|
||||
Info Info
|
||||
PluginActions
|
||||
}
|
||||
|
||||
type Routing struct {
|
||||
URL string
|
||||
Method string
|
||||
Handler func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Name string
|
||||
Description string
|
||||
Form string
|
||||
}
|
||||
|
||||
type PluginActions interface {
|
||||
GetInfo() Info
|
||||
GetForm() string
|
||||
OnLoad(sqlbuilder.Database)
|
||||
SetInfo(map[string]interface{}) Info
|
||||
Routes() []Routing
|
||||
OnSave(map[string]interface{})
|
||||
OnFailure(map[string]interface{})
|
||||
OnSuccess(map[string]interface{})
|
||||
OnSettingsSaved(map[string]interface{})
|
||||
OnNewUser(map[string]interface{})
|
||||
OnNewService(map[string]interface{})
|
||||
OnUpdatedService(map[string]interface{})
|
||||
OnDeletedService(map[string]interface{})
|
||||
OnInstall(map[string]interface{})
|
||||
OnUninstall(map[string]interface{})
|
||||
OnBeforeRequest(map[string]interface{})
|
||||
OnAfterRequest(map[string]interface{})
|
||||
OnShutdown()
|
||||
}
|
||||
|
||||
type AllNotifiers interface{}
|
||||
|
||||
type Core struct {
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"name"`
|
||||
Config string `db:"config" json:"-"`
|
||||
ApiKey string `db:"api_key" json:"-"`
|
||||
ApiSecret string `db:"api_secret" json:"-"`
|
||||
Style string `db:"style" json:"-"`
|
||||
Footer string `db:"footer" json:"-"`
|
||||
Domain string `db:"domain" json:"domain,omitempty"`
|
||||
Version string `db:"version" json:"version,omitempty"`
|
||||
MigrationId int64 `db:"migration_id" json:"-"`
|
||||
UseCdn bool `db:"use_cdn" json:"-"`
|
||||
Services []*Service `json:"services,omitempty"`
|
||||
Plugins []Info
|
||||
Repos []PluginJSON
|
||||
AllPlugins []PluginActions
|
||||
Communications []AllNotifiers
|
||||
DbConnection string
|
||||
Started time.Time
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
Id int64 `db:"id,omitempty" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
|
@ -67,16 +130,6 @@ type Checkin struct {
|
|||
Last time.Time `json:"last"`
|
||||
}
|
||||
|
||||
type Email struct {
|
||||
To string
|
||||
Subject string
|
||||
Template string
|
||||
From string
|
||||
Data interface{}
|
||||
Source string
|
||||
Sent bool
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Connection string `yaml:"connection"`
|
||||
Host string `yaml:"host"`
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"github.com/ararog/timeago"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func StringInt(s string) int64 {
|
||||
|
@ -12,6 +14,21 @@ func StringInt(s string) int64 {
|
|||
return int64(num)
|
||||
}
|
||||
|
||||
func IntString(s int) string {
|
||||
return strconv.Itoa(s)
|
||||
}
|
||||
|
||||
type Timestamp time.Time
|
||||
|
||||
type Timestamper interface {
|
||||
Ago() string
|
||||
}
|
||||
|
||||
func (t Timestamp) Ago() string {
|
||||
got, _ := timeago.TimeAgoWithTime(time.Now(), time.Time(t))
|
||||
return got
|
||||
}
|
||||
|
||||
func UnderScoreString(str string) string {
|
||||
|
||||
// convert every letter to lower case
|
||||
|
|
Loading…
Reference in New Issue