Commit d796ee3b authored by Mike Jones's avatar Mike Jones 馃尪

Store usernames against nicknames

parent bc37c25c
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"github.com/boltdb/bolt" "github.com/boltdb/bolt"
"git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/gauntlet" "git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/gauntlet"
"git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/store"
"git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/util" "git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/util"
) )
...@@ -13,35 +14,25 @@ func main() { ...@@ -13,35 +14,25 @@ func main() {
log.Println("Initialising stella-irc Last.fm module, hold tight...") log.Println("Initialising stella-irc Last.fm module, hold tight...")
config := util.NewConfig() config := util.NewConfig()
db, err := bolt.Open(config.DBPath, 0600, nil) db, err := bolt.Open(config.DBPath, 0600, nil)
if err != nil { if err != nil {
log.Fatalf("Could not open database: %s", err.Error()) log.Fatalf("Could not open database: %s", err.Error())
} }
st, err := store.NewBoltStore(db)
if err != nil {
log.Fatalf("Error initialising database: %s", err.Error())
}
// initialise commands // initialise commands
gauntlet.New(config, db) gauntlet.New(config, st)
out := gauntlet.Run("ne7split", `artist Begrime Exemious`) // TODO: collect this from IRC input
out := gauntlet.Run("Mike", `l`, st)
if out != "" { if out != "" {
log.Println(out) log.Println(out)
} }
/*
st, err := store.NewBoltStore(db)
if err != nil {
log.Fatalf("Error initialising database: %s", err.Error())
}
inputChannel := make(chan *input.Message)
input.Watch(inputChannel, func(m *input.Message) {
if m != nil {
log.Println(m)
}
})
*/
} }
...@@ -4,9 +4,9 @@ import ( ...@@ -4,9 +4,9 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"github.com/boltdb/bolt"
"github.com/n7st/lastfm-go/lastfm" "github.com/n7st/lastfm-go/lastfm"
"git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/store"
"git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/util" "git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/util"
) )
...@@ -17,7 +17,7 @@ type ( ...@@ -17,7 +17,7 @@ type (
type Fn struct { type Fn struct {
Config *util.Config Config *util.Config
DB *bolt.DB Store *store.BoltStore
LastFM *lastfm.Api LastFM *lastfm.Api
} }
......
...@@ -14,6 +14,26 @@ const ( ...@@ -14,6 +14,26 @@ const (
noTopArtistsForPeriodF = "%s has no listening data for this period" noTopArtistsForPeriodF = "%s has no listening data for this period"
) )
func (f *Fn) SetUser(message string) string {
var err error
if message == "" {
err = f.Store.RemoveAssociatedUser("Mike")
return "Last.fm username unset"
}
args := strings.Split(message, " ")
err = f.Store.SetAssociatedUser("Mike", args[0])
if err != nil {
return fmtError(err)
}
return fmt.Sprintf("Last.fm username set to %s", args[0])
}
func (f *Fn) NowPlaying(message string, username string) string { func (f *Fn) NowPlaying(message string, username string) string {
resp, err := f.LastFM.User.GetRecentTracks(lastfm.P{ resp, err := f.LastFM.User.GetRecentTracks(lastfm.P{
"autocorrect": 1, "autocorrect": 1,
......
package gauntlet package gauntlet
import ( import (
"fmt"
"git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/store"
"strings" "strings"
"github.com/boltdb/bolt"
"github.com/n7st/lastfm-go/lastfm" "github.com/n7st/lastfm-go/lastfm"
"git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/command" "git.netsplit.uk/stella-irc/modlastfm/internal/app/modlastfm/command"
...@@ -20,10 +21,10 @@ var ( ...@@ -20,10 +21,10 @@ var (
// sets up fn commands (which contain the configuration, database and an // sets up fn commands (which contain the configuration, database and an
// instance of shkh/lastfm-go/lastfm) // instance of shkh/lastfm-go/lastfm)
func New(c *util.Config, db *bolt.DB) { func New(c *util.Config, store *store.BoltStore) {
var fn = command.Fn{ var fn = command.Fn{
Config: c, Config: c,
DB: db, Store: store,
LastFM: lastfm.New(c.APIKey, c.APISecret), LastFM: lastfm.New(c.APIKey, c.APISecret),
} }
...@@ -41,18 +42,27 @@ func New(c *util.Config, db *bolt.DB) { ...@@ -41,18 +42,27 @@ func New(c *util.Config, db *bolt.DB) {
} }
openCommands = map[string]command.OpenFnCommand{ openCommands = map[string]command.OpenFnCommand{
"artist": fn.ArtistInfo, "artist": fn.ArtistInfo,
"band": fn.ArtistInfo, "band": fn.ArtistInfo,
"setuser": fn.SetUser,
} }
} }
// Run() attempts to run a command with the given user input // Run() attempts to run a command with the given user input
func Run(username string, message string) string { func Run(nickname string, message string, db *store.BoltStore) string {
var arguments = strings.Split(message, " ") var arguments = strings.Split(message, " ")
userFnCommand := userCommands[arguments[0]] userFnCommand := userCommands[arguments[0]]
if userFnCommand != nil { if userFnCommand != nil {
username, err := db.GetAssociatedUser(nickname)
if err != nil || username == "" {
return fmt.Sprintf("No Last.fm username found for %s. Set one with setuser <username>",
nickname,
)
}
return userFnCommand(strings.Join(arguments[1:], " "), username) return userFnCommand(strings.Join(arguments[1:], " "), username)
} }
......
package input
type Message struct {
Raw string
Target string
}
func Watch(channel chan *Message, sendFunc func(*Message)) {
for msg := range channel {
sendFunc(msg)
}
}
package store package store
import "github.com/boltdb/bolt" import (
"github.com/boltdb/bolt"
)
const userBucketKey = "user" const (
userBucketKey = "user"
noUserBucketErr = "DB error: no user bucket"
)
type BoltStore struct { type BoltStore struct {
db *bolt.DB db *bolt.DB
...@@ -12,7 +17,6 @@ type BoltStore struct { ...@@ -12,7 +17,6 @@ type BoltStore struct {
// member // member
func NewBoltStore(db *bolt.DB) (*BoltStore, error) { func NewBoltStore(db *bolt.DB) (*BoltStore, error) {
st := &BoltStore{db: db} st := &BoltStore{db: db}
err := st.init() err := st.init()
if err != nil { if err != nil {
...@@ -22,6 +26,54 @@ func NewBoltStore(db *bolt.DB) (*BoltStore, error) { ...@@ -22,6 +26,54 @@ func NewBoltStore(db *bolt.DB) (*BoltStore, error) {
return st, err return st, err
} }
// SetAssociatedUser() sets an associated Last.fm user against an IRC nickname
func (b *BoltStore) SetAssociatedUser(nickname string, username string) error {
err := b.db.Update(func(tx *bolt.Tx) error {
userBucket := tx.Bucket([]byte(userBucketKey))
if userBucket == nil {
panic(noUserBucketErr)
}
return userBucket.Put([]byte(nickname), []byte(username))
})
return err
}
// GetAssociatedUser() gets an associated Last.fm username for an IRC nickname
func (b *BoltStore) GetAssociatedUser(nickname string) (string, error) {
var username []byte
err := b.db.View(func(tx *bolt.Tx) error {
userBucket := tx.Bucket([]byte(userBucketKey))
if userBucket == nil {
panic(noUserBucketErr)
}
username = userBucket.Get([]byte(nickname))
return nil
})
return string(username), err
}
// RemoveAssociatedUser() deletes a username set against a nickname (woo, GDPR
// compliance!)
func (b *BoltStore) RemoveAssociatedUser(nickname string) error {
return b.db.Update(func (tx *bolt.Tx) error {
userBucket := tx.Bucket([]byte(userBucketKey))
if userBucket == nil {
panic(noUserBucketErr)
}
return userBucket.Delete([]byte(nickname))
})
}
// init() initialises the database with the required buckets // init() initialises the database with the required buckets
func (b *BoltStore) init() error { func (b *BoltStore) init() error {
return b.db.Update(func(tx *bolt.Tx) error { return b.db.Update(func(tx *bolt.Tx) error {
...@@ -29,4 +81,4 @@ func (b *BoltStore) init() error { ...@@ -29,4 +81,4 @@ func (b *BoltStore) init() error {
return err return err
}) })
} }
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment