1// This program is free software: you can redistribute it and/or modify2// it under the terms of the GNU Affero General Public License as3// published by the Free Software Foundation, either version 3 of the4// License, or (at your option) any later version.5//6// This program is distributed in the hope that it will be useful, but7// WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU9// Affero General Public License for more details.10//11// You should have received a copy of the GNU Affero General Public12// License along with this program. If not, see <http://www.gnu.org/licenses/>.1314package modules1516import (17 "encoding/json"18 "fmt"19 "github.com/nmeum/marvin/irc"20 "io/ioutil"21 "os"22 "path/filepath"23 "strings"24)2526type Module interface {27 Name() string28 Help() string29 Load(*irc.Client) error30 Defaults()31}3233type ModuleSet struct {34 client *irc.Client35 modules []Module36 configs string37}3839func NewModuleSet(client *irc.Client, configs string) *ModuleSet {40 return &ModuleSet{client: client, configs: configs}41}4243func (m *ModuleSet) Register(module Module) {44 m.modules = append(m.modules, module)45}4647func (m *ModuleSet) LoadAll() error {48 if err := os.MkdirAll(m.configs, 0755); err != nil {49 return err50 }5152 for _, module := range m.modules {53 fn := fmt.Sprintf("%s.json", module.Name())54 fp := filepath.Join(m.configs, fn)5556 module.Defaults()57 data, err := ioutil.ReadFile(fp)58 if err == nil {59 if err := json.Unmarshal(data, &module); err != nil {60 return err61 }62 } else if !os.IsNotExist(err) {63 return err64 }6566 if err := module.Load(m.client); err != nil {67 return err68 }69 }7071 m.client.CmdHook("privmsg", m.helpCmd)72 m.client.CmdHook("privmsg", m.moduleCmd)73 m.client.CmdHook("privmsg", m.modulesCmd)7475 return nil76}7778func (m *ModuleSet) findModule(name string) Module {79 for _, module := range m.modules {80 if module.Name() == name {81 return module82 }83 }8485 return nil86}8788func (m *ModuleSet) helpCmd(client *irc.Client, msg irc.Message) error {89 if msg.Data != "!help" {90 return nil91 }9293 return client.Write("NOTICE %s :%s", msg.Receiver,94 "Use !help MODULE to see the help message for the given module, use !modules to list all modules.")95}9697func (m *ModuleSet) modulesCmd(client *irc.Client, msg irc.Message) error {98 if msg.Data != "!modules" || len(m.modules) <= 0 {99 return nil100 }101102 var names []string103 for _, module := range m.modules {104 names = append(names, module.Name())105 }106107 help := fmt.Sprintf("The following modules are available: %s",108 strings.Join(names, ", "))109110 return client.Write("NOTICE %s :%s", msg.Receiver, help)111}112113func (m *ModuleSet) moduleCmd(client *irc.Client, msg irc.Message) error {114 splited := strings.Fields(msg.Data)115 if len(splited) < 2 || splited[0] != "!help" {116 return nil117 }118119 name := strings.ToLower(splited[1])120 module := m.findModule(name)121 if module == nil {122 return client.Write("NOTICE %s :Module %q isn't installed",123 msg.Receiver, name)124 }125126 return client.Write("NOTICE %s :%s: %s",127 msg.Receiver, module.Name(), module.Help())128}