contracts and models
This commit is contained in:
14
go.mod
14
go.mod
@@ -2,16 +2,4 @@ module gitea.mrixs.me/Mrixs/yamusic-bot
|
|||||||
|
|
||||||
go 1.24
|
go 1.24
|
||||||
|
|
||||||
require (
|
require github.com/caarlos0/env/v10 v10.0.0
|
||||||
github.com/bogem/id3v2 v1.2.1
|
|
||||||
github.com/caarlos0/env/v10 v10.0.0
|
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.22
|
|
||||||
golang.org/x/sync v0.7.0
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/lmittmann/tint v1.0.4 // indirect
|
|
||||||
golang.org/x/net v0.21.0 // indirect
|
|
||||||
golang.org/x/text v0.14.0 // indirect
|
|
||||||
)
|
|
||||||
|
|||||||
2
go.sum
Normal file
2
go.sum
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
github.com/caarlos0/env/v10 v10.0.0 h1:yIHUBZGsyqCnpTkbjk8asUlx6RFhhEs+h7TOBdgdzXA=
|
||||||
|
github.com/caarlos0/env/v10 v10.0.0/go.mod h1:ZfulV76NvVPw3tm591U4SwL3Xx9ldzBP9aGxzeN7G18=
|
||||||
56
internal/config/config.go
Normal file
56
internal/config/config.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/caarlos0/env/v10"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config содержит всю конфигурацию приложения, получаемую из переменных окружения.
|
||||||
|
type Config struct {
|
||||||
|
TelegramBotToken string `env:"TELEGRAM_BOT_TOKEN,required"`
|
||||||
|
TelegramAdminIDsRaw string `env:"TELEGRAM_ADMIN_IDS,required"`
|
||||||
|
TelegramCacheChatID int64 `env:"TELEGRAM_CACHE_CHAT_ID,required"`
|
||||||
|
YandexMusicToken string `env:"YANDEX_MUSIC_TOKEN"`
|
||||||
|
DatabasePath string `env:"DATABASE_PATH" envDefault:"/data/bot.db"`
|
||||||
|
LogLevel string `env:"LOG_LEVEL" envDefault:"info"`
|
||||||
|
ProcessorWorkers int `env:"PROCESSOR_WORKERS" envDefault:"4"`
|
||||||
|
YandexAPIRateLimit int `env:"YANDEX_API_RATE_LIMIT" envDefault:"5"`
|
||||||
|
TelegramAdminIDs []int64 `env:"-"` // Это поле будет заполнено после парсинга
|
||||||
|
}
|
||||||
|
|
||||||
|
// New загружает конфигурацию из переменных окружения и парсит необходимые поля.
|
||||||
|
func New() *Config {
|
||||||
|
cfg := &Config{}
|
||||||
|
if err := env.Parse(cfg); err != nil {
|
||||||
|
log.Fatalf("failed to parse config: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Парсим ID администраторов из строки
|
||||||
|
if cfg.TelegramAdminIDsRaw != "" {
|
||||||
|
ids := strings.Split(cfg.TelegramAdminIDsRaw, ",")
|
||||||
|
cfg.TelegramAdminIDs = make([]int64, 0, len(ids))
|
||||||
|
for _, idStr := range ids {
|
||||||
|
var id int64
|
||||||
|
if _, err := Sscanf(strings.TrimSpace(idStr), "%d", &id); err == nil {
|
||||||
|
cfg.TelegramAdminIDs = append(cfg.TelegramAdminIDs, id)
|
||||||
|
} else {
|
||||||
|
log.Printf("warning: could not parse admin ID: %s", idStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cfg.TelegramAdminIDs) == 0 {
|
||||||
|
log.Fatalf("no valid admin IDs provided in TELEGRAM_ADMIN_IDS")
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sscanf - простая реализация для парсинга, чтобы избежать лишних зависимостей.
|
||||||
|
// В стандартной библиотеке fmt.Sscanf требует, чтобы вся строка была разобрана.
|
||||||
|
func Sscanf(str, format string, a ...interface{}) (int, error) {
|
||||||
|
return fmt.Sscanf(str, format, a...)
|
||||||
|
}
|
||||||
42
internal/interfaces/interfaces.go
Normal file
42
internal/interfaces/interfaces.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package interfaces
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gitea.mrixs.me/Mrixs/yamusic-bot/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// YandexMusicClient определяет методы для взаимодействия с API Yandex.Music.
|
||||||
|
type YandexMusicClient interface {
|
||||||
|
GetTrackInfo(ctx context.Context, trackID string) (*model.TrackInfo, error)
|
||||||
|
GetAlbumTrackInfos(ctx context.Context, albumID string) ([]*model.TrackInfo, error)
|
||||||
|
GetArtistTrackInfos(ctx context.Context, artistID string) ([]*model.TrackInfo, error)
|
||||||
|
GetDownloadURL(ctx context.Context, trackID string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrackStorage определяет методы для работы с постоянным кэшем.
|
||||||
|
type TrackStorage interface {
|
||||||
|
Get(ctx context.Context, yandexTrackID string) (telegramFileID string, err error)
|
||||||
|
Set(ctx context.Context, yandexTrackID, telegramFileID string) error
|
||||||
|
Count(ctx context.Context) (int, error)
|
||||||
|
Close() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// TelegramClient определяет методы для взаимодействия с Telegram Bot API.
|
||||||
|
// Мы определяем свой интерфейс, чтобы не зависеть напрямую от библиотеки
|
||||||
|
// и упростить тестирование.
|
||||||
|
type TelegramClient interface {
|
||||||
|
SendAudioToCacheChannel(ctx context.Context, audioPath, title, performer string) (string, error)
|
||||||
|
AnswerInlineQuery(ctx context.Context, queryID string, results []interface{}) error
|
||||||
|
SendMessage(ctx context.Context, chatID int64, text string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tagger определяет методы для работы с метаданными аудиофайлов.
|
||||||
|
type Tagger interface {
|
||||||
|
WriteTags(filePath string, coverPath string, info *model.TrackInfo) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileDownloader определяет метод для скачивания файла.
|
||||||
|
type FileDownloader interface {
|
||||||
|
Download(ctx context.Context, url string) (filePath string, err error)
|
||||||
|
}
|
||||||
15
internal/model/model.go
Normal file
15
internal/model/model.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
// TrackInfo содержит всю необходимую информацию о треке для его обработки и тегирования.
|
||||||
|
type TrackInfo struct {
|
||||||
|
YandexTrackID string
|
||||||
|
YandexAlbumID string
|
||||||
|
Title string
|
||||||
|
Album string
|
||||||
|
Artist string
|
||||||
|
Year int
|
||||||
|
Genre string
|
||||||
|
TrackPosition int
|
||||||
|
CoverURL string
|
||||||
|
DownloadURL string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user