diff --git a/Gopkg.lock b/Gopkg.lock index c394ca0..da88526 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -10,8 +10,8 @@ [[projects]] name = "github.com/go-telegram-bot-api/telegram-bot-api" packages = ["."] - revision = "0a57807db79efce7f6719fbb2c0e0f83fda79aec" - version = "v4.6" + revision = "2022d04b94f50056a09962b1ac81cdd821d20a55" + version = "v4.6.1" [[projects]] branch = "master" @@ -25,21 +25,45 @@ revision = "056a4d47dcc4d67fa3947a4f13945a5c690e568b" version = "v2.1.0" +[[projects]] + name = "github.com/sirupsen/logrus" + packages = ["."] + revision = "f006c2ac4710855cf0f916dd6b77acf6b048dc6e" + version = "v1.0.3" + [[projects]] name = "github.com/technoweenie/multipartstreamer" packages = ["."] revision = "a90a01d73ae432e2611d178c18367fbaa13e0154" 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]] branch = "v2" name = "gopkg.in/yaml.v2" packages = ["."] revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f" +[[projects]] + branch = "master" + name = "lab.pztrn.name/golibs/mogrus" + packages = ["."] + revision = "a888e29e1fff06c2e6ebc607055a02de22a6ddae" + [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "5020a2712e7a565f5f7ed84b6ea5fe7a369303903dc3dfeb0de03777806f585e" + inputs-digest = "3e9df6d446d8789d138790622cf19935d4331f9903af640d13654c07b9f433a5" solver-name = "gps-cdcl" solver-version = 1 diff --git a/cmd/i2_bot/i2_bot.go b/cmd/i2_bot/i2_bot.go index 328997d..8ed4871 100644 --- a/cmd/i2_bot/i2_bot.go +++ b/cmd/i2_bot/i2_bot.go @@ -4,18 +4,17 @@ package main import ( - // stdlib - "time" - // 3rd-party "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/forwarder" "lab.pztrn.name/fat0troll/i2_bot/lib/getters" "lab.pztrn.name/fat0troll/i2_bot/lib/migrations" "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/talkers" "lab.pztrn.name/fat0troll/i2_bot/lib/welcomer" + "time" ) var ( @@ -28,11 +27,17 @@ func main() { router.New(c) migrations.New(c) c.RunDatabaseMigrations() + forwarder.New(c) parsers.New(c) + pinner.New(c) talkers.New(c) getters.New(c) welcomer.New(c) + c.Log.Info("=======================") + c.Log.Info("= i2_bot initialized. =") + c.Log.Info("=======================") + u := tgbotapi.NewUpdate(0) u.Timeout = 60 @@ -46,6 +51,6 @@ func main() { continue } - c.Router.RouteRequest(update) + c.Router.RouteRequest(&update) } } diff --git a/config.yml.example b/config.yml.example index 147fd4e..fc32e77 100644 --- a/config.yml.example +++ b/config.yml.example @@ -8,3 +8,5 @@ database_connection: database: "i2_bot" notifications: group_id: "group_id" +logs: + log_path: "./i2_bot.log" diff --git a/lib/appcontext/appcontext.go b/lib/appcontext/appcontext.go index 438fa51..bc22f18 100644 --- a/lib/appcontext/appcontext.go +++ b/lib/appcontext/appcontext.go @@ -4,25 +4,28 @@ package appcontext import ( - // 3rd-party "github.com/go-telegram-bot-api/telegram-bot-api" "github.com/jmoiron/sqlx" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/config" "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/migrations/migrationsinterface" "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/talkers/talkersinterface" "lab.pztrn.name/fat0troll/i2_bot/lib/welcomer/welcomerinterface" + "lab.pztrn.name/golibs/mogrus" + "os" ) // Context is an application context struct type Context struct { Cfg *config.Config + Log *mogrus.LoggerHandler Bot *tgbotapi.BotAPI + Forwarder forwarderinterface.ForwarderInterface Migrations migrationsinterface.MigrationsInterface Router routerinterface.RouterInterface Parsers parsersinterface.ParsersInterface @@ -30,14 +33,30 @@ type Context struct { Talkers talkersinterface.TalkersInterface Getters gettersinterface.GettersInterface Welcomer welcomerinterface.WelcomerInterface + Pinner pinnerinterface.PinnerInterface } // Init is a initialization function for context func (c *Context) Init() { c.Cfg = config.New() 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 @@ -60,16 +79,31 @@ func (c *Context) RegisterParsersInterface(pi parsersinterface.ParsersInterface) // RegisterTalkersInterface registering talkers interface in application func (c *Context) RegisterTalkersInterface(ti talkersinterface.TalkersInterface) { c.Talkers = ti + c.Talkers.Init() } // RegisterGettersInterface registering getters interface in application func (c *Context) RegisterGettersInterface(gi gettersinterface.GettersInterface) { c.Getters = gi + c.Getters.Init() } // RegisterWelcomerInterface registering welcomer interface in application func (c *Context) RegisterWelcomerInterface(wi welcomerinterface.WelcomerInterface) { 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 diff --git a/lib/config/config.go b/lib/config/config.go index ae33124..76e14d1 100644 --- a/lib/config/config.go +++ b/lib/config/config.go @@ -4,15 +4,13 @@ package config import ( - // stdlib + "gopkg.in/yaml.v2" "io/ioutil" "log" "path/filepath" - // 3rd-party - "gopkg.in/yaml.v2" ) -const VERSION = "0.297" +const VERSION = "0.35" // DatabaseConnection handles database connection settings in config.yaml type DatabaseConnection struct { @@ -33,11 +31,17 @@ type NotificationsConnection struct { 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 type Config struct { Telegram TelegramConnection `yaml:"telegram_connection"` Database DatabaseConnection `yaml:"database_connection"` Notifications NotificationsConnection `yaml:"notifications"` + Logs LoggingConfig `yaml:"logs"` } // Init is a configuration initializer diff --git a/lib/connections/connections.go b/lib/connections/connections.go index bd0b5fd..cac8919 100644 --- a/lib/connections/connections.go +++ b/lib/connections/connections.go @@ -4,37 +4,34 @@ package connections import ( - // stdlib - "log" - // 3rd-party _ "github.com/go-sql-driver/mysql" - "github.com/jmoiron/sqlx" "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/golibs/mogrus" ) // 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) if err != nil { - log.Panic(err) + lg.Fatal(err.Error()) } bot.Debug = true - log.Printf("Bot version: " + config.VERSION) - log.Printf("Authorized on account %s", bot.Self.UserName) + lg.Info("Bot version: " + config.VERSION) + lg.Info("Authorized on account @", bot.Self.UserName) return bot } // 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") if err != nil { - log.Fatal(err) + lg.Fatal(err) } - log.Printf("Database connection established!") + lg.Info("Database connection established!") return database } diff --git a/lib/dbmapping/broadcast.go b/lib/dbmapping/broadcast.go index 5d912e1..87ffa29 100644 --- a/lib/dbmapping/broadcast.go +++ b/lib/dbmapping/broadcast.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/chats.go b/lib/dbmapping/chats.go index 62c3381..03443be 100644 --- a/lib/dbmapping/chats.go +++ b/lib/dbmapping/chats.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/elements.go b/lib/dbmapping/elements.go index 6159364..e7f46a7 100644 --- a/lib/dbmapping/elements.go +++ b/lib/dbmapping/elements.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/leagues.go b/lib/dbmapping/leagues.go index e9c8da9..8d338f6 100644 --- a/lib/dbmapping/leagues.go +++ b/lib/dbmapping/leagues.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/levels.go b/lib/dbmapping/levels.go index 59999c7..1902509 100644 --- a/lib/dbmapping/levels.go +++ b/lib/dbmapping/levels.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/locations.go b/lib/dbmapping/locations.go index 25b8f3d..f64a453 100644 --- a/lib/dbmapping/locations.go +++ b/lib/dbmapping/locations.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/players.go b/lib/dbmapping/players.go index e6ff4ff..fac87bc 100644 --- a/lib/dbmapping/players.go +++ b/lib/dbmapping/players.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/pokememes.go b/lib/dbmapping/pokememes.go index a95054c..e284dd4 100644 --- a/lib/dbmapping/pokememes.go +++ b/lib/dbmapping/pokememes.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/pokememes_elements.go b/lib/dbmapping/pokememes_elements.go index 62e7c78..3cc0130 100644 --- a/lib/dbmapping/pokememes_elements.go +++ b/lib/dbmapping/pokememes_elements.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/pokememes_locations.go b/lib/dbmapping/pokememes_locations.go index 3a889c1..3af9d84 100644 --- a/lib/dbmapping/pokememes_locations.go +++ b/lib/dbmapping/pokememes_locations.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/profiles.go b/lib/dbmapping/profiles.go index 51c1133..fcba4b1 100644 --- a/lib/dbmapping/profiles.go +++ b/lib/dbmapping/profiles.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/profiles_pokememes.go b/lib/dbmapping/profiles_pokememes.go index d18b0bb..bdc7c4f 100644 --- a/lib/dbmapping/profiles_pokememes.go +++ b/lib/dbmapping/profiles_pokememes.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/squads.go b/lib/dbmapping/squads.go index 33087f5..01f4983 100644 --- a/lib/dbmapping/squads.go +++ b/lib/dbmapping/squads.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/squads_players.go b/lib/dbmapping/squads_players.go index 61781f8..62d472e 100644 --- a/lib/dbmapping/squads_players.go +++ b/lib/dbmapping/squads_players.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/dbmapping/weapons.go b/lib/dbmapping/weapons.go index 4c1111d..c40d8c5 100644 --- a/lib/dbmapping/weapons.go +++ b/lib/dbmapping/weapons.go @@ -4,7 +4,6 @@ package dbmapping import ( - // stdlib "time" ) diff --git a/lib/forwarder/exported.go b/lib/forwarder/exported.go new file mode 100644 index 0000000..6241460 --- /dev/null +++ b/lib/forwarder/exported.go @@ -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...") +} diff --git a/lib/forwarder/forwarder.go b/lib/forwarder/forwarder.go new file mode 100644 index 0000000..66b80e0 --- /dev/null +++ b/lib/forwarder/forwarder.go @@ -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" +} diff --git a/lib/forwarder/forwarderinterface/forwarderinterface.go b/lib/forwarder/forwarderinterface/forwarderinterface.go new file mode 100644 index 0000000..061a71c --- /dev/null +++ b/lib/forwarder/forwarderinterface/forwarderinterface.go @@ -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 +} diff --git a/lib/getters/broadcasts.go b/lib/getters/broadcasts.go index af2473c..c5a3e88 100644 --- a/lib/getters/broadcasts.go +++ b/lib/getters/broadcasts.go @@ -4,11 +4,8 @@ package getters import ( - // stdlib - "log" - "time" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" + "time" ) // CreateBroadcastMessage creates broadcast message item in database @@ -21,12 +18,12 @@ func (g *Getters) CreateBroadcastMessage(playerRaw *dbmapping.Player, messageBod messageRaw.CreatedAt = time.Now().UTC() _, err := c.Db.NamedExec("INSERT INTO broadcasts VALUES(NULL, :text, :broadcast_type, :status, :author_id, :created_at)", &messageRaw) if err != nil { - log.Printf(err.Error()) + c.Log.Error(err.Error()) return messageRaw, false } err2 := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE author_id=? AND text=?"), messageRaw.AuthorID, messageRaw.Text) if err2 != nil { - log.Println(err2) + c.Log.Error(err2) return messageRaw, false } @@ -38,7 +35,7 @@ func (g *Getters) GetBroadcastMessageByID(messageID int) (dbmapping.Broadcast, b messageRaw := dbmapping.Broadcast{} err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID) if err != nil { - log.Println(err) + c.Log.Error(err) return messageRaw, false } @@ -50,18 +47,18 @@ func (g *Getters) UpdateBroadcastMessageStatus(messageID int, messageStatus stri messageRaw := dbmapping.Broadcast{} err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID) if err != nil { - log.Println(err) + c.Log.Error(err.Error()) return messageRaw, false } messageRaw.Status = messageStatus _, err = c.Db.NamedExec("UPDATE broadcasts SET status=:status WHERE id=:id", &messageRaw) if err != nil { - log.Printf(err.Error()) + c.Log.Error(err.Error()) return messageRaw, false } err = c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE author_id=? AND text=?"), messageRaw.AuthorID, messageRaw.Text) if err != nil { - log.Println(err) + c.Log.Error(err.Error()) return messageRaw, false } diff --git a/lib/getters/chat.go b/lib/getters/chat.go index d1ecdf8..ff6507d 100644 --- a/lib/getters/chat.go +++ b/lib/getters/chat.go @@ -4,13 +4,9 @@ package getters import ( - // stdlib - "log" - "time" - // 3rd-party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" + "time" ) // GetChatByID returns dbmapping.Chat instance with given ID. @@ -18,7 +14,7 @@ func (g *Getters) GetChatByID(chatID int64) (dbmapping.Chat, bool) { chatRaw := dbmapping.Chat{} err := c.Db.Get(&chatRaw, c.Db.Rebind("SELECT * FROM chats WHERE id=?"), chatID) if err != nil { - log.Println(err) + c.Log.Error(err) 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. func (g *Getters) GetOrCreateChat(telegramUpdate *tgbotapi.Update) (dbmapping.Chat, bool) { 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) if err != nil { - log.Printf("Chat stream not found in database.") - log.Printf(err.Error()) + c.Log.Error("Chat stream not found in database.") + c.Log.Error(err.Error()) nameOfChat := "" if telegramUpdate.Message.Chat.FirstName != "" { @@ -56,16 +52,16 @@ func (g *Getters) GetOrCreateChat(telegramUpdate *tgbotapi.Update) (dbmapping.Ch chatRaw.CreatedAt = time.Now().UTC() _, err = c.Db.NamedExec("INSERT INTO chats VALUES(NULL, :name, :chat_type, :telegram_id, :created_at)", &chatRaw) if err != nil { - log.Printf(err.Error()) + c.Log.Error(err.Error()) return chatRaw, false } err2 := c.Db.Get(&chatRaw, c.Db.Rebind("SELECT * FROM chats WHERE telegram_id=? AND chat_type=?"), chatRaw.TelegramID, chatRaw.ChatType) if err2 != nil { - log.Println(err2) + c.Log.Error(err2) return chatRaw, false } } else { - log.Printf("Chat stream found in database.") + c.Log.Info("Chat stream found in database.") } 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'") if err != nil { - log.Println(err) + c.Log.Error(err) 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')") if err != nil { - log.Println(err) + c.Log.Error(err) 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')") if err != nil { - log.Println(err) + c.Log.Error(err) return chatsSquads, false } @@ -113,7 +109,7 @@ func (g *Getters) GetAllGroupChatsWithSquads() ([]dbmapping.SquadChat, bool) { squad := dbmapping.Squad{} err = c.Db.Select(&squad, c.Db.Rebind("SELECT * FROM squads WHERE chat_id="), groupChats[i].ID) if err != nil { - log.Println(err) + c.Log.Debug(err) chatSquad.IsSquad = false } else { chatSquad.IsSquad = true @@ -129,11 +125,11 @@ func (g *Getters) GetAllGroupChatsWithSquads() ([]dbmapping.SquadChat, bool) { } // 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 _, err := c.Db.NamedExec("UPDATE chats SET name=:name WHERE id=:id", &chatRaw) if err != nil { - log.Println(err) + c.Log.Error(err) return chatRaw, false } diff --git a/lib/getters/exported.go b/lib/getters/exported.go index c84c1b5..cfb4c23 100644 --- a/lib/getters/exported.go +++ b/lib/getters/exported.go @@ -4,9 +4,6 @@ package getters import ( - // stdlib - "log" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "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 func (g *Getters) Init() { - log.Printf("Initializing getters...") + c.Log.Info("Initializing getters...") } diff --git a/lib/getters/gettersinterface/gettersinterface.go b/lib/getters/gettersinterface/gettersinterface.go index cab612f..cb9a5a8 100644 --- a/lib/getters/gettersinterface/gettersinterface.go +++ b/lib/getters/gettersinterface/gettersinterface.go @@ -4,9 +4,7 @@ package gettersinterface import ( - // 3rd-party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" ) @@ -21,7 +19,7 @@ type GettersInterface interface { GetAllPrivateChats() ([]dbmapping.Chat, bool) GetAllGroupChats() ([]dbmapping.Chat, 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) GetPlayerByID(playerID int) (dbmapping.Player, bool) PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool diff --git a/lib/getters/player.go b/lib/getters/player.go index db48d38..c98f9ae 100644 --- a/lib/getters/player.go +++ b/lib/getters/player.go @@ -4,11 +4,8 @@ package getters import ( - // stdlib - "log" - "time" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" + "time" ) // GetPlayerByID returns dbmapping.Player instance with given ID. @@ -16,7 +13,7 @@ func (g *Getters) GetPlayerByID(playerID int) (dbmapping.Player, bool) { playerRaw := dbmapping.Player{} err := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE id=?"), playerID) if err != nil { - log.Println(err) + c.Log.Error(err.Error()) return playerRaw, false } @@ -29,8 +26,8 @@ func (g *Getters) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) { playerRaw := dbmapping.Player{} err := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id=?"), telegramID) if err != nil { - log.Printf("Message user not found in database.") - log.Printf(err.Error()) + c.Log.Error("Message user not found in database.") + c.Log.Error(err.Error()) // Create "nobody" user playerRaw.TelegramID = telegramID @@ -40,11 +37,11 @@ func (g *Getters) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) { playerRaw.UpdatedAt = time.Now().UTC() _, err = c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :status, :created_at, :updated_at)", &playerRaw) if err != nil { - log.Printf(err.Error()) + c.Log.Error(err.Error()) return playerRaw, false } } else { - log.Printf("Message user found in database.") + c.Log.Debug("Message user found in database.") } return playerRaw, true diff --git a/lib/getters/pokememes.go b/lib/getters/pokememes.go index 14370d7..bd53dee 100644 --- a/lib/getters/pokememes.go +++ b/lib/getters/pokememes.go @@ -4,11 +4,8 @@ package getters import ( - // stdlib - "log" - "strconv" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" + "strconv" ) // Internal functions @@ -18,25 +15,25 @@ func (g *Getters) formFullPokememes(pokememes []dbmapping.Pokememe) ([]dbmapping elements := []dbmapping.Element{} err := c.Db.Select(&elements, "SELECT * FROM elements") if err != nil { - log.Println(err) + c.Log.Error(err) return pokememesArray, false } locations := []dbmapping.Location{} err = c.Db.Select(&locations, "SELECT * FROM locations") if err != nil { - log.Println(err) + c.Log.Error(err) return pokememesArray, false } pokememesElements := []dbmapping.PokememeElement{} err = c.Db.Select(&pokememesElements, "SELECT * FROM pokememes_elements") if err != nil { - log.Println(err) + c.Log.Error(err) return pokememesArray, false } pokememesLocations := []dbmapping.PokememeLocation{} err = c.Db.Select(&pokememesLocations, "SELECT * FROM pokememes_locations") if err != nil { - log.Println(err) + c.Log.Error(err) return pokememesArray, false } @@ -83,7 +80,7 @@ func (g *Getters) GetPokememes() ([]dbmapping.PokememeFull, bool) { pokememes := []dbmapping.Pokememe{} err := c.Db.Select(&pokememes, "SELECT * FROM pokememes ORDER BY grade asc, name asc") if err != nil { - log.Println(err) + c.Log.Error(err) return pokememesArray, false } @@ -111,7 +108,7 @@ func (g *Getters) GetBestPokememes(playerID int) ([]dbmapping.PokememeFull, bool 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) if err != nil { - log.Println(err) + c.Log.Error(err) return pokememesArray, false } @@ -125,31 +122,31 @@ func (g *Getters) GetPokememeByID(pokememeID string) (dbmapping.PokememeFull, bo pokememe := dbmapping.Pokememe{} err := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE id=?"), pokememeID) if err != nil { - log.Println(err) + c.Log.Error(err) return fullPokememe, false } elements := []dbmapping.Element{} err = c.Db.Select(&elements, "SELECT * FROM elements") if err != nil { - log.Println(err) + c.Log.Error(err) return fullPokememe, false } locations := []dbmapping.Location{} err = c.Db.Select(&locations, "SELECT * FROM locations") if err != nil { - log.Println(err) + c.Log.Error(err) return fullPokememe, false } pokememesElements := []dbmapping.PokememeElement{} err = c.Db.Select(&pokememesElements, "SELECT * FROM pokememes_elements WHERE pokememe_id='"+strconv.Itoa(pokememe.ID)+"'") if err != nil { - log.Println(err) + c.Log.Error(err) return fullPokememe, false } pokememesLocations := []dbmapping.PokememeLocation{} err = c.Db.Select(&pokememesLocations, "SELECT * FROM pokememes_locations WHERE pokememe_id='"+strconv.Itoa(pokememe.ID)+"'") if err != nil { - log.Println(err) + c.Log.Error(err) return fullPokememe, false } diff --git a/lib/getters/possibility.go b/lib/getters/possibility.go index efea354..dca9339 100644 --- a/lib/getters/possibility.go +++ b/lib/getters/possibility.go @@ -3,11 +3,6 @@ package getters -import ( - // stdlib - "log" -) - // PossibilityRequiredPokeballs returns possibility of catching pokememe // 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) { @@ -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) if err != nil { - log.Println(err) + c.Log.Error(err) } if basePossibility != 0 && pokememesCount != 0 { diff --git a/lib/getters/profile.go b/lib/getters/profile.go index bba9f5d..3d21228 100644 --- a/lib/getters/profile.go +++ b/lib/getters/profile.go @@ -4,9 +4,6 @@ package getters import ( - // stdlib - "log" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" ) @@ -15,7 +12,7 @@ func (g *Getters) GetProfile(playerID int) (dbmapping.Profile, bool) { 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) if err != nil { - log.Println(err) + c.Log.Error(err) return profileRaw, false } diff --git a/lib/migrations/10_update_leagues.go b/lib/migrations/10_update_leagues.go index 9a8869a..3cc4b4c 100644 --- a/lib/migrations/10_update_leagues.go +++ b/lib/migrations/10_update_leagues.go @@ -4,10 +4,10 @@ package migrations import ( - // stdlib "database/sql" ) +// UpdateLeaguesUp fixes some fuckup with leagues' emoji func UpdateLeaguesUp(tx *sql.Tx) error { _, err := tx.Exec("UPDATE `leagues` SET symbol='🈸' WHERE symbol=':u7533:';") if err != nil { @@ -25,6 +25,7 @@ func UpdateLeaguesUp(tx *sql.Tx) error { return nil } +// UpdateLeaguesDown returns leagues emoji fuckup for sanity purposes func UpdateLeaguesDown(tx *sql.Tx) error { _, err := tx.Exec("UPDATE `leagues` SET symbol=':u7533:' WHERE symbol='🈸';") if err != nil { diff --git a/lib/migrations/11_profile_data_additions.go b/lib/migrations/11_profile_data_additions.go index 3c96f22..16dda35 100644 --- a/lib/migrations/11_profile_data_additions.go +++ b/lib/migrations/11_profile_data_additions.go @@ -4,26 +4,26 @@ package migrations import ( - // stdlib "database/sql" ) +// ProfileDataAdditionsUp creates some helping databases for profiles func ProfileDataAdditionsUp(tx *sql.Tx) error { _, err := tx.Exec("ALTER TABLE `profiles` ADD `pokeballs` INT(11) DEFAULT 5 NOT NULL COMMENT 'Покеболы' AFTER `level_id`;") if err != nil { return err } - create_request := "CREATE TABLE `levels` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID уровня и его номер'," - create_request += "`max_exp` int(11) NOT NULL COMMENT 'Опыт для прохождения уровня'," - create_request += "`max_egg` int(11) NOT NULL COMMENT 'Опыт для открытия яйца'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `levels_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Уровни';" - _, err = tx.Exec(create_request) + request := "CREATE TABLE `levels` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID уровня и его номер'," + request += "`max_exp` int(11) NOT NULL COMMENT 'Опыт для прохождения уровня'," + request += "`max_egg` int(11) NOT NULL COMMENT 'Опыт для открытия яйца'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `levels_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Уровни';" + _, err = tx.Exec(request) if err != nil { return err } @@ -69,6 +69,7 @@ func ProfileDataAdditionsUp(tx *sql.Tx) error { return nil } +// ProfileDataAdditionsDown drops `levels` table and `pokeballs` column of `profiles` table func ProfileDataAdditionsDown(tx *sql.Tx) error { _, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `pokeballs`;") if err != nil { diff --git a/lib/migrations/12_create_profile_relations.go b/lib/migrations/12_create_profile_relations.go index 4cf6de4..c2b2667 100644 --- a/lib/migrations/12_create_profile_relations.go +++ b/lib/migrations/12_create_profile_relations.go @@ -4,29 +4,30 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateProfileRelationsUp creates profile-pokememes relation table func CreateProfileRelationsUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `profiles_pokememes` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," - create_request += "`profile_id` int(11) NOT NULL COMMENT 'ID профиля'," - create_request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," - create_request += "`pokememe_lvl` int(11) NOT NULL COMMENT 'Уровень покемема'," - create_request += "`pokememe_rarity` varchar(191) NOT NULL DEFAULT 'common' COMMENT 'Редкость покемема'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `profiles_pokememes_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Профили-Покемемы';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `profiles_pokememes` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," + request += "`profile_id` int(11) NOT NULL COMMENT 'ID профиля'," + request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," + request += "`pokememe_lvl` int(11) NOT NULL COMMENT 'Уровень покемема'," + request += "`pokememe_rarity` varchar(191) NOT NULL DEFAULT 'common' COMMENT 'Редкость покемема'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `profiles_pokememes_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Профили-Покемемы';" + _, err := tx.Exec(request) if err != nil { return err } return nil } +// CreateProfileRelationsDown drops profile-pokememes relation table func CreateProfileRelationsDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `profiles_pokememes`;") if err != nil { diff --git a/lib/migrations/13_create_weapons_and_add_wealth.go b/lib/migrations/13_create_weapons_and_add_wealth.go index 7851862..afe1768 100644 --- a/lib/migrations/13_create_weapons_and_add_wealth.go +++ b/lib/migrations/13_create_weapons_and_add_wealth.go @@ -4,22 +4,22 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateWeaponsAndAddWealthUp creates `weapons` table and adds `wealth` column to `profiles` func CreateWeaponsAndAddWealthUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `weapons` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID оружия'," - create_request += "`name` varchar(191) NOT NULL COMMENT 'Название оружия'," - create_request += "`power` int(11) NOT NULL COMMENT 'Атака оружия'," - create_request += "`price` int(11) NOT NULL COMMENT 'Цена в магазине'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `weapons_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Оружие';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `weapons` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID оружия'," + request += "`name` varchar(191) NOT NULL COMMENT 'Название оружия'," + request += "`power` int(11) NOT NULL COMMENT 'Атака оружия'," + request += "`price` int(11) NOT NULL COMMENT 'Цена в магазине'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `weapons_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Оружие';" + _, err := tx.Exec(request) if err != nil { return err } @@ -57,6 +57,7 @@ func CreateWeaponsAndAddWealthUp(tx *sql.Tx) error { return nil } +// CreateWeaponsAndAddWealthDown drops `weapons` table and `wealth` column of `profiles` table func CreateWeaponsAndAddWealthDown(tx *sql.Tx) error { _, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `wealth`;") if err != nil { diff --git a/lib/migrations/14_fix_time_element.go b/lib/migrations/14_fix_time_element.go index 16f8494..50ca338 100644 --- a/lib/migrations/14_fix_time_element.go +++ b/lib/migrations/14_fix_time_element.go @@ -4,10 +4,10 @@ package migrations import ( - // stdlib "database/sql" ) +// FixTimeElementUp fixes time element emoji func FixTimeElementUp(tx *sql.Tx) error { _, err := tx.Exec("UPDATE `elements` SET league_id=3 WHERE symbol='⌛';") if err != nil { @@ -17,6 +17,7 @@ func FixTimeElementUp(tx *sql.Tx) error { return nil } +// FixTimeElementDown returns fucked up emoji of time element for sanity func FixTimeElementDown(tx *sql.Tx) error { _, err := tx.Exec("UPDATE `elements` SET league_id=1 WHERE symbol='⌛';") if err != nil { diff --git a/lib/migrations/15_create_chats.go b/lib/migrations/15_create_chats.go index ac231a4..a605899 100644 --- a/lib/migrations/15_create_chats.go +++ b/lib/migrations/15_create_chats.go @@ -4,22 +4,22 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateChatsUp creates `chats` table func CreateChatsUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `chats` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID чата'," - create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя чата'," - create_request += "`chat_type` bool NOT NULL COMMENT 'Тип чата'," - create_request += "`telegram_id` int(11) NOT NULL COMMENT 'ID чата в Телеграме'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `chats_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Чаты';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `chats` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID чата'," + request += "`name` varchar(191) NOT NULL COMMENT 'Имя чата'," + request += "`chat_type` bool NOT NULL COMMENT 'Тип чата'," + request += "`telegram_id` int(11) NOT NULL COMMENT 'ID чата в Телеграме'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `chats_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Чаты';" + _, err := tx.Exec(request) if err != nil { return err } @@ -27,6 +27,7 @@ func CreateChatsUp(tx *sql.Tx) error { return nil } +// CreateChatsDown drops `chats` table func CreateChatsDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `chats`;") if err != nil { diff --git a/lib/migrations/16_change_chat_type_column.go b/lib/migrations/16_change_chat_type_column.go index 68429a5..0ebe6dd 100644 --- a/lib/migrations/16_change_chat_type_column.go +++ b/lib/migrations/16_change_chat_type_column.go @@ -4,10 +4,10 @@ package migrations import ( - // stdlib "database/sql" ) +// ChangeChatTypeColumnUp changes `chat_type` column of `chats` table func ChangeChatTypeColumnUp(tx *sql.Tx) error { _, err := tx.Exec("ALTER TABLE `chats` MODIFY `chat_type` varchar(191);") if err != nil { @@ -17,6 +17,7 @@ func ChangeChatTypeColumnUp(tx *sql.Tx) error { return nil } +// ChangeChatTypeColumnDown changes `chat_type` column of `chats` table func ChangeChatTypeColumnDown(tx *sql.Tx) error { _, err := tx.Exec("ALTER TABLE `chats` MODIFY `chat_type` bool;") if err != nil { diff --git a/lib/migrations/17_change_profile_pokememes_columns.go b/lib/migrations/17_change_profile_pokememes_columns.go index 947ebe1..a42e598 100644 --- a/lib/migrations/17_change_profile_pokememes_columns.go +++ b/lib/migrations/17_change_profile_pokememes_columns.go @@ -4,10 +4,10 @@ package migrations import ( - // stdlib "database/sql" ) +// ChangeProfilePokememesColumnsUp prepares database for latest game update in mid-October 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`;;") if err != nil { @@ -22,6 +22,7 @@ func ChangeProfilePokememesColumnsUp(tx *sql.Tx) error { return nil } +// ChangeProfilePokememesColumnsDown restores mid-October behaviour 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`;;") if err != nil { diff --git a/lib/migrations/18_add_pokememes_wealth.go b/lib/migrations/18_add_pokememes_wealth.go index 836b475..b867a92 100644 --- a/lib/migrations/18_add_pokememes_wealth.go +++ b/lib/migrations/18_add_pokememes_wealth.go @@ -8,6 +8,7 @@ import ( "database/sql" ) +// AddPokememesWealth prepares database for latest game update in mid-October 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`;") if err != nil { @@ -17,6 +18,7 @@ func AddPokememesWealthUp(tx *sql.Tx) error { return nil } +// AddPokememesWealthDown restores mid-October behaviour func AddPokememesWealthDown(tx *sql.Tx) error { _, err := tx.Exec("ALTER TABLE `profiles` DROP COLUMN `pokememes_wealth`;") if err != nil { diff --git a/lib/migrations/19_create_broadcasts.go b/lib/migrations/19_create_broadcasts.go index f707517..abc629e 100644 --- a/lib/migrations/19_create_broadcasts.go +++ b/lib/migrations/19_create_broadcasts.go @@ -4,10 +4,10 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateBroadcastsUp creates `broadcasts` table func CreateBroadcastsUp(tx *sql.Tx) error { request := "CREATE TABLE `broadcasts` (" request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID сообщения'," @@ -28,6 +28,7 @@ func CreateBroadcastsUp(tx *sql.Tx) error { return nil } +// CreateBroadcastsDown drops `broadcasts` table func CreateBroadcastsDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `broadcasts`;") if err != nil { diff --git a/lib/migrations/1_hello.go b/lib/migrations/1_hello.go index d18db4e..1743930 100644 --- a/lib/migrations/1_hello.go +++ b/lib/migrations/1_hello.go @@ -4,15 +4,12 @@ package migrations import ( - // stdlib "database/sql" - "log" ) -// First migration, added for testing purposes - +// HelloUp is the first migration, added for testing purposes 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 } diff --git a/lib/migrations/20_create_squads.go b/lib/migrations/20_create_squads.go index 1888c72..aa1ccdf 100644 --- a/lib/migrations/20_create_squads.go +++ b/lib/migrations/20_create_squads.go @@ -4,10 +4,10 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateSquadsUp creates `squads` table func CreateSquadsUp(tx *sql.Tx) error { request := "CREATE TABLE `squads` (" request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID отряда'," @@ -47,6 +47,7 @@ func CreateSquadsUp(tx *sql.Tx) error { return nil } +// CreateSquadsDown drops `squads` table func CreateSquadsDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `squads`;") if err != nil { diff --git a/lib/migrations/21_change_telegram_id_column.go b/lib/migrations/21_change_telegram_id_column.go new file mode 100644 index 0000000..afb28bc --- /dev/null +++ b/lib/migrations/21_change_telegram_id_column.go @@ -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 +} diff --git a/lib/migrations/2_create_players.go b/lib/migrations/2_create_players.go index a9977b0..5c85a53 100644 --- a/lib/migrations/2_create_players.go +++ b/lib/migrations/2_create_players.go @@ -4,31 +4,32 @@ package migrations import ( - // stdlib "database/sql" ) +// CreatePlayersUp creates `players` table func CreatePlayersUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `players` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID игрока'," - create_request += "`telegram_id` int(11) NOT NULL COMMENT 'ID в телеграме'," - create_request += "`league_id` int(11) COMMENT 'ID лиги' DEFAULT 0," - create_request += "`squad_id` int(11) COMMENT 'ID отряда' DEFAULT 0," - create_request += "`status` varchar(191) COMMENT 'Статус в лиге' DEFAULT 'common'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," - create_request += "`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Время последнего обновления'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `players_created_at` (`created_at`)," - create_request += "KEY `players_updated_at` (`updated_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Зарегистрированные игроки';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `players` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID игрока'," + request += "`telegram_id` int(11) NOT NULL COMMENT 'ID в телеграме'," + request += "`league_id` int(11) COMMENT 'ID лиги' DEFAULT 0," + request += "`squad_id` int(11) COMMENT 'ID отряда' DEFAULT 0," + request += "`status` varchar(191) COMMENT 'Статус в лиге' DEFAULT 'common'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," + request += "`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Время последнего обновления'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `players_created_at` (`created_at`)," + request += "KEY `players_updated_at` (`updated_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Зарегистрированные игроки';" + _, err := tx.Exec(request) if err != nil { return err } return nil } +// CreatePlayersDown drops `players` table func CreatePlayersDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `players`;") if err != nil { diff --git a/lib/migrations/3_create_profiles.go b/lib/migrations/3_create_profiles.go index 28a45ac..4e852b3 100644 --- a/lib/migrations/3_create_profiles.go +++ b/lib/migrations/3_create_profiles.go @@ -4,35 +4,36 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateProfilesUp creates `profiles` table func CreateProfilesUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `profiles` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID сохраненного профиля'," - create_request += "`player_id` int(11) NOT NULL COMMENT 'ID игрока в системе'," - create_request += "`nickname` varchar(191) NOT NULL COMMENT 'Ник игрока'," - create_request += "`telegram_nickname` varchar(191) NOT NULL COMMENT 'Ник в Телеграме (@)'," - create_request += "`level_id` int(11) NOT NULL COMMENT 'Уровень'," - create_request += "`exp` int(11) NOT NULL COMMENT 'Опыт'," - create_request += "`egg_exp` int(11) NOT NULL COMMENT 'Опыт яйца'," - create_request += "`power` int(11) NOT NULL COMMENT 'Сила без оружия'," - create_request += "`weapon_id` int(11) NOT NULL COMMENT 'Тип оружия'," - create_request += "`crystalls` int(11) NOT NULL COMMENT 'Кристаллы'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `profiles_created_at` (`created_at`)," - create_request += "KEY `profiles_nickname` (`nickname`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Профили зарегистрированных игроков';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `profiles` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID сохраненного профиля'," + request += "`player_id` int(11) NOT NULL COMMENT 'ID игрока в системе'," + request += "`nickname` varchar(191) NOT NULL COMMENT 'Ник игрока'," + request += "`telegram_nickname` varchar(191) NOT NULL COMMENT 'Ник в Телеграме (@)'," + request += "`level_id` int(11) NOT NULL COMMENT 'Уровень'," + request += "`exp` int(11) NOT NULL COMMENT 'Опыт'," + request += "`egg_exp` int(11) NOT NULL COMMENT 'Опыт яйца'," + request += "`power` int(11) NOT NULL COMMENT 'Сила без оружия'," + request += "`weapon_id` int(11) NOT NULL COMMENT 'Тип оружия'," + request += "`crystalls` int(11) NOT NULL COMMENT 'Кристаллы'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `profiles_created_at` (`created_at`)," + request += "KEY `profiles_nickname` (`nickname`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Профили зарегистрированных игроков';" + _, err := tx.Exec(request) if err != nil { return err } return nil } +// CreateProfilesDown drops `profiles` table func CreateProfilesDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `profiles`;") if err != nil { diff --git a/lib/migrations/4_create_pokememes.go b/lib/migrations/4_create_pokememes.go index 7ae5782..c25e9d4 100644 --- a/lib/migrations/4_create_pokememes.go +++ b/lib/migrations/4_create_pokememes.go @@ -4,37 +4,38 @@ package migrations import ( - // stdlib "database/sql" ) +// CreatePokememesUp creates `pokememes` table func CreatePokememesUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `pokememes` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID покемема'," - create_request += "`grade` int(11) NOT NULL COMMENT 'Поколение покемема'," - create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя покемема'," - create_request += "`description` TEXT NOT NULL COMMENT 'Описание покемема'," - create_request += "`attack` int(11) NOT NULL COMMENT 'Атака'," - create_request += "`hp` int(11) NOT NULL COMMENT 'Здоровье'," - create_request += "`mp` int(11) NOT NULL COMMENT 'МР'," - create_request += "`defence` int(11) NOT NULL COMMENT 'Защита'," - create_request += "`price` int(11) NOT NULL COMMENT 'Стоимость'," - create_request += "`purchaseable` bool NOT NULL DEFAULT true COMMENT 'Можно купить?'," - create_request += "`image_url` varchar(191) NOT NULL COMMENT 'Изображение покемема'," - create_request += "`player_id` int(11) NOT NULL COMMENT 'Кто добавил в базу'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `pokememes_created_at` (`created_at`)," - create_request += "KEY `pokememes_player_id` (`player_id`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Покемемы';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `pokememes` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID покемема'," + request += "`grade` int(11) NOT NULL COMMENT 'Поколение покемема'," + request += "`name` varchar(191) NOT NULL COMMENT 'Имя покемема'," + request += "`description` TEXT NOT NULL COMMENT 'Описание покемема'," + request += "`attack` int(11) NOT NULL COMMENT 'Атака'," + request += "`hp` int(11) NOT NULL COMMENT 'Здоровье'," + request += "`mp` int(11) NOT NULL COMMENT 'МР'," + request += "`defence` int(11) NOT NULL COMMENT 'Защита'," + request += "`price` int(11) NOT NULL COMMENT 'Стоимость'," + request += "`purchaseable` bool NOT NULL DEFAULT true COMMENT 'Можно купить?'," + request += "`image_url` varchar(191) NOT NULL COMMENT 'Изображение покемема'," + request += "`player_id` int(11) NOT NULL COMMENT 'Кто добавил в базу'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `pokememes_created_at` (`created_at`)," + request += "KEY `pokememes_player_id` (`player_id`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Покемемы';" + _, err := tx.Exec(request) if err != nil { return err } return nil } +// CreatePokememesDown drops `pokememes` table func CreatePokememesDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `pokememes`;") if err != nil { diff --git a/lib/migrations/5_create_locations.go b/lib/migrations/5_create_locations.go index 5f73d24..c7682ce 100644 --- a/lib/migrations/5_create_locations.go +++ b/lib/migrations/5_create_locations.go @@ -4,21 +4,21 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateLocationsUp creates `locations` table and fills it with data func CreateLocationsUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `locations` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID локации'," - create_request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ локации'," - create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя локации'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлена в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `locations_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Локации';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `locations` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID локации'," + request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ локации'," + request += "`name` varchar(191) NOT NULL COMMENT 'Имя локации'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлена в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `locations_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Локации';" + _, err := tx.Exec(request) if err != nil { return err } @@ -52,6 +52,7 @@ func CreateLocationsUp(tx *sql.Tx) error { return nil } +// CreateLocationsDown drops `locations` table func CreateLocationsDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `locations`;") if err != nil { diff --git a/lib/migrations/6_create_elements.go b/lib/migrations/6_create_elements.go index 830ad52..4fa9323 100644 --- a/lib/migrations/6_create_elements.go +++ b/lib/migrations/6_create_elements.go @@ -4,22 +4,22 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateElementsUp creates `elements` table and fills it with data func CreateElementsUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `elements` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID элемента'," - create_request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ элемента'," - create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя элемента'," - create_request += "`league_id` int(11) NOT NULL COMMENT 'ID родной лиги'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `elements_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Элементы';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `elements` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID элемента'," + request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ элемента'," + request += "`name` varchar(191) NOT NULL COMMENT 'Имя элемента'," + request += "`league_id` int(11) NOT NULL COMMENT 'ID родной лиги'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлен в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `elements_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Элементы';" + _, err := tx.Exec(request) if err != nil { return err } @@ -77,6 +77,7 @@ func CreateElementsUp(tx *sql.Tx) error { return nil } +// CreateElementsDown drops `elements` table func CreateElementsDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `elements`;") if err != nil { diff --git a/lib/migrations/7_create_leagues.go b/lib/migrations/7_create_leagues.go index ce55d20..cd6fff8 100644 --- a/lib/migrations/7_create_leagues.go +++ b/lib/migrations/7_create_leagues.go @@ -4,21 +4,21 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateLeaguesUp creates `leagues` table and fills it with data func CreateLeaguesUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `leagues` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID лиги'," - create_request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ лиги'," - create_request += "`name` varchar(191) NOT NULL COMMENT 'Имя лиги'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлена в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `leagues_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Лиги';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `leagues` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID лиги'," + request += "`symbol` varchar(191) COLLATE 'utf8mb4_unicode_520_ci' NOT NULL COMMENT 'Символ лиги'," + request += "`name` varchar(191) NOT NULL COMMENT 'Имя лиги'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлена в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `leagues_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Лиги';" + _, err := tx.Exec(request) if err != nil { return err } @@ -40,6 +40,7 @@ func CreateLeaguesUp(tx *sql.Tx) error { return nil } +// CreateLeaguesDown drops `leagues` table func CreateLeaguesDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `leagues`;") if err != nil { diff --git a/lib/migrations/8_create_relations.go b/lib/migrations/8_create_relations.go index bbfe49a..609da89 100644 --- a/lib/migrations/8_create_relations.go +++ b/lib/migrations/8_create_relations.go @@ -4,41 +4,42 @@ package migrations import ( - // stdlib "database/sql" ) +// CreateRelationsUp creates tables for pokememes-locations and pokememes-elements links func CreateRelationsUp(tx *sql.Tx) error { - create_request := "CREATE TABLE `pokememes_locations` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," - create_request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," - create_request += "`location_id` int(11) NOT NULL COMMENT 'ID локации'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `pokememes_locations_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Локации';" - _, err := tx.Exec(create_request) + request := "CREATE TABLE `pokememes_locations` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," + request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," + request += "`location_id` int(11) NOT NULL COMMENT 'ID локации'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `pokememes_locations_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Локации';" + _, err := tx.Exec(request) if err != nil { return err } - create_request = "CREATE TABLE `pokememes_elements` (" - create_request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," - create_request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," - create_request += "`element_id` int(11) NOT NULL COMMENT 'ID элемента'," - create_request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," - create_request += "PRIMARY KEY (`id`)," - create_request += "UNIQUE KEY `id` (`id`)," - create_request += "KEY `pokememes_elements_created_at` (`created_at`)" - create_request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Элементы';" - _, err2 := tx.Exec(create_request) + request = "CREATE TABLE `pokememes_elements` (" + request += "`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID связи'," + request += "`pokememe_id` int(11) NOT NULL COMMENT 'ID покемема'," + request += "`element_id` int(11) NOT NULL COMMENT 'ID элемента'," + request += "`created_at` datetime NOT NULL COMMENT 'Добавлено в базу'," + request += "PRIMARY KEY (`id`)," + request += "UNIQUE KEY `id` (`id`)," + request += "KEY `pokememes_elements_created_at` (`created_at`)" + request += ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Связь Покемемы-Элементы';" + _, err2 := tx.Exec(request) if err2 != nil { return err2 } return nil } +// CreateRelationsDown drops pokememe-* relations tables func CreateRelationsDown(tx *sql.Tx) error { _, err := tx.Exec("DROP TABLE `pokememes_locations`;") if err != nil { diff --git a/lib/migrations/9_update_locations.go b/lib/migrations/9_update_locations.go index d0da7d6..9f0f029 100644 --- a/lib/migrations/9_update_locations.go +++ b/lib/migrations/9_update_locations.go @@ -4,10 +4,10 @@ package migrations import ( - // stdlib "database/sql" ) +// UpdateLocationsUp fixes some fuckup with locations' emoji func UpdateLocationsUp(tx *sql.Tx) error { _, err := tx.Exec("UPDATE `locations` SET symbol='⛪' WHERE symbol=':church:';") if err != nil { @@ -25,6 +25,7 @@ func UpdateLocationsUp(tx *sql.Tx) error { return nil } +// UpdateLocationsDown returns location emoji fuckup for sanity purposes func UpdateLocationsDown(tx *sql.Tx) error { _, err := tx.Exec("UPDATE `locations` SET symbol=':church:' WHERE symbol='⛪'';") if err != nil { diff --git a/lib/migrations/exported.go b/lib/migrations/exported.go index c12925b..b50943a 100644 --- a/lib/migrations/exported.go +++ b/lib/migrations/exported.go @@ -4,15 +4,18 @@ package migrations import ( - // local "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "lab.pztrn.name/fat0troll/i2_bot/lib/migrations/migrationsinterface" ) +// Migrations handles all functions of migrations package +type Migrations struct{} + var ( c *appcontext.Context ) +// New is an initialization function for migrations package func New(ac *appcontext.Context) { c = ac m := &Migrations{} diff --git a/lib/migrations/migrations.go b/lib/migrations/migrations.go index 3029d71..d7dea07 100644 --- a/lib/migrations/migrations.go +++ b/lib/migrations/migrations.go @@ -4,16 +4,12 @@ package migrations import ( - // stdlib - "log" - // 3rd-party "github.com/pressly/goose" ) -type Migrations struct{} - +// Init adds all migrations to applications func (m *Migrations) Init() { - log.Printf("Initializing migrations...") + c.Log.Info("Initializing migrations...") // All migrations are here goose.AddNamedMigration("1_hello.go", HelloUp, nil) 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("19_create_broadcasts.go", CreateBroadcastsUp, CreateBroadcastsDown) 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 { - log.Printf("Starting database migrations...") + c.Log.Printf("Starting database migrations...") err := goose.Up(c.Db.DB, ".") if err != nil { - log.Fatal(err) + c.Log.Fatal(err) return err } @@ -49,6 +47,7 @@ func (m *Migrations) Migrate() error { return nil } +// SetDialect sets dialect for migrations func (m *Migrations) SetDialect(dialect string) error { return goose.SetDialect(dialect) } diff --git a/lib/parsers/parsersinterface/parsersinterface.go b/lib/parsers/parsersinterface/parsersinterface.go index d5fa494..4e15553 100644 --- a/lib/parsers/parsersinterface/parsersinterface.go +++ b/lib/parsers/parsersinterface/parsersinterface.go @@ -12,7 +12,7 @@ import ( // ParsersInterface implements Parsers for importing via appcontext. type ParsersInterface interface { - ParsePokememe(text string, playerRaw dbmapping.Player) string - ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Player) string + ParsePokememe(text string, playerRaw *dbmapping.Player) string + ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Player) string ReturnPoints(points int) string } diff --git a/lib/parsers/pokememe.go b/lib/parsers/pokememe.go index d7fe1a5..91b2e8c 100644 --- a/lib/parsers/pokememe.go +++ b/lib/parsers/pokememe.go @@ -4,14 +4,11 @@ package parsers import ( - // stdlib - "log" + "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "regexp" "strconv" "strings" "time" - // local - "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" ) // Internal functions @@ -35,7 +32,7 @@ func (p *Parsers) getPoints(pointsStr string) int { // External functions // 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 pokememeStringsArray := strings.Split(text, "\n") 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, "', '")+"')") if err != nil { - log.Printf(err.Error()) + c.Log.Error(err.Error()) return "fail" } @@ -68,8 +65,8 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string hitPointsRx := regexp.MustCompile("(\\d|\\.)+(K|M)?") hitPoints := hitPointsRx.FindAllString(string(pokememeRunesArray[5]), -1) if len(hitPoints) != 3 { - log.Printf("Can't parse hitpoints!") - log.Println(pokememeRunesArray[5]) + c.Log.Error("Can't parse hitpoints!") + c.Log.Debug(pokememeRunesArray[5]) return "fail" } @@ -85,34 +82,34 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string // Actions for high-grade pokememes defenceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[6]), -1) if len(defenceMatch) < 1 { - log.Printf("Can't parse defence!") - log.Println(pokememeRunesArray[6]) + c.Log.Error("Can't parse defence!") + c.Log.Debug(pokememeRunesArray[6]) return "fail" } defence = defenceMatch[0] priceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[7]), -1) if len(priceMatch) < 1 { - log.Printf("Can't parse price!") - log.Println(pokememeRunesArray[7]) + c.Log.Error("Can't parse price!") + c.Log.Debug(pokememeRunesArray[7]) return "fail" } price = priceMatch[0] locationsPrepare := strings.Split(string(pokememeRunesArray[8]), ": ") if len(locationsPrepare) < 2 { - log.Printf("Can't parse locations!") - log.Println(pokememeRunesArray[8]) + c.Log.Error("Can't parse locations!") + c.Log.Debug(pokememeRunesArray[8]) return "fail" } locationsNames := strings.Split(locationsPrepare[1], ", ") if len(locationsNames) < 1 { - log.Printf("Can't parse locations!") - log.Println(locationsPrepare) + c.Log.Error("Can't parse locations!") + c.Log.Debug(locationsPrepare) return "fail" } err2 := c.Db.Select(&locations, "SELECT * FROM locations WHERE name IN ('"+strings.Join(locationsNames, "', '")+"')") if err2 != nil { - log.Printf(err2.Error()) + c.Log.Error(err2.Error()) return "fail" } if strings.HasSuffix(string(pokememeRunesArray[9]), "Можно") { @@ -124,27 +121,27 @@ func (p *Parsers) ParsePokememe(text string, playerRaw dbmapping.Player) string defence = hitPoints[0] priceMatch := hitPointsRx.FindAllString(string(pokememeRunesArray[6]), -1) if len(priceMatch) < 1 { - log.Printf("Can't parse price!") - log.Println(pokememeRunesArray[6]) + c.Log.Error("Can't parse price!") + c.Log.Debug(pokememeRunesArray[6]) return "fail" } price = priceMatch[0] locationsPrepare := strings.Split(string(pokememeRunesArray[7]), ": ") if len(locationsPrepare) < 2 { - log.Printf("Can't parse locations!") - log.Println(pokememeRunesArray[7]) + c.Log.Error("Can't parse locations!") + c.Log.Debug(pokememeRunesArray[7]) return "fail" } locationsNames := strings.Split(locationsPrepare[1], ", ") if len(locationsNames) < 1 { - log.Printf("Can't parse locations!") - log.Println(locationsPrepare) + c.Log.Error("Can't parse locations!") + c.Log.Debug(locationsPrepare) return "fail" } err2 := c.Db.Select(&locations, "SELECT * FROM locations WHERE name IN ('"+strings.Join(locationsNames, "', '")+"')") if err2 != nil { - log.Printf(err2.Error()) + c.Log.Error(err2.Error()) return "fail" } 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]) name := string(pokememeRunesArray[0][3:]) description := string(pokememeRunesArray[1]) - log.Printf("Pokememe grade: " + grade) - log.Printf("Pokememe name: " + name) - log.Printf("Pokememe description: " + description) - log.Printf("Elements:") + c.Log.Debug("Pokememe grade: " + grade) + c.Log.Debug("Pokememe name: " + name) + c.Log.Debug("Pokememe description: " + description) + c.Log.Debug("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]) - log.Printf("HP: " + hitPoints[1]) - log.Printf("MP: " + hitPoints[2]) - log.Printf("Defence: " + defence) - log.Printf("Price: " + price) - log.Printf("Locations:") + c.Log.Debug("Attack: " + hitPoints[0]) + c.Log.Debug("HP: " + hitPoints[1]) + c.Log.Debug("MP: " + hitPoints[2]) + c.Log.Debug("Defence: " + defence) + c.Log.Debug("Price: " + price) + c.Log.Debug("Locations:") for i := range locations { - log.Printf(locations[i].Symbol + " " + locations[i].Name) + c.Log.Debug(locations[i].Symbol + " " + locations[i].Name) } if purchaseable { - log.Printf("Purchaseable") + c.Log.Debug("Purchaseable") } else { - log.Printf("Non-purchaseable") + c.Log.Debug("Non-purchaseable") } - log.Printf("Image: " + image) + c.Log.Debug("Image: " + image) // Building pokememe pokememe := dbmapping.Pokememe{} // Checking if pokememe exists in database err3 := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE grade='"+grade+"' AND name='"+name+"';")) if err3 != nil { - log.Printf("Adding new pokememe...") + c.Log.Debug("Adding new pokememe...") } else { - log.Printf("This pokememe already exist. Return specific error.") + c.Log.Info("This pokememe already exist. Return specific error.") 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) if err4 != nil { - log.Printf(err4.Error()) + c.Log.Error(err4.Error()) return "fail" } // Getting new pokememe err5 := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE grade='"+grade+"' AND name='"+name+"';")) if err5 != nil { - log.Printf("Pokememe isn't added!") + c.Log.Error("Pokememe isn't added!") return "fail" } 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) if err6 != nil { - log.Printf(err6.Error()) + c.Log.Error(err6.Error()) 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) if err7 != nil { - log.Printf(err7.Error()) + c.Log.Error(err7.Error()) return "fail" } } diff --git a/lib/parsers/profile.go b/lib/parsers/profile.go index ad327dd..a8a147d 100644 --- a/lib/parsers/profile.go +++ b/lib/parsers/profile.go @@ -4,16 +4,12 @@ package parsers import ( - // stdlib - "log" + "github.com/go-telegram-bot-api/telegram-bot-api" + "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "regexp" "strconv" "strings" "time" - // 3rd party - "github.com/go-telegram-bot-api/telegram-bot-api" - // local - "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" ) // Internal functions @@ -22,7 +18,7 @@ func (p *Parsers) fillProfilePokememe(profileID int, meme string, attack string, spkRaw := dbmapping.Pokememe{} err := c.Db.Get(&spkRaw, c.Db.Rebind("SELECT * FROM pokememes WHERE name='"+meme+"';")) if err != nil { - log.Println(err) + c.Log.Error(err.Error()) } else { attackInt := p.getPoints(attack) ppk := dbmapping.ProfilePokememe{} @@ -33,7 +29,7 @@ func (p *Parsers) fillProfilePokememe(profileID int, meme string, attack string, 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) 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 // 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 - log.Println(text) + c.Log.Info(text) profileStringsArray := strings.Split(text, "\n") 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, "🈵") { err1 := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE symbol='"+string(currentRunes[0])+"'")) if err1 != nil { - log.Println(err1) + c.Log.Error(err1.Error()) return "fail" } for j := range currentRunes { @@ -94,7 +90,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe levelRx := regexp.MustCompile("\\d+") levelArray := levelRx.FindAllString(currentString, -1) if len(levelArray) < 1 { - log.Println("Level string broken") + c.Log.Error("Level string broken") return "fail" } level = levelArray[0] @@ -105,7 +101,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe expRx := regexp.MustCompile("\\d+") expArray := expRx.FindAllString(currentString, -1) if len(expArray) < 4 { - log.Println("Exp string broken") + c.Log.Error("Exp string broken") return "fail" } exp = expArray[0] @@ -118,7 +114,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe pkbRx := regexp.MustCompile("\\d+") pkbArray := pkbRx.FindAllString(currentString, -1) if len(pkbArray) < 2 { - log.Println("Pokeballs string broken") + c.Log.Error("Pokeballs string broken") return "fail" } pokeballs = pkbArray[1] @@ -129,7 +125,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe wealthRx := regexp.MustCompile("(\\d|\\.|K|M)+") wealthArray := wealthRx.FindAllString(currentString, -1) if len(wealthArray) < 2 { - log.Println("Wealth string broken") + c.Log.Error("Wealth string broken") return "fail" } wealth = wealthArray[0] @@ -149,7 +145,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe pkmnumRx := regexp.MustCompile(`(\d+)(\d|K|M|)`) pkNumArray := pkmnumRx.FindAllString(currentString, -1) if len(pkNumArray) < 3 { - log.Println("Pokememes count broken") + c.Log.Error("Pokememes count broken") return "fail" } pokememesCount, _ := strconv.Atoi(pkNumArray[0]) @@ -172,37 +168,37 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, playerRaw dbmapping.Playe } } - log.Printf("Telegram nickname: " + telegramNickname) - log.Printf("Nickname: " + nickname) - log.Printf("League: " + league.Name) - log.Printf("Level: " + level) - log.Println(levelInt) - log.Printf("Exp: " + exp) - log.Println(expInt) - log.Printf("Egg exp: " + eggexp) - log.Println(eggexpInt) - log.Printf("Pokeballs: " + pokeballs) - log.Println(pokeballsInt) - log.Printf("Wealth: " + wealth) - log.Println(wealthInt) - log.Printf("Crystalls: " + crystalls) - log.Println(crystallsInt) - log.Printf("Weapon: " + weapon) + c.Log.Debug("Telegram nickname: " + telegramNickname) + c.Log.Debug("Nickname: " + nickname) + c.Log.Debug("League: " + league.Name) + c.Log.Debug("Level: " + level) + c.Log.Debugln(levelInt) + c.Log.Debug("Exp: " + exp) + c.Log.Debugln(expInt) + c.Log.Debug("Egg exp: " + eggexp) + c.Log.Debugln(eggexpInt) + c.Log.Debug("Pokeballs: " + pokeballs) + c.Log.Debugln(pokeballsInt) + c.Log.Debug("Wealth: " + wealth) + c.Log.Debugln(wealthInt) + c.Log.Debug("Crystalls: " + crystalls) + c.Log.Debugln(crystallsInt) + c.Log.Debug("Weapon: " + weapon) if len(pokememes) > 0 { - log.Printf("Hand cost: " + pokememesWealth) - log.Println(pokememesWealthInt) + c.Log.Debug("Hand cost: " + pokememesWealth) + c.Log.Debugln(pokememesWealthInt) for meme, attack := range pokememes { - log.Printf(meme + ": " + attack) + c.Log.Debug(meme + ": " + attack) } } else { - log.Printf("Hand is empty.") + c.Log.Debug("Hand is empty.") } // Information is gathered, let's create profile in database! weaponRaw := dbmapping.Weapon{} err2 := c.Db.Get(&weaponRaw, c.Db.Rebind("SELECT * FROM weapons WHERE name='"+weapon+"'")) if err2 != nil { - log.Println(err2) + c.Log.Error(err2.Error()) } 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) if err4 != nil { - log.Println(err4) + c.Log.Error(err4.Error()) return "fail" } } 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() _, err5 := c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :status, :created_at, :updated_at)", &playerRaw) if err5 != nil { - log.Println(err5) + c.Log.Error(err5.Error()) 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)+"';")) if err6 != nil { - log.Println(err6) + c.Log.Error(err6.Error()) 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) if err3 != nil { - log.Println(err3) + c.Log.Error(err3.Error()) return "fail" } err8 := c.Db.Get(&profileRaw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? AND created_at=?"), profileRaw.PlayerID, profileRaw.CreatedAt) if err8 != nil { - log.Println(err8) - log.Printf("Profile isn't added!") + c.Log.Error(err8.Error()) + c.Log.Error("Profile isn't added!") return "fail" } playerRaw.UpdatedAt = time.Now().UTC() _, err7 := c.Db.NamedExec("UPDATE `players` SET updated_at=:updated_at WHERE id=:id", &playerRaw) if err7 != nil { - log.Println(err7) + c.Log.Error(err7.Error()) return "fail" } diff --git a/lib/pinner/exported.go b/lib/pinner/exported.go new file mode 100644 index 0000000..f6170c5 --- /dev/null +++ b/lib/pinner/exported.go @@ -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...") +} diff --git a/lib/pinner/pinner.go b/lib/pinner/pinner.go new file mode 100644 index 0000000..49fa56a --- /dev/null +++ b/lib/pinner/pinner.go @@ -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" +} diff --git a/lib/pinner/pinnerinterface/pinnerinterface.go b/lib/pinner/pinnerinterface/pinnerinterface.go new file mode 100644 index 0000000..e9d3ff3 --- /dev/null +++ b/lib/pinner/pinnerinterface/pinnerinterface.go @@ -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 +} diff --git a/lib/router/exported.go b/lib/router/exported.go index 246e029..2eae45b 100644 --- a/lib/router/exported.go +++ b/lib/router/exported.go @@ -4,25 +4,24 @@ package router import ( - // stdlib - "log" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" ) var ( c *appcontext.Context - r *Router ) +// Router is a function-handling struct for router +type Router struct{} + // New is an initialization function for appcontext func New(ac *appcontext.Context) { c = ac - rh := RouterHandler{} - c.RegisterRouterInterface(rh) + r := &Router{} + c.RegisterRouterInterface(r) } // Init is an initialization function for package router func (r *Router) Init() { - log.Printf("Initialized request router...") + c.Log.Info("Initialized request router...") } diff --git a/lib/router/group_request.go b/lib/router/group_request.go index 2305f73..da47dc0 100644 --- a/lib/router/group_request.go +++ b/lib/router/group_request.go @@ -4,15 +4,12 @@ package router import ( - // stdlib - "regexp" - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "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 // Regular expressions var durakMsg = regexp.MustCompile("(Д|д)(У|у)(Р|р)(А|а|Е|е|О|о)") @@ -22,8 +19,11 @@ func (r *Router) routeGroupRequest(update tgbotapi.Update, playerRaw dbmapping.P var piMsg = regexp.MustCompile("(П|п)(И|и)(З|з)(Д|д)") // Welcomes - if update.Message.NewChatMember != nil { - return c.Welcomer.WelcomeMessage(update) + if update.Message.NewChatMembers != nil { + newUsers := *update.Message.NewChatMembers + if len(newUsers) > 0 { + return c.Welcomer.WelcomeMessage(update) + } } // New chat names if update.Message.NewChatTitle != "" { diff --git a/lib/router/handler.go b/lib/router/handler.go deleted file mode 100644 index 9db84b7..0000000 --- a/lib/router/handler.go +++ /dev/null @@ -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) -} diff --git a/lib/router/private_request.go b/lib/router/private_request.go index 598e5f5..7701cc2 100644 --- a/lib/router/private_request.go +++ b/lib/router/private_request.go @@ -4,21 +4,13 @@ package router import ( - // stdlib - "log" - "regexp" - "strings" - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "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 - // 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 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.ID != 360402625 { - log.Printf("Forward from another user or bot. Ignoring") + c.Log.Info("Forward from another user or bot. Ignoring") } else { - log.Printf("Forward from PokememBro bot! Processing...") + c.Log.Info("Forward from PokememBro bot! Processing...") if playerRaw.ID != 0 { - switch { - 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" - } + c.Forwarder.ProcessForward(update, playerRaw) } else { c.Talkers.AnyMessageUnauthorized(update) return "fail" @@ -82,28 +40,11 @@ func (r *Router) routePrivateRequest(update tgbotapi.Update, playerRaw dbmapping c.Talkers.HelloMessageUnauthorized(update) return "ok" case update.Message.Command() == "help": - c.Talkers.HelpMessage(update, &playerRaw) + c.Talkers.HelpMessage(update, playerRaw) return "ok" // Pokememes info case pokedexMsg.MatchString(text): - if strings.HasSuffix(text, "1") { - 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) + c.Talkers.PokememesList(update) return "ok" case pokememeInfoMsg.MatchString(text): c.Talkers.PokememeInfo(update, playerRaw) @@ -120,27 +61,34 @@ func (r *Router) routePrivateRequest(update tgbotapi.Update, playerRaw dbmapping c.Talkers.BestPokememesList(update, playerRaw) return "ok" case update.Message.Command() == "send_all": - if c.Getters.PlayerBetterThan(&playerRaw, "admin") { - c.Talkers.AdminBroadcastMessageCompose(update, &playerRaw) + if c.Getters.PlayerBetterThan(playerRaw, "admin") { + c.Talkers.AdminBroadcastMessageCompose(update, playerRaw) return "ok" } c.Talkers.AnyMessageUnauthorized(update) return "fail" case update.Message.Command() == "send_confirm": - if c.Getters.PlayerBetterThan(&playerRaw, "admin") { - c.Talkers.AdminBroadcastMessageSend(update, &playerRaw) + if c.Getters.PlayerBetterThan(playerRaw, "admin") { + c.Talkers.AdminBroadcastMessageSend(update, playerRaw) return "ok" } c.Talkers.AnyMessageUnauthorized(update) return "fail" case update.Message.Command() == "group_chats": - if c.Getters.PlayerBetterThan(&playerRaw, "admin") { + if c.Getters.PlayerBetterThan(playerRaw, "admin") { c.Talkers.GroupsList(update) 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) return "fail" } diff --git a/lib/router/router.go b/lib/router/router.go index 0973eef..7fa028d 100644 --- a/lib/router/router.go +++ b/lib/router/router.go @@ -4,35 +4,29 @@ package router import ( - // stdlib - "log" - // 3rd party "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 -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) if !ok { // Silently fail return "fail" } - chatRaw, ok := c.Getters.GetOrCreateChat(&update) + chatRaw, ok := c.Getters.GetOrCreateChat(update) if !ok { return "fail" } - log.Printf("Received message from chat ") - log.Println(chatRaw.TelegramID) + c.Log.Debug("Received message from chat ") + c.Log.Debugln(chatRaw.TelegramID) 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() { - return r.routePrivateRequest(update, playerRaw, chatRaw) + return r.routePrivateRequest(update, &playerRaw, &chatRaw) } return "ok" diff --git a/lib/router/routerinterface/routerinterface.go b/lib/router/routerinterface/routerinterface.go index 4146c33..1b27557 100644 --- a/lib/router/routerinterface/routerinterface.go +++ b/lib/router/routerinterface/routerinterface.go @@ -4,12 +4,11 @@ package routerinterface import ( - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" ) // RouterInterface implements Router for importing via appcontext. type RouterInterface interface { Init() - RouteRequest(update tgbotapi.Update) string + RouteRequest(update *tgbotapi.Update) string } diff --git a/lib/talkers/broadcast.go b/lib/talkers/broadcast.go index fa3a29d..8562261 100644 --- a/lib/talkers/broadcast.go +++ b/lib/talkers/broadcast.go @@ -4,17 +4,14 @@ package talkers import ( - // stdlib "strconv" "strings" - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" ) // 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) 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 -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) messageNumInt, _ := strconv.Atoi(messageNum) messageRaw, ok := c.Getters.GetBroadcastMessageByID(messageNumInt) diff --git a/lib/talkers/chats.go b/lib/talkers/chats.go index b1d1aad..4f30bb4 100644 --- a/lib/talkers/chats.go +++ b/lib/talkers/chats.go @@ -4,14 +4,12 @@ package talkers import ( - // stdlib - "strconv" - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" + "strconv" ) -// GroupsList lists all known pokememes -func (t *Talkers) GroupsList(update tgbotapi.Update) string { +// GroupsList lists all chats where bot exist +func (t *Talkers) GroupsList(update *tgbotapi.Update) string { groupChats, ok := c.Getters.GetAllGroupChatsWithSquads() if !ok { return "fail" diff --git a/lib/talkers/easter.go b/lib/talkers/easter.go index c257abe..a62d429 100644 --- a/lib/talkers/easter.go +++ b/lib/talkers/easter.go @@ -4,18 +4,13 @@ package talkers import ( - // stdlib - "log" + "github.com/go-telegram-bot-api/telegram-bot-api" "math/rand" "time" - // 3rd party - "github.com/go-telegram-bot-api/telegram-bot-api" ) // DurakMessage is an easter egg -func (t *Talkers) DurakMessage(update tgbotapi.Update) { - log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) - +func (t *Talkers) DurakMessage(update *tgbotapi.Update) { reactions := make([]string, 0) reactions = append(reactions, "Сам такой!", "А ты типа нет?", @@ -31,9 +26,7 @@ func (t *Talkers) DurakMessage(update tgbotapi.Update) { } // MatMessage is an easter rgg -func (t *Talkers) MatMessage(update tgbotapi.Update) { - log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) - +func (t *Talkers) MatMessage(update *tgbotapi.Update) { reactions := make([]string, 0) reactions = append(reactions, "Фу, как некультурно!", "Иди рот с мылом помой", diff --git a/lib/talkers/errors.go b/lib/talkers/errors.go index b037ffc..4f03cad 100644 --- a/lib/talkers/errors.go +++ b/lib/talkers/errors.go @@ -4,12 +4,11 @@ package talkers import ( - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" ) // 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 += "Если тебе кажется, что это ошибка, пиши @fat0troll.\n" @@ -20,7 +19,7 @@ func (t *Talkers) AnyMessageUnauthorized(update tgbotapi.Update) { } // 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 += "Напиши @fat0troll, приложив форвардом последние сообщения до этого.\n" diff --git a/lib/talkers/exported.go b/lib/talkers/exported.go index d46e060..19e10c4 100644 --- a/lib/talkers/exported.go +++ b/lib/talkers/exported.go @@ -4,9 +4,6 @@ package talkers import ( - // stdlib - "log" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "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 func (t *Talkers) Init() { - log.Printf("Initializing responders...") + c.Log.Info("Initializing responders...") } diff --git a/lib/talkers/hello.go b/lib/talkers/hello.go index 2a3e671..1a8f8a4 100644 --- a/lib/talkers/hello.go +++ b/lib/talkers/hello.go @@ -4,14 +4,12 @@ package talkers import ( - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" ) // 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 += "Для начала работы с ботом, пожалуйста, перешли от бота игры @PokememBroBot профиль героя.\n" message += "Все дальнейшие действия с ботом возможны лишь при наличии профиля игрока." @@ -23,7 +21,7 @@ func (t *Talkers) HelloMessageUnauthorized(update tgbotapi.Update) { } // 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 += "Привет, " + update.Message.From.FirstName + " " + update.Message.From.LastName + "!\n" message += "Последнее обновление информации о тебе: " + playerRaw.UpdatedAt.Format("02.01.2006 15:04:05 -0700") diff --git a/lib/talkers/help.go b/lib/talkers/help.go index 5d16ddd..96b7af6 100644 --- a/lib/talkers/help.go +++ b/lib/talkers/help.go @@ -4,15 +4,13 @@ package talkers import ( - // 3rd party "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/dbmapping" ) // 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 += "Текущая версия: *" + config.VERSION + "*\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") { message += "+ /send\\_all _текст_ — отправить сообщение всем пользователям бота\n" message += "+ /group\\_chats — получить список групп, в которых работает бот.\n" + message += "+ /pin _текст_ — отправить сообщение во все группы, где находится бот. Сообщение будет автоматически запинено.\n" } message += "+ /help – выводит данное сообщение\n" diff --git a/lib/talkers/pokedex.go b/lib/talkers/pokedex.go index a66622d..20402e1 100644 --- a/lib/talkers/pokedex.go +++ b/lib/talkers/pokedex.go @@ -4,18 +4,15 @@ package talkers import ( - // stdlib + "github.com/go-telegram-bot-api/telegram-bot-api" + "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" "strconv" "strings" - // 3rd party - "github.com/go-telegram-bot-api/telegram-bot-api" - // local - "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" ) // 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 += "Покедекс: " + strconv.Itoa(len(pokememesArray)) + " / 219\n" @@ -62,7 +59,13 @@ func (t *Talkers) pokememesListing(update tgbotapi.Update, page int, pokememesAr // External functions // 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() if !ok { 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 -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) var calculatePossibilites = true profileRaw, ok := c.Getters.GetProfile(playerRaw.ID) diff --git a/lib/talkers/pokememe_add.go b/lib/talkers/pokememe_add.go index 0ca357b..e06383d 100644 --- a/lib/talkers/pokememe_add.go +++ b/lib/talkers/pokememe_add.go @@ -4,12 +4,11 @@ package talkers import ( - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" ) // PokememeAddSuccessMessage shows pokememe adding success message -func (t *Talkers) PokememeAddSuccessMessage(update tgbotapi.Update) { +func (t *Talkers) PokememeAddSuccessMessage(update *tgbotapi.Update) { message := "*Покемем успешно добавлен.*\n\n" message += "Посмотреть всех известных боту покемемов можно командой /pokedeks" @@ -20,7 +19,7 @@ func (t *Talkers) PokememeAddSuccessMessage(update tgbotapi.Update) { } // PokememeAddDuplicateMessage shows pokememe add duplication message -func (t *Talkers) PokememeAddDuplicateMessage(update tgbotapi.Update) { +func (t *Talkers) PokememeAddDuplicateMessage(update *tgbotapi.Update) { message := "*Мы уже знаем об этом покемеме*\n\n" message += "Посмотреть всех известных боту покемемов можно командой /pokedeks\n\n" message += "Если у покемема изменились описание или характеристики, напиши @fat0troll для обновления базы." @@ -32,7 +31,7 @@ func (t *Talkers) PokememeAddDuplicateMessage(update tgbotapi.Update) { } // PokememeAddFailureMessage shows pokememe add error message -func (t *Talkers) PokememeAddFailureMessage(update tgbotapi.Update) { +func (t *Talkers) PokememeAddFailureMessage(update *tgbotapi.Update) { message := "*Неудачно получилось :(*\n\n" message += "Случилась жуткая ошибка, и мы не смогли записать покемема в базу. Напиши @fat0troll, он разберется.\n\n" message += "Посмотреть всех известных боту покемемов можно командой /pokedeks" diff --git a/lib/talkers/profile.go b/lib/talkers/profile.go index b8c5b89..e796a21 100644 --- a/lib/talkers/profile.go +++ b/lib/talkers/profile.go @@ -4,17 +4,13 @@ package talkers import ( - // stdlib - "log" - "strconv" - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" + "strconv" ) // 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) if !ok { c.Talkers.AnyMessageUnauthorized(update) @@ -23,29 +19,29 @@ func (t *Talkers) ProfileMessage(update tgbotapi.Update, playerRaw dbmapping.Pla league := dbmapping.League{} err := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE id=?"), playerRaw.LeagueID) if err != nil { - log.Println(err) + c.Log.Error(err) } level := dbmapping.Level{} err = c.Db.Get(&level, c.Db.Rebind("SELECT * FROM levels WHERE id=?"), profileRaw.LevelID) if err != nil { - log.Println(err) + c.Log.Error(err) } weapon := dbmapping.Weapon{} if profileRaw.WeaponID != 0 { err = c.Db.Get(&weapon, c.Db.Rebind("SELECT * FROM weapons WHERE id=?"), profileRaw.WeaponID) if err != nil { - log.Println(err) + c.Log.Error(err) } } profilePokememes := []dbmapping.ProfilePokememe{} err = c.Db.Select(&profilePokememes, c.Db.Rebind("SELECT * FROM profiles_pokememes WHERE profile_id=?"), profileRaw.ID) if err != nil { - log.Println(err) + c.Log.Error(err) } pokememes := []dbmapping.Pokememe{} err = c.Db.Select(&pokememes, c.Db.Rebind("SELECT * FROM pokememes")) if err != nil { - log.Println(err) + c.Log.Error(err) } attackPokememes := 0 diff --git a/lib/talkers/profile_add.go b/lib/talkers/profile_add.go index 03af8dc..9d8e315 100644 --- a/lib/talkers/profile_add.go +++ b/lib/talkers/profile_add.go @@ -4,12 +4,11 @@ package talkers import ( - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" ) // 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" message += "Сохраненный профиль ты можешь просмотреть командой /me.\n\n" @@ -22,7 +21,7 @@ func (t *Talkers) ProfileAddSuccessMessage(update tgbotapi.Update) { } // ProfileAddFailureMessage shows profile addition failure message -func (t *Talkers) ProfileAddFailureMessage(update tgbotapi.Update) { +func (t *Talkers) ProfileAddFailureMessage(update *tgbotapi.Update) { message := "*Неудачно получилось :(*\n\n" message += "Случилась жуткая ошибка, и мы не смогли записать профиль в базу. Напиши @fat0troll, он разберется." diff --git a/lib/talkers/suggestions.go b/lib/talkers/suggestions.go index c425fd9..2b5cc3b 100644 --- a/lib/talkers/suggestions.go +++ b/lib/talkers/suggestions.go @@ -4,20 +4,16 @@ package talkers import ( - // stdlib - "log" - "strconv" - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" + "strconv" ) // 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) if !ok { - log.Printf("Cannot get pokememes from getter!") + c.Log.Error("Cannot get pokememes from getter!") return "fail" } diff --git a/lib/talkers/talkersinterface/talkersinterface.go b/lib/talkers/talkersinterface/talkersinterface.go index 821b4e3..ef0b0dd 100644 --- a/lib/talkers/talkersinterface/talkersinterface.go +++ b/lib/talkers/talkersinterface/talkersinterface.go @@ -4,37 +4,35 @@ package talkersinterface import ( - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping" ) // TalkersInterface implements Talkers for importing via appcontex type TalkersInterface interface { Init() - HelloMessageUnauthorized(update tgbotapi.Update) - HelloMessageAuthorized(update tgbotapi.Update, playerRaw dbmapping.Player) - HelpMessage(update tgbotapi.Update, playerRaw *dbmapping.Player) - PokememesList(update tgbotapi.Update, page int) - PokememeInfo(update tgbotapi.Update, playerRaw dbmapping.Player) string - BestPokememesList(update tgbotapi.Update, playerRaw dbmapping.Player) string + HelloMessageUnauthorized(update *tgbotapi.Update) + HelloMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player) + HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) + PokememesList(update *tgbotapi.Update) + PokememeInfo(update *tgbotapi.Update, playerRaw *dbmapping.Player) string + BestPokememesList(update *tgbotapi.Update, playerRaw *dbmapping.Player) string - PokememeAddSuccessMessage(update tgbotapi.Update) - PokememeAddDuplicateMessage(update tgbotapi.Update) - PokememeAddFailureMessage(update tgbotapi.Update) - ProfileAddSuccessMessage(update tgbotapi.Update) - ProfileAddFailureMessage(update tgbotapi.Update) - ProfileMessage(update tgbotapi.Update, playerRaw dbmapping.Player) string + PokememeAddSuccessMessage(update *tgbotapi.Update) + PokememeAddDuplicateMessage(update *tgbotapi.Update) + PokememeAddFailureMessage(update *tgbotapi.Update) + ProfileAddSuccessMessage(update *tgbotapi.Update) + ProfileAddFailureMessage(update *tgbotapi.Update) + ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) string - AnyMessageUnauthorized(update tgbotapi.Update) - GetterError(update tgbotapi.Update) + AnyMessageUnauthorized(update *tgbotapi.Update) + GetterError(update *tgbotapi.Update) - AdminBroadcastMessageCompose(update tgbotapi.Update, playerRaw *dbmapping.Player) string - AdminBroadcastMessageSend(update tgbotapi.Update, playerRaw *dbmapping.Player) string + AdminBroadcastMessageCompose(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) - MatMessage(update tgbotapi.Update) + DurakMessage(update *tgbotapi.Update) + MatMessage(update *tgbotapi.Update) } diff --git a/lib/welcomer/exported.go b/lib/welcomer/exported.go index b0ab5d6..60f19ea 100644 --- a/lib/welcomer/exported.go +++ b/lib/welcomer/exported.go @@ -4,9 +4,6 @@ package welcomer import ( - // stdlib - "log" - // local "lab.pztrn.name/fat0troll/i2_bot/lib/appcontext" "lab.pztrn.name/fat0troll/i2_bot/lib/welcomer/welcomerinterface" ) @@ -15,7 +12,7 @@ var ( c *appcontext.Context ) -// Welcomer is a function-handling struct for talkers +// Welcomer is a function-handling struct for welcomer type Welcomer struct{} // New is a appcontext initialization function @@ -25,7 +22,7 @@ func New(ac *appcontext.Context) { c.RegisterWelcomerInterface(welcomerinterface.WelcomerInterface(m)) } -// Init is an initialization function for talkers +// Init is an initialization function for welcomer func (w *Welcomer) Init() { - log.Printf("Initializing Welcomer...") + c.Log.Info("Initializing Welcomer...") } diff --git a/lib/welcomer/notifications.go b/lib/welcomer/notifications.go index 09ac8c2..17cb4be 100644 --- a/lib/welcomer/notifications.go +++ b/lib/welcomer/notifications.go @@ -4,21 +4,19 @@ package welcomer import ( - // stdlib - "strconv" - // 3rd party "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) - chat, ok := c.Getters.GetOrCreateChat(&update) + chat, ok := c.Getters.GetOrCreateChat(update) if !ok { return "fail" } message := "*Новый вход пользователя без профиля в чат с ботом!*\n" - message += "В чат _" + chat.Name + "_ вошёл некто @" + update.Message.NewChatMember.UserName + message += "В чат _" + chat.Name + "_ вошёл некто @" + newUser.UserName message += ". Он получил уведомление о том, что ему нужно создать профиль в боте." msg := tgbotapi.NewMessage(alertGroupID, message) @@ -29,15 +27,15 @@ func (w *Welcomer) alertUserWithoutProfile(update tgbotapi.Update) string { 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) - chat, ok := c.Getters.GetOrCreateChat(&update) + chat, ok := c.Getters.GetOrCreateChat(update) if !ok { return "fail" } message := "*Шпион в деле!*\n" - message += "В чат _" + chat.Name + "_ вошёл некто @" + update.Message.NewChatMember.UserName + message += "В чат _" + chat.Name + "_ вошёл некто @" + newUser.UserName message += ". У него профиль другой лиги. Ждём обновлений." msg := tgbotapi.NewMessage(alertGroupID, message) diff --git a/lib/welcomer/welcomer.go b/lib/welcomer/welcomer.go index 0eaa4c6..40a9061 100644 --- a/lib/welcomer/welcomer.go +++ b/lib/welcomer/welcomer.go @@ -4,14 +4,12 @@ package welcomer import ( - // stdlib - "time" - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" + "time" ) -func (w *Welcomer) groupWelcomeUser(update tgbotapi.Update) string { - playerRaw, ok := c.Getters.GetOrCreatePlayer(update.Message.NewChatMember.ID) +func (w *Welcomer) groupWelcomeUser(update *tgbotapi.Update, newUser *tgbotapi.User) string { + playerRaw, ok := c.Getters.GetOrCreatePlayer(newUser.ID) if !ok { return "fail" } @@ -19,7 +17,7 @@ func (w *Welcomer) groupWelcomeUser(update tgbotapi.Update) string { profileRaw, profileExist := c.Getters.GetProfile(playerRaw.ID) message := "*Бот Инстинкта приветствует тебя, *@" - message += update.Message.NewChatMember.UserName + message += newUser.UserName message += "*!*\n\n" if profileExist { @@ -29,13 +27,13 @@ func (w *Welcomer) groupWelcomeUser(update tgbotapi.Update) string { } else { message += "Обнови профиль, отправив его боту в личку. Так надо." - w.alertSpyUser(update) + w.alertSpyUser(update, newUser) } } else { // newbie message += "Добавь себе бота @i2\\_bot в список контактов и скинь в него игровой профиль. Это важно для успешной игры!\n" - w.alertUserWithoutProfile(update) + w.alertUserWithoutProfile(update, newUser) } msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) @@ -46,7 +44,7 @@ func (w *Welcomer) groupWelcomeUser(update tgbotapi.Update) string { return "ok" } -func (w *Welcomer) groupStartMessage(update tgbotapi.Update) string { +func (w *Welcomer) groupStartMessage(update *tgbotapi.Update) string { message := "*Бот Инстинкта приветствует этот чатик!*\n\n" 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 -func (w *Welcomer) WelcomeMessage(update tgbotapi.Update) string { - if (update.Message.NewChatMember.UserName == "i2_bot") || (update.Message.NewChatMember.UserName == "i2_dev_bot") { - return w.groupStartMessage(update) +func (w *Welcomer) WelcomeMessage(update *tgbotapi.Update) string { + newUsers := *update.Message.NewChatMembers + 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" } diff --git a/lib/welcomer/welcomerinterface/welcomerinterface.go b/lib/welcomer/welcomerinterface/welcomerinterface.go index 4683a62..d6d99ae 100644 --- a/lib/welcomer/welcomerinterface/welcomerinterface.go +++ b/lib/welcomer/welcomerinterface/welcomerinterface.go @@ -4,12 +4,11 @@ package welcomerinterface import ( - // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" ) // WelcomerInterface implements Welcomer for importing via appcontex type WelcomerInterface interface { Init() - WelcomeMessage(update tgbotapi.Update) string + WelcomeMessage(update *tgbotapi.Update) string }