258 lines
7.3 KiB
Go
258 lines
7.3 KiB
Go
// i2_bot – Instinct PokememBro Bot
|
||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||
|
||
package squader
|
||
|
||
import (
|
||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
func (s *Squader) getAllSquadsWithChats() ([]dbmapping.SquadChat, bool) {
|
||
squadsWithChats := []dbmapping.SquadChat{}
|
||
squads := []dbmapping.Squad{}
|
||
|
||
err := c.Db.Select(&squads, "SELECT * FROM squads")
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squadsWithChats, false
|
||
}
|
||
|
||
for i := range squads {
|
||
chatSquad := dbmapping.SquadChat{}
|
||
chat := dbmapping.Chat{}
|
||
floodChat := dbmapping.Chat{}
|
||
err = c.Db.Get(&chat, c.Db.Rebind("SELECT * FROM chats WHERE id=?"), squads[i].ChatID)
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squadsWithChats, false
|
||
}
|
||
err = c.Db.Get(&floodChat, c.Db.Rebind("SELECT * FROM chats WHERE id=?"), squads[i].FloodChatID)
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squadsWithChats, false
|
||
}
|
||
|
||
chatSquad.Squad = squads[i]
|
||
chatSquad.Chat = chat
|
||
chatSquad.FloodChat = floodChat
|
||
|
||
squadsWithChats = append(squadsWithChats, chatSquad)
|
||
}
|
||
|
||
return squadsWithChats, true
|
||
}
|
||
|
||
func (s *Squader) createSquad(update *tgbotapi.Update, chatID int, floodChatID int) (dbmapping.Squad, string) {
|
||
squad := dbmapping.Squad{}
|
||
chat := dbmapping.Chat{}
|
||
floodChat := dbmapping.Chat{}
|
||
|
||
// Checking if chats in database exist
|
||
err := c.Db.Get(&chat, c.Db.Rebind("SELECT * FROM chats WHERE id=?"), chatID)
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squad, "fail"
|
||
}
|
||
err = c.Db.Get(&floodChat, c.Db.Rebind("SELECT * FROM chats WHERE id=?"), floodChatID)
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squad, "fail"
|
||
}
|
||
|
||
err2 := c.Db.Get(&squad, c.Db.Rebind("SELECT * FROM squads WHERE chat_id IN (?, ?) OR flood_chat_id IN (?, ?)"), chat.ID, floodChat.ID, chat.ID, floodChat.ID)
|
||
if err2 == nil {
|
||
return squad, "dup"
|
||
}
|
||
c.Log.Debug(err2)
|
||
|
||
err = c.Db.Get(&squad, c.Db.Rebind("SELECT * FROM squads WHERE chat_id=? AND flood_chat_id=?"), chatID, floodChatID)
|
||
if err != nil {
|
||
c.Log.Debug(err)
|
||
|
||
playerRaw, ok := c.Getters.GetOrCreatePlayer(update.Message.From.ID)
|
||
if !ok {
|
||
return squad, "fail"
|
||
}
|
||
|
||
squad.AuthorID = playerRaw.ID
|
||
squad.ChatID = chatID
|
||
squad.FloodChatID = floodChatID
|
||
squad.CreatedAt = time.Now().UTC()
|
||
|
||
_, err = c.Db.NamedExec("INSERT INTO `squads` VALUES(NULL, :chat_id, :flood_chat_id, :author_id, :created_at)", &squad)
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squad, "fail"
|
||
}
|
||
|
||
err = c.Db.Get(&squad, c.Db.Rebind("SELECT * FROM squads WHERE chat_id=? AND flood_chat_id=?"), chatID, floodChatID)
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squad, "fail"
|
||
}
|
||
|
||
return squad, "ok"
|
||
}
|
||
|
||
return squad, "dup"
|
||
}
|
||
|
||
func (s *Squader) getSquadByChatID(update *tgbotapi.Update, chatID int) (dbmapping.Squad, string) {
|
||
squad := dbmapping.Squad{}
|
||
chat := dbmapping.Chat{}
|
||
|
||
// Checking if chat in database exist
|
||
err := c.Db.Get(&chat, c.Db.Rebind("SELECT * FROM chats WHERE id=?"), chatID)
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squad, "fail"
|
||
}
|
||
|
||
err = c.Db.Get(&squad, c.Db.Rebind("SELECT * FROM squads WHERE chat_id=?"), chat.ID)
|
||
if err != nil {
|
||
c.Log.Error(err)
|
||
return squad, "fail"
|
||
}
|
||
|
||
return squad, "ok"
|
||
}
|
||
|
||
func (s *Squader) squadCreationDuplicate(update *tgbotapi.Update) string {
|
||
message := "*Отряд уже существует*\n"
|
||
message += "Проверьте, правильно ли вы ввели команду, и повторите попытку."
|
||
|
||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||
msg.ParseMode = "Markdown"
|
||
|
||
c.Bot.Send(msg)
|
||
|
||
return "fail"
|
||
}
|
||
|
||
func (s *Squader) squadCreationFailure(update *tgbotapi.Update) string {
|
||
message := "*Не удалось добавить отряд в базу*\n"
|
||
message += "Проверьте, правильно ли вы ввели команду, и повторите попытку."
|
||
|
||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||
msg.ParseMode = "Markdown"
|
||
|
||
c.Bot.Send(msg)
|
||
|
||
return "fail"
|
||
}
|
||
|
||
func (s *Squader) squadCreationSuccess(update *tgbotapi.Update) string {
|
||
message := "*Отряд успешно добавлен в базу*\n"
|
||
message += "Просмотреть список отрядов можно командой /squads."
|
||
|
||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||
msg.ParseMode = "Markdown"
|
||
|
||
c.Bot.Send(msg)
|
||
|
||
return "fail"
|
||
}
|
||
|
||
// External functions
|
||
|
||
// CreateSquad creates new squad from chat if not already exist
|
||
func (s *Squader) CreateSquad(update *tgbotapi.Update) string {
|
||
commandArugments := update.Message.CommandArguments()
|
||
argumentsRx := regexp.MustCompile(`(\d+)\s(\d+)`)
|
||
|
||
if !argumentsRx.MatchString(commandArugments) {
|
||
return s.squadCreationFailure(update)
|
||
}
|
||
|
||
chatNumbers := strings.Split(commandArugments, " ")
|
||
if len(chatNumbers) < 2 {
|
||
return s.squadCreationFailure(update)
|
||
}
|
||
chatID, _ := strconv.Atoi(chatNumbers[0])
|
||
if chatID == 0 {
|
||
return s.squadCreationFailure(update)
|
||
}
|
||
floodChatID, _ := strconv.Atoi(chatNumbers[1])
|
||
if floodChatID == 0 {
|
||
return s.squadCreationFailure(update)
|
||
}
|
||
|
||
_, ok := s.createSquad(update, chatID, floodChatID)
|
||
if ok == "fail" {
|
||
return s.squadCreationFailure(update)
|
||
} else if ok == "dup" {
|
||
return s.squadCreationDuplicate(update)
|
||
}
|
||
|
||
return s.squadCreationSuccess(update)
|
||
}
|
||
|
||
// SquadsList lists all squads
|
||
func (s *Squader) SquadsList(update *tgbotapi.Update) string {
|
||
squads, ok := s.getAllSquadsWithChats()
|
||
if !ok {
|
||
return "fail"
|
||
}
|
||
|
||
message := "*Наши отряды:*\n"
|
||
|
||
for i := range squads {
|
||
message += "---\n"
|
||
message += "[#" + strconv.Itoa(squads[i].Squad.ID) + "] _" + squads[i].Chat.Name
|
||
message += "_ /show\\_squad" + strconv.Itoa(squads[i].Squad.ID) + "\n"
|
||
message += "Telegram ID: " + strconv.FormatInt(squads[i].Chat.TelegramID, 10) + "\n"
|
||
message += "Флудилка отряда: _" + squads[i].FloodChat.Name + "_\n"
|
||
message += "Статистика отряда:\n"
|
||
message += s.SquadStatictics(squads[i].Squad.ID)
|
||
}
|
||
|
||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||
msg.ParseMode = "Markdown"
|
||
|
||
c.Bot.Send(msg)
|
||
|
||
return "ok"
|
||
}
|
||
|
||
// SquadStatictics generates statistics message snippet. Public due to usage in chats list
|
||
func (s *Squader) SquadStatictics(squadID int) string {
|
||
squadMembersWithInformation := []dbmapping.SquadPlayerFull{}
|
||
squadMembers := []dbmapping.SquadPlayer{}
|
||
squad := dbmapping.Squad{}
|
||
|
||
err := c.Db.Get(&squad, c.Db.Rebind("SELECT * FROM squads WHERE id=?"), squadID)
|
||
if err != nil {
|
||
c.Log.Error(err.Error())
|
||
return "Отряда не существует!"
|
||
}
|
||
|
||
err = c.Db.Select(&squadMembers, c.Db.Rebind("SELECT * FROM squads_players WHERE squad_id=?"), squadID)
|
||
if err != nil {
|
||
c.Log.Error(err.Error())
|
||
return "Невозможно получить информацию о данном отряде. Возможно, он пуст или произошла ошибка."
|
||
}
|
||
|
||
for i := range squadMembers {
|
||
fullInfo := dbmapping.SquadPlayerFull{}
|
||
|
||
playerRaw, _ := c.Getters.GetPlayerByID(squadMembers[i].PlayerID)
|
||
profileRaw, _ := c.Getters.GetProfile(playerRaw.ID)
|
||
|
||
fullInfo.Squad = squad
|
||
fullInfo.Player = playerRaw
|
||
fullInfo.Profile = profileRaw
|
||
|
||
squadMembersWithInformation = append(squadMembersWithInformation, fullInfo)
|
||
}
|
||
|
||
message := "Количество человек в отряде: " + strconv.Itoa(len(squadMembersWithInformation))
|
||
message += "\n"
|
||
|
||
return message
|
||
}
|