diff --git a/.gitignore b/.gitignore
index 785c0bc..03f52e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,3 +74,7 @@ gus.sh
rathaus.sh
run.sh
impact.ttf
+.env
+*.store
+rathaus_discord.sh
+util/migrate/migrate
diff --git a/bot/handlers.go b/bot/handlers.go
index 4797862..c152384 100644
--- a/bot/handlers.go
+++ b/bot/handlers.go
@@ -67,7 +67,9 @@ func ParseValues(r *regexp.Regexp, body string) RegexValues {
func (b *bot) runCallback(conn Connector, plugin Plugin, evt Kind, message msg.Message, args ...interface{}) bool {
t := reflect.TypeOf(plugin).String()
for _, spec := range b.callbacks[t][evt] {
+ log.Debug().Msgf("Trying callback %v with regex %v for msg %v", t, spec.Regex.String(), message.Body)
if spec.Regex.MatchString(message.Body) {
+ log.Debug().Msgf("Running callback")
req := Request{
Conn: conn,
Kind: evt,
diff --git a/plugins/achievements/achievements.go b/plugins/achievements/achievements.go
index 2bd1da2..2e9db69 100644
--- a/plugins/achievements/achievements.go
+++ b/plugins/achievements/achievements.go
@@ -1,6 +1,7 @@
package achievements
import (
+ "database/sql"
"fmt"
bh "github.com/timshannon/bolthold"
"regexp"
@@ -179,7 +180,7 @@ func (p *AchievementsPlugin) Grant(nick, emojy string) (Award, error) {
Holder: nick,
Emojy: emojy,
Description: trophy.Description,
- Granted: time.Now(),
+ Granted: sql.NullTime{Time: time.Now()},
}
if err = p.store.Insert(bh.NextSequence(), &award); err != nil {
return Award{}, err
@@ -205,17 +206,18 @@ func (p *AchievementsPlugin) Create(emojy, description, creator string) (Trophy,
}
type Trophy struct {
- Emojy string
+ Emojy string `boltholderKey:"Emojy"`
Description string
Creator string
}
type Award struct {
- ID int64 `boltholderid:"ID"`
- Holder string
+ ID uint64 `boltholderKey:"ID"`
Emojy string
Description string
- Granted time.Time
+ Holder string
+ Amount int64
+ Granted sql.NullTime
}
func (p *AchievementsPlugin) AllTrophies() ([]Trophy, error) {
diff --git a/plugins/fact/factoid.go b/plugins/fact/factoid.go
index ace51b5..ca40953 100644
--- a/plugins/fact/factoid.go
+++ b/plugins/fact/factoid.go
@@ -4,18 +4,14 @@ package fact
import (
"embed"
- "encoding/json"
"fmt"
bh "github.com/timshannon/bolthold"
- "html/template"
"math/rand"
- "net/http"
"net/url"
"regexp"
"strings"
"time"
- "github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
"github.com/velour/catbase/bot"
@@ -40,16 +36,20 @@ type Factoid struct {
Count int
}
-type alias struct {
+type Alias struct {
Fact string
Next string
}
-func (a *alias) resolve(store *bh.Store) (*Factoid, error) {
+func (a Alias) Key() string {
+ return a.Fact + a.Next
+}
+
+func (a *Alias) resolve(store *bh.Store) (*Factoid, error) {
// perform db query to fill the To field
// todo: remove this query
//q := `select fact, next from factoid_alias where fact=?`
- var next alias
+ var next Alias
err := store.FindOne(&next, bh.Where("Fact").Eq(a.Next))
if err != nil {
// we hit the end of the chain, get a factoid named Next
@@ -66,7 +66,7 @@ func (a *alias) resolve(store *bh.Store) (*Factoid, error) {
func findAlias(store *bh.Store, fact string) (bool, *Factoid) {
// todo: remove this query
//q := `select * from factoid_alias where fact=?`
- var a alias
+ var a Alias
err := store.FindOne(&a, bh.Where("Fact").Eq(fact))
if err != nil {
return false, nil
@@ -75,9 +75,9 @@ func findAlias(store *bh.Store, fact string) (bool, *Factoid) {
return err == nil, f
}
-func (a *alias) save(store *bh.Store) error {
+func (a *Alias) save(store *bh.Store) error {
//q := `select * from factoid_alias where fact=?`
- var offender alias
+ var offender Alias
err := store.FindOne(&offender, bh.Where("Fact").Eq(a.Next))
if err == nil {
return fmt.Errorf("DANGER: an opposite alias already exists")
@@ -95,8 +95,8 @@ func (a *alias) save(store *bh.Store) error {
return nil
}
-func aliasFromStrings(from, to string) *alias {
- return &alias{from, to}
+func aliasFromStrings(from, to string) *Alias {
+ return &Alias{from, to}
}
func (f *Factoid) Save(store *bh.Store) error {
@@ -123,7 +123,7 @@ func (f *Factoid) delete(store *bh.Store) error {
func getFacts(store *bh.Store, fact string, tidbit string) ([]*Factoid, error) {
var fs []*Factoid
- err := store.Find(&fs, bh.Where("Fact").Contains(fact).And("Tidbit").Contains(tidbit))
+ err := store.Find(&fs, bh.Where("Fact").RegExp(regexp.MustCompile(`.*`+fact+`.*`)).And("Tidbit").RegExp(regexp.MustCompile(`.*`+tidbit+`.*`)))
if err != nil {
log.Error().Err(err).Msg("Error regexping for facts")
return nil, err
@@ -669,58 +669,3 @@ func (p *FactoidPlugin) factTimer(c bot.Connector, channel string) {
}
}
}
-
-// Register any web URLs desired
-func (p *FactoidPlugin) registerWeb() {
- r := chi.NewRouter()
- r.HandleFunc("/api", p.serveAPI)
- r.HandleFunc("/req", p.serveQuery)
- r.HandleFunc("/", p.serveQuery)
- p.Bot.RegisterWebName(r, "/factoid", "Factoid")
-}
-
-func linkify(text string) template.HTML {
- parts := strings.Fields(text)
- for i, word := range parts {
- if strings.HasPrefix(word, "http") {
- parts[i] = fmt.Sprintf("%s", word, word)
- }
- }
- return template.HTML(strings.Join(parts, " "))
-}
-func (p *FactoidPlugin) serveAPI(w http.ResponseWriter, r *http.Request) {
- if r.Method != http.MethodPost {
- fmt.Fprintf(w, "Incorrect HTTP method")
- return
- }
- info := struct {
- Query string `json:"query"`
- }{}
- decoder := json.NewDecoder(r.Body)
- err := decoder.Decode(&info)
- if err != nil {
- w.WriteHeader(500)
- fmt.Fprint(w, err)
- return
- }
-
- entries, err := getFacts(p.store, info.Query, "")
- if err != nil {
- w.WriteHeader(500)
- fmt.Fprint(w, err)
- return
- }
-
- data, err := json.Marshal(entries)
- if err != nil {
- w.WriteHeader(500)
- fmt.Fprint(w, err)
- return
- }
- w.Write(data)
-}
-
-func (p *FactoidPlugin) serveQuery(w http.ResponseWriter, r *http.Request) {
- index, _ := embeddedFS.ReadFile("index.html")
- w.Write(index)
-}
diff --git a/plugins/fact/web.go b/plugins/fact/web.go
new file mode 100644
index 0000000..c9c06aa
--- /dev/null
+++ b/plugins/fact/web.go
@@ -0,0 +1,68 @@
+package fact
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/go-chi/chi/v5"
+ "github.com/rs/zerolog/log"
+ "html/template"
+ "net/http"
+ "strings"
+)
+
+// Register any web URLs desired
+func (p *FactoidPlugin) registerWeb() {
+ r := chi.NewRouter()
+ r.HandleFunc("/api", p.serveAPI)
+ r.HandleFunc("/req", p.serveQuery)
+ r.HandleFunc("/", p.serveQuery)
+ p.Bot.RegisterWebName(r, "/factoid", "Factoid")
+}
+
+func linkify(text string) template.HTML {
+ parts := strings.Fields(text)
+ for i, word := range parts {
+ if strings.HasPrefix(word, "http") {
+ parts[i] = fmt.Sprintf("%s", word, word)
+ }
+ }
+ return template.HTML(strings.Join(parts, " "))
+}
+func (p *FactoidPlugin) serveAPI(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodPost {
+ fmt.Fprintf(w, "Incorrect HTTP method")
+ return
+ }
+ info := struct {
+ Query string `json:"query"`
+ }{}
+ decoder := json.NewDecoder(r.Body)
+ err := decoder.Decode(&info)
+ if err != nil {
+ w.WriteHeader(500)
+ fmt.Fprint(w, err)
+ return
+ }
+
+ entries, err := getFacts(p.store, info.Query, "")
+ if err != nil {
+ w.WriteHeader(500)
+ fmt.Fprint(w, err)
+ return
+ }
+
+ log.Debug().Msgf("api request got %d entries", len(entries))
+
+ data, err := json.Marshal(entries)
+ if err != nil {
+ w.WriteHeader(500)
+ fmt.Fprint(w, err)
+ return
+ }
+ w.Write(data)
+}
+
+func (p *FactoidPlugin) serveQuery(w http.ResponseWriter, r *http.Request) {
+ index, _ := embeddedFS.ReadFile("index.html")
+ w.Write(index)
+}
diff --git a/plugins/reminder/reminder.go b/plugins/reminder/reminder.go
index 542ec8f..1708f23 100644
--- a/plugins/reminder/reminder.go
+++ b/plugins/reminder/reminder.go
@@ -264,11 +264,11 @@ func (p *ReminderPlugin) getRemindersFormatted(filter, who string) (string, erro
if filter == "" || who == "" {
total, _ = p.store.Count(Reminder{}, &bh.Query{})
- err = p.store.Find(&reminders, (&bh.Query{}).SortBy("ID").Limit(max))
+ err = p.store.Find(&reminders, (&bh.Query{}).SortBy("When").Limit(max))
} else {
log.Debug().Msgf("Looking for reminders where %s eq %s", filter, who)
total, _ = p.store.Count(Reminder{}, bh.Where(filter).Eq(who))
- err = p.store.Find(&reminders, bh.Where(filter).Eq(who).SortBy("ID").Limit(max))
+ err = p.store.Find(&reminders, bh.Where(filter).Eq(who).SortBy("When").Limit(max))
}
if err != nil {
log.Error().Err(err).Msgf("error finding reminders")
@@ -281,7 +281,7 @@ func (p *ReminderPlugin) getRemindersFormatted(filter, who string) (string, erro
txt := ""
for counter, reminder := range reminders {
- txt += fmt.Sprintf("%d) %s -> %s :: %s @ %s (%d)\n", reminder.ID, reminder.From, reminder.Who, reminder.What, reminder.When, reminder.ID)
+ txt += fmt.Sprintf("%d) %s -> %s :: %s @ %s\n", reminder.ID, reminder.From, reminder.Who, reminder.What, reminder.When.Format(time.RFC3339))
counter++
}
diff --git a/plugins/rest/rest.go b/plugins/rest/rest.go
index 9f373c0..bebf71c 100644
--- a/plugins/rest/rest.go
+++ b/plugins/rest/rest.go
@@ -146,7 +146,7 @@ type Wire struct {
// ID
ID int64 `boltholdIndex:"ID"`
// The URL to make a request to
- URL ScanableURL
+ URL string
// The regex which will trigger this REST action
ParseRegex string `db:"parse_regex"`
regex *regexp.Regexp
@@ -230,10 +230,11 @@ func (p *RestPlugin) mkWire(r bot.Request) (Wire, error) {
return w, err
}
- w.URL.URL, err = url.Parse(r.Values["url"])
+ _, err = url.Parse(r.Values["url"])
if err != nil {
return w, err
}
+ w.URL = r.Values["url"]
w.ReturnField = r.Values["returnField"]
@@ -287,7 +288,7 @@ func (p *RestPlugin) mkHandler(w Wire) bot.ResponseHandler {
values[k] = url.QueryEscape(r.Values[k])
}
log.Debug().Interface("values", values).Msgf("r.Values")
- urlStr := w.URL.String()
+ urlStr := w.URL
parse, err := template.New(urlStr).Parse(urlStr)
if p.handleErr(err, r) {
return true
diff --git a/util/migrate/apppass.go b/util/migrate/apppass.go
index 419b7da..31077d8 100644
--- a/util/migrate/apppass.go
+++ b/util/migrate/apppass.go
@@ -23,7 +23,7 @@ func migrateApppass(db *sqlx.DB, store *bh.Store) error {
return err
}
for _, i := range all {
- if err := store.Insert(i.ID, i); err != nil {
+ if err := store.Insert(bh.NextSequence(), i); err != nil {
return err
}
}
diff --git a/util/migrate/awards.go b/util/migrate/awards.go
index 5fdeaf2..a4de5d4 100644
--- a/util/migrate/awards.go
+++ b/util/migrate/awards.go
@@ -1,44 +1,29 @@
package main
import (
- "database/sql"
"github.com/jmoiron/sqlx"
"github.com/rs/zerolog/log"
bh "github.com/timshannon/bolthold"
+ "github.com/velour/catbase/plugins/achievements"
goals2 "github.com/velour/catbase/plugins/goals"
)
-type Trophy struct {
- Emojy string
- Description string
- Creator string
-}
-
-type Award struct {
- ID int64 `boltholderid:"ID"`
- Holder string
- Emojy string
- Description string
- Granted sql.NullTime
- Amount int64
-}
-
func migrateAwards(db *sqlx.DB, store *bh.Store) error {
- awards := []Award{}
+ awards := []achievements.Award{}
log.Printf("Migrating %T", awards)
err := db.Select(&awards, `select * from awards`)
if err != nil {
return err
}
for _, a := range awards {
- err := store.Insert(a.ID, a)
+ err := store.Insert(bh.NextSequence(), &a)
if err != nil {
return err
}
}
log.Printf("Migrated %d awards", len(awards))
- trophies := []Trophy{}
+ trophies := []achievements.Trophy{}
err = db.Select(&trophies, `select * from trophies`)
for _, t := range trophies {
err := store.Insert(t.Emojy, t)
@@ -54,7 +39,7 @@ func migrateAwards(db *sqlx.DB, store *bh.Store) error {
return err
}
for _, i := range goals {
- if err := store.Insert(i.ID, i); err != nil {
+ if err := store.Insert(bh.NextSequence(), &i); err != nil {
return err
}
}
diff --git a/util/migrate/counter.go b/util/migrate/counter.go
index dcc6ea2..4967378 100644
--- a/util/migrate/counter.go
+++ b/util/migrate/counter.go
@@ -25,7 +25,7 @@ func migrateCounter(db *sqlx.DB, store *bh.Store) error {
if i.UserID.Valid {
it.UserID = i.UserID.String
}
- if err := store.Insert(i.ID, it); err != nil {
+ if err := store.Insert(bh.NextSequence(), &it); err != nil {
return err
}
}
@@ -36,7 +36,7 @@ func migrateCounter(db *sqlx.DB, store *bh.Store) error {
return err
}
for _, i := range all {
- if err := store.Insert(i.ID, i); err != nil {
+ if err := store.Insert(bh.NextSequence(), &i); err != nil {
return err
}
}
diff --git a/util/migrate/fact.go b/util/migrate/fact.go
index 1b8ac44..6285fb9 100644
--- a/util/migrate/fact.go
+++ b/util/migrate/fact.go
@@ -3,6 +3,7 @@ package main
import (
"github.com/rs/zerolog/log"
bh "github.com/timshannon/bolthold"
+ fact2 "github.com/velour/catbase/plugins/fact"
_ "modernc.org/sqlite"
"time"
@@ -10,28 +11,12 @@ import (
)
type SQLFactoid struct {
- Factoid
+ fact2.Factoid
Created int64
Accessed int64
}
-type Factoid struct {
- ID uint64 `boltholdKey:"ID"`
- Fact string
- Tidbit string
- Verb string
- Owner string
- Created time.Time
- Accessed time.Time
- Count int
-}
-
-type Alias struct {
- Fact string
- Next string
-}
-
func migrateFacts(db *sqlx.DB, store *bh.Store) error {
q := `select * from factoid`
allFacts := []SQLFactoid{}
@@ -43,7 +28,7 @@ func migrateFacts(db *sqlx.DB, store *bh.Store) error {
f := sqlf.Factoid
f.Accessed = time.Unix(sqlf.Accessed, 0)
f.Created = time.Unix(sqlf.Created, 0)
- if err := store.Insert(f.ID, f); err != nil {
+ if err := store.Insert(bh.NextSequence(), &f); err != nil {
return err
}
}
@@ -51,14 +36,14 @@ func migrateFacts(db *sqlx.DB, store *bh.Store) error {
log.Printf("Migrated %d facts", len(allFacts))
q = `select * from factoid_alias`
- allAliases := []Alias{}
+ allAliases := []fact2.Alias{}
if err := db.Select(&allAliases, q); err != nil {
return err
}
for _, f := range allAliases {
- if err := store.Insert(bh.NextSequence(), &f); err != nil {
+ if err := store.Insert(f.Key(), &f); err != nil {
return err
}
}
diff --git a/util/migrate/first.go b/util/migrate/first.go
index b874fe7..884b28d 100644
--- a/util/migrate/first.go
+++ b/util/migrate/first.go
@@ -25,7 +25,7 @@ func migrateFirst(db *sqlx.DB, store *bh.Store) error {
fe := i.FirstEntry
fe.Day = time.Unix(i.Day, 0)
fe.Time = time.Unix(i.Time, 0)
- if err := store.Insert(i.ID, fe); err != nil {
+ if err := store.Insert(bh.NextSequence(), &fe); err != nil {
return err
}
}
diff --git a/util/migrate/reminders.go b/util/migrate/reminders.go
index 51ae8c7..d4de47c 100644
--- a/util/migrate/reminders.go
+++ b/util/migrate/reminders.go
@@ -23,7 +23,7 @@ func migrateReminders(db *sqlx.DB, store *bh.Store) error {
for _, r := range allReminders {
rem := r.Reminder
rem.When, _ = time.Parse("2006-01-02 15:04:05", r.When)
- if err := store.Insert(r.ID, rem); err != nil {
+ if err := store.Insert(bh.NextSequence(), &rem); err != nil {
return err
}
}
diff --git a/util/migrate/tell.go b/util/migrate/tell.go
index 43346d5..4076068 100644
--- a/util/migrate/tell.go
+++ b/util/migrate/tell.go
@@ -15,7 +15,7 @@ func migrateTell(db *sqlx.DB, store *bh.Store) error {
}
for _, t := range tells {
- if err := store.Insert(t.ID, t); err != nil {
+ if err := store.Insert(bh.NextSequence(), &t); err != nil {
return err
}
}
diff --git a/util/migrate/webshit.go b/util/migrate/webshit.go
index 3f51794..976287a 100644
--- a/util/migrate/webshit.go
+++ b/util/migrate/webshit.go
@@ -25,7 +25,7 @@ func migrateWebshit(db *sqlx.DB, store *bh.Store) error {
}
for _, b := range balances {
- if err := store.Insert(b.User, b); err != nil {
+ if err := store.Insert(bh.NextSequence(), &b); err != nil {
return err
}
}
@@ -39,7 +39,7 @@ func migrateWebshit(db *sqlx.DB, store *bh.Store) error {
bid := b.Bid
bid.Placed = time.Unix(b.Placed, 0)
bid.Processed = time.Unix(b.Processed, 0)
- if err := store.Insert(b.ID, bid); err != nil {
+ if err := store.Insert(bh.NextSequence(), &bid); err != nil {
return err
}
}
diff --git a/util/migrate/wires.go b/util/migrate/wires.go
index 1d308b8..e9a4897 100644
--- a/util/migrate/wires.go
+++ b/util/migrate/wires.go
@@ -5,27 +5,16 @@ import (
bh "github.com/timshannon/bolthold"
"github.com/velour/catbase/plugins/rest"
"log"
- "net/url"
)
-type WireSQL struct {
- rest.Wire
-
- // The URL to make a request to
- URL string
-}
-
func migrateWires(db *sqlx.DB, store *bh.Store) error {
- wires := []WireSQL{}
+ wires := []rest.Wire{}
log.Printf("Migrating %T", wires)
if err := db.Select(&wires, `select * from wires`); err != nil {
return err
}
for _, w := range wires {
- wire := w.Wire
- u, _ := url.Parse(w.URL)
- wire.URL = rest.ScanableURL{u}
- if err := store.Insert(w.ID, wire); err != nil {
+ if err := store.Insert(bh.NextSequence(), &w); err != nil {
return err
}
}