2022-08-25 19:23:44 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
2022-08-28 16:37:43 +00:00
|
|
|
|
2022-08-25 19:23:44 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
|
|
)
|
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
var (
|
|
|
|
db = init_limit_db()
|
|
|
|
)
|
|
|
|
|
2022-08-25 19:23:44 +00:00
|
|
|
// Init database
|
2022-08-28 16:37:43 +00:00
|
|
|
func init_limit_db() *sql.DB {
|
|
|
|
db, err := sql.Open("sqlite3", *DBPath)
|
2022-08-25 19:23:44 +00:00
|
|
|
if err != nil {
|
2022-08-28 16:37:43 +00:00
|
|
|
ErrorLogger.Println("Open database")
|
2022-08-25 19:23:44 +00:00
|
|
|
}
|
2022-09-01 11:31:27 +00:00
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
cmd1 := `CREATE TABLE IF NOT EXISTS Limits (id INTEGER PRIMARY KEY AUTOINCREMENT, acct TEXT, ticket INTEGER, order_msg INTEGER, got_notice INTEGER, posted TEXT)`
|
2022-09-01 11:31:27 +00:00
|
|
|
cmd2 := `CREATE TABLE IF NOT EXISTS MsgHashs (message_hash TEXT)`
|
|
|
|
|
|
|
|
stat1, err := db.Prepare(cmd1)
|
|
|
|
if err != nil {
|
2022-09-06 09:31:05 +00:00
|
|
|
ErrorLogger.Println("Create database and table Limits")
|
2022-09-01 11:31:27 +00:00
|
|
|
}
|
|
|
|
stat1.Exec()
|
|
|
|
|
|
|
|
stat2, err := db.Prepare(cmd2)
|
2022-08-25 19:23:44 +00:00
|
|
|
if err != nil {
|
2022-09-06 09:31:05 +00:00
|
|
|
ErrorLogger.Println("Create database and table MsgHashs")
|
2022-08-25 19:23:44 +00:00
|
|
|
}
|
2022-09-01 11:31:27 +00:00
|
|
|
stat2.Exec()
|
2022-08-25 19:23:44 +00:00
|
|
|
|
|
|
|
return db
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add account to database
|
2022-09-01 11:31:27 +00:00
|
|
|
func add_to_db(acct string) {
|
2022-09-08 12:26:25 +00:00
|
|
|
cmd := `INSERT INTO Limits (acct, ticket, order_msg, got_notice) VALUES (?, ?, ?, ?)`
|
2022-08-25 19:23:44 +00:00
|
|
|
stat, err := db.Prepare(cmd)
|
|
|
|
if err != nil {
|
2022-09-08 12:26:25 +00:00
|
|
|
ErrorLogger.Println("Add account to database")
|
2022-08-25 19:23:44 +00:00
|
|
|
}
|
2022-09-08 12:26:25 +00:00
|
|
|
stat.Exec(acct, Conf.Max_toots, 0, 0)
|
2022-08-25 19:23:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check followed once
|
2022-09-08 12:26:25 +00:00
|
|
|
func exist_in_database(acct string) bool {
|
2022-08-25 19:23:44 +00:00
|
|
|
cmd := `SELECT acct FROM Limits WHERE acct = ?`
|
|
|
|
err := db.QueryRow(cmd, acct).Scan(&acct)
|
|
|
|
if err != nil {
|
|
|
|
if err != sql.ErrNoRows {
|
2022-09-01 11:31:27 +00:00
|
|
|
InfoLogger.Println("Check followed")
|
2022-08-25 19:23:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2022-09-01 11:31:27 +00:00
|
|
|
// Take ticket for tooting
|
|
|
|
func take_ticket(acct string) {
|
|
|
|
cmd1 := `SELECT ticket FROM Limits WHERE acct = ?`
|
2022-09-08 12:26:25 +00:00
|
|
|
cmd2 := `UPDATE Limits SET ticket = ?, posted = ? WHERE acct = ?`
|
2022-09-01 11:31:27 +00:00
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
var ticket uint
|
2022-09-01 11:31:27 +00:00
|
|
|
db.QueryRow(cmd1, acct).Scan(&ticket)
|
|
|
|
if ticket > 0 {
|
|
|
|
ticket = ticket - 1
|
|
|
|
}
|
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
now := time.Now()
|
|
|
|
last_toot_at := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Format("2006/01/02 15:04:05 MST")
|
|
|
|
|
2022-09-01 11:31:27 +00:00
|
|
|
stat, err := db.Prepare(cmd2)
|
|
|
|
if err != nil {
|
|
|
|
ErrorLogger.Println("Take ticket")
|
|
|
|
}
|
|
|
|
|
|
|
|
stat.Exec(ticket, last_toot_at, acct)
|
|
|
|
}
|
|
|
|
|
2022-08-25 19:23:44 +00:00
|
|
|
// Check ticket availability
|
2022-09-08 12:26:25 +00:00
|
|
|
func check_ticket(acct string) uint {
|
2022-08-25 19:23:44 +00:00
|
|
|
cmd1 := `SELECT ticket FROM Limits WHERE acct = ?`
|
2022-09-08 12:26:25 +00:00
|
|
|
cmd2 := `SELECT posted FROM Limits WHERE acct = ?`
|
2022-08-25 19:23:44 +00:00
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
var tickets uint
|
2022-08-25 19:23:44 +00:00
|
|
|
var lastS string
|
|
|
|
|
|
|
|
db.QueryRow(cmd1, acct).Scan(&tickets)
|
|
|
|
db.QueryRow(cmd2, acct).Scan(&lastS)
|
|
|
|
|
|
|
|
lastT, _ := time.Parse("2006/01/02 15:04:05 MST", lastS)
|
|
|
|
|
|
|
|
since := time.Since(lastT)
|
2022-09-01 11:31:27 +00:00
|
|
|
limit := fmt.Sprintf("%dh", Conf.Toots_interval)
|
2022-08-25 19:23:44 +00:00
|
|
|
interval, _ := time.ParseDuration(limit)
|
|
|
|
|
|
|
|
if since >= interval {
|
|
|
|
cmd := `UPDATE Limits SET ticket = ? WHERE acct = ?`
|
|
|
|
stat, err := db.Prepare(cmd)
|
|
|
|
if err != nil {
|
2022-08-28 16:37:43 +00:00
|
|
|
ErrorLogger.Println("Check ticket availability")
|
2022-08-25 19:23:44 +00:00
|
|
|
}
|
2022-09-01 11:31:27 +00:00
|
|
|
stat.Exec(Conf.Max_toots, acct)
|
2022-08-25 19:23:44 +00:00
|
|
|
|
2022-09-01 11:31:27 +00:00
|
|
|
return Conf.Max_toots
|
2022-08-25 19:23:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return tickets
|
|
|
|
}
|
2022-09-06 09:31:05 +00:00
|
|
|
|
|
|
|
// Save message hash
|
|
|
|
func save_msg_hash(hash string) {
|
|
|
|
cmd1 := `SELECT COUNT(*) FROM MsgHashs`
|
|
|
|
cmd2 := `DELETE FROM MsgHashs WHERE ROWID IN (SELECT ROWID FROM MsgHashs LIMIT 1)`
|
|
|
|
cmd3 := `INSERT INTO MsgHashs (message_hash) VALUES (?)`
|
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
var rows uint
|
2022-09-06 09:31:05 +00:00
|
|
|
|
|
|
|
db.QueryRow(cmd1).Scan(&rows)
|
|
|
|
|
|
|
|
if rows >= Conf.Duplicate_buf {
|
|
|
|
superfluous := rows - Conf.Duplicate_buf
|
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
for i := uint(0); i <= superfluous; i++ {
|
2022-09-06 09:31:05 +00:00
|
|
|
stat2, err := db.Prepare(cmd2)
|
|
|
|
if err != nil {
|
|
|
|
ErrorLogger.Println("Delete message hash from database")
|
|
|
|
}
|
|
|
|
stat2.Exec()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stat1, err := db.Prepare(cmd3)
|
|
|
|
if err != nil {
|
|
|
|
ErrorLogger.Println("Add message hash to database")
|
|
|
|
}
|
|
|
|
stat1.Exec(hash)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check message hash
|
|
|
|
func check_msg_hash(hash string) bool {
|
|
|
|
cmd := `SELECT message_hash FROM MsgHashs WHERE message_hash = ?`
|
|
|
|
err := db.QueryRow(cmd, hash).Scan(&hash)
|
|
|
|
if err != nil {
|
|
|
|
if err != sql.ErrNoRows {
|
|
|
|
InfoLogger.Println("Check message hash in database")
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Count order
|
|
|
|
func count_order(acct string) {
|
|
|
|
cmd1 := `UPDATE Limits SET order_msg = ? WHERE acct != ?`
|
|
|
|
cmd2 := `SELECT order_msg FROM Limits WHERE acct = ?`
|
|
|
|
cmd3 := `UPDATE Limits SET order_msg = ? WHERE acct = ?`
|
|
|
|
|
|
|
|
stat1, err := db.Prepare(cmd1)
|
|
|
|
if err != nil {
|
|
|
|
ErrorLogger.Println("Count order to zero")
|
|
|
|
}
|
|
|
|
|
|
|
|
stat1.Exec(0, acct)
|
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
var order uint
|
2022-09-06 09:31:05 +00:00
|
|
|
db.QueryRow(cmd2, acct).Scan(&order)
|
|
|
|
if order < Conf.Order_limit {
|
|
|
|
order = order + 1
|
|
|
|
}
|
|
|
|
|
|
|
|
stat2, err := db.Prepare(cmd3)
|
|
|
|
if err != nil {
|
|
|
|
ErrorLogger.Println("Count order")
|
|
|
|
}
|
|
|
|
|
|
|
|
stat2.Exec(order, acct)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check order
|
2022-09-08 12:26:25 +00:00
|
|
|
func check_order(acct string) uint {
|
2022-09-06 09:31:05 +00:00
|
|
|
cmd := `SELECT order_msg FROM Limits WHERE acct = ?`
|
|
|
|
|
2022-09-08 12:26:25 +00:00
|
|
|
var order uint
|
2022-09-06 09:31:05 +00:00
|
|
|
db.QueryRow(cmd, acct).Scan(&order)
|
|
|
|
|
|
|
|
return order
|
|
|
|
}
|
2022-09-08 12:26:25 +00:00
|
|
|
|
|
|
|
// Mark notice
|
|
|
|
func mark_notice(acct string) {
|
|
|
|
cmd1 := `SELECT got_notice FROM Limits WHERE acct = ?`
|
|
|
|
cmd2 := `UPDATE Limits SET got_notice = ? WHERE acct = ?`
|
|
|
|
|
|
|
|
var notice uint
|
|
|
|
db.QueryRow(cmd1, acct).Scan(¬ice)
|
|
|
|
|
|
|
|
if notice == 0 {
|
|
|
|
notice = notice + 1
|
|
|
|
}
|
|
|
|
|
|
|
|
stat, err := db.Prepare(cmd2)
|
|
|
|
if err != nil {
|
|
|
|
ErrorLogger.Println("Mark notice")
|
|
|
|
}
|
|
|
|
stat.Exec(notice, acct)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset notice counter
|
|
|
|
func reset_notice_counter() {
|
|
|
|
cmd := `UPDATE Limits SET got_notice = ?`
|
|
|
|
|
|
|
|
stat, err := db.Prepare(cmd)
|
|
|
|
if err != nil {
|
|
|
|
ErrorLogger.Println("Reset notice counter")
|
|
|
|
}
|
|
|
|
stat.Exec(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if got notification
|
|
|
|
func got_notice(acct string) uint {
|
|
|
|
cmd := `SELECT got_notice FROM Limits WHERE acct = ?`
|
|
|
|
|
|
|
|
var notice uint
|
|
|
|
db.QueryRow(cmd, acct).Scan(¬ice)
|
|
|
|
|
|
|
|
return notice
|
|
|
|
}
|