diff --git a/.gitignore b/.gitignore index 797d89f..09f1a77 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /subscribe-bot -/db +/test.db /config.toml /repos diff --git a/config.go b/config/config.go similarity index 97% rename from config.go rename to config/config.go index d9a5a7f..ee702a2 100644 --- a/config.go +++ b/config/config.go @@ -1,4 +1,4 @@ -package main +package config import ( "fmt" diff --git a/db.go b/db/db.go similarity index 97% rename from db.go rename to db/db.go index 21823dd..dd656cb 100644 --- a/db.go +++ b/db/db.go @@ -1,4 +1,4 @@ -package main +package db // Database is laid out like this: // mapper//trackers/ -> priority @@ -7,6 +7,7 @@ package main import ( "strconv" + "subscribe-bot/osuapi" bolt "go.etcd.io/bbolt" ) @@ -17,10 +18,10 @@ var ( type Db struct { *bolt.DB - api *Osuapi + api *osuapi.Osuapi } -func OpenDb(path string, api *Osuapi) (db *Db, err error) { +func OpenDb(path string, api *osuapi.Osuapi) (db *Db, err error) { inner, err := bolt.Open(path, 0666, nil) db = &Db{inner, api} return diff --git a/bot.go b/discord/bot.go similarity index 91% rename from bot.go rename to discord/bot.go index d4d3454..cae0089 100644 --- a/bot.go +++ b/discord/bot.go @@ -1,4 +1,4 @@ -package main +package discord import ( "errors" @@ -17,18 +17,21 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" + + "subscribe-bot/config" + "subscribe-bot/db" + "subscribe-bot/osuapi" ) type Bot struct { *discordgo.Session mentionRe *regexp.Regexp - db *Db - api *Osuapi - requests chan int - config *Config + db *db.Db + api *osuapi.Osuapi + config *config.Config } -func NewBot(config *Config, db *Db, requests chan int) (bot *Bot, err error) { +func NewBot(config *config.Config, db *db.Db, api *osuapi.Osuapi) (bot *Bot, err error) { s, err := discordgo.New("Bot " + config.BotToken) if err != nil { return @@ -45,7 +48,7 @@ func NewBot(config *Config, db *Db, requests chan int) (bot *Bot, err error) { return } - bot = &Bot{s, re, db, db.api, requests, config} + bot = &Bot{s, re, db, api, config} s.AddHandler(bot.errWrap(bot.newMessageHandler)) return } @@ -74,7 +77,7 @@ func (bot *Bot) errWrap(fn interface{}) interface{} { return newFunc.Interface() } -func (bot *Bot) NotifyNewBeatmap(channels []string, newMaps []Beatmapset) (err error) { +func (bot *Bot) NotifyNewBeatmap(channels []string, newMaps []osuapi.Beatmapset) (err error) { for _, beatmapSet := range newMaps { var eventTime time.Time eventTime, err = time.Parse(time.RFC3339, beatmapSet.LastUpdated) @@ -220,7 +223,7 @@ type BeatmapsetDownloaded struct { Path string } -func (bot *Bot) downloadBeatmapTo(beatmapSet *Beatmapset, repo *git.Repository, repoDir string) (err error) { +func (bot *Bot) downloadBeatmapTo(beatmapSet *osuapi.Beatmapset, repo *git.Repository, repoDir string) (err error) { // clear all OSU files files, err := ioutil.ReadDir(repoDir) if err != nil { @@ -244,7 +247,7 @@ func (bot *Bot) downloadBeatmapTo(beatmapSet *Beatmapset, repo *git.Repository, return } -func (bot *Bot) getBeatmapsetInfo(event Event) (beatmapSet Beatmapset, err error) { +func (bot *Bot) getBeatmapsetInfo(event osuapi.Event) (beatmapSet osuapi.Beatmapset, err error) { beatmapSetId, err := strconv.Atoi(strings.TrimPrefix(event.Beatmapset.URL, "/s/")) if err != nil { return @@ -283,7 +286,7 @@ func (bot *Bot) newMessageHandler(s *discordgo.Session, m *discordgo.MessageCrea return } - var mapper User + var mapper osuapi.User mapperName := strings.Join(parts[1:], " ") mapper, err = bot.api.GetUser(mapperName) if err != nil { diff --git a/main.go b/main.go index 6a0a025..fd65434 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,12 @@ import ( "os" "os/signal" "syscall" + + "subscribe-bot/config" + "subscribe-bot/db" + "subscribe-bot/discord" + "subscribe-bot/osuapi" + "subscribe-bot/scrape" ) var exit_chan = make(chan int) @@ -14,24 +20,22 @@ func main() { configPath := flag.String("config", "config.toml", "Path to the config file (defaults to config.toml)") flag.Parse() - config, err := ReadConfig(*configPath) + config, err := config.ReadConfig(*configPath) - requests := make(chan int) + api := osuapi.New(&config) - api := NewOsuapi(&config) - - db, err := OpenDb("db", api) + db, err := db.OpenDb("db", api) if err != nil { log.Fatal(err) } log.Println("opened db") - bot, err := NewBot(&config, db, requests) + bot, err := discord.NewBot(&config, db, api) if err != nil { log.Fatal(err) } - go RunScraper(bot, db, api, requests) + go scrape.RunScraper(bot, db, api) signal_chan := make(chan os.Signal, 1) signal.Notify(signal_chan, @@ -60,6 +64,6 @@ func main() { db.Close() bot.Close() - ticker.Stop() + scrape.Ticker.Stop() os.Exit(code) } diff --git a/models.go b/osuapi/models.go similarity index 87% rename from models.go rename to osuapi/models.go index 07535ac..5c7514f 100644 --- a/models.go +++ b/osuapi/models.go @@ -1,4 +1,4 @@ -package main +package osuapi type User struct { ID int `json:"id"` @@ -41,15 +41,8 @@ type Event struct { ID int `json:"id"` Type string `json:"type"` - // type: achievement Achievement EventAchievement `json:"achievement,omitempty"` - - // type: beatmapsetApprove - // type: beatmapsetDelete - // type: beatmapsetRevive - // type: beatmapsetUpdate - // type: beatmapsetUpload - Beatmapset EventBeatmapset `json:"beatmapset,omitempty"` + Beatmapset EventBeatmapset `json:"beatmapset,omitempty"` User EventUser `json:"user,omitempty"` } diff --git a/osuapi.go b/osuapi/osuapi.go similarity index 98% rename from osuapi.go rename to osuapi/osuapi.go index 3ceadb1..97e9f47 100644 --- a/osuapi.go +++ b/osuapi/osuapi.go @@ -1,4 +1,4 @@ -package main +package osuapi import ( "context" @@ -14,6 +14,8 @@ import ( "time" "golang.org/x/sync/semaphore" + + "subscribe-bot/config" ) const BASE_URL = "https://osu.ppy.sh/api/v2" @@ -27,7 +29,7 @@ type Osuapi struct { clientSecret string } -func NewOsuapi(config *Config) *Osuapi { +func New(config *config.Config) *Osuapi { client := &http.Client{ Timeout: 9 * time.Second, } diff --git a/scrape.go b/scrape/scrape.go similarity index 84% rename from scrape.go rename to scrape/scrape.go index bd6d6d6..10426bb 100644 --- a/scrape.go +++ b/scrape/scrape.go @@ -1,20 +1,24 @@ -package main +package scrape import ( "fmt" "log" "time" + + "subscribe-bot/db" + "subscribe-bot/discord" + "subscribe-bot/osuapi" ) var ( refreshInterval = 30 * time.Second - ticker = time.NewTicker(refreshInterval) + Ticker = time.NewTicker(refreshInterval) ) -func RunScraper(bot *Bot, db *Db, api *Osuapi, requests chan int) { +func RunScraper(bot *discord.Bot, db *db.Db, api *osuapi.Osuapi) { lastUpdateTime := time.Now() go func() { - for ; true; <-ticker.C { + for ; true; <-Ticker.C { // build a list of currently tracked mappers trackedMappers := make(map[int]int) db.IterTrackedMappers(func(userId int) error { @@ -23,12 +27,12 @@ func RunScraper(bot *Bot, db *Db, api *Osuapi, requests chan int) { }) // TODO: is this sorted for sure?? - pendingSets, err := bot.api.SearchBeatmaps("pending") + pendingSets, err := api.SearchBeatmaps("pending") if err != nil { log.Println("error fetching pending sets", err) } - allNewMaps := make(map[int][]Beatmapset, 0) + allNewMaps := make(map[int][]osuapi.Beatmapset, 0) var newLastUpdateTime = time.Unix(0, 0) for _, beatmapSet := range pendingSets.Beatmapsets { updatedTime, err := time.Parse(time.RFC3339, beatmapSet.LastUpdated) @@ -48,7 +52,7 @@ func RunScraper(bot *Bot, db *Db, api *Osuapi, requests chan int) { mapperId := beatmapSet.UserId if _, ok := trackedMappers[mapperId]; ok { if _, ok2 := allNewMaps[mapperId]; !ok2 { - allNewMaps[mapperId] = make([]Beatmapset, 0) + allNewMaps[mapperId] = make([]osuapi.Beatmapset, 0) } allNewMaps[mapperId] = append(allNewMaps[mapperId], beatmapSet) @@ -77,12 +81,12 @@ func RunScraper(bot *Bot, db *Db, api *Osuapi, requests chan int) { }() } -func getNewMaps(db *Db, api *Osuapi, userId int) (newMaps []Event, err error) { +func getNewMaps(db *db.Db, api *osuapi.Osuapi, userId int) (newMaps []osuapi.Event, err error) { // see if there's a last event hasLastEvent, lastEventId := db.MapperLastEvent(userId) - newMaps = make([]Event, 0) + newMaps = make([]osuapi.Event, 0) var ( - events []Event + events []osuapi.Event newLatestEvent = 0 updateLatestEvent = false ) @@ -152,10 +156,3 @@ func getNewMaps(db *Db, api *Osuapi, userId int) (newMaps []Event, err error) { return } - -func startTimers(db *Db, requests chan int) { - db.IterTrackedMappers(func(userId int) error { - requests <- userId - return nil - }) -}