moving lastfm.go render.go imageUtils.go to the new render package

This commit is contained in:
aditya-K2
2021-12-22 21:19:37 +05:30
parent 6b7fff82b7
commit 6390039ea9
4 changed files with 45 additions and 23 deletions

85
render/imageUtils.go Normal file
View File

@@ -0,0 +1,85 @@
package render
import (
"github.com/aditya-K2/gomp/utils"
"os"
"strings"
"github.com/bogem/id3v2"
"github.com/mewkiz/flac"
"github.com/mewkiz/flac/meta"
"github.com/spf13/viper"
)
func GetMp3Image(songPath, imagePath string) string {
tag, err := id3v2.Open(songPath, id3v2.Options{Parse: true})
if err != nil {
return ""
}
defer tag.Close()
if err != nil {
return ""
}
// Read tags.
Frames := tag.GetFrames(tag.CommonID("Attached picture"))
var ImageData []byte
for _, er := range Frames {
pic, ok := er.(id3v2.PictureFrame)
if ok {
for _, i := range pic.Picture {
ImageData = append(ImageData, byte(i))
}
imageHandler, err := os.Create(imagePath)
if err != nil {
return ""
} else {
imageHandler.Write(ImageData)
return imagePath
}
}
}
return ""
}
func GetFlacImage(songPath, imagePath string) string {
stream, err := flac.ParseFile(songPath)
if err != nil {
return ""
}
defer stream.Close()
for _, block := range stream.Blocks {
if block.Type == meta.TypePicture {
pic := block.Body.(*meta.Picture)
if pic.Type == 3 {
imageHandler, err := os.Create(imagePath)
if err != nil {
return ""
}
imageHandler.Write(pic.Data)
return imagePath
}
}
}
return ""
}
func ExtractImageFromFile(uri string, imagePath string) string {
_i := imagePath
if strings.HasSuffix(uri, ".mp3") {
imagePath := GetMp3Image(uri, imagePath)
if imagePath == "" {
utils.Copy(viper.GetString("DEFAULT_IMAGE_PATH"), _i)
return viper.GetString("DEFAULT_IMAGE_PATH")
}
} else if strings.HasSuffix(uri, ".flac") {
imagePath := GetFlacImage(uri, imagePath)
if imagePath == "" {
utils.Copy(viper.GetString("DEFAULT_IMAGE_PATH"), _i)
return viper.GetString("DEFAULT_IMAGE_PATH")
}
} else {
utils.Copy(viper.GetString("DEFAULT_IMAGE_PATH"), _i)
return viper.GetString("DEFAULT_IMAGE_PATH")
}
return imagePath
}

53
render/lastfm.go Normal file
View File

@@ -0,0 +1,53 @@
package render
import (
"errors"
_ "image/jpeg"
"io"
"net/http"
"os"
"strings"
"github.com/shkh/lastfm-go/lastfm"
"github.com/spf13/viper"
)
func getImageFromLastFM(artist, album, imagePath string) (string, error) {
api := lastfm.New(viper.GetString("LASTFM_API_KEY"), viper.GetString("LASTFM_API_SECRET"))
v, err := api.Album.GetInfo(map[string]interface{}{
"artist": artist,
"album": album,
"autocorrect": viper.GetInt("LASTFM_AUTO_CORRECT"),
})
if err != nil {
return "", err
} else {
return downloadImage(v.Images[len(v.Images)-1].Url, imagePath)
}
}
func downloadImage(url string, imagePath string) (string, error) {
var reader io.Reader
if strings.HasPrefix(url, "http") {
r, err := http.Get(url)
if err != nil {
return "", err
}
defer r.Body.Close()
reader = r.Body
v, err := io.ReadAll(reader)
if err == nil {
b, err := os.Create(imagePath)
if err == nil {
b.Write(v)
return imagePath, nil
} else {
b.Close()
return "", err
}
} else {
return "", err
}
}
return "", errors.New("Image Not Received")
}

137
render/render.go Normal file
View File

