mirror of
https://github.com/mxpv/podsync.git
synced 2024-05-11 05:55:04 +00:00
Implement server handler, add startup logic
This commit is contained in:
+46
-1
@@ -8,6 +8,14 @@ import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/mxpv/podsync/web/pkg/api"
|
||||
"github.com/mxpv/podsync/web/pkg/builders"
|
||||
"github.com/mxpv/podsync/web/pkg/config"
|
||||
"github.com/mxpv/podsync/web/pkg/feeds"
|
||||
"github.com/mxpv/podsync/web/pkg/id"
|
||||
"github.com/mxpv/podsync/web/pkg/server"
|
||||
"github.com/mxpv/podsync/web/pkg/storage"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -17,8 +25,45 @@ func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// Create core sevices
|
||||
|
||||
cfg, err := config.ReadConfiguration()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
hashIds, err := id.NewIdGenerator()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
redis, err := storage.NewRedisStorage(cfg.RedisURL)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Builders
|
||||
|
||||
youtube, err := builders.NewYouTubeBuilder(cfg.YouTubeApiKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
vimeo, err := builders.NewVimeoBuilder(ctx, cfg.VimeoApiKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
feed := feeds.NewFeedService(
|
||||
feeds.WithIdGen(hashIds),
|
||||
feeds.WithStorage(redis),
|
||||
feeds.WithBuilder(api.Youtube, youtube),
|
||||
feeds.WithBuilder(api.Vimeo, vimeo),
|
||||
)
|
||||
|
||||
srv := http.Server{
|
||||
Addr: fmt.Sprintf(":%d", 8080),
|
||||
Addr: fmt.Sprintf(":%d", 8080),
|
||||
Handler: server.MakeHandlers(feed),
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
||||
@@ -73,3 +73,34 @@ func (s *service) GetMetadata(hashId string) (*api.Feed, error) {
|
||||
|
||||
return feed, nil
|
||||
}
|
||||
|
||||
type feedOption func(*service)
|
||||
|
||||
func WithStorage(storage storage) feedOption {
|
||||
return func(service *service) {
|
||||
service.storage = storage
|
||||
}
|
||||
}
|
||||
|
||||
func WithIdGen(id id) feedOption {
|
||||
return func(service *service) {
|
||||
service.id = id
|
||||
}
|
||||
}
|
||||
|
||||
func WithBuilder(provider api.Provider, builder builder) feedOption {
|
||||
return func(service *service) {
|
||||
service.builders[provider] = builder
|
||||
}
|
||||
}
|
||||
|
||||
func NewFeedService(opts ...feedOption) *service {
|
||||
svc := &service{}
|
||||
svc.builders = make(map[api.Provider]builder)
|
||||
|
||||
for _, fn := range opts {
|
||||
fn(svc)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
itunes "github.com/mxpv/podcast"
|
||||
"github.com/mxpv/podsync/web/pkg/api"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type feed interface {
|
||||
CreateFeed(ctx context.Context, req *api.CreateFeedRequest) (string, error)
|
||||
GetFeed(hashId string) (*itunes.Podcast, error)
|
||||
GetMetadata(hashId string) (*api.Feed, error)
|
||||
}
|
||||
|
||||
func MakeHandlers(feed feed) http.Handler {
|
||||
r := gin.New()
|
||||
r.Use(gin.Recovery())
|
||||
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "ok")
|
||||
})
|
||||
|
||||
r.POST("/create", func(c *gin.Context) {
|
||||
req := &api.CreateFeedRequest{}
|
||||
|
||||
if err := c.BindJSON(req); err != nil {
|
||||
c.JSON(badRequest(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err := binding.Validator.ValidateStruct(req); err != nil {
|
||||
c.JSON(badRequest(err))
|
||||
return
|
||||
}
|
||||
|
||||
hashId, err := feed.CreateFeed(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
c.JSON(internalError(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"id": hashId})
|
||||
})
|
||||
|
||||
r.GET("/:hashId", func(c *gin.Context) {
|
||||
hashId := c.Param("hashId")
|
||||
if hashId == "" || len(hashId) > 12 {
|
||||
c.JSON(badRequest(errors.New("invalid feed id")))
|
||||
return
|
||||
}
|
||||
|
||||
podcast, err := feed.GetFeed(hashId)
|
||||
if err != nil {
|
||||
c.JSON(internalError(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.Data(http.StatusOK, "application/rss+xml", podcast.Bytes())
|
||||
})
|
||||
|
||||
r.GET("/metadata/:hashId", func(c *gin.Context) {
|
||||
hashId := c.Param("hashId")
|
||||
if hashId == "" || len(hashId) > 12 {
|
||||
c.JSON(badRequest(errors.New("invalid feed id")))
|
||||
return
|
||||
}
|
||||
|
||||
feed, err := feed.GetMetadata(hashId)
|
||||
if err != nil {
|
||||
c.JSON(internalError(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, feed)
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func badRequest(err error) (int, interface{}) {
|
||||
return http.StatusBadRequest, gin.H{"error": err.Error()}
|
||||
}
|
||||
|
||||
func internalError(err error) (int, interface{}) {
|
||||
return http.StatusInternalServerError, gin.H{"error": err.Error()}
|
||||
}
|
||||
Reference in New Issue
Block a user