Join webbapp core modules into single package
This commit is contained in:
@@ -9,8 +9,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"aleesa-webapp-go/internal/config"
|
"aleesa-webapp-go/internal/config"
|
||||||
"aleesa-webapp-go/internal/lib"
|
|
||||||
"aleesa-webapp-go/internal/log"
|
"aleesa-webapp-go/internal/log"
|
||||||
|
"aleesa-webapp-go/internal/webapp"
|
||||||
|
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
)
|
)
|
||||||
@@ -35,7 +35,7 @@ func main() {
|
|||||||
logfile *os.File
|
logfile *os.File
|
||||||
)
|
)
|
||||||
|
|
||||||
cfg, err := config.ReadConfig()
|
err := webapp.ReadConfig()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Unable to parse config: %s", err)
|
log.Errorf("Unable to parse config: %s", err)
|
||||||
@@ -43,24 +43,24 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Откроем лог и скормим его логгеру.
|
// Откроем лог и скормим его логгеру.
|
||||||
if cfg.Log != "" {
|
if webapp.Config.Log != "" {
|
||||||
logfile, err = os.OpenFile(cfg.Log, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
logfile, err = os.OpenFile(webapp.Config.Log, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Unable to open log file %s: %s", cfg.Log, err)
|
log.Errorf("Unable to open log file %s: %s", webapp.Config.Log, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Init(cfg.Loglevel, logfile)
|
log.Init(webapp.Config.Loglevel, logfile)
|
||||||
|
|
||||||
// Иницализируем клиента Редиски.
|
// Иницализируем клиента Редиски.
|
||||||
cfg.RedisClient = redis.NewClient(&redis.Options{
|
webapp.Config.RedisClient = redis.NewClient(&redis.Options{
|
||||||
Addr: fmt.Sprintf("%s:%d", cfg.Server, cfg.Port),
|
Addr: fmt.Sprintf("%s:%d", webapp.Config.Server, webapp.Config.Port),
|
||||||
}).WithContext(Ctx).WithTimeout(time.Duration(cfg.Timeout) * time.Second)
|
}).WithContext(Ctx).WithTimeout(time.Duration(webapp.Config.Timeout) * time.Second)
|
||||||
|
|
||||||
// Обозначим, что хотим после соединения подписаться на события из канала config.Channel.
|
// Обозначим, что хотим после соединения подписаться на события из канала config.Channel.
|
||||||
Subscriber = cfg.RedisClient.Subscribe(Ctx, cfg.Channel)
|
Subscriber = webapp.Config.RedisClient.Subscribe(Ctx, webapp.Config.Channel)
|
||||||
|
|
||||||
// Самое время поставить трапы на сигналы.
|
// Самое время поставить трапы на сигналы.
|
||||||
signal.Notify(SigChan,
|
signal.Notify(SigChan,
|
||||||
@@ -68,18 +68,8 @@ func main() {
|
|||||||
syscall.SIGTERM,
|
syscall.SIGTERM,
|
||||||
syscall.SIGQUIT)
|
syscall.SIGQUIT)
|
||||||
|
|
||||||
// Откроем лог и скормим его логгеру.
|
|
||||||
if cfg.Log != "" {
|
|
||||||
logfile, err = os.OpenFile(cfg.Log, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Unable to open log file %s: %s", cfg.Log, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Запустим обработчик сигналов.
|
// Запустим обработчик сигналов.
|
||||||
go SigHandler(cfg)
|
go SigHandler(webapp.Config)
|
||||||
|
|
||||||
// Начнём выгребать события из редиски (длина конвеера/буфера канала по-умолчанию - 100 сообщений).
|
// Начнём выгребать события из редиски (длина конвеера/буфера канала по-умолчанию - 100 сообщений).
|
||||||
ch := Subscriber.Channel()
|
ch := Subscriber.Channel()
|
||||||
@@ -88,13 +78,15 @@ func main() {
|
|||||||
|
|
||||||
for msg := range ch {
|
for msg := range ch {
|
||||||
if !Shutdown {
|
if !Shutdown {
|
||||||
lib.MsgParser(cfg, Ctx, msg.Payload)
|
webapp.MsgParser(webapp.Config, Ctx, msg.Payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SigHandler хэндлер сигналов закрывает все бд и сваливает из приложения.
|
// SigHandler хэндлер сигналов закрывает все бд и сваливает из приложения.
|
||||||
func SigHandler(cfg *config.MyConfig) {
|
func SigHandler(cfg *config.MyConfig) {
|
||||||
|
// TODO: утащить отсюда в модули.
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"aleesa-webapp-go/internal/config"
|
|
||||||
"aleesa-webapp-go/internal/flickr"
|
"aleesa-webapp-go/internal/flickr"
|
||||||
|
"aleesa-webapp-go/internal/webapp"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if c, err := config.ReadConfig(); err != nil {
|
if err := webapp.ReadConfig(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else {
|
} else {
|
||||||
if err := flickr.APIClientInit(c); err != nil {
|
if err := flickr.APIClientInit(webapp.Config); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"aleesa-webapp-go/internal/config"
|
|
||||||
"aleesa-webapp-go/internal/flickr"
|
"aleesa-webapp-go/internal/flickr"
|
||||||
|
"aleesa-webapp-go/internal/webapp"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if c, err := config.ReadConfig(); err != nil {
|
if err := webapp.ReadConfig(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else {
|
} else {
|
||||||
if err := flickr.Populate(c); err != nil {
|
if err := flickr.Populate(webapp.Config); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"aleesa-webapp-go/internal/config"
|
|
||||||
"aleesa-webapp-go/internal/flickr"
|
"aleesa-webapp-go/internal/flickr"
|
||||||
|
"aleesa-webapp-go/internal/webapp"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if c, err := config.ReadConfig(); err != nil {
|
if err := webapp.ReadConfig(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else {
|
} else {
|
||||||
result, err := flickr.SearchByTags(c, []string{"snail", "slug"})
|
result, err := flickr.SearchByTags(webapp.Config, []string{"snail", "slug"})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
|||||||
37
internal/config/types.go
Normal file
37
internal/config/types.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// Этот package нужен, чтобы разбить кольцевую зависимость.
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cockroachdb/pebble"
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MyConfig структурка, описывающая конфиг.
|
||||||
|
type MyConfig struct {
|
||||||
|
Server string `json:"server,omitempty"`
|
||||||
|
Port int `json:"port,omitempty"`
|
||||||
|
Timeout int `json:"timeout,omitempty"`
|
||||||
|
Loglevel string `json:"loglevel,omitempty"`
|
||||||
|
Log string `json:"log,omitempty"`
|
||||||
|
Channel string `json:"channel,omitempty"`
|
||||||
|
DataDir string `json:"datadir,omitempty"`
|
||||||
|
Csign string `json:"csign,omitempty"`
|
||||||
|
ForwardsMax int64 `json:"forwards_max,omitempty"`
|
||||||
|
OpenWeatherMap struct {
|
||||||
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
|
Country bool `json:"country,omitempty"`
|
||||||
|
Appid string `json:"appid,omitempty"`
|
||||||
|
} `json:"openweathermap,omitempty"`
|
||||||
|
Flickr struct {
|
||||||
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
|
Key string `json:"key,omitempty"`
|
||||||
|
Secret string `json:"secret,omitempty"`
|
||||||
|
OAuthToken string `json:"oauth_token,omitempty"`
|
||||||
|
OAuthTokenSecret string `json:"oauth_token_secret,omitempty"`
|
||||||
|
} `json:"flickr,omitempty"`
|
||||||
|
UserAgents []string `json:"user_agents,omitempty"`
|
||||||
|
PcacheDB map[string]*pebble.DB
|
||||||
|
RedisClient *redis.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package lib
|
package webapp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"aleesa-webapp-go/internal/anekdotru"
|
"aleesa-webapp-go/internal/anekdotru"
|
||||||
@@ -13,7 +13,6 @@ import (
|
|||||||
"aleesa-webapp-go/internal/prazdnikisegodnyaru"
|
"aleesa-webapp-go/internal/prazdnikisegodnyaru"
|
||||||
"aleesa-webapp-go/internal/randomfox"
|
"aleesa-webapp-go/internal/randomfox"
|
||||||
"aleesa-webapp-go/internal/thecatapi"
|
"aleesa-webapp-go/internal/thecatapi"
|
||||||
"aleesa-webapp-go/internal/types"
|
|
||||||
"aleesa-webapp-go/internal/xkcdru"
|
"aleesa-webapp-go/internal/xkcdru"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -28,7 +27,7 @@ func MsgParser(cfg *config.MyConfig, ctx context.Context, msg string) {
|
|||||||
var (
|
var (
|
||||||
sendTo string
|
sendTo string
|
||||||
answer string
|
answer string
|
||||||
j types.RMsg
|
j RMsg
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -469,7 +468,7 @@ func MsgParser(cfg *config.MyConfig, ctx context.Context, msg string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Настало время формировать json и засылать его в дальше
|
// Настало время формировать json и засылать его в дальше
|
||||||
var message types.SMsg
|
var message SMsg
|
||||||
message.From = j.From
|
message.From = j.From
|
||||||
message.Userid = j.Userid
|
message.Userid = j.Userid
|
||||||
message.Chatid = j.Chatid
|
message.Chatid = j.Chatid
|
||||||
@@ -501,62 +500,4 @@ func MsgParser(cfg *config.MyConfig, ctx context.Context, msg string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateRmsg валидирует входящее сообщение.
|
|
||||||
func ValidateRmsg(cfg *config.MyConfig, j types.RMsg, msg string) (types.RMsg, error) {
|
|
||||||
if exist := j.From; exist == "" {
|
|
||||||
emsg := fmt.Errorf("incorrect msg from redis, no from field: %s", msg)
|
|
||||||
|
|
||||||
return j, emsg
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Chatid; exist == "" {
|
|
||||||
emsg := fmt.Errorf("incorrect msg from redis, no chatid field: %s", msg)
|
|
||||||
|
|
||||||
return j, emsg
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Userid; exist == "" {
|
|
||||||
emsg := fmt.Errorf("incorrect msg from redis, no userid field: %s", msg)
|
|
||||||
|
|
||||||
return j, emsg
|
|
||||||
}
|
|
||||||
|
|
||||||
// j.Threadid может быть пустым, значит либо нам его не дали, либо дали пустым. Это нормально.
|
|
||||||
|
|
||||||
if exist := j.Message; exist == "" {
|
|
||||||
emsg := fmt.Errorf("incorrect msg from redis, no message field: %s", msg)
|
|
||||||
|
|
||||||
return j, emsg
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Plugin; exist == "" {
|
|
||||||
emsg := fmt.Errorf("incorrect msg from redis, no plugin field: %s", msg)
|
|
||||||
|
|
||||||
return j, emsg
|
|
||||||
}
|
|
||||||
|
|
||||||
if exist := j.Mode; exist == "" {
|
|
||||||
emsg := fmt.Errorf("incorrect msg from redis, no mode field: %s", msg)
|
|
||||||
|
|
||||||
return j, emsg
|
|
||||||
}
|
|
||||||
|
|
||||||
// j.Misc.Answer может и не быть, тогда ответа на такое сообщение не будет
|
|
||||||
// j.Misc.Botnick тоже можно не передавать, тогда будет записана пустая строка
|
|
||||||
// j.Misc.Csign если нам его не передали, возьмём значение из конфига
|
|
||||||
if exist := j.Misc.Csign; exist == "" {
|
|
||||||
j.Misc.Csign = cfg.Csign
|
|
||||||
}
|
|
||||||
|
|
||||||
// j.Misc.Fwdcnt если нам его не передали, то будет 0
|
|
||||||
if exist := j.Misc.Fwdcnt; exist == 0 {
|
|
||||||
j.Misc.Fwdcnt = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// j.Misc.GoodMorning может быть быть 1 или 0, по-умолчанию 0
|
|
||||||
// j.Misc.Msgformat может быть быть 1 или 0, по-умолчанию 0
|
|
||||||
// j.Misc.Username можно не передавать, тогда будет пустая строка
|
|
||||||
return j, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
@@ -1,54 +1,24 @@
|
|||||||
package config
|
package webapp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"aleesa-webapp-go/internal/defaults"
|
"aleesa-webapp-go/internal/config"
|
||||||
"aleesa-webapp-go/internal/log"
|
"aleesa-webapp-go/internal/log"
|
||||||
"bufio"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/cockroachdb/pebble"
|
"github.com/cockroachdb/pebble"
|
||||||
"github.com/go-redis/redis/v8"
|
|
||||||
"github.com/hjson/hjson-go"
|
"github.com/hjson/hjson-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MyConfig структурка, описывающая конфиг.
|
|
||||||
type MyConfig struct {
|
|
||||||
Server string `json:"server,omitempty"`
|
|
||||||
Port int `json:"port,omitempty"`
|
|
||||||
Timeout int `json:"timeout,omitempty"`
|
|
||||||
Loglevel string `json:"loglevel,omitempty"`
|
|
||||||
Log string `json:"log,omitempty"`
|
|
||||||
Channel string `json:"channel,omitempty"`
|
|
||||||
DataDir string `json:"datadir,omitempty"`
|
|
||||||
Csign string `json:"csign,omitempty"`
|
|
||||||
ForwardsMax int64 `json:"forwards_max,omitempty"`
|
|
||||||
OpenWeatherMap struct {
|
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
|
||||||
Country bool `json:"country,omitempty"`
|
|
||||||
Appid string `json:"appid,omitempty"`
|
|
||||||
} `json:"openweathermap,omitempty"`
|
|
||||||
Flickr struct {
|
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
|
||||||
Key string `json:"key,omitempty"`
|
|
||||||
Secret string `json:"secret,omitempty"`
|
|
||||||
OAuthToken string `json:"oauth_token,omitempty"`
|
|
||||||
OAuthTokenSecret string `json:"oauth_token_secret,omitempty"`
|
|
||||||
} `json:"flickr,omitempty"`
|
|
||||||
UserAgents []string `json:"user_agents,omitempty"`
|
|
||||||
PcacheDB map[string]*pebble.DB
|
|
||||||
RedisClient *redis.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadConfig читает и валидирует конфиг, а также выставляет некоторые default-ы, если значений для параметров в конфиге
|
// ReadConfig читает и валидирует конфиг, а также выставляет некоторые default-ы, если значений для параметров в конфиге
|
||||||
// нет.
|
// нет.
|
||||||
func ReadConfig() (*MyConfig, error) {
|
func ReadConfig() error {
|
||||||
locations, err := defaults.DefaultConfigFileLocations()
|
locations, err := DefaultConfigFileLocations()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &MyConfig{}, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, location := range locations {
|
for _, location := range locations {
|
||||||
@@ -60,7 +30,7 @@ func ReadConfig() (*MyConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Конфиг-файл длинноват для конфига, попробуем следующего кандидата
|
// Конфиг-файл длинноват для конфига, попробуем следующего кандидата
|
||||||
if fileInfo.Size() > defaults.ConfigFileSize {
|
if fileInfo.Size() > ConfigFileSize {
|
||||||
log.Warnf("Config file %s is too long for config, skipping", location)
|
log.Warnf("Config file %s is too long for config, skipping", location)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
@@ -79,7 +49,7 @@ func ReadConfig() (*MyConfig, error) {
|
|||||||
// Интереснее на выходе получить структурку: то есть мы вначале конфиг преобразуем в map-ку, затем эту map-ку
|
// Интереснее на выходе получить структурку: то есть мы вначале конфиг преобразуем в map-ку, затем эту map-ку
|
||||||
// сериализуем в json, а потом json преврщааем в стркутурку. Не очень эффективно, но он и не часто требуется.
|
// сериализуем в json, а потом json преврщааем в стркутурку. Не очень эффективно, но он и не часто требуется.
|
||||||
var (
|
var (
|
||||||
sampleConfig *MyConfig
|
sampleConfig *config.MyConfig
|
||||||
tmp map[string]interface{}
|
tmp map[string]interface{}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,19 +79,19 @@ func ReadConfig() (*MyConfig, error) {
|
|||||||
|
|
||||||
// Валидируем значения из конфига
|
// Валидируем значения из конфига
|
||||||
if sampleConfig.Server == "" {
|
if sampleConfig.Server == "" {
|
||||||
sampleConfig.Server = defaults.Host
|
sampleConfig.Server = Host
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Port == 0 {
|
if sampleConfig.Port == 0 {
|
||||||
sampleConfig.Port = defaults.RedisPort
|
sampleConfig.Port = RedisPort
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Timeout == 0 {
|
if sampleConfig.Timeout == 0 {
|
||||||
sampleConfig.Timeout = defaults.NetworkTimeout
|
sampleConfig.Timeout = NetworkTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Loglevel == "" {
|
if sampleConfig.Loglevel == "" {
|
||||||
sampleConfig.Loglevel = defaults.Loglevel
|
sampleConfig.Loglevel = Loglevel
|
||||||
}
|
}
|
||||||
|
|
||||||
// sampleConfig.Log = "" if not set
|
// sampleConfig.Log = "" if not set
|
||||||
@@ -133,7 +103,7 @@ func ReadConfig() (*MyConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.DataDir == "" {
|
if sampleConfig.DataDir == "" {
|
||||||
sampleConfig.DataDir = defaults.DataDir
|
sampleConfig.DataDir = DataDir
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Csign == "" {
|
if sampleConfig.Csign == "" {
|
||||||
@@ -143,7 +113,7 @@ func ReadConfig() (*MyConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.ForwardsMax == 0 {
|
if sampleConfig.ForwardsMax == 0 {
|
||||||
sampleConfig.ForwardsMax = defaults.ForwardMax
|
sampleConfig.ForwardsMax = ForwardMax
|
||||||
}
|
}
|
||||||
|
|
||||||
if unsafe.Sizeof(sampleConfig.OpenWeatherMap) == 0 {
|
if unsafe.Sizeof(sampleConfig.OpenWeatherMap) == 0 {
|
||||||
@@ -165,7 +135,7 @@ func ReadConfig() (*MyConfig, error) {
|
|||||||
uaList, err := ReadLines(uaFile)
|
uaList, err := ReadLines(uaFile)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &MyConfig{}, fmt.Errorf("unable to read %s: %w", uaFile, err)
|
return fmt.Errorf("unable to read %s: %w", uaFile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleConfig.UserAgents = uaList
|
sampleConfig.UserAgents = uaList
|
||||||
@@ -174,37 +144,12 @@ func ReadConfig() (*MyConfig, error) {
|
|||||||
|
|
||||||
log.Infof("Using %s as config file", location)
|
log.Infof("Using %s as config file", location)
|
||||||
|
|
||||||
return sampleConfig, nil
|
Config = sampleConfig
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &MyConfig{}, fmt.Errorf("config was not loaded! Refusing to start")
|
return fmt.Errorf("config was not loaded! Refusing to start")
|
||||||
}
|
|
||||||
|
|
||||||
// ReadLines читает даденный файл построчно в массив строк.
|
|
||||||
func ReadLines(path string) ([]string, error) {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func(file *os.File) {
|
|
||||||
err := file.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Unable to close file %s:%s", path, err)
|
|
||||||
}
|
|
||||||
}(file)
|
|
||||||
|
|
||||||
var (
|
|
||||||
lines []string
|
|
||||||
scanner = bufio.NewScanner(file)
|
|
||||||
)
|
|
||||||
|
|
||||||
for scanner.Scan() {
|
|
||||||
lines = append(lines, scanner.Text())
|
|
||||||
}
|
|
||||||
|
|
||||||
return lines, scanner.Err()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
36
internal/webapp/ReadLines.go
Normal file
36
internal/webapp/ReadLines.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package webapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"aleesa-webapp-go/internal/log"
|
||||||
|
"bufio"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReadLines читает даденный файл построчно в массив строк.
|
||||||
|
func ReadLines(path string) ([]string, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func(file *os.File) {
|
||||||
|
err := file.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Unable to close file %s:%s", path, err)
|
||||||
|
}
|
||||||
|
}(file)
|
||||||
|
|
||||||
|
var (
|
||||||
|
lines []string
|
||||||
|
scanner = bufio.NewScanner(file)
|
||||||
|
)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
lines = append(lines, scanner.Text())
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines, scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
66
internal/webapp/ValidateRmsg.go
Normal file
66
internal/webapp/ValidateRmsg.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package webapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"aleesa-webapp-go/internal/config"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValidateRmsg валидирует входящее сообщение.
|
||||||
|
func ValidateRmsg(cfg *config.MyConfig, j RMsg, msg string) (RMsg, error) {
|
||||||
|
if exist := j.From; exist == "" {
|
||||||
|
emsg := fmt.Errorf("incorrect msg from redis, no from field: %s", msg)
|
||||||
|
|
||||||
|
return j, emsg
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist := j.Chatid; exist == "" {
|
||||||
|
emsg := fmt.Errorf("incorrect msg from redis, no chatid field: %s", msg)
|
||||||
|
|
||||||
|
return j, emsg
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist := j.Userid; exist == "" {
|
||||||
|
emsg := fmt.Errorf("incorrect msg from redis, no userid field: %s", msg)
|
||||||
|
|
||||||
|
return j, emsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// j.Threadid может быть пустым, значит либо нам его не дали, либо дали пустым. Это нормально.
|
||||||
|
|
||||||
|
if exist := j.Message; exist == "" {
|
||||||
|
emsg := fmt.Errorf("incorrect msg from redis, no message field: %s", msg)
|
||||||
|
|
||||||
|
return j, emsg
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist := j.Plugin; exist == "" {
|
||||||
|
emsg := fmt.Errorf("incorrect msg from redis, no plugin field: %s", msg)
|
||||||
|
|
||||||
|
return j, emsg
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist := j.Mode; exist == "" {
|
||||||
|
emsg := fmt.Errorf("incorrect msg from redis, no mode field: %s", msg)
|
||||||
|
|
||||||
|
return j, emsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// j.Misc.Answer может и не быть, тогда ответа на такое сообщение не будет
|
||||||
|
// j.Misc.Botnick тоже можно не передавать, тогда будет записана пустая строка
|
||||||
|
// j.Misc.Csign если нам его не передали, возьмём значение из конфига
|
||||||
|
if exist := j.Misc.Csign; exist == "" {
|
||||||
|
j.Misc.Csign = cfg.Csign
|
||||||
|
}
|
||||||
|
|
||||||
|
// j.Misc.Fwdcnt если нам его не передали, то будет 0
|
||||||
|
if exist := j.Misc.Fwdcnt; exist == 0 {
|
||||||
|
j.Misc.Fwdcnt = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// j.Misc.GoodMorning может быть быть 1 или 0, по-умолчанию 0
|
||||||
|
// j.Misc.Msgformat может быть быть 1 или 0, по-умолчанию 0
|
||||||
|
// j.Misc.Username можно не передавать, тогда будет пустая строка
|
||||||
|
return j, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package defaults
|
package webapp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -6,14 +6,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ForwardMax int64 = 5
|
|
||||||
var ConfigFileSize int64 = 65535
|
|
||||||
var DataDir = "data"
|
|
||||||
var Host = "localhost"
|
|
||||||
var Loglevel = "info"
|
|
||||||
var RedisPort = 6379
|
|
||||||
var NetworkTimeout = 10
|
|
||||||
|
|
||||||
func DefaultConfigFileLocations() ([]string, error) {
|
func DefaultConfigFileLocations() ([]string, error) {
|
||||||
var locations []string
|
var locations []string
|
||||||
|
|
||||||
18
internal/webapp/globals.go
Normal file
18
internal/webapp/globals.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package webapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"aleesa-webapp-go/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ForwardMax int64 = 5
|
||||||
|
ConfigFileSize int64 = 65535
|
||||||
|
DataDir = "data"
|
||||||
|
Host = "localhost"
|
||||||
|
Loglevel = "info"
|
||||||
|
RedisPort = 6379
|
||||||
|
NetworkTimeout = 10
|
||||||
|
Config *config.MyConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package types
|
package webapp
|
||||||
|
|
||||||
// RMsg структурка, описывающая входящее сообщение из pubsub-канала redis-ки.
|
// RMsg структурка, описывающая входящее сообщение из pubsub-канала redis-ки.
|
||||||
type RMsg struct {
|
type RMsg struct {
|
||||||
Reference in New Issue
Block a user