2022-04-27 00:19:05 -04:00
|
|
|
package app
|
2022-04-26 09:55:59 -04:00
|
|
|
|
|
|
|
import (
|
2022-05-27 18:26:30 -04:00
|
|
|
"fmt"
|
2022-04-26 09:55:59 -04:00
|
|
|
"os"
|
2022-04-28 19:24:21 -04:00
|
|
|
"path"
|
2022-04-26 09:55:59 -04:00
|
|
|
|
2022-05-03 17:14:37 -04:00
|
|
|
"go.balki.me/tss/parser"
|
2022-04-26 09:55:59 -04:00
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
)
|
|
|
|
|
2022-05-02 23:23:56 -04:00
|
|
|
type FeedLimit int
|
|
|
|
|
|
|
|
const NoLimit FeedLimit = -1
|
|
|
|
|
2022-05-27 18:26:30 -04:00
|
|
|
type FeedURL []string
|
|
|
|
|
2022-04-28 19:24:21 -04:00
|
|
|
type FeedCfg struct {
|
2022-06-20 19:31:28 -04:00
|
|
|
// Unique identifier for the feed. Used as filename, so keep it simple
|
|
|
|
Name string `yaml:"name" jsonschema:"required"`
|
|
|
|
|
|
|
|
// Telegram channel name in the form "@foobar" or "-1004242442" (private)
|
|
|
|
Channel string `yaml:"channel" jsonschema:"required"`
|
|
|
|
|
|
|
|
// Telegram instant view rhash id, see https://instantview.telegram.org/#publishing-templates
|
|
|
|
Rhash string `yaml:"rhash" jsonschema:"default="`
|
|
|
|
|
|
|
|
// Feed Url, string or array of strings
|
|
|
|
// If array, all entries are merged, e.g ["https://example.com/blog/tag/foo/feed", "https://example.com/blog/tag/bar/feed" ]
|
|
|
|
Url FeedURL `yaml:"url" jsonschema:"required,oneof_type=string;array"`
|
|
|
|
|
|
|
|
// Cron expression, see https://pkg.go.dev/github.com/robfig/cron#hdr-CRON_Expression_Format
|
|
|
|
Cron string `yaml:"cron" jsonschema:"required"`
|
|
|
|
|
|
|
|
// Proxy for this feed if different from global
|
|
|
|
Proxy string `yaml:"proxy" jsonschema:"default=<global proxy>"`
|
|
|
|
|
|
|
|
// Rss or Atom feed
|
|
|
|
Type parser.FeedType `yaml:"type" jsonschema:"required,enum=rss,enum=atom"`
|
|
|
|
|
|
|
|
// Text of the link sent to telegram,
|
|
|
|
Title string `yaml:"title" jsonschema:"default=Link"`
|
|
|
|
|
|
|
|
// Number of entries to process when the feed is seen for the first time
|
|
|
|
FTL *int `yaml:"first_time_limit" jsonschema:"default=<global value>"`
|
|
|
|
|
|
|
|
FirstTimeLimit FeedLimit `yaml:"-"`
|
2022-04-28 19:24:21 -04:00
|
|
|
}
|
|
|
|
|
2022-04-26 09:55:59 -04:00
|
|
|
type Config struct {
|
2022-06-20 19:31:28 -04:00
|
|
|
// default proxy url that http.Client can understand
|
|
|
|
// or socks5://unix/path/to/sock for socks proxy over unix socket
|
|
|
|
// empty for no proxy
|
|
|
|
Proxy string `yaml:"proxy" jsonschema:"default="`
|
|
|
|
|
|
|
|
// proxy for telegram if different from default
|
|
|
|
// NONE to not use global default
|
|
|
|
TelegramProxy string `yaml:"telegram_proxy" jsonschema:"default=<global proxy>"`
|
|
|
|
|
|
|
|
// Auth token for telegram in the form of 424242424:AB02132skdcjlisjkjflewjlfkjslkfHHXX
|
|
|
|
TelegramAuthToken string `yaml:"telegram_auth_token" jsonschema:"required"` //TODO: read from credential file
|
|
|
|
|
|
|
|
// Base directory to write feed data and schedule file
|
|
|
|
DataDir string `yaml:"data_dir" jsonschema:"default=./"`
|
|
|
|
|
|
|
|
// Path to the file where last success time for each feed is saved
|
|
|
|
LastSuccessPath string `yaml:"last_loaded_path" jsonschema:"default=<datadir>/last_success.yml"`
|
|
|
|
|
|
|
|
// Path to the directory where feed content is saved
|
|
|
|
DbDir string `yaml:"db_dir" jsonschema:"default=<datadir>/feed_data"`
|
|
|
|
|
|
|
|
// Number of entries to process when the feed is seen for the first time
|
|
|
|
// -1 means no limit
|
|
|
|
FTL *int `yaml:"first_time_limit" jsonschema:"default=-1"`
|
|
|
|
|
|
|
|
// Feed config
|
|
|
|
Feeds []FeedCfg `yaml:"feeds" jsonschema:"required"`
|
2022-04-26 09:55:59 -04:00
|
|
|
}
|
|
|
|
|
2022-04-27 00:19:05 -04:00
|
|
|
func ParseConfig(configPath string) (*Config, error) {
|
2022-04-28 19:24:21 -04:00
|
|
|
|
2022-04-27 00:19:05 -04:00
|
|
|
cfg, err := os.ReadFile(configPath)
|
2022-04-26 09:55:59 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
c := Config{}
|
|
|
|
err = yaml.Unmarshal(cfg, &c)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-04-28 19:24:21 -04:00
|
|
|
if c.DataDir == "" {
|
|
|
|
c.DataDir = "."
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.LastSuccessPath == "" {
|
|
|
|
c.LastSuccessPath = path.Join(c.DataDir, "last_success.yml")
|
|
|
|
}
|
|
|
|
|
2022-05-01 15:32:41 -04:00
|
|
|
if c.DbDir == "" {
|
|
|
|
c.DbDir = path.Join(c.DataDir, "feed_data")
|
|
|
|
}
|
|
|
|
|
2022-05-02 23:23:56 -04:00
|
|
|
err = os.MkdirAll(c.DbDir, 0755)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = os.MkdirAll(c.DataDir, 0755)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-05-01 19:13:27 -04:00
|
|
|
if c.Proxy != "" {
|
|
|
|
if c.TelegramProxy == "" {
|
|
|
|
c.TelegramProxy = c.Proxy
|
|
|
|
}
|
|
|
|
for i, _ := range c.Feeds {
|
|
|
|
feedCfg := &c.Feeds[i]
|
|
|
|
if feedCfg.Proxy == "" {
|
|
|
|
feedCfg.Proxy = c.Proxy
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-02 11:36:24 -04:00
|
|
|
if c.TelegramProxy == "NONE" {
|
|
|
|
c.TelegramProxy = ""
|
|
|
|
}
|
|
|
|
|
2022-05-01 19:13:27 -04:00
|
|
|
for i, _ := range c.Feeds {
|
|
|
|
feedCfg := &c.Feeds[i]
|
|
|
|
if feedCfg.Proxy == "NONE" {
|
|
|
|
feedCfg.Proxy = ""
|
|
|
|
}
|
2022-05-02 23:23:56 -04:00
|
|
|
if feedCfg.FTL != nil {
|
|
|
|
feedCfg.FirstTimeLimit = FeedLimit(*feedCfg.FTL)
|
|
|
|
} else if c.FTL != nil {
|
|
|
|
feedCfg.FirstTimeLimit = FeedLimit(*c.FTL)
|
|
|
|
} else {
|
|
|
|
feedCfg.FirstTimeLimit = NoLimit
|
|
|
|
}
|
2022-05-01 19:13:27 -04:00
|
|
|
}
|
|
|
|
|
2022-04-26 09:55:59 -04:00
|
|
|
return &c, nil
|
|
|
|
}
|
2022-05-27 18:26:30 -04:00
|
|
|
|
|
|
|
func (fu *FeedURL) UnmarshalYAML(node *yaml.Node) error {
|
|
|
|
switch node.Kind {
|
|
|
|
case yaml.SequenceNode:
|
|
|
|
return node.Decode((*[]string)(fu))
|
|
|
|
case yaml.ScalarNode:
|
2022-05-27 23:05:59 -04:00
|
|
|
*fu = []string{""}
|
2022-05-27 18:26:30 -04:00
|
|
|
return node.Decode(&(*fu)[0])
|
|
|
|
}
|
|
|
|
return fmt.Errorf("unexpected node type: %s, at %d:%d", node.ShortTag(), node.Line, node.Column)
|
|
|
|
}
|