Restructures configuration for birthdays and adds pictures directory
This commit is contained in:
parent
c7399eb9da
commit
ec2cdfdeaa
9 changed files with 55 additions and 31 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
dist
|
dist
|
||||||
config.yml
|
config.yml
|
||||||
|
pics
|
|
@ -1,6 +1,8 @@
|
||||||
---
|
---
|
||||||
birthday_file: birthdays.csv
|
birthdays:
|
||||||
birthday_template: ./birthday_message.tmpl
|
file: birthdays.csv
|
||||||
|
template: ./birthday_message.tmpl
|
||||||
|
pictures: ./pics
|
||||||
|
|
||||||
logger:
|
logger:
|
||||||
level: debug
|
level: debug
|
||||||
|
|
|
@ -10,22 +10,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrConfigBirthdayFileEmpty = errors.New("birthday file cannot be empty")
|
ErrBirthdaysConfigFileEmpty = errors.New("birthday file cannot be empty")
|
||||||
ErrLoggerConfigBadLevel = errors.New("logger level needs to be one of debug, info, warn, error, fatal or left empty")
|
ErrLoggerConfigBadLevel = errors.New("logger level needs to be one of debug, info, warn, error, fatal or left empty")
|
||||||
ErrTelegramNotificationsConfigEmptyBotToken = errors.New("bot token cannot be empty")
|
ErrTelegramNotificationsConfigEmptyBotToken = errors.New("bot token cannot be empty")
|
||||||
ErrTelegramNotificationsConfigEmptyChannelID = errors.New("channel ID cannot be empty")
|
ErrTelegramNotificationsConfigEmptyChannelID = errors.New("channel ID cannot be empty")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
BirthdayFile string `yaml:"birthday_file"`
|
Birthdays *BirthdaysConfig `yaml:"birthdays"`
|
||||||
BirthdayTemplate string `yaml:"birthday_template"`
|
|
||||||
Logger *LoggerConfig `yaml:"logger"`
|
Logger *LoggerConfig `yaml:"logger"`
|
||||||
TelegramNotifications *TelegramNotificationsConfig `yaml:"telegram_notifications"`
|
TelegramNotifications *TelegramNotificationsConfig `yaml:"telegram_notifications"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) IsValid() error {
|
func (c *Config) IsValid() error {
|
||||||
if c.BirthdayFile == "" {
|
if err := c.Birthdays.IsValid(); err != nil {
|
||||||
return ErrConfigBirthdayFileEmpty
|
return fmt.Errorf("invalid birthdays config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Logger.IsValid(); err != nil {
|
if err := c.Logger.IsValid(); err != nil {
|
||||||
|
@ -42,6 +41,12 @@ func (c *Config) IsValid() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) SetDefaults() {
|
func (c *Config) SetDefaults() {
|
||||||
|
if c.Birthdays == nil {
|
||||||
|
c.Birthdays = &BirthdaysConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Birthdays.SetDefaults()
|
||||||
|
|
||||||
if c.Logger == nil {
|
if c.Logger == nil {
|
||||||
c.Logger = &LoggerConfig{}
|
c.Logger = &LoggerConfig{}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +58,22 @@ func (c *Config) SetDefaults() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BirthdaysConfig struct {
|
||||||
|
File string `yaml:"file"`
|
||||||
|
Template string `yaml:"template"`
|
||||||
|
Picures string `yaml:"pictures"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BirthdaysConfig) IsValid() error {
|
||||||
|
if bc.File == "" {
|
||||||
|
return ErrBirthdaysConfigFileEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BirthdaysConfig) SetDefaults() {}
|
||||||
|
|
||||||
type LoggerConfig struct {
|
type LoggerConfig struct {
|
||||||
Level string `yaml:"level"`
|
Level string `yaml:"level"`
|
||||||
ReportCaller bool `yaml:"report_caller"`
|
ReportCaller bool `yaml:"report_caller"`
|
||||||
|
|
|
@ -15,13 +15,13 @@ func TestReadConfig(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer os.Remove(f.Name())
|
defer os.Remove(f.Name())
|
||||||
|
|
||||||
_, werr := io.WriteString(f, "---\nbirthday_file: birthday.csv")
|
_, werr := io.WriteString(f, "---\nbirthdays:\n file: birthday.csv")
|
||||||
require.NoError(t, werr)
|
require.NoError(t, werr)
|
||||||
require.NoError(t, f.Close())
|
require.NoError(t, f.Close())
|
||||||
|
|
||||||
config, err := ReadConfig(f.Name())
|
config, err := ReadConfig(f.Name())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "birthday.csv", config.BirthdayFile)
|
require.Equal(t, "birthday.csv", config.Birthdays.File)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should fail if the file doesn't exist", func(t *testing.T) {
|
t.Run("should fail if the file doesn't exist", func(t *testing.T) {
|
||||||
|
|
|
@ -13,12 +13,12 @@ import (
|
||||||
|
|
||||||
type TelegramNotificationService struct {
|
type TelegramNotificationService struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
config *model.TelegramNotificationsConfig
|
config *model.Config
|
||||||
bot *tgbotapi.BotAPI
|
bot *tgbotapi.BotAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTelegramNotificationService(logger *log.Logger, config *model.TelegramNotificationsConfig) (*TelegramNotificationService, error) {
|
func NewTelegramNotificationService(logger *log.Logger, config *model.Config) (*TelegramNotificationService, error) {
|
||||||
bot, err := tgbotapi.NewBotAPI(config.BotToken)
|
bot, err := tgbotapi.NewBotAPI(config.TelegramNotifications.BotToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create bot: %w", err)
|
return nil, fmt.Errorf("cannot create bot: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ func testConfig(t *testing.T) *model.Config {
|
||||||
require.NoError(t, f.Close())
|
require.NoError(t, f.Close())
|
||||||
require.NoError(t, os.Remove(f.Name()))
|
require.NoError(t, os.Remove(f.Name()))
|
||||||
|
|
||||||
return &model.Config{BirthdayFile: f.Name()}
|
return &model.Config{Birthdays: &model.BirthdaysConfig{File: f.Name()}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupTestHelper(t *testing.T) *TestHelper {
|
func SetupTestHelper(t *testing.T) *TestHelper {
|
||||||
|
|
|
@ -10,7 +10,7 @@ type Option func(*Server) *Server
|
||||||
|
|
||||||
func WithConfig(config *model.Config) Option {
|
func WithConfig(config *model.Config) Option {
|
||||||
return func(server *Server) *Server {
|
return func(server *Server) *Server {
|
||||||
server.config = config
|
server.Config = config
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,18 +19,18 @@ var (
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Logger *log.Logger
|
Logger *log.Logger
|
||||||
config *model.Config
|
Config *model.Config
|
||||||
workers []Worker
|
workers []Worker
|
||||||
birthdays []*model.Birthday
|
birthdays []*model.Birthday
|
||||||
notificationServices []notification.NotificationService
|
notificationServices []notification.NotificationService
|
||||||
tmpl *template.Template
|
tmpl *template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNotificationServices(logger *log.Logger, config *model.Config) ([]notification.NotificationService, error) {
|
func (s *Server) createNotificationServices() ([]notification.NotificationService, error) {
|
||||||
notificationServices := []notification.NotificationService{}
|
notificationServices := []notification.NotificationService{}
|
||||||
|
|
||||||
if config.TelegramNotifications != nil {
|
if s.Config.TelegramNotifications != nil {
|
||||||
telegramNotificationService, err := notification.NewTelegramNotificationService(logger, config.TelegramNotifications)
|
telegramNotificationService, err := notification.NewTelegramNotificationService(s.Logger, s.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create telegram notification service: %w", err)
|
return nil, fmt.Errorf("cannot create telegram notification service: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -54,18 +54,18 @@ func New(options ...Option) (*Server, error) {
|
||||||
return nil, ErrNoLogger
|
return nil, ErrNoLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
if srv.config == nil {
|
if srv.Config == nil {
|
||||||
return nil, ErrNoConfig
|
return nil, ErrNoConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(srv.birthdays) == 0 {
|
if len(srv.birthdays) == 0 {
|
||||||
srv.Logger.Debug("parsing CSV file", "birthdayFile", srv.config.BirthdayFile)
|
srv.Logger.Debug("parsing CSV file", "birthdayFile", srv.Config.Birthdays.File)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
srv.birthdays, err = parser.ParseCSV(srv.config.BirthdayFile)
|
srv.birthdays, err = parser.ParseCSV(srv.Config.Birthdays.File)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srv.Logger.Error("cannot parse CSV file", "birthdayFile", srv.config.BirthdayFile, "error", err)
|
srv.Logger.Error("cannot parse CSV file", "birthdayFile", srv.Config.Birthdays.File, "error", err)
|
||||||
return nil, fmt.Errorf("cannot parse CSV file %s: %w", srv.config.BirthdayFile, err)
|
return nil, fmt.Errorf("cannot parse CSV file %s: %w", srv.Config.Birthdays.File, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ func New(options ...Option) (*Server, error) {
|
||||||
srv.Logger.Debug("creating notification services from config")
|
srv.Logger.Debug("creating notification services from config")
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
srv.notificationServices, err = createNotificationServices(srv.Logger, srv.config)
|
srv.notificationServices, err = srv.createNotificationServices()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srv.Logger.Error("error creating notification services", "error", err)
|
srv.Logger.Error("error creating notification services", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -86,13 +86,13 @@ func New(options ...Option) (*Server, error) {
|
||||||
srv.workers = []Worker{NewSimpleWorker(srv)}
|
srv.workers = []Worker{NewSimpleWorker(srv)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if srv.config.BirthdayTemplate != "" {
|
if srv.Config.Birthdays.Template != "" {
|
||||||
srv.Logger.Debug("parsing birthday template", "file", srv.config.BirthdayTemplate)
|
srv.Logger.Debug("parsing birthday template", "file", srv.Config.Birthdays.Template)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
srv.tmpl, err = template.ParseFiles(srv.config.BirthdayTemplate)
|
srv.tmpl, err = template.ParseFiles(srv.Config.Birthdays.Template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse template file %q: %w", srv.config.BirthdayTemplate, err)
|
return nil, fmt.Errorf("cannot parse template file %q: %w", srv.Config.Birthdays.Template, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestNotify(t *testing.T) {
|
||||||
birthday := th.srv.birthdays[0]
|
birthday := th.srv.birthdays[0]
|
||||||
th.mockNotificationService.
|
th.mockNotificationService.
|
||||||
EXPECT().
|
EXPECT().
|
||||||
Notify(birthday).
|
Notify(birthday, nil).
|
||||||
Return(nil).
|
Return(nil).
|
||||||
Times(1)
|
Times(1)
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ func TestNotify(t *testing.T) {
|
||||||
birthday := th.srv.birthdays[0]
|
birthday := th.srv.birthdays[0]
|
||||||
th.mockNotificationService.
|
th.mockNotificationService.
|
||||||
EXPECT().
|
EXPECT().
|
||||||
Notify(birthday).
|
Notify(birthday, nil).
|
||||||
Return(mockErr).
|
Return(mockErr).
|
||||||
Times(1)
|
Times(1)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue