♻️ Refactoring code due new telegram package changes

This commit is contained in:
Maxim Lebedev 2018-04-19 20:16:17 +05:00
parent 638dd0f6b6
commit ade07764c0
No known key found for this signature in database
GPG Key ID: F8978F46FF0FFA4F
28 changed files with 153 additions and 164 deletions

View File

@ -12,17 +12,21 @@ import (
// init prepare configuration and other things for successful start
func init() {
log.Ln("Initializing...")
// Preload localization strings
err := i18n.Open("i18n/")
errors.Check(err)
var err error
// Preload configuration file
config.Open("configs/config.yaml")
config.Config, err = config.Open("./configs")
errors.Check(err)
// Preload localization strings
err = i18n.Open("i18n/")
errors.Check(err)
// Open database or create new one
db.Open("stickers.db")
db.DB, err = db.Open("stickers.db")
errors.Check(err)
// Create bot with credentials from config
bot.New()
bot.Bot, err = bot.New(config.Config.GetString("telegram.token"))
errors.Check(err)
}

View File

@ -11,7 +11,7 @@ import (
// 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)

View File

@ -29,9 +29,7 @@ func Add(msg *tg.Message, pack bool) {
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 {
@ -61,9 +59,7 @@ func Add(msg *tg.Message, pack bool) {
allExists := true
for _, sticker := 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, &sticker)
errors.Check(err)
if !exist {

View File

@ -37,16 +37,12 @@ func Delete(msg *tg.Message, pack bool) {
"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")
}
} 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")
}

View File

@ -17,7 +17,7 @@ func Reset(msg *tg.Message) {
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)
@ -33,7 +33,7 @@ func Reset(msg *tg.Message) {
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"))

View File

@ -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 "github.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) (*tg.Bot, error) {
return tg.New(accessToken)
}

View File

@ -23,13 +23,13 @@ func Add(msg *tg.Message, pack bool) {
reply.ParseMode = tg.ModeMarkdown
reply.ReplyMarkup = helpers.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")
err = db.ChangeUserState(msg.From.ID, models.StateAddPack)
err = db.DB.ChangeUserState(msg.From, models.StateAddPack)
errors.Check(err)
}

View File

@ -15,7 +15,7 @@ func Cancel(msg *tg.Message) {
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)
@ -37,7 +37,7 @@ func Cancel(msg *tg.Message) {
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)

View File

@ -10,21 +10,21 @@ import (
func Command(msg *tg.Message) {
log.Ln("command:", msg.Command())
switch {
case msg.IsCommand(models.CommandStart):
case msg.IsCommandEqual(models.CommandStart):
Start(msg)
case msg.IsCommand(models.CommandHelp):
case msg.IsCommandEqual(models.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)
}
}

View File

@ -15,14 +15,14 @@ func Delete(msg *tg.Message, pack bool) {
T, err := i18n.SwitchTo(msg.From.LanguageCode)
errors.Check(err)
stickers, err := db.GetUserStickers(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 len(stickers) <= 0 {
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, T("error_empty_del"))
@ -36,11 +36,11 @@ func Delete(msg *tg.Message, pack bool) {
reply.ParseMode = tg.ModeMarkdown
reply.ReplyMarkup = helpers.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")

View File

@ -15,7 +15,7 @@ func Help(msg *tg.Message) {
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)
@ -29,7 +29,7 @@ func Help(msg *tg.Message) {
"DeletePackCommand": models.CommandDeletePack,
"ResetCommand": models.CommandReset,
"CancelCommand": models.CommandCancel,
"Username": bot.Bot.Self.Username,
"Username": bot.Bot.Username,
}),
)
reply.ParseMode = tg.ModeMarkdown

View File

@ -15,14 +15,14 @@ func Reset(msg *tg.Message) {
T, err := i18n.SwitchTo(msg.From.LanguageCode)
errors.Check(err)
stickers, err := db.GetUserStickers(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 len(stickers) <= 0 {
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, T("error_already_reset"))
@ -33,7 +33,7 @@ func Reset(msg *tg.Message) {
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{}{

View File

@ -15,7 +15,7 @@ import (
// 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)
@ -35,8 +35,8 @@ func Start(msg *tg.Message) {
reply := tg.NewMessage(
msg.Chat.ID,
T("reply_start", map[string]interface{}{
"Username": bot.Bot.Self.Username,
"ID": bot.Bot.Self.ID,
"Username": bot.Bot.Username,
"ID": bot.Bot.ID,
}),
)
reply.ParseMode = tg.ModeMarkdown

View File

@ -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
}

View File

@ -6,22 +6,23 @@ import (
log "github.com/kirillDanshin/dlog"
"github.com/tidwall/buntdb"
"github.com/toby3d/MyPackBot/internal/models"
tg "github.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

View File

@ -5,13 +5,14 @@ import (
log "github.com/kirillDanshin/dlog"
"github.com/tidwall/buntdb"
tg "github.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
})
}

View File

@ -7,19 +7,20 @@ import (
log "github.com/kirillDanshin/dlog"
"github.com/tidwall/buntdb"
"github.com/toby3d/MyPackBot/internal/models"
tg "github.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 ids []string
err := DB.View(func(tx *buntdb.Tx) error {
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, ":")
ids = append(ids, keys[5])
@ -32,9 +33,9 @@ func DeletePack(userID int, setName string) (bool, error) {
return true, nil
}
for _, fileID := range ids {
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
}
@ -42,7 +43,7 @@ func DeletePack(userID int, setName string) (bool, error) {
switch err {
case buntdb.ErrNotFound:
log.Ln(userID, "not found")
log.Ln(user.ID, "not found")
return true, nil
}

View File

@ -6,23 +6,24 @@ import (
log "github.com/kirillDanshin/dlog"
"github.com/tidwall/buntdb"
"github.com/toby3d/MyPackBot/internal/models"
tg "github.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
}

View File

@ -0,0 +1,29 @@
package db
import (
"fmt"
log "github.com/kirillDanshin/dlog"
"github.com/tidwall/buntdb"
"github.com/toby3d/MyPackBot/internal/models"
tg "github.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
}

View File

@ -7,21 +7,23 @@ import (
log "github.com/kirillDanshin/dlog"
"github.com/tidwall/buntdb"
tg "github.com/toby3d/telegram"
)
// GetUserStickers return array of saved stickers for input UserID and his total count
func GetUserStickers(userID, offset int, query string) ([]string, error) {
log.Ln("Trying to get", userID, "stickers")
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 {
err := db.View(func(tx *buntdb.Tx) error {
return 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) {
return true
}
@ -34,7 +36,7 @@ func GetUserStickers(userID, offset int, query string) ([]string, error) {
return true
}
if query != "" && !strings.Contains(query, val) {
if query.Query != "" && !strings.Contains(query.Query, val) {
return true
}

View File

@ -9,9 +9,9 @@ import (
)
// GetUsers return array of all available UserID in database
func GetUsers() ([]int, error) {
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 {

View File

@ -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
}

View File

@ -7,18 +7,19 @@ import (
log "github.com/kirillDanshin/dlog"
"github.com/tidwall/buntdb"
tg "github.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

View File

@ -1,28 +0,0 @@
package db
import (
"fmt"
log "github.com/kirillDanshin/dlog"
"github.com/tidwall/buntdb"
"github.com/toby3d/MyPackBot/internal/models"
)
// UserState return current state for UserID
func UserState(userID int) (string, error) {
log.Ln("Trying to get", userID, "state")
var state string
err := DB.View(func(tx *buntdb.Tx) error {
var err error
state, err = tx.Get(fmt.Sprint("user:", userID, ":state"))
return err
})
if err == buntdb.ErrNotFound {
log.Ln(userID, "not found, create new one")
if err = ChangeUserState(userID, models.StateNone); err != nil {
return state, err
}
}
return state, err
}

View File

@ -34,14 +34,9 @@ func Channel(webhookMode bool) tg.UpdatesChannel {
})
}
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 := config.Config.GetString("telegram.webhook.set")
listen := config.Config.GetString("telegram.webhook.listen")
serve := config.Config.GetString("telegram.webhook.serve")
log.Ln(
"Trying set webhook on address:",

View File

@ -13,12 +13,13 @@ import (
// 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.GetUsers()
users, err := db.DB.GetUsers()
errors.Check(err)
for i := range users {

View File

@ -43,8 +43,12 @@ func InlineQuery(inlineQuery *tg.InlineQuery) {
errors.Check(err)
offset++
stickers, err := db.GetUserStickers(
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)

View File

@ -16,6 +16,7 @@ var flagWebhook = flag.Bool(
// main function is a general function for work of this bot
func main() {
flag.Parse() // Parse flagWebhook
for update := range updates.Channel(*flagWebhook) {
log.D(update)
switch {