Skip to content

Commit

Permalink
Refactor code to allow pluggable storages
Browse files Browse the repository at this point in the history
  • Loading branch information
mxpv committed Jan 2, 2022
1 parent 26f4b2a commit 12cdbf6
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 192 deletions.
7 changes: 3 additions & 4 deletions cmd/podsync/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ import (
"github.com/robfig/cron/v3"
log "github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
"gopkg.in/natefinch/lumberjack.v2"

"github.com/mxpv/podsync/pkg/config"
"github.com/mxpv/podsync/pkg/db"
"github.com/mxpv/podsync/pkg/fs"
"github.com/mxpv/podsync/pkg/ytdl"

"gopkg.in/natefinch/lumberjack.v2"
)

type Opts struct {
Expand Down Expand Up @@ -107,7 +106,7 @@ func main() {
log.WithError(err).Fatal("failed to open database")
}

storage, err := fs.NewLocal(cfg.Server.DataDir, cfg.Server.Hostname)
storage, err := fs.NewLocal(cfg.Server.DataDir)
if err != nil {
log.WithError(err).Fatal("failed to open storage")
}
Expand Down Expand Up @@ -178,7 +177,7 @@ func main() {
})

// Run web server
srv := NewServer(cfg)
srv := NewServer(cfg, storage)