@@ -0,0 +1,137 @@
package render
import (
"github.com/aditya-K2/gomp/ui"
"github.com/fhs/gompd/mpd"
"image"
"os"
"github.com/aditya-K2/gomp/cache"
"github.com/aditya-K2/gomp/utils"
"github.com/nfnt/resize"
"github.com/spf13/viper"
"gitlab.com/diamondburned/ueberzug-go"
)
var (
CONN *mpd.Client
Notify interface { Send(string) }
)
func SetConnection(c *mpd.Client) {
CONN = c
}
func SetNotificationServer(n interface{ Send(string) }) {
Notify = n
}
/*
Renderer is just a channel on which we will send the Path to the song whose
Image is to be Rendered. This channel is passed to the OpenImage which in turn is called
by the Start() function as a go routine.
*/
type Renderer struct {
c chan string
}
/*
Returns a new Renderer with a string channel
*/
func NewRenderer() *Renderer {
c := make(chan string)
return &Renderer{
c: c,
}
}
/*
Send Image Path to Renderer
*/
func (self *Renderer) Send(path string) {
self.c <- path
}
/*
Go Routine that will Be Called and will listen on the channel c
for changes and on getting a string over the channel will open the Image and
keep listening again. This will keep the image blocked ( i.e no need to use time.Sleep() etc. )
and saves resources too.
*/
func OpenImage(path string, c chan string) {
fw, fh := utils.GetFontWidth()
var im *ueberzug.Image
if path != "stop" {
extractedImage := GetImagePath(path)
img2, _ := GetImg(extractedImage)
im, _ = ueberzug.NewImage(img2, int(float32(ui.IMG_X)*fw)+viper.GetInt("ADDITIONAL_PADDING_X"), int(float32(ui.IMG_Y)*fh)+viper.GetInt("ADDITIONAL_PADDING_Y"))
}
d := <-c
if im != nil {
im.Clear()
}
if d != "stop" {
OpenImage(d, c)
} else {
OpenImage("stop", c)
}
}
/*
Initialises the Renderer and calls the go routine OpenImage and passes the channel
as argument.
*/
func (self *Renderer) Start(path string) {
go OpenImage(path, self.c)
}
/*
This Function returns the path to the image that is to be rendered it checks first for the image in the cache
else it adds the image to the cache and then extracts it and renders it.
*/
func GetImagePath(path string) string {
a, err := CONN.ListInfo(path)
var extractedImage string
if err == nil && len(a) != 0 {
if cache.Exists(a[0]["artist"], a[0]["album"]) {
extractedImage = cache.GenerateName(a[0]["artist"], a[0]["album"])
} else {
imagePath := cache.GenerateName(a[0]["artist"], a[0]["album"])
absPath := utils.CheckDirectoryFmt(viper.GetString("MUSIC_DIRECTORY")) + path
extractedImage = ExtractImageFromFile(absPath, imagePath)
if extractedImage == viper.GetString("DEFAULT_IMAGE_PATH") && viper.GetString("GET_COVER_ART_FROM_LAST_FM") == "TRUE" {
downloadedImage, err := getImageFromLastFM(a[0]["artist"], a[0]["album"], imagePath)
if err == nil {
Notify.Send("Image From LastFM")
extractedImage = downloadedImage
} else {
Notify.Send("Falling Back to Default Image.")
}
} else {
Notify.Send("Extracted Image Successfully")
}
}
}
return extractedImage
}
func GetImg(uri string) (image.Image, error) {
f, err := os.Open(uri)
if err != nil {
return nil, err
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
return nil, err
}
fw, fh := utils.GetFontWidth()
img = resize.Resize(
uint(float32(ui.IMG_W)*(fw+float32(viper.GetFloat64("IMAGE_WIDTH_EXTRA_X")))), uint(float32(ui.IMG_H)*(fh+float32(viper.GetFloat64("IMAGE_WIDTH_EXTRA_Y")))),
img,
resize.Bilinear,
)
return img, nil
}