Refactored to not use full URL imports, Goland stuff, pulled command implementations into a separate file

master
chiefnoah 5 years ago committed by Noah Pederson
parent 5ebf95020d
commit e52b0e96eb

3
.gitignore vendored

@ -24,5 +24,6 @@ _testmain.go
*.test
*.prof
*.ini
config.ini
*.db
images/

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
</state>
</component>

@ -1,23 +0,0 @@
<component name="libraryTable">
<library name="GOPATH &lt;GoGetMeHentai&gt;">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../golang.org" />
<root url="file://$PROJECT_DIR$/../../../9fans.net" />
<root url="file://$PROJECT_DIR$/../.." />
<root url="file://$PROJECT_DIR$/../../../sourcegraph.com" />
<root url="file://$PROJECT_DIR$/../../../gopkg.in" />
<root url="file://$PROJECT_DIR$/../../../github.com" />
</CLASSES>
<SOURCES>
<root url="file://$PROJECT_DIR$/../../../golang.org" />
<root url="file://$PROJECT_DIR$/../../../9fans.net" />
<root url="file://$PROJECT_DIR$/../.." />
<root url="file://$PROJECT_DIR$/../../../sourcegraph.com" />
<root url="file://$PROJECT_DIR$/../../../gopkg.in" />
<root url="file://$PROJECT_DIR$/../../../github.com" />
</SOURCES>
<excluded>
<root url="file://$PROJECT_DIR$" />
</excluded>
</library>
</component>

@ -1,10 +0,0 @@
<component name="libraryTable">
<library name="Go SDK">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../../../../Go/src" />
</CLASSES>
<SOURCES>
<root url="file://$PROJECT_DIR$/../../../../../Go/src" />
</SOURCES>
</library>
</component>

@ -4,6 +4,5 @@
<content url="file://$MODULE_DIR$" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="GOPATH &lt;GoGetMeHentai&gt;" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Go SDK" level="project" />
</component>
</module>