group.Go(func() error {
log.Infof("running listener at %s", srv.Addr)
Expand Down
12 changes: 7 additions & 5 deletions cmd/podsync/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,26 @@ type Server struct {
http.Server
}

func NewServer(cfg *config.Config) *Server {
func NewServer(cfg *config.Config, storage http.FileSystem) *Server {
port := cfg.Server.Port
if port == 0 {
port = 8080
}

bindAddress := cfg.Server.BindAddress
if bindAddress == "*" {
bindAddress = ""
}

srv := Server{}

srv.Addr = fmt.Sprintf("%s:%d", bindAddress, port)
log.Debugf("using address: %s:%s", bindAddress, srv.Addr)

fs := http.FileServer(http.Dir(cfg.Server.DataDir))
path := cfg.Server.Path
http.Handle(fmt.Sprintf("/%s", path), fs)
log.Debugf("handle path: /%s", path)
fileServer := http.FileServer(storage)

log.Debugf("handle path: /%s", cfg.Server.Path)
http.Handle(fmt.Sprintf("/%s", cfg.Server.Path), fileServer)

return &srv
}
21 changes: 13 additions & 8 deletions cmd/podsync/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (u *Updater) downloadEpisodes(ctx context.Context, feedConfig *config.Feed)

// Limit the number of episodes downloaded at once
pageSize--
if pageSize <= 0 {
if pageSize < 0 {
return nil
}

Expand Down Expand Up @@ -235,7 +235,7 @@ func (u *Updater) downloadEpisodes(ctx context.Context, feedConfig *config.Feed)
)

// Check whether episode already exists
size, err := u.fs.Size(ctx, feedID, episodeName)
size, err := fs.Size(u.fs, fmt.Sprintf("%s/%s", feedID, episodeName))
if err == nil {
logger.Infof("episode %q already exists on disk", episode.ID)

Expand Down Expand Up @@ -283,7 +283,7 @@ func (u *Updater) downloadEpisodes(ctx context.Context, feedConfig *config.Feed)
}

logger.Debug("copying file")
fileSize, err := u.fs.Create(ctx, feedID, episodeName, tempFile)
fileSize, err := u.fs.Create(ctx, fmt.Sprintf("%s/%s", feedID, episodeName), tempFile)
tempFile.Close()
if err != nil {
logger.WithError(err).Error("failed to copy file")
Expand Down Expand Up @@ -316,7 +316,7 @@ func (u *Updater) buildXML(ctx context.Context, feedConfig *config.Feed) error {

// Build iTunes XML feed with data received from builder
log.Debug("building iTunes podcast feed")
podcast, err := feed.Build(ctx, f, feedConfig, u.fs)
podcast, err := feed.Build(ctx, f, feedConfig, u.config.Server.Hostname)
if err != nil {
return err
}
Expand All @@ -326,7 +326,7 @@ func (u *Updater) buildXML(ctx context.Context, feedConfig *config.Feed) error {
xmlName = fmt.Sprintf("%s.xml", feedConfig.ID)
)

if _, err := u.fs.Create(ctx, "", xmlName, reader); err != nil {
if _, err := u.fs.Create(ctx, xmlName, reader); err != nil {
return errors.Wrap(err, "failed to upload new XML feed")
}

Expand All @@ -336,7 +336,7 @@ func (u *Updater) buildXML(ctx context.Context, feedConfig *config.Feed) error {
func (u *Updater) buildOPML(ctx context.Context) error {
// Build OPML with data received from builder
log.Debug("building podcast OPML")
opml, err := feed.BuildOPML(ctx, u.config, u.db, u.fs)
opml, err := feed.BuildOPML(ctx, u.config, u.db, u.config.Server.Hostname)
if err != nil {
return err
}
Expand All @@ -346,7 +346,7 @@ func (u *Updater) buildOPML(ctx context.Context) error {
xmlName = fmt.Sprintf("%s.opml", "podsync")
)

if _, err := u.fs.Create(ctx, "", xmlName, reader); err != nil {
if _, err := u.fs.Create(ctx, xmlName, reader); err != nil {
return errors.Wrap(err, "failed to upload OPML")
}

Expand Down Expand Up @@ -388,7 +388,12 @@ func (u *Updater) cleanup(ctx context.Context, feedConfig *config.Feed) error {
for _, episode := range list[count:] {
logger.WithField("episode_id", episode.ID).Infof("deleting %q", episode.Title)

if err := u.fs.Delete(ctx, feedConfig.ID, feed.EpisodeName(feedConfig, episode)); err != nil {
var (
episodeName = feed.EpisodeName(feedConfig, episode)
path = fmt.Sprintf("%s/%s", feedConfig.ID, episodeName)
)

if err := u.fs.Delete(ctx, path); err != nil {
result = multierror.Append(result, errors.Wrapf(err, "failed to delete episode: %s", episode.ID))
continue
}
Expand Down
4 changes: 0 additions & 4 deletions pkg/feed/deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,3 @@ import (
type feedProvider interface {
GetFeed(ctx context.Context, feedID string) (*model.Feed, error)
}

type urlProvider interface {
URL(ctx context.Context, ns string, fileName string) (string, error)
}
53 changes: 8 additions & 45 deletions pkg/feed/deps_mock_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 3 additions & 7 deletions pkg/feed/opml.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package feed
import (
"context"
"fmt"
"strings"

"github.com/gilliek/go-opml/opml"
"github.com/pkg/errors"
Expand All @@ -12,7 +13,7 @@ import (
"github.com/mxpv/podsync/pkg/model"
)

func BuildOPML(ctx context.Context, config *config.Config, db feedProvider, provider urlProvider) (string, error) {
func BuildOPML(ctx context.Context, config *config.Config, db feedProvider, hostname string) (string, error) {
doc := opml.OPML{Version: "1.0"}
doc.Head = opml.Head{Title: "Podsync feeds"}
doc.Body = opml.Body{}
Expand All @@ -31,16 +32,11 @@ func BuildOPML(ctx context.Context, config *config.Config, db feedProvider, prov
continue
}

downloadURL, err := provider.URL(ctx, "", fmt.Sprintf("%s.xml", feed.ID))
if err != nil {
return "", errors.Wrapf(err, "failed to get feed URL for %q", feed.ID)
}

outline := opml.Outline{
Title: f.Title,
Text: f.Description,
Type: "rss",
XMLURL: downloadURL,
XMLURL: fmt.Sprintf("%s/%s.xml", strings.TrimRight(hostname, "/"), feed.ID),
}

doc.Body.Outlines = append(doc.Body.Outlines, outline)
Expand Down
5 changes: 1 addition & 4 deletions pkg/feed/opml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ func TestBuildOPML(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

urlMock := NewMockurlProvider(ctrl)
urlMock.EXPECT().URL(gomock.Any(), "", "1.xml").Return("https://url/1.xml", nil)

dbMock := NewMockfeedProvider(ctrl)
dbMock.EXPECT().GetFeed(gomock.Any(), "1").Return(&model.Feed{Title: "1", Description: "desc"}, nil)

Expand All @@ -37,7 +34,7 @@ func TestBuildOPML(t *testing.T) {
},
}

out, err := BuildOPML(context.Background(), &cfg, dbMock, urlMock)
out, err := BuildOPML(context.Background(), &cfg, dbMock, "https://url/")
assert.NoError(t, err)
assert.Equal(t, expected, out)
}
12 changes: 6 additions & 6 deletions pkg/feed/xml.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"sort"
"strconv"
"strings"
"time"

itunes "github.com/eduncan911/podcast"
Expand All @@ -30,7 +31,7 @@ func (p timeSlice) Swap(i, j int) {
p[i], p[j] = p[j], p[i]
}

func Build(ctx context.Context, feed *model.Feed, cfg *config.Feed, provider urlProvider) (*itunes.Podcast, error) {
func Build(_ctx context.Context, feed *model.Feed, cfg *config.Feed, hostname string) (*itunes.Podcast, error) {
const (
podsyncGenerator = "Podsync generator (support us at https://github.com/mxpv/podsync)"
defaultCategory = "TV & Film"
Expand Down Expand Up @@ -125,11 +126,10 @@ func Build(ctx context.Context, feed *model.Feed, cfg *config.Feed, provider url
enclosureType = itunes.MP3
}

episodeName := EpisodeName(cfg, episode)
downloadURL, err := provider.URL(ctx, cfg.ID, episodeName)
if err != nil {
return nil, errors.Wrapf(err, "failed to obtain download URL for: %s", episodeName)
}
var (
episodeName = EpisodeName(cfg, episode)
downloadURL = fmt.Sprintf("%s/%s/%s", strings.TrimRight(hostname, "/"), cfg.ID, episodeName)
)

item.AddEnclosure(downloadURL, enclosureType, episode.Size)

Expand Down
32 changes: 21 additions & 11 deletions pkg/feed/xml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,31 @@ import (
"context"
"testing"

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

itunes "github.com/eduncan911/podcast"
"github.com/mxpv/podsync/pkg/config"
"github.com/mxpv/podsync/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestBuildXML(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

urlMock := NewMockurlProvider(ctrl)

feed := model.Feed{}
feed := model.Feed{
Episodes: []*model.Episode{
{
ID: "1",
Status: model.EpisodeDownloaded,
Title: "title",
Description: "description",
},
},
}

cfg := config.Feed{
ID: "test",
Custom: config.Custom{Description: "description", Category: "Technology", Subcategories: []string{"Gadgets", "Podcasting"}},
}

out, err := Build(context.Background(), &feed, &cfg, urlMock)
out, err := Build(context.Background(), &feed, &cfg, "http://localhost/")
assert.NoError(t, err)

assert.EqualValues(t, "description", out.Description)
Expand All @@ -33,7 +37,13 @@ func TestBuildXML(t *testing.T) {
require.Len(t, out.ICategories, 1)
category := out.ICategories[0]
assert.EqualValues(t, "Technology", category.Text)

require.Len(t, category.ICategories, 2)
assert.EqualValues(t, "Gadgets", category.ICategories[0].Text)
assert.EqualValues(t, "Podcasting", category.ICategories[1].Text)

require.Len(t, out.Items, 1)
require.NotNil(t, out.Items[0].Enclosure)
assert.EqualValues(t, out.Items[0].Enclosure.URL, "http://localhost/test/1.mp4")
assert.EqualValues(t, out.Items[0].Enclosure.Type, itunes.MP4)
}
Loading

0 comments on commit 12cdbf6

Please sign in to comment.