2024-03-24 01:57:46 +00:00
package main
import (
"bytes"
_ "embed"
"encoding/json"
"os"
"regexp"
"text/template"
2024-03-24 12:29:57 +00:00
"time"
2024-03-24 01:57:46 +00:00
2024-03-24 12:29:57 +00:00
"git.luzifer.io/luzifer/twitch-bot-streak/pkg/database"
2024-03-24 01:57:46 +00:00
_ "github.com/go-sql-driver/mysql"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/Luzifer/rconfig/v2"
)
2024-03-24 12:29:57 +00:00
type (
botResponse struct {
Type string ` json:"type" `
Attributes map [ string ] any ` json:"attributes" `
}
)
2024-03-24 01:57:46 +00:00
var (
cfg = struct {
2024-03-24 12:29:57 +00:00
Action string ` flag:"action,a" description:"Which action to perform" `
TwitchID uint64 ` flag:"twitch-id" description:"ID of the user to access the streak of" `
TwitchUsername string ` flag:"twitch-username" description:"Username of the user to update in streaks table" `
StreamOfflineGrace time . Duration ` flag:"stream-offline-grace" default:"30m" description:"How long to not start a new stream after previous went offline" `
StorageConnString string ` flag:"storage-conn-string" default:"./storage.db" description:"Connection string for the database" `
StorageConnType string ` flag:"storage-conn-type" default:"sqlite" description:"One of: mysql, postgres, sqlite" `
2024-03-24 01:57:46 +00:00
2024-03-24 12:29:57 +00:00
LogLevel string ` flag:"log-level" default:"info" description:"Log level (debug, info, warn, error, fatal)" `
VersionAndExit bool ` flag:"version" default:"false" description:"Prints current version and exits" `
2024-03-24 01:57:46 +00:00
} { }
version = "dev"
//go:embed message.tpl
messageTemplate string
)
func initApp ( ) error {
rconfig . AutoEnv ( true )
if err := rconfig . ParseAndValidate ( & cfg ) ; err != nil {
return errors . Wrap ( err , "parsing cli options" )
}
l , err := logrus . ParseLevel ( cfg . LogLevel )
if err != nil {
return errors . Wrap ( err , "parsing log-level" )
}
logrus . SetLevel ( l )
return nil
}
func main ( ) {
var err error
if err = initApp ( ) ; err != nil {
logrus . WithError ( err ) . Fatal ( "initializing app" )
}
if cfg . VersionAndExit {
logrus . WithField ( "version" , version ) . Info ( "twitch-bot-streak" )
os . Exit ( 0 )
}
tpl , err := template . New ( "tpl" ) . Parse ( messageTemplate )
if err != nil {
logrus . WithError ( err ) . Fatal ( "parsing message template" )
}
2024-03-24 12:29:57 +00:00
db , err := database . New ( cfg . StorageConnType , cfg . StorageConnString )
2024-03-24 01:57:46 +00:00
if err != nil {
logrus . WithError ( err ) . Fatal ( "connecting to database" )
}
switch cfg . Action {
case "stream_start" :
2024-03-24 12:29:57 +00:00
if err = db . StartStream ( cfg . StreamOfflineGrace ) ; err != nil {
2024-03-24 01:57:46 +00:00
logrus . WithError ( err ) . Fatal ( "starting stream" )
}
case "stream_offline" :
2024-03-24 12:29:57 +00:00
if err = db . SetStreamOffline ( ) ; err != nil {
2024-03-24 01:57:46 +00:00
logrus . WithError ( err ) . Fatal ( "stopping stream" )
}
case "count_stream" :
2024-03-24 12:29:57 +00:00
if err = db . StartStream ( cfg . StreamOfflineGrace ) ; err != nil {
2024-03-24 01:57:46 +00:00
logrus . WithError ( err ) . Fatal ( "starting stream" )
}
2024-03-24 12:29:57 +00:00
user , err := db . CountStreak ( cfg . TwitchID , cfg . TwitchUsername )
2024-03-24 01:57:46 +00:00
if err != nil {
logrus . WithError ( err ) . Fatal ( "counting streak" )
}
buf := new ( bytes . Buffer )
if err = tpl . Execute ( buf , user ) ; err != nil {
logrus . WithError ( err ) . Fatal ( "rendering template" )
}
msg := regexp . MustCompile ( ` \s+ ` ) . ReplaceAllString ( buf . String ( ) , " " )
if err = json . NewEncoder ( os . Stdout ) . Encode ( [ ] botResponse {
{
Type : "respond" ,
Attributes : map [ string ] any {
"message" : msg ,
} ,
} ,
} ) ; err != nil {
logrus . WithError ( err ) . Fatal ( "encoding bot response" )
}
default :
logrus . Fatalf ( "unknown action %q" , cfg . Action )
}
}