mirror of https://github.com/statping/statping
parent
ab2832d0a3
commit
b920ba56c3
|
@ -18,7 +18,7 @@ services:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- VERSION=0.29.2
|
- VERSION=0.29.3
|
||||||
- DB_HOST=localhost
|
- DB_HOST=localhost
|
||||||
- DB_USER=travis
|
- DB_USER=travis
|
||||||
- DB_PASS=
|
- DB_PASS=
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
|
|
||||||
ENV VERSION=v0.29.2
|
ENV VERSION=v0.29.3
|
||||||
|
|
||||||
RUN apk --no-cache add libstdc++ ca-certificates
|
RUN apk --no-cache add libstdc++ ca-certificates
|
||||||
RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \
|
RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \
|
||||||
|
|
88
cli.go
88
cli.go
|
@ -3,8 +3,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hunterlong/statup/core"
|
"github.com/hunterlong/statup/core"
|
||||||
|
"github.com/hunterlong/statup/plugin"
|
||||||
"github.com/hunterlong/statup/utils"
|
"github.com/hunterlong/statup/utils"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"upper.io/db.v3/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CatchCLI(args []string) {
|
func CatchCLI(args []string) {
|
||||||
|
@ -18,6 +22,12 @@ func CatchCLI(args []string) {
|
||||||
core.CompileSASS()
|
core.CompileSASS()
|
||||||
case "api":
|
case "api":
|
||||||
HelpEcho()
|
HelpEcho()
|
||||||
|
case "test":
|
||||||
|
cmd := args[2]
|
||||||
|
switch cmd {
|
||||||
|
case "plugins":
|
||||||
|
LoadPlugins(true)
|
||||||
|
}
|
||||||
case "export":
|
case "export":
|
||||||
var err error
|
var err error
|
||||||
fmt.Printf("Statup v%v Exporting Static 'index.html' page...\n", VERSION)
|
fmt.Printf("Statup v%v Exporting Static 'index.html' page...\n", VERSION)
|
||||||
|
@ -86,6 +96,7 @@ func HelpEcho() {
|
||||||
fmt.Println(" statup - Main command to run Statup server")
|
fmt.Println(" statup - Main command to run Statup server")
|
||||||
fmt.Println(" statup version - Returns the current version of Statup")
|
fmt.Println(" statup version - Returns the current version of Statup")
|
||||||
fmt.Println(" statup run - Check all service 1 time and then quit")
|
fmt.Println(" statup run - Check all service 1 time and then quit")
|
||||||
|
fmt.Println(" statup test plugins - Test all plugins for required information")
|
||||||
fmt.Println(" statup assets - Export all assets used locally to be edited.")
|
fmt.Println(" statup assets - Export all assets used locally to be edited.")
|
||||||
fmt.Println(" statup env - Show all environment variables being used for Statup")
|
fmt.Println(" statup env - Show all environment variables being used for Statup")
|
||||||
fmt.Println(" statup export - Exports the index page as a static HTML for pushing")
|
fmt.Println(" statup export - Exports the index page as a static HTML for pushing")
|
||||||
|
@ -95,3 +106,80 @@ func HelpEcho() {
|
||||||
fmt.Println(" statup help - Shows the user basic information about Statup")
|
fmt.Println(" statup help - Shows the user basic information about Statup")
|
||||||
fmt.Println("Give Statup a Star at https://github.com/hunterlong/statup")
|
fmt.Println("Give Statup a Star at https://github.com/hunterlong/statup")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPlugin(plug plugin.PluginActions) {
|
||||||
|
RenderBoxes()
|
||||||
|
defer utils.DeleteFile("./.plugin_test.db")
|
||||||
|
core.CoreApp.AllPlugins = []plugin.PluginActions{plug}
|
||||||
|
info := plug.GetInfo()
|
||||||
|
utils.Log(1, "=======================================================================")
|
||||||
|
utils.Log(1, fmt.Sprintf(" Plugin Name: %v", info.Name))
|
||||||
|
utils.Log(1, fmt.Sprintf(" Plugin Description: %v", info.Description))
|
||||||
|
utils.Log(1, fmt.Sprintf(" Plugin Routes: %v", len(plug.Routes())))
|
||||||
|
for k, r := range plug.Routes() {
|
||||||
|
utils.Log(1, fmt.Sprintf(" - Route %v - (%v) /%v", k+1, r.Method, r.URL))
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeSrv := &core.Service{
|
||||||
|
Id: 56,
|
||||||
|
Name: "Test Plugin Service",
|
||||||
|
Domain: "https://google.com",
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeFailD := core.FailureData{
|
||||||
|
Issue: "No issue, just testing this plugin.",
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeCore := &core.Core{
|
||||||
|
Name: "Plugin Test",
|
||||||
|
Description: "This is a fake Core for testing your plugin",
|
||||||
|
ApiSecret: "0x0x0x0x0",
|
||||||
|
ApiKey: "abcdefg12345",
|
||||||
|
Services: []*core.Service{fakeSrv},
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeUser := &core.User{
|
||||||
|
Id: 6334,
|
||||||
|
Username: "Bulbasaur",
|
||||||
|
Password: "$2a$14$NzT/fLdE3f9iB1Eux2C84O6ZoPhI4NfY0Ke32qllCFo8pMTkUPZzy",
|
||||||
|
Email: "info@testdomain.com",
|
||||||
|
Admin: true,
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.Log(1, fmt.Sprintf("Creating a SQLite database for testing, will be deleted automatically..."))
|
||||||
|
sqlFake := sqlite.ConnectionURL{
|
||||||
|
Database: "./.plugin_test.db",
|
||||||
|
}
|
||||||
|
fakeDb, err := sqlite.Open(sqlFake)
|
||||||
|
if err != nil {
|
||||||
|
utils.Log(3, err)
|
||||||
|
}
|
||||||
|
up, _ := core.SqlBox.String("sqlite_up.sql")
|
||||||
|
requests := strings.Split(up, ";")
|
||||||
|
for _, request := range requests {
|
||||||
|
_, err := fakeDb.Exec(request)
|
||||||
|
if err != nil {
|
||||||
|
utils.Log(2, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
utils.Log(1, fmt.Sprintf("Finished creating Test SQLite database, sending events."))
|
||||||
|
|
||||||
|
utils.Log(1, "======> Sending 'OnLoad(sqlbuilder.Database)'")
|
||||||
|
core.OnLoad(fakeDb)
|
||||||
|
utils.Log(1, "======> Sending 'OnSuccess(Service)'")
|
||||||
|
core.OnSuccess(fakeSrv)
|
||||||
|
utils.Log(1, "======> Sending 'OnFailure(Service, FailureData)'")
|
||||||
|
core.OnFailure(fakeSrv, fakeFailD)
|
||||||
|
utils.Log(1, "======> Sending 'OnSettingsSaved(Core)'")
|
||||||
|
core.OnSettingsSaved(fakeCore)
|
||||||
|
utils.Log(1, "======> Sending 'OnNewService(Service)'")
|
||||||
|
core.OnNewService(fakeSrv)
|
||||||
|
utils.Log(1, "======> Sending 'OnNewUser(User)'")
|
||||||
|
core.OnNewUser(fakeUser)
|
||||||
|
utils.Log(1, "======> Sending 'OnUpdateService(Service)'")
|
||||||
|
core.OnUpdateService(fakeSrv)
|
||||||
|
utils.Log(1, "======> Sending 'OnDeletedService(Service)'")
|
||||||
|
core.OnDeletedService(fakeSrv)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -21,19 +21,26 @@ func CheckServices() {
|
||||||
for _, v := range CoreApp.Services {
|
for _, v := range CoreApp.Services {
|
||||||
obj := v
|
obj := v
|
||||||
//go obj.StartCheckins()
|
//go obj.StartCheckins()
|
||||||
|
obj.stopRoutine = make(chan struct{})
|
||||||
go obj.CheckQueue()
|
go obj.CheckQueue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) CheckQueue() {
|
func (s *Service) CheckQueue() {
|
||||||
defer s.CheckQueue()
|
for {
|
||||||
s.Check()
|
select {
|
||||||
if s.Interval < 1 {
|
case <-s.stopRoutine:
|
||||||
s.Interval = 1
|
return
|
||||||
|
default:
|
||||||
|
s.Check()
|
||||||
|
if s.Interval < 1 {
|
||||||
|
s.Interval = 1
|
||||||
|
}
|
||||||
|
msg := fmt.Sprintf("Service: %v | Online: %v | Latency: %0.0fms", s.Name, s.Online, (s.Latency * 1000))
|
||||||
|
utils.Log(1, msg)
|
||||||
|
time.Sleep(time.Duration(s.Interval) * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
msg := fmt.Sprintf("Service: %v | Online: %v | Latency: %0.0fms", s.Name, s.Online, (s.Latency * 1000))
|
|
||||||
utils.Log(1, msg)
|
|
||||||
time.Sleep(time.Duration(s.Interval) * time.Second)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) DNSCheck() (float64, error) {
|
func (s *Service) DNSCheck() (float64, error) {
|
||||||
|
|
|
@ -61,6 +61,7 @@ func Create(c *types.Communication) (int64, error) {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
c.Id = uuid.(int64)
|
c.Id = uuid.(int64)
|
||||||
|
c.Routine = make(chan struct{})
|
||||||
if CoreApp != nil {
|
if CoreApp != nil {
|
||||||
CoreApp.Communications = append(CoreApp.Communications, c)
|
CoreApp.Communications = append(CoreApp.Communications, c)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/GeertJohan/go.rice"
|
"github.com/GeertJohan/go.rice"
|
||||||
"github.com/hunterlong/statup/plugin"
|
"github.com/hunterlong/statup/plugin"
|
||||||
"github.com/hunterlong/statup/types"
|
"github.com/hunterlong/statup/types"
|
||||||
|
@ -67,10 +66,6 @@ func InitApp() {
|
||||||
func (c *Core) Update() (*Core, error) {
|
func (c *Core) Update() (*Core, error) {
|
||||||
res := DbSession.Collection("core").Find().Limit(1)
|
res := DbSession.Collection("core").Find().Limit(1)
|
||||||
err := res.Update(c)
|
err := res.Update(c)
|
||||||
CoreApp.Services, err = SelectAllServices()
|
|
||||||
|
|
||||||
fmt.Println(CoreApp.Name, CoreApp.Description)
|
|
||||||
|
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,12 @@ func OnFailure(s *Service, f FailureData) {
|
||||||
for _, p := range CoreApp.AllPlugins {
|
for _, p := range CoreApp.AllPlugins {
|
||||||
p.OnFailure(structs.Map(s))
|
p.OnFailure(structs.Map(s))
|
||||||
}
|
}
|
||||||
|
if notifications.SlackComm != nil {
|
||||||
onFailureEmail(s, f)
|
onFailureSlack(s, f)
|
||||||
onFailureSlack(s, f)
|
}
|
||||||
|
if notifications.EmailComm != nil {
|
||||||
|
onFailureEmail(s, f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func onFailureSlack(s *Service, f FailureData) {
|
func onFailureSlack(s *Service, f FailureData) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ type Service struct {
|
||||||
OrderId int64 `json:"order_id"`
|
OrderId int64 `json:"order_id"`
|
||||||
Failures []*Failure `json:"failures"`
|
Failures []*Failure `json:"failures"`
|
||||||
Checkins []*Checkin `json:"checkins"`
|
Checkins []*Checkin `json:"checkins"`
|
||||||
runRoutine bool
|
stopRoutine chan struct{}
|
||||||
LastResponse string
|
LastResponse string
|
||||||
LastStatusCode int
|
LastStatusCode int
|
||||||
LastOnline time.Time
|
LastOnline time.Time
|
||||||
|
@ -212,6 +212,11 @@ func (u *Service) Delete() error {
|
||||||
utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", u.Name, err))
|
utils.Log(3, fmt.Sprintf("Failed to delete service %v. %v", u.Name, err))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
utils.Log(1, fmt.Sprintf("Stopping %v Monitoring...", u.Name))
|
||||||
|
if u.stopRoutine != nil {
|
||||||
|
close(u.stopRoutine)
|
||||||
|
}
|
||||||
|
utils.Log(1, fmt.Sprintf("Stopped %v Monitoring Service", u.Name))
|
||||||
u.RemoveArray()
|
u.RemoveArray()
|
||||||
OnDeletedService(u)
|
OnDeletedService(u)
|
||||||
return err
|
return err
|
||||||
|
@ -237,8 +242,9 @@ func (u *Service) Create() (int64, error) {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
u.Id = uuid.(int64)
|
u.Id = uuid.(int64)
|
||||||
|
u.stopRoutine = make(chan struct{})
|
||||||
CoreApp.Services = append(CoreApp.Services, u)
|
CoreApp.Services = append(CoreApp.Services, u)
|
||||||
//go u.CheckQueue()
|
go u.CheckQueue()
|
||||||
OnNewService(u)
|
OnNewService(u)
|
||||||
return uuid.(int64), err
|
return uuid.(int64), err
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@ func RunHTTPServer() {
|
||||||
for _, p := range core.CoreApp.AllPlugins {
|
for _, p := range core.CoreApp.AllPlugins {
|
||||||
info := p.GetInfo()
|
info := p.GetInfo()
|
||||||
for _, route := range p.Routes() {
|
for _, route := range p.Routes() {
|
||||||
path := fmt.Sprintf("/plugins/%v/%v", info.Name, route.URL)
|
path := fmt.Sprintf("%v", route.URL)
|
||||||
r.Handle(path, http.HandlerFunc(route.Handler)).Methods(route.Method)
|
r.Handle(path, http.HandlerFunc(route.Handler)).Methods(route.Method)
|
||||||
fmt.Printf("Added Route %v for plugin %v\n", path, info.Name)
|
utils.Log(1, fmt.Sprintf("Added Route %v for plugin %v\n", path, info.Name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
|
|
|
@ -11,7 +11,7 @@ type index struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if core.CoreApp.Services == nil {
|
if core.CoreApp == nil {
|
||||||
http.Redirect(w, r, "/setup", http.StatusSeeOther)
|
http.Redirect(w, r, "/setup", http.StatusSeeOther)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
30
main.go
30
main.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/GeertJohan/go.rice"
|
"github.com/GeertJohan/go.rice"
|
||||||
|
"github.com/fatih/structs"
|
||||||
"github.com/hunterlong/statup/core"
|
"github.com/hunterlong/statup/core"
|
||||||
"github.com/hunterlong/statup/handlers"
|
"github.com/hunterlong/statup/handlers"
|
||||||
"github.com/hunterlong/statup/plugin"
|
"github.com/hunterlong/statup/plugin"
|
||||||
|
@ -68,7 +69,7 @@ func mainProcess() {
|
||||||
core.InitApp()
|
core.InitApp()
|
||||||
|
|
||||||
if !core.SetupMode {
|
if !core.SetupMode {
|
||||||
LoadPlugins()
|
LoadPlugins(false)
|
||||||
handlers.RunHTTPServer()
|
handlers.RunHTTPServer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,14 +82,13 @@ func ForEachPlugin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadPlugins() {
|
func LoadPlugins(debug bool) {
|
||||||
utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
|
utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
|
||||||
if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
|
if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
|
||||||
os.Mkdir("./plugins", os.ModePerm)
|
os.Mkdir("./plugins", os.ModePerm)
|
||||||
}
|
}
|
||||||
|
|
||||||
//ForEachPlugin()
|
//ForEachPlugin()
|
||||||
|
|
||||||
files, err := ioutil.ReadDir("./plugins")
|
files, err := ioutil.ReadDir("./plugins")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
|
utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
|
||||||
|
@ -116,18 +116,30 @@ func LoadPlugins() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
|
||||||
|
utils.Log(1, structs.Map(symPlugin))
|
||||||
|
}
|
||||||
|
|
||||||
var plugActions plugin.PluginActions
|
var plugActions plugin.PluginActions
|
||||||
plugActions, ok := symPlugin.(plugin.PluginActions)
|
plugActions, ok := symPlugin.(plugin.PluginActions)
|
||||||
if !ok {
|
if !ok {
|
||||||
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
|
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
|
||||||
|
if debug {
|
||||||
|
//fmt.Println(symPlugin.(plugin.PluginActions))
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
plugActions.OnLoad(core.DbSession)
|
if debug {
|
||||||
|
TestPlugin(plugActions)
|
||||||
core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
|
} else {
|
||||||
core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
|
plugActions.OnLoad(core.DbSession)
|
||||||
|
core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
|
||||||
|
core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !debug {
|
||||||
|
utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ func (p *PluginInfo) Form() string {
|
||||||
type PluginActions interface {
|
type PluginActions interface {
|
||||||
GetInfo() Info
|
GetInfo() Info
|
||||||
GetForm() string
|
GetForm() string
|
||||||
|
OnLoad(sqlbuilder.Database)
|
||||||
SetInfo(map[string]interface{}) Info
|
SetInfo(map[string]interface{}) Info
|
||||||
Routes() []Routing
|
Routes() []Routing
|
||||||
OnSave(map[string]interface{})
|
OnSave(map[string]interface{})
|
||||||
|
@ -52,7 +53,6 @@ type PluginActions interface {
|
||||||
OnBeforeRequest(map[string]interface{})
|
OnBeforeRequest(map[string]interface{})
|
||||||
OnAfterRequest(map[string]interface{})
|
OnAfterRequest(map[string]interface{})
|
||||||
OnShutdown()
|
OnShutdown()
|
||||||
OnLoad(sqlbuilder.Database)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Routing struct {
|
type Routing struct {
|
||||||
|
|
|
@ -41,6 +41,14 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="col-12 full-col-12">
|
<div class="col-12 full-col-12">
|
||||||
|
{{ if not .Services }}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<h4 class="alert-heading">No Services to Monitor!</h4>
|
||||||
|
<p>Your Statup Status Page is working correctly, but you don't have any services to monitor. Go to the <b>Dashboard</b> and add a website to begin really using your status page!</p>
|
||||||
|
<hr>
|
||||||
|
<p class="mb-0">If this is a bug, please make an issue in the Statup Github Repo. <a href="https://github.com/hunterlong/statup" class="btn btn-sm btn-outline-danger float-right">Statup Github Repo</a></p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
{{ range .Services }}
|
{{ range .Services }}
|
||||||
<div class="mt-4" id="service_id_{{.Id}}">
|
<div class="mt-4" id="service_id_{{.Id}}">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
|
@ -55,6 +55,7 @@ type Communication struct {
|
||||||
Limits int64 `db:"limits" json:"-"`
|
Limits int64 `db:"limits" json:"-"`
|
||||||
Removable bool `db:"removable" json:"-"`
|
Removable bool `db:"removable" json:"-"`
|
||||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
Routine chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Email struct {
|
type Email struct {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -33,3 +34,12 @@ func UnderScoreString(str string) string {
|
||||||
|
|
||||||
return newStr
|
return newStr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteFile(file string) bool {
|
||||||
|
err := os.Remove(file)
|
||||||
|
if err != nil {
|
||||||
|
Log(3, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue