Archived
1

Pins to supergroups, managed by admins

This commit is contained in:
Vladimir Hodakov 2017-11-14 03:44:21 +04:00
parent 5c08899d25
commit 95a9a2146a
84 changed files with 786 additions and 622 deletions

30
Gopkg.lock generated
View File

@ -10,8 +10,8 @@
[[projects]] [[projects]]
name = "github.com/go-telegram-bot-api/telegram-bot-api" name = "github.com/go-telegram-bot-api/telegram-bot-api"
packages = ["."] packages = ["."]
revision = "0a57807db79efce7f6719fbb2c0e0f83fda79aec" revision = "2022d04b94f50056a09962b1ac81cdd821d20a55"
version = "v4.6" version = "v4.6.1"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -25,21 +25,45 @@
revision = "056a4d47dcc4d67fa3947a4f13945a5c690e568b" revision = "056a4d47dcc4d67fa3947a4f13945a5c690e568b"
version = "v2.1.0" version = "v2.1.0"
[[projects]]
name = "github.com/sirupsen/logrus"
packages = ["."]
revision = "f006c2ac4710855cf0f916dd6b77acf6b048dc6e"
version = "v1.0.3"
[[projects]] [[projects]]
name = "github.com/technoweenie/multipartstreamer" name = "github.com/technoweenie/multipartstreamer"
packages = ["."] packages = ["."]
revision = "a90a01d73ae432e2611d178c18367fbaa13e0154" revision = "a90a01d73ae432e2611d178c18367fbaa13e0154"
version = "v1.0.1" version = "v1.0.1"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = ["ssh/terminal"]
revision = "9f005a07e0d31d45e6656d241bb5c0f2efd4bc94"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix","windows"]
revision = "665f6529cca930e27b831a0d1dafffbe1c172924"
[[projects]] [[projects]]
branch = "v2" branch = "v2"
name = "gopkg.in/yaml.v2" name = "gopkg.in/yaml.v2"
packages = ["."] packages = ["."]
revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f" revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
[[projects]]
branch = "master"
name = "lab.pztrn.name/golibs/mogrus"
packages = ["."]
revision = "a888e29e1fff06c2e6ebc607055a02de22a6ddae"
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "5020a2712e7a565f5f7ed84b6ea5fe7a369303903dc3dfeb0de03777806f585e" inputs-digest = "3e9df6d446d8789d138790622cf19935d4331f9903af640d13654c07b9f433a5"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -4,18 +4,17 @@
package main package main
import ( import (
// stdlib
"time"
// 3rd-party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
"lab.pztrn.name/fat0troll/i2_bot/lib/forwarder"
"lab.pztrn.name/fat0troll/i2_bot/lib/getters" "lab.pztrn.name/fat0troll/i2_bot/lib/getters"
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations" "lab.pztrn.name/fat0troll/i2_bot/lib/migrations"
"lab.pztrn.name/fat0troll/i2_bot/lib/parsers" "lab.pztrn.name/fat0troll/i2_bot/lib/parsers"
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner"
"lab.pztrn.name/fat0troll/i2_bot/lib/router" "lab.pztrn.name/fat0troll/i2_bot/lib/router"
"lab.pztrn.name/fat0troll/i2_bot/lib/talkers" "lab.pztrn.name/fat0troll/i2_bot/lib/talkers"
"lab.pztrn.name/fat0troll/i2_bot/lib/welcomer" "lab.pztrn.name/fat0troll/i2_bot/lib/welcomer"
"time"
) )
var ( var (
@ -28,11 +27,17 @@ func main() {
router.New(c) router.New(c)
migrations.New(c) migrations.New(c)
c.RunDatabaseMigrations() c.RunDatabaseMigrations()
forwarder.New(c)
parsers.New(c) parsers.New(c)
pinner.New(c)
talkers.New(c) talkers.New(c)
getters.New(c) getters.New(c)
welcomer.New(c) welcomer.New(c)
c.Log.Info("=======================")
c.Log.Info("= i2_bot initialized. =")
c.Log.Info("=======================")
u := tgbotapi.NewUpdate(0) u := tgbotapi.NewUpdate(0)
u.Timeout = 60 u.Timeout = 60
@ -46,6 +51,6 @@ func main() {
continue continue
} }
c.Router.RouteRequest(update) c.Router.RouteRequest(&update)
} }
} }

View File

@ -8,3 +8,5 @@ database_connection:
database: "i2_bot" database: "i2_bot"
notifications: notifications:
group_id: "group_id" group_id: "group_id"
logs:
log_path: "./i2_bot.log"

View File

@ -4,25 +4,28 @@
package appcontext package appcontext
import ( import (
// 3rd-party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/config" "lab.pztrn.name/fat0troll/i2_bot/lib/config"
"lab.pztrn.name/fat0troll/i2_bot/lib/connections" "lab.pztrn.name/fat0troll/i2_bot/lib/connections"
// interfaces "lab.pztrn.name/fat0troll/i2_bot/lib/forwarder/forwarderinterface"
"lab.pztrn.name/fat0troll/i2_bot/lib/getters/gettersinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/getters/gettersinterface"
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations/migrationsinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/migrations/migrationsinterface"
"lab.pztrn.name/fat0troll/i2_bot/lib/parsers/parsersinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/parsers/parsersinterface"
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner/pinnerinterface"
"lab.pztrn.name/fat0troll/i2_bot/lib/router/routerinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/router/routerinterface"
"lab.pztrn.name/fat0troll/i2_bot/lib/talkers/talkersinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/talkers/talkersinterface"
"lab.pztrn.name/fat0troll/i2_bot/lib/welcomer/welcomerinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/welcomer/welcomerinterface"
"lab.pztrn.name/golibs/mogrus"
"os"
) )
// Context is an application context struct // Context is an application context struct
type Context struct { type Context struct {
Cfg *config.Config Cfg *config.Config
Log *mogrus.LoggerHandler
Bot *tgbotapi.BotAPI Bot *tgbotapi.BotAPI
Forwarder forwarderinterface.ForwarderInterface
Migrations migrationsinterface.MigrationsInterface Migrations migrationsinterface.MigrationsInterface
Router routerinterface.RouterInterface Router routerinterface.RouterInterface
Parsers parsersinterface.ParsersInterface Parsers parsersinterface.ParsersInterface
@ -30,14 +33,30 @@ type Context struct {
Talkers talkersinterface.TalkersInterface Talkers talkersinterface.TalkersInterface
Getters gettersinterface.GettersInterface Getters gettersinterface.GettersInterface
Welcomer welcomerinterface.WelcomerInterface Welcomer welcomerinterface.WelcomerInterface
Pinner pinnerinterface.PinnerInterface
} }
// Init is a initialization function for context // Init is a initialization function for context
func (c *Context) Init() { func (c *Context) Init() {
c.Cfg = config.New() c.Cfg = config.New()
c.Cfg.Init() c.Cfg.Init()
c.Bot = connections.BotInit(c.Cfg)
c.Db = connections.DBInit(c.Cfg) l := mogrus.New()
l.Initialize()
log := l.CreateLogger("i2_bot")
log.CreateOutput("stdout", os.Stdout, true, "debug")
logFile, err := os.OpenFile(c.Cfg.Logs.LogPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660)
if err != nil {
log.Fatalln(err)
}
log.CreateOutput("file="+c.Cfg.Logs.LogPath, logFile, true, "debug")
c.Log = log
c.Bot = connections.BotInit(c.Cfg, c.Log)
c.Db = connections.DBInit(c.Cfg, c.Log)
} }
// RegisterRouterInterface registering router interface in application // RegisterRouterInterface registering router interface in application
@ -60,16 +79,31 @@ func (c *Context) RegisterParsersInterface(pi parsersinterface.ParsersInterface)
// RegisterTalkersInterface registering talkers interface in application // RegisterTalkersInterface registering talkers interface in application
func (c *Context) RegisterTalkersInterface(ti talkersinterface.TalkersInterface) { func (c *Context) RegisterTalkersInterface(ti talkersinterface.TalkersInterface) {
c.Talkers = ti c.Talkers = ti
c.Talkers.Init()
} }
// RegisterGettersInterface registering getters interface in application // RegisterGettersInterface registering getters interface in application
func (c *Context) RegisterGettersInterface(gi gettersinterface.GettersInterface) { func (c *Context) RegisterGettersInterface(gi gettersinterface.GettersInterface) {
c.Getters = gi c.Getters = gi
c.Getters.Init()
} }
// RegisterWelcomerInterface registering welcomer interface in application // RegisterWelcomerInterface registering welcomer interface in application
func (c *Context) RegisterWelcomerInterface(wi welcomerinterface.WelcomerInterface) { func (c *Context) RegisterWelcomerInterface(wi welcomerinterface.WelcomerInterface) {
c.Welcomer = wi c.Welcomer = wi
c.Welcomer.Init()
}
// RegisterPinnerInterface registering pinner interface in application
func (c *Context) RegisterPinnerInterface(pi pinnerinterface.PinnerInterface) {
c.Pinner = pi
c.Pinner.Init()
}
// RegisterForwarderInterface registers forwarder interface in application
func (c *Context) RegisterForwarderInterface(fi forwarderinterface.ForwarderInterface) {
c.Forwarder = fi
c.Forwarder.Init()
} }
// RunDatabaseMigrations applies migrations on bot's startup // RunDatabaseMigrations applies migrations on bot's startup

View File

@ -4,15 +4,13 @@
package config package config
import ( import (
// stdlib "gopkg.in/yaml.v2"
"io/ioutil" "io/ioutil"
"log" "log"
"path/filepath" "path/filepath"
// 3rd-party
"gopkg.in/yaml.v2"
) )
const VERSION = "0.297" const VERSION = "0.35"
// DatabaseConnection handles database connection settings in config.yaml // DatabaseConnection handles database connection settings in config.yaml
type DatabaseConnection struct { type DatabaseConnection struct {
@ -33,11 +31,17 @@ type NotificationsConnection struct {
GroupID string `yaml:"group_id"` GroupID string `yaml:"group_id"`
} }
// LoggingConfig handles log file configuration
type LoggingConfig struct {
LogPath string `yaml:"log_path"`
}
// Config is a struct which represents config.yaml structure // Config is a struct which represents config.yaml structure
type Config struct { type Config struct {
Telegram TelegramConnection `yaml:"telegram_connection"` Telegram TelegramConnection `yaml:"telegram_connection"`
Database DatabaseConnection `yaml:"database_connection"` Database DatabaseConnection `yaml:"database_connection"`
Notifications NotificationsConnection `yaml:"notifications"` Notifications NotificationsConnection `yaml:"notifications"`
Logs LoggingConfig `yaml:"logs"`
} }
// Init is a configuration initializer // Init is a configuration initializer

View File

@ -4,37 +4,34 @@
package connections package connections
import ( import (
// stdlib
"log"
// 3rd-party
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local "github.com/jmoiron/sqlx"
"lab.pztrn.name/fat0troll/i2_bot/lib/config" "lab.pztrn.name/fat0troll/i2_bot/lib/config"
"lab.pztrn.name/golibs/mogrus"
) )
// BotInit initializes connection to Telegram // BotInit initializes connection to Telegram
func BotInit(cfg *config.Config) *tgbotapi.BotAPI { func BotInit(cfg *config.Config, lg *mogrus.LoggerHandler) *tgbotapi.BotAPI {
bot, err := tgbotapi.NewBotAPI(cfg.Telegram.APIToken) bot, err := tgbotapi.NewBotAPI(cfg.Telegram.APIToken)
if err != nil { if err != nil {
log.Panic(err) lg.Fatal(err.Error())
} }
bot.Debug = true bot.Debug = true
log.Printf("Bot version: " + config.VERSION) lg.Info("Bot version: " + config.VERSION)
log.Printf("Authorized on account %s", bot.Self.UserName) lg.Info("Authorized on account @", bot.Self.UserName)
return bot return bot
} }
// DBInit initializes database connection // DBInit initializes database connection
func DBInit(cfg *config.Config) *sqlx.DB { func DBInit(cfg *config.Config, lg *mogrus.LoggerHandler) *sqlx.DB {
database, err := sqlx.Connect("mysql", cfg.Database.User+":"+cfg.Database.Password+"@tcp("+cfg.Database.Host+":"+cfg.Database.Port+")/"+cfg.Database.Database+"?parseTime=true&charset=utf8mb4,utf8") database, err := sqlx.Connect("mysql", cfg.Database.User+":"+cfg.Database.Password+"@tcp("+cfg.Database.Host+":"+cfg.Database.Port+")/"+cfg.Database.Database+"?parseTime=true&charset=utf8mb4,utf8")
if err != nil { if err != nil {
log.Fatal(err) lg.Fatal(err)
} }
log.Printf("Database connection established!") lg.Info("Database connection established!")
return database return database
} }

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

View File

@ -4,7 +4,6 @@
package dbmapping package dbmapping
import ( import (
// stdlib
"time" "time"
) )

28
lib/forwarder/exported.go Normal file
View File

@ -0,0 +1,28 @@
// i2_bot Instinct PokememBro Bot
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
package forwarder
import (
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
"lab.pztrn.name/fat0troll/i2_bot/lib/forwarder/forwarderinterface"
)
var (
c *appcontext.Context
)
// Forwarder is a function-handling struct for package forwarder.
type Forwarder struct{}
// New is an initialization function for appcontext
func New(ac *appcontext.Context) {
c = ac
f := &Forwarder{}
c.RegisterForwarderInterface(forwarderinterface.ForwarderInterface(f))
}
// Init is a initialization function for package
func (f *Forwarder) Init() {
c.Log.Info("Initializing forwarder...")
}

View File

@ -0,0 +1,55 @@
// i2_bot Instinct PokememBro Bot
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
package forwarder
import (
"github.com/go-telegram-bot-api/telegram-bot-api"
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"regexp"
)
// ProcessForward process forwards for single-user chats
func (f *Forwarder) ProcessForward(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
text := update.Message.Text
// Forwards
var pokememeMsg = regexp.MustCompile("(Уровень)(.+)(Опыт)(.+)\n(Элементы:)(.+)\n(.+)(💙MP)")
var profileMsg = regexp.MustCompile(`(Онлайн: )(\d+)\n(Турнир через)(.+)\n\n((.*)\n|(.*)\n(.*)\n)(Элементы)(.+)\n(.*)\n\n(.+)(Уровень)(.+)\n`)
switch {
case pokememeMsg.MatchString(text):
c.Log.Debug("Pokememe posted!")
if playerRaw.LeagueID == 1 {
status := c.Parsers.ParsePokememe(text, playerRaw)
switch status {
case "ok":
c.Talkers.PokememeAddSuccessMessage(update)
return "ok"
case "dup":
c.Talkers.PokememeAddDuplicateMessage(update)
return "ok"
case "fail":
c.Talkers.PokememeAddFailureMessage(update)
return "fail"
}
} else {
c.Talkers.AnyMessageUnauthorized(update)
return "fail"
}
case profileMsg.MatchString(text):
c.Log.Debug("Profile posted!")
status := c.Parsers.ParseProfile(update, playerRaw)
switch status {
case "ok":
c.Talkers.ProfileAddSuccessMessage(update)
return "ok"
case "fail":
c.Talkers.ProfileAddFailureMessage(update)
return "fail"
}
default:
c.Log.Debug(text)
}
return "fail"
}

View File

@ -0,0 +1,15 @@
// i2_bot Instinct PokememBro Bot
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
package forwarderinterface
import (
"github.com/go-telegram-bot-api/telegram-bot-api"
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
)
// ForwarderInterface implements Getters for importing via appcontext.
type ForwarderInterface interface {
Init()
ProcessForward(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
}

View File

@ -4,11 +4,8 @@
package getters package getters
import ( import (
// stdlib
"log"
"time"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"time"
) )
// CreateBroadcastMessage creates broadcast message item in database // CreateBroadcastMessage creates broadcast message item in database
@ -21,12 +18,12 @@ func (g *Getters) CreateBroadcastMessage(playerRaw *dbmapping.Player, messageBod
messageRaw.CreatedAt = time.Now().UTC() messageRaw.CreatedAt = time.Now().UTC()
_, err := c.Db.NamedExec("INSERT INTO broadcasts VALUES(NULL, :text, :broadcast_type, :status, :author_id, :created_at)", &messageRaw) _, err := c.Db.NamedExec("INSERT INTO broadcasts VALUES(NULL, :text, :broadcast_type, :status, :author_id, :created_at)", &messageRaw)
if err != nil { if err != nil {
log.Printf(err.Error()) c.Log.Error(err.Error())
return messageRaw, false return messageRaw, false
} }
err2 := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE author_id=? AND text=?"), messageRaw.AuthorID, messageRaw.Text) err2 := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE author_id=? AND text=?"), messageRaw.AuthorID, messageRaw.Text)
if err2 != nil { if err2 != nil {
log.Println(err2) c.Log.Error(err2)
return messageRaw, false return messageRaw, false
} }
@ -38,7 +35,7 @@ func (g *Getters) GetBroadcastMessageByID(messageID int) (dbmapping.Broadcast, b
messageRaw := dbmapping.Broadcast{} messageRaw := dbmapping.Broadcast{}
err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID) err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return messageRaw, false return messageRaw, false
} }
@ -50,18 +47,18 @@ func (g *Getters) UpdateBroadcastMessageStatus(messageID int, messageStatus stri
messageRaw := dbmapping.Broadcast{} messageRaw := dbmapping.Broadcast{}
err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID) err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err.Error())
return messageRaw, false return messageRaw, false
} }
messageRaw.Status = messageStatus messageRaw.Status = messageStatus
_, err = c.Db.NamedExec("UPDATE broadcasts SET status=:status WHERE id=:id", &messageRaw) _, err = c.Db.NamedExec("UPDATE broadcasts SET status=:status WHERE id=:id", &messageRaw)
if err != nil { if err != nil {
log.Printf(err.Error()) c.Log.Error(err.Error())
return messageRaw, false return messageRaw, false
} }
err = c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE author_id=? AND text=?"), messageRaw.AuthorID, messageRaw.Text) err = c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE author_id=? AND text=?"), messageRaw.AuthorID, messageRaw.Text)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err.Error())
return messageRaw, false return messageRaw, false
} }

View File

@ -4,13 +4,9 @@
package getters package getters
import ( import (
// stdlib
"log"
"time"
// 3rd-party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"time"
) )
// GetChatByID returns dbmapping.Chat instance with given ID. // GetChatByID returns dbmapping.Chat instance with given ID.
@ -18,7 +14,7 @@ func (g *Getters) GetChatByID(chatID int64) (dbmapping.Chat, bool) {
chatRaw := dbmapping.Chat{} chatRaw := dbmapping.Chat{}
err := c.Db.Get(&chatRaw, c.Db.Rebind("SELECT * FROM chats WHERE id=?"), chatID) err := c.Db.Get(&chatRaw, c.Db.Rebind("SELECT * FROM chats WHERE id=?"), chatID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return chatRaw, false return chatRaw, false
} }
@ -29,11 +25,11 @@ func (g *Getters) GetChatByID(chatID int64) (dbmapping.Chat, bool) {
// In case, when there is no chat with such ID, new chat will be created. // In case, when there is no chat with such ID, new chat will be created.
func (g *Getters) GetOrCreateChat(telegramUpdate *tgbotapi.Update) (dbmapping.Chat, bool) { func (g *Getters) GetOrCreateChat(telegramUpdate *tgbotapi.Update) (dbmapping.Chat, bool) {
chatRaw := dbmapping.Chat{} chatRaw := dbmapping.Chat{}
log.Println("TGID: ", telegramUpdate.Message.Chat.ID) c.Log.Debug("TGID: ", telegramUpdate.Message.Chat.ID)
err := c.Db.Get(&chatRaw, c.Db.Rebind("SELECT * FROM chats WHERE telegram_id=?"), telegramUpdate.Message.Chat.ID) err := c.Db.Get(&chatRaw, c.Db.Rebind("SELECT * FROM chats WHERE telegram_id=?"), telegramUpdate.Message.Chat.ID)
if err != nil { if err != nil {
log.Printf("Chat stream not found in database.") c.Log.Error("Chat stream not found in database.")
log.Printf(err.Error()) c.Log.Error(err.Error())
nameOfChat := "" nameOfChat := ""
if telegramUpdate.Message.Chat.FirstName != "" { if telegramUpdate.Message.Chat.FirstName != "" {
@ -56,16 +52,16 @@ func (g *Getters) GetOrCreateChat(telegramUpdate *tgbotapi.Update) (dbmapping.Ch
chatRaw.CreatedAt = time.Now().UTC() chatRaw.CreatedAt = time.Now().UTC()
_, err = c.Db.NamedExec("INSERT INTO chats VALUES(NULL, :name, :chat_type, :telegram_id, :created_at)", &chatRaw) _, err = c.Db.NamedExec("INSERT INTO chats VALUES(NULL, :name, :chat_type, :telegram_id, :created_at)", &chatRaw)
if err != nil { if err != nil {
log.Printf(err.Error()) c.Log.Error(err.Error())
return chatRaw, false return chatRaw, false
} }
err2 := c.Db.Get(&chatRaw, c.Db.Rebind("SELECT * FROM chats WHERE telegram_id=? AND chat_type=?"), chatRaw.TelegramID, chatRaw.ChatType) err2 := c.Db.Get(&chatRaw, c.Db.Rebind("SELECT * FROM chats WHERE telegram_id=? AND chat_type=?"), chatRaw.TelegramID, chatRaw.ChatType)
if err2 != nil { if err2 != nil {
log.Println(err2) c.Log.Error(err2)
return chatRaw, false return chatRaw, false
} }
} else { } else {
log.Printf("Chat stream found in database.") c.Log.Info("Chat stream found in database.")
} }
return chatRaw, true return chatRaw, true
@ -77,7 +73,7 @@ func (g *Getters) GetAllPrivateChats() ([]dbmapping.Chat, bool) {
err := c.Db.Select(&privateChats, "SELECT * FROM chats WHERE chat_type='private'") err := c.Db.Select(&privateChats, "SELECT * FROM chats WHERE chat_type='private'")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return privateChats, false return privateChats, false
} }
@ -90,7 +86,7 @@ func (g *Getters) GetAllGroupChats() ([]dbmapping.Chat, bool) {
err := c.Db.Select(&groupChats, "SELECT * FROM chats WHERE chat_type IN ('group', 'supergroup')") err := c.Db.Select(&groupChats, "SELECT * FROM chats WHERE chat_type IN ('group', 'supergroup')")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return groupChats, false return groupChats, false
} }
@ -104,7 +100,7 @@ func (g *Getters) GetAllGroupChatsWithSquads() ([]dbmapping.SquadChat, bool) {
err := c.Db.Select(&groupChats, "SELECT * FROM chats WHERE chat_type IN ('group', 'supergroup')") err := c.Db.Select(&groupChats, "SELECT * FROM chats WHERE chat_type IN ('group', 'supergroup')")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return chatsSquads, false return chatsSquads, false
} }
@ -113,7 +109,7 @@ func (g *Getters) GetAllGroupChatsWithSquads() ([]dbmapping.SquadChat, bool) {
squad := dbmapping.Squad{} squad := dbmapping.Squad{}
err = c.Db.Select(&squad, c.Db.Rebind("SELECT * FROM squads WHERE chat_id="), groupChats[i].ID) err = c.Db.Select(&squad, c.Db.Rebind("SELECT * FROM squads WHERE chat_id="), groupChats[i].ID)
if err != nil { if err != nil {
log.Println(err) c.Log.Debug(err)
chatSquad.IsSquad = false chatSquad.IsSquad = false
} else { } else {
chatSquad.IsSquad = true chatSquad.IsSquad = true
@ -129,11 +125,11 @@ func (g *Getters) GetAllGroupChatsWithSquads() ([]dbmapping.SquadChat, bool) {
} }
// UpdateChatTitle updates chat title in database // UpdateChatTitle updates chat title in database
func (g *Getters) UpdateChatTitle(chatRaw dbmapping.Chat, newTitle string) (dbmapping.Chat, bool) { func (g *Getters) UpdateChatTitle(chatRaw *dbmapping.Chat, newTitle string) (*dbmapping.Chat, bool) {
chatRaw.Name = newTitle chatRaw.Name = newTitle
_, err := c.Db.NamedExec("UPDATE chats SET name=:name WHERE id=:id", &chatRaw) _, err := c.Db.NamedExec("UPDATE chats SET name=:name WHERE id=:id", &chatRaw)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return chatRaw, false return chatRaw, false
} }

View File

@ -4,9 +4,6 @@
package getters package getters
import ( import (
// stdlib
"log"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
"lab.pztrn.name/fat0troll/i2_bot/lib/getters/gettersinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/getters/gettersinterface"
) )
@ -27,5 +24,5 @@ func New(ac *appcontext.Context) {
// Init is a initialization function for package // Init is a initialization function for package
func (g *Getters) Init() { func (g *Getters) Init() {
log.Printf("Initializing getters...") c.Log.Info("Initializing getters...")
} }

View File

@ -4,9 +4,7 @@
package gettersinterface package gettersinterface
import ( import (
// 3rd-party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
@ -21,7 +19,7 @@ type GettersInterface interface {
GetAllPrivateChats() ([]dbmapping.Chat, bool) GetAllPrivateChats() ([]dbmapping.Chat, bool)
GetAllGroupChats() ([]dbmapping.Chat, bool) GetAllGroupChats() ([]dbmapping.Chat, bool)
GetAllGroupChatsWithSquads() ([]dbmapping.SquadChat, bool) GetAllGroupChatsWithSquads() ([]dbmapping.SquadChat, bool)
UpdateChatTitle(chatRaw dbmapping.Chat, newTitle string) (dbmapping.Chat, bool) UpdateChatTitle(chatRaw *dbmapping.Chat, newTitle string) (*dbmapping.Chat, bool)
GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool)
GetPlayerByID(playerID int) (dbmapping.Player, bool) GetPlayerByID(playerID int) (dbmapping.Player, bool)
PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool

View File

@ -4,11 +4,8 @@
package getters package getters
import ( import (
// stdlib
"log"
"time"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"time"
) )
// GetPlayerByID returns dbmapping.Player instance with given ID. // GetPlayerByID returns dbmapping.Player instance with given ID.
@ -16,7 +13,7 @@ func (g *Getters) GetPlayerByID(playerID int) (dbmapping.Player, bool) {
playerRaw := dbmapping.Player{} playerRaw := dbmapping.Player{}
err := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE id=?"), playerID) err := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE id=?"), playerID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err.Error())
return playerRaw, false return playerRaw, false
} }
@ -29,8 +26,8 @@ func (g *Getters) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) {
playerRaw := dbmapping.Player{} playerRaw := dbmapping.Player{}
err := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id=?"), telegramID) err := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id=?"), telegramID)
if err != nil { if err != nil {
log.Printf("Message user not found in database.") c.Log.Error("Message user not found in database.")
log.Printf(err.Error()) c.Log.Error(err.Error())
// Create "nobody" user // Create "nobody" user
playerRaw.TelegramID = telegramID playerRaw.TelegramID = telegramID
@ -40,11 +37,11 @@ func (g *Getters) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) {
playerRaw.UpdatedAt = time.Now().UTC() playerRaw.UpdatedAt = time.Now().UTC()
_, err = c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :status, :created_at, :updated_at)", &playerRaw) _, err = c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :status, :created_at, :updated_at)", &playerRaw)
if err != nil { if err != nil {
log.Printf(err.Error()) c.Log.Error(err.Error())
return playerRaw, false return playerRaw, false
} }
} else { } else {
log.Printf("Message user found in database.") c.Log.Debug("Message user found in database.")
} }
return playerRaw, true return playerRaw, true

View File

@ -4,11 +4,8 @@
package getters package getters
import ( import (
// stdlib
"log"
"strconv"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"strconv"
) )
// Internal functions // Internal functions
@ -18,25 +15,25 @@ func (g *Getters) formFullPokememes(pokememes []dbmapping.Pokememe) ([]dbmapping
elements := []dbmapping.Element{} elements := []dbmapping.Element{}
err := c.Db.Select(&elements, "SELECT * FROM elements") err := c.Db.Select(&elements, "SELECT * FROM elements")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return pokememesArray, false return pokememesArray, false
} }
locations := []dbmapping.Location{} locations := []dbmapping.Location{}
err = c.Db.Select(&locations, "SELECT * FROM locations") err = c.Db.Select(&locations, "SELECT * FROM locations")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return pokememesArray, false return pokememesArray, false
} }
pokememesElements := []dbmapping.PokememeElement{} pokememesElements := []dbmapping.PokememeElement{}
err = c.Db.Select(&pokememesElements, "SELECT * FROM pokememes_elements") err = c.Db.Select(&pokememesElements, "SELECT * FROM pokememes_elements")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return pokememesArray, false return pokememesArray, false
} }
pokememesLocations := []dbmapping.PokememeLocation{} pokememesLocations := []dbmapping.PokememeLocation{}
err = c.Db.Select(&pokememesLocations, "SELECT * FROM pokememes_locations") err = c.Db.Select(&pokememesLocations, "SELECT * FROM pokememes_locations")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return pokememesArray, false return pokememesArray, false
} }
@ -83,7 +80,7 @@ func (g *Getters) GetPokememes() ([]dbmapping.PokememeFull, bool) {
pokememes := []dbmapping.Pokememe{} pokememes := []dbmapping.Pokememe{}
err := c.Db.Select(&pokememes, "SELECT * FROM pokememes ORDER BY grade asc, name asc") err := c.Db.Select(&pokememes, "SELECT * FROM pokememes ORDER BY grade asc, name asc")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return pokememesArray, false return pokememesArray, false
} }
@ -111,7 +108,7 @@ func (g *Getters) GetBestPokememes(playerID int) ([]dbmapping.PokememeFull, bool
pokememes := []dbmapping.Pokememe{} pokememes := []dbmapping.Pokememe{}
err := c.Db.Select(&pokememes, c.Db.Rebind("SELECT p.* FROM pokememes p, pokememes_elements pe, elements e WHERE e.league_id = ? AND p.grade = ? AND pe.element_id = e.id AND pe.pokememe_id = p.id ORDER BY p.attack DESC"), playerRaw.LeagueID, profileRaw.LevelID+1) err := c.Db.Select(&pokememes, c.Db.Rebind("SELECT p.* FROM pokememes p, pokememes_elements pe, elements e WHERE e.league_id = ? AND p.grade = ? AND pe.element_id = e.id AND pe.pokememe_id = p.id ORDER BY p.attack DESC"), playerRaw.LeagueID, profileRaw.LevelID+1)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return pokememesArray, false return pokememesArray, false
} }
@ -125,31 +122,31 @@ func (g *Getters) GetPokememeByID(pokememeID string) (dbmapping.PokememeFull, bo
pokememe := dbmapping.Pokememe{} pokememe := dbmapping.Pokememe{}
err := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE id=?"), pokememeID) err := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE id=?"), pokememeID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return fullPokememe, false return fullPokememe, false
} }
elements := []dbmapping.Element{} elements := []dbmapping.Element{}
err = c.Db.Select(&elements, "SELECT * FROM elements") err = c.Db.Select(&elements, "SELECT * FROM elements")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return fullPokememe, false return fullPokememe, false
} }
locations := []dbmapping.Location{} locations := []dbmapping.Location{}
err = c.Db.Select(&locations, "SELECT * FROM locations") err = c.Db.Select(&locations, "SELECT * FROM locations")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return fullPokememe, false return fullPokememe, false
} }
pokememesElements := []dbmapping.PokememeElement{} pokememesElements := []dbmapping.PokememeElement{}
err = c.Db.Select(&pokememesElements, "SELECT * FROM pokememes_elements WHERE pokememe_id='"+strconv.Itoa(pokememe.ID)+"'") err = c.Db.Select(&pokememesElements, "SELECT * FROM pokememes_elements WHERE pokememe_id='"+strconv.Itoa(pokememe.ID)+"'")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return fullPokememe, false return fullPokememe, false
} }
pokememesLocations := []dbmapping.PokememeLocation{} pokememesLocations := []dbmapping.PokememeLocation{}
err = c.Db.Select(&pokememesLocations, "SELECT * FROM pokememes_locations WHERE pokememe_id='"+strconv.Itoa(pokememe.ID)+"'") err = c.Db.Select(&pokememesLocations, "SELECT * FROM pokememes_locations WHERE pokememe_id='"+strconv.Itoa(pokememe.ID)+"'")
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return fullPokememe, false return fullPokememe, false
} }

