github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/pluginlangs.go (about)

     1  package common
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"io/ioutil"
     7  	"path/filepath"
     8  )
     9  
    10  var pluginLangs = make(map[string]PluginLang)
    11  
    12  // For non-native plugins to bind JSON files to. E.g. JS and Lua
    13  type PluginMeta struct {
    14  	UName    string
    15  	Name     string
    16  	Author   string
    17  	URL      string
    18  	Settings string
    19  	Tag      string
    20  
    21  	Skip  bool              // Skip this folder?
    22  	Main  string            // The main file
    23  	Hooks map[string]string // Hooks mapped to functions
    24  }
    25  
    26  type PluginLang interface {
    27  	GetName() string
    28  	GetExts() []string
    29  
    30  	Init() error
    31  	AddPlugin(meta PluginMeta) (*Plugin, error)
    32  	//AddHook(name string, handler interface{}) error
    33  	//RemoveHook(name string, handler interface{})
    34  	//RunHook(name string, data interface{}) interface{}
    35  	//RunVHook(name string data ...interface{}) interface{}
    36  }
    37  
    38  /*
    39  var ext = filepath.Ext(pluginFile.Name())
    40  if ext == ".txt" || ext == ".go" {
    41  	continue
    42  }
    43  */
    44  
    45  func InitPluginLangs() error {
    46  	for _, pluginLang := range pluginLangs {
    47  		pluginLang.Init()
    48  	}
    49  	pluginList, err := GetPluginFiles()
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	for _, pluginItem := range pluginList {
    55  		pluginFile, err := ioutil.ReadFile("./extend/" + pluginItem + "/plugin.json")
    56  		if err != nil {
    57  			return err
    58  		}
    59  
    60  		var plugin PluginMeta
    61  		err = json.Unmarshal(pluginFile, &plugin)
    62  		if err != nil {
    63  			return err
    64  		}
    65  		if plugin.Skip {
    66  			continue
    67  		}
    68  
    69  		e := func(field, name string) error {
    70  			return errors.New("The " + field + " field must not be blank on plugin '" + name + "'")
    71  		}
    72  		if plugin.UName == "" {
    73  			return e("UName", pluginItem)
    74  		}
    75  		if plugin.Name == "" {
    76  			return e("Name", pluginItem)
    77  		}
    78  		if plugin.Author == "" {
    79  			return e("Author", pluginItem)
    80  		}
    81  		if plugin.Main == "" {
    82  			return errors.New("Couldn't find a main file for plugin '" + pluginItem + "'")
    83  		}
    84  
    85  		ext := filepath.Ext(plugin.Main)
    86  		pluginLang, err := ExtToPluginLang(ext)
    87  		if err != nil {
    88  			return err
    89  		}
    90  		pplugin, err := pluginLang.AddPlugin(plugin)
    91  		if err != nil {
    92  			return err
    93  		}
    94  		Plugins[plugin.UName] = pplugin
    95  	}
    96  	return nil
    97  }
    98  
    99  func GetPluginFiles() (pluginList []string, err error) {
   100  	pluginFiles, err := ioutil.ReadDir("./extend")
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	for _, pluginFile := range pluginFiles {
   105  		if !pluginFile.IsDir() {
   106  			continue
   107  		}
   108  		pluginList = append(pluginList, pluginFile.Name())
   109  	}
   110  	return pluginList, nil
   111  }
   112  
   113  func ExtToPluginLang(ext string) (PluginLang, error) {
   114  	for _, pluginLang := range pluginLangs {
   115  		for _, registeredExt := range pluginLang.GetExts() {
   116  			if registeredExt == ext {
   117  				return pluginLang, nil
   118  			}
   119  		}
   120  	}
   121  	return nil, errors.New("No plugin lang handlers are capable of handling extension '" + ext + "'")
   122  }