@ -0,0 +1,165 @@
package commands
import (
"github.com/bwmarrin/discordgo"
"log"
"strings"
"../danbooru"
"net/url"
"../redditbooru"
"io/ioutil"
"encoding/base64"
"math/rand"
)
func helpCommand(s *discordgo.Session, c *discordgo.Message, tags []string, removeCommand bool) {
output := ""
for _, command := range enabledCommands {
for trigger := range command.Triggers {
output += trigger + ", "
}
output += " - " + command.Description + "\n"
}
message, err := s.ChannelMessageSend(c.ChannelID, output)
if err != nil || message == nil {
log.Printf("Unable to send messagea: %s", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
//Implements Command interface
//Searches danbooru for the provided tags
func danbooruSearch(s *discordgo.Session, c *discordgo.Message, tags []string, removeCommand bool) {
if len(c.Content) < 2 {
return
}
query := strings.Split(c.Content, " ")[1:]
query = append(query, tags...)
post, err := danbooru.SearchPost(query)
messageContent := ""
if err != nil || tags == nil || post.LargeFileUrl == "" {
log.Printf("Unable to retrieve an image")
messageContent = "I'm sorry, I was unable to find any images, @" + c.Author.Username + "#" + c.Author.Discriminator + " senpai."
} else {
messageContent = "I was able to find this for you @" + c.Author.Username + "#" + c.Author.Discriminator + " with tags (" + strings.Join(tags, ", ") + ") " + danbooru.BASE + post.LargeFileUrl
addCommandEntry(s, c)
}
message, err := s.ChannelMessageSend(c.ChannelID, messageContent)
if err != nil || message == nil {
log.Printf("Unable to send messagea: %s", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
func myAnimeListSearch(s *discordgo.Session, c *discordgo.Message, a []string, removeCommand bool) {
}
func hentaiSearch(s *discordgo.Session, c *discordgo.Message, a []string, removeCommand bool) {
}
func mangaSearch(s *discordgo.Session, c *discordgo.Message, a []string, removeCommand bool) {
}
func redditBooruSearch(s *discordgo.Session, c *discordgo.Message, additionalParams []string, removeCommand bool) {
if len(c.Content) < 2 {
return
}
query := strings.Split(c.Content, " ")[1:] //drop the command part of the message
p := ""
if len(query) == 1 {
p = query[0]
} else if len(query) > 1 {
p = url.QueryEscape(strings.Join(query, " ")) //join the params with spaces, and URL Query escape them
}
log.Printf("Retrieved arguments: %+s", query)
post, err := redditbooru.Search(p)
messageContent := ""
if err != nil || query == nil || post.CDNURL == "" {
log.Print("Unable to retrieve image from Redditbooru")
messageContent = "I'm sorry, I was unable to find any images for that query, @" + c.Author.Username + "#" + c.Author.Discriminator + " senpai."
} else {
messageContent = "I found this for you @" + c.Author.Username + "#" + c.Author.Discriminator + " with query \"" + strings.Join(query, ", ") + "\"" + post.CDNURL
addCommandEntry(s, c)
}
message, err := s.ChannelMessageSend(c.ChannelID, messageContent)
if err != nil || message == nil {
log.Print("Unable to send message to discord: ", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
func lennyFaceReply(s *discordgo.Session, c *discordgo.Message, additionalParams []string, removeCommand bool) {
if len(c.Content) < 2 {
return
}
command := strings.Split(c.Content, " ")[0][1:]
messageContent := ""
if command == "lenny" {
messageContent = "( ͡° ͜ʖ ͡°)"
} else if command == "asianlenny" {
messageContent = "( ͡° ╭ʖ╮ ͡° )"
} else if command == "apple" {
messageContent = "\\_(:3 」__ __ )_"
}
addCommandEntry(s, c)
message, err := s.ChannelMessageSend(c.ChannelID, messageContent)
if err != nil || message == nil {
log.Print("Unable to send message to discord: ", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
func randomProfileImage(s *discordgo.Session, c *discordgo.Message, additionalParams []string, removeCommand bool) {
botUser, err := s.User("@me")
if err != nil {
log.Print("Unable to get bot user!")
return
}
files, err := ioutil.ReadDir("./images")
if err != nil || len(files) == 0 {
log.Print("Unable to scan directory for images: ", err)
return
}
r := rand.Intn(len(files))
image := "data:image/jpeg;base64,"
data, err := ioutil.ReadFile("./images/" + files[r].Name())
if err != nil {
log.Print("Unable to load image file :(, ", err)
return
}
image += base64.StdEncoding.EncodeToString(data)
_, err = s.UserUpdate("", "", botUser.Username, image, "")
if err != nil {
log.Print("Unable to update profile picture ", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
func echoCommand(s *discordgo.Session, c *discordgo.Message, additionalParams []string, removeCommand bool) {
messageSplit := strings.Split(c.Content, " ")[1:]
messageContent := strings.Join(messageSplit, " ")
message, err := s.ChannelMessageSend(c.ChannelID, messageContent)
if err != nil || message == nil {
log.Print("Unable to send message to discord: ", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}

@ -4,14 +4,8 @@ import (
"github.com/bwmarrin/discordgo"
"strings"
"log"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/danbooru"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/redditbooru"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/database"
"net/url"
"io/ioutil"
"math/rand"
"encoding/base64"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/config"
"../config"
"../database"
"time"
"strconv"
)
@ -20,100 +14,100 @@ import (
=================================================================================================
*/
var help = CommandProcess{
Triggers: map[string]interface{}{"help": nil},
Run: nil,
Triggers: map[string]interface{}{"help": nil},
Run: nil,
AdditionalParams: []string{},
DeleteCommand: true,
Description: "Displays this dialog",
DeleteCommand: true,
Description: "Displays this dialog",
}
var dbooru = CommandProcess{
Triggers: map[string]interface{}{"d": nil, "danbooru": nil, "moe": nil},
Run: danbooruSearch,
Triggers: map[string]interface{}{"d": nil, "danbooru": nil, "moe": nil},
Run: danbooruSearch,
AdditionalParams: []string{"rating:safe"},
DeleteCommand: false,
Description: "Searches danbooru for tags. Format is ]d [tag, tag, etc.]",
DeleteCommand: false,
Description: "Searches danbooru for tags. Format is ]d [tag, tag, etc.]",
}
var dfetch = CommandProcess{
Triggers: map[string]interface{}{"search": nil, "fetch": nil},
Run: danbooruSearch,
Triggers: map[string]interface{}{"search": nil, "fetch": nil},
Run: danbooruSearch,
AdditionalParams: []string{},
DeleteCommand: true,
Description: "same as d/danbooru/moe but doesn't delete the query message.",
DeleteCommand: true,
Description: "same as d/danbooru/moe but doesn't delete the query message.",
}
var anime = CommandProcess{
Triggers: map[string]interface{}{"a": nil, "anime": nil, "show": nil},
Run: myAnimeListSearch,
Triggers: map[string]interface{}{"a": nil, "anime": nil, "show": nil},
Run: myAnimeListSearch,
AdditionalParams: []string{},
DeleteCommand: true,
Description: "Not yet implemented.",
DeleteCommand: true,
Description: "Not yet implemented.",
}
var manga = CommandProcess{
Triggers: map[string]interface{}{"m": nil, "manga": nil},
Run: mangaSearch,
Triggers: map[string]interface{}{"m": nil, "manga": nil},
Run: mangaSearch,
AdditionalParams: []string{},
Description: "Not yet implemented.",
Description: "Not yet implemented.",
}
var hentai = CommandProcess{
Triggers: map[string]interface{}{"h": nil, "lewd": nil, "hentai": nil},
Run: danbooruSearch,
Triggers: map[string]interface{}{"h": nil, "lewd": nil, "hentai": nil},
Run: danbooruSearch,
AdditionalParams: []string{"rating:explicit"},
DeleteCommand: true,
Description: "Searches danbooru using the explicit tag. NSFW! Format is ]h [tag, tag, etc.]",
DeleteCommand: true,
Description: "Searches danbooru using the explicit tag. NSFW! Format is ]h [tag, tag, etc.]",
}
var redditBooru = CommandProcess{
Triggers: map[string]interface{}{"rb": nil, "redditbooru": nil, },
Run: redditBooruSearch,
Triggers: map[string]interface{}{"rb": nil, "redditbooru": nil,},
Run: redditBooruSearch,
AdditionalParams: []string{},
DeleteCommand: true,
Description: "Searches RedditBooru for the provided tags. Format is ]rb [tag, tag, etc.]",
DeleteCommand: true,
Description: "Searches RedditBooru for the provided tags. Format is ]rb [tag, tag, etc.]",
}
var lennyFace = CommandProcess{
Triggers: map[string]interface{}{"lenny": nil, "asianlenny": nil, "apple": nil },
Run: lennyFaceReply,
Triggers: map[string]interface{}{"lenny": nil, "asianlenny": nil, "apple": nil},
Run: lennyFaceReply,
AdditionalParams: []string{},
DeleteCommand: true,
Description: "Prints a lenny face to the chat.",
DeleteCommand: true,
Description: "Prints a lenny face to the chat.",
}
//Does exact opposite of what you'd expect
var loli = CommandProcess{
Triggers: map[string]interface{}{"loli": nil, "anands-favorite": nil},
Run: danbooruSearch,
var pettanko = CommandProcess{
Triggers: map[string]interface{}{"anands-favorite": nil, "pettanko": nil},
Run: danbooruSearch,
AdditionalParams: []string{"+small_breasts"},
DeleteCommand: false,
Description: "Anands favorite search. Finds best chest size images.",
DeleteCommand: false,
Description: "Anands favorite search. Finds best chest size images.",
}
var profile = CommandProcess{
Triggers: map[string]interface{}{"profile": nil, "pr": nil},
Run: randomProfileImage,
Triggers: map[string]interface{}{"profile": nil, "pr": nil},
Run: randomProfileImage,
AdditionalParams: []string{},
DeleteCommand: true,
Description: "Changes the profile picture of the bot.",
DeleteCommand: true,
Description: "Changes the profile picture of the bot.",
}
var echo = CommandProcess{
Triggers: map[string]interface{}{"echo": nil, "say": nil},
Run: echoCommand,
Triggers: map[string]interface{}{"echo": nil, "say": nil},
Run: echoCommand,
AdditionalParams: []string{},
DeleteCommand: true,
Description: "Make the bot say things for you.",
DeleteCommand: true,
Description: "Make the bot say things for you.",
}
/*
=================================================================================================
*/
//Commands MUST be specified here to be checked.
var enabledCommands []CommandProcess = []CommandProcess{dbooru, dfetch, anime, hentai, loli, manga, redditBooru, lennyFace, profile, echo}
var enabledCommands []CommandProcess = []CommandProcess{dbooru, dfetch, anime, hentai, pettanko, manga, redditBooru, lennyFace, profile, echo}
//Wraps command triggers, additional parameters, and explicitly defines the function to be called when a command is typed
type CommandProcess struct {
Triggers map[string]interface{} //Maps for fast lookup, we don't actually care about what they hold
Run func(*discordgo.Session, *discordgo.Message, []string, bool) //I explicity define a function that implements Command so we can just loop through all the CommandProcesses and call Run generically
AdditionalParams []string
DeleteCommand bool
Description string
Description string
}
var cfg *config.ConfigWrapper
func Init() {
cfg = config.LoadConfig()
}
@ -141,7 +135,7 @@ func ParseCommand(s *discordgo.Session, c *discordgo.Message) {
} else {
timeoutMessage(s, c, d)
}
//Explicitly check this one otherwise we get a circular reference
//Explicitly check this one otherwise we get a circular reference
}
}
if contains(help.Triggers, command) {
@ -151,8 +145,8 @@ func ParseCommand(s *discordgo.Session, c *discordgo.Message) {
}
func timeoutMessage(s *discordgo.Session, c *discordgo.Message, timeLeft int64) {
message, err := s.ChannelMessageSend(c.ChannelID, "You're going to fast <@!" + c.Author.ID + ">! please wait " +
strconv.Itoa(int(cfg.AppConfig.CommandTimeout - timeLeft)) + " more seconds")
message, err := s.ChannelMessageSend(c.ChannelID, "You're going to fast <@!" + c.Author.ID + ">! please wait "+
strconv.Itoa(int(cfg.AppConfig.CommandTimeout-timeLeft))+ " more seconds")
if err != nil || message == nil {
log.Printf("Unable to send message to channel: %s", err)
}
@ -177,156 +171,3 @@ func contains(set map[string]interface{}, s string) bool {
_, ok := set[s]
return ok
}
func helpCommand(s *discordgo.Session, c *discordgo.Message, tags []string, removeCommand bool) {
output := ""
for _, command := range enabledCommands {
for trigger := range command.Triggers {
output += trigger + ", "
}
output += " - " + command.Description + "\n"
}
message, err := s.ChannelMessageSend(c.ChannelID, output)
if err != nil || message == nil {
log.Printf("Unable to send messagea: %s", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
//Implements Command interface
//Searches danbooru for the provided tags
func danbooruSearch(s *discordgo.Session, c *discordgo.Message, tags []string, removeCommand bool) {
if len(c.Content) < 2 {
return
}
query := strings.Split(c.Content, " ")[1:]
query = append(query, tags...)
post, err := danbooru.SearchPost(query)
messageContent := ""
if err != nil || tags == nil || post.LargeFileUrl == "" {
log.Printf("Unable to retrieve an image")
messageContent = "I'm sorry, I was unable to find any images, @" + c.Author.Username + "#" + c.Author.Discriminator + " senpai."
} else {
messageContent = "I was able to find this for you @" + c.Author.Username + "#" + c.Author.Discriminator + " with tags (" + strings.Join(tags, ", ") + ") " + danbooru.BASE + post.LargeFileUrl
addCommandEntry(s, c)
}
message, err := s.ChannelMessageSend(c.ChannelID, messageContent)
if err != nil || message == nil {
log.Printf("Unable to send messagea: %s", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
func myAnimeListSearch(s *discordgo.Session, c *discordgo.Message, a []string, removeCommand bool) {
}
func hentaiSearch(s *discordgo.Session, c *discordgo.Message, a []string, removeCommand bool) {
}
func mangaSearch(s *discordgo.Session, c *discordgo.Message, a []string, removeCommand bool) {
}
func redditBooruSearch(s *discordgo.Session, c *discordgo.Message, additionalParams []string, removeCommand bool) {
if len(c.Content) < 2 {
return
}
query := strings.Split(c.Content, " ")[1:] //drop the command part of the message
p := ""
if len(query) == 1 {
p = query[0]
} else if len(query) > 1 {
p = url.QueryEscape(strings.Join(query, " ")) //join the params with spaces, and URL Query escape them
}
log.Printf("Retrieved arguments: %+s", query)
post, err := redditbooru.Search(p)
messageContent := ""
if err != nil || query == nil || post.CDNURL == "" {
log.Print("Unable to retrieve image from Redditbooru")
messageContent = "I'm sorry, I was unable to find any images for that query, @" + c.Author.Username + "#" + c.Author.Discriminator + " senpai."
} else {
messageContent = "I found this for you @" + c.Author.Username + "#" + c.Author.Discriminator + " with query \"" + strings.Join(query, ", ") + "\"" + post.CDNURL
addCommandEntry(s, c)
}
message, err := s.ChannelMessageSend(c.ChannelID, messageContent)
if err != nil || message == nil {
log.Print("Unable to send message to discord: ", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
func lennyFaceReply(s *discordgo.Session, c *discordgo.Message, additionalParams []string, removeCommand bool) {
if len(c.Content) < 2 {
return
}
command := strings.Split(c.Content, " ")[0][1:]
messageContent := ""
if command == "lenny" {
messageContent = "( ͡° ͜ʖ ͡°)"
} else if command == "asianlenny" {
messageContent = "( ͡° ╭ʖ╮ ͡° )"
} else if command == "apple" {
messageContent = "\\_(:3 」__ __ )_"
}
addCommandEntry(s, c)
message, err := s.ChannelMessageSend(c.ChannelID, messageContent)
if err != nil || message == nil {
log.Print("Unable to send message to discord: ", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
func randomProfileImage(s *discordgo.Session, c *discordgo.Message, additionalParams []string, removeCommand bool) {
botUser, err := s.User("@me")
if err != nil {
log.Print("Unable to get bot user!")
return
}
files, err := ioutil.ReadDir("./images")
if err != nil || len(files) == 0 {
log.Print("Unable to scan directory for images: ", err)
return
}
r := rand.Intn(len(files))
image := "data:image/jpeg;base64,"
data, err := ioutil.ReadFile("./images/" + files[r].Name())
if err != nil {
log.Print("Unable to load image file :(, ", err)
return
}
image += base64.StdEncoding.EncodeToString(data)
_, err = s.UserUpdate("", "", botUser.Username, image, "")
if err != nil {
log.Print("Unable to update profile picture ", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}
func echoCommand(s *discordgo.Session, c *discordgo.Message, additionalParams []string, removeCommand bool) {
messageSplit := strings.Split(c.Content, " ")[1:]
messageContent := strings.Join(messageSplit, " ")
message, err := s.ChannelMessageSend(c.ChannelID, messageContent)
if err != nil || message == nil {
log.Print("Unable to send message to discord: ", err)
}
if removeCommand {
s.ChannelMessageDelete(c.ChannelID, c.ID)
}
}

@ -0,0 +1,19 @@
[AppConfig]
AuthToken = "Bot DISCORD_AUTH_TOKEN"
ApplicationID = "APPLICATIONID"
CommandPrefix = "]"
CommandTimeout = 10
[Danbooru]
DanbooruUser = "DANBOORU_USER"
DanbooruKey = "DANBOORU_API_KEY"
[Redditbooru]
#The allowed subreddit IDs on RedditBooru. It's most of them
#-1 is all subreddits
AllowedSubreddits = [
"49", "40", "45", "44", "50", "53", "51", "1", "25", "39", "38", "9", "43", "47", "26", "27", "20", "7", "46", "33",
"30", "17", "22", "35", "19", "34", "23", "11" ]

@ -1,7 +1,7 @@
package danbooru
import (
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/config"
"git.packetlostandfound.us/chiefnoah/GoGetMeHentai/config"
"net/http"
"log"
"io/ioutil"

@ -5,7 +5,7 @@ import (
_ "github.com/mattn/go-sqlite3"
"log"
"github.com/bwmarrin/discordgo"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/config"
"git.packetlostandfound.us/chiefnoah/GoGetMeHentai/config"
"time"
)

@ -1,9 +1,9 @@
package main
import (
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/commands"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/config"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/database"
"./commands"
"./config"
"./database"
"github.com/bwmarrin/discordgo"
"log"
"time"

@ -1,7 +1,7 @@
package redditbooru
import (
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/config"
"git.packetlostandfound.us/chiefnoah/GoGetMeHentai/config"
"strconv"
"log"
"strings"

Loading…
Cancel
Save