mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-06 08:22:24 +01:00
chore (about): revamp about page
This commit is contained in:
parent
a96a192f2e
commit
e2f3475bfc
7 changed files with 155 additions and 133 deletions
28
cmd/main.go
28
cmd/main.go
|
|
@ -7,9 +7,10 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/mickael-kerjean/filestash"
|
"github.com/mickael-kerjean/filestash"
|
||||||
. "github.com/mickael-kerjean/filestash/server"
|
"github.com/mickael-kerjean/filestash/server"
|
||||||
. "github.com/mickael-kerjean/filestash/server/common"
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
. "github.com/mickael-kerjean/filestash/server/ctrl"
|
"github.com/mickael-kerjean/filestash/server/ctrl"
|
||||||
|
"github.com/mickael-kerjean/filestash/server/model"
|
||||||
_ "github.com/mickael-kerjean/filestash/server/plugin"
|
_ "github.com/mickael-kerjean/filestash/server/plugin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -18,7 +19,7 @@ func main() {
|
||||||
router *mux.Router = mux.NewRouter()
|
router *mux.Router = mux.NewRouter()
|
||||||
app = App{}
|
app = App{}
|
||||||
)
|
)
|
||||||
Build(router, app)
|
server.Build(router, app)
|
||||||
Run(router, app)
|
Run(router, app)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,21 +28,20 @@ func Run(routes *mux.Router, app App) {
|
||||||
// support many more protocols in the future: HTTPS, HTTP2, TOR or whatever that sounds
|
// support many more protocols in the future: HTTPS, HTTP2, TOR or whatever that sounds
|
||||||
// fancy I don't know much when this got written: IPFS, solid, ...
|
// fancy I don't know much when this got written: IPFS, solid, ...
|
||||||
Log.Info("Filestash %s starting", APP_VERSION)
|
Log.Info("Filestash %s starting", APP_VERSION)
|
||||||
|
check(InitLogger(), "Logger init failed. err=%s")
|
||||||
|
check(InitConfig(), "Config init failed. err=%s")
|
||||||
|
check(model.PluginDiscovery(), "Plugin Discovery failed. err=%s")
|
||||||
|
ctrl.InitPluginList(embed.EmbedPluginList, model.PLUGINS)
|
||||||
if len(Hooks.Get.Starter()) == 0 {
|
if len(Hooks.Get.Starter()) == 0 {
|
||||||
Log.Warning("No starter plugin available")
|
check(ErrNotFound, "Missing starter plugin. err=%s")
|
||||||
os.Exit(1)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
InitLogger()
|
|
||||||
InitConfig()
|
|
||||||
InitPluginList(embed.EmbedPluginList)
|
|
||||||
for _, obj := range Hooks.Get.HttpEndpoint() {
|
for _, obj := range Hooks.Get.HttpEndpoint() {
|
||||||
obj(routes, &app)
|
obj(routes, &app)
|
||||||
}
|
}
|
||||||
for _, fn := range Hooks.Get.Onload() {
|
for _, fn := range Hooks.Get.Onload() {
|
||||||
fn()
|
fn()
|
||||||
}
|
}
|
||||||
CatchAll(routes, app)
|
server.CatchAll(routes, app)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for _, obj := range Hooks.Get.Starter() {
|
for _, obj := range Hooks.Get.Starter() {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
@ -52,3 +52,11 @@ func Run(routes *mux.Router, app App) {
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func check(err error, msg string) {
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log.Error(msg, err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,13 @@ type FormElement struct {
|
||||||
Required bool `json:"required"`
|
Required bool `json:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitConfig() {
|
func InitConfig() error {
|
||||||
Config = NewConfiguration()
|
Config = NewConfiguration()
|
||||||
Config.Load()
|
if err := Config.Load(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
Config.Initialise()
|
Config.Initialise()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfiguration() Configuration {
|
func NewConfiguration() Configuration {
|
||||||
|
|
@ -218,11 +221,11 @@ func (this *Form) Iterator() []FormIterator {
|
||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Configuration) Load() {
|
func (this *Configuration) Load() error {
|
||||||
cFile, err := LoadConfig()
|
cFile, err := LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log.Error("config::load %s", err)
|
Log.Error("config::load %s", err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract enabled backends
|
// Extract enabled backends
|
||||||
|
|
@ -251,7 +254,7 @@ func (this *Configuration) Load() {
|
||||||
this.onChange[i].Listener <- nil
|
this.onChange[i].Listener <- nil
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type JSONIterator struct {
|
type JSONIterator struct {
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ var (
|
||||||
logfile *os.File
|
logfile *os.File
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitLogger() {
|
func InitLogger() error {
|
||||||
var err error
|
logfile, err := os.OpenFile(GetAbsolutePath(LOG_PATH, "access.log"), os.O_APPEND|os.O_WRONLY|os.O_CREATE, os.ModePerm)
|
||||||
logfile, err = os.OpenFile(GetAbsolutePath(LOG_PATH, "access.log"), os.O_APPEND|os.O_WRONLY|os.O_CREATE, os.ModePerm)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Printf("ERROR log file: %+v", err)
|
slog.Printf("ERROR log file: %+v", err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
logfile.WriteString("")
|
logfile.WriteString("")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type log struct {
|
type log struct {
|
||||||
|
|
|
||||||
124
server/ctrl/about.go
Normal file
124
server/ctrl/about.go
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
package ctrl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
. "github.com/mickael-kerjean/filestash/server/common"
|
||||||
|
"github.com/mickael-kerjean/filestash/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var listOfPlugins = struct {
|
||||||
|
oss []string
|
||||||
|
enterprise []string
|
||||||
|
custom []string
|
||||||
|
apps []string
|
||||||
|
}{}
|
||||||
|
|
||||||
|
func InitPluginList(code []byte, plgs map[string]model.PluginImpl) {
|
||||||
|
listOfPackages := regexp.MustCompile(`\t_?\s*\"(github.com/[^\"]+)`).FindAllStringSubmatch(string(code), -1)
|
||||||
|
for _, packageNameMatch := range listOfPackages {
|
||||||
|
if len(packageNameMatch) != 2 {
|
||||||
|
Log.Error("ctrl::static error=assertion_failed msg=invalid_match_size arg=%d", len(packageNameMatch))
|
||||||
|
}
|
||||||
|
packageName := packageNameMatch[1]
|
||||||
|
packageShortName := filepath.Base(packageName)
|
||||||
|
|
||||||
|
if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/server/plugin/") {
|
||||||
|
listOfPlugins.oss = append(listOfPlugins.oss, packageShortName)
|
||||||
|
} else if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/filestash-enterprise/plugins/") {
|
||||||
|
listOfPlugins.enterprise = append(listOfPlugins.enterprise, packageShortName)
|
||||||
|
} else if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/filestash-enterprise/customers/") {
|
||||||
|
listOfPlugins.custom = append(listOfPlugins.custom, packageShortName)
|
||||||
|
} else {
|
||||||
|
listOfPlugins.custom = append(listOfPlugins.custom, packageShortName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for name, _ := range plgs {
|
||||||
|
listOfPlugins.apps = append(listOfPlugins.apps, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AboutHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||||
|
t, _ := template.
|
||||||
|
New("about").
|
||||||
|
Funcs(map[string]interface{}{
|
||||||
|
"renderPlugin": func(lstr string, commit string) string {
|
||||||
|
if len(lstr) == 0 {
|
||||||
|
return "N/A"
|
||||||
|
} else if commit == "" {
|
||||||
|
return html.EscapeString(lstr)
|
||||||
|
}
|
||||||
|
list := strings.Split(lstr, " ")
|
||||||
|
for i, _ := range list {
|
||||||
|
list[i] = `<a href="https://github.com/mickael-kerjean/filestash/tree/` + commit +
|
||||||
|
`/server/plugin/` + html.EscapeString(list[i]) + `" target="_blank">` + html.EscapeString(list[i]) + `</a>`
|
||||||
|
}
|
||||||
|
return strings.Join(list, " ")
|
||||||
|
},
|
||||||
|
}).
|
||||||
|
Parse(Page(`
|
||||||
|
<h1> {{ .Version }} </h1>
|
||||||
|
<table>
|
||||||
|
<tr> <td style="width:150px;"> Commit hash </td> <td> <a href="https://github.com/mickael-kerjean/filestash/tree/{{ .CommitHash }}">{{ .CommitHash }}</a> </td> </tr>
|
||||||
|
<tr> <td> Binary hash </td> <td> {{ index .Checksum 0}} </td> </tr>
|
||||||
|
<tr> <td> Config hash </td> <td> {{ index .Checksum 1}} </td> </tr>
|
||||||
|
<tr> <td> License </td> <td> {{ .License }} </td> </tr>
|
||||||
|
<tr>
|
||||||
|
<td> Plugins </td>
|
||||||
|
<td>
|
||||||
|
STANDARD[<span class="small">{{ renderPlugin (index .Plugins 0) .CommitHash }}</span>]
|
||||||
|
<br/>
|
||||||
|
APPS[<span class="small">{{ renderPlugin (index .Plugins 3) "" }}</span>]
|
||||||
|
<br/>
|
||||||
|
ENTERPRISE[<span class="small">{{ renderPlugin (index .Plugins 1) "" }}</span>]
|
||||||
|
<br/>
|
||||||
|
CUSTOM[<span class="small">{{ renderPlugin (index .Plugins 2) "" }}</span>]
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body.common_response_page { background: var(--bg-color); }
|
||||||
|
table { margin: 0 auto; font-family: monospace; opacity: 0.8; max-width: 1000px; width: 95%;}
|
||||||
|
table td { text-align: right; padding-left: 10px; vertical-align: top; }
|
||||||
|
table td span.small { font-size:0.8rem; }
|
||||||
|
table a { color: inherit; text-decoration: none; }
|
||||||
|
</style>
|
||||||
|
`))
|
||||||
|
hashFileContent := func(path string, n int) string {
|
||||||
|
f, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
return HashStream(f, n)
|
||||||
|
}
|
||||||
|
t.Execute(res, struct {
|
||||||
|
Version string
|
||||||
|
CommitHash string
|
||||||
|
Checksum []string
|
||||||
|
License string
|
||||||
|
Plugins []string
|
||||||
|
}{
|
||||||
|
Version: fmt.Sprintf("Filestash %s.%s", APP_VERSION, BUILD_DATE),
|
||||||
|
CommitHash: BUILD_REF,
|
||||||
|
Checksum: []string{
|
||||||
|
hashFileContent(GetAbsolutePath("filestash"), 0),
|
||||||
|
hashFileContent(GetAbsolutePath(CONFIG_PATH, "config.json"), 0),
|
||||||
|
},
|
||||||
|
License: strings.ToUpper(LICENSE),
|
||||||
|
Plugins: []string{
|
||||||
|
strings.Join(listOfPlugins.oss, " "),
|
||||||
|
strings.Join(listOfPlugins.enterprise, " "),
|
||||||
|
strings.Join(listOfPlugins.custom, " "),
|
||||||
|
strings.Join(listOfPlugins.apps, " "),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -13,15 +13,6 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
Hooks.Register.Onload(func() {
|
|
||||||
if err := model.PluginDiscovery(); err != nil {
|
|
||||||
Log.Error("Plugin Discovery failed. err=%s", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func PluginExportHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
|
func PluginExportHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||||
plgExports := map[string][]string{}
|
plgExports := map[string][]string{}
|
||||||
for name, plg := range model.PLUGINS {
|
for name, plg := range model.PLUGINS {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
|
@ -105,87 +104,6 @@ func NotFoundHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||||
SendErrorResult(res, ErrNotFound)
|
SendErrorResult(res, ErrNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
var listOfPlugins map[string][]string = map[string][]string{
|
|
||||||
"oss": []string{},
|
|
||||||
"enterprise": []string{},
|
|
||||||
"custom": []string{},
|
|
||||||
}
|
|
||||||
|
|
||||||
func AboutHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
|
|
||||||
t, _ := template.
|
|
||||||
New("about").
|
|
||||||
Funcs(map[string]interface{}{
|
|
||||||
"renderPlugin": func(lstr string, commit string) string {
|
|
||||||
if len(lstr) == 0 {
|
|
||||||
return "N/A"
|
|
||||||
} else if commit == "" {
|
|
||||||
return lstr
|
|
||||||
}
|
|
||||||
list := strings.Split(lstr, " ")
|
|
||||||
for i, _ := range list {
|
|
||||||
list[i] = `<a href="https://github.com/mickael-kerjean/filestash/tree/` + commit +
|
|
||||||
`/server/plugin/` + list[i] + `" target="_blank">` + list[i] + `</a>`
|
|
||||||
}
|
|
||||||
return strings.Join(list, " ")
|
|
||||||
},
|
|
||||||
}).
|
|
||||||
Parse(Page(`
|
|
||||||
<h1> {{ .Version }} </h1>
|
|
||||||
<table>
|
|
||||||
<tr> <td style="width:150px;"> Commit hash </td> <td> <a href="https://github.com/mickael-kerjean/filestash/tree/{{ .CommitHash }}">{{ .CommitHash }}</a> </td> </tr>
|
|
||||||
<tr> <td> Binary hash </td> <td> {{ index .Checksum 0}} </td> </tr>
|
|
||||||
<tr> <td> Config hash </td> <td> {{ index .Checksum 1}} </td> </tr>
|
|
||||||
<tr> <td> License </td> <td> {{ .License }} </td> </tr>
|
|
||||||
<tr>
|
|
||||||
<td> Plugins </td>
|
|
||||||
<td>
|
|
||||||
STANDARD[<span class="small">{{ renderPlugin (index .Plugins 0) .CommitHash }}</span>]
|
|
||||||
<br/>
|
|
||||||
ENTERPRISE[<span class="small">{{ renderPlugin (index .Plugins 1) "" }}</span>]
|
|
||||||
<br/>
|
|
||||||
CUSTOM[<span class="small">{{ renderPlugin (index .Plugins 2) "" }}</span>]
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body.common_response_page { background: var(--bg-color); }
|
|
||||||
table { margin: 0 auto; font-family: monospace; opacity: 0.8; max-width: 1000px; width: 95%;}
|
|
||||||
table td { text-align: right; padding-left: 10px; vertical-align: top; }
|
|
||||||
table td span.small { font-size:0.8rem; }
|
|
||||||
table a { color: inherit; text-decoration: none; }
|
|
||||||
</style>
|
|
||||||
`))
|
|
||||||
hashFileContent := func(path string, n int) string {
|
|
||||||
f, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
return HashStream(f, n)
|
|
||||||
}
|
|
||||||
t.Execute(res, struct {
|
|
||||||
Version string
|
|
||||||
CommitHash string
|
|
||||||
Checksum []string
|
|
||||||
License string
|
|
||||||
Plugins []string
|
|
||||||
}{
|
|
||||||
Version: fmt.Sprintf("Filestash %s.%s", APP_VERSION, BUILD_DATE),
|
|
||||||
CommitHash: BUILD_REF,
|
|
||||||
Checksum: []string{
|
|
||||||
hashFileContent(GetAbsolutePath("filestash"), 0),
|
|
||||||
hashFileContent(GetAbsolutePath(CONFIG_PATH, "config.json"), 0),
|
|
||||||
},
|
|
||||||
License: strings.ToUpper(LICENSE),
|
|
||||||
Plugins: []string{
|
|
||||||
strings.Join(listOfPlugins["oss"], " "),
|
|
||||||
strings.Join(listOfPlugins["enterprise"], " "),
|
|
||||||
strings.Join(listOfPlugins["custom"], " "),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ManifestHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
|
func ManifestHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||||
res.WriteHeader(http.StatusOK)
|
res.WriteHeader(http.StatusOK)
|
||||||
res.Write([]byte(fmt.Sprintf(`{
|
res.Write([]byte(fmt.Sprintf(`{
|
||||||
|
|
@ -234,7 +152,6 @@ func ServeFile(chroot string) func(*App, http.ResponseWriter, *http.Request) {
|
||||||
)
|
)
|
||||||
head := res.Header()
|
head := res.Header()
|
||||||
|
|
||||||
// case: patch must be apply because of a "StaticPatch" plugin
|
|
||||||
if f := applyPatch(filePath); f != nil {
|
if f := applyPatch(filePath); f != nil {
|
||||||
head.Set("Content-Type", GetMimeType(filepath.Ext(filePath)))
|
head.Set("Content-Type", GetMimeType(filepath.Ext(filePath)))
|
||||||
head.Set("Cache-Control", "no-cache")
|
head.Set("Cache-Control", "no-cache")
|
||||||
|
|
@ -405,27 +322,6 @@ func applyPatch(filePath string) (file *bytes.Buffer) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitPluginList(code []byte) {
|
|
||||||
listOfPackages := regexp.MustCompile(`\t_?\s*\"(github.com/[^\"]+)`).FindAllStringSubmatch(string(code), -1)
|
|
||||||
for _, packageNameMatch := range listOfPackages {
|
|
||||||
if len(packageNameMatch) != 2 {
|
|
||||||
Log.Error("ctrl::static error=assertion_failed msg=invalid_match_size arg=%d", len(packageNameMatch))
|
|
||||||
}
|
|
||||||
packageName := packageNameMatch[1]
|
|
||||||
packageShortName := filepath.Base(packageName)
|
|
||||||
|
|
||||||
if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/server/plugin/") {
|
|
||||||
listOfPlugins["oss"] = append(listOfPlugins["oss"], packageShortName)
|
|
||||||
} else if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/filestash-enterprise/plugins/") {
|
|
||||||
listOfPlugins["enterprise"] = append(listOfPlugins["enterprise"], packageShortName)
|
|
||||||
} else if strings.HasPrefix(packageName, "github.com/mickael-kerjean/filestash/filestash-enterprise/customers/") {
|
|
||||||
listOfPlugins["custom"] = append(listOfPlugins["custom"], packageShortName)
|
|
||||||
} else {
|
|
||||||
listOfPlugins["custom"] = append(listOfPlugins["custom"], packageShortName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func preload() string {
|
func preload() string {
|
||||||
out, _ := json.Marshal([][]string{
|
out, _ := json.Marshal([][]string{
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package routes
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue