generate proper filenames for bulk download, and use that as base folder inside tar
This commit is contained in:
parent
612a443dde
commit
dd2e995720
|
@ -21,6 +21,7 @@ def _add_cors_headers(request, response, methods: Iterable[str]) -> None:
|
||||||
"origin, content-type, accept, "
|
"origin, content-type, accept, "
|
||||||
"authorization, x-xsrf-token, x-request-id"
|
"authorization, x-xsrf-token, x-request-id"
|
||||||
),
|
),
|
||||||
|
"Access-Control-Expose-Headers": "content-disposition",
|
||||||
}
|
}
|
||||||
response.headers.extend(headers)
|
response.headers.extend(headers)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
from datetime import date
|
||||||
from json import load as jsonload
|
from json import load as jsonload
|
||||||
from os.path import join, exists, isfile
|
from os.path import join, exists, isfile
|
||||||
|
|
||||||
from sanic.exceptions import InvalidUsage, NotFound, Forbidden
|
from sanic.exceptions import InvalidUsage, NotFound, Forbidden
|
||||||
from sanic.response import file_stream, empty
|
from sanic.response import file_stream, empty
|
||||||
|
from slugify import slugify
|
||||||
from sqlalchemy import select, func, and_
|
from sqlalchemy import select, func, and_
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
|
@ -163,7 +165,11 @@ async def tracks_bulk_action(req):
|
||||||
await req.ctx.db.commit()
|
await req.ctx.db.commit()
|
||||||
|
|
||||||
if action == "download":
|
if action == "download":
|
||||||
await tar_of_tracks(req, files)
|
username_slug = slugify(req.ctx.user.username, separator="-")
|
||||||
|
date_str = date.today().isoformat()
|
||||||
|
file_basename = f"tracks_{username_slug}_{date_str}"
|
||||||
|
|
||||||
|
await tar_of_tracks(req, files, file_basename)
|
||||||
return
|
return
|
||||||
|
|
||||||
return empty()
|
return empty()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import queue
|
import queue
|
||||||
import tarfile
|
import tarfile
|
||||||
|
from os.path import commonpath, relpath, join
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
|
|
||||||
|
@ -86,22 +86,24 @@ class chunk:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
async def tar_of_tracks(req, files):
|
async def tar_of_tracks(req, files, file_basename="tracks"):
|
||||||
response = await req.respond(
|
response = await req.respond(
|
||||||
content_type="application/x-gtar",
|
content_type="application/x-gtar",
|
||||||
headers={"Content-Disposition": 'attachment; filename="tracks.tar.bz2"'},
|
headers={
|
||||||
|
"content-disposition": f'attachment; filename="{file_basename}.tar.bz2"'
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
helper = StreamerHelper(response)
|
helper = StreamerHelper(response)
|
||||||
|
|
||||||
tar = tarfile.open(name=None, fileobj=helper, mode="w|bz2", bufsize=256 * 512)
|
tar = tarfile.open(name=None, fileobj=helper, mode="w|bz2", bufsize=256 * 512)
|
||||||
|
|
||||||
root = os.path.commonpath(list(files))
|
root = commonpath(list(files))
|
||||||
for fname in files:
|
for fname in files:
|
||||||
log.info("Write file to tar: %s", fname)
|
log.info("Write file to tar: %s", fname)
|
||||||
with open(fname, "rb") as fobj:
|
with open(fname, "rb") as fobj:
|
||||||
tarinfo = tar.gettarinfo(fname)
|
tarinfo = tar.gettarinfo(fname)
|
||||||
tarinfo.name = os.path.relpath(fname, root)
|
tarinfo.name = join(file_basename, relpath(fname, root))
|
||||||
tar.addfile(tarinfo, fobj)
|
tar.addfile(tarinfo, fobj)
|
||||||
await helper.send_all()
|
await helper.send_all()
|
||||||
tar.close()
|
tar.close()
|
||||||
|
|
|
@ -240,10 +240,17 @@ function TracksTable({ title }) {
|
||||||
action,
|
action,
|
||||||
tracks: Object.keys(selectedTracks),
|
tracks: Object.keys(selectedTracks),
|
||||||
},
|
},
|
||||||
returnResponse: true
|
returnResponse: true,
|
||||||
});
|
});
|
||||||
if (action === "download") {
|
if (action === "download") {
|
||||||
download(await response.blob(), "tracks.tar.bz2", "application/x-gtar");
|
const contentType =
|
||||||
|
response.headers.get("content-type") ?? "application/x-gtar";
|
||||||
|
|
||||||
|
const filename =
|
||||||
|
response.headers
|
||||||
|
.get("content-disposition")
|
||||||
|
?.match(/filename="([^"]+)"/)?.[1] ?? "tracks.tar.bz2";
|
||||||
|
download(await response.blob(), filename, contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
setShowBulkDelete(false);
|
setShowBulkDelete(false);
|
||||||
|
|
Loading…
Reference in a new issue