add logging

This commit is contained in:
fade 2022-08-28 12:37:43 -04:00
parent d3f2bcbdcd
commit 7e00624577
9 changed files with 91 additions and 40 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
go.mod go.mod
go.sum go.sum
*.db *.db
*.log
/mastodon-group-bot

View file

@ -36,13 +36,15 @@ go build
``` ```
# Setup services # Setup services
For first copy config, binary and make dirs For first make dirs, copy config and binary
``` ```
mkdir /etc/mastodon-group-bot mkdir /etc/mastodon-group-bot
mkdir /var/lib/mastodon-group-bot mkdir /var/lib/mastodon-group-bot
mkdir /var/log/mastodon-group-bot
chown nobody /var/lib/mastodon-group-bot chown nobody /var/lib/mastodon-group-bot
cp mastodon-group-bot /usr/bin/mastodon-group-bot chown nobody /var/log/mastodon-group-bot
cp config.json /etc/mastodon-group-bot/config.json cp config.json /etc/mastodon-group-bot/config.json
cp mastodon-group-bot /usr/bin/mastodon-group-bot
``` ```
## Systemd ## Systemd
@ -57,5 +59,5 @@ cp ./services/openrc/mastodon-group-bot /etc/init.d/mastodon-group-bot
# Usage # Usage
``` ```
mastodon-group-bot -config <path> -db <path> mastodon-group-bot -config <path> -db <path> -log <path>
``` ```

48
bot.go
View file

@ -3,14 +3,15 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"regexp" "regexp"
"strings" "strings"
"github.com/mattn/go-mastodon" "github.com/mattn/go-mastodon"
) )
func run_bot(Conf Config, DB string) { func RunBot(Conf Config) {
logger_init()
c := mastodon.NewClient(&mastodon.Config{ c := mastodon.NewClient(&mastodon.Config{
Server: Conf.Server, Server: Conf.Server,
ClientID: Conf.ClientID, ClientID: Conf.ClientID,
@ -21,16 +22,16 @@ func run_bot(Conf Config, DB string) {
ctx := context.Background() ctx := context.Background()
events, err := c.StreamingUser(ctx) events, err := c.StreamingUser(ctx)
if err != nil { if err != nil {
log.Fatal(err) ErrorLogger.Println("Streaming")
} }
my_account, err := c.GetAccountCurrentUser(ctx) my_account, err := c.GetAccountCurrentUser(ctx)
if err != nil { if err != nil {
log.Fatal(err) ErrorLogger.Println("Fetch account info")
} }
followers, err := c.GetAccountFollowers(ctx, my_account.ID, &mastodon.Pagination{Limit: 60}) followers, err := c.GetAccountFollowers(ctx, my_account.ID, &mastodon.Pagination{Limit: 60})
if err != nil { if err != nil {
log.Fatal(err) ErrorLogger.Println("Fetch followers")
} }
// Run bot // Run bot
@ -55,10 +56,18 @@ func run_bot(Conf Config, DB string) {
// New follower // New follower
if notif.Type == "follow" { if notif.Type == "follow" {
acct := notif.Account.Acct acct := notif.Account.Acct
if !followed(acct, DB) { // Add to db and post welcome message if !followed(acct) { // Add to db and post welcome message
add_to_db(acct, Conf.Max_toots, DB) InfoLogger.Printf("%s followed", acct)
add_to_db(acct, Conf.Max_toots)
InfoLogger.Printf("%s added to database", acct)
var message = fmt.Sprintf("%s @%s", Conf.WelcomeMessage, acct) var message = fmt.Sprintf("%s @%s", Conf.WelcomeMessage, acct)
postToot(message, "public") err := postToot(message, "public")
if err != nil {
ErrorLogger.Println("Post welcome message")
}
InfoLogger.Printf("%s was welcomed", acct)
} }
} }
@ -69,13 +78,20 @@ func run_bot(Conf Config, DB string) {
if acct == string(followers[i].Acct) { // Follow check if acct == string(followers[i].Acct) { // Follow check
if notif.Status.Visibility == "public" { // Reblog toot if notif.Status.Visibility == "public" { // Reblog toot
if notif.Status.InReplyToID == nil { // Not boost replies if notif.Status.InReplyToID == nil { // Not boost replies
if !followed(acct, DB) { // Add to db if needed if !followed(acct) { // Add to db if needed
add_to_db(acct, Conf.Max_toots, DB) add_to_db(acct, Conf.Max_toots)
InfoLogger.Printf("%s added to database", acct)
} }
if check_ticket(acct, Conf.Max_toots, Conf.Toots_interval, DB) > 0 { // Limit if check_ticket(acct, Conf.Max_toots, Conf.Toots_interval) > 0 { // Limit
take_ticket(acct, DB) take_ticket(acct)
InfoLogger.Printf("Ticket of %s was taken", acct)
c.Reblog(ctx, notif.Status.ID) c.Reblog(ctx, notif.Status.ID)
InfoLogger.Printf("Toot %s of %s was rebloged", notif.Status.URL, acct)
} else {
WarnLogger.Printf("%s haven't tickets", acct)
} }
} else {
WarnLogger.Printf("%s is reply and not boosted", notif.Status.URL)
} }
} else if notif.Status.Visibility == "direct" { // Admin commands } else if notif.Status.Visibility == "direct" { // Admin commands
for y := 0; y < len(Conf.Admins); y++ { for y := 0; y < len(Conf.Admins); y++ {
@ -98,8 +114,12 @@ func run_bot(Conf Config, DB string) {
c.AccountUnblock(ctx, mID) c.AccountUnblock(ctx, mID)
} }
} }
} } else {
} break
}
}
} else {
break
} }
} }
} }

