From f94cd96aecb63c831d1bb85c66771a4af58f14df Mon Sep 17 00:00:00 2001 From: Solamish <1124053312@qq.com> Date: Sun, 28 Jun 2020 21:08:38 +0800 Subject: [PATCH 1/5] add metadata api --- src/fs/metadata.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++ src/fs/service.go | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 src/fs/metadata.go diff --git a/src/fs/metadata.go b/src/fs/metadata.go new file mode 100644 index 0000000..a509806 --- /dev/null +++ b/src/fs/metadata.go @@ -0,0 +1,52 @@ +package main + +import ( + "github.com/frolovo22/tag" +) + +type Metadata struct { + Tag string `json:"tag"` + FileType string `json:"file_type"` + Title string `json:"title"` + Album string `json:"album"` + Artist string `json:"artist"` + AlbumArtist string `json:"album_artist"` + Composer string `json:"composer"` + Genre string `json:"genre"` + Year int `json:"year"` + TrackNumber int `json:"track_number"` +} + +func getMetaData(tags tag.Metadata) (*Metadata) { + + title, _ := tags.GetTitle() + album, _ := tags.GetAlbum() + tagVersion := tags.GetVersion() + artist, _ := tags.GetArtist() + albumArtist, _ := tags.GetAlbumArtist() + genre, _ := tags.GetGenre() + trackNumber, _, _ := tags.GetTrackNumber() + composer, _ := tags.GetComposer() + year, _ := tags.GetYear() + + metadata := &Metadata{ + Tag: tagVersion.String(), + Title: title, + Album: album, + Artist: artist, + AlbumArtist: albumArtist, + Composer: composer, + Genre: genre, + Year: year, + TrackNumber: trackNumber, + } + return metadata +} + +func getMetadataByPath(path string) (*Metadata, error) { + tags, err := tag.ReadFile(path) + if err != nil { + return nil, err + } + return getMetaData(tags), nil +} \ No newline at end of file diff --git a/src/fs/service.go b/src/fs/service.go index 08baa3c..c87828c 100644 --- a/src/fs/service.go +++ b/src/fs/service.go @@ -13,6 +13,7 @@ import ( "bytes" "crypto/tls" "database/sql" + "encoding/json" "errors" "fmt" "github.com/amahi/go-metadata" @@ -76,6 +77,7 @@ func NewMercuryFSService(rootDir, localAddr string, isDemo bool) (service *Mercu apiRouter.HandleFunc("/files", use(service.deleteFile, service.shareWriteAccess, service.restrictCache)).Methods("DELETE") apiRouter.HandleFunc("/files", use(service.uploadFile, service.shareWriteAccess, service.restrictCache)).Methods("POST") apiRouter.HandleFunc("/cache", use(service.serveCache, service.shareReadAccess)).Methods("GET") + apiRouter.HandleFunc("/meta", use(service.serveMetadata, service.shareReadAccess)).Methods("GET") apiRouter.HandleFunc("/apps", service.appsList).Methods("GET") apiRouter.HandleFunc("/md", service.getMetadata).Methods("GET") apiRouter.HandleFunc("/hda_debug", service.hdaDebug).Methods("GET") @@ -745,6 +747,51 @@ func (service *MercuryFsService) uploadFile(writer http.ResponseWriter, request return } +func (service *MercuryFsService) serveMetadata(writer http.ResponseWriter, request *http.Request) { + q := request.URL + path := q.Query().Get("p") + share := q.Query().Get("s") + + debug(2, "metadata GET request") + + service.printRequest(request) + + fullPath, err := service.fullPathToFile(share, path) + + if err != nil { + debug(2, "File not found: %s", err) + http.NotFound(writer, request) + service.debugInfo.requestServed(int64(0)) + service.accessLog(logging, request, http.StatusNotFound, 0) + return + } + + var m *Metadata + m, err = getMetadataByPath(fullPath) + + if err != nil { + debug(2, "Error getting metadata: %s", err.Error()) + http.NotFound(writer, request) + service.debugInfo.requestServed(int64(0)) + service.accessLog(logging, request, http.StatusNotFound, 0) + return + } + + b, err := json.Marshal(m) + if err != nil { + debug(2, "Internal Server Error: %s", err.Error()) + writer.WriteHeader(http.StatusInternalServerError) + service.debugInfo.requestServed(int64(0)) + service.accessLog(logging, request, http.StatusInternalServerError,0) + return + } + writer.Header().Set("Content-Type", "application/json") + writer.WriteHeader(http.StatusOK) + size, _ := writer.Write(b) + service.accessLog(logging, request, http.StatusOK, size) + service.debugInfo.requestServed(int64(size)) +} + func (service *MercuryFsService) accessLog(logging *Logging, request *http.Request, statusCode int, bodySize int) { var requestTime time.Time var elapsedTime time.Duration From 56380fb5563031f9b715e565acd43ab10a0f87d0 Mon Sep 17 00:00:00 2001 From: Solamish <1124053312@qq.com> Date: Sun, 28 Jun 2020 21:10:31 +0800 Subject: [PATCH 2/5] cache album artwork for the media --- src/fs/cache.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/fs/cache.go b/src/fs/cache.go index a38d205..dc7a6a4 100644 --- a/src/fs/cache.go +++ b/src/fs/cache.go @@ -2,6 +2,7 @@ package main import ( "github.com/disintegration/imaging" + "github.com/frolovo22/tag" "os" "path/filepath" "strings" @@ -33,6 +34,39 @@ func thumbnailer(imagePath string, savePath string) error { return nil } +func cacheMetadataPicture(path string, savePath string) error { + tags, err := tag.ReadFile(path) + if err != nil { + logging.Error("error opening file: %s", err.Error()) + return err + } + + picture, err := tags.GetPicture() + if err != nil { + logging.Error(`Error getting media picture: %s`, err.Error()) + return err + } + + if picture != nil { + savePath = savePath + ".jpg" + if err = os.MkdirAll(filepath.Dir(savePath), os.ModePerm); err != nil { + logging.Error(`Error creating parent directory for file: "%s". Error is: "%s"`, savePath, err.Error()) + return err + } + + if err = imaging.Save(picture, savePath); err != nil { + logging.Error(`Error saving image thumbnail for file at location: "%s". Error is: "%s"`, savePath, err.Error()) + return err + } + logging.Info("Thumbnail image saved for file: %s", path) + return nil + } + + logging.Info("Thumbnail image not found for file: %s", path) + return nil +} + + func fillCache(root string) error { filepath.Walk(root, fillCacheWalkFunc) return nil @@ -59,6 +93,8 @@ func fillCacheWalkFunc(path string, info os.FileInfo, err error) error { contentType := getContentType(path) if strings.Contains(contentType, "image") { thumbnailer(path, thumbnailPath) + } else { + cacheMetadataPicture(path, thumbnailPath) } } } else { From 74e86908c8980441679c33917940bbf1a8e7bd4e Mon Sep 17 00:00:00 2001 From: Solamish <1124053312@qq.com> Date: Sun, 28 Jun 2020 21:13:12 +0800 Subject: [PATCH 3/5] fix artwork path for media --- src/fs/cache.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/fs/cache.go b/src/fs/cache.go index dc7a6a4..e490097 100644 --- a/src/fs/cache.go +++ b/src/fs/cache.go @@ -48,7 +48,13 @@ func cacheMetadataPicture(path string, savePath string) error { } if picture != nil { - savePath = savePath + ".jpg" + // song.mp3 + fileName := filepath.Base(path) + index := strings.Index(fileName, ".") + // song_artwork.jpg + artworkName := fileName[:index] + "_artwork" + ".jpg" + savePath = filepath.Join(filepath.Dir(savePath), artworkName) + if err = os.MkdirAll(filepath.Dir(savePath), os.ModePerm); err != nil { logging.Error(`Error creating parent directory for file: "%s". Error is: "%s"`, savePath, err.Error()) return err From b1c752aa6d45b3fe51929f481843ed568a346d32 Mon Sep 17 00:00:00 2001 From: Solamish <1124053312@qq.com> Date: Sun, 28 Jun 2020 21:14:13 +0800 Subject: [PATCH 4/5] cache album artwork for media --- src/fs/metadata.go | 1 - src/fs/service.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fs/metadata.go b/src/fs/metadata.go index a509806..9ac90c8 100644 --- a/src/fs/metadata.go +++ b/src/fs/metadata.go @@ -6,7 +6,6 @@ import ( type Metadata struct { Tag string `json:"tag"` - FileType string `json:"file_type"` Title string `json:"title"` Album string `json:"album"` Artist string `json:"artist"` diff --git a/src/fs/service.go b/src/fs/service.go index c87828c..7176107 100644 --- a/src/fs/service.go +++ b/src/fs/service.go @@ -77,7 +77,7 @@ func NewMercuryFSService(rootDir, localAddr string, isDemo bool) (service *Mercu apiRouter.HandleFunc("/files", use(service.deleteFile, service.shareWriteAccess, service.restrictCache)).Methods("DELETE") apiRouter.HandleFunc("/files", use(service.uploadFile, service.shareWriteAccess, service.restrictCache)).Methods("POST") apiRouter.HandleFunc("/cache", use(service.serveCache, service.shareReadAccess)).Methods("GET") - apiRouter.HandleFunc("/meta", use(service.serveMetadata, service.shareReadAccess)).Methods("GET") + apiRouter.HandleFunc("/meta", use(service.serveMetadata, service.shareReadAccess, service.restrictCache)).Methods("GET") apiRouter.HandleFunc("/apps", service.appsList).Methods("GET") apiRouter.HandleFunc("/md", service.getMetadata).Methods("GET") apiRouter.HandleFunc("/hda_debug", service.hdaDebug).Methods("GET") From 7c1d32e8b343bff7f7717d94a304a5c67ac307d5 Mon Sep 17 00:00:00 2001 From: Solamish <1124053312@qq.com> Date: Tue, 30 Jun 2020 11:34:23 +0800 Subject: [PATCH 5/5] return the album artwork as an endpoint --- src/fs/metadata.go | 1 + src/fs/service.go | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/fs/metadata.go b/src/fs/metadata.go index 9ac90c8..b376917 100644 --- a/src/fs/metadata.go +++ b/src/fs/metadata.go @@ -14,6 +14,7 @@ type Metadata struct { Genre string `json:"genre"` Year int `json:"year"` TrackNumber int `json:"track_number"` + AlbumArtwork string `json:"album_artwork"` } func getMetaData(tags tag.Metadata) (*Metadata) { diff --git a/src/fs/service.go b/src/fs/service.go index 7176107..d91ee08 100644 --- a/src/fs/service.go +++ b/src/fs/service.go @@ -768,7 +768,6 @@ func (service *MercuryFsService) serveMetadata(writer http.ResponseWriter, reque var m *Metadata m, err = getMetadataByPath(fullPath) - if err != nil { debug(2, "Error getting metadata: %s", err.Error()) http.NotFound(writer, request) @@ -776,6 +775,12 @@ func (service *MercuryFsService) serveMetadata(writer http.ResponseWriter, reque service.accessLog(logging, request, http.StatusNotFound, 0) return } + parentDir := filepath.Dir(path) + fileName := filepath.Base(path) + index := strings.Index(fileName, ".") + artworkName := fileName[:index] + "_artwork" + ".jpg" + artworkPath := filepath.Join(parentDir,artworkName) + m.AlbumArtwork = fmt.Sprintf("/cache?s=%s&p=%s",share,artworkPath) b, err := json.Marshal(m) if err != nil {