Skip to content

Commit

Permalink
Remove DB usage from factoids and HJT
Browse files Browse the repository at this point in the history
  • Loading branch information
LordRalex committed May 8, 2024
1 parent ff1933e commit fa121a4
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 90 deletions.
21 changes: 21 additions & 0 deletions api/http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package api

import (
"io"
"net/http"
)

func GetFromUrl(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()

data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return data, nil
}
80 changes: 52 additions & 28 deletions modules/factoids/factoids.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package factoids

import (
"errors"
"bytes"
"encoding/json"
"fmt"
"github.com/bwmarrin/discordgo"
"github.com/lordralex/absol/api"
"github.com/lordralex/absol/api/database"
"github.com/lordralex/absol/api/env"
"github.com/lordralex/absol/api/logger"
"gorm.io/gorm"
"slices"
"strings"
"time"
)

var factoidsUrl string
var maxFactoids int

type Module struct {
api.Module
}
Expand All @@ -23,6 +25,13 @@ func (*Module) Load(ds *discordgo.Session) {
api.RegisterCommand("factoid", RunCommand)

api.RegisterIntentNeed(discordgo.IntentsGuildMessages, discordgo.IntentsDirectMessages)

factoidsUrl = env.GetOr("hjt.url", "https://minecrafthopper.net/factoids.json")

maxFactoids = env.GetInt("factoids.max")
if maxFactoids <= 0 {
maxFactoids = 5
}
}

func RunCommand(ds *discordgo.Session, mc *discordgo.MessageCreate, cmd string, args []string) {
Expand Down Expand Up @@ -58,40 +67,27 @@ func RunCommand(ds *discordgo.Session, mc *discordgo.MessageCreate, cmd string,
}
}

