diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..3821993 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,47 @@ +image: golang:alpine + +cache: + paths: + - /go/src/github.com + - /go/src/gitlab.com + - /go/src/golang.org + - /go/src/google.golang.org + - /go/src/gopkg.in + +stages: + - test + - build + +before_script: + - apk add --no-cache git build-base bash + - mkdir -p /go/src/gitlab.com/$CI_PROJECT_NAMESPACE /go/src/_/builds + - cp -r $CI_PROJECT_DIR /go/src/gitlab.com/$CI_PROJECT_PATH + - ln -s /go/src/gitlab.com/$CI_PROJECT_NAMESPACE /go/src/_/builds/$CI_PROJECT_NAMESPACE + - make dep + +unit_tests: + stage: test + script: + - make test + +.race_detector: + stage: test + script: + - make race + +code_coverage: + stage: test + script: + - make coverage + +lint_code: + stage: test + script: + - go get github.com/go-critic/go-critic/cmd/gocritic + - go install github.com/go-critic/go-critic/cmd/gocritic + - make lint + +build: + stage: build + script: + - make \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 558c7a5..0000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go - -go: - - tip - -install: - - go get -tags=debug - - go get -u github.com/nicksnyder/go-i18n/goi18n \ No newline at end of file diff --git a/Makefile b/Makefile index c53f312..705f162 100644 --- a/Makefile +++ b/Makefile @@ -1,31 +1,32 @@ -# Build package by default with all general tools and things -all: - make localization - make build +PROJECT_NAMESPACE := $(CI_PROJECT_NAMESPACE) +PROJECT_NAME := $(CI_PROJECT_NAME) +PROJECT_PATH := $(PROJECT_NAMESPACE)/$(PROJECT_NAME) +PACKAGE_NAME := "gitlab.com/$(PROJECT_PATH)" +PACKAGE_PATH := $(GOPATH)/src/$(PACKAGE_NAME) +PACKAGE_LIST := $(shell go list $(PACKAGE_NAME)/... | grep -v /vendor/) +GO_FILES := $(shell find . -name '*.go' | grep -v /vendor/ | grep -v _test.go) -# Build minimal package only -build: - go build +.PHONY: all lint test rase coverage dep build clean -# Build debug version with more logs -debug: - go build -tags=debug +all: build -# Format the source code -fmt: - go fmt +lint: ## Lint the files + @gocritic check-project $(PACKAGE_PATH) -# Build localization files with separated untranslated strings -translation: - goi18n merge -format yaml \ - -sourceLanguage en \ - -outdir ./i18n/ \ - ./i18n/src/*/* +race: dep ## Run data race detector + @go test -race -short ${PACKAGE_LIST} -# Build localization files and merge untranslated strings -localization: - make translation - goi18n -format yaml \ - -sourceLanguage en \ - -outdir ./i18n/ \ - ./i18n/*.all.yaml ./i18n/*.untranslated.yaml \ No newline at end of file +coverage: ## Generate global code coverage report + @go test -cover -v -coverpkg=$(PACKAGE_NAME) ${PACKAGE_LIST} + +dep: ## Get the dependencies + @go get -v -d -t ${PACKAGE_LIST} + +build: dep ## Build the binary file + @go build -i -v $(PACKAGE_NAME) + +clean: ## Remove previous build + @rm -f $(PROJECT_NAME) + +help: ## Display this help screen + @grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' \ No newline at end of file diff --git a/docs/ISSUE_TEMPLATE.md b/docs/ISSUE_TEMPLATE.md deleted file mode 100644 index de1e68b..0000000 --- a/docs/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,20 +0,0 @@ - -### Summary - - -### How-To - \ No newline at end of file diff --git a/docs/PULL_REQUEST_TEMPLATE.md b/docs/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 469fc23..0000000 --- a/docs/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,16 +0,0 @@ - -### Summary - \ No newline at end of file diff --git a/init/init.go b/init/init.go deleted file mode 100644 index cade941..0000000 --- a/init/init.go +++ /dev/null @@ -1,28 +0,0 @@ -package init - -import ( - log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/config" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/i18n" -) - -// init prepare configuration and other things for successful start -func init() { - log.Ln("Initializing...") - - // Preload localization strings - err := i18n.Open("i18n/") - errors.Check(err) - - // Preload configuration file - config.Open("configs/config.yaml") - - // Open database or create new one - db.Open("stickers.db") - - // Create bot with credentials from config - bot.New() -} diff --git a/internal/actions/action.go b/internal/actions/action.go index fe75ccd..cde47ed 100755 --- a/internal/actions/action.go +++ b/internal/actions/action.go @@ -2,16 +2,16 @@ package actions import ( log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/models" + tg "gitlab.com/toby3d/telegram" ) // Action function check Message update on commands, sended stickers or other // user stuff if user state is not 'none' func Action(msg *tg.Message) { - state, err := db.UserState(msg.From.ID) + state, err := db.DB.GetUserState(msg.From) errors.Check(err) log.Ln("state:", state) @@ -27,7 +27,7 @@ func Action(msg *tg.Message) { case models.StateReset: Reset(msg) default: - err = db.ChangeUserState(msg.From.ID, models.StateNone) + err = db.DB.ChangeUserState(msg.From, models.StateNone) errors.Check(err) Error(msg) diff --git a/internal/actions/add.go b/internal/actions/add.go index 503eaee..38ef564 100644 --- a/internal/actions/add.go +++ b/internal/actions/add.go @@ -2,13 +2,13 @@ package actions import ( log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Add action add sticker or set to user's pack @@ -17,34 +17,32 @@ func Add(msg *tg.Message, pack bool) { return } - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) - reply := tg.NewMessage(msg.Chat.ID, T("success_add_sticker")) - reply.ParseMode = tg.ModeMarkdown + reply := tg.NewMessage(msg.Chat.ID, t("success_add_sticker")) + reply.ParseMode = tg.StyleMarkdown if !pack { var exist bool sticker := msg.Sticker - exist, err = db.AddSticker( - msg.From.ID, sticker.SetName, sticker.FileID, sticker.Emoji, - ) + exist, err = db.DB.AddSticker(msg.From, sticker) errors.Check(err) if exist { - reply.Text = T("error_already_add_sticker") + reply.Text = t("error_already_add_sticker") } - reply.ReplyMarkup = helpers.CancelButton(T) + reply.ReplyMarkup = utils.CancelButton(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) return } - reply.Text = T("error_empty_add_pack", map[string]interface{}{ + reply.Text = t("error_empty_add_pack", map[string]interface{}{ "AddStickerCommand": models.CommandAddSticker, }) @@ -54,16 +52,14 @@ func Add(msg *tg.Message, pack bool) { errors.Check(err) log.Ln("SetTitle:", set.Title) - reply.Text = T("success_add_pack", map[string]interface{}{ + reply.Text = t("success_add_pack", map[string]interface{}{ "SetTitle": set.Title, }) allExists := true - for _, sticker := range set.Stickers { + for i := range set.Stickers { var exist bool - exist, err = db.AddSticker( - msg.From.ID, sticker.SetName, sticker.FileID, sticker.Emoji, - ) + exist, err = db.DB.AddSticker(msg.From, &set.Stickers[i]) errors.Check(err) if !exist { @@ -73,13 +69,13 @@ func Add(msg *tg.Message, pack bool) { log.Ln("All exists?", allExists) if allExists { - reply.Text = T("error_already_add_pack", map[string]interface{}{ + reply.Text = t("error_already_add_pack", map[string]interface{}{ "SetTitle": set.Title, }) } } - reply.ReplyMarkup = helpers.CancelButton(T) + reply.ReplyMarkup = utils.CancelButton(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) } diff --git a/internal/actions/delete.go b/internal/actions/delete.go index 75eb33b..0dbb29b 100644 --- a/internal/actions/delete.go +++ b/internal/actions/delete.go @@ -2,12 +2,12 @@ package actions import ( log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Delete action remove sticker or set from user's pack @@ -16,15 +16,15 @@ func Delete(msg *tg.Message, pack bool) { return } - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) - reply := tg.NewMessage(msg.Chat.ID, T("success_del_sticker")) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.CancelButton(T) + reply := tg.NewMessage(msg.Chat.ID, t("success_del_sticker")) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.CancelButton(t) var notExist bool if pack { @@ -33,22 +33,18 @@ func Delete(msg *tg.Message, pack bool) { errors.Check(err) log.Ln("SetName:", set.Title) - reply.Text = T("success_del_pack", map[string]interface{}{ + reply.Text = t("success_del_pack", map[string]interface{}{ "SetTitle": set.Title, }) - notExist, err = db.DeletePack(msg.From.ID, msg.Sticker.SetName) + notExist, err = db.DB.DeletePack(msg.From, msg.Sticker) if notExist { - reply.Text = T("error_already_del_pack") + reply.Text = t("error_already_del_pack") } } else { - notExist, err = db.DeleteSticker( - msg.From.ID, - msg.Sticker.SetName, - msg.Sticker.FileID, - ) + notExist, err = db.DB.DeleteSticker(msg.From, msg.Sticker) if notExist { - reply.Text = T("error_already_del_sticker") + reply.Text = t("error_already_del_sticker") } } errors.Check(err) diff --git a/internal/actions/error.go b/internal/actions/error.go index 0b2ade9..b966507 100644 --- a/internal/actions/error.go +++ b/internal/actions/error.go @@ -1,32 +1,32 @@ package actions import ( - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Error action send error reply about invalid user request func Error(msg *tg.Message) { - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) reply := tg.NewMessage( - msg.Chat.ID, T("error_unknown", map[string]interface{}{ + msg.Chat.ID, t("error_unknown", map[string]interface{}{ "AddStickerCommand": models.CommandAddSticker, "AddPackCommand": models.CommandAddPack, "DeleteStickerCommand": models.CommandDeleteSticker, "DeletePackCommand": models.CommandDeletePack, }), ) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.MenuKeyboard(T) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.MenuKeyboard(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) diff --git a/internal/actions/reset.go b/internal/actions/reset.go index d73a233..044803c 100644 --- a/internal/actions/reset.go +++ b/internal/actions/reset.go @@ -3,42 +3,42 @@ package actions import ( "strings" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Reset action checks key phrase and reset user's pack func Reset(msg *tg.Message) { - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) - err = db.ChangeUserState(msg.From.ID, models.StateNone) + err = db.DB.ChangeUserState(msg.From, models.StateNone) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) - if !strings.EqualFold(msg.Text, T("key_phrase")) { - reply := tg.NewMessage(msg.Chat.ID, T("error_reset_phrase")) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.MenuKeyboard(T) + if !strings.EqualFold(msg.Text, t("key_phrase")) { + reply := tg.NewMessage(msg.Chat.ID, t("error_reset_phrase")) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.MenuKeyboard(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) return } - err = db.ResetUser(msg.From.ID) + err = db.DB.ResetUser(msg.From) errors.Check(err) - reply := tg.NewMessage(msg.Chat.ID, T("success_reset")) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.MenuKeyboard(T) + reply := tg.NewMessage(msg.Chat.ID, t("success_reset")) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.MenuKeyboard(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) } diff --git a/internal/bot/new.go b/internal/bot/new.go index 868bc0f..7157b8a 100644 --- a/internal/bot/new.go +++ b/internal/bot/new.go @@ -1,19 +1,11 @@ package bot -import ( - "github.com/toby3d/MyPackBot/internal/config" - "github.com/toby3d/MyPackBot/internal/errors" - tg "github.com/toby3d/telegram" -) +import tg "gitlab.com/toby3d/telegram" // Bot is a main object of Telegram bot var Bot *tg.Bot // New just create new bot by configuration credentials -func New() { - accessToken, err := config.Config.String("telegram.token") - errors.Check(err) - - Bot, err = tg.NewBot(accessToken) - errors.Check(err) +func New(accessToken string) (bot *tg.Bot, err error) { + return tg.New(accessToken) } diff --git a/internal/commands/add.go b/internal/commands/add.go index ed937b8..7b5a92c 100644 --- a/internal/commands/add.go +++ b/internal/commands/add.go @@ -2,34 +2,34 @@ package commands import ( log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Add command prepare user for adding some stickers or sets to his pack func Add(msg *tg.Message, pack bool) { - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) - reply := tg.NewMessage(msg.Chat.ID, T("reply_add_sticker")) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.CancelButton(T) + reply := tg.NewMessage(msg.Chat.ID, t("reply_add_sticker")) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.CancelButton(t) - err = db.ChangeUserState(msg.From.ID, models.StateAddSticker) + err = db.DB.ChangeUserState(msg.From, models.StateAddSticker) errors.Check(err) if pack { - reply.Text = T("reply_add_pack") + reply.Text = t("reply_add_pack") - err = db.ChangeUserState(msg.From.ID, models.StateAddPack) + err = db.DB.ChangeUserState(msg.From, models.StateAddPack) errors.Check(err) } diff --git a/internal/commands/cancel.go b/internal/commands/cancel.go index 18068ca..aeb8d7a 100755 --- a/internal/commands/cancel.go +++ b/internal/commands/cancel.go @@ -1,21 +1,21 @@ package commands import ( - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Cancel just cancel current user operation func Cancel(msg *tg.Message) { - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) - state, err := db.UserState(msg.From.ID) + state, err := db.DB.GetUserState(msg.From) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) @@ -24,24 +24,24 @@ func Cancel(msg *tg.Message) { var text string switch state { case models.StateAddSticker: - text = T("cancel_add_sticker") + text = t("cancel_add_sticker") case models.StateAddPack: - text = T("cancel_add_pack") + text = t("cancel_add_pack") case models.StateDeleteSticker: - text = T("cancel_del_sticker") + text = t("cancel_del_sticker") case models.StateDeletePack: - text = T("cancel_del_pack") + text = t("cancel_del_pack") case models.StateReset: - text = T("cancel_reset") + text = t("cancel_reset") default: - text = T("cancel_error") + text = t("cancel_error") } - err = db.ChangeUserState(msg.From.ID, models.StateNone) + err = db.DB.ChangeUserState(msg.From, models.StateNone) errors.Check(err) reply := tg.NewMessage(msg.Chat.ID, text) - reply.ReplyMarkup = helpers.MenuKeyboard(T) + reply.ReplyMarkup = utils.MenuKeyboard(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) diff --git a/internal/commands/command.go b/internal/commands/command.go index 0e4e455..72e68af 100755 --- a/internal/commands/command.go +++ b/internal/commands/command.go @@ -2,29 +2,29 @@ package commands import ( log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/models" + tg "gitlab.com/toby3d/telegram" ) // Command check's got user command func Command(msg *tg.Message) { log.Ln("command:", msg.Command()) switch { - case msg.IsCommand(models.CommandStart): + case msg.IsCommandEqual(tg.CommandStart): Start(msg) - case msg.IsCommand(models.CommandHelp): + case msg.IsCommandEqual(tg.CommandHelp): Help(msg) - case msg.IsCommand(models.CommandAddSticker): + case msg.IsCommandEqual(models.CommandAddSticker): Add(msg, false) - case msg.IsCommand(models.CommandAddPack): + case msg.IsCommandEqual(models.CommandAddPack): Add(msg, true) - case msg.IsCommand(models.CommandDeleteSticker): + case msg.IsCommandEqual(models.CommandDeleteSticker): Delete(msg, false) - case msg.IsCommand(models.CommandDeletePack): + case msg.IsCommandEqual(models.CommandDeletePack): Delete(msg, true) - case msg.IsCommand(models.CommandReset): + case msg.IsCommandEqual(models.CommandReset): Reset(msg) - case msg.IsCommand(models.CommandCancel): + case msg.IsCommandEqual(models.CommandCancel): Cancel(msg) } } diff --git a/internal/commands/delete.go b/internal/commands/delete.go index 86f4c76..a92d772 100755 --- a/internal/commands/delete.go +++ b/internal/commands/delete.go @@ -1,49 +1,49 @@ package commands import ( - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Delete prepare user to remove some stickers or sets from his pack func Delete(msg *tg.Message, pack bool) { - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) - _, total, err := db.UserStickers(msg.From.ID, 0, "") + stickers, err := db.DB.GetUserStickers(msg.From, &tg.InlineQuery{}) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) - if total <= 0 { - err = db.ChangeUserState(msg.From.ID, models.StateNone) + if len(stickers) <= 0 { + err = db.DB.ChangeUserState(msg.From, models.StateNone) errors.Check(err) - reply := tg.NewMessage(msg.Chat.ID, T("error_empty_del")) - reply.ReplyMarkup = helpers.MenuKeyboard(T) + reply := tg.NewMessage(msg.Chat.ID, t("error_empty_del")) + reply.ReplyMarkup = utils.MenuKeyboard(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) return } - reply := tg.NewMessage(msg.Chat.ID, T("reply_del_sticker")) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.CancelButton(T) + reply := tg.NewMessage(msg.Chat.ID, t("reply_del_sticker")) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.CancelButton(t) - err = db.ChangeUserState(msg.From.ID, models.StateDeleteSticker) + err = db.DB.ChangeUserState(msg.From, models.StateDeleteSticker) errors.Check(err) if pack { - err = db.ChangeUserState(msg.From.ID, models.StateDeletePack) + err = db.DB.ChangeUserState(msg.From, models.StateDeletePack) errors.Check(err) - reply.Text = T("reply_del_pack") + reply.Text = t("reply_del_pack") } _, err = bot.Bot.SendMessage(reply) @@ -52,8 +52,8 @@ func Delete(msg *tg.Message, pack bool) { _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) - reply = tg.NewMessage(msg.Chat.ID, T("reply_switch_button")) - reply.ReplyMarkup = helpers.SwitchButton(T) + reply = tg.NewMessage(msg.Chat.ID, t("reply_switch_button")) + reply.ReplyMarkup = utils.SwitchButton(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) } diff --git a/internal/commands/help.go b/internal/commands/help.go index e3e3936..a8b34c3 100755 --- a/internal/commands/help.go +++ b/internal/commands/help.go @@ -1,39 +1,39 @@ package commands import ( - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Help just send instructions about bot usage func Help(msg *tg.Message) { - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) - err = db.ChangeUserState(msg.From.ID, models.StateNone) + err = db.DB.ChangeUserState(msg.From, models.StateNone) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) reply := tg.NewMessage( - msg.Chat.ID, T("reply_help", map[string]interface{}{ + msg.Chat.ID, t("reply_help", map[string]interface{}{ "AddStickerCommand": models.CommandAddSticker, "AddPackCommand": models.CommandAddPack, "DeleteStickerCommand": models.CommandDeleteSticker, "DeletePackCommand": models.CommandDeletePack, "ResetCommand": models.CommandReset, "CancelCommand": models.CommandCancel, - "Username": bot.Bot.Self.Username, + "Username": bot.Bot.Username, }), ) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.MenuKeyboard(T) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.MenuKeyboard(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) diff --git a/internal/commands/reset.go b/internal/commands/reset.go index 6ddccee..f5e4cb4 100644 --- a/internal/commands/reset.go +++ b/internal/commands/reset.go @@ -1,47 +1,47 @@ package commands import ( - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Reset prepare user to reset his pack func Reset(msg *tg.Message) { - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) - _, total, err := db.UserStickers(msg.From.ID, 0, "") + stickers, err := db.DB.GetUserStickers(msg.From, &tg.InlineQuery{}) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) errors.Check(err) - if total <= 0 { - err = db.ChangeUserState(msg.From.ID, models.StateNone) + if len(stickers) <= 0 { + err = db.DB.ChangeUserState(msg.From, models.StateNone) errors.Check(err) - reply := tg.NewMessage(msg.Chat.ID, T("error_already_reset")) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.MenuKeyboard(T) + reply := tg.NewMessage(msg.Chat.ID, t("error_already_reset")) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.MenuKeyboard(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) return } - err = db.ChangeUserState(msg.From.ID, models.StateReset) + err = db.DB.ChangeUserState(msg.From, models.StateReset) errors.Check(err) - reply := tg.NewMessage(msg.Chat.ID, T("reply_reset", map[string]interface{}{ - "KeyPhrase": T("key_phrase"), + reply := tg.NewMessage(msg.Chat.ID, t("reply_reset", map[string]interface{}{ + "KeyPhrase": t("key_phrase"), "CancelCommand": models.CommandCancel, })) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.CancelButton(T) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.CancelButton(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) } diff --git a/internal/commands/start.go b/internal/commands/start.go index cccbfdb..d64650a 100644 --- a/internal/commands/start.go +++ b/internal/commands/start.go @@ -4,18 +4,18 @@ import ( "strings" log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // Start just send introduction about bot to user func Start(msg *tg.Message) { - err := db.ChangeUserState(msg.From.ID, models.StateNone) + err := db.DB.ChangeUserState(msg.From, models.StateNone) errors.Check(err) _, err = bot.Bot.SendChatAction(msg.Chat.ID, tg.ActionTyping) @@ -23,24 +23,24 @@ func Start(msg *tg.Message) { if msg.HasCommandArgument() { log.Ln("Received a", msg.Command(), "command with", msg.CommandArgument(), "argument") - if strings.EqualFold(msg.CommandArgument(), models.CommandHelp) { + if strings.EqualFold(msg.CommandArgument(), tg.CommandHelp) { Help(msg) return } } - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) reply := tg.NewMessage( msg.Chat.ID, - T("reply_start", map[string]interface{}{ - "Username": bot.Bot.Self.Username, - "ID": bot.Bot.Self.ID, + t("reply_start", map[string]interface{}{ + "Username": bot.Bot.Username, + "ID": bot.Bot.ID, }), ) - reply.ParseMode = tg.ModeMarkdown - reply.ReplyMarkup = helpers.MenuKeyboard(T) + reply.ParseMode = tg.StyleMarkdown + reply.ReplyMarkup = utils.MenuKeyboard(t) _, err = bot.Bot.SendMessage(reply) errors.Check(err) diff --git a/internal/config/open.go b/internal/config/open.go index dc23ef7..2320e1f 100644 --- a/internal/config/open.go +++ b/internal/config/open.go @@ -1,23 +1,17 @@ package config -import ( - "github.com/olebedev/config" - "github.com/toby3d/MyPackBot/internal/errors" -) +import "github.com/spf13/viper" -var ( - // Config is a main object of preloaded configuration YAML - Config *config.Config - - // ChannelID is a announcements channel ID - ChannelID int64 -) +var Config *viper.Viper // Open just open configuration file for parsing some data in other functions -func Open(path string) { - var err error - Config, err = config.ParseYamlFile(path) - errors.Check(err) +func Open(path string) (*viper.Viper, error) { + cfg := viper.New() - ChannelID = int64(Config.UInt("telegram.channel")) + cfg.AddConfigPath(path) + cfg.SetConfigName("config") + cfg.SetConfigType("yaml") + + err := cfg.ReadInConfig() + return cfg, err } diff --git a/internal/db/add_sticker.go b/internal/db/add_sticker.go index 7680aee..e9c9887 100644 --- a/internal/db/add_sticker.go +++ b/internal/db/add_sticker.go @@ -5,23 +5,24 @@ import ( log "github.com/kirillDanshin/dlog" "github.com/tidwall/buntdb" - "github.com/toby3d/MyPackBot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/models" + tg "gitlab.com/toby3d/telegram" ) // AddSticker add sticker FileID, Emoji and SetName meta for UserID -func AddSticker(userID int, setName, fileID, emoji string) (bool, error) { - log.Ln("Trying to add", fileID, "sticker from", userID, "user") - if setName == "" { - setName = models.SetUploaded +func (db *DataBase) AddSticker(user *tg.User, sticker *tg.Sticker) (bool, error) { + log.Ln("Trying to add", sticker.FileID, "sticker from", user.ID, "user") + if sticker.SetName == "" { + sticker.SetName = models.SetUploaded } var exists bool - err := DB.Update(func(tx *buntdb.Tx) error { + err := db.Update(func(tx *buntdb.Tx) error { var err error _, exists, err = tx.Set( - fmt.Sprint("user:", userID, ":set:", setName, ":sticker:", fileID), // key - emoji, // value - nil, // options + fmt.Sprint("user:", user.ID, ":set:", sticker.SetName, ":sticker:", sticker.FileID), // key + sticker.Emoji, // value + nil, // options ) if err == buntdb.ErrIndexExists { exists = true diff --git a/internal/db/change_user_state.go b/internal/db/change_user_state.go index 3ab9442..b6113a8 100644 --- a/internal/db/change_user_state.go +++ b/internal/db/change_user_state.go @@ -5,13 +5,14 @@ import ( log "github.com/kirillDanshin/dlog" "github.com/tidwall/buntdb" + tg "gitlab.com/toby3d/telegram" ) // ChangeUserState change current user state on input state. -func ChangeUserState(userID int, state string) error { - log.Ln("Trying to change", userID, "state to", state) - return DB.Update(func(tx *buntdb.Tx) error { - _, _, err := tx.Set(fmt.Sprint("user:", userID, ":state"), state, nil) +func (db *DataBase) ChangeUserState(user *tg.User, state string) error { + log.Ln("Trying to change", user.ID, "state to", state) + return db.Update(func(tx *buntdb.Tx) error { + _, _, err := tx.Set(fmt.Sprint("user:", user.ID, ":state"), state, nil) return err }) } diff --git a/internal/db/delete_pack.go b/internal/db/delete_pack.go index 310025d..0967fd5 100644 --- a/internal/db/delete_pack.go +++ b/internal/db/delete_pack.go @@ -6,43 +6,43 @@ import ( log "github.com/kirillDanshin/dlog" "github.com/tidwall/buntdb" - "github.com/toby3d/MyPackBot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/models" + tg "gitlab.com/toby3d/telegram" ) // DeletePack remove all keys for UserID which contains input SetName -func DeletePack(userID int, setName string) (bool, error) { - log.Ln("Trying to remove all", setName, "sticker from", userID, "user") - if setName == "" { - setName = models.SetUploaded +func (db *DataBase) DeletePack(user *tg.User, sticker *tg.Sticker) (bool, error) { + log.Ln("Trying to remove all", sticker.SetName, "sticker from", user.ID, "user") + if sticker.SetName == "" { + sticker.SetName = models.SetUploaded } - var fileIDs []string - err := DB.View(func(tx *buntdb.Tx) error { + var ids []string + err := db.View(func(tx *buntdb.Tx) error { return tx.AscendKeys( - fmt.Sprint("user:", userID, ":set:", setName, ":*"), + fmt.Sprint("user:", user.ID, ":set:", sticker.SetName, ":*"), func(key, val string) bool { keys := strings.Split(key, ":") - fileIDs = append(fileIDs, keys[5]) + ids = append(ids, keys[5]) return true }, ) }) - if len(fileIDs) == 0 { + if len(ids) == 0 { return true, nil } - for _, fileID := range fileIDs { + for _, id := range ids { var notExist bool - notExist, err = DeleteSticker(userID, setName, fileID) + notExist, err = db.DeleteSticker(user, &tg.Sticker{FileID: id}) if err != nil { return notExist, err } } - switch err { - case buntdb.ErrNotFound: - log.Ln(userID, "not found") + if err == buntdb.ErrNotFound { + log.Ln(user.ID, "not found") return true, nil } diff --git a/internal/db/delete_sticker.go b/internal/db/delete_sticker.go index 4b982be..8dbcdc1 100644 --- a/internal/db/delete_sticker.go +++ b/internal/db/delete_sticker.go @@ -5,25 +5,25 @@ import ( log "github.com/kirillDanshin/dlog" "github.com/tidwall/buntdb" - "github.com/toby3d/MyPackBot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/models" + tg "gitlab.com/toby3d/telegram" ) // DeleteSticker just remove specified sticker key from database. -func DeleteSticker(userID int, setName, fileID string) (bool, error) { - log.Ln("Trying to remove", fileID, "sticker from", userID, "user") - if setName == "" { - setName = models.SetUploaded +func (db *DataBase) DeleteSticker(user *tg.User, sticker *tg.Sticker) (bool, error) { + log.Ln("Trying to remove", sticker.FileID, "sticker from", user.ID, "user") + if sticker.SetName == "" { + sticker.SetName = models.SetUploaded } - err := DB.Update(func(tx *buntdb.Tx) error { + err := db.Update(func(tx *buntdb.Tx) error { _, err := tx.Delete( - fmt.Sprint("user:", userID, ":set:", setName, ":sticker:", fileID), + fmt.Sprint("user:", user.ID, ":set:", sticker.SetName, ":sticker:", sticker.FileID), ) return err }) - if err == buntdb.ErrNotFound { - log.Ln(userID, "not found, create new one") + log.Ln(user.ID, "not found, create new one") return true, nil } diff --git a/internal/db/get_user_state.go b/internal/db/get_user_state.go new file mode 100644 index 0000000..cfd8aab --- /dev/null +++ b/internal/db/get_user_state.go @@ -0,0 +1,29 @@ +package db + +import ( + "fmt" + + log "github.com/kirillDanshin/dlog" + "github.com/tidwall/buntdb" + "gitlab.com/toby3d/mypackbot/internal/models" + tg "gitlab.com/toby3d/telegram" +) + +// UserState return current state for UserID +func (db *DataBase) GetUserState(user *tg.User) (string, error) { + log.Ln("Trying to get", user.ID, "state") + var state string + err := db.View(func(tx *buntdb.Tx) error { + var err error + state, err = tx.Get(fmt.Sprint("user:", user.ID, ":state")) + return err + }) + if err == buntdb.ErrNotFound { + log.Ln(user.ID, "not found, create new one") + if err = db.ChangeUserState(user, models.StateNone); err != nil { + return state, err + } + } + + return state, err +} diff --git a/internal/db/get_user_stickers.go b/internal/db/get_user_stickers.go new file mode 100644 index 0000000..9087583 --- /dev/null +++ b/internal/db/get_user_stickers.go @@ -0,0 +1,55 @@ +package db + +import ( + "fmt" + "strconv" + "strings" + + log "github.com/kirillDanshin/dlog" + "github.com/tidwall/buntdb" + tg "gitlab.com/toby3d/telegram" +) + +// GetUserStickers return array of saved stickers for input UserID and his total count +func (db *DataBase) GetUserStickers(user *tg.User, query *tg.InlineQuery) ([]string, error) { + log.Ln("Trying to get", user.ID, "stickers") + var i int + var stickers []string + offset, _ := strconv.Atoi(query.Offset) + offset *= 50 + + err := db.View(func(tx *buntdb.Tx) error { + return tx.AscendKeys( + fmt.Sprint("user:", user.ID, ":set:*"), // index + func(key, val string) bool { // iterator + subKeys := strings.Split(key, ":") + if subKeys[1] != strconv.Itoa(user.ID) { + return true + } + + if len(stickers) == 50 { + return false + } + + i++ + if i < offset { + return true + } + + if query.Query != "" && !strings.Contains(query.Query, val) { + return true + } + + stickers = append(stickers, subKeys[5]) + return true + }, + ) + }) + + if err == buntdb.ErrNotFound { + log.Ln("Not found stickers") + return nil, nil + } + + return stickers, err +} diff --git a/internal/db/users.go b/internal/db/get_users.go similarity index 74% rename from internal/db/users.go rename to internal/db/get_users.go index 2a9b443..a6165a5 100644 --- a/internal/db/users.go +++ b/internal/db/get_users.go @@ -8,10 +8,10 @@ import ( "github.com/tidwall/buntdb" ) -// Users return array of all available UserID in database -func Users() ([]int, error) { +// GetUsers return array of all available UserID in database +func (db *DataBase) GetUsers() ([]int, error) { var users []int - err := DB.View(func(tx *buntdb.Tx) error { + err := db.View(func(tx *buntdb.Tx) error { return tx.AscendKeys( "user:*:state", func(key, val string) bool { diff --git a/internal/db/open.go b/internal/db/open.go index 8e207f1..ecc0749 100644 --- a/internal/db/open.go +++ b/internal/db/open.go @@ -3,18 +3,16 @@ package db import ( log "github.com/kirillDanshin/dlog" "github.com/tidwall/buntdb" - "github.com/toby3d/MyPackBot/internal/errors" ) +type DataBase struct{ *buntdb.DB } + // DB is a main object of current database connection -var DB *buntdb.DB +var DB *DataBase // Open just open connection to database for work -func Open(path string) { +func Open(path string) (*DataBase, error) { log.Ln("Open database file...") - go func() { - var err error - DB, err = buntdb.Open(path) - errors.Check(err) - }() + db, err := buntdb.Open(path) + return &DataBase{db}, err } diff --git a/internal/db/reset.go b/internal/db/reset.go index 6789810..64e9712 100644 --- a/internal/db/reset.go +++ b/internal/db/reset.go @@ -7,18 +7,19 @@ import ( log "github.com/kirillDanshin/dlog" "github.com/tidwall/buntdb" + tg "gitlab.com/toby3d/telegram" ) // ResetUser just drop out all stickers keys for input UserID -func ResetUser(userID int) error { - log.Ln("Trying reset all stickers of", userID, "user") - return DB.Update(func(tx *buntdb.Tx) error { +func (db *DataBase) ResetUser(user *tg.User) error { + log.Ln("Trying reset all stickers of", user.ID, "user") + return db.Update(func(tx *buntdb.Tx) error { var keys []string if err := tx.AscendKeys( - fmt.Sprint("user:", userID, ":set:*"), // index + fmt.Sprint("user:", user.ID, ":set:*"), // index func(key, val string) bool { // iterator subKeys := strings.Split(key, ":") - if subKeys[1] == strconv.Itoa(userID) { + if subKeys[1] == strconv.Itoa(user.ID) { keys = append(keys, key) } return true diff --git a/internal/db/user_state.go b/internal/db/user_state.go index 6eec82b..6123c5f 100644 --- a/internal/db/user_state.go +++ b/internal/db/user_state.go @@ -5,23 +5,23 @@ import ( log "github.com/kirillDanshin/dlog" "github.com/tidwall/buntdb" - "github.com/toby3d/MyPackBot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/models" + tg "gitlab.com/toby3d/telegram" ) // UserState return current state for UserID -func UserState(userID int) (string, error) { - log.Ln("Trying to get", userID, "state") +func (db *DataBase) UserState(usr *tg.User) (string, error) { + log.Ln("Trying to get", usr.ID, "state") var state string err := DB.View(func(tx *buntdb.Tx) error { var err error - state, err = tx.Get(fmt.Sprint("user:", userID, ":state")) + state, err = tx.Get(fmt.Sprint("user:", usr.ID, ":state")) return err }) - switch err { - case buntdb.ErrNotFound: - log.Ln(userID, "not found, create new one") - if err = ChangeUserState(userID, models.StateNone); err != nil { + if err == buntdb.ErrNotFound { + log.Ln(usr.ID, "not found, create new one") + if err = db.ChangeUserState(usr, models.StateNone); err != nil { return state, err } } diff --git a/internal/db/user_stickers.go b/internal/db/user_stickers.go deleted file mode 100644 index 83ba13f..0000000 --- a/internal/db/user_stickers.go +++ /dev/null @@ -1,54 +0,0 @@ -package db - -import ( - "fmt" - "strconv" - "strings" - - log "github.com/kirillDanshin/dlog" - "github.com/tidwall/buntdb" -) - -// UserStickers return array of saved stickers for input UserID and his total count -func UserStickers(userID, offset int, query string) ([]string, int, error) { - log.Ln("Trying to get", userID, "stickers") - var total, count int - var stickers []string - offset = offset * 50 - - err := DB.View(func(tx *buntdb.Tx) error { - return tx.AscendKeys( - fmt.Sprint("user:", userID, ":set:*"), // index - func(key, val string) bool { // iterator - subKeys := strings.Split(key, ":") - if subKeys[1] != strconv.Itoa(userID) { - return true - } - - total++ - if count >= 51 { - return true - } - - if total < offset { - return true - } - - if query != "" && !strings.Contains(query, val) { - return true - } - - count++ - stickers = append(stickers, subKeys[5]) - return true - }, - ) - }) - - if err == buntdb.ErrNotFound { - log.Ln("Not found stickers") - return nil, total, nil - } - - return stickers, total, err -} diff --git a/internal/helpers/menu_keyboard.go b/internal/helpers/menu_keyboard.go deleted file mode 100644 index 070f8b6..0000000 --- a/internal/helpers/menu_keyboard.go +++ /dev/null @@ -1,23 +0,0 @@ -package helpers - -import ( - "github.com/nicksnyder/go-i18n/i18n" - tg "github.com/toby3d/telegram" -) - -// MenuKeyboard helper just generate ReplyMarkup with menu buttons -func MenuKeyboard(T i18n.TranslateFunc) *tg.ReplyKeyboardMarkup { - return tg.NewReplyKeyboardMarkup( - tg.NewReplyKeyboardRow( - tg.NewReplyKeyboardButton(T("button_add_sticker")), - tg.NewReplyKeyboardButton(T("button_add_pack")), - ), - tg.NewReplyKeyboardRow( - tg.NewReplyKeyboardButton(T("button_del_sticker")), - tg.NewReplyKeyboardButton(T("button_del_pack")), - ), - tg.NewReplyKeyboardRow( - tg.NewReplyKeyboardButton(T("button_reset")), - ), - ) -} diff --git a/internal/i18n/switch_to.go b/internal/i18n/switch_to.go index 1a3023c..f5f5e2c 100644 --- a/internal/i18n/switch_to.go +++ b/internal/i18n/switch_to.go @@ -2,12 +2,12 @@ package i18n import ( "github.com/nicksnyder/go-i18n/i18n" - "github.com/toby3d/MyPackBot/internal/models" + "gitlab.com/toby3d/mypackbot/internal/models" ) // SwitchTo try load locales by input language codes and return TranslateFunc -func SwitchTo(codes ...string) (T i18n.TranslateFunc, err error) { +func SwitchTo(codes ...string) (t i18n.TranslateFunc, err error) { codes = append(codes, models.LanguageFallback) - T, err = i18n.Tfunc(codes[0], codes[1:]...) + t, err = i18n.Tfunc(codes[0], codes[1:]...) return } diff --git a/internal/messages/message.go b/internal/messages/message.go index ba2ee12..0061a91 100644 --- a/internal/messages/message.go +++ b/internal/messages/message.go @@ -3,31 +3,31 @@ package messages import ( "strings" - "github.com/toby3d/MyPackBot/internal/actions" - "github.com/toby3d/MyPackBot/internal/commands" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/i18n" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/actions" + "gitlab.com/toby3d/mypackbot/internal/commands" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + tg "gitlab.com/toby3d/telegram" ) // Message checks user message on response, stickers, reset key phrase, else do // Actions func Message(msg *tg.Message) { - T, err := i18n.SwitchTo(msg.From.LanguageCode) + t, err := i18n.SwitchTo(msg.From.LanguageCode) errors.Check(err) switch { - case strings.EqualFold(msg.Text, T("button_add_sticker")): + case strings.EqualFold(msg.Text, t("button_add_sticker")): commands.Add(msg, false) - case strings.EqualFold(msg.Text, T("button_add_pack")): + case strings.EqualFold(msg.Text, t("button_add_pack")): commands.Add(msg, true) - case strings.EqualFold(msg.Text, T("button_del_sticker")): + case strings.EqualFold(msg.Text, t("button_del_sticker")): commands.Delete(msg, false) - case strings.EqualFold(msg.Text, T("button_del_pack")): + case strings.EqualFold(msg.Text, t("button_del_pack")): commands.Delete(msg, true) - case strings.EqualFold(msg.Text, T("button_reset")): + case strings.EqualFold(msg.Text, t("button_reset")): commands.Reset(msg) - case strings.EqualFold(msg.Text, T("button_cancel")): + case strings.EqualFold(msg.Text, t("button_cancel")): commands.Cancel(msg) default: actions.Action(msg) diff --git a/internal/models/models.go b/internal/models/models.go index 66625b7..e7d0264 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -1,17 +1,15 @@ package models -import tg "github.com/toby3d/telegram" +import tg "gitlab.com/toby3d/telegram" // Commands... represents available and supported bot commands const ( CommandAddPack = "addPack" CommandAddSticker = "addSticker" CommandCancel = "cancel" - CommandHelp = "help" CommandDeleteSticker = "delSticker" CommandDeletePack = "delPack" CommandReset = "reset" - CommandStart = "start" ) // State... represents current state of user action diff --git a/internal/updates/channel.go b/internal/updates/channel.go index c7e9916..876235d 100644 --- a/internal/updates/channel.go +++ b/internal/updates/channel.go @@ -2,63 +2,67 @@ package updates import ( "fmt" + "net/url" log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/config" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/config" + "gitlab.com/toby3d/mypackbot/internal/models" + tg "gitlab.com/toby3d/telegram" ) // Channel return webhook or long polling channel with bot updates -func Channel(webhookMode bool) tg.UpdatesChannel { +func Channel(webhookMode bool) (updates tg.UpdatesChannel, err error) { log.Ln("Preparing channel for updates...") if !webhookMode { log.Ln("Use LongPolling updates") - info, err := bot.Bot.GetWebhookInfo() - errors.Check(err) + var info *tg.WebhookInfo + info, err = bot.Bot.GetWebhookInfo() + if err != nil { + return + } if info.URL != "" { log.Ln("Deleting webhook...") - _, err := bot.Bot.DeleteWebhook() - errors.Check(err) + _, err = bot.Bot.DeleteWebhook() + return } - return bot.Bot.NewLongPollingChannel(&tg.GetUpdatesParameters{ + updates = bot.Bot.NewLongPollingChannel(&tg.GetUpdatesParameters{ Offset: 0, Limit: 100, Timeout: 60, AllowedUpdates: models.AllowedUpdates, }) + return } - var err error - var set, listen, serve string - set, err = config.Config.String("telegram.webhook.set") - errors.Check(err) - listen, err = config.Config.String("telegram.webhook.listen") - errors.Check(err) - serve, err = config.Config.String("telegram.webhook.serve") - errors.Check(err) + set, err := url.Parse(config.Config.GetString("telegram.webhook.set")) + if err != nil { + return nil, err + } + + listen := config.Config.GetString("telegram.webhook.listen") + serve := config.Config.GetString("telegram.webhook.serve") log.Ln( "Trying set webhook on address:", - fmt.Sprint(set, listen, bot.Bot.AccessToken), + fmt.Sprint(set.String(), bot.Bot.AccessToken), ) log.Ln("Creating new webhook...") - webhook := tg.NewWebhook(fmt.Sprint(set, listen, bot.Bot.AccessToken), nil) - webhook.MaxConnections = 40 - webhook.AllowedUpdates = models.AllowedUpdates + params := tg.NewWebhook(fmt.Sprint(set, listen, bot.Bot.AccessToken), nil) + params.MaxConnections = 40 + params.AllowedUpdates = models.AllowedUpdates - return bot.Bot.NewWebhookChannel( - webhook, // params - "", // certFile - "", // keyFile - set, // set - fmt.Sprint(listen, bot.Bot.AccessToken), // listen - serve, // serve + updates = bot.Bot.NewWebhookChannel( + set, + params, // params + "", // certFile + "", // keyFile + serve, // serve ) + + return } diff --git a/internal/updates/channel_post.go b/internal/updates/channel_post.go index 8ce302c..c280f55 100644 --- a/internal/updates/channel_post.go +++ b/internal/updates/channel_post.go @@ -4,21 +4,22 @@ import ( "time" log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/config" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/config" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + tg "gitlab.com/toby3d/telegram" ) // ChannelPost checks ChannelPost update for forwarding content to bot users func ChannelPost(post *tg.Message) { - if post.Chat.ID != config.ChannelID { - log.Ln(post.Chat.ID, "!=", config.ChannelID) + channelID := config.Config.GetInt64("telegram.channel") + if post.Chat.ID != channelID { + log.Ln(post.Chat.ID, "!=", channelID) return } - users, err := db.Users() + users, err := db.DB.GetUsers() errors.Check(err) for i := range users { diff --git a/internal/updates/inline_query.go b/internal/updates/inline_query.go index c52abcb..f4ed3c0 100755 --- a/internal/updates/inline_query.go +++ b/internal/updates/inline_query.go @@ -4,23 +4,22 @@ import ( "strconv" log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/db" - "github.com/toby3d/MyPackBot/internal/errors" - "github.com/toby3d/MyPackBot/internal/helpers" - "github.com/toby3d/MyPackBot/internal/i18n" - "github.com/toby3d/MyPackBot/internal/models" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/utils" + tg "gitlab.com/toby3d/telegram" ) // InlineQuery checks InlineQuery updates for answer with personal results func InlineQuery(inlineQuery *tg.InlineQuery) { - fixedQuery, err := helpers.FixEmoji(inlineQuery.Query) + fixedQuery, err := utils.FixEmoji(inlineQuery.Query) if err == nil { inlineQuery.Query = fixedQuery } - answer := &tg.AnswerInlineQueryParameters{} + answer := new(tg.AnswerInlineQueryParameters) answer.InlineQueryID = inlineQuery.ID answer.CacheTime = 1 answer.IsPersonal = true @@ -32,7 +31,7 @@ func InlineQuery(inlineQuery *tg.InlineQuery) { } log.Ln("Let's preparing answer...") - T, err := i18n.SwitchTo(inlineQuery.From.LanguageCode) + t, err := i18n.SwitchTo(inlineQuery.From.LanguageCode) errors.Check(err) log.Ln("INLINE OFFSET:", inlineQuery.Offset) @@ -43,51 +42,40 @@ func InlineQuery(inlineQuery *tg.InlineQuery) { errors.Check(err) offset++ - stickers, packSize, err := db.UserStickers( - inlineQuery.From.ID, offset, inlineQuery.Query, + stickers, err := db.DB.GetUserStickers( + inlineQuery.From, + &tg.InlineQuery{ + Offset: strconv.Itoa(offset), + Query: inlineQuery.Query, + }, ) errors.Check(err) - totalStickers := len(stickers) - if totalStickers == 0 { - if offset == 0 { - if inlineQuery.Query != "" { - // If search stickers by emoji return 0 results - answer.SwitchPrivateMessageText = T( - "button_inline_nothing", map[string]interface{}{ - "Query": inlineQuery.Query, - }, - ) - answer.SwitchPrivateMessageParameter = models.CommandAddSticker - } else { - // If query is empty and get 0 stickers - answer.SwitchPrivateMessageText = T("button_inline_empty") - answer.SwitchPrivateMessageParameter = models.CommandAddSticker - } - answer.Results = nil + if len(stickers) == 0 { + if offset == 0 && inlineQuery.Query != "" { + // If search stickers by emoji return 0 results + answer.SwitchPrivateMessageText = t( + "button_inline_nothing", map[string]interface{}{ + "Query": inlineQuery.Query, + }, + ) + + answer.SwitchPrivateMessageParameter = tg.CommandHelp } + + answer.Results = nil } else { - log.Ln("STICKERS FROM REQUEST:", totalStickers) - if totalStickers > 50 { + log.Ln("STICKERS FROM REQUEST:", len(stickers)) + if len(stickers) == 50 { answer.NextOffset = strconv.Itoa(offset) log.Ln("NEXT OFFSET:", answer.NextOffset) - - stickers = stickers[:totalStickers-1] } - log.Ln("Stickers after checks:", len(stickers)) - var results = make([]interface{}, len(stickers)) for i, sticker := range stickers { results[i] = tg.NewInlineQueryResultCachedSticker(sticker, sticker) } - answer.SwitchPrivateMessageText = T( - "button_inline_search", packSize, map[string]interface{}{ - "Count": packSize, - }, - ) - answer.SwitchPrivateMessageParameter = models.CommandHelp answer.Results = results } diff --git a/internal/updates/message.go b/internal/updates/message.go index d15f9aa..b67a214 100644 --- a/internal/updates/message.go +++ b/internal/updates/message.go @@ -2,11 +2,11 @@ package updates import ( log "github.com/kirillDanshin/dlog" - "github.com/toby3d/MyPackBot/internal/actions" - "github.com/toby3d/MyPackBot/internal/bot" - "github.com/toby3d/MyPackBot/internal/commands" - "github.com/toby3d/MyPackBot/internal/messages" - tg "github.com/toby3d/telegram" + "gitlab.com/toby3d/mypackbot/internal/actions" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/commands" + "gitlab.com/toby3d/mypackbot/internal/messages" + tg "gitlab.com/toby3d/telegram" ) // Message checks Message updates for answer to user commands, replies or sended diff --git a/internal/helpers/cancel_button.go b/internal/utils/cancel_button.go similarity index 54% rename from internal/helpers/cancel_button.go rename to internal/utils/cancel_button.go index a621e4a..7e5a6fc 100644 --- a/internal/helpers/cancel_button.go +++ b/internal/utils/cancel_button.go @@ -1,15 +1,15 @@ -package helpers +package utils import ( "github.com/nicksnyder/go-i18n/i18n" - tg "github.com/toby3d/telegram" + tg "gitlab.com/toby3d/telegram" ) // CancelButton helper just generate ReplyMarkup with cancel button -func CancelButton(T i18n.TranslateFunc) *tg.ReplyKeyboardMarkup { +func CancelButton(t i18n.TranslateFunc) *tg.ReplyKeyboardMarkup { return tg.NewReplyKeyboardMarkup( tg.NewReplyKeyboardRow( - tg.NewReplyKeyboardButton(T("button_cancel")), + tg.NewReplyKeyboardButton(t("button_cancel")), ), ) } diff --git a/internal/helpers/fix_emoji.go b/internal/utils/fix_emoji.go similarity index 97% rename from internal/helpers/fix_emoji.go rename to internal/utils/fix_emoji.go index 69bcd7c..efc9823 100644 --- a/internal/helpers/fix_emoji.go +++ b/internal/utils/fix_emoji.go @@ -1,4 +1,4 @@ -package helpers +package utils import ( "golang.org/x/text/runes" diff --git a/internal/utils/menu_keyboard.go b/internal/utils/menu_keyboard.go new file mode 100644 index 0000000..134eea9 --- /dev/null +++ b/internal/utils/menu_keyboard.go @@ -0,0 +1,23 @@ +package utils + +import ( + "github.com/nicksnyder/go-i18n/i18n" + tg "gitlab.com/toby3d/telegram" +) + +// MenuKeyboard helper just generate ReplyMarkup with menu buttons +func MenuKeyboard(t i18n.TranslateFunc) *tg.ReplyKeyboardMarkup { + return tg.NewReplyKeyboardMarkup( + tg.NewReplyKeyboardRow( + tg.NewReplyKeyboardButton(t("button_add_sticker")), + tg.NewReplyKeyboardButton(t("button_add_pack")), + ), + tg.NewReplyKeyboardRow( + tg.NewReplyKeyboardButton(t("button_del_sticker")), + tg.NewReplyKeyboardButton(t("button_del_pack")), + ), + tg.NewReplyKeyboardRow( + tg.NewReplyKeyboardButton(t("button_reset")), + ), + ) +} diff --git a/internal/helpers/switch_button.go b/internal/utils/switch_button.go similarity index 54% rename from internal/helpers/switch_button.go rename to internal/utils/switch_button.go index 4631f8d..342b032 100644 --- a/internal/helpers/switch_button.go +++ b/internal/utils/switch_button.go @@ -1,15 +1,15 @@ -package helpers +package utils import ( "github.com/nicksnyder/go-i18n/i18n" - tg "github.com/toby3d/telegram" + tg "gitlab.com/toby3d/telegram" ) // SwitchButton helper just generate ReplyMarkup with SelfSwitch button -func SwitchButton(T i18n.TranslateFunc) *tg.InlineKeyboardMarkup { +func SwitchButton(t i18n.TranslateFunc) *tg.InlineKeyboardMarkup { return tg.NewInlineKeyboardMarkup( tg.NewInlineKeyboardRow( - tg.NewInlineKeyboardButtonSwitchSelf(T("button_inline_select"), " "), + tg.NewInlineKeyboardButtonSwitchSelf(t("button_inline_select"), " "), ), ) } diff --git a/main.go b/main.go index 8d5340b..4a8ec74 100644 --- a/main.go +++ b/main.go @@ -4,8 +4,12 @@ import ( "flag" log "github.com/kirillDanshin/dlog" - _ "github.com/toby3d/MyPackBot/init" - "github.com/toby3d/MyPackBot/internal/updates" + "gitlab.com/toby3d/mypackbot/internal/bot" + "gitlab.com/toby3d/mypackbot/internal/config" + "gitlab.com/toby3d/mypackbot/internal/db" + "gitlab.com/toby3d/mypackbot/internal/errors" + "gitlab.com/toby3d/mypackbot/internal/i18n" + "gitlab.com/toby3d/mypackbot/internal/updates" ) var flagWebhook = flag.Bool( @@ -13,11 +17,33 @@ var flagWebhook = flag.Bool( "enable work via webhooks (required valid certificates)", ) +// init prepare configuration and other things for successful start +func init() { + log.Ln("Initializing...") + + // Preload localization strings + err := i18n.Open("i18n/") + errors.Check(err) + + // Preload configuration file + config.Open("configs/config.yaml") + + // Open database or create new one + db.Open("stickers.db") + + // Create bot with credentials from config + bot.Bot, err = bot.New(config.Config.GetString("telegram.token")) + errors.Check(err) +} + // main function is a general function for work of this bot func main() { flag.Parse() // Parse flagWebhook - for update := range updates.Channel(*flagWebhook) { + channel, err := updates.Channel(*flagWebhook) + errors.Check(err) + + for update := range channel { log.D(update) switch { case update.IsInlineQuery():