From b9bbeafafb1f0750e4adaf12462b86094a5cad25 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Sat, 16 Jul 2022 23:54:06 +0200 Subject: actually implement the multi download button --- fietsboek/static/fietsboek.js | 20 ++++++++++++++++++++ fietsboek/templates/browse.jinja2 | 6 ++++-- fietsboek/views/browse.py | 33 +++++++++++++++++++++++---------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/fietsboek/static/fietsboek.js b/fietsboek/static/fietsboek.js index dd5b9bf..d27e21e 100644 --- a/fietsboek/static/fietsboek.js +++ b/fietsboek/static/fietsboek.js @@ -130,4 +130,24 @@ document.addEventListener('DOMContentLoaded', function(event) { }, false) }) + /* Enable the "Download archive" button */ + var button = $("#archiveDownloadButton"); + if (button) { + button.addEventListener('click', () => { + let checked = document.querySelectorAll(".archive-checkbox:checked"); + let url = new URL("/track/archive", window.location); + checked.forEach((c) => { + url.searchParams.append("track_id[]", c.value); + }); + window.location.assign(url); + }); + } + + /* Enable checkbox listeners */ + document.querySelectorAll(".archive-checkbox").forEach((c) => { + c.addEventListener("change", () => { + let checked = document.querySelectorAll(".archive-checkbox:checked"); + $("#archiveDownloadButton").disabled = (checked.length == 0); + }); + }); }); diff --git a/fietsboek/templates/browse.jinja2 b/fietsboek/templates/browse.jinja2 index 1f61bc6..2732984 100644 --- a/fietsboek/templates/browse.jinja2 +++ b/fietsboek/templates/browse.jinja2 @@ -2,10 +2,11 @@ {% block content %}

{{ _("page.browse.title") }}

+ {% if tracks %} {% for track in tracks %}
- + {{ track.title | default(track.date, true) }} {% if track.text_tags() %} {% for tag in track.tags %}{{ tag.tag }} {% endfor %} @@ -56,7 +57,8 @@
{% endfor %} - {% if not tracks %} + + {% else %}

{{ _("page.browse.no_tracks") }}

{% endif %} diff --git a/fietsboek/views/browse.py b/fietsboek/views/browse.py index 24cf082..490c0cf 100644 --- a/fietsboek/views/browse.py +++ b/fietsboek/views/browse.py @@ -1,5 +1,6 @@ """Views for browsing all tracks.""" -from zipfile import ZipFile +from io import RawIOBase +from zipfile import ZipFile, ZIP_DEFLATED from pyramid.view import view_config from pyramid.httpexceptions import HTTPForbidden @@ -10,12 +11,20 @@ from sqlalchemy import select from .. import models, util -class Stream: +class Stream(RawIOBase): + """A :class:`Stream` represents an in-memory buffered FIFO. + + This is useful for the zipfile module, as it needs a file-like object, but + we do not want to create an actual temporary file. + """ + def __init__(self): + super().__init__() self.buffer = [] def write(self, b): self.buffer.append(b) + return len(b) def readall(self): buf = self.buffer @@ -71,10 +80,11 @@ def archive(request): :return: The HTTP response. :rtype: pyramid.response.Response """ - from pprint import pformat + # We need to create a separate session, otherwise we will get detached instances + session = request.registry['dbsession_factory']() track_ids = set(map(int, request.params.getall("track_id[]"))) - tracks = request.dbsession.execute( + tracks = session.execute( select(models.Track).filter(models.Track.id.in_(track_ids))).scalars().fetchall() for track in tracks: @@ -82,12 +92,15 @@ def archive(request): return HTTPForbidden() def generate(): - stream = Stream() - with ZipFile(stream, "w") as zipfile: - for track in tracks: - zipfile.writestr(f"track_{track.id}.gpx", track.gpx_data) - yield sream.readall() - yield stream.readall() + try: + stream = Stream() + with ZipFile(stream, "w", ZIP_DEFLATED) as zipfile: + for track in tracks: + zipfile.writestr(f"track_{track.id}.gpx", track.gpx_data) + yield stream.readall() + yield stream.readall() + finally: + session.close() return Response( app_iter=generate(), -- cgit v1.2.3