diff --git a/api/get_cover_art.go b/api/get_cover_art.go index 98236d4aa..c2f1942d6 100644 --- a/api/get_cover_art.go +++ b/api/get_cover_art.go @@ -3,64 +3,32 @@ package api import ( "github.com/astaxie/beego" "github.com/deluan/gosonic/api/responses" - "github.com/deluan/gosonic/domain" + "github.com/deluan/gosonic/engine" "github.com/deluan/gosonic/utils" - "github.com/dhowden/tag" "github.com/karlkfi/inject" - "io/ioutil" - "os" ) type GetCoverArtController struct { BaseAPIController - repo domain.MediaFileRepository + cover engine.Cover } func (c *GetCoverArtController) Prepare() { - inject.ExtractAssignable(utils.Graph, &c.repo) + inject.ExtractAssignable(utils.Graph, &c.cover) } // TODO accept size parameter func (c *GetCoverArtController) Get() { id := c.RequiredParamString("id", "id parameter required") - mf, err := c.repo.Get(id) - if err != nil { - beego.Error("Error reading mediafile", id, "from the database", ":", err) - c.SendError(responses.ERROR_GENERIC, "Internal error") + err := c.cover.GetCover(id, 0, c.Ctx.ResponseWriter) + + switch { + case err == engine.DataNotFound: + beego.Error(err, "Id:", id) + c.SendError(responses.ERROR_DATA_NOT_FOUND, "Directory not found") + case err != nil: + beego.Error(err) + c.SendError(responses.ERROR_GENERIC, "Internal Error") } - - var img []byte - - if mf != nil && mf.HasCoverArt { - img, err = readFromTag(mf.Path) - beego.Debug("Serving cover art from", mf.Path) - } else { - img, err = ioutil.ReadFile("static/default_cover.jpg") - beego.Debug("Serving default cover art") - } - - if err != nil { - beego.Error("Could not retrieve cover art", id, ":", err) - c.SendError(responses.ERROR_DATA_NOT_FOUND, "cover art not available") - } - - c.Ctx.Output.Body(img) -} - -func readFromTag(path string) ([]byte, error) { - f, err := os.Open(path) - if err != nil { - beego.Warn("Error opening file", path, "-", err) - return nil, err - } - defer f.Close() - - m, err := tag.ReadFrom(f) - if err != nil { - beego.Warn("Error reading tag from file", path, "-", err) - return nil, err - } - - return m.Picture().Data, nil } diff --git a/conf/inject_definitions.go b/conf/inject_definitions.go index 28d28c916..131e46fca 100644 --- a/conf/inject_definitions.go +++ b/conf/inject_definitions.go @@ -19,4 +19,5 @@ func init() { utils.DefineSingleton(new(engine.PropertyRepository), persistence.NewPropertyRepository) utils.DefineSingleton(new(engine.Browser), engine.NewBrowser) utils.DefineSingleton(new(engine.ListGenerator), engine.NewListGenerator) + utils.DefineSingleton(new(engine.Cover), engine.NewCover) } diff --git a/engine/cover.go b/engine/cover.go new file mode 100644 index 000000000..8f2feb193 --- /dev/null +++ b/engine/cover.go @@ -0,0 +1,59 @@ +package engine + +import ( + "io" + "io/ioutil" + "os" + + "github.com/deluan/gosonic/domain" + "github.com/dhowden/tag" +) + +type Cover interface { + GetCover(id string, size int, out io.Writer) error +} + +type cover struct { + mfileRepo domain.MediaFileRepository +} + +func NewCover(mr domain.MediaFileRepository) Cover { + return cover{mr} +} + +func (c cover) GetCover(id string, size int, out io.Writer) error { + mf, err := c.mfileRepo.Get(id) + if err != nil { + return err + } + + var img []byte + + if mf != nil && mf.HasCoverArt { + img, err = readFromTag(mf.Path) + } else { + img, err = ioutil.ReadFile("static/default_cover.jpg") + } + + if err != nil { + return DataNotFound + } + + _, err = out.Write(img) + return err +} + +func readFromTag(path string) ([]byte, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + + m, err := tag.ReadFrom(f) + if err != nil { + return nil, err + } + + return m.Picture().Data, nil +}