diff --git a/pkg/api/api.go b/pkg/api/api.go index 84f011c..beb583a 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -1,8 +1,6 @@ package api import ( - "time" - "github.com/pkg/errors" ) @@ -46,18 +44,10 @@ const ( DefaultQuality = QualityHigh ) -type Feed struct { - Id int64 `json:"id"` - HashId string `json:"hash_id"` // Short human readable feed id for users - UserId string `json:"user_id"` // Patreon user id - ItemId string `json:"item_id"` - Provider Provider `json:"provider"` // Youtube or Vimeo - LinkType LinkType `json:"link_type"` // Either group, channel or user - PageSize int `json:"page_size"` // The number of episodes to return - Format Format `json:"format"` - Quality Quality `json:"quality"` - FeatureLevel int `json:"feature_level"` // Available features - LastAccess time.Time `json:"last_access"` +type Metadata struct { + Provider Provider `json:"provider"` + Format Format `json:"format"` + Quality Quality `json:"quality"` } const ( diff --git a/pkg/builders/common.go b/pkg/builders/common.go index 867e61d..fd295fb 100644 --- a/pkg/builders/common.go +++ b/pkg/builders/common.go @@ -5,6 +5,7 @@ import ( itunes "github.com/mxpv/podcast" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" ) const ( @@ -12,7 +13,7 @@ const ( defaultCategory = "TV & Film" ) -func makeEnclosure(feed *api.Feed, id string, lengthInBytes int64) (string, itunes.EnclosureType, int64) { +func makeEnclosure(feed *model.Feed, id string, lengthInBytes int64) (string, itunes.EnclosureType, int64) { ext := "mp4" contentType := itunes.MP4 if feed.Format == api.FormatAudio { @@ -20,6 +21,6 @@ func makeEnclosure(feed *api.Feed, id string, lengthInBytes int64) (string, itun contentType = itunes.M4A } - url := fmt.Sprintf("https://podsync.net/download/%s/%s.%s", feed.HashId, id, ext) + url := fmt.Sprintf("https://podsync.net/download/%s/%s.%s", feed.HashID, id, ext) return url, contentType, lengthInBytes } diff --git a/pkg/builders/vimeo.go b/pkg/builders/vimeo.go index 2800060..4824c20 100644 --- a/pkg/builders/vimeo.go +++ b/pkg/builders/vimeo.go @@ -6,6 +6,7 @@ import ( itunes "github.com/mxpv/podcast" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/pkg/errors" "github.com/silentsokolov/go-vimeo" "golang.org/x/net/context" @@ -32,8 +33,8 @@ func (v *VimeoBuilder) selectImage(p *vimeo.Pictures, q api.Quality) string { } } -func (v *VimeoBuilder) queryChannel(feed *api.Feed) (*itunes.Podcast, error) { - channelId := feed.ItemId +func (v *VimeoBuilder) queryChannel(feed *model.Feed) (*itunes.Podcast, error) { + channelId := feed.ItemID ch, resp, err := v.client.Channels.Get(channelId) if err != nil { @@ -54,8 +55,8 @@ func (v *VimeoBuilder) queryChannel(feed *api.Feed) (*itunes.Podcast, error) { return &podcast, nil } -func (v *VimeoBuilder) queryGroup(feed *api.Feed) (*itunes.Podcast, error) { - groupId := feed.ItemId +func (v *VimeoBuilder) queryGroup(feed *model.Feed) (*itunes.Podcast, error) { + groupId := feed.ItemID gr, resp, err := v.client.Groups.Get(groupId) if err != nil { @@ -76,8 +77,8 @@ func (v *VimeoBuilder) queryGroup(feed *api.Feed) (*itunes.Podcast, error) { return &podcast, nil } -func (v *VimeoBuilder) queryUser(feed *api.Feed) (*itunes.Podcast, error) { - userId := feed.ItemId +func (v *VimeoBuilder) queryUser(feed *model.Feed) (*itunes.Podcast, error) { + userId := feed.ItemID user, resp, err := v.client.Users.Get(userId) if err != nil { @@ -105,7 +106,7 @@ func (v *VimeoBuilder) getVideoSize(video *vimeo.Video) int64 { type getVideosFunc func(id string, opt *vimeo.ListVideoOptions) ([]*vimeo.Video, *vimeo.Response, error) -func (v *VimeoBuilder) queryVideos(getVideos getVideosFunc, podcast *itunes.Podcast, feed *api.Feed) error { +func (v *VimeoBuilder) queryVideos(getVideos getVideosFunc, podcast *itunes.Podcast, feed *model.Feed) error { opt := vimeo.ListVideoOptions{} opt.Page = 1 opt.PerPage = vimeoDefaultPageSize @@ -113,7 +114,7 @@ func (v *VimeoBuilder) queryVideos(getVideos getVideosFunc, podcast *itunes.Podc added := 0 for { - videos, response, err := getVideos(feed.ItemId, &opt) + videos, response, err := getVideos(feed.ItemID, &opt) if err != nil { return errors.Wrapf(err, "failed to query videos (error %d %s)", response.StatusCode, response.Status) } @@ -152,7 +153,7 @@ func (v *VimeoBuilder) queryVideos(getVideos getVideosFunc, podcast *itunes.Podc } } -func (v *VimeoBuilder) Build(feed *api.Feed) (podcast *itunes.Podcast, err error) { +func (v *VimeoBuilder) Build(feed *model.Feed) (podcast *itunes.Podcast, err error) { if feed.LinkType == api.LinkTypeChannel { if podcast, err = v.queryChannel(feed); err == nil { err = v.queryVideos(v.client.Channels.ListVideo, podcast, feed) diff --git a/pkg/builders/vimeo_test.go b/pkg/builders/vimeo_test.go index da1ea95..827e82b 100644 --- a/pkg/builders/vimeo_test.go +++ b/pkg/builders/vimeo_test.go @@ -7,6 +7,7 @@ import ( itunes "github.com/mxpv/podcast" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/stretchr/testify/require" ) @@ -18,7 +19,7 @@ func TestQueryVimeoChannel(t *testing.T) { builder, err := NewVimeoBuilder(context.Background(), vimeoKey) require.NoError(t, err) - podcast, err := builder.queryChannel(&api.Feed{ItemId: "staffpicks", Quality: api.QualityHigh}) + podcast, err := builder.queryChannel(&model.Feed{ItemID: "staffpicks", Quality: api.QualityHigh}) require.NoError(t, err) require.Equal(t, "https://vimeo.com/channels/staffpicks", podcast.Link) @@ -33,7 +34,7 @@ func TestQueryVimeoGroup(t *testing.T) { builder, err := NewVimeoBuilder(context.Background(), vimeoKey) require.NoError(t, err) - podcast, err := builder.queryGroup(&api.Feed{ItemId: "motion", Quality: api.QualityHigh}) + podcast, err := builder.queryGroup(&model.Feed{ItemID: "motion", Quality: api.QualityHigh}) require.NoError(t, err) require.Equal(t, "https://vimeo.com/groups/motion", podcast.Link) @@ -48,7 +49,7 @@ func TestQueryVimeoUser(t *testing.T) { builder, err := NewVimeoBuilder(context.Background(), vimeoKey) require.NoError(t, err) - podcast, err := builder.queryUser(&api.Feed{ItemId: "motionarray", Quality: api.QualityHigh}) + podcast, err := builder.queryUser(&model.Feed{ItemID: "motionarray", Quality: api.QualityHigh}) require.NoError(t, err) require.Equal(t, "https://vimeo.com/motionarray", podcast.Link) @@ -63,7 +64,7 @@ func TestQueryVimeoVideos(t *testing.T) { feed := &itunes.Podcast{} - err = builder.queryVideos(builder.client.Channels.ListVideo, feed, &api.Feed{ItemId: "staffpicks"}) + err = builder.queryVideos(builder.client.Channels.ListVideo, feed, &model.Feed{ItemID: "staffpicks"}) require.NoError(t, err) require.Equal(t, vimeoDefaultPageSize, len(feed.Items)) diff --git a/pkg/builders/youtube.go b/pkg/builders/youtube.go index 883d331..f3279dd 100644 --- a/pkg/builders/youtube.go +++ b/pkg/builders/youtube.go @@ -9,6 +9,7 @@ import ( "github.com/BrianHicks/finch/duration" itunes "github.com/mxpv/podcast" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/pkg/errors" "google.golang.org/api/youtube/v3" ) @@ -130,11 +131,11 @@ func (yt *YouTubeBuilder) selectThumbnail(snippet *youtube.ThumbnailDetails, qua // Cost: // - 5 units for channel or user // - 3 units for playlist -func (yt *YouTubeBuilder) queryFeed(feed *api.Feed) (*itunes.Podcast, string, error) { +func (yt *YouTubeBuilder) queryFeed(feed *model.Feed) (*itunes.Podcast, string, error) { now := time.Now() if feed.LinkType == api.LinkTypeChannel || feed.LinkType == api.LinkTypeUser { - channel, err := yt.listChannels(feed.LinkType, feed.ItemId) + channel, err := yt.listChannels(feed.LinkType, feed.ItemID) if err != nil { return nil, "", err } @@ -166,7 +167,7 @@ func (yt *YouTubeBuilder) queryFeed(feed *api.Feed) (*itunes.Podcast, string, er } if feed.LinkType == api.LinkTypePlaylist { - playlist, err := yt.listPlaylists(feed.ItemId, "") + playlist, err := yt.listPlaylists(feed.ItemID, "") if err != nil { return nil, "", err } @@ -197,7 +198,7 @@ func (yt *YouTubeBuilder) queryFeed(feed *api.Feed) (*itunes.Podcast, string, er // Video size information requires 1 additional call for each video (1 feed = 50 videos = 50 calls), // which is too expensive, so get approximated size depending on duration and definition params -func (yt *YouTubeBuilder) getSize(duration int64, feed *api.Feed) int64 { +func (yt *YouTubeBuilder) getSize(duration int64, feed *model.Feed) int64 { if feed.Format == api.FormatAudio { if feed.Quality == api.QualityHigh { return highAudioBytesPerSecond * duration @@ -215,7 +216,7 @@ func (yt *YouTubeBuilder) getSize(duration int64, feed *api.Feed) int64 { // Cost: 5 units (call: 1, snippet: 2, contentDetails: 2) // See https://developers.google.com/youtube/v3/docs/videos/list#part -func (yt *YouTubeBuilder) queryVideoDescriptions(playlistItems map[string]*youtube.PlaylistItemSnippet, feed *api.Feed, podcast *itunes.Podcast) error { +func (yt *YouTubeBuilder) queryVideoDescriptions(playlistItems map[string]*youtube.PlaylistItemSnippet, feed *model.Feed, podcast *itunes.Podcast) error { // Make the list of video ids ids := make([]string, 0, len(playlistItems)) for _, s := range playlistItems { @@ -290,7 +291,7 @@ func (yt *YouTubeBuilder) queryVideoDescriptions(playlistItems map[string]*youtu } // Cost: (3 units + 5 units) * X pages = 8 units per page -func (yt *YouTubeBuilder) queryItems(itemId string, feed *api.Feed, podcast *itunes.Podcast) error { +func (yt *YouTubeBuilder) queryItems(itemId string, feed *model.Feed, podcast *itunes.Podcast) error { pageToken := "" count := 0 @@ -322,7 +323,7 @@ func (yt *YouTubeBuilder) queryItems(itemId string, feed *api.Feed, podcast *itu } } -func (yt *YouTubeBuilder) Build(feed *api.Feed) (*itunes.Podcast, error) { +func (yt *YouTubeBuilder) Build(feed *model.Feed) (*itunes.Podcast, error) { // Query general information about feed (title, description, lang, etc) diff --git a/pkg/feeds/feeds.go b/pkg/feeds/feeds.go index 0f7afb7..32c1332 100644 --- a/pkg/feeds/feeds.go +++ b/pkg/feeds/feeds.go @@ -6,6 +6,7 @@ import ( itunes "github.com/mxpv/podcast" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/pkg/errors" ) @@ -14,16 +15,16 @@ const ( ) type idService interface { - Generate(feed *api.Feed) (string, error) + Generate(feed *model.Feed) (string, error) } type storageService interface { - CreateFeed(feed *api.Feed) error - GetFeed(hashId string) (*api.Feed, error) + CreateFeed(feed *model.Feed) error + GetFeed(hashId string) (*model.Feed, error) } type builder interface { - Build(feed *api.Feed) (podcast *itunes.Podcast, err error) + Build(feed *model.Feed) (podcast *itunes.Podcast, err error) } type service struct { @@ -52,7 +53,7 @@ func (s *service) CreateFeed(req *api.CreateFeedRequest, identity *api.Identity) feed.LastAccess = time.Now().UTC() if identity.FeatureLevel > 0 { - feed.UserId = identity.UserId + feed.UserID = identity.UserId feed.Quality = req.Quality feed.Format = req.Format feed.FeatureLevel = identity.FeatureLevel @@ -68,7 +69,7 @@ func (s *service) CreateFeed(req *api.CreateFeedRequest, identity *api.Identity) return "", errors.Wrap(err, "failed to generate id for feed") } - feed.HashId = hashId + feed.HashID = hashId // Save to database if err := s.storage.CreateFeed(feed); err != nil { @@ -79,7 +80,7 @@ func (s *service) CreateFeed(req *api.CreateFeedRequest, identity *api.Identity) } func (s *service) GetFeed(hashId string) (*itunes.Podcast, error) { - feed, err := s.GetMetadata(hashId) + feed, err := s.storage.GetFeed(hashId) if err != nil { return nil, err } @@ -92,24 +93,36 @@ func (s *service) GetFeed(hashId string) (*itunes.Podcast, error) { return builder.Build(feed) } -func (s *service) GetMetadata(hashId string) (*api.Feed, error) { - return s.storage.GetFeed(hashId) +func (s *service) GetMetadata(hashId string) (*api.Metadata, error) { + feed, err := s.storage.GetFeed(hashId) + if err != nil { + return nil, err + } + + return &api.Metadata{ + Provider: feed.Provider, + Format: feed.Format, + Quality: feed.Quality, + }, nil } type feedOption func(*service) +//noinspection GoExportedFuncWithUnexportedType func WithStorage(storage storageService) feedOption { return func(service *service) { service.storage = storage } } +//noinspection GoExportedFuncWithUnexportedType func WithIdGen(id idService) feedOption { return func(service *service) { service.id = id } } +//noinspection GoExportedFuncWithUnexportedType func WithBuilder(provider api.Provider, builder builder) feedOption { return func(service *service) { service.builders[provider] = builder diff --git a/pkg/feeds/feeds_mock_test.go b/pkg/feeds/feeds_mock_test.go index cc1cdcc..6676e11 100644 --- a/pkg/feeds/feeds_mock_test.go +++ b/pkg/feeds/feeds_mock_test.go @@ -6,7 +6,7 @@ package feeds import ( gomock "github.com/golang/mock/gomock" podcast "github.com/mxpv/podcast" - api "github.com/mxpv/podsync/pkg/api" + model "github.com/mxpv/podsync/pkg/model" reflect "reflect" ) @@ -34,7 +34,7 @@ func (_m *MockidService) EXPECT() *MockidServiceMockRecorder { } // Generate mocks base method -func (_m *MockidService) Generate(feed *api.Feed) (string, error) { +func (_m *MockidService) Generate(feed *model.Feed) (string, error) { ret := _m.ctrl.Call(_m, "Generate", feed) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) @@ -70,7 +70,7 @@ func (_m *MockstorageService) EXPECT() *MockstorageServiceMockRecorder { } // CreateFeed mocks base method -func (_m *MockstorageService) CreateFeed(feed *api.Feed) error { +func (_m *MockstorageService) CreateFeed(feed *model.Feed) error { ret := _m.ctrl.Call(_m, "CreateFeed", feed) ret0, _ := ret[0].(error) return ret0 @@ -82,9 +82,9 @@ func (_mr *MockstorageServiceMockRecorder) CreateFeed(arg0 interface{}) *gomock. } // GetFeed mocks base method -func (_m *MockstorageService) GetFeed(hashId string) (*api.Feed, error) { +func (_m *MockstorageService) GetFeed(hashId string) (*model.Feed, error) { ret := _m.ctrl.Call(_m, "GetFeed", hashId) - ret0, _ := ret[0].(*api.Feed) + ret0, _ := ret[0].(*model.Feed) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -118,7 +118,7 @@ func (_m *Mockbuilder) EXPECT() *MockbuilderMockRecorder { } // Build mocks base method -func (_m *Mockbuilder) Build(feed *api.Feed) (*podcast.Podcast, error) { +func (_m *Mockbuilder) Build(feed *model.Feed) (*podcast.Podcast, error) { ret := _m.ctrl.Call(_m, "Build", feed) ret0, _ := ret[0].(*podcast.Podcast) ret1, _ := ret[1].(error) diff --git a/pkg/feeds/feeds_test.go b/pkg/feeds/feeds_test.go index 14247e0..a8c16eb 100644 --- a/pkg/feeds/feeds_test.go +++ b/pkg/feeds/feeds_test.go @@ -7,6 +7,7 @@ import ( "github.com/golang/mock/gomock" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/stretchr/testify/require" ) @@ -42,7 +43,7 @@ func TestService_GetFeed(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - feed := &api.Feed{Provider: api.ProviderYoutube} + feed := &model.Feed{Provider: api.ProviderYoutube} storage := NewMockstorageService(ctrl) storage.EXPECT().GetFeed("123").Times(1).Return(feed, nil) @@ -64,7 +65,7 @@ func TestService_GetMetadata(t *testing.T) { defer ctrl.Finish() storage := NewMockstorageService(ctrl) - storage.EXPECT().GetFeed("123").Times(1).Return(&api.Feed{}, nil) + storage.EXPECT().GetFeed("123").Times(1).Return(&model.Feed{}, nil) s := service{storage: storage} _, err := s.GetMetadata("123") diff --git a/pkg/feeds/url.go b/pkg/feeds/url.go index 1462402..31d32cb 100644 --- a/pkg/feeds/url.go +++ b/pkg/feeds/url.go @@ -5,10 +5,11 @@ import ( "strings" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/pkg/errors" ) -func parseURL(link string) (*api.Feed, error) { +func parseURL(link string) (*model.Feed, error) { if !strings.HasPrefix(link, "http") { link = "https://" + link } @@ -19,7 +20,7 @@ func parseURL(link string) (*api.Feed, error) { return nil, err } - feed := &api.Feed{} + feed := &model.Feed{} if strings.HasSuffix(parsed.Host, "youtube.com") { kind, id, err := parseYoutubeURL(parsed) @@ -29,7 +30,7 @@ func parseURL(link string) (*api.Feed, error) { feed.Provider = api.ProviderYoutube feed.LinkType = kind - feed.ItemId = id + feed.ItemID = id return feed, nil } @@ -42,7 +43,7 @@ func parseURL(link string) (*api.Feed, error) { feed.Provider = api.ProviderVimeo feed.LinkType = kind - feed.ItemId = id + feed.ItemID = id return feed, nil } diff --git a/pkg/handler/handler.go b/pkg/handler/handler.go index 806857c..d379cfd 100644 --- a/pkg/handler/handler.go +++ b/pkg/handler/handler.go @@ -25,7 +25,7 @@ const ( type feedService interface { CreateFeed(req *api.CreateFeedRequest, identity *api.Identity) (string, error) GetFeed(hashId string) (*itunes.Podcast, error) - GetMetadata(hashId string) (*api.Feed, error) + GetMetadata(hashId string) (*api.Metadata, error) } type patreonService interface { diff --git a/pkg/handler/handler_mock_test.go b/pkg/handler/handler_mock_test.go index 050eb6a..41e4013 100644 --- a/pkg/handler/handler_mock_test.go +++ b/pkg/handler/handler_mock_test.go @@ -61,9 +61,9 @@ func (_mr *MockfeedServiceMockRecorder) GetFeed(arg0 interface{}) *gomock.Call { } // GetMetadata mocks base method -func (_m *MockfeedService) GetMetadata(hashId string) (*api.Feed, error) { +func (_m *MockfeedService) GetMetadata(hashId string) (*api.Metadata, error) { ret := _m.ctrl.Call(_m, "GetMetadata", hashId) - ret0, _ := ret[0].(*api.Feed) + ret0, _ := ret[0].(*api.Metadata) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/pkg/handler/handler_test.go b/pkg/handler/handler_test.go index 593c8ac..367e334 100644 --- a/pkg/handler/handler_test.go +++ b/pkg/handler/handler_test.go @@ -116,7 +116,7 @@ func TestGetMetadata(t *testing.T) { defer ctrl.Finish() feed := NewMockfeedService(ctrl) - feed.EXPECT().GetMetadata("123").Times(1).Return(&api.Feed{}, nil) + feed.EXPECT().GetMetadata("123").Times(1).Return(&api.Metadata{}, nil) srv := httptest.NewServer(New(feed, nil, cfg)) defer srv.Close() diff --git a/pkg/id/hashids.go b/pkg/id/hashids.go index 44c1314..1500f36 100644 --- a/pkg/id/hashids.go +++ b/pkg/id/hashids.go @@ -4,7 +4,7 @@ import ( "hash/fnv" "time" - "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/ventu-io/go-shortid" ) @@ -18,7 +18,7 @@ func hashString(s string) int { return int(h.Sum32()) } -func (h *hashId) Generate(feed *api.Feed) (string, error) { +func (h *hashId) Generate(feed *model.Feed) (string, error) { return h.sid.Generate() } diff --git a/pkg/storage/pg.go b/pkg/storage/pg.go index a88cb6c..a558f71 100644 --- a/pkg/storage/pg.go +++ b/pkg/storage/pg.go @@ -8,7 +8,7 @@ import ( "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/proxy" "github.com/go-pg/pg" - "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/pkg/errors" ) @@ -20,7 +20,7 @@ type PgStorage struct { db *pg.DB } -func (p *PgStorage) CreateFeed(feed *api.Feed) error { +func (p *PgStorage) CreateFeed(feed *model.Feed) error { feed.LastAccess = time.Now().UTC() _, err := p.db.Model(feed).OnConflict("DO NOTHING").Insert() if err != nil { @@ -30,10 +30,10 @@ func (p *PgStorage) CreateFeed(feed *api.Feed) error { return nil } -func (p *PgStorage) GetFeed(hashId string) (*api.Feed, error) { +func (p *PgStorage) GetFeed(hashId string) (*model.Feed, error) { lastAccess := time.Now().UTC() - feed := &api.Feed{} + feed := &model.Feed{} _, err := p.db.Model(feed). Set("last_access = ?", lastAccess). Where("hash_id = ?", hashId). diff --git a/pkg/storage/pg_sql.go b/pkg/storage/pg_sql.go index 4a74a61..d082aee 100644 --- a/pkg/storage/pg_sql.go +++ b/pkg/storage/pg_sql.go @@ -21,7 +21,7 @@ END $$; CREATE TABLE IF NOT EXISTS feeds ( - id BIGSERIAL PRIMARY KEY, + feed_id BIGSERIAL PRIMARY KEY, hash_id VARCHAR(12) NOT NULL CHECK (hash_id <> '') UNIQUE, user_id VARCHAR(32) NULL, item_id VARCHAR(32) NOT NULL CHECK (item_id <> ''), diff --git a/pkg/storage/pg_test.go b/pkg/storage/pg_test.go index 11b9979..97858db 100644 --- a/pkg/storage/pg_test.go +++ b/pkg/storage/pg_test.go @@ -4,29 +4,30 @@ import ( "testing" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/stretchr/testify/require" ) func TestPgStorage_CreateFeed(t *testing.T) { - feed := &api.Feed{ - HashId: "xyz", + feed := &model.Feed{ + HashID: "xyz", Provider: api.ProviderYoutube, LinkType: api.LinkTypeChannel, - ItemId: "123", + ItemID: "123", } client := createClient(t) err := client.CreateFeed(feed) require.NoError(t, err) - require.True(t, feed.Id > 0) + require.True(t, feed.FeedID > 0) } func TestPgStorage_CreateFeedWithDuplicate(t *testing.T) { - feed := &api.Feed{ - HashId: "123", + feed := &model.Feed{ + HashID: "123", Provider: api.ProviderYoutube, LinkType: api.LinkTypeChannel, - ItemId: "123", + ItemID: "123", } client := createClient(t) @@ -34,7 +35,7 @@ func TestPgStorage_CreateFeedWithDuplicate(t *testing.T) { require.NoError(t, err) // Ensure 1 record - count, err := client.db.Model(&api.Feed{}).Count() + count, err := client.db.Model(&model.Feed{}).Count() require.NoError(t, err) require.Equal(t, 1, count) @@ -43,18 +44,18 @@ func TestPgStorage_CreateFeedWithDuplicate(t *testing.T) { require.NoError(t, err) // Check no duplicates inserted - count, err = client.db.Model(&api.Feed{}).Count() + count, err = client.db.Model(&model.Feed{}).Count() require.NoError(t, err) require.Equal(t, 1, count) } func TestPgStorage_GetFeed(t *testing.T) { - feed := &api.Feed{ - HashId: "xyz", - UserId: "123", + feed := &model.Feed{ + HashID: "xyz", + UserID: "123", Provider: api.ProviderYoutube, LinkType: api.LinkTypeChannel, - ItemId: "123", + ItemID: "123", } client := createClient(t) @@ -62,16 +63,16 @@ func TestPgStorage_GetFeed(t *testing.T) { out, err := client.GetFeed("xyz") require.NoError(t, err) - require.Equal(t, feed.Id, out.Id) + require.Equal(t, feed.FeedID, out.FeedID) } func TestPgStorage_UpdateLastAccess(t *testing.T) { - feed := &api.Feed{ - HashId: "xyz", - UserId: "123", + feed := &model.Feed{ + HashID: "xyz", + UserID: "123", Provider: api.ProviderYoutube, LinkType: api.LinkTypeChannel, - ItemId: "123", + ItemID: "123", } client := createClient(t) @@ -84,11 +85,11 @@ func TestPgStorage_UpdateLastAccess(t *testing.T) { last, err := client.GetFeed("xyz") require.NoError(t, err) - require.NotEmpty(t, last.HashId) - require.NotEmpty(t, last.UserId) + require.NotEmpty(t, last.HashID) + require.NotEmpty(t, last.UserID) require.NotEmpty(t, last.Provider) require.NotEmpty(t, last.LinkType) - require.NotEmpty(t, last.ItemId) + require.NotEmpty(t, last.ItemID) require.True(t, last.LastAccess.UnixNano() > lastAccess.UnixNano()) } @@ -99,7 +100,7 @@ func createClient(t *testing.T) *PgStorage { pg, err := NewPgStorage(&PgConfig{ConnectionUrl: TestDatabaseConnectionUrl}) require.NoError(t, err) - _, err = pg.db.Model(&api.Feed{}).Where("1=1").Delete() + _, err = pg.db.Model(&model.Feed{}).Where("1=1").Delete() require.NoError(t, err) return pg diff --git a/pkg/storage/redis.go b/pkg/storage/redis.go index 8bf5af6..9f56d20 100644 --- a/pkg/storage/redis.go +++ b/pkg/storage/redis.go @@ -8,6 +8,7 @@ import ( "github.com/go-redis/redis" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/pkg/errors" ) @@ -55,7 +56,7 @@ func (r *RedisStorage) parseFormat(m map[string]string) (api.Format, api.Quality return "", "", fmt.Errorf("unsupported formmat %s", quality) } -func (r *RedisStorage) GetFeed(hashId string) (*api.Feed, error) { +func (r *RedisStorage) GetFeed(hashId string) (*model.Feed, error) { result, err := r.client.HGetAll(hashId).Result() if err != nil { return nil, errors.Wrapf(err, "failed to query feed with id %s", hashId) @@ -70,11 +71,11 @@ func (r *RedisStorage) GetFeed(hashId string) (*api.Feed, error) { return nil, errors.Wrap(err, "failed query update feed") } - feed := &api.Feed{ + feed := &model.Feed{ PageSize: api.DefaultPageSize, Quality: api.DefaultQuality, Format: api.DefaultFormat, - HashId: hashId, + HashID: hashId, LastAccess: time.Now().UTC(), } @@ -122,12 +123,12 @@ func (r *RedisStorage) GetFeed(hashId string) (*api.Feed, error) { return nil, errors.New("failed to unpack item id") } - feed.ItemId = id + feed.ItemID = id // Fetch user id patreonId, ok := m["patreonid"] if ok { - feed.UserId = patreonId + feed.UserID = patreonId } // Unpack page size @@ -153,12 +154,12 @@ func (r *RedisStorage) GetFeed(hashId string) (*api.Feed, error) { return feed, nil } -func (r *RedisStorage) CreateFeed(feed *api.Feed) error { +func (r *RedisStorage) CreateFeed(feed *model.Feed) error { fields := map[string]interface{}{ "provider": string(feed.Provider), "type": string(feed.LinkType), - "id": feed.ItemId, - "patreonid": feed.UserId, + "id": feed.ItemID, + "patreonid": feed.UserID, "pagesize": feed.PageSize, } @@ -180,11 +181,11 @@ func (r *RedisStorage) CreateFeed(feed *api.Feed) error { } - if err := r.client.HMSet(feed.HashId, fields).Err(); err != nil { + if err := r.client.HMSet(feed.HashID, fields).Err(); err != nil { return errors.Wrap(err, "failed to save feed") } - return r.client.Expire(feed.HashId, expiration).Err() + return r.client.Expire(feed.HashID, expiration).Err() } func (r *RedisStorage) keys() ([]string, error) { diff --git a/pkg/storage/redis_test.go b/pkg/storage/redis_test.go index 46d26e0..04d13f8 100644 --- a/pkg/storage/redis_test.go +++ b/pkg/storage/redis_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/mxpv/podsync/pkg/api" + "github.com/mxpv/podsync/pkg/model" "github.com/stretchr/testify/require" ) @@ -37,12 +38,12 @@ func TestRedisStorage_CreateFeed(t *testing.T) { hashId := strconv.FormatInt(time.Now().UTC().UnixNano(), 10) - err := client.CreateFeed(&api.Feed{ - HashId: hashId, - UserId: "321", + err := client.CreateFeed(&model.Feed{ + HashID: hashId, + UserID: "321", Provider: api.ProviderYoutube, LinkType: api.LinkTypeChannel, - ItemId: "123", + ItemID: "123", PageSize: 45, Quality: api.QualityLow, Format: api.FormatAudio, @@ -53,11 +54,11 @@ func TestRedisStorage_CreateFeed(t *testing.T) { feed, err := client.GetFeed(hashId) require.NoError(t, err) - require.Equal(t, hashId, feed.HashId) - require.Equal(t, "321", feed.UserId) + require.Equal(t, hashId, feed.HashID) + require.Equal(t, "321", feed.UserID) require.Equal(t, api.ProviderYoutube, feed.Provider) require.Equal(t, api.LinkTypeChannel, feed.LinkType) - require.Equal(t, "123", feed.ItemId) + require.Equal(t, "123", feed.ItemID) require.Equal(t, 45, feed.PageSize) require.Equal(t, api.QualityLow, feed.Quality) require.Equal(t, api.FormatAudio, feed.Format)