Merge pull request #191 from natilou/download-track
Ability to download tracks
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package mediaprovider
|
||||
|
||||
import "image"
|
||||
import (
|
||||
"image"
|
||||
"io"
|
||||
)
|
||||
|
||||
type AlbumFilter struct {
|
||||
MinYear int
|
||||
@@ -83,4 +86,6 @@ type MediaProvider interface {
|
||||
DeletePlaylist(id string) error
|
||||
|
||||
Scrobble(trackID string, submission bool) error
|
||||
|
||||
DownloadTrack(trackID string) (io.Reader, error)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package subsonic
|
||||
import (
|
||||
"errors"
|
||||
"image"
|
||||
"io"
|
||||
"math"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -249,6 +250,10 @@ func (s *subsonicMediaProvider) SetRating(params mediaprovider.RatingFavoritePar
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *subsonicMediaProvider) DownloadTrack(trackID string) (io.Reader, error) {
|
||||
return s.client.Download(trackID)
|
||||
}
|
||||
|
||||
func toTrack(ch *subsonic.Child) *mediaprovider.Track {
|
||||
if ch == nil {
|
||||
return nil
|
||||
|
||||
@@ -7,7 +7,7 @@ require (
|
||||
fyne.io/x/fyne v0.0.0-20230611151101-afdcd6b92cf3
|
||||
github.com/20after4/configdir v0.1.1
|
||||
github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee
|
||||
github.com/dweymouth/go-subsonic v0.0.0-20230513020020-0790f53c2868
|
||||
github.com/dweymouth/go-subsonic v0.0.0-20230614154319-792d18c75fb4
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/pelletier/go-toml/v2 v2.0.8
|
||||
github.com/zalando/go-keyring v0.2.1
|
||||
|
||||
@@ -80,6 +80,8 @@ github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee h1:ZGyJ6wp7CAfT31
|
||||
github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee/go.mod h1:Ov0ieN90M7i+0k3OxhA/g1dozGs+UcPHDsMKqPgRDk0=
|
||||
github.com/dweymouth/go-subsonic v0.0.0-20230513020020-0790f53c2868 h1:403Dden/cdQyDM8ydonHLxTBPjgQXZ76PUfmBG92+Dw=
|
||||
github.com/dweymouth/go-subsonic v0.0.0-20230513020020-0790f53c2868/go.mod h1:fUez6NFiEJiQTZizZ1BThZr5GJXAbigzGYjEPNm4tdI=
|
||||
github.com/dweymouth/go-subsonic v0.0.0-20230614154319-792d18c75fb4 h1:cuyvB4GjTMBHKJwMJ/LFpuKfSVXuCheNj6fgxBa3m1Y=
|
||||
github.com/dweymouth/go-subsonic v0.0.0-20230614154319-792d18c75fb4/go.mod h1:fUez6NFiEJiQTZizZ1BThZr5GJXAbigzGYjEPNm4tdI=
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.5/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"image"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/dweymouth/supersonic/backend"
|
||||
@@ -113,6 +117,7 @@ func (m *Controller) ConnectTracklistActions(tracklist *widgets.Tracklist) {
|
||||
tracklist.OnColumnVisibilityMenuShown = func(pop *widget.PopUp) {
|
||||
m.ClosePopUpOnEscape(pop)
|
||||
}
|
||||
tracklist.OnDownload = m.ShowDownloadDialog
|
||||
}
|
||||
|
||||
func (m *Controller) ConnectAlbumGridActions(grid *widgets.GridView) {
|
||||
@@ -516,3 +521,95 @@ func (c *Controller) SetTrackRatings(trackIDs []string, rating int) {
|
||||
c.App.PlaybackManager.OnTrackRatingChanged(id, rating)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) ShowDownloadDialog(tracks []*mediaprovider.Track) {
|
||||
numTracks := len(tracks)
|
||||
var fileName string
|
||||
if numTracks == 1 {
|
||||
fileName = filepath.Base(tracks[0].FilePath)
|
||||
} else {
|
||||
fileName = "downloaded_tracks.zip"
|
||||
}
|
||||
|
||||
dg := dialog.NewFileSave(
|
||||
func(file fyne.URIWriteCloser, err error) {
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if file == nil {
|
||||
return
|
||||
}
|
||||
if numTracks == 1 {
|
||||
go c.downloadTrack(tracks[0], file.URI().Path())
|
||||
} else {
|
||||
go c.downloadTracks(tracks, file.URI().Path())
|
||||
}
|
||||
|
||||
},
|
||||
c.MainWindow)
|
||||
dg.SetFileName(fileName)
|
||||
dg.Show()
|
||||
}
|
||||
|
||||
func (c *Controller) downloadTrack(track *mediaprovider.Track, filePath string) {
|
||||
reader, err := c.App.ServerManager.Server.DownloadTrack(track.ID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(file, reader)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Saved song %s to: %s\n", track.Name, filePath)
|
||||
}
|
||||
|
||||
func (c *Controller) downloadTracks(tracks []*mediaprovider.Track, filePath string) {
|
||||
zipFile, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
defer zipFile.Close()
|
||||
|
||||
zipWriter := zip.NewWriter(zipFile)
|
||||
defer zipWriter.Close()
|
||||
|
||||
for _, track := range tracks {
|
||||
reader, err := c.App.ServerManager.Server.DownloadTrack(track.ID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
fileName := filepath.Base(track.FilePath)
|
||||
|
||||
fileWriter, err := zipWriter.Create(fileName)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = io.Copy(fileWriter, reader)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("Saved song %s to: %s\n", track.Name, filePath)
|
||||
}
|
||||
|
||||
log.Printf("Finished download to: %s\n", filePath)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ type Tracklist struct {
|
||||
OnAddToPlaylist func(trackIDs []string)
|
||||
OnSetFavorite func(trackIDs []string, fav bool)
|
||||
OnSetRating func(trackIDs []string, rating int)
|
||||
OnDownload func(tracks []*mediaprovider.Track)
|
||||
|
||||
OnShowArtistPage func(artistID string)
|
||||
OnShowAlbumPage func(albumID string)
|
||||
@@ -508,6 +509,10 @@ func (t *Tracklist) onShowContextMenu(e *fyne.PointEvent, trackIdx int) {
|
||||
t.OnAddToPlaylist(t.SelectedTrackIDs())
|
||||
}
|
||||
}))
|
||||
t.ctxMenu.Items = append(t.ctxMenu.Items,
|
||||
fyne.NewMenuItem("Download", func() {
|
||||
t.onDownload(t.selectedTracks())
|
||||
}))
|
||||
t.ctxMenu.Items = append(t.ctxMenu.Items, fyne.NewMenuItemSeparator())
|
||||
t.ctxMenu.Items = append(t.ctxMenu.Items,
|
||||
fyne.NewMenuItem("Set favorite", func() {
|
||||
@@ -582,6 +587,12 @@ func (t *Tracklist) onAlbumTapped(albumID string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tracklist) onDownload(tracks []*mediaprovider.Track) {
|
||||
if t.OnDownload != nil {
|
||||
t.OnDownload(tracks)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tracklist) findTrackByID(id string) *mediaprovider.Track {
|
||||
idx := sharedutil.Find(t.tracks, func(tr *trackModel) bool {
|
||||
return tr.track.ID == id
|
||||
|
||||
Reference in New Issue
Block a user