Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An API to fetch the metadata #33

Open
wants to merge 7 commits into
base: non-admin-users
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/fs/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"github.com/disintegration/imaging"
"github.com/frolovo22/tag"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -33,6 +34,45 @@ 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 {
// 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
}

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
Expand All @@ -59,6 +99,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 {
Expand Down
52 changes: 52 additions & 0 deletions src/fs/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package main

import (
"github.com/frolovo22/tag"
)

type Metadata struct {
Tag string `json:"tag"`
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"`
AlbumArtwork string `json:"album_artwork"`
}

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
}
52 changes: 52 additions & 0 deletions src/fs/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"bytes"
"crypto/tls"
"database/sql"
"encoding/json"
"errors"
"fmt"
"github.com/amahi/go-metadata"
Expand Down Expand Up @@ -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, 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")
Expand Down Expand Up @@ -745,6 +747,56 @@ 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
}
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 {
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
Expand Down