refactor into modules
This commit is contained in:
parent
6ccacec1ec
commit
fe777d5301
8 changed files with 52 additions and 52 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
||||||
/subscribe-bot
|
/subscribe-bot
|
||||||
/db
|
/test.db
|
||||||
/config.toml
|
/config.toml
|
||||||
/repos
|
/repos
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package db
|
||||||
|
|
||||||
// Database is laid out like this:
|
// Database is laid out like this:
|
||||||
// mapper/<mapper_id>/trackers/<channel_id> -> priority
|
// mapper/<mapper_id>/trackers/<channel_id> -> priority
|
||||||
|
@ -7,6 +7,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"subscribe-bot/osuapi"
|
||||||
|
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -17,10 +18,10 @@ var (
|
||||||
|
|
||||||
type Db struct {
|
type Db struct {
|
||||||
*bolt.DB
|
*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)
|
inner, err := bolt.Open(path, 0666, nil)
|
||||||
db = &Db{inner, api}
|
db = &Db{inner, api}
|
||||||
return
|
return
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package discord
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -17,18 +17,21 @@ import (
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/go-git/go-git/v5/plumbing/object"
|
"github.com/go-git/go-git/v5/plumbing/object"
|
||||||
|
|
||||||
|
"subscribe-bot/config"
|
||||||
|
"subscribe-bot/db"
|
||||||
|
"subscribe-bot/osuapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Bot struct {
|
type Bot struct {
|
||||||
*discordgo.Session
|
*discordgo.Session
|
||||||
mentionRe *regexp.Regexp
|
mentionRe *regexp.Regexp
|
||||||
db *Db
|
db *db.Db
|
||||||
api *Osuapi
|
api *osuapi.Osuapi
|
||||||
requests chan int
|
config *config.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)
|
s, err := discordgo.New("Bot " + config.BotToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -45,7 +48,7 @@ func NewBot(config *Config, db *Db, requests chan int) (bot *Bot, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bot = &Bot{s, re, db, db.api, requests, config}
|
bot = &Bot{s, re, db, api, config}
|
||||||
s.AddHandler(bot.errWrap(bot.newMessageHandler))
|
s.AddHandler(bot.errWrap(bot.newMessageHandler))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -74,7 +77,7 @@ func (bot *Bot) errWrap(fn interface{}) interface{} {
|
||||||
return newFunc.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 {
|
for _, beatmapSet := range newMaps {
|
||||||
var eventTime time.Time
|
var eventTime time.Time
|
||||||
eventTime, err = time.Parse(time.RFC3339, beatmapSet.LastUpdated)
|
eventTime, err = time.Parse(time.RFC3339, beatmapSet.LastUpdated)
|
||||||
|
@ -220,7 +223,7 @@ type BeatmapsetDownloaded struct {
|
||||||
Path string
|
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
|
// clear all OSU files
|
||||||
files, err := ioutil.ReadDir(repoDir)
|
files, err := ioutil.ReadDir(repoDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -244,7 +247,7 @@ func (bot *Bot) downloadBeatmapTo(beatmapSet *Beatmapset, repo *git.Repository,
|
||||||
return
|
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/"))
|
beatmapSetId, err := strconv.Atoi(strings.TrimPrefix(event.Beatmapset.URL, "/s/"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -283,7 +286,7 @@ func (bot *Bot) newMessageHandler(s *discordgo.Session, m *discordgo.MessageCrea
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var mapper User
|
var mapper osuapi.User
|
||||||
mapperName := strings.Join(parts[1:], " ")
|
mapperName := strings.Join(parts[1:], " ")
|
||||||
mapper, err = bot.api.GetUser(mapperName)
|
mapper, err = bot.api.GetUser(mapperName)
|
||||||
if err != nil {
|
if err != nil {
|
20
main.go
20
main.go
|
@ -6,6 +6,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"subscribe-bot/config"
|
||||||
|
"subscribe-bot/db"
|
||||||
|
"subscribe-bot/discord"
|
||||||
|
"subscribe-bot/osuapi"
|
||||||
|
"subscribe-bot/scrape"
|
||||||
)
|
)
|
||||||
|
|
||||||
var exit_chan = make(chan int)
|
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)")
|
configPath := flag.String("config", "config.toml", "Path to the config file (defaults to config.toml)")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
config, err := ReadConfig(*configPath)
|
config, err := config.ReadConfig(*configPath)
|
||||||
|
|
||||||
requests := make(chan int)
|
api := osuapi.New(&config)
|
||||||
|
|
||||||
api := NewOsuapi(&config)
|
db, err := db.OpenDb("db", api)
|
||||||
|
|
||||||
db, err := OpenDb("db", api)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Println("opened db")
|
log.Println("opened db")
|
||||||
|
|
||||||
bot, err := NewBot(&config, db, requests)
|
bot, err := discord.NewBot(&config, db, api)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go RunScraper(bot, db, api, requests)
|
go scrape.RunScraper(bot, db, api)
|
||||||
|
|
||||||
signal_chan := make(chan os.Signal, 1)
|
signal_chan := make(chan os.Signal, 1)
|
||||||
signal.Notify(signal_chan,
|
signal.Notify(signal_chan,
|
||||||
|
@ -60,6 +64,6 @@ func main() {
|
||||||
|
|
||||||
db.Close()
|
db.Close()
|
||||||
bot.Close()
|
bot.Close()
|
||||||
ticker.Stop()
|
scrape.Ticker.Stop()
|
||||||
os.Exit(code)
|
os.Exit(code)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package osuapi
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
|
@ -41,15 +41,8 @@ type Event struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
|
||||||
// type: achievement
|
|
||||||
Achievement EventAchievement `json:"achievement,omitempty"`
|
Achievement EventAchievement `json:"achievement,omitempty"`
|
||||||
|
Beatmapset EventBeatmapset `json:"beatmapset,omitempty"`
|
||||||
// type: beatmapsetApprove
|
|
||||||
// type: beatmapsetDelete
|
|
||||||
// type: beatmapsetRevive
|
|
||||||
// type: beatmapsetUpdate
|
|
||||||
// type: beatmapsetUpload
|
|
||||||
Beatmapset EventBeatmapset `json:"beatmapset,omitempty"`
|
|
||||||
|
|
||||||
User EventUser `json:"user,omitempty"`
|
User EventUser `json:"user,omitempty"`
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package osuapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -14,6 +14,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/sync/semaphore"
|
"golang.org/x/sync/semaphore"
|
||||||
|
|
||||||
|
"subscribe-bot/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const BASE_URL = "https://osu.ppy.sh/api/v2"
|
const BASE_URL = "https://osu.ppy.sh/api/v2"
|
||||||
|
@ -27,7 +29,7 @@ type Osuapi struct {
|
||||||
clientSecret string
|
clientSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOsuapi(config *Config) *Osuapi {
|
func New(config *config.Config) *Osuapi {
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Timeout: 9 * time.Second,
|
Timeout: 9 * time.Second,
|
||||||
}
|
}
|
|
@ -1,20 +1,24 @@
|
||||||
package main
|
package scrape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"subscribe-bot/db"
|
||||||
|
"subscribe-bot/discord"
|
||||||
|
"subscribe-bot/osuapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
refreshInterval = 30 * time.Second
|
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()
|
lastUpdateTime := time.Now()
|
||||||
go func() {
|
go func() {
|
||||||
for ; true; <-ticker.C {
|
for ; true; <-Ticker.C {
|
||||||
// build a list of currently tracked mappers
|
// build a list of currently tracked mappers
|
||||||
trackedMappers := make(map[int]int)
|
trackedMappers := make(map[int]int)
|
||||||
db.IterTrackedMappers(func(userId int) error {
|
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??
|
// TODO: is this sorted for sure??
|
||||||
pendingSets, err := bot.api.SearchBeatmaps("pending")
|
pendingSets, err := api.SearchBeatmaps("pending")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error fetching pending sets", err)
|
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)
|
var newLastUpdateTime = time.Unix(0, 0)
|
||||||
for _, beatmapSet := range pendingSets.Beatmapsets {
|
for _, beatmapSet := range pendingSets.Beatmapsets {
|
||||||
updatedTime, err := time.Parse(time.RFC3339, beatmapSet.LastUpdated)
|
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
|
mapperId := beatmapSet.UserId
|
||||||
if _, ok := trackedMappers[mapperId]; ok {
|
if _, ok := trackedMappers[mapperId]; ok {
|
||||||
if _, ok2 := allNewMaps[mapperId]; !ok2 {
|
if _, ok2 := allNewMaps[mapperId]; !ok2 {
|
||||||
allNewMaps[mapperId] = make([]Beatmapset, 0)
|
allNewMaps[mapperId] = make([]osuapi.Beatmapset, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
allNewMaps[mapperId] = append(allNewMaps[mapperId], beatmapSet)
|
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
|
// see if there's a last event
|
||||||
hasLastEvent, lastEventId := db.MapperLastEvent(userId)
|
hasLastEvent, lastEventId := db.MapperLastEvent(userId)
|
||||||
newMaps = make([]Event, 0)
|
newMaps = make([]osuapi.Event, 0)
|
||||||
var (
|
var (
|
||||||
events []Event
|
events []osuapi.Event
|
||||||
newLatestEvent = 0
|
newLatestEvent = 0
|
||||||
updateLatestEvent = false
|
updateLatestEvent = false
|
||||||
)
|
)
|
||||||
|
@ -152,10 +156,3 @@ func getNewMaps(db *Db, api *Osuapi, userId int) (newMaps []Event, err error) {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func startTimers(db *Db, requests chan int) {
|
|
||||||
db.IterTrackedMappers(func(userId int) error {
|
|
||||||
requests <- userId
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue