Ability to download all maps from user’s dashboard

This commit is contained in:
David Larlet 2023-11-24 17:04:47 -05:00
parent 77b35d079a
commit 5476cbee0f
No known key found for this signature in database
GPG key ID: 3E2953A359E7E7BD
4 changed files with 59 additions and 21 deletions

View file

@ -1,3 +1,4 @@
import json
import os
import time
@ -222,6 +223,20 @@ class Map(NamedModel):
)
return map_settings
def generate_geojson(self, request):
geojson = self.settings
geojson["type"] = "umap"
geojson["uri"] = request.build_absolute_uri(self.get_absolute_url())
datalayers = []
for datalayer in self.datalayer_set.all():
with open(datalayer.geojson.path, "rb") as f:
layer = json.loads(f.read())
if datalayer.settings:
layer["_umap_options"] = datalayer.settings
datalayers.append(layer)
geojson["layers"] = datalayers
return geojson
def get_absolute_url(self):
return reverse("map", kwargs={"slug": self.slug or "map", "map_id": self.pk})

View file

@ -43,6 +43,14 @@
{% endwith %}
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td>
<a href="{% url 'user_download' %}" class="button">{% translate "Download all maps" %}</a>
</td>
</tr>
</tfoot>
</table>
<div class="pagination">
{% if maps.has_previous %}

View file

@ -109,16 +109,9 @@ i18n_urls += decorated_patterns(
views.ToggleMapStarStatus.as_view(),
name="map_star",
),
re_path(
r"^me$",
views.user_dashboard,
name="user_dashboard",
),
re_path(
r"^me/profile$",
views.user_profile,
name="user_profile",
),
re_path(r"^me$", views.user_dashboard, name="user_dashboard"),
re_path(r"^me/profile$", views.user_profile, name="user_profile"),
re_path(r"^me/download$", views.user_download, name="user_download"),
)
map_urls = [
re_path(

View file

@ -1,8 +1,10 @@
import io
import json
import mimetypes
import os
import re
import socket
import zipfile
from datetime import datetime, timedelta
from http.client import InvalidURL
from io import BytesIO
@ -302,6 +304,36 @@ class UserDashboard(PaginatorMixin, DetailView, SearchMixin):
user_dashboard = UserDashboard.as_view()
class UserDownload(PaginatorMixin, DetailView, SearchMixin):
model = User
def get_object(self):
return self.get_queryset().get(pk=self.request.user.pk)
def get_maps(self):
qs = self.get_search_queryset() or Map.objects.all()
qs = qs.filter(owner=self.object).union(qs.filter(editors=self.object))
return qs.order_by("-modified_at")
def render_to_response(self, context, *args, **kwargs):
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file:
for map_ in self.get_maps():
map_geojson = map_.generate_geojson(self.request)
geojson_file = io.StringIO(json.dumps(map_geojson))
file_name = f"umap_backup_{map_.slug}.umap"
zip_file.writestr(file_name, geojson_file.getvalue())
response = HttpResponse(zip_buffer.getvalue(), content_type="application/zip")
response[
"Content-Disposition"
] = 'attachment; filename="umap_backup_complete.zip"'
return response
user_download = UserDownload.as_view()
class MapsShowCase(View):
def get(self, *args, **kwargs):
maps = Map.public.filter(center__distance_gt=(DEFAULT_CENTER, D(km=1)))
@ -633,17 +665,7 @@ class MapDownload(DetailView):
return reverse("map_download", args=(self.object.pk,))
def render_to_response(self, context, *args, **kwargs):
geojson = self.object.settings
geojson["type"] = "umap"
geojson["uri"] = self.request.build_absolute_uri(self.object.get_absolute_url())
datalayers = []
for datalayer in self.object.datalayer_set.all():
with open(datalayer.geojson.path, "rb") as f:
layer = json.loads(f.read())
if datalayer.settings:
layer["_umap_options"] = datalayer.settings
datalayers.append(layer)
geojson["layers"] = datalayers
geojson = self.object.generate_geojson(self.request)
response = simple_json_response(**geojson)
response[
"Content-Disposition"