0

[WIP] MOAR linter fixes, also move init to tg lib

This commit is contained in:
eleksir
2025-11-09 12:25:51 +03:00
parent bb2425f404
commit ddcc8b1c87
12 changed files with 120 additions and 103 deletions

View File

@@ -5,7 +5,6 @@ import (
"fmt"
"os"
"os/signal"
"path/filepath"
"syscall"
"aleesa-telegram-go/internal/log"
@@ -15,48 +14,15 @@ import (
"github.com/go-redis/redis/v8"
)
// init производит некоторую инициализацию перед запуском main().
func init() {
var (
err error
)
executablePath, err := os.Executable()
if err != nil {
log.Fatalf("Unable to get current executable path: %s", err)
}
configJSONPath := filepath.Dir(executablePath) + "/data/config.json"
locations := []string{
"~/.aleesa-telegram-go.json",
"~/aleesa-telegram-go.json",
"/etc/aleesa-telegram-go.json",
configJSONPath,
}
for _, location := range locations {
tg.Config, err = tg.ParseConfig(location)
if err == nil {
break
}
log.Errorf("Unable to parse config at %s: %s", location, err)
}
if err != nil {
os.Exit(1)
}
}
func main() {
var (
logfile *os.File
err error
)
// Найдём и прочитаем конфиг.
tg.ReadConfig()
// Откроем лог и скормим его логгеру.
if tg.Config.Log != "" {
logfile, err = os.OpenFile(tg.Config.Log, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)

View File

@@ -1,4 +1,5 @@
package settingsmigrator
// main Импортирует настройки из файла settings.json в базу с настройками.
package main
import (
"fmt"

View File

@@ -21,47 +21,43 @@ func Admin(msg *echotron.Update) (bool, error) {
case c == "admin" || c == "админ":
answer = "```\n"
answer += fmt.Sprintf("%sadmin censor - показать список состояния типов сообщений\n", Config.Csign)
answer += fmt.Sprintf("%sадмин ценз - показать список состояния типов сообщений\n", Config.Csign)
answer += fmt.Sprintf("%sadmin censor type # - где 1 - вкл, 0 - выкл цензуры для означенного типа сообщений\n", Config.Csign)
answer += fmt.Sprintf("%sадмин ценз тип # - где 1 - вкл, 0 - выкл цензуры для означенного типа сообщений\n", Config.Csign)
answer += fmt.Sprintf("%sadmin fortune - показываем ли с утра фортунку для чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin фортунка - показываем ли с утра фортунку для чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin fortune # - где 1 - вкл, 0 - выкл фортунку с утра\n", Config.Csign)
answer += fmt.Sprintf("%sadmin фортунка # - где 1 - вкл, 0 - выкл фортунку с утра\n", Config.Csign)
answer += fmt.Sprintf("%sadmin greet - приветствуем ли новых участников чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin приветствие - приветствуем ли новых участников чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin greet # - где 1 - вкл, 0 - выкл приветствия новых участников чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin приветствие # - где 1 - вкл, 0 - выкл приветствия новых участников чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin goodbye - прощаемся ли с ушедшими участниками чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin прощание - прощаемся ли с ушедшими участниками чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin goodbye # - где 1 - вкл, 0 - выкл прощания с ушедшими участниками чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin прощание # - где 1 - вкл, 0 - выкл прощания с ушедшими участниками чата\n", Config.Csign)
answer += fmt.Sprintf("%sadmin oboobs # - где 1 - вкл, 0 - выкл плагина oboobs\n", Config.Csign)
answer += Config.Csign + "admin censor - показать список состояния типов сообщений\n"
answer += Config.Csign + "админ ценз - показать список состояния типов сообщений\n"
answer += Config.Csign + "admin censor type # - где 1 - вкл, 0 - выкл цензуры для означенного типа сообщений\n"
answer += Config.Csign + "админ ценз тип # - где 1 - вкл, 0 - выкл цензуры для означенного типа сообщений\n"
answer += Config.Csign + "admin fortune - показываем ли с утра фортунку для чата\n"
answer += Config.Csign + "admin фортунка - показываем ли с утра фортунку для чата\n"
answer += Config.Csign + "admin fortune # - где 1 - вкл, 0 - выкл фортунку с утра\n"
answer += Config.Csign + "admin фортунка # - где 1 - вкл, 0 - выкл фортунку с утра\n"
answer += Config.Csign + "admin greet - приветствуем ли новых участников чата\n"
answer += Config.Csign + "admin приветствие - приветствуем ли новых участников чата\n"
answer += Config.Csign + "admin greet # - где 1 - вкл, 0 - выкл приветствия новых участников чата\n"
answer += Config.Csign + "admin приветствие # - где 1 - вкл, 0 - выкл приветствия новых участников чата\n"
answer += Config.Csign + "admin goodbye - прощаемся ли с ушедшими участниками чата\n"
answer += Config.Csign + "admin прощание - прощаемся ли с ушедшими участниками чата\n"
answer += Config.Csign + "admin goodbye # - где 1 - вкл, 0 - выкл прощания с ушедшими участниками чата\n"
answer += Config.Csign + "admin прощание # - где 1 - вкл, 0 - выкл прощания с ушедшими участниками чата\n"
answer += Config.Csign + "admin oboobs # - где 1 - вкл, 0 - выкл плагина oboobs\n"
answer += fmt.Sprintf(
"%sadmin oboobs - показываем ли сисечки по просьбе участников чата (команды %stits, %stities, %sboobs, %sboobies, %sсиси, %sсисечки)\n",
Config.Csign, Config.Csign, Config.Csign, Config.Csign, Config.Csign, Config.Csign, Config.Csign,
)
answer += fmt.Sprintf("%sadmin obutts # - где 1 - вкл, 0 - выкл плагина obutts\n", Config.Csign)
answer += Config.Csign + "admin obutts # - где 1 - вкл, 0 - выкл плагина obutts\n"
answer += fmt.Sprintf(
"%sadmin obutts - показываем ли попки по просьбе участников чата (команды %sass, %sbutt, %sbooty, %sпопа, %sпопка)\n",
Config.Csign, Config.Csign, Config.Csign, Config.Csign, Config.Csign, Config.Csign,
)
answer += fmt.Sprintf("%sadmin chan_msg - оставляем ли сообщения присланные от имени (других) каналов\n", Config.Csign)
answer += fmt.Sprintf("%sadmin chan_msg # - где 1 - оставляем, 0 - удаляем\n", Config.Csign)
answer += fmt.Sprintf(
"%sadmin ban userid sec - выдаём ban указанному user-у на указанное количество секунд (от 30 сек до 1 года), доступно только создателю чата\n",
Config.Csign,
)
answer += fmt.Sprintf(
"%sadmin mute userid sec - выдаём mute указанному user-у на указанное количество секунд (от 30 сек до 1 года), доступно только создателю чата\n",
Config.Csign,
)
answer += fmt.Sprintf(
"%sadmin admin mute - разрешено ли обычным админам мьютить участников чата через бота (если бот - админ), (создатель чата всегда может попросить бота-админа замьютить обычного участника чата)\n",
Config.Csign,
)
answer += fmt.Sprintf("%sadmin admin mute # - где 1 - разрешено, 0 - не разрешено\n", Config.Csign)
answer += Config.Csign + "admin chan_msg - оставляем ли сообщения присланные от имени (других) каналов\n"
answer += Config.Csign + "admin chan_msg # - где 1 - оставляем, 0 - удаляем\n"
answer += Config.Csign + "admin ban userid sec - выдаём ban указанному user-у на указанное количество секунд (от 30 сек до 1 года), доступно только создателю чата\n"
answer += Config.Csign + "admin mute userid sec - выдаём mute указанному user-у на указанное количество секунд (от 30 сек до 1 года), доступно только создателю чата\n"
answer += Config.Csign + "admin admin mute - разрешено ли обычным админам мьютить участников чата через бота (если бот - админ), (создатель чата всегда может попросить бота-админа замьютить обычного участника чата)\n"
answer += Config.Csign + "%sadmin admin mute # - где 1 - разрешено, 0 - не разрешено\n"
answer += "\n"
answer += "Типы сообщений:\naudio voice photo video video_note animation sticker dice game poll document\n"
answer += "```"

View File

@@ -13,7 +13,7 @@ func Help(cmd *echotron.Update) (bool, error) {
help += fmt.Sprintf("%shelp | %sпомощь - список команд", Config.Csign, Config.Csign)
help += fmt.Sprintf("%sanek | %sанек | %sанекдот - рандомный анекдот с anekdot.ru", Config.Csign, Config.Csign, Config.Csign)
help += fmt.Sprintf("%sbuni - рандомный стрип hapi buni", Config.Csign)
help += Config.Csign + "buni - рандомный стрип hapi buni"
help += fmt.Sprintf("%sbunny | %srabbit | %sкролик - кролик", Config.Csign, Config.Csign, Config.Csign)
help += fmt.Sprintf("%scat | %sкис - кошечка", Config.Csign, Config.Csign)
help += fmt.Sprintf("%scoin | %sмонетка - подбросить монетку - орёл или решка?", Config.Csign, Config.Csign)
@@ -28,7 +28,7 @@ func Help(cmd *echotron.Update) (bool, error) {
help += fmt.Sprintf("%sfrog | %sлягушка - лягушка", Config.Csign, Config.Csign)
help += fmt.Sprintf("%shorse | %sлошадка - лошадка", Config.Csign, Config.Csign)
help += fmt.Sprintf("%slat | %sлат - сгенерить фразу из крылатых латинских выражений", Config.Csign, Config.Csign)
help += fmt.Sprintf("%smonkeyuser - рандомный стрип MonkeyUser", Config.Csign)
help += Config.Csign + "monkeyuser - рандомный стрип MonkeyUser"
help += fmt.Sprintf("%sowl | %sсова | %sсыч - сова", Config.Csign, Config.Csign, Config.Csign)
help += fmt.Sprintf("%sproverb | %sпословица - рандомная русская пословица", Config.Csign, Config.Csign)
help += fmt.Sprintf("%sping | %sпинг - попинговать бота", Config.Csign, Config.Csign)
@@ -36,11 +36,11 @@ func Help(cmd *echotron.Update) (bool, error) {
help += fmt.Sprintf("%ssnail | %sулитка - улитка", Config.Csign, Config.Csign)
help += fmt.Sprintf("%sver | %sversion | %sверсия - что-то про версию ПО", Config.Csign, Config.Csign, Config.Csign)
help += fmt.Sprintf("%sw <город> | %sп <город> - погода в указанном городе", Config.Csign, Config.Csign)
help += fmt.Sprintf("%sweather <город> - погода в указанном городе", Config.Csign)
help += fmt.Sprintf("%sпогода <город> - погода в указанном городе", Config.Csign)
help += fmt.Sprintf("%sпогодка <город> - погода в указанном городе", Config.Csign)
help += fmt.Sprintf("%sпогадка <город> - погода в указанном городе", Config.Csign)
help += fmt.Sprintf("%sxkcd - рандомный стрип с сайта xkcd.ru", Config.Csign)
help += Config.Csign + "weather <город> - погода в указанном городе"
help += Config.Csign + "погода <город> - погода в указанном городе"
help += Config.Csign + "погодка <город> - погода в указанном городе"
help += Config.Csign + "погадка <город> - погода в указанном городе"
help += Config.Csign + "xkcd - рандомный стрип с сайта xkcd.ru"
help += fmt.Sprintf("%skarma фраза | %sкарма фраза - посмотреть карму фразы", Config.Csign, Config.Csign)
help += "```\n"
help += "Но на самом деле я бот больше для общения, чем для исполнения команд.\n"

46
internal/tg/lib.go Normal file
View File

@@ -0,0 +1,46 @@
package tg
import (
"aleesa-telegram-go/internal/log"
"os"
"path/filepath"
)
// ReadConfig читает конфиг. Есть несколько преодопределённых локаций, откуда он пытается его вычитать.
// ./data/config.json, ~/.aleesa-telegram-go.json, ~/aleesa-telegram-go.json, ~/aleesa-telegram-go.json.
func ReadConfig() {
var (
err error
)
executablePath, err := os.Executable()
if err != nil {
log.Fatalf("Unable to get current executable path: %s", err)
}
configJSONPath := filepath.Dir(executablePath) + "/data/config.json"
locations := []string{
"~/.aleesa-telegram-go.json",
"~/aleesa-telegram-go.json",
"/etc/aleesa-telegram-go.json",
configJSONPath,
}
for _, location := range locations {
Config, err = parseConfig(location)
if err == nil {
break
}
log.Errorf("Unable to parse config at %s: %s", location, err)
}
if err != nil {
os.Exit(1)
}
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -10,8 +10,8 @@ import (
"github.com/hjson/hjson-go"
)
// ParseConfig разбирает и валидирует даденный конфиг.
func ParseConfig(path string) (MyConfig, error) {
// parseConfig разбирает и валидирует даденный конфиг.
func parseConfig(path string) (MyConfig, error) {
fileInfo, err := os.Stat(path)
// Предполагаем, что файла либо нет, либо мы не можем его прочитать, второе надо бы логгировать, но пока забьём.

View File

@@ -31,9 +31,16 @@ var (
// SendGoodMorning отсылает сообщение "с добрым утром" (сейчас - фортунку). Предполагается, что оно прогоняется по
// всем желающим чатам раз в сутки, с утра. Утро отсчитывается от настроек локали в системе.
SendGoodMorning = func() {
me, err := tg.GetMe()
if err != nil {
log.Errorf("Unable to send good mornings message, cannot get info about myself: %s", err)
return
}
for _, chatID := range chatGroupList {
if GetSetting(chatID, "FortuneMsg") == "1" {
me, err := tg.GetMe()
// Засылаем фразу в misc-канал (в роутер).
var rmsg rMsg

View File

@@ -65,34 +65,29 @@ func InitChatListDB() error {
chatListDB, err = pebble.Open(dbPath, &options)
if err != nil {
return fmt.Errorf("Unable to open settings db, %s: %w\n", dbPath, err)
return fmt.Errorf("unable to open settings db, %s: %w", dbPath, err)
}
// Заполним слайс со списком чатов. Операция нудная.
iterator, err := chatListDB.NewIter(&pebble.IterOptions{})
if !iterator.First() {
return errors.New("Unable to iterate slice with chats")
return errors.New("unable to iterate slice with chats")
}
// Попробуем извлечь список ключей и заполнить слайс с чатами.
for {
// Закончили итерировать по списку.
if !iterator.Valid() {
break
}
for !iterator.Valid() {
// Битая база?
if err := iterator.Error(); err != nil {
chatList = []string{}
return fmt.Errorf("Unable to get chat list: %w", err)
return fmt.Errorf("unable to get chat list: %w", err)
}
chatName := iterator.Key()
if string(chatName) == "" {
return errors.New("Got empty chat name when query " + chatListDBName)
if len(chatName) == 0 {
return errors.New("got empty chat name when query " + chatListDBName)
}
chatID := string(chatName)
@@ -121,18 +116,21 @@ func AppendChatListDB(chatID string) error {
}
if err = StoreKV(chatListDB, chatID, "1"); err != nil {
return fmt.Errorf("Unable to append %s to %s: %w", chatID, chatListDBName, err)
return fmt.Errorf("unable to append chat %s to chatListDB %s: %w", chatID, chatListDBName, err)
}
// Не забываем актуализировать список чатов.
chatList = append(chatList, chatID)
slices.Sort(chatList)
chatList = slices.Compact(chatList)
// Если СhatID начинается с - это значит, что мы имеем дело именно с группой/супергруппой/каналом.
if strings.HasPrefix(chatID, "-") {
chatGroupList = append(chatGroupList, chatID)
slices.Sort(chatGroupList)
chatGroupList = slices.Compact(chatGroupList)
}

View File

@@ -66,6 +66,7 @@ func SigHandler() {
}
log.Debug("Closing known chat list db")
_ = chatListDB.Close()
os.Exit(0)

View File

@@ -75,10 +75,10 @@ func ConstructFullChatName(c *echotron.Chat) string {
func ConstructPartialUserUsername(u *echotron.User) string {
switch {
case u.Username != "":
return fmt.Sprintf("@%s", u.Username)
return "@" + u.Username
case u.FirstName != "" && u.LastName != "":
return fmt.Sprintf("%s %s", u.FirstName, u.LastName)
return u.FirstName + " " + u.LastName
case u.FirstName != "":
return u.FirstName
@@ -96,10 +96,10 @@ func ConstructPartialUserUsername(u *echotron.User) string {
func ConstructPartialChatUsername(c *echotron.Chat) string {
switch {
case c.Username != "":
return fmt.Sprintf("@%s", c.Username)
return "@" + c.Username
case c.FirstName != "" && c.LastName != "":
return fmt.Sprintf("%s %s", c.FirstName, c.LastName)
return c.FirstName + " " + c.LastName
case c.FirstName != "":
return c.FirstName
@@ -119,13 +119,13 @@ func ConstructUserFirstLastName(u *echotron.User) string {
switch {
case u.FirstName != "" && u.LastName != "":
user = fmt.Sprintf("%s %s", u.FirstName, u.LastName)
user = u.FirstName + " " + u.LastName
case u.FirstName != "":
user = u.FirstName
case u.LastName != "":
user = u.LastName
case u.Username != "":
user = fmt.Sprintf("@%s", u.Username)
user = "@" + u.Username
default:
user = strconv.FormatInt(u.ID, 10)
}

View File

@@ -21,7 +21,9 @@ func telegramMsgParser(msg *echotron.Update) {
return
}
AppendChatListDB(strconv.FormatInt(msg.ChatID(), 10))
if err := AppendChatListDB(strconv.FormatInt(msg.ChatID(), 10)); err != nil {
log.Error(err.Error())
}
// Сообщение о том, что этот чятик изменился, например, превратился в супергруппу.
if (msg.Message.MigrateFromChatID < 0) && (msg.Message.MigrateToChatID < 0) {
@@ -77,7 +79,7 @@ func telegramMsgParser(msg *echotron.Update) {
users = strings.Join(usersSlice, ", ")
users += fmt.Sprintf(" and %s", ConstructTelegramHighlightName(lastOne))
users += " and " + ConstructTelegramHighlightName(lastOne)
} else {
users = ConstructTelegramHighlightName(msg.Message.NewChatMembers[0])
}
@@ -130,7 +132,7 @@ func telegramMsgParser(msg *echotron.Update) {
if GetSetting(strconv.FormatInt(msg.Message.Chat.ID, 10), "GoodbyeMsg") == "1" {
user := ConstructUserFirstLastName(msg.Message.From)
goodbye := fmt.Sprintf("Прощаемся с %s", user)
goodbye := "Прощаемся с " + user
opts := echotron.MessageOptions{DisableNotification: true, ParseMode: "MarkdownV2"}