max := env.GetInt("factoids.max")
if max == 0 {
max = 5
}
if len(factoids) > max {
_ = SendWithSelfDelete(ds, mc.ChannelID, fmt.Sprintf("Cannot send more than %d factoids at once", max))
if len(factoids) > maxFactoids {
_ = SendWithSelfDelete(ds, mc.ChannelID, fmt.Sprintf("Cannot send more than %d factoids at once", maxFactoids))
return
}

db, err := database.Get()
matches, err := getMatchingFactoids(factoids)
if err != nil {
err = SendWithSelfDelete(ds, mc.ChannelID, "Failed to connect to database")
logger.Err().Printf("Failed to connect to database\n%s", err)
logger.Err().Printf("Failed to pull data from database\n%s", err)
return
}

var data []Factoid
err = db.Where("name IN (?)", factoids).Find(&data).Error

if errors.Is(err, gorm.ErrRecordNotFound) || (err == nil && len(data) == 0) {
} else if len(matches) == 0 {
_ = SendWithSelfDelete(ds, mc.ChannelID, "No factoid with the given name was found: "+strings.Join(factoids, ", "))
return
} else if err != nil {
logger.Err().Printf("Failed to pull data from database\n%s", err)
return
}

if len(factoids) != len(data) {
if len(factoids) != len(matches) {
//we have a missing one...
missing := make([]string, 0)
for _, v := range factoids {
good := false
for _, k := range data {
if v == k.Name {
for _, k := range matches {
if match(k.Name, v) {
good = true
break
}
Expand All @@ -110,8 +106,8 @@ func RunCommand(ds *discordgo.Session, mc *discordgo.MessageCreate, cmd string,

msg := ""
for i, v := range factoids {
for _, o := range data {
if o.Name == v {
for _, o := range matches {
if match(v, o.Name) {
msg += CleanupFactoid(o.Content)
if i+1 != len(factoids) {
msg += "\n\n"
Expand Down Expand Up @@ -202,10 +198,38 @@ func CleanupFactoid(msg string) string {
}

type Factoid struct {
Name string `gorm:"name"`
Content string `gorm:"content"`
Name string `json:"name"`
Content string `json:"content"`
}

func (*Module) Name() string {
return "factoids"
}

func getMatchingFactoids(names []string) ([]Factoid, error) {
data, err := api.GetFromUrl(factoidsUrl)
if err != nil {
return nil, err
}
var factoids []Factoid
err = json.NewDecoder(bytes.NewReader(data)).Decode(&factoids)
if err != nil {
return nil, err
}

var matches []Factoid

for _, v := range names {
for _, z := range factoids {
if match(v, z.Name) {
matches = append(matches, z)
}
}
}

return matches, err
}

func match(v, z string) bool {
return strings.ToLower(v) == strings.ToLower(z)
}
90 changes: 28 additions & 62 deletions modules/hjt/hjt.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package hjt

import (
"bytes"
"encoding/json"
"github.com/bwmarrin/discordgo"
"github.com/lordralex/absol/api"
"github.com/lordralex/absol/api/database"
"github.com/lordralex/absol/api/env"
"github.com/lordralex/absol/api/logger"
"gorm.io/gorm"
"io"
"net/http"
"regexp"
)

Expand All @@ -17,6 +15,7 @@ type Module struct {
}

var appId string
var hjtUrl string

func (*Module) Load(ds *discordgo.Session) {
appId = env.Get("discord.app_id")
Expand All @@ -32,6 +31,8 @@ func (*Module) Load(ds *discordgo.Session) {
guilds = append(guilds, v)
}

hjtUrl = env.GetOr("hjt.url", "https://minecrafthopper.net/hjt.json")

ds.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) {
for _, v := range guilds {
logger.Out().Printf("Registering %s for guild %s\n", hjtOperation.Name, v)
Expand Down Expand Up @@ -80,7 +81,7 @@ func runCommand(ds *discordgo.Session, i *discordgo.InteractionCreate) {

pasteLink := i.ApplicationCommandData().Options[0].StringValue()

content, err := readFromUrl(pasteLink)
content, err := api.GetFromUrl(pasteLink)
if err != nil {
msg := "Invalid URL"
_, _ = ds.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
Expand All @@ -89,31 +90,21 @@ func runCommand(ds *discordgo.Session, i *discordgo.InteractionCreate) {
return
}

db, err := database.Get()
if err != nil {
logger.Err().Printf("Failed to connect to database\n%s", err)
msg := "Failed to connect to database"
_, _ = ds.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
Content: &msg,
})
return
}

var values []HJT
err = db.Table("hjts").Select([]string{"id", "name", "match_criteria"}).Find(&values).Error

values, err = getHjts()
if err != nil {
logger.Err().Printf("Failed to pull data from database\n%s", err)
logger.Err().Printf("Failed to connect to database\n%s", err)
msg := "Failed to connect to database"
_, _ = ds.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
Content: &msg,
})
return
}

var results []uint
var results []HJT
var matches bool
for _, v := range values {
matches, err := regexp.Match(v.MatchCriteria, content)
matches, err = regexp.Match(v.MatchCriteria, content)
if err != nil {
msg := v.Name + " is an invalid regex statement: " + err.Error()
_, _ = ds.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
Expand All @@ -122,7 +113,7 @@ func runCommand(ds *discordgo.Session, i *discordgo.InteractionCreate) {
return
}
if matches {
results = append(results, v.Id)
results = append(results, v)
}
}

Expand All @@ -134,52 +125,25 @@ func runCommand(ds *discordgo.Session, i *discordgo.InteractionCreate) {
return
}

var data []HJT
err = db.Find(&data, results).Order("severity desc").Error
if err != nil {
logger.Err().Printf("Failed to pull data from database\n%s", err)
msg := "Failed to connect to database"
_, _ = ds.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
Content: &msg,
})
return
}

message := "Report for " + pasteLink + "\n"
for i, v := range data {
if i != 0 {
for id, v := range results {
if id != 0 {
message += "\n"
}
message += v.SeverityEmoji + " [" + v.Category + "] " + v.Name + ": " + v.Description
message += v.GetEmojiString() + " [" + v.Category + "] " + v.Name + ": " + v.Description
}
_, _ = ds.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
Content: &message,
})
}

func readFromUrl(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return []byte{}, err
}
defer resp.Body.Close()

data, err := io.ReadAll(resp.Body)

if err != nil {
return []byte{}, err
}
return data, nil
}

type HJT struct {
Id uint
Name string
MatchCriteria string
MatchCriteria string `json:"match_criteria"`
Description string
Category string
Severity Severity
SeverityEmoji string `gorm:"-"`
}

type Severity int
Expand All @@ -189,8 +153,8 @@ var SeverityLow Severity = 1
var SeverityMedium Severity = 2
var SeverityHigh Severity = 3

func (s Severity) ToEmojiString() string {
switch s {
func (s HJT) GetEmojiString() string {
switch s.Severity {
case SeverityHigh:
return ":red_circle:"
case SeverityLow:
Expand All @@ -202,14 +166,16 @@ func (s Severity) ToEmojiString() string {
}
}

func (h *HJT) AfterFind(tx *gorm.DB) (err error) {
h.SeverityEmoji = h.Severity.ToEmojiString()
if h.Name == "" {
h.Name = h.MatchCriteria
}
return
}

func (*Module) Name() string {
return "hjt"
}

func getHjts() ([]HJT, error) {
data, err := api.GetFromUrl(hjtUrl)
if err != nil {
return nil, err
}
var results []HJT
err = json.NewDecoder(bytes.NewReader(data)).Decode(&results)
return results, err
}

0 comments on commit fa121a4

Please sign in to comment.