View file

@ -7,6 +7,12 @@ import (
"os" "os"
) )
var (
ConfPath = flag.String("config", "config.json", "Path to config")
DBPath = flag.String("db", "limits.db", "Path to database")
LogPath = flag.String("log", "mastodon-group-bot.log", "Path to log")
)
type Config struct { type Config struct {
Server string `json:"Server"` Server string `json:"Server"`
ClientID string `json:"ClientID"` ClientID string `json:"ClientID"`
@ -18,18 +24,16 @@ type Config struct {
Admins []string `json:"Admins"` Admins []string `json:"Admins"`
} }
func read_conf() (Config, *string) { func ReadConf() Config {
ConfPath := flag.String("config", "config.json", "Path to config")
DBPath := flag.String("db", "limits.db", "Path to database")
flag.Parse() flag.Parse()
data, err := os.ReadFile(*ConfPath) data, err := os.ReadFile(*ConfPath)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal("Failed to read config")
} }
var Conf Config var Conf Config
json.Unmarshal(data, &Conf) json.Unmarshal(data, &Conf)
return Conf, DBPath return Conf
} }

View file

@ -3,22 +3,22 @@ package main
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"log"
"time" "time"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
) )
// Init database // Init database
func init_limit_db(DBPath string) *sql.DB { func init_limit_db() *sql.DB {
db, err := sql.Open("sqlite3", DBPath) db, err := sql.Open("sqlite3", *DBPath)
if err != nil { if err != nil {
log.Fatal(err) ErrorLogger.Println("Open database")
} }
cmd := `CREATE TABLE IF NOT EXISTS Limits (id INTEGER PRIMARY KEY AUTOINCREMENT, acct TEXT, ticket INTEGER, time TEXT)` cmd := `CREATE TABLE IF NOT EXISTS Limits (id INTEGER PRIMARY KEY AUTOINCREMENT, acct TEXT, ticket INTEGER, time TEXT)`
stat, err := db.Prepare(cmd) stat, err := db.Prepare(cmd)
if err != nil { if err != nil {
log.Fatal(err) ErrorLogger.Println("Create database")
} }
stat.Exec() stat.Exec()
@ -26,19 +26,19 @@ func init_limit_db(DBPath string) *sql.DB {
} }
// Add account to database // Add account to database
func add_to_db(acct string, limit uint16, DBPath string) { func add_to_db(acct string, limit uint16) {
db := init_limit_db(DBPath) db := init_limit_db()
cmd := `INSERT INTO Limits (acct, ticket) VALUES (?, ?)` cmd := `INSERT INTO Limits (acct, ticket) VALUES (?, ?)`
stat, err := db.Prepare(cmd) stat, err := db.Prepare(cmd)
if err != nil { if err != nil {
log.Fatal(err) ErrorLogger.Println("Add account to databse")
} }
stat.Exec(acct, limit) stat.Exec(acct, limit)
} }
// Take ticket for tooting // Take ticket for tooting
func take_ticket(acct string, DBPath string) { func take_ticket(acct string) {
db := init_limit_db(DBPath) db := init_limit_db()
cmd1 := `SELECT ticket FROM Limits WHERE acct = ?` cmd1 := `SELECT ticket FROM Limits WHERE acct = ?`
cmd2 := `UPDATE Limits SET ticket = ?, time = ? WHERE acct = ?` cmd2 := `UPDATE Limits SET ticket = ?, time = ? WHERE acct = ?`
@ -50,7 +50,7 @@ func take_ticket(acct string, DBPath string) {
stat, err := db.Prepare(cmd2) stat, err := db.Prepare(cmd2)
if err != nil { if err != nil {
log.Fatal(err) ErrorLogger.Println("Take ticket")
} }
now := time.Now() now := time.Now()
@ -60,13 +60,13 @@ func take_ticket(acct string, DBPath string) {
} }
// Check followed once // Check followed once
func followed(acct string, DBPath string) bool { func followed(acct string) bool {
db := init_limit_db(DBPath) db := init_limit_db()
cmd := `SELECT acct FROM Limits WHERE acct = ?` cmd := `SELECT acct FROM Limits WHERE acct = ?`
err := db.QueryRow(cmd, acct).Scan(&acct) err := db.QueryRow(cmd, acct).Scan(&acct)
if err != nil { if err != nil {
if err != sql.ErrNoRows { if err != sql.ErrNoRows {
log.Fatal(err) ErrorLogger.Println("Check followed")
} }
return false return false
@ -76,8 +76,8 @@ func followed(acct string, DBPath string) bool {
} }
// Check ticket availability // Check ticket availability
func check_ticket(acct string, ticket uint16, toots_interval uint16, DBPath string) uint16 { func check_ticket(acct string, ticket uint16, toots_interval uint16) uint16 {
db := init_limit_db(DBPath) db := init_limit_db()
cmd1 := `SELECT ticket FROM Limits WHERE acct = ?` cmd1 := `SELECT ticket FROM Limits WHERE acct = ?`
cmd2 := `SELECT time FROM Limits WHERE acct = ?` cmd2 := `SELECT time FROM Limits WHERE acct = ?`
@ -97,7 +97,7 @@ func check_ticket(acct string, ticket uint16, toots_interval uint16, DBPath stri
cmd := `UPDATE Limits SET ticket = ? WHERE acct = ?` cmd := `UPDATE Limits SET ticket = ? WHERE acct = ?`
stat, err := db.Prepare(cmd) stat, err := db.Prepare(cmd)
if err != nil { if err != nil {
log.Fatal(err) ErrorLogger.Println("Check ticket availability")
} }
stat.Exec(ticket, acct) stat.Exec(ticket, acct)

22
logger.go Normal file
View file

@ -0,0 +1,22 @@
package main
import (
"log"
"os"
)
var (
InfoLogger *log.Logger
WarnLogger *log.Logger
ErrorLogger *log.Logger
)
func logger_init() {
file, err := os.OpenFile(*LogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
log.Fatal("Failed to read log file")
}
InfoLogger = log.New(file, "[INFO] ", log.LstdFlags|log.Lshortfile)
WarnLogger = log.New(file, "[WARNING] ", log.LstdFlags|log.Lshortfile)
ErrorLogger = log.New(file, "[ERROR] ", log.LstdFlags|log.Lshortfile)
}

View file

@ -1,7 +1,7 @@
package main package main
func main() { func main() {
config, db := read_conf() config := ReadConf()
run_bot(config, *db) RunBot(config)
} }

View file

@ -3,6 +3,7 @@ name=$RC_SVCNAME
command="/usr/bin/$name" command="/usr/bin/$name"
command_arg1="-config /etc/$name/config.json" command_arg1="-config /etc/$name/config.json"
command_arg2="-db /var/lib/$name/limits.db" command_arg2="-db /var/lib/$name/limits.db"
command_arg3="-log /var/log/$name/$name.log"
pidfile="/run/$name.pid" pidfile="/run/$name.pid"
user="nobody" user="nobody"
description="Mastodon group bot which reposts toots" description="Mastodon group bot which reposts toots"

View file

@ -6,7 +6,7 @@ Wants=network-online.target
[Service] [Service]
Type=simple Type=simple
User=nobody User=nobody
ExecStart=/usr/bin/mastodon-group-bot -config /etc/mastodon-group-bot/config.json -db /var/lib/mastodon-group-bot/limits.db ExecStart=/usr/bin/mastodon-group-bot -config /etc/mastodon-group-bot/config.json -db /var/lib/mastodon-group-bot/limits.db -log /var/log/mastodon-group-bot/mastodon-group-bot.log
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target