// © 2019 the CatBase Authors under the WTFPL. See AUTHORS for the list of authors. package nerdepedia import ( "bufio" "fmt" "html" "net/http" "strings" "github.com/velour/catbase/bot" "github.com/velour/catbase/bot/msg" "github.com/velour/catbase/config" ) const ( descriptionPrefix = "" ) type HTTPClient interface { Do(req *http.Request) (*http.Response, error) } var ( client HTTPClient ) func init() { client = &http.Client{} } type NerdepediaPlugin struct { bot bot.Bot config *config.Config } // NewNerdepediaPlugin creates a new NerdepediaPlugin with the Plugin interface func New(b bot.Bot) *NerdepediaPlugin { np := &NerdepediaPlugin{ bot: b, config: b.Config(), } b.Register(np, bot.Message, np.message) b.Register(np, bot.Help, np.help) return np } func defaultSites() map[string]string { starWars := "http://starwars.wikia.com/wiki/Special:Random" starTrek := "http://memory-alpha.wikia.com/wiki/Special:Random" dune := "http://dune.wikia.com/wiki/Special:Random" lotr := "http://lotr.wikia.com/wiki/Special:Random" pokemon := "http://pokemon.wikia.com/wiki/Special:Random" return map[string]string{ "may the force be with you": starWars, "help me obi-wan": starWars, "beam me up scotty": starTrek, "live long and prosper": starTrek, "bless the maker": dune, "i must not fear": dune, "the spice must flow": dune, "my precious": lotr, "one ring to rule them all": lotr, "one does not simply walk into mordor": lotr, "pikachu i choose you": pokemon, "gotta catch em all": pokemon, } } // Message responds to the bot hook on recieving messages. // This function returns true if the plugin responds in a meaningful way to the users message. // Otherwise, the function returns false and the bot continues execution of other plugins. func (p *NerdepediaPlugin) message(c bot.Connector, kind bot.Kind, message msg.Message, args ...interface{}) bool { lowerCase := strings.ToLower(message.Body) query := "" queries := p.config.GetMap("nerdepedia.sites", defaultSites()) for k, v := range queries { if lowerCase == k { query = v break } } if query != "" { req, _ := http.NewRequest(http.MethodGet, query, nil) resp, err := client.Do(req) if err != nil { return false } defer resp.Body.Close() scanner := bufio.NewScanner(resp.Body) link := "" description := "" for scanner.Scan() { line := scanner.Text() if description == "" { index := strings.Index(line, descriptionPrefix) if index >= 0 { description = html.UnescapeString(html.UnescapeString(strings.TrimSuffix(strings.TrimPrefix(line, descriptionPrefix), closingTagSuffix))) } } if link == "" { index := strings.Index(line, linkPrefix) if index >= 0 { link = strings.TrimSuffix(strings.TrimPrefix(line, linkPrefix), closingTagSuffix) } } if description != "" && link != "" { p.bot.Send(c, bot.Message, message.Channel, fmt.Sprintf("%s (%s)", description, link)) return true } } } return false } // Help responds to help requests. Every plugin must implement a help function. func (p *NerdepediaPlugin) help(c bot.Connector, kind bot.Kind, message msg.Message, args ...interface{}) bool { p.bot.Send(c, bot.Message, message.Channel, "nerd stuff") return true }