176 lines
3.7 KiB
Go
176 lines
3.7 KiB
Go
package chat
|
|
|
|
import (
|
|
"database/sql"
|
|
"strings"
|
|
"time"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
"github.com/owncast/owncast/core/data"
|
|
"github.com/owncast/owncast/models"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var _db *sql.DB
|
|
|
|
func setupPersistence() {
|
|
_db = data.GetDatabase()
|
|
createTable()
|
|
}
|
|
|
|
func createTable() {
|
|
createTableSQL := `CREATE TABLE IF NOT EXISTS messages (
|
|
"id" string NOT NULL PRIMARY KEY,
|
|
"author" TEXT,
|
|
"body" TEXT,
|
|
"messageType" TEXT,
|
|
"visible" INTEGER,
|
|
"timestamp" DATE
|
|
);`
|
|
|
|
stmt, err := _db.Prepare(createTableSQL)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer stmt.Close()
|
|
_, err = stmt.Exec()
|
|
if err != nil {
|
|
log.Warnln(err)
|
|
}
|
|
}
|
|
|
|
func addMessage(message models.ChatEvent) {
|
|
tx, err := _db.Begin()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
stmt, err := tx.Prepare("INSERT INTO messages(id, author, body, messageType, visible, timestamp) values(?, ?, ?, ?, ?, ?)")
|
|
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer stmt.Close()
|
|
|
|
_, err = stmt.Exec(message.ID, message.Author, message.Body, message.MessageType, 1, message.Timestamp)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
err = tx.Commit()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func getChat(query string) []models.ChatEvent {
|
|
history := make([]models.ChatEvent, 0)
|
|
rows, err := _db.Query(query)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
var id string
|
|
var author string
|
|
var body string
|
|
var messageType models.EventType
|
|
var visible int
|
|
var timestamp time.Time
|
|
|
|
err = rows.Scan(&id, &author, &body, &messageType, &visible, ×tamp)
|
|
if err != nil {
|
|
log.Debugln(err)
|
|
log.Error("There is a problem with the chat database. Restore a backup of owncast.db or remove it and start over.")
|
|
break
|
|
}
|
|
|
|
message := models.ChatEvent{}
|
|
message.ID = id
|
|
message.Author = author
|
|
message.Body = body
|
|
message.MessageType = messageType
|
|
message.Visible = visible == 1
|
|
message.Timestamp = timestamp
|
|
|
|
history = append(history, message)
|
|
}
|
|
|
|
if err := rows.Err(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
return history
|
|
}
|
|
|
|
func getChatModerationHistory() []models.ChatEvent {
|
|
var query = "SELECT * FROM messages WHERE messageType == 'CHAT' AND datetime(timestamp) >=datetime('now', '-5 Hour')"
|
|
return getChat(query)
|
|
}
|
|
|
|
func getChatHistory() []models.ChatEvent {
|
|
// Get all messages sent within the past 5hrs, max 50
|
|
var query = "SELECT * FROM (SELECT * FROM messages WHERE datetime(timestamp) >=datetime('now', '-5 Hour') AND visible = 1 ORDER BY timestamp DESC LIMIT 50) ORDER BY timestamp asc"
|
|
return getChat(query)
|
|
}
|
|
|
|
func saveMessageVisibility(messageIDs []string, visible bool) error {
|
|
tx, err := _db.Begin()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
stmt, err := tx.Prepare("UPDATE messages SET visible=? WHERE id IN (?" + strings.Repeat(",?", len(messageIDs)-1) + ")")
|
|
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
return err
|
|
}
|
|
defer stmt.Close()
|
|
|
|
args := make([]interface{}, len(messageIDs)+1)
|
|
args[0] = visible
|
|
for i, id := range messageIDs {
|
|
args[i+1] = id
|
|
}
|
|
|
|
_, err = stmt.Exec(args...)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
return err
|
|
}
|
|
|
|
if err = tx.Commit(); err != nil {
|
|
log.Fatal(err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getMessageById(messageID string) (models.ChatEvent, error) {
|
|
var query = "SELECT * FROM messages WHERE id = ?"
|
|
row := _db.QueryRow(query, messageID)
|
|
|
|
var id string
|
|
var author string
|
|
var body string
|
|
var messageType models.EventType
|
|
var visible int
|
|
var timestamp time.Time
|
|
|
|
err := row.Scan(&id, &author, &body, &messageType, &visible, ×tamp)
|
|
if err != nil {
|
|
log.Errorln(err)
|
|
return models.ChatEvent{}, err
|
|
}
|
|
|
|
return models.ChatEvent{
|
|
ID: id,
|
|
Author: author,
|
|
Body: body,
|
|
MessageType: messageType,
|
|
Visible: visible == 1,
|
|
Timestamp: timestamp,
|
|
}, nil
|
|
}
|