courses export and bulk export
This commit is contained in:
@@ -55,6 +55,17 @@
|
||||
<li>
|
||||
<a href="/rowers/list-courses/?liked=true">Courses I like</a>
|
||||
</li>
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="grid_4">
|
||||
<a href="{% url 'course_export_zip_view' %}"
|
||||
target="download_frame"
|
||||
class="btn btn-default">
|
||||
Download my courses (ZIP)
|
||||
</a> - With this button you can download all your courses in one ZIP file. The ZIP file contains one KML file per course, which you can open in Google Earth or CrewNerd and port to the new courses library supporting CrewNerd.
|
||||
<iframe name="download_frame" style="display:none"></iframe>
|
||||
</a>
|
||||
<li>
|
||||
{% endif %}
|
||||
<li class="grid_4">
|
||||
{% if courses %}
|
||||
<p>
|
||||
|
||||
@@ -1089,6 +1089,8 @@ urlpatterns = [
|
||||
views.course_delete_view, name='course_delete_view'),
|
||||
re_path(r'^courses/(?P<id>\d+)/downloadkml/$', views.course_kmldownload_view,
|
||||
name='course_kmldownload_view'),
|
||||
re_path(r'^courses/export-zip/$', views.course_export_zip_view,
|
||||
name='course_export_zip_view'),
|
||||
re_path(r'^courses/(?P<id>\d+)/$', views.course_view, name='course_view'),
|
||||
re_path(r'^standards/(?P<id>\d+)/$',
|
||||
views.standard_view, name='standard_view'),
|
||||
|
||||
@@ -9,6 +9,9 @@ from rowers.plannedsessions import timefield_to_seconds_duration
|
||||
|
||||
from rowers.courses import getnearestraces, getnearestcourses,coursetokml, coursestokml
|
||||
from random import sample
|
||||
import io
|
||||
import json
|
||||
import zipfile
|
||||
|
||||
# landing page for challenges & courses
|
||||
def courses_challenges_view(request):
|
||||
@@ -3894,3 +3897,37 @@ def virtualevent_entry_edit_view(request, id=0, entryid=0):
|
||||
'userid': r.user.id,
|
||||
'race': race,
|
||||
})
|
||||
|
||||
# download_courses view where logged in user can download
|
||||
# their own courses (they are course_manager)
|
||||
# should download a zip file with all courses as KML files
|
||||
# and a manifest.json file with owned and liked course ID and name lists
|
||||
@login_required()
|
||||
def course_export_zip_view(request):
|
||||
r = getrower(request.user)
|
||||
owned_courses = GeoCourse.objects.filter(manager=r)
|
||||
liked_courses = GeoCourse.objects.filter(followers=r).exclude(manager=r)
|
||||
|
||||
if not owned_courses and not liked_courses:
|
||||
messages.info(request, "You don't have any courses to download")
|
||||
return HttpResponseRedirect(reverse('courses_view'))
|
||||
|
||||
manifest = {
|
||||
'version': 1,
|
||||
'exported_at': timezone.now().isoformat(),
|
||||
'owned': [{'id': str(c.id), 'name': c.name} for c in owned_courses],
|
||||
'liked': [{'id': str(c.id), 'name': c.name} for c in liked_courses],
|
||||
}
|
||||
|
||||
in_memory = io.BytesIO()
|
||||
with zipfile.ZipFile(in_memory, 'w', zipfile.ZIP_DEFLATED) as zf:
|
||||
zf.writestr('manifest.json', json.dumps(manifest, indent=2))
|
||||
for course in owned_courses:
|
||||
kml = coursetokml(course, cn=False)
|
||||
safe_name = course.name.replace('/', '-').replace('\\', '-')
|
||||
zf.writestr(f'courses/{safe_name}_{course.id}.kml', kml)
|
||||
|
||||
in_memory.seek(0)
|
||||
response = HttpResponse(in_memory, content_type='application/zip')
|
||||
response['Content-Disposition'] = 'attachment; filename="my-rowsandall-courses.zip"'
|
||||
return response
|
||||
|
||||
Reference in New Issue
Block a user