refactor into modules

This commit is contained in:
Michael Zhang 2020-10-12 08:47:28 -05:00
parent 6ccacec1ec
commit fe777d5301
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
8 changed files with 52 additions and 52 deletions

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
/subscribe-bot
/db
/test.db
/config.toml
/repos

View file

@ -1,4 +1,4 @@
package main
package config
import (
"fmt"

View file

@ -1,4 +1,4 @@
package main
package db
// Database is laid out like this:
// mapper/<mapper_id>/trackers/<channel_id> -> 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

View file

@ -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 {

20
main.go
View file

@ -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)
}

View file

@ -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"`
}

View file

@ -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,
}

View file

@ -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
})
}