View File

@ -3,11 +3,6 @@
package getters package getters
import (
// stdlib
"log"
)
// PossibilityRequiredPokeballs returns possibility of catching pokememe // PossibilityRequiredPokeballs returns possibility of catching pokememe
// It's based on location, grade of pokememe and current level of player // It's based on location, grade of pokememe and current level of player
func (g *Getters) PossibilityRequiredPokeballs(location int, grade int, lvl int) (float64, int) { func (g *Getters) PossibilityRequiredPokeballs(location int, grade int, lvl int) (float64, int) {
@ -69,7 +64,7 @@ func (g *Getters) PossibilityRequiredPokeballs(location int, grade int, lvl int)
err := c.Db.Get(&pokememesCount, c.Db.Rebind("SELECT count(*) FROM pokememes p, pokememes_locations pl WHERE p.grade = ? AND pl.location_id = ? AND pl.pokememe_id = p.id;"), grade, location) err := c.Db.Get(&pokememesCount, c.Db.Rebind("SELECT count(*) FROM pokememes p, pokememes_locations pl WHERE p.grade = ? AND pl.location_id = ? AND pl.pokememe_id = p.id;"), grade, location)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
} }
if basePossibility != 0 && pokememesCount != 0 { if basePossibility != 0 && pokememesCount != 0 {

View File

@ -4,9 +4,6 @@
package getters package getters
import ( import (
// stdlib
"log"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
@ -15,7 +12,7 @@ func (g *Getters) GetProfile(playerID int) (dbmapping.Profile, bool) {
profileRaw := dbmapping.Profile{} profileRaw := dbmapping.Profile{}
err := c.Db.Get(&profileRaw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? ORDER BY created_at DESC LIMIT 1"), playerID) err := c.Db.Get(&profileRaw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? ORDER BY created_at DESC LIMIT 1"), playerID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
return profileRaw, false return profileRaw, false
} }

View File

@ -4,10 +4,10 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// UpdateLeaguesUp fixes some fuckup with leagues' emoji
func UpdateLeaguesUp(tx *sql.Tx) error { func UpdateLeaguesUp(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE `leagues` SET symbol='🈸' WHERE symbol=':u7533:';") _, err := tx.Exec("UPDATE `leagues` SET symbol='🈸' WHERE symbol=':u7533:';")
if err != nil { if err != nil {
@ -25,6 +25,7 @@ func UpdateLeaguesUp(tx *sql.Tx) error {
return nil return nil
} }
// UpdateLeaguesDown returns leagues emoji fuckup for sanity purposes
func UpdateLeaguesDown(tx *sql.Tx) error { func UpdateLeaguesDown(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE `leagues` SET symbol=':u7533:' WHERE symbol='🈸';") _, err := tx.Exec("UPDATE `leagues` SET symbol=':u7533:' WHERE symbol='🈸';")
if err != nil { if err != nil {

View File

@ -4,26 +4,26 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// ProfileDataAdditionsUp creates some helping databases for profiles
func ProfileDataAdditionsUp(tx *sql.Tx) error { func ProfileDataAdditionsUp(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `profiles` ADD `pokeballs` INT(11) DEFAULT 5 NOT NULL COMMENT 'Покеболы' AFTER `level_id`;") _, err := tx.Exec("ALTER TABLE `profiles` ADD `pokeballs` INT(11) DEFAULT 5 NOT NULL COMMENT 'Покеболы' AFTER `level_id`;")
if err != nil { if err != nil {
return err return err
} }
create_request := "CREATE TABLE `levels` (" request := "CREATE TABLE `levels` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID уровня и его номер'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID уровня и его номер',"
create_request += "`max_exp` int(11) NOT NULL COMMENT 'Опыт для прохождения уровня'," request += "`max_exp` int(11) NOT NULL COMMENT 'Опыт для прохождения уровня',"
create_request += "`max_egg` int(11) NOT NULL COMMENT 'Опыт для открытия яйца'," request += "`max_egg` int(11) NOT NULL COMMENT 'Опыт для открытия яйца',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `levels_created_at` (`created_at`)" request += "KEY `levels_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Уровни';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Уровни';"
_, err = tx.Exec(create_request) _, err = tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
@ -69,6 +69,7 @@ func ProfileDataAdditionsUp(tx *sql.Tx) error {
return nil return nil
} }
// ProfileDataAdditionsDown drops `levels` table and `pokeballs` column of `profiles` table
func ProfileDataAdditionsDown(tx *sql.Tx) error { func ProfileDataAdditionsDown(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `pokeballs`;") _, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `pokeballs`;")
if err != nil { if err != nil {

View File

@ -4,29 +4,30 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateProfileRelationsUp creates profile-pokememes relation table
func CreateProfileRelationsUp(tx *sql.Tx) error { func CreateProfileRelationsUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `profiles_pokememes` (" request := "CREATE TABLE `profiles_pokememes` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи',"
create_request += "`profile_id` int(11) NOT NULL COMMENT 'ID профиля'," request += "`profile_id` int(11) NOT NULL COMMENT 'ID профиля',"
create_request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема',"
create_request += "`pokememe_lvl` int(11) NOT NULL COMMENT 'Уровень покемема'," request += "`pokememe_lvl` int(11) NOT NULL COMMENT 'Уровень покемема',"
create_request += "`pokememe_rarity` varchar(191) NOT NULL DEFAULT 'common' COMMENT 'Редкость покемема'," request += "`pokememe_rarity` varchar(191) NOT NULL DEFAULT 'common' COMMENT 'Редкость покемема',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `profiles_pokememes_created_at` (`created_at`)" request += "KEY `profiles_pokememes_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Профили-Покемемы';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Профили-Покемемы';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// CreateProfileRelationsDown drops profile-pokememes relation table
func CreateProfileRelationsDown(tx *sql.Tx) error { func CreateProfileRelationsDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `profiles_pokememes`;") _, err := tx.Exec("DROP TABLE `profiles_pokememes`;")
if err != nil { if err != nil {

View File

@ -4,22 +4,22 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateWeaponsAndAddWealthUp creates `weapons` table and adds `wealth` column to `profiles`
func CreateWeaponsAndAddWealthUp(tx *sql.Tx) error { func CreateWeaponsAndAddWealthUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `weapons` (" request := "CREATE TABLE `weapons` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID оружия'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID оружия',"
create_request += "`name` varchar(191) NOT NULL COMMENT 'Название оружия'," request += "`name` varchar(191) NOT NULL COMMENT 'Название оружия',"
create_request += "`power` int(11) NOT NULL COMMENT 'Атака оружия'," request += "`power` int(11) NOT NULL COMMENT 'Атака оружия',"
create_request += "`price` int(11) NOT NULL COMMENT 'Цена в магазине'," request += "`price` int(11) NOT NULL COMMENT 'Цена в магазине',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `weapons_created_at` (`created_at`)" request += "KEY `weapons_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Оружие';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Оружие';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
@ -57,6 +57,7 @@ func CreateWeaponsAndAddWealthUp(tx *sql.Tx) error {
return nil return nil
} }
// CreateWeaponsAndAddWealthDown drops `weapons` table and `wealth` column of `profiles` table
func CreateWeaponsAndAddWealthDown(tx *sql.Tx) error { func CreateWeaponsAndAddWealthDown(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `wealth`;") _, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `wealth`;")
if err != nil { if err != nil {

View File

@ -4,10 +4,10 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// FixTimeElementUp fixes time element emoji
func FixTimeElementUp(tx *sql.Tx) error { func FixTimeElementUp(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE `elements` SET league_id=3 WHERE symbol='⌛';") _, err := tx.Exec("UPDATE `elements` SET league_id=3 WHERE symbol='⌛';")
if err != nil { if err != nil {
@ -17,6 +17,7 @@ func FixTimeElementUp(tx *sql.Tx) error {
return nil return nil
} }
// FixTimeElementDown returns fucked up emoji of time element for sanity
func FixTimeElementDown(tx *sql.Tx) error { func FixTimeElementDown(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE `elements` SET league_id=1 WHERE symbol='⌛';") _, err := tx.Exec("UPDATE `elements` SET league_id=1 WHERE symbol='⌛';")
if err != nil { if err != nil {

View File

@ -4,22 +4,22 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateChatsUp creates `chats` table
func CreateChatsUp(tx *sql.Tx) error { func CreateChatsUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `chats` (" request := "CREATE TABLE `chats` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID чата'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID чата',"
create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя чата'," request += "`name` varchar(191) NOT NULL COMMENT 'Имя чата',"
create_request += "`chat_type` bool NOT NULL COMMENT 'Тип чата'," request += "`chat_type` bool NOT NULL COMMENT 'Тип чата',"
create_request += "`telegram_id` int(11) NOT NULL COMMENT 'ID чата в Телеграме'," request += "`telegram_id` int(11) NOT NULL COMMENT 'ID чата в Телеграме',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `chats_created_at` (`created_at`)" request += "KEY `chats_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Чаты';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Чаты';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
@ -27,6 +27,7 @@ func CreateChatsUp(tx *sql.Tx) error {
return nil return nil
} }
// CreateChatsDown drops `chats` table
func CreateChatsDown(tx *sql.Tx) error { func CreateChatsDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `chats`;") _, err := tx.Exec("DROP TABLE `chats`;")
if err != nil { if err != nil {

View File

@ -4,10 +4,10 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// ChangeChatTypeColumnUp changes `chat_type` column of `chats` table
func ChangeChatTypeColumnUp(tx *sql.Tx) error { func ChangeChatTypeColumnUp(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `chats` MODIFY `chat_type` varchar(191);") _, err := tx.Exec("ALTER TABLE `chats` MODIFY `chat_type` varchar(191);")
if err != nil { if err != nil {
@ -17,6 +17,7 @@ func ChangeChatTypeColumnUp(tx *sql.Tx) error {
return nil return nil
} }
// ChangeChatTypeColumnDown changes `chat_type` column of `chats` table
func ChangeChatTypeColumnDown(tx *sql.Tx) error { func ChangeChatTypeColumnDown(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `chats` MODIFY `chat_type` bool;") _, err := tx.Exec("ALTER TABLE `chats` MODIFY `chat_type` bool;")
if err != nil { if err != nil {

View File

@ -4,10 +4,10 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// ChangeProfilePokememesColumnsUp prepares database for latest game update in mid-October
func ChangeProfilePokememesColumnsUp(tx *sql.Tx) error { func ChangeProfilePokememesColumnsUp(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `profiles_pokememes` ADD COLUMN `pokememe_attack` INT(11) NOT NULL DEFAULT 0 COMMENT 'Атака покемема' AFTER `pokememe_id`;;") _, err := tx.Exec("ALTER TABLE `profiles_pokememes` ADD COLUMN `pokememe_attack` INT(11) NOT NULL DEFAULT 0 COMMENT 'Атака покемема' AFTER `pokememe_id`;;")
if err != nil { if err != nil {
@ -22,6 +22,7 @@ func ChangeProfilePokememesColumnsUp(tx *sql.Tx) error {
return nil return nil
} }
// ChangeProfilePokememesColumnsDown restores mid-October behaviour
func ChangeProfilePokememesColumnsDown(tx *sql.Tx) error { func ChangeProfilePokememesColumnsDown(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `profiles_pokememes` ADD COLUMN `pokememe_lvl` INT(11) NOT NULL DEFAULT 0 COMMENT 'Уровень покемема' AFTER `pokememe_id`;;") _, err := tx.Exec("ALTER TABLE `profiles_pokememes` ADD COLUMN `pokememe_lvl` INT(11) NOT NULL DEFAULT 0 COMMENT 'Уровень покемема' AFTER `pokememe_id`;;")
if err != nil { if err != nil {

View File

@ -8,6 +8,7 @@ import (
"database/sql" "database/sql"
) )
// AddPokememesWealth prepares database for latest game update in mid-October
func AddPokememesWealthUp(tx *sql.Tx) error { func AddPokememesWealthUp(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `profiles` ADD COLUMN `pokememes_wealth` INT(11) NOT NULL DEFAULT 0 COMMENT 'Стоимость покемонов на руках' AFTER `wealth`;") _, err := tx.Exec("ALTER TABLE `profiles` ADD COLUMN `pokememes_wealth` INT(11) NOT NULL DEFAULT 0 COMMENT 'Стоимость покемонов на руках' AFTER `wealth`;")
if err != nil { if err != nil {
@ -17,6 +18,7 @@ func AddPokememesWealthUp(tx *sql.Tx) error {
return nil return nil
} }
// AddPokememesWealthDown restores mid-October behaviour
func AddPokememesWealthDown(tx *sql.Tx) error { func AddPokememesWealthDown(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `pokememes_wealth`;") _, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `pokememes_wealth`;")
if err != nil { if err != nil {

View File

@ -4,10 +4,10 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateBroadcastsUp creates `broadcasts` table
func CreateBroadcastsUp(tx *sql.Tx) error { func CreateBroadcastsUp(tx *sql.Tx) error {
request := "CREATE TABLE `broadcasts` (" request := "CREATE TABLE `broadcasts` ("
request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID сообщения'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID сообщения',"
@ -28,6 +28,7 @@ func CreateBroadcastsUp(tx *sql.Tx) error {
return nil return nil
} }
// CreateBroadcastsDown drops `broadcasts` table
func CreateBroadcastsDown(tx *sql.Tx) error { func CreateBroadcastsDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `broadcasts`;") _, err := tx.Exec("DROP TABLE `broadcasts`;")
if err != nil { if err != nil {

View File

@ -4,15 +4,12 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
"log"
) )
// First migration, added for testing purposes // HelloUp is the first migration, added for testing purposes
func HelloUp(tx *sql.Tx) error { func HelloUp(tx *sql.Tx) error {
log.Printf("Migration framework loaded. All systems are OK.") c.Log.Printf("Migration framework loaded. All systems are OK.")
return nil return nil
} }

View File

@ -4,10 +4,10 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateSquadsUp creates `squads` table
func CreateSquadsUp(tx *sql.Tx) error { func CreateSquadsUp(tx *sql.Tx) error {
request := "CREATE TABLE `squads` (" request := "CREATE TABLE `squads` ("
request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID отряда'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID отряда',"
@ -47,6 +47,7 @@ func CreateSquadsUp(tx *sql.Tx) error {
return nil return nil
} }
// CreateSquadsDown drops `squads` table
func CreateSquadsDown(tx *sql.Tx) error { func CreateSquadsDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `squads`;") _, err := tx.Exec("DROP TABLE `squads`;")
if err != nil { if err != nil {

View File

@ -0,0 +1,28 @@
// i2_bot Instinct PokememBro Bot
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
package migrations
import (
"database/sql"
)
// ChangeTelegramIDColumnUp changes `telegram_id` column of `chats` table
func ChangeTelegramIDColumnUp(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `chats` MODIFY `telegram_id` bigint;")
if err != nil {
return err
}
return nil
}
// ChangeTelegramIDColumnDown changes `telegram_id` column of `chats` table
func ChangeTelegramIDColumnDown(tx *sql.Tx) error {
_, err := tx.Exec("ALTER TABLE `chats` MODIFY `telegram_id` bigint;")
if err != nil {
return err
}
return nil
}

View File

@ -4,31 +4,32 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreatePlayersUp creates `players` table
func CreatePlayersUp(tx *sql.Tx) error { func CreatePlayersUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `players` (" request := "CREATE TABLE `players` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID игрока'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID игрока',"
create_request += "`telegram_id` int(11) NOT NULL COMMENT 'ID в телеграме'," request += "`telegram_id` int(11) NOT NULL COMMENT 'ID в телеграме',"
create_request += "`league_id` int(11) COMMENT 'ID лиги' DEFAULT 0," request += "`league_id` int(11) COMMENT 'ID лиги' DEFAULT 0,"
create_request += "`squad_id` int(11) COMMENT 'ID отряда' DEFAULT 0," request += "`squad_id` int(11) COMMENT 'ID отряда' DEFAULT 0,"
create_request += "`status` varchar(191) COMMENT 'Статус в лиге' DEFAULT 'common'," request += "`status` varchar(191) COMMENT 'Статус в лиге' DEFAULT 'common',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу',"
create_request += "`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Время последнего обновления'," request += "`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Время последнего обновления',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `players_created_at` (`created_at`)," request += "KEY `players_created_at` (`created_at`),"
create_request += "KEY `players_updated_at` (`updated_at`)" request += "KEY `players_updated_at` (`updated_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Зарегистрированные игроки';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Зарегистрированные игроки';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// CreatePlayersDown drops `players` table
func CreatePlayersDown(tx *sql.Tx) error { func CreatePlayersDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `players`;") _, err := tx.Exec("DROP TABLE `players`;")
if err != nil { if err != nil {

View File

@ -4,35 +4,36 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateProfilesUp creates `profiles` table
func CreateProfilesUp(tx *sql.Tx) error { func CreateProfilesUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `profiles` (" request := "CREATE TABLE `profiles` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID сохраненного профиля'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID сохраненного профиля',"
create_request += "`player_id` int(11) NOT NULL COMMENT 'ID игрока в системе'," request += "`player_id` int(11) NOT NULL COMMENT 'ID игрока в системе',"
create_request += "`nickname` varchar(191) NOT NULL COMMENT 'Ник игрока'," request += "`nickname` varchar(191) NOT NULL COMMENT 'Ник игрока',"
create_request += "`telegram_nickname` varchar(191) NOT NULL COMMENT 'Ник в Телеграме (@)'," request += "`telegram_nickname` varchar(191) NOT NULL COMMENT 'Ник в Телеграме (@)',"
create_request += "`level_id` int(11) NOT NULL COMMENT 'Уровень'," request += "`level_id` int(11) NOT NULL COMMENT 'Уровень',"
create_request += "`exp` int(11) NOT NULL COMMENT 'Опыт'," request += "`exp` int(11) NOT NULL COMMENT 'Опыт',"
create_request += "`egg_exp` int(11) NOT NULL COMMENT 'Опыт яйца'," request += "`egg_exp` int(11) NOT NULL COMMENT 'Опыт яйца',"
create_request += "`power` int(11) NOT NULL COMMENT 'Сила без оружия'," request += "`power` int(11) NOT NULL COMMENT 'Сила без оружия',"
create_request += "`weapon_id` int(11) NOT NULL COMMENT 'Тип оружия'," request += "`weapon_id` int(11) NOT NULL COMMENT 'Тип оружия',"
create_request += "`crystalls` int(11) NOT NULL COMMENT 'Кристаллы'," request += "`crystalls` int(11) NOT NULL COMMENT 'Кристаллы',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `profiles_created_at` (`created_at`)," request += "KEY `profiles_created_at` (`created_at`),"
create_request += "KEY `profiles_nickname` (`nickname`)" request += "KEY `profiles_nickname` (`nickname`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Профили зарегистрированных игроков';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Профили зарегистрированных игроков';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// CreateProfilesDown drops `profiles` table
func CreateProfilesDown(tx *sql.Tx) error { func CreateProfilesDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `profiles`;") _, err := tx.Exec("DROP TABLE `profiles`;")
if err != nil { if err != nil {

View File

@ -4,37 +4,38 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreatePokememesUp creates `pokememes` table
func CreatePokememesUp(tx *sql.Tx) error { func CreatePokememesUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `pokememes` (" request := "CREATE TABLE `pokememes` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID покемема'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID покемема',"
create_request += "`grade` int(11) NOT NULL COMMENT 'Поколение покемема'," request += "`grade` int(11) NOT NULL COMMENT 'Поколение покемема',"
create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя покемема'," request += "`name` varchar(191) NOT NULL COMMENT 'Имя покемема',"
create_request += "`description` TEXT NOT NULL COMMENT 'Описание покемема'," request += "`description` TEXT NOT NULL COMMENT 'Описание покемема',"
create_request += "`attack` int(11) NOT NULL COMMENT 'Атака'," request += "`attack` int(11) NOT NULL COMMENT 'Атака',"
create_request += "`hp` int(11) NOT NULL COMMENT 'Здоровье'," request += "`hp` int(11) NOT NULL COMMENT 'Здоровье',"
create_request += "`mp` int(11) NOT NULL COMMENT 'МР'," request += "`mp` int(11) NOT NULL COMMENT 'МР',"
create_request += "`defence` int(11) NOT NULL COMMENT 'Защита'," request += "`defence` int(11) NOT NULL COMMENT 'Защита',"
create_request += "`price` int(11) NOT NULL COMMENT 'Стоимость'," request += "`price` int(11) NOT NULL COMMENT 'Стоимость',"
create_request += "`purchaseable` bool NOT NULL DEFAULT true COMMENT 'Можно купить?'," request += "`purchaseable` bool NOT NULL DEFAULT true COMMENT 'Можно купить?',"
create_request += "`image_url` varchar(191) NOT NULL COMMENT 'Изображение покемема'," request += "`image_url` varchar(191) NOT NULL COMMENT 'Изображение покемема',"
create_request += "`player_id` int(11) NOT NULL COMMENT 'Кто добавил в базу'," request += "`player_id` int(11) NOT NULL COMMENT 'Кто добавил в базу',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `pokememes_created_at` (`created_at`)," request += "KEY `pokememes_created_at` (`created_at`),"
create_request += "KEY `pokememes_player_id` (`player_id`)" request += "KEY `pokememes_player_id` (`player_id`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Покемемы';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Покемемы';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// CreatePokememesDown drops `pokememes` table
func CreatePokememesDown(tx *sql.Tx) error { func CreatePokememesDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `pokememes`;") _, err := tx.Exec("DROP TABLE `pokememes`;")
if err != nil { if err != nil {

View File

@ -4,21 +4,21 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateLocationsUp creates `locations` table and fills it with data
func CreateLocationsUp(tx *sql.Tx) error { func CreateLocationsUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `locations` (" request := "CREATE TABLE `locations` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID локации'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID локации',"
create_request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ локации'," request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ локации',"
create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя локации'," request += "`name` varchar(191) NOT NULL COMMENT 'Имя локации',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлена в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлена в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `locations_created_at` (`created_at`)" request += "KEY `locations_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Локации';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Локации';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
@ -52,6 +52,7 @@ func CreateLocationsUp(tx *sql.Tx) error {
return nil return nil
} }
// CreateLocationsDown drops `locations` table
func CreateLocationsDown(tx *sql.Tx) error { func CreateLocationsDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `locations`;") _, err := tx.Exec("DROP TABLE `locations`;")
if err != nil { if err != nil {

View File

@ -4,22 +4,22 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateElementsUp creates `elements` table and fills it with data
func CreateElementsUp(tx *sql.Tx) error { func CreateElementsUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `elements` (" request := "CREATE TABLE `elements` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID элемента'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID элемента',"
create_request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ элемента'," request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ элемента',"
create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя элемента'," request += "`name` varchar(191) NOT NULL COMMENT 'Имя элемента',"
create_request += "`league_id` int(11) NOT NULL COMMENT 'ID родной лиги'," request += "`league_id` int(11) NOT NULL COMMENT 'ID родной лиги',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `elements_created_at` (`created_at`)" request += "KEY `elements_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Элементы';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Элементы';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
@ -77,6 +77,7 @@ func CreateElementsUp(tx *sql.Tx) error {
return nil return nil
} }
// CreateElementsDown drops `elements` table
func CreateElementsDown(tx *sql.Tx) error { func CreateElementsDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `elements`;") _, err := tx.Exec("DROP TABLE `elements`;")
if err != nil { if err != nil {

View File

@ -4,21 +4,21 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateLeaguesUp creates `leagues` table and fills it with data
func CreateLeaguesUp(tx *sql.Tx) error { func CreateLeaguesUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `leagues` (" request := "CREATE TABLE `leagues` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID лиги'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID лиги',"
create_request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ лиги'," request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ лиги',"
create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя лиги'," request += "`name` varchar(191) NOT NULL COMMENT 'Имя лиги',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлена в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлена в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `leagues_created_at` (`created_at`)" request += "KEY `leagues_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Лиги';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Лиги';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
@ -40,6 +40,7 @@ func CreateLeaguesUp(tx *sql.Tx) error {
return nil return nil
} }
// CreateLeaguesDown drops `leagues` table
func CreateLeaguesDown(tx *sql.Tx) error { func CreateLeaguesDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `leagues`;") _, err := tx.Exec("DROP TABLE `leagues`;")
if err != nil { if err != nil {

View File

@ -4,41 +4,42 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// CreateRelationsUp creates tables for pokememes-locations and pokememes-elements links
func CreateRelationsUp(tx *sql.Tx) error { func CreateRelationsUp(tx *sql.Tx) error {
create_request := "CREATE TABLE `pokememes_locations` (" request := "CREATE TABLE `pokememes_locations` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи',"
create_request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема',"
create_request += "`location_id` int(11) NOT NULL COMMENT 'ID локации'," request += "`location_id` int(11) NOT NULL COMMENT 'ID локации',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `pokememes_locations_created_at` (`created_at`)" request += "KEY `pokememes_locations_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Локации';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Локации';"
_, err := tx.Exec(create_request) _, err := tx.Exec(request)
if err != nil { if err != nil {
return err return err
} }
create_request = "CREATE TABLE `pokememes_elements` (" request = "CREATE TABLE `pokememes_elements` ("
create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи',"
create_request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема',"
create_request += "`element_id` int(11) NOT NULL COMMENT 'ID элемента'," request += "`element_id` int(11) NOT NULL COMMENT 'ID элемента',"
create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу',"
create_request += "PRIMARY KEY (`id`)," request += "PRIMARY KEY (`id`),"
create_request += "UNIQUE KEY `id` (`id`)," request += "UNIQUE KEY `id` (`id`),"
create_request += "KEY `pokememes_elements_created_at` (`created_at`)" request += "KEY `pokememes_elements_created_at` (`created_at`)"
create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Элементы';" request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Элементы';"
_, err2 := tx.Exec(create_request) _, err2 := tx.Exec(request)
if err2 != nil { if err2 != nil {
return err2 return err2
} }
return nil return nil
} }
// CreateRelationsDown drops pokememe-* relations tables
func CreateRelationsDown(tx *sql.Tx) error { func CreateRelationsDown(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE `pokememes_locations`;") _, err := tx.Exec("DROP TABLE `pokememes_locations`;")
if err != nil { if err != nil {

View File

@ -4,10 +4,10 @@
package migrations package migrations
import ( import (
// stdlib
"database/sql" "database/sql"
) )
// UpdateLocationsUp fixes some fuckup with locations' emoji
func UpdateLocationsUp(tx *sql.Tx) error { func UpdateLocationsUp(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE `locations` SET symbol='⛪' WHERE symbol=':church:';") _, err := tx.Exec("UPDATE `locations` SET symbol='⛪' WHERE symbol=':church:';")
if err != nil { if err != nil {
@ -25,6 +25,7 @@ func UpdateLocationsUp(tx *sql.Tx) error {
return nil return nil
} }
// UpdateLocationsDown returns location emoji fuckup for sanity purposes
func UpdateLocationsDown(tx *sql.Tx) error { func UpdateLocationsDown(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE `locations` SET symbol=':church:' WHERE symbol='⛪'';") _, err := tx.Exec("UPDATE `locations` SET symbol=':church:' WHERE symbol='⛪'';")
if err != nil { if err != nil {

View File

@ -4,15 +4,18 @@
package migrations package migrations
import ( import (
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations/migrationsinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/migrations/migrationsinterface"
) )
// Migrations handles all functions of migrations package
type Migrations struct{}
var ( var (
c *appcontext.Context c *appcontext.Context
) )
// New is an initialization function for migrations package
func New(ac *appcontext.Context) { func New(ac *appcontext.Context) {
c = ac c = ac
m := &Migrations{} m := &Migrations{}

View File

@ -4,16 +4,12 @@
package migrations package migrations
import ( import (
// stdlib
"log"
// 3rd-party
"github.com/pressly/goose" "github.com/pressly/goose"
) )
type Migrations struct{} // Init adds all migrations to applications
func (m *Migrations) Init() { func (m *Migrations) Init() {
log.Printf("Initializing migrations...") c.Log.Info("Initializing migrations...")
// All migrations are here // All migrations are here
goose.AddNamedMigration("1_hello.go", HelloUp, nil) goose.AddNamedMigration("1_hello.go", HelloUp, nil)
goose.AddNamedMigration("2_create_players.go", CreatePlayersUp, CreatePlayersDown) goose.AddNamedMigration("2_create_players.go", CreatePlayersUp, CreatePlayersDown)
@ -35,13 +31,15 @@ func (m *Migrations) Init() {
goose.AddNamedMigration("18_add_pokememes_wealth.go", AddPokememesWealthUp, AddPokememesWealthDown) goose.AddNamedMigration("18_add_pokememes_wealth.go", AddPokememesWealthUp, AddPokememesWealthDown)
goose.AddNamedMigration("19_create_broadcasts.go", CreateBroadcastsUp, CreateBroadcastsDown) goose.AddNamedMigration("19_create_broadcasts.go", CreateBroadcastsUp, CreateBroadcastsDown)
goose.AddNamedMigration("20_create_squads.go", CreateSquadsUp, CreateSquadsDown) goose.AddNamedMigration("20_create_squads.go", CreateSquadsUp, CreateSquadsDown)
goose.AddNamedMigration("21_change_telegram_id_column.go", ChangeTelegramIDColumnUp, ChangeTelegramIDColumnDown)
} }
// Migrate migrates database to current version
func (m *Migrations) Migrate() error { func (m *Migrations) Migrate() error {
log.Printf("Starting database migrations...") c.Log.Printf("Starting database migrations...")
err := goose.Up(c.Db.DB, ".") err := goose.Up(c.Db.DB, ".")
if err != nil { if err != nil {
log.Fatal(err) c.Log.Fatal(err)
return err return err
} }
@ -49,6 +47,7 @@ func (m *Migrations) Migrate() error {
return nil return nil
} }
// SetDialect sets dialect for migrations
func (m *Migrations) SetDialect(dialect string) error { func (m *Migrations) SetDialect(dialect string) error {
return goose.SetDialect(dialect) return goose.SetDialect(dialect)
} }

View File

@ -12,7 +12,7 @@ import (
// ParsersInterface implements Parsers for importing via appcontext. // ParsersInterface implements Parsers for importing via appcontext.
type ParsersInterface interface { type ParsersInterface interface {
ParsePokememe(text string, playerRaw dbmapping.Player) string ParsePokememe(text string, playerRaw *dbmapping.Player) string
ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Player) string ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
ReturnPoints(points int) string ReturnPoints(points int) string
} }

View File

@ -4,14 +4,11 @@
package parsers package parsers
import ( import (
// stdlib "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"log"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
// Internal functions // Internal functions
@ -35,7 +32,7 @@ func (p *Parsers) getPoints(pointsStr string) int {
// External functions // External functions
// ParsePokememe parses pokememe, forwarded from PokememeBroBot, to database // ParsePokememe parses pokememe, forwarded from PokememeBroBot, to database
func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string { func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string {
var defendablePokememe = false var defendablePokememe = false
pokememeStringsArray := strings.Split(text, "\n") pokememeStringsArray := strings.Split(text, "\n")
pokememeRunesArray := make([][]rune, 0) pokememeRunesArray := make([][]rune, 0)
@ -60,7 +57,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string
err := c.Db.Select(&elements, "SELECT * FROM elements WHERE symbol IN ('"+strings.Join(elementEmojis, "', '")+"')") err := c.Db.Select(&elements, "SELECT * FROM elements WHERE symbol IN ('"+strings.Join(elementEmojis, "', '")+"')")
if err != nil { if err != nil {
log.Printf(err.Error()) c.Log.Error(err.Error())
return "fail" return "fail"
} }
@ -68,8 +65,8 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string
hitPointsRx := regexp.MustCompile("(\\d|\\.)+(K|M)?") hitPointsRx := regexp.MustCompile("(\\d|\\.)+(K|M)?")
hitPoints := hitPointsRx.FindAllString(string(pokememeRunesArray[5]), -1) hitPoints := hitPointsRx.FindAllString(string(pokememeRunesArray[5]), -1)
if len(hitPoints) != 3 { if len(hitPoints) != 3 {
log.Printf("Can't parse hitpoints!") c.Log.Error("Can't parse hitpoints!")
log.Println(pokememeRunesArray[5]) c.Log.Debug(pokememeRunesArray[5])
return "fail" return "fail"
} }
@ -85,34 +82,34 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string
// Actions for high-grade pokememes // Actions for high-grade pokememes
defenceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[6]), -1) defenceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[6]), -1)
if len(defenceMatch) < 1 { if len(defenceMatch) < 1 {
log.Printf("Can't parse defence!") c.Log.Error("Can't parse defence!")
log.Println(pokememeRunesArray[6]) c.Log.Debug(pokememeRunesArray[6])
return "fail" return "fail"
} }
defence = defenceMatch[0] defence = defenceMatch[0]
priceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[7]), -1) priceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[7]), -1)
if len(priceMatch) < 1 { if len(priceMatch) < 1 {
log.Printf("Can't parse price!") c.Log.Error("Can't parse price!")
log.Println(pokememeRunesArray[7]) c.Log.Debug(pokememeRunesArray[7])
return "fail" return "fail"
} }
price = priceMatch[0] price = priceMatch[0]
locationsPrepare := strings.Split(string(pokememeRunesArray[8]), ": ") locationsPrepare := strings.Split(string(pokememeRunesArray[8]), ": ")
if len(locationsPrepare) < 2 { if len(locationsPrepare) < 2 {
log.Printf("Can't parse locations!") c.Log.Error("Can't parse locations!")
log.Println(pokememeRunesArray[8]) c.Log.Debug(pokememeRunesArray[8])
return "fail" return "fail"
} }
locationsNames := strings.Split(locationsPrepare[1], ", ") locationsNames := strings.Split(locationsPrepare[1], ", ")
if len(locationsNames) < 1 { if len(locationsNames) < 1 {
log.Printf("Can't parse locations!") c.Log.Error("Can't parse locations!")
log.Println(locationsPrepare) c.Log.Debug(locationsPrepare)
return "fail" return "fail"
} }
err2 := c.Db.Select(&locations, "SELECT * FROM locations WHERE name IN ('"+strings.Join(locationsNames, "', '")+"')") err2 := c.Db.Select(&locations, "SELECT * FROM locations WHERE name IN ('"+strings.Join(locationsNames, "', '")+"')")
if err2 != nil { if err2 != nil {
log.Printf(err2.Error()) c.Log.Error(err2.Error())
return "fail" return "fail"
} }
if strings.HasSuffix(string(pokememeRunesArray[9]), "Можно") { if strings.HasSuffix(string(pokememeRunesArray[9]), "Можно") {
@ -124,27 +121,27 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string
defence = hitPoints[0] defence = hitPoints[0]
priceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[6]), -1) priceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[6]), -1)
if len(priceMatch) < 1 { if len(priceMatch) < 1 {
log.Printf("Can't parse price!") c.Log.Error("Can't parse price!")
log.Println(pokememeRunesArray[6]) c.Log.Debug(pokememeRunesArray[6])
return "fail" return "fail"
} }
price = priceMatch[0] price = priceMatch[0]
locationsPrepare := strings.Split(string(pokememeRunesArray[7]), ": ") locationsPrepare := strings.Split(string(pokememeRunesArray[7]), ": ")
if len(locationsPrepare) < 2 { if len(locationsPrepare) < 2 {
log.Printf("Can't parse locations!") c.Log.Error("Can't parse locations!")
log.Println(pokememeRunesArray[7]) c.Log.Debug(pokememeRunesArray[7])
return "fail" return "fail"
} }
locationsNames := strings.Split(locationsPrepare[1], ", ") locationsNames := strings.Split(locationsPrepare[1], ", ")
if len(locationsNames) < 1 { if len(locationsNames) < 1 {
log.Printf("Can't parse locations!") c.Log.Error("Can't parse locations!")
log.Println(locationsPrepare) c.Log.Debug(locationsPrepare)
return "fail" return "fail"
} }
err2 := c.Db.Select(&locations, "SELECT * FROM locations WHERE name IN ('"+strings.Join(locationsNames, "', '")+"')") err2 := c.Db.Select(&locations, "SELECT * FROM locations WHERE name IN ('"+strings.Join(locationsNames, "', '")+"')")
if err2 != nil { if err2 != nil {
log.Printf(err2.Error()) c.Log.Error(err2.Error())
return "fail" return "fail"
} }
if strings.HasSuffix(string(pokememeRunesArray[8]), "Можно") { if strings.HasSuffix(string(pokememeRunesArray[8]), "Можно") {
@ -156,37 +153,37 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string
grade := string(pokememeRunesArray[0][0]) grade := string(pokememeRunesArray[0][0])
name := string(pokememeRunesArray[0][3:]) name := string(pokememeRunesArray[0][3:])
description := string(pokememeRunesArray[1]) description := string(pokememeRunesArray[1])
log.Printf("Pokememe grade: " + grade) c.Log.Debug("Pokememe grade: " + grade)
log.Printf("Pokememe name: " + name) c.Log.Debug("Pokememe name: " + name)
log.Printf("Pokememe description: " + description) c.Log.Debug("Pokememe description: " + description)
log.Printf("Elements:") c.Log.Debug("Elements:")
for i := range elements { for i := range elements {
log.Printf(elements[i].Symbol + " " + elements[i].Name) c.Log.Debug(elements[i].Symbol + " " + elements[i].Name)
} }
log.Printf("Attack: " + hitPoints[0]) c.Log.Debug("Attack: " + hitPoints[0])
log.Printf("HP: " + hitPoints[1]) c.Log.Debug("HP: " + hitPoints[1])
log.Printf("MP: " + hitPoints[2]) c.Log.Debug("MP: " + hitPoints[2])
log.Printf("Defence: " + defence) c.Log.Debug("Defence: " + defence)
log.Printf("Price: " + price) c.Log.Debug("Price: " + price)
log.Printf("Locations:") c.Log.Debug("Locations:")
for i := range locations { for i := range locations {
log.Printf(locations[i].Symbol + " " + locations[i].Name) c.Log.Debug(locations[i].Symbol + " " + locations[i].Name)
} }
if purchaseable { if purchaseable {
log.Printf("Purchaseable") c.Log.Debug("Purchaseable")
} else { } else {
log.Printf("Non-purchaseable") c.Log.Debug("Non-purchaseable")
} }
log.Printf("Image: " + image) c.Log.Debug("Image: " + image)
// Building pokememe // Building pokememe
pokememe := dbmapping.Pokememe{} pokememe := dbmapping.Pokememe{}
// Checking if pokememe exists in database // Checking if pokememe exists in database
err3 := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE grade='"+grade+"' AND name='"+name+"';")) err3 := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE grade='"+grade+"' AND name='"+name+"';"))
if err3 != nil { if err3 != nil {
log.Printf("Adding new pokememe...") c.Log.Debug("Adding new pokememe...")
} else { } else {
log.Printf("This pokememe already exist. Return specific error.") c.Log.Info("This pokememe already exist. Return specific error.")
return "dup" return "dup"
} }
@ -216,14 +213,14 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string
_, err4 := c.Db.NamedExec("INSERT INTO pokememes VALUES(NULL, :grade, :name, :description, :attack, :hp, :mp, :defence, :price, :purchaseable, :image_url, :player_id, :created_at)", &pokememe) _, err4 := c.Db.NamedExec("INSERT INTO pokememes VALUES(NULL, :grade, :name, :description, :attack, :hp, :mp, :defence, :price, :purchaseable, :image_url, :player_id, :created_at)", &pokememe)
if err4 != nil { if err4 != nil {
log.Printf(err4.Error()) c.Log.Error(err4.Error())
return "fail" return "fail"
} }
// Getting new pokememe // Getting new pokememe
err5 := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE grade='"+grade+"' AND name='"+name+"';")) err5 := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE grade='"+grade+"' AND name='"+name+"';"))
if err5 != nil { if err5 != nil {
log.Printf("Pokememe isn't added!") c.Log.Error("Pokememe isn't added!")
return "fail" return "fail"
} }
for i := range elements { for i := range elements {
@ -234,7 +231,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string
_, err6 := c.Db.NamedExec("INSERT INTO pokememes_elements VALUES(NULL, :pokememe_id, :element_id, :created_at)", &link) _, err6 := c.Db.NamedExec("INSERT INTO pokememes_elements VALUES(NULL, :pokememe_id, :element_id, :created_at)", &link)
if err6 != nil { if err6 != nil {
log.Printf(err6.Error()) c.Log.Error(err6.Error())
return "fail" return "fail"
} }
} }
@ -246,7 +243,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string
_, err7 := c.Db.NamedExec("INSERT INTO pokememes_locations VALUES(NULL, :pokememe_id, :location_id, :created_at)", &link) _, err7 := c.Db.NamedExec("INSERT INTO pokememes_locations VALUES(NULL, :pokememe_id, :location_id, :created_at)", &link)
if err7 != nil { if err7 != nil {
log.Printf(err7.Error()) c.Log.Error(err7.Error())
return "fail" return "fail"
} }
} }

View File

@ -4,16 +4,12 @@
package parsers package parsers
import ( import (
// stdlib "github.com/go-telegram-bot-api/telegram-bot-api"
"log" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
// Internal functions // Internal functions
@ -22,7 +18,7 @@ func (p *Parsers) fillProfilePokememe(profileID int, meme string, attack string,
spkRaw := dbmapping.Pokememe{} spkRaw := dbmapping.Pokememe{}
err := c.Db.Get(&spkRaw, c.Db.Rebind("SELECT * FROM pokememes WHERE name='"+meme+"';")) err := c.Db.Get(&spkRaw, c.Db.Rebind("SELECT * FROM pokememes WHERE name='"+meme+"';"))
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err.Error())
} else { } else {
attackInt := p.getPoints(attack) attackInt := p.getPoints(attack)
ppk := dbmapping.ProfilePokememe{} ppk := dbmapping.ProfilePokememe{}
@ -33,7 +29,7 @@ func (p *Parsers) fillProfilePokememe(profileID int, meme string, attack string,
ppk.CreatedAt = time.Now().UTC() ppk.CreatedAt = time.Now().UTC()
_, err2 := c.Db.NamedExec("INSERT INTO `profiles_pokememes` VALUES(NULL, :profile_id, :pokememe_id, :pokememe_attack, :pokememe_rarity, :created_at)", &ppk) _, err2 := c.Db.NamedExec("INSERT INTO `profiles_pokememes` VALUES(NULL, :profile_id, :pokememe_id, :pokememe_attack, :pokememe_rarity, :created_at)", &ppk)
if err2 != nil { if err2 != nil {
log.Println(err2) c.Log.Error(err2.Error())
} }
} }
} }
@ -41,9 +37,9 @@ func (p *Parsers) fillProfilePokememe(profileID int, meme string, attack string,
// External functions // External functions
// ParseProfile parses user profile, forwarded from PokememBroBot, to database // ParseProfile parses user profile, forwarded from PokememBroBot, to database
func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Player) string { func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
text := update.Message.Text text := update.Message.Text
log.Println(text) c.Log.Info(text)
profileStringsArray := strings.Split(text, "\n") profileStringsArray := strings.Split(text, "\n")
profileRunesArray := make([][]rune, 0) profileRunesArray := make([][]rune, 0)
@ -81,7 +77,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
if strings.HasPrefix(currentString, "🈸") || strings.HasPrefix(currentString, "🈳 ") || strings.HasPrefix(currentString, "🈵") { if strings.HasPrefix(currentString, "🈸") || strings.HasPrefix(currentString, "🈳 ") || strings.HasPrefix(currentString, "🈵") {
err1 := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE symbol='"+string(currentRunes[0])+"'")) err1 := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE symbol='"+string(currentRunes[0])+"'"))
if err1 != nil { if err1 != nil {
log.Println(err1) c.Log.Error(err1.Error())
return "fail" return "fail"
} }
for j := range currentRunes { for j := range currentRunes {
@ -94,7 +90,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
levelRx := regexp.MustCompile("\\d+") levelRx := regexp.MustCompile("\\d+")
levelArray := levelRx.FindAllString(currentString, -1) levelArray := levelRx.FindAllString(currentString, -1)
if len(levelArray) < 1 { if len(levelArray) < 1 {
log.Println("Level string broken") c.Log.Error("Level string broken")
return "fail" return "fail"
} }
level = levelArray[0] level = levelArray[0]
@ -105,7 +101,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
expRx := regexp.MustCompile("\\d+") expRx := regexp.MustCompile("\\d+")
expArray := expRx.FindAllString(currentString, -1) expArray := expRx.FindAllString(currentString, -1)
if len(expArray) < 4 { if len(expArray) < 4 {
log.Println("Exp string broken") c.Log.Error("Exp string broken")
return "fail" return "fail"
} }
exp = expArray[0] exp = expArray[0]
@ -118,7 +114,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
pkbRx := regexp.MustCompile("\\d+") pkbRx := regexp.MustCompile("\\d+")
pkbArray := pkbRx.FindAllString(currentString, -1) pkbArray := pkbRx.FindAllString(currentString, -1)
if len(pkbArray) < 2 { if len(pkbArray) < 2 {
log.Println("Pokeballs string broken") c.Log.Error("Pokeballs string broken")
return "fail" return "fail"
} }
pokeballs = pkbArray[1] pokeballs = pkbArray[1]
@ -129,7 +125,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
wealthRx := regexp.MustCompile("(\\d|\\.|K|M)+") wealthRx := regexp.MustCompile("(\\d|\\.|K|M)+")
wealthArray := wealthRx.FindAllString(currentString, -1) wealthArray := wealthRx.FindAllString(currentString, -1)
if len(wealthArray) < 2 { if len(wealthArray) < 2 {
log.Println("Wealth string broken") c.Log.Error("Wealth string broken")
return "fail" return "fail"
} }
wealth = wealthArray[0] wealth = wealthArray[0]
@ -149,7 +145,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
pkmnumRx := regexp.MustCompile(`(\d+)(\d|K|M|)`) pkmnumRx := regexp.MustCompile(`(\d+)(\d|K|M|)`)
pkNumArray := pkmnumRx.FindAllString(currentString, -1) pkNumArray := pkmnumRx.FindAllString(currentString, -1)
if len(pkNumArray) < 3 { if len(pkNumArray) < 3 {
log.Println("Pokememes count broken") c.Log.Error("Pokememes count broken")
return "fail" return "fail"
} }
pokememesCount, _ := strconv.Atoi(pkNumArray[0]) pokememesCount, _ := strconv.Atoi(pkNumArray[0])
@ -172,37 +168,37 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
} }
} }
log.Printf("Telegram nickname: " + telegramNickname) c.Log.Debug("Telegram nickname: " + telegramNickname)
log.Printf("Nickname: " + nickname) c.Log.Debug("Nickname: " + nickname)
log.Printf("League: " + league.Name) c.Log.Debug("League: " + league.Name)
log.Printf("Level: " + level) c.Log.Debug("Level: " + level)
log.Println(levelInt) c.Log.Debugln(levelInt)
log.Printf("Exp: " + exp) c.Log.Debug("Exp: " + exp)
log.Println(expInt) c.Log.Debugln(expInt)
log.Printf("Egg exp: " + eggexp) c.Log.Debug("Egg exp: " + eggexp)
log.Println(eggexpInt) c.Log.Debugln(eggexpInt)
log.Printf("Pokeballs: " + pokeballs) c.Log.Debug("Pokeballs: " + pokeballs)
log.Println(pokeballsInt) c.Log.Debugln(pokeballsInt)
log.Printf("Wealth: " + wealth) c.Log.Debug("Wealth: " + wealth)
log.Println(wealthInt) c.Log.Debugln(wealthInt)
log.Printf("Crystalls: " + crystalls) c.Log.Debug("Crystalls: " + crystalls)
log.Println(crystallsInt) c.Log.Debugln(crystallsInt)
log.Printf("Weapon: " + weapon) c.Log.Debug("Weapon: " + weapon)
if len(pokememes) > 0 { if len(pokememes) > 0 {
log.Printf("Hand cost: " + pokememesWealth) c.Log.Debug("Hand cost: " + pokememesWealth)
log.Println(pokememesWealthInt) c.Log.Debugln(pokememesWealthInt)
for meme, attack := range pokememes { for meme, attack := range pokememes {
log.Printf(meme + ": " + attack) c.Log.Debug(meme + ": " + attack)
} }
} else { } else {
log.Printf("Hand is empty.") c.Log.Debug("Hand is empty.")
} }
// Information is gathered, let's create profile in database! // Information is gathered, let's create profile in database!
weaponRaw := dbmapping.Weapon{} weaponRaw := dbmapping.Weapon{}
err2 := c.Db.Get(&weaponRaw, c.Db.Rebind("SELECT * FROM weapons WHERE name='"+weapon+"'")) err2 := c.Db.Get(&weaponRaw, c.Db.Rebind("SELECT * FROM weapons WHERE name='"+weapon+"'"))
if err2 != nil { if err2 != nil {
log.Println(err2) c.Log.Error(err2.Error())
} }
if playerRaw.LeagueID == 0 { if playerRaw.LeagueID == 0 {
@ -213,7 +209,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
} }
_, err4 := c.Db.NamedExec("UPDATE `players` SET league_id=:league_id, status=:status WHERE id=:id", &playerRaw) _, err4 := c.Db.NamedExec("UPDATE `players` SET league_id=:league_id, status=:status WHERE id=:id", &playerRaw)
if err4 != nil { if err4 != nil {
log.Println(err4) c.Log.Error(err4.Error())
return "fail" return "fail"
} }
} else if playerRaw.LeagueID != league.ID { } else if playerRaw.LeagueID != league.ID {
@ -223,12 +219,12 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
playerRaw.CreatedAt = time.Now().UTC() playerRaw.CreatedAt = time.Now().UTC()
_, err5 := c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :status, :created_at, :updated_at)", &playerRaw) _, err5 := c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :status, :created_at, :updated_at)", &playerRaw)
if err5 != nil { if err5 != nil {
log.Println(err5) c.Log.Error(err5.Error())
return "fail" return "fail"
} }
err6 := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id='"+strconv.Itoa(playerRaw.TelegramID)+"' AND league_id='"+strconv.Itoa(league.ID)+"';")) err6 := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id='"+strconv.Itoa(playerRaw.TelegramID)+"' AND league_id='"+strconv.Itoa(league.ID)+"';"))
if err6 != nil { if err6 != nil {
log.Println(err6) c.Log.Error(err6.Error())
return "fail" return "fail"
} }
} }
@ -250,21 +246,21 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe
_, err3 := c.Db.NamedExec("INSERT INTO `profiles` VALUES(NULL, :player_id, :nickname, :telegram_nickname, :level_id, :pokeballs, :wealth, :pokememes_wealth, :exp, :egg_exp, :power, :weapon_id, :crystalls, :created_at)", &profileRaw) _, err3 := c.Db.NamedExec("INSERT INTO `profiles` VALUES(NULL, :player_id, :nickname, :telegram_nickname, :level_id, :pokeballs, :wealth, :pokememes_wealth, :exp, :egg_exp, :power, :weapon_id, :crystalls, :created_at)", &profileRaw)
if err3 != nil { if err3 != nil {
log.Println(err3) c.Log.Error(err3.Error())
return "fail" return "fail"
} }
err8 := c.Db.Get(&profileRaw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? AND created_at=?"), profileRaw.PlayerID, profileRaw.CreatedAt) err8 := c.Db.Get(&profileRaw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? AND created_at=?"), profileRaw.PlayerID, profileRaw.CreatedAt)
if err8 != nil { if err8 != nil {
log.Println(err8) c.Log.Error(err8.Error())
log.Printf("Profile isn't added!") c.Log.Error("Profile isn't added!")
return "fail" return "fail"
} }
playerRaw.UpdatedAt = time.Now().UTC() playerRaw.UpdatedAt = time.Now().UTC()
_, err7 := c.Db.NamedExec("UPDATE `players` SET updated_at=:updated_at WHERE id=:id", &playerRaw) _, err7 := c.Db.NamedExec("UPDATE `players` SET updated_at=:updated_at WHERE id=:id", &playerRaw)
if err7 != nil { if err7 != nil {
log.Println(err7) c.Log.Error(err7.Error())
return "fail" return "fail"
} }

28
lib/pinner/exported.go Normal file
View File

@ -0,0 +1,28 @@
// i2_bot Instinct PokememBro Bot
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
package pinner
import (
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner/pinnerinterface"
)
var (
c *appcontext.Context
)
// Pinner is a function-handling struct for Pinner
type Pinner struct{}
// New is a appcontext initialization function
func New(ac *appcontext.Context) {
c = ac
p := &Pinner{}
c.RegisterPinnerInterface(pinnerinterface.PinnerInterface(p))
}
// Init is an initialization function for pinner
func (p *Pinner) Init() {
c.Log.Info("Initializing Pinner...")
}

71
lib/pinner/pinner.go Normal file
View File

@ -0,0 +1,71 @@
// i2_bot Instinct PokememBro Bot
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
package pinner
import (
"github.com/go-telegram-bot-api/telegram-bot-api"
)
// PinMessageToAllChats pins message to all groups where bot exist
func (p *Pinner) PinMessageToAllChats(update *tgbotapi.Update) string {
messageToPin := update.Message.CommandArguments()
if messageToPin == "" {
return "fail"
}
groupChats, ok := c.Getters.GetAllGroupChats()
if !ok {
return "fail"
}
for i := range groupChats {
if groupChats[i].ChatType == "supergroup" {
message := messageToPin + "\n\n"
message += "© " + update.Message.From.FirstName + " " + update.Message.From.LastName
message += " (@" + update.Message.From.UserName + ")"
msg := tgbotapi.NewMessage(groupChats[i].TelegramID, message)
msg.ParseMode = "Markdown"
pinnableMessage, err := c.Bot.Send(msg)
if err != nil {
c.Log.Error(err.Error())
message := "*Ваше сообщение не отправлено.*\n\n"
message += "Обычно это связано с тем, что нарушена разметка Markdown. "
message += "К примеру, если вы хотели использовать нижнее\\_подчёркивание, то печатать его надо так — \\\\_. То же самое касается всех управляющих разметкой символов в Markdown в случае, если вы их хотите использовать как текст, а не как управляющий символ Markdown."
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
msg.ParseMode = "Markdown"
c.Bot.Send(msg)
return "fail"
}
pinChatMessageConfig := tgbotapi.PinChatMessageConfig{
ChatID: pinnableMessage.Chat.ID,
MessageID: pinnableMessage.MessageID,
DisableNotification: true,
}
_, err = c.Bot.PinChatMessage(pinChatMessageConfig)
if err != nil {
c.Log.Error(err.Error())
}
}
}
message := "*Ваше сообщение отправлено и запинено во все чаты, где сидит бот.*\n\n"
message += "Текст отправленного сообщения:\n\n"
message += messageToPin
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
msg.ParseMode = "Markdown"
c.Bot.Send(msg)
return "ok"
}

View File

@ -0,0 +1,14 @@
// i2_bot Instinct PokememBro Bot
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
package pinnerinterface
import (
"github.com/go-telegram-bot-api/telegram-bot-api"
)
// PinnerInterface implements Pinner for importing via appcontex
type PinnerInterface interface {
Init()
PinMessageToAllChats(update *tgbotapi.Update) string
}

View File

@ -4,25 +4,24 @@
package router package router
import ( import (
// stdlib
"log"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
) )
var ( var (
c *appcontext.Context c *appcontext.Context
r *Router
) )
// Router is a function-handling struct for router
type Router struct{}
// New is an initialization function for appcontext // New is an initialization function for appcontext
func New(ac *appcontext.Context) { func New(ac *appcontext.Context) {
c = ac c = ac
rh := RouterHandler{} r := &Router{}
c.RegisterRouterInterface(rh) c.RegisterRouterInterface(r)
} }
// Init is an initialization function for package router // Init is an initialization function for package router
func (r *Router) Init() { func (r *Router) Init() {
log.Printf("Initialized request router...") c.Log.Info("Initialized request router...")
} }

View File

@ -4,15 +4,12 @@
package router package router
import ( import (
// stdlib
"regexp"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"regexp"
) )
func (r *Router) routeGroupRequest(update tgbotapi.Update, playerRaw dbmapping.Player, chatRaw dbmapping.Chat) string { func (r *Router) routeGroupRequest(update *tgbotapi.Update, playerRaw *dbmapping.Player, chatRaw *dbmapping.Chat) string {
text := update.Message.Text text := update.Message.Text
// Regular expressions // Regular expressions
var durakMsg = regexp.MustCompile("(Д|д)(У|у)(Р|р)(А|а|Е|е|О|о)") var durakMsg = regexp.MustCompile("(Д|д)(У|у)(Р|р)(А|а|Е|е|О|о)")
@ -22,8 +19,11 @@ func (r *Router) routeGroupRequest(update tgbotapi.Update, playerRaw dbmapping.P
var piMsg = regexp.MustCompile("(П|п)(И|и)(З|з)(Д|д)") var piMsg = regexp.MustCompile("(П|п)(И|и)(З|з)(Д|д)")
// Welcomes // Welcomes
if update.Message.NewChatMember != nil { if update.Message.NewChatMembers != nil {
return c.Welcomer.WelcomeMessage(update) newUsers := *update.Message.NewChatMembers
if len(newUsers) > 0 {
return c.Welcomer.WelcomeMessage(update)
}
} }
// New chat names // New chat names
if update.Message.NewChatTitle != "" { if update.Message.NewChatTitle != "" {

View File

@ -1,22 +0,0 @@
// i2_bot Instinct PokememBro Bot
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
package router
import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api"
)
// RouterHandler is a handler for router package
type RouterHandler struct{}
// Init is an initialization function of router
func (rh RouterHandler) Init() {
r.Init()
}
// RouteRequest decides, what to do with user input
func (rh RouterHandler) RouteRequest(update tgbotapi.Update) string {
return r.RouteRequest(update)
}

View File

@ -4,21 +4,13 @@
package router package router
import ( import (
// stdlib
"log"
"regexp"
"strings"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"regexp"
) )
func (r *Router) routePrivateRequest(update tgbotapi.Update, playerRaw dbmapping.Player, chatRaw dbmapping.Chat) string { func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmapping.Player, chatRaw *dbmapping.Chat) string {
text := update.Message.Text text := update.Message.Text
// Forwards
var pokememeMsg = regexp.MustCompile("(Уровень)(.+)(Опыт)(.+)\n(Элементы:)(.+)\n(.+)(💙MP)")
var profileMsg = regexp.MustCompile(`(Онлайн: )(\d+)\n(Турнир через)(.+)\n\n((.*)\n|(.*)\n(.*)\n)(Элементы)(.+)\n(.*)\n\n(.+)(Уровень)(.+)\n`)
// Commands with regexps // Commands with regexps
var pokedexMsg = regexp.MustCompile("/pokede(x|ks)\\d?\\z") var pokedexMsg = regexp.MustCompile("/pokede(x|ks)\\d?\\z")
@ -26,45 +18,11 @@ func (r *Router) routePrivateRequest(update tgbotapi.Update, playerRaw dbmapping
if update.Message.ForwardFrom != nil { if update.Message.ForwardFrom != nil {
if update.Message.ForwardFrom.ID != 360402625 { if update.Message.ForwardFrom.ID != 360402625 {
log.Printf("Forward from another user or bot. Ignoring") c.Log.Info("Forward from another user or bot. Ignoring")
} else { } else {
log.Printf("Forward from PokememBro bot! Processing...") c.Log.Info("Forward from PokememBro bot! Processing...")
if playerRaw.ID != 0 { if playerRaw.ID != 0 {
switch { c.Forwarder.ProcessForward(update, playerRaw)
case pokememeMsg.MatchString(text):
log.Printf("Pokememe posted!")
if playerRaw.LeagueID == 1 {
status := c.Parsers.ParsePokememe(text, playerRaw)
switch status {
case "ok":
c.Talkers.PokememeAddSuccessMessage(update)
return "ok"
case "dup":
c.Talkers.PokememeAddDuplicateMessage(update)
return "ok"
case "fail":
c.Talkers.PokememeAddFailureMessage(update)
return "fail"
}
} else {
c.Talkers.AnyMessageUnauthorized(update)
return "fail"
}
case profileMsg.MatchString(text):
log.Printf("Profile posted!")
status := c.Parsers.ParseProfile(update, playerRaw)
switch status {
case "ok":
c.Talkers.ProfileAddSuccessMessage(update)
return "ok"
case "fail":
c.Talkers.ProfileAddFailureMessage(update)
return "fail"
}
default:
log.Printf(text)
return "fail"
}
} else { } else {
c.Talkers.AnyMessageUnauthorized(update) c.Talkers.AnyMessageUnauthorized(update)
return "fail" return "fail"
@ -82,28 +40,11 @@ func (r *Router) routePrivateRequest(update tgbotapi.Update, playerRaw dbmapping
c.Talkers.HelloMessageUnauthorized(update) c.Talkers.HelloMessageUnauthorized(update)
return "ok" return "ok"
case update.Message.Command() == "help": case update.Message.Command() == "help":
c.Talkers.HelpMessage(update, &playerRaw) c.Talkers.HelpMessage(update, playerRaw)
return "ok" return "ok"
// Pokememes info // Pokememes info
case pokedexMsg.MatchString(text): case pokedexMsg.MatchString(text):
if strings.HasSuffix(text, "1") { c.Talkers.PokememesList(update)
c.Talkers.PokememesList(update, 1)
return "ok"
} else if strings.HasSuffix(text, "2") {
c.Talkers.PokememesList(update, 2)
return "ok"
} else if strings.HasSuffix(text, "3") {
c.Talkers.PokememesList(update, 3)
return "ok"
} else if strings.HasSuffix(text, "4") {
c.Talkers.PokememesList(update, 4)
return "ok"
} else if strings.HasSuffix(text, "5") {
c.Talkers.PokememesList(update, 5)
return "ok"
}
c.Talkers.PokememesList(update, 1)
return "ok" return "ok"
case pokememeInfoMsg.MatchString(text): case pokememeInfoMsg.MatchString(text):
c.Talkers.PokememeInfo(update, playerRaw) c.Talkers.PokememeInfo(update, playerRaw)
@ -120,27 +61,34 @@ func (r *Router) routePrivateRequest(update tgbotapi.Update, playerRaw dbmapping
c.Talkers.BestPokememesList(update, playerRaw) c.Talkers.BestPokememesList(update, playerRaw)
return "ok" return "ok"
case update.Message.Command() == "send_all": case update.Message.Command() == "send_all":
if c.Getters.PlayerBetterThan(&playerRaw, "admin") { if c.Getters.PlayerBetterThan(playerRaw, "admin") {
c.Talkers.AdminBroadcastMessageCompose(update, &playerRaw) c.Talkers.AdminBroadcastMessageCompose(update, playerRaw)
return "ok" return "ok"
} }
c.Talkers.AnyMessageUnauthorized(update) c.Talkers.AnyMessageUnauthorized(update)
return "fail" return "fail"
case update.Message.Command() == "send_confirm": case update.Message.Command() == "send_confirm":
if c.Getters.PlayerBetterThan(&playerRaw, "admin") { if c.Getters.PlayerBetterThan(playerRaw, "admin") {
c.Talkers.AdminBroadcastMessageSend(update, &playerRaw) c.Talkers.AdminBroadcastMessageSend(update, playerRaw)
return "ok" return "ok"
} }
c.Talkers.AnyMessageUnauthorized(update) c.Talkers.AnyMessageUnauthorized(update)
return "fail" return "fail"
case update.Message.Command() == "group_chats": case update.Message.Command() == "group_chats":
if c.Getters.PlayerBetterThan(&playerRaw, "admin") { if c.Getters.PlayerBetterThan(playerRaw, "admin") {
c.Talkers.GroupsList(update) c.Talkers.GroupsList(update)
return "ok" return "ok"
} }
c.Talkers.AnyMessageUnauthorized(update)
return "fail"
case update.Message.Command() == "pin":
if c.Getters.PlayerBetterThan(playerRaw, "admin") {
return c.Pinner.PinMessageToAllChats(update)
}
c.Talkers.AnyMessageUnauthorized(update) c.Talkers.AnyMessageUnauthorized(update)
return "fail" return "fail"
} }

View File

@ -4,35 +4,29 @@
package router package router
import ( import (
// stdlib
"log"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
) )
// Router is a function-handling struct for router
type Router struct{}
// RouteRequest decides, what to do with user input // RouteRequest decides, what to do with user input
func (r *Router) RouteRequest(update tgbotapi.Update) string { func (r *Router) RouteRequest(update *tgbotapi.Update) string {
playerRaw, ok := c.Getters.GetOrCreatePlayer(update.Message.From.ID) playerRaw, ok := c.Getters.GetOrCreatePlayer(update.Message.From.ID)
if !ok { if !ok {
// Silently fail // Silently fail
return "fail" return "fail"
} }
chatRaw, ok := c.Getters.GetOrCreateChat(&update) chatRaw, ok := c.Getters.GetOrCreateChat(update)
if !ok { if !ok {
return "fail" return "fail"
} }
log.Printf("Received message from chat ") c.Log.Debug("Received message from chat ")
log.Println(chatRaw.TelegramID) c.Log.Debugln(chatRaw.TelegramID)
if update.Message.Chat.IsGroup() || update.Message.Chat.IsSuperGroup() { if update.Message.Chat.IsGroup() || update.Message.Chat.IsSuperGroup() {
return r.routeGroupRequest(update, playerRaw, chatRaw) return r.routeGroupRequest(update, &playerRaw, &chatRaw)
} else if update.Message.Chat.IsPrivate() { } else if update.Message.Chat.IsPrivate() {
return r.routePrivateRequest(update, playerRaw, chatRaw) return r.routePrivateRequest(update, &playerRaw, &chatRaw)
} }
return "ok" return "ok"

View File

@ -4,12 +4,11 @@
package routerinterface package routerinterface
import ( import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
) )
// RouterInterface implements Router for importing via appcontext. // RouterInterface implements Router for importing via appcontext.
type RouterInterface interface { type RouterInterface interface {
Init() Init()
RouteRequest(update tgbotapi.Update) string RouteRequest(update *tgbotapi.Update) string
} }

View File

@ -4,17 +4,14 @@
package talkers package talkers
import ( import (
// stdlib
"strconv" "strconv"
"strings" "strings"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
// AdminBroadcastMessageCompose saves message for future broadcast // AdminBroadcastMessageCompose saves message for future broadcast
func (t *Talkers) AdminBroadcastMessageCompose(update tgbotapi.Update, playerRaw *dbmapping.Player) string { func (t *Talkers) AdminBroadcastMessageCompose(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
broadcastingMessageBody := strings.Replace(update.Message.Text, "/send_all ", "", 1) broadcastingMessageBody := strings.Replace(update.Message.Text, "/send_all ", "", 1)
messageRaw, ok := c.Getters.CreateBroadcastMessage(playerRaw, broadcastingMessageBody, "all") messageRaw, ok := c.Getters.CreateBroadcastMessage(playerRaw, broadcastingMessageBody, "all")
@ -50,7 +47,7 @@ func (t *Talkers) AdminBroadcastMessageCompose(update tgbotapi.Update, playerRaw
} }
// AdminBroadcastMessageSend sends saved message to all private chats // AdminBroadcastMessageSend sends saved message to all private chats
func (t *Talkers) AdminBroadcastMessageSend(update tgbotapi.Update, playerRaw *dbmapping.Player) string { func (t *Talkers) AdminBroadcastMessageSend(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
messageNum := strings.Replace(update.Message.Text, "/send_confirm ", "", 1) messageNum := strings.Replace(update.Message.Text, "/send_confirm ", "", 1)
messageNumInt, _ := strconv.Atoi(messageNum) messageNumInt, _ := strconv.Atoi(messageNum)
messageRaw, ok := c.Getters.GetBroadcastMessageByID(messageNumInt) messageRaw, ok := c.Getters.GetBroadcastMessageByID(messageNumInt)

View File

@ -4,14 +4,12 @@
package talkers package talkers
import ( import (
// stdlib
"strconv"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
"strconv"
) )
// GroupsList lists all known pokememes // GroupsList lists all chats where bot exist
func (t *Talkers) GroupsList(update tgbotapi.Update) string { func (t *Talkers) GroupsList(update *tgbotapi.Update) string {
groupChats, ok := c.Getters.GetAllGroupChatsWithSquads() groupChats, ok := c.Getters.GetAllGroupChatsWithSquads()
if !ok { if !ok {
return "fail" return "fail"

View File

@ -4,18 +4,13 @@
package talkers package talkers
import ( import (
// stdlib "github.com/go-telegram-bot-api/telegram-bot-api"
"log"
"math/rand" "math/rand"
"time" "time"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api"
) )
// DurakMessage is an easter egg // DurakMessage is an easter egg
func (t *Talkers) DurakMessage(update tgbotapi.Update) { func (t *Talkers) DurakMessage(update *tgbotapi.Update) {
log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
reactions := make([]string, 0) reactions := make([]string, 0)
reactions = append(reactions, "Сам такой!", reactions = append(reactions, "Сам такой!",
"А ты типа нет?", "А ты типа нет?",
@ -31,9 +26,7 @@ func (t *Talkers) DurakMessage(update tgbotapi.Update) {
} }
// MatMessage is an easter rgg // MatMessage is an easter rgg
func (t *Talkers) MatMessage(update tgbotapi.Update) { func (t *Talkers) MatMessage(update *tgbotapi.Update) {
log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
reactions := make([]string, 0) reactions := make([]string, 0)
reactions = append(reactions, "Фу, как некультурно!", reactions = append(reactions, "Фу, как некультурно!",
"Иди рот с мылом помой", "Иди рот с мылом помой",

View File

@ -4,12 +4,11 @@
package talkers package talkers
import ( import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
) )
// AnyMessageUnauthorized throws when user can't do something // AnyMessageUnauthorized throws when user can't do something
func (t *Talkers) AnyMessageUnauthorized(update tgbotapi.Update) { func (t *Talkers) AnyMessageUnauthorized(update *tgbotapi.Update) {
message := "Извини, действие для тебя недоступно. Возможно, у меня нет твоего профиля или же твои права недостаточны для совершения данного действия\n\n" message := "Извини, действие для тебя недоступно. Возможно, у меня нет твоего профиля или же твои права недостаточны для совершения данного действия\n\n"
message += "Если тебе кажется, что это ошибка, пиши @fat0troll.\n" message += "Если тебе кажется, что это ошибка, пиши @fat0troll.\n"
@ -20,7 +19,7 @@ func (t *Talkers) AnyMessageUnauthorized(update tgbotapi.Update) {
} }
// GetterError throws when bot can't get something // GetterError throws when bot can't get something
func (t *Talkers) GetterError(update tgbotapi.Update) { func (t *Talkers) GetterError(update *tgbotapi.Update) {
message := "Ой, внутренняя ошибка в боте :(\n\n" message := "Ой, внутренняя ошибка в боте :(\n\n"
message += "Напиши @fat0troll, приложив форвардом последние сообщения до этого.\n" message += "Напиши @fat0troll, приложив форвардом последние сообщения до этого.\n"

View File

@ -4,9 +4,6 @@
package talkers package talkers
import ( import (
// stdlib
"log"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
"lab.pztrn.name/fat0troll/i2_bot/lib/talkers/talkersinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/talkers/talkersinterface"
) )
@ -27,5 +24,5 @@ func New(ac *appcontext.Context) {
// Init is an initialization function for talkers // Init is an initialization function for talkers
func (t *Talkers) Init() { func (t *Talkers) Init() {
log.Printf("Initializing responders...") c.Log.Info("Initializing responders...")
} }

View File

@ -4,14 +4,12 @@
package talkers package talkers
import ( import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
// HelloMessageUnauthorized tell new user what to do. // HelloMessageUnauthorized tell new user what to do.
func (t *Talkers) HelloMessageUnauthorized(update tgbotapi.Update) { func (t *Talkers) HelloMessageUnauthorized(update *tgbotapi.Update) {
message := "*Бот Инстинкта приветствует тебя!*\n\n" message := "*Бот Инстинкта приветствует тебя!*\n\n"
message += "Для начала работы с ботом, пожалуйста, перешли от бота игры @PokememBroBot профиль героя.\n" message += "Для начала работы с ботом, пожалуйста, перешли от бота игры @PokememBroBot профиль героя.\n"
message += "Все дальнейшие действия с ботом возможны лишь при наличии профиля игрока." message += "Все дальнейшие действия с ботом возможны лишь при наличии профиля игрока."
@ -23,7 +21,7 @@ func (t *Talkers) HelloMessageUnauthorized(update tgbotapi.Update) {
} }
// HelloMessageAuthorized greets existing user // HelloMessageAuthorized greets existing user
func (t *Talkers) HelloMessageAuthorized(update tgbotapi.Update, playerRaw dbmapping.Player) { func (t *Talkers) HelloMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player) {
message := "*Бот Инстинкта приветствует тебя. Снова.*\n\n" message := "*Бот Инстинкта приветствует тебя. Снова.*\n\n"
message += "Привет, " + update.Message.From.FirstName + " " + update.Message.From.LastName + "!\n" message += "Привет, " + update.Message.From.FirstName + " " + update.Message.From.LastName + "!\n"
message += "Последнее обновление информации о тебе: " + playerRaw.UpdatedAt.Format("02.01.2006 15:04:05 -0700") message += "Последнее обновление информации о тебе: " + playerRaw.UpdatedAt.Format("02.01.2006 15:04:05 -0700")

View File

@ -4,15 +4,13 @@
package talkers package talkers
import ( import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/config" "lab.pztrn.name/fat0troll/i2_bot/lib/config"
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
// HelpMessage gives user all available commands // HelpMessage gives user all available commands
func (t *Talkers) HelpMessage(update tgbotapi.Update, playerRaw *dbmapping.Player) { func (t *Talkers) HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) {
message := "*Бот Инстинкта Enchanched.*\n\n" message := "*Бот Инстинкта Enchanched.*\n\n"
message += "Текущая версия: *" + config.VERSION + "*\n\n" message += "Текущая версия: *" + config.VERSION + "*\n\n"
message += "Список команд\n\n" message += "Список команд\n\n"
@ -22,6 +20,7 @@ func (t *Talkers) HelpMessage(update tgbotapi.Update, playerRaw *dbmapping.Playe
if c.Getters.PlayerBetterThan(playerRaw, "admin") { if c.Getters.PlayerBetterThan(playerRaw, "admin") {
message += "+ /send\\_all _текст_ — отправить сообщение всем пользователям бота\n" message += "+ /send\\_all _текст_ — отправить сообщение всем пользователям бота\n"
message += "+ /group\\_chats — получить список групп, в которых работает бот.\n" message += "+ /group\\_chats — получить список групп, в которых работает бот.\n"
message += "+ /pin _текст_ — отправить сообщение во все группы, где находится бот. Сообщение будет автоматически запинено.\n"
} }
message += "+ /help выводит данное сообщение\n" message += "+ /help выводит данное сообщение\n"

View File

@ -4,18 +4,15 @@
package talkers package talkers
import ( import (
// stdlib "github.com/go-telegram-bot-api/telegram-bot-api"
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"strconv" "strconv"
"strings" "strings"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
// Internal functions // Internal functions
func (t *Talkers) pokememesListing(update tgbotapi.Update, page int, pokememesArray []dbmapping.PokememeFull) { func (t *Talkers) pokememesListing(update *tgbotapi.Update, page int, pokememesArray []dbmapping.PokememeFull) {
message := "*Известные боту покемемы*\n" message := "*Известные боту покемемы*\n"
message += "Список отсортирован по грейду и алфавиту.\n" message += "Список отсортирован по грейду и алфавиту.\n"
message += "Покедекс: " + strconv.Itoa(len(pokememesArray)) + " / 219\n" message += "Покедекс: " + strconv.Itoa(len(pokememesArray)) + " / 219\n"
@ -62,7 +59,13 @@ func (t *Talkers) pokememesListing(update tgbotapi.Update, page int, pokememesAr
// External functions // External functions
// PokememesList lists all known pokememes // PokememesList lists all known pokememes
func (t *Talkers) PokememesList(update tgbotapi.Update, page int) { func (t *Talkers) PokememesList(update *tgbotapi.Update) {
pageNumber := strings.Replace(update.Message.Text, "/pokedex", "", 1)
pageNumber = strings.Replace(pageNumber, "/pokedeks", "", 1)
page, _ := strconv.Atoi(pageNumber)
if page == 0 {
page = 1
}
pokememesArray, ok := c.Getters.GetPokememes() pokememesArray, ok := c.Getters.GetPokememes()
if !ok { if !ok {
t.GetterError(update) t.GetterError(update)
@ -72,7 +75,7 @@ func (t *Talkers) PokememesList(update tgbotapi.Update, page int) {
} }
// PokememeInfo shows information about single pokememe based on internal ID // PokememeInfo shows information about single pokememe based on internal ID
func (t *Talkers) PokememeInfo(update tgbotapi.Update, playerRaw dbmapping.Player) string { func (t *Talkers) PokememeInfo(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
pokememeNumber := strings.Replace(update.Message.Text, "/pk", "", 1) pokememeNumber := strings.Replace(update.Message.Text, "/pk", "", 1)
var calculatePossibilites = true var calculatePossibilites = true
profileRaw, ok := c.Getters.GetProfile(playerRaw.ID) profileRaw, ok := c.Getters.GetProfile(playerRaw.ID)

View File

@ -4,12 +4,11 @@
package talkers package talkers
import ( import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
) )
// PokememeAddSuccessMessage shows pokememe adding success message // PokememeAddSuccessMessage shows pokememe adding success message
func (t *Talkers) PokememeAddSuccessMessage(update tgbotapi.Update) { func (t *Talkers) PokememeAddSuccessMessage(update *tgbotapi.Update) {
message := "*Покемем успешно добавлен.*\n\n" message := "*Покемем успешно добавлен.*\n\n"
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks" message += "Посмотреть всех известных боту покемемов можно командой /pokedeks"
@ -20,7 +19,7 @@ func (t *Talkers) PokememeAddSuccessMessage(update tgbotapi.Update) {
} }
// PokememeAddDuplicateMessage shows pokememe add duplication message // PokememeAddDuplicateMessage shows pokememe add duplication message
func (t *Talkers) PokememeAddDuplicateMessage(update tgbotapi.Update) { func (t *Talkers) PokememeAddDuplicateMessage(update *tgbotapi.Update) {
message := "*Мы уже знаем об этом покемеме*\n\n" message := "*Мы уже знаем об этом покемеме*\n\n"
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks\n\n" message += "Посмотреть всех известных боту покемемов можно командой /pokedeks\n\n"
message += "Если у покемема изменились описание или характеристики, напиши @fat0troll для обновления базы." message += "Если у покемема изменились описание или характеристики, напиши @fat0troll для обновления базы."
@ -32,7 +31,7 @@ func (t *Talkers) PokememeAddDuplicateMessage(update tgbotapi.Update) {
} }
// PokememeAddFailureMessage shows pokememe add error message // PokememeAddFailureMessage shows pokememe add error message
func (t *Talkers) PokememeAddFailureMessage(update tgbotapi.Update) { func (t *Talkers) PokememeAddFailureMessage(update *tgbotapi.Update) {
message := "*Неудачно получилось :(*\n\n" message := "*Неудачно получилось :(*\n\n"
message += "Случилась жуткая ошибка, и мы не смогли записать покемема в базу. Напиши @fat0troll, он разберется.\n\n" message += "Случилась жуткая ошибка, и мы не смогли записать покемема в базу. Напиши @fat0troll, он разберется.\n\n"
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks" message += "Посмотреть всех известных боту покемемов можно командой /pokedeks"

View File

@ -4,17 +4,13 @@
package talkers package talkers
import ( import (
// stdlib
"log"
"strconv"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"strconv"
) )
// ProfileMessage shows current player's profile // ProfileMessage shows current player's profile
func (t *Talkers) ProfileMessage(update tgbotapi.Update, playerRaw dbmapping.Player) string { func (t *Talkers) ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
profileRaw, ok := c.Getters.GetProfile(playerRaw.ID) profileRaw, ok := c.Getters.GetProfile(playerRaw.ID)
if !ok { if !ok {
c.Talkers.AnyMessageUnauthorized(update) c.Talkers.AnyMessageUnauthorized(update)
@ -23,29 +19,29 @@ func (t *Talkers) ProfileMessage(update tgbotapi.Update, playerRaw dbmapping.Pla
league := dbmapping.League{} league := dbmapping.League{}
err := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE id=?"), playerRaw.LeagueID) err := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE id=?"), playerRaw.LeagueID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
} }
level := dbmapping.Level{} level := dbmapping.Level{}
err = c.Db.Get(&level, c.Db.Rebind("SELECT * FROM levels WHERE id=?"), profileRaw.LevelID) err = c.Db.Get(&level, c.Db.Rebind("SELECT * FROM levels WHERE id=?"), profileRaw.LevelID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
} }
weapon := dbmapping.Weapon{} weapon := dbmapping.Weapon{}
if profileRaw.WeaponID != 0 { if profileRaw.WeaponID != 0 {
err = c.Db.Get(&weapon, c.Db.Rebind("SELECT * FROM weapons WHERE id=?"), profileRaw.WeaponID) err = c.Db.Get(&weapon, c.Db.Rebind("SELECT * FROM weapons WHERE id=?"), profileRaw.WeaponID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
} }
} }
profilePokememes := []dbmapping.ProfilePokememe{} profilePokememes := []dbmapping.ProfilePokememe{}
err = c.Db.Select(&profilePokememes, c.Db.Rebind("SELECT * FROM profiles_pokememes WHERE profile_id=?"), profileRaw.ID) err = c.Db.Select(&profilePokememes, c.Db.Rebind("SELECT * FROM profiles_pokememes WHERE profile_id=?"), profileRaw.ID)
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
} }
pokememes := []dbmapping.Pokememe{} pokememes := []dbmapping.Pokememe{}
err = c.Db.Select(&pokememes, c.Db.Rebind("SELECT * FROM pokememes")) err = c.Db.Select(&pokememes, c.Db.Rebind("SELECT * FROM pokememes"))
if err != nil { if err != nil {
log.Println(err) c.Log.Error(err)
} }
attackPokememes := 0 attackPokememes := 0

View File

@ -4,12 +4,11 @@
package talkers package talkers
import ( import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
) )
// ProfileAddSuccessMessage shows profile addition success message // ProfileAddSuccessMessage shows profile addition success message
func (t *Talkers) ProfileAddSuccessMessage(update tgbotapi.Update) { func (t *Talkers) ProfileAddSuccessMessage(update *tgbotapi.Update) {
message := "*Профиль успешно обновлен.*\n\n" message := "*Профиль успешно обновлен.*\n\n"
message += "Функциональность бота держится на актуальности профилей. Обновляйся почаще, и да пребудет с тобой Рандом!\n" message += "Функциональность бота держится на актуальности профилей. Обновляйся почаще, и да пребудет с тобой Рандом!\n"
message += "Сохраненный профиль ты можешь просмотреть командой /me.\n\n" message += "Сохраненный профиль ты можешь просмотреть командой /me.\n\n"
@ -22,7 +21,7 @@ func (t *Talkers) ProfileAddSuccessMessage(update tgbotapi.Update) {
} }
// ProfileAddFailureMessage shows profile addition failure message // ProfileAddFailureMessage shows profile addition failure message
func (t *Talkers) ProfileAddFailureMessage(update tgbotapi.Update) { func (t *Talkers) ProfileAddFailureMessage(update *tgbotapi.Update) {
message := "*Неудачно получилось :(*\n\n" message := "*Неудачно получилось :(*\n\n"
message += "Случилась жуткая ошибка, и мы не смогли записать профиль в базу. Напиши @fat0troll, он разберется." message += "Случилась жуткая ошибка, и мы не смогли записать профиль в базу. Напиши @fat0troll, он разберется."

View File

@ -4,20 +4,16 @@
package talkers package talkers
import ( import (
// stdlib
"log"
"strconv"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
"strconv"
) )
// BestPokememesList shows list for catching based on player league and grade // BestPokememesList shows list for catching based on player league and grade
func (t *Talkers) BestPokememesList(update tgbotapi.Update, playerRaw dbmapping.Player) string { func (t *Talkers) BestPokememesList(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
pokememes, ok := c.Getters.GetBestPokememes(playerRaw.ID) pokememes, ok := c.Getters.GetBestPokememes(playerRaw.ID)
if !ok { if !ok {
log.Printf("Cannot get pokememes from getter!") c.Log.Error("Cannot get pokememes from getter!")
return "fail" return "fail"
} }

View File

@ -4,37 +4,35 @@
package talkersinterface package talkersinterface
import ( import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
) )
// TalkersInterface implements Talkers for importing via appcontex // TalkersInterface implements Talkers for importing via appcontex
type TalkersInterface interface { type TalkersInterface interface {
Init() Init()
HelloMessageUnauthorized(update tgbotapi.Update) HelloMessageUnauthorized(update *tgbotapi.Update)
HelloMessageAuthorized(update tgbotapi.Update, playerRaw dbmapping.Player) HelloMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player)
HelpMessage(update tgbotapi.Update, playerRaw *dbmapping.Player) HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player)
PokememesList(update tgbotapi.Update, page int) PokememesList(update *tgbotapi.Update)
PokememeInfo(update tgbotapi.Update, playerRaw dbmapping.Player) string PokememeInfo(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
BestPokememesList(update tgbotapi.Update, playerRaw dbmapping.Player) string BestPokememesList(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
PokememeAddSuccessMessage(update tgbotapi.Update) PokememeAddSuccessMessage(update *tgbotapi.Update)
PokememeAddDuplicateMessage(update tgbotapi.Update) PokememeAddDuplicateMessage(update *tgbotapi.Update)
PokememeAddFailureMessage(update tgbotapi.Update) PokememeAddFailureMessage(update *tgbotapi.Update)
ProfileAddSuccessMessage(update tgbotapi.Update) ProfileAddSuccessMessage(update *tgbotapi.Update)
ProfileAddFailureMessage(update tgbotapi.Update) ProfileAddFailureMessage(update *tgbotapi.Update)
ProfileMessage(update tgbotapi.Update, playerRaw dbmapping.Player) string ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
AnyMessageUnauthorized(update tgbotapi.Update) AnyMessageUnauthorized(update *tgbotapi.Update)
GetterError(update tgbotapi.Update) GetterError(update *tgbotapi.Update)
AdminBroadcastMessageCompose(update tgbotapi.Update, playerRaw *dbmapping.Player) string AdminBroadcastMessageCompose(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
AdminBroadcastMessageSend(update tgbotapi.Update, playerRaw *dbmapping.Player) string AdminBroadcastMessageSend(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
GroupsList(update tgbotapi.Update) string GroupsList(update *tgbotapi.Update) string
DurakMessage(update tgbotapi.Update) DurakMessage(update *tgbotapi.Update)
MatMessage(update tgbotapi.Update) MatMessage(update *tgbotapi.Update)
} }

View File

@ -4,9 +4,6 @@
package welcomer package welcomer
import ( import (
// stdlib
"log"
// local
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
"lab.pztrn.name/fat0troll/i2_bot/lib/welcomer/welcomerinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/welcomer/welcomerinterface"
) )
@ -15,7 +12,7 @@ var (
c *appcontext.Context c *appcontext.Context
) )
// Welcomer is a function-handling struct for talkers // Welcomer is a function-handling struct for welcomer
type Welcomer struct{} type Welcomer struct{}
// New is a appcontext initialization function // New is a appcontext initialization function
@ -25,7 +22,7 @@ func New(ac *appcontext.Context) {
c.RegisterWelcomerInterface(welcomerinterface.WelcomerInterface(m)) c.RegisterWelcomerInterface(welcomerinterface.WelcomerInterface(m))
} }
// Init is an initialization function for talkers // Init is an initialization function for welcomer
func (w *Welcomer) Init() { func (w *Welcomer) Init() {
log.Printf("Initializing Welcomer...") c.Log.Info("Initializing Welcomer...")
} }

View File

@ -4,21 +4,19 @@
package welcomer package welcomer
import ( import (
// stdlib
"strconv"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
"strconv"
) )
func (w *Welcomer) alertUserWithoutProfile(update tgbotapi.Update) string { func (w *Welcomer) alertUserWithoutProfile(update *tgbotapi.Update, newUser *tgbotapi.User) string {
alertGroupID, _ := strconv.ParseInt(c.Cfg.Notifications.GroupID, 10, 64) alertGroupID, _ := strconv.ParseInt(c.Cfg.Notifications.GroupID, 10, 64)
chat, ok := c.Getters.GetOrCreateChat(&update) chat, ok := c.Getters.GetOrCreateChat(update)
if !ok { if !ok {
return "fail" return "fail"
} }
message := "*Новый вход пользователя без профиля в чат с ботом!*\n" message := "*Новый вход пользователя без профиля в чат с ботом!*\n"
message += "В чат _" + chat.Name + "_ вошёл некто @" + update.Message.NewChatMember.UserName message += "В чат _" + chat.Name + "_ вошёл некто @" + newUser.UserName
message += ". Он получил уведомление о том, что ему нужно создать профиль в боте." message += ". Он получил уведомление о том, что ему нужно создать профиль в боте."
msg := tgbotapi.NewMessage(alertGroupID, message) msg := tgbotapi.NewMessage(alertGroupID, message)
@ -29,15 +27,15 @@ func (w *Welcomer) alertUserWithoutProfile(update tgbotapi.Update) string {
return "ok" return "ok"
} }
func (w *Welcomer) alertSpyUser(update tgbotapi.Update) string { func (w *Welcomer) alertSpyUser(update *tgbotapi.Update, newUser *tgbotapi.User) string {
alertGroupID, _ := strconv.ParseInt(c.Cfg.Notifications.GroupID, 10, 64) alertGroupID, _ := strconv.ParseInt(c.Cfg.Notifications.GroupID, 10, 64)
chat, ok := c.Getters.GetOrCreateChat(&update) chat, ok := c.Getters.GetOrCreateChat(update)
if !ok { if !ok {
return "fail" return "fail"
} }
message := "*Шпион в деле!*\n" message := "*Шпион в деле!*\n"
message += "В чат _" + chat.Name + "_ вошёл некто @" + update.Message.NewChatMember.UserName message += "В чат _" + chat.Name + "_ вошёл некто @" + newUser.UserName
message += ". У него профиль другой лиги. Ждём обновлений." message += ". У него профиль другой лиги. Ждём обновлений."
msg := tgbotapi.NewMessage(alertGroupID, message) msg := tgbotapi.NewMessage(alertGroupID, message)

View File

@ -4,14 +4,12 @@
package welcomer package welcomer
import ( import (
// stdlib
"time"
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
"time"
) )
func (w *Welcomer) groupWelcomeUser(update tgbotapi.Update) string { func (w *Welcomer) groupWelcomeUser(update *tgbotapi.Update, newUser *tgbotapi.User) string {
playerRaw, ok := c.Getters.GetOrCreatePlayer(update.Message.NewChatMember.ID) playerRaw, ok := c.Getters.GetOrCreatePlayer(newUser.ID)
if !ok { if !ok {
return "fail" return "fail"
} }
@ -19,7 +17,7 @@ func (w *Welcomer) groupWelcomeUser(update tgbotapi.Update) string {
profileRaw, profileExist := c.Getters.GetProfile(playerRaw.ID) profileRaw, profileExist := c.Getters.GetProfile(playerRaw.ID)
message := "*Бот Инстинкта приветствует тебя, *@" message := "*Бот Инстинкта приветствует тебя, *@"
message += update.Message.NewChatMember.UserName message += newUser.UserName
message += "*!*\n\n" message += "*!*\n\n"
if profileExist { if profileExist {
@ -29,13 +27,13 @@ func (w *Welcomer) groupWelcomeUser(update tgbotapi.Update) string {
} else { } else {
message += "Обнови профиль, отправив его боту в личку. Так надо." message += "Обнови профиль, отправив его боту в личку. Так надо."
w.alertSpyUser(update) w.alertSpyUser(update, newUser)
} }
} else { } else {
// newbie // newbie
message += "Добавь себе бота @i2\\_bot в список контактов и скинь в него игровой профиль. Это важно для успешной игры!\n" message += "Добавь себе бота @i2\\_bot в список контактов и скинь в него игровой профиль. Это важно для успешной игры!\n"
w.alertUserWithoutProfile(update) w.alertUserWithoutProfile(update, newUser)
} }
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
@ -46,7 +44,7 @@ func (w *Welcomer) groupWelcomeUser(update tgbotapi.Update) string {
return "ok" return "ok"
} }
func (w *Welcomer) groupStartMessage(update tgbotapi.Update) string { func (w *Welcomer) groupStartMessage(update *tgbotapi.Update) string {
message := "*Бот Инстинкта приветствует этот чатик!*\n\n" message := "*Бот Инстинкта приветствует этот чатик!*\n\n"
message += "На слубже здравого смысла с " + time.Now().Format("02.01.2006 15:04:05") + "." message += "На слубже здравого смысла с " + time.Now().Format("02.01.2006 15:04:05") + "."
@ -59,10 +57,16 @@ func (w *Welcomer) groupStartMessage(update tgbotapi.Update) string {
} }
// WelcomeMessage welcomes new user on group or bot itself // WelcomeMessage welcomes new user on group or bot itself
func (w *Welcomer) WelcomeMessage(update tgbotapi.Update) string { func (w *Welcomer) WelcomeMessage(update *tgbotapi.Update) string {
if (update.Message.NewChatMember.UserName == "i2_bot") || (update.Message.NewChatMember.UserName == "i2_dev_bot") { newUsers := *update.Message.NewChatMembers
return w.groupStartMessage(update) for i := range newUsers {
if (newUsers[i].UserName == "i2_bot") || (newUsers[i].UserName == "i2_dev_bot") {
w.groupStartMessage(update)
}
newUser := newUsers[i]
w.groupWelcomeUser(update, &newUser)
} }
return w.groupWelcomeUser(update) return "ok"
} }

View File

@ -4,12 +4,11 @@
package welcomerinterface package welcomerinterface
import ( import (
// 3rd party
"github.com/go-telegram-bot-api/telegram-bot-api" "github.com/go-telegram-bot-api/telegram-bot-api"
) )
// WelcomerInterface implements Welcomer for importing via appcontex // WelcomerInterface implements Welcomer for importing via appcontex
type WelcomerInterface interface { type WelcomerInterface interface {
Init() Init()
WelcomeMessage(update tgbotapi.Update) string WelcomeMessage(update *tgbotapi.Update) string
} }