From d1bd2c2d246f8def3c80811e9cebe608e7b2a16b Mon Sep 17 00:00:00 2001 From: Maksym Pavlenko Date: Mon, 20 Apr 2020 20:54:49 -0700 Subject: [PATCH] Integrate key providers --- cmd/podsync/updater.go | 14 +++++++++++++- pkg/config/config.go | 11 +---------- pkg/config/config_test.go | 14 +++++++------- pkg/feed/common.go | 18 ++++++++---------- pkg/feed/key.go | 11 +++++++++++ 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/cmd/podsync/updater.go b/cmd/podsync/updater.go index db425c7e..37d45409 100644 --- a/cmd/podsync/updater.go +++ b/cmd/podsync/updater.go @@ -31,14 +31,26 @@ type Updater struct { downloader Downloader db db.Storage fs fs.Storage + keys map[model.Provider]feed.KeyProvider } func NewUpdater(config *config.Config, downloader Downloader, db db.Storage, fs fs.Storage) (*Updater, error) { + keys := map[model.Provider]feed.KeyProvider{} + + for name, list := range config.Tokens { + provider, err := feed.NewKeyProvider(list) + if err != nil { + return nil, errors.Wrapf(err, "failed to create key provider for %q", name) + } + keys[name] = provider + } + return &Updater{ config: config, downloader: downloader, db: db, fs: fs, + keys: keys, }, nil } @@ -79,7 +91,7 @@ func (u *Updater) Update(ctx context.Context, feedConfig *config.Feed) error { // updateFeed pulls API for new episodes and saves them to database func (u *Updater) updateFeed(ctx context.Context, feedConfig *config.Feed) error { // Create an updater for this feed type - provider, err := feed.New(ctx, feedConfig, u.config.Tokens) + provider, err := feed.New(ctx, feedConfig, u.keys) if err != nil { return err } diff --git a/pkg/config/config.go b/pkg/config/config.go index 9e43e5a5..22414971 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -56,15 +56,6 @@ type Custom struct { Language string `toml:"lang"` } -type Tokens struct { - // YouTube API key. - // See https://developers.google.com/youtube/registering_an_application - YouTube StringSlice `toml:"youtube"` - // Vimeo developer key. - // See https://developer.vimeo.com/api/guides/start#generate-access-token - Vimeo StringSlice `toml:"vimeo"` -} - type Server struct { // Hostname to use for download links Hostname string `toml:"hostname"` @@ -123,7 +114,7 @@ type Config struct { // ID will be used as feed ID in http://podsync.net/{FEED_ID}.xml Feeds map[string]*Feed // Tokens is API keys to use to access YouTube/Vimeo APIs. - Tokens Tokens `toml:"tokens"` + Tokens map[model.Provider]StringSlice `toml:"tokens"` // Downloader (youtube-dl) configuration Downloader Downloader `toml:"downloader"` } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index b2372018..177a08cd 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -54,11 +54,11 @@ self_update = true assert.Equal(t, "/home/user/db/", config.Database.Dir) - require.Len(t, config.Tokens.YouTube, 1) - assert.Equal(t, "123", config.Tokens.YouTube[0]) - require.Len(t, config.Tokens.Vimeo, 2) - assert.Equal(t, "321", config.Tokens.Vimeo[0]) - assert.Equal(t, "456", config.Tokens.Vimeo[1]) + require.Len(t, config.Tokens["youtube"], 1) + assert.Equal(t, "123", config.Tokens["youtube"][0]) + require.Len(t, config.Tokens["vimeo"], 2) + assert.Equal(t, "321", config.Tokens["vimeo"][0]) + assert.Equal(t, "456", config.Tokens["vimeo"][1]) assert.Len(t, config.Feeds, 1) feed, ok := config.Feeds["XYZ"] @@ -99,8 +99,8 @@ data_dir = "/data" assert.NoError(t, err) require.NotNil(t, config) - require.Len(t, config.Tokens.YouTube, 0) - require.Len(t, config.Tokens.Vimeo, 0) + require.Len(t, config.Tokens, 1) + require.Len(t, config.Tokens["vimeo"], 0) } func TestApplyDefaults(t *testing.T) { diff --git a/pkg/feed/common.go b/pkg/feed/common.go index debaf51d..5f75def3 100644 --- a/pkg/feed/common.go +++ b/pkg/feed/common.go @@ -13,27 +13,25 @@ type Builder interface { Build(ctx context.Context, cfg *config.Feed) (*model.Feed, error) } -func New(ctx context.Context, cfg *config.Feed, tokens config.Tokens) (Builder, error) { - var ( - provider Builder - err error - ) - +func New(ctx context.Context, cfg *config.Feed, keys map[model.Provider]KeyProvider) (Builder, error) { info, err := ParseURL(cfg.URL) if err != nil { return nil, err } + keyProvider, ok := keys[info.Provider] + if !ok { + return nil, errors.Errorf("unknown key provider: %s", info.Provider) + } + switch info.Provider { case model.ProviderYoutube: - provider, err = NewYouTubeBuilder(tokens.YouTube[0]) + return NewYouTubeBuilder(keyProvider.Get()) case model.ProviderVimeo: - provider, err = NewVimeoBuilder(ctx, tokens.Vimeo[0]) + return NewVimeoBuilder(ctx, keyProvider.Get()) default: return nil, errors.Errorf("unsupported provider %q", info.Provider) } - - return provider, err } type feedProvider interface { diff --git a/pkg/feed/key.go b/pkg/feed/key.go index 8063b3cd..5872b92c 100644 --- a/pkg/feed/key.go +++ b/pkg/feed/key.go @@ -10,6 +10,17 @@ type KeyProvider interface { Get() string } +func NewKeyProvider(keys []string) (KeyProvider, error) { + switch len(keys) { + case 0: + return nil, errors.New("no keys") + case 1: + return NewFixedKey(keys[0]) + default: + return NewRotatedKeys(keys) + } +} + type FixedKeyProvider struct { key string }