From e717e4ebc26ad8e07ad501b8e9e6ee29cb6250e5 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Thu, 14 Jul 2022 17:20:26 +0200 Subject: [wip] implement multi track download --- fietsboek/routes.py | 2 ++ fietsboek/templates/browse.jinja2 | 1 + fietsboek/views/browse.py | 51 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/fietsboek/routes.py b/fietsboek/routes.py index dad8026..9b17173 100644 --- a/fietsboek/routes.py +++ b/fietsboek/routes.py @@ -7,6 +7,8 @@ def includeme(config): config.add_route('logout', '/logout') config.add_route('browse', '/track/') + config.add_route('track-archive', '/track/archive') + config.add_route('password-reset', '/password-reset') config.add_route('use-token', '/token/{uuid}') config.add_route('create-account', '/create-account') diff --git a/fietsboek/templates/browse.jinja2 b/fietsboek/templates/browse.jinja2 index 10b16e3..1f61bc6 100644 --- a/fietsboek/templates/browse.jinja2 +++ b/fietsboek/templates/browse.jinja2 @@ -5,6 +5,7 @@ {% for track in tracks %}
+ {{ track.title | default(track.date, true) }} {% if track.text_tags() %} {% for tag in track.tags %}{{ tag.tag }} {% endfor %} diff --git a/fietsboek/views/browse.py b/fietsboek/views/browse.py index 3739061..24cf082 100644 --- a/fietsboek/views/browse.py +++ b/fietsboek/views/browse.py @@ -1,11 +1,28 @@ """Views for browsing all tracks.""" +from zipfile import ZipFile + from pyramid.view import view_config +from pyramid.httpexceptions import HTTPForbidden +from pyramid.response import Response from sqlalchemy import select from .. import models, util +class Stream: + def __init__(self): + self.buffer = [] + + def write(self, b): + self.buffer.append(b) + + def readall(self): + buf = self.buffer + self.buffer = [] + return b"".join(buf) + + def visible_tracks(dbsession, user): """Returns all visible tracks for the given user. @@ -43,3 +60,37 @@ def browse(request): 'tracks': tracks, 'mps_to_kph': util.mps_to_kph, } + + +@view_config(route_name="track-archive", request_method="GET") +def archive(request): + """Packs multiple tracks into a single archive. + + :param request: The Pyramid request. + :type request: pyramid.request.Request + :return: The HTTP response. + :rtype: pyramid.response.Response + """ + from pprint import pformat + + track_ids = set(map(int, request.params.getall("track_id[]"))) + tracks = request.dbsession.execute( + select(models.Track).filter(models.Track.id.in_(track_ids))).scalars().fetchall() + + for track in tracks: + if not track.is_visible_to(request.identity): + 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() + + return Response( + app_iter=generate(), + content_type="application/zip", + content_disposition="attachment; filename=tracks.zip", + ) -- cgit v1.2.3