1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-22 17:06:17 +00:00

Add support for downloadong folders and albums

Ref #131
This commit is contained in:
spl0k 2019-01-13 17:18:27 +01:00
parent 6b86f3a43a
commit 25c5c8277e
3 changed files with 35 additions and 4 deletions

View File

@ -21,7 +21,8 @@ reqs = [
'pony>=0.7.6',
'Pillow',
'requests>=1.0.0',
'mutagen>=1.33'
'mutagen>=1.33',
'zipstream'
]
extras = {
'watcher': [ 'watchdog>=0.8.0' ]

View File

@ -14,11 +14,15 @@ import os.path
import requests
import shlex
import subprocess
import uuid
from flask import request, Response, send_file
from flask import current_app
from PIL import Image
from pony.orm import ObjectNotFound
from xml.etree import ElementTree
from zipfile import ZIP_DEFLATED
from zipstream import ZipFile
from .. import scanner
from ..db import Track, Album, Artist, Folder, User, ClientPrefs, now
@ -129,8 +133,29 @@ def stream_media():
@api.route('/download.view', methods = [ 'GET', 'POST' ])
def download_media():
res = get_entity(Track)
return send_file(res.path, mimetype = res.content_type, conditional=True)
id = request.values['id']
uid = uuid.UUID(id)
try: # Track -> direct download
rv = Track[uid]
return send_file(rv.path, mimetype = rv.content_type, conditional=True)
except ObjectNotFound:
pass
try: # Folder -> stream zipped tracks, non recursive
rv = Folder[uid]
except ObjectNotFound:
try: # Album -> stream zipped tracks
rv = Album[uid]
except ObjectNotFound:
raise NotFound('Track, Folder or Album')
z = ZipFile(compression = ZIP_DEFLATED)
for track in rv.tracks:
z.write(track.path, os.path.basename(track.path))
resp = Response(z, mimetype = 'application/zip')
resp.headers['Content-Disposition'] = 'attachment; filename={}.zip'.format(rv.name)
return resp
@api.route('/getCoverArt.view', methods = [ 'GET', 'POST' ])
def cover_art():

View File

@ -89,8 +89,8 @@ class MediaTestCase(ApiTestBase):
self._make_request('download', error = 10)
self._make_request('download', { 'id': 'string' }, error = 0)
self._make_request('download', { 'id': str(uuid.uuid4()) }, error = 70)
self._make_request('download', { 'id': str(self.folderid) }, error = 70)
# download single file
rv = self.client.get('/rest/download.view', query_string = { 'u': 'alice', 'p': 'Alic3', 'c': 'tests', 'id': str(self.trackid) })
self.assertEqual(rv.status_code, 200)
self.assertEqual(rv.mimetype, 'audio/mpeg')
@ -98,6 +98,11 @@ class MediaTestCase(ApiTestBase):
with db_session:
self.assertEqual(Track[self.trackid].play_count, 0)
# dowload folder
rv = self.client.get('/rest/download.view', query_string = { 'u': 'alice', 'p': 'Alic3', 'c': 'tests', 'id': str(self.folderid) })
self.assertEqual(rv.status_code, 200)
self.assertEqual(rv.mimetype, 'application/zip')
def test_get_cover_art(self):
self._make_request('getCoverArt', error = 10)
self._make_request('getCoverArt', { 'id': 'string' }, error = 0)