mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-10-27 03:26:22 +08:00
129 lines
2.7 KiB
Go
129 lines
2.7 KiB
Go
package model
|
|
|
|
import (
|
|
"archive/zip"
|
|
"encoding/json"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
|
|
. "github.com/mickael-kerjean/filestash/server/common"
|
|
)
|
|
|
|
var PLUGINS = map[string]PluginImpl{}
|
|
|
|
type PluginImpl struct {
|
|
Author string `json:"author"`
|
|
Version string `json:"version"`
|
|
Modules []map[string]string `json:"modules"`
|
|
}
|
|
|
|
func PluginDiscovery() error {
|
|
f, err := os.Open(GetAbsolutePath(PLUGIN_PATH))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
entries, err := f.ReadDir(0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, entry := range entries {
|
|
if entry.IsDir() {
|
|
continue
|
|
}
|
|
fname := entry.Name()
|
|
if strings.HasSuffix(fname, ".zip") == false {
|
|
continue
|
|
}
|
|
name, impl, err := InitModule(entry.Name())
|
|
if err != nil {
|
|
Log.Error("could not initialise module name=%s err=%s", entry.Name(), err.Error())
|
|
continue
|
|
}
|
|
for i := 0; i < len(impl.Modules); i++ {
|
|
switch impl.Modules[i]["type"] {
|
|
case "css":
|
|
b, err := GetPluginFile(name, impl.Modules[i]["entrypoint"])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
Hooks.Register.CSS(string(b))
|
|
case "patch":
|
|
b, err := GetPluginFile(name, impl.Modules[i]["entrypoint"])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
Hooks.Register.StaticPatch(b)
|
|
case "favicon":
|
|
b, err := GetPluginFile(name, impl.Modules[i]["entrypoint"])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
Hooks.Register.Favicon(b)
|
|
}
|
|
}
|
|
PLUGINS[name] = impl
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func GetPluginFile(pluginName string, path string) ([]byte, error) {
|
|
zipReader, err := zip.OpenReader(JoinPath(
|
|
GetAbsolutePath(PLUGIN_PATH),
|
|
pluginName+".zip",
|
|
))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, zipFile := range zipReader.File {
|
|
if zipFile.Name != path {
|
|
continue
|
|
}
|
|
f, err := zipFile.Open()
|
|
if err != nil {
|
|
zipReader.Close()
|
|
return nil, err
|
|
}
|
|
data, err := io.ReadAll(f)
|
|
f.Close()
|
|
zipReader.Close()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return data, nil
|
|
}
|
|
zipReader.Close()
|
|
return nil, ErrNotFound
|
|
}
|
|
|
|
func InitModule(plgName string) (string, PluginImpl, error) {
|
|
var plgImpl = PluginImpl{}
|
|
r, err := zip.OpenReader(JoinPath(GetAbsolutePath(PLUGIN_PATH), plgName))
|
|
plgName = strings.TrimSuffix(plgName, ".zip")
|
|
if err != nil {
|
|
return plgName, plgImpl, err
|
|
}
|
|
defer r.Close()
|
|
|
|
var manifestFile io.ReadCloser
|
|
for _, f := range r.File {
|
|
if f.Name != "manifest.json" {
|
|
continue
|
|
}
|
|
rc, err := f.Open()
|
|
if err != nil {
|
|
return plgName, plgImpl, err
|
|
}
|
|
manifestFile = rc
|
|
break
|
|
}
|
|
if manifestFile == nil {
|
|
return plgName, plgImpl, ErrNotFound
|
|
}
|
|
defer manifestFile.Close()
|
|
if err = json.NewDecoder(manifestFile).Decode(&plgImpl); err != nil {
|
|
return plgName, plgImpl, err
|
|
}
|
|
return plgName, plgImpl, nil
|
|
}
|