upgrades - plugins

pull/10/head v0.12
Hunter Long 2018-06-12 00:21:16 -07:00
parent b81b76881f
commit afd6ec52f1
8 changed files with 136 additions and 8 deletions

View File

@ -14,7 +14,7 @@ services:
- docker
env:
- VERSION=0.1
- VERSION=0.12
matrix:
allow_failures:

View File

@ -12,6 +12,7 @@ type Core struct {
Secret string
Version string
Plugins []plugin.Info
Repos []PluginJSON
}
func SelectCore() (*Core, error) {

View File

@ -6,16 +6,13 @@ import (
)
func (f *Failure) ParseError() string {
err := strings.Contains(f.Issue, "operation timed out")
if err {
return fmt.Sprintf("HTTP Request timed out after x seconds")
}
err = strings.Contains(f.Issue, "x509: certificate is valid")
if err {
return fmt.Sprintf("SSL Certificate invalid")
}
return f.Issue
}

View File

@ -14,6 +14,7 @@
<div class="container">
{{template "nav"}}
<div class="row">
@ -22,6 +23,7 @@
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
<a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Settings</a>
<a class="nav-link" id="v-pills-browse-tab" data-toggle="pill" href="#v-pills-browse" role="tab" aria-controls="v-pills-home" aria-selected="true">Browse Plugins</a>
{{ range .Plugins }}
<a class="nav-link text-capitalize" id="v-pills-{{.Name}}-tab" data-toggle="pill" href="#v-pills-{{.Name}}" role="tab" aria-controls="v-pills-profile" aria-selected="false">{{.Name}}</a>
{{end}}
@ -29,15 +31,27 @@
</div>
<div class="col-8">
<div class="tab-content" id="v-pills-tabContent">
<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">...</div>
<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
<h3>Settings</h3>
</div>
<div class="tab-pane fade" id="v-pills-browse" role="tabpanel" aria-labelledby="v-pills-browse-tab">
{{ range .Repos }}
<div class="card col-6" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">{{ .Name }}</h5>
<p class="card-text">{{ .Description }}</p>
<a href="/plugins/download/{{ .Name }}" class="card-link">Add</a>
</div>
</div>
{{ end }}
</div>
{{ range .Plugins }}
<div class="tab-pane fade" id="v-pills-{{.Name}}" role="tabpanel" aria-labelledby="v-pills-{{.Name}}-tab">
<form action="/plugins/{{.Name}}/save" method="POST">
{{safe .Form }}
</form>
</div>
{{end}}

76
main.go
View File

@ -2,6 +2,7 @@ package main
import (
"database/sql"
"encoding/json"
"fmt"
"github.com/GeertJohan/go.rice"
"github.com/go-yaml/yaml"
@ -10,6 +11,8 @@ import (
_ "github.com/lib/pq"
"golang.org/x/crypto/bcrypt"
"io/ioutil"
"net/http"
"os"
plg "plugin"
"strings"
)
@ -28,6 +31,10 @@ var (
allPlugins []plg.Plugin
)
const (
pluginsRepo = "https://raw.githubusercontent.com/hunterlong/statup/master/plugins.json"
)
type Config struct {
Connection string `yaml:"connection"`
Host string `yaml:"host"`
@ -38,6 +45,71 @@ type Config struct {
Secret string `yaml:"secret"`
}
type PluginRepos struct {
Plugins []PluginJSON
}
type PluginJSON struct {
Name string `json:"name"`
Description string `json:"description"`
Repo string `json:"repo"`
Author string `json:"author"`
Namespace string `json:"namespace"`
}
func (c *Core) FetchPluginRepo() []PluginJSON {
resp, err := http.Get(pluginsRepo)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var pk []PluginJSON
json.Unmarshal(body, &pk)
c.Repos = pk
return pk
}
func SelectPlugin(name string) *PluginJSON {
for _, v := range core.FetchPluginRepo() {
if v.Namespace == name {
return &v
}
}
return nil
}
func DownloadPlugin(name string) {
plugin := SelectPlugin(name)
var _, err = os.Stat("plugins/" + plugin.Namespace)
if err != nil {
}
if os.IsNotExist(err) {
var file, _ = os.Create("plugins/" + plugin.Namespace)
defer file.Close()
}
resp, err := http.Get("https://raw.githubusercontent.com/hunterlong/statup/master/plugins.json")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
file, err := os.OpenFile("plugins/"+plugin.Namespace, os.O_RDWR, 0644)
if err != nil {
panic(err)
}
defer file.Close()
_, err = file.Write(body)
if err != nil {
panic(err)
}
err = file.Sync()
}
func main() {
VERSION = "1.1.1"
fmt.Printf("Starting Statup v%v\n", VERSION)
@ -74,6 +146,10 @@ func ForEachPlugin() {
}
func LoadPlugins() {
if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
os.Mkdir("./plugins", os.ModePerm)
}
ForEachPlugin()
files, err := ioutil.ReadDir("./plugins")

View File

@ -3,7 +3,9 @@ package plugin
import (
"database/sql"
"html/template"
"io"
"net/http"
"os"
)
var (
@ -34,6 +36,27 @@ func (i Info) Template() *template.Template {
return temp
}
func DownloadFile(filepath string, url string) error {
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}
type Add func(p PluginInfo)
type PluginActions interface {

BIN
slack.so

Binary file not shown.

19
web.go
View File

@ -42,6 +42,7 @@ func RunHTTPServer() {
r.Handle("/settings", http.HandlerFunc(SettingsHandler))
r.Handle("/plugins", http.HandlerFunc(PluginsHandler))
r.Handle("/plugins/download/{name}", http.HandlerFunc(PluginsDownloadHandler))
r.Handle("/help", http.HandlerFunc(HelpHandler))
for _, p := range allPlugins {
@ -251,7 +252,23 @@ func PluginsHandler(w http.ResponseWriter, r *http.Request) {
return
}
tmpl := ParsePlugins("plugins.html")
tmpl.Execute(w, core)
core.FetchPluginRepo()
fmt.Println(core.FetchPluginRepo())
tmpl.Execute(w, &core)
}
func PluginsDownloadHandler(w http.ResponseWriter, r *http.Request) {
auth := IsAuthenticated(r)
if !auth {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
vars := mux.Vars(r)
name := vars["name"]
DownloadPlugin(name)
LoadConfig()
http.Redirect(w, r, "/plugins", http.StatusSeeOther)
}
func HelpHandler(w http.ResponseWriter, r *http.Request) {