Skip to content

Commit

Permalink
Generate ZIP file for download on click of QR code button
Browse files Browse the repository at this point in the history
  • Loading branch information
johannaengland committed May 6, 2024
1 parent 9276af0 commit afdc234
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 3 deletions.
10 changes: 9 additions & 1 deletion python/nav/web/seeddb/page/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,19 @@ def not_implemented(*_args, **_kwargs):
raise NotImplementedError()


def view_switcher(request, list_view=None, move_view=None, delete_view=None):
def view_switcher(
request,
list_view=None,
move_view=None,
delete_view=None,
generate_qr_codes_view=None,
):
"""Selects appropriate view depending on POST data."""
if request.method == 'POST':
if 'move' in request.POST:
return move_view(request)
elif 'delete' in request.POST:
return delete_view(request)
elif 'qr_code' in request.POST:
return generate_qr_codes_view(request)
return list_view(request)
65 changes: 64 additions & 1 deletion python/nav/web/seeddb/page/netbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
import datetime
from django.db import transaction
from django.contrib.postgres.aggregates import ArrayAgg
from django.http import HttpResponseRedirect
from django.urls import reverse

from nav.models.manage import Netbox
from nav.bulkparse import NetboxBulkParser
from nav.bulkimport import NetboxImporter

from nav.web.message import new_message, Messages
from nav.web.seeddb import SeeddbInfo, reverse_lazy
from nav.web.seeddb.constants import SEEDDB_EDITABLE_MODELS
from nav.web.seeddb.page import view_switcher
Expand All @@ -31,6 +34,10 @@
from nav.web.seeddb.utils.move import move
from nav.web.seeddb.utils.bulk import render_bulkimport
from nav.web.seeddb.page.netbox.forms import NetboxFilterForm, NetboxMoveForm
from nav.web.utils import (
generate_qr_codes_as_byte_strings,
generate_qr_codes_as_zip_file,
)


class NetboxInfo(SeeddbInfo):
Expand All @@ -54,7 +61,11 @@ class NetboxInfo(SeeddbInfo):
def netbox(request):
"""Controller for landing page for netboxes"""
return view_switcher(
request, list_view=netbox_list, move_view=netbox_move, delete_view=netbox_delete
request,
list_view=netbox_list,
move_view=netbox_move,
delete_view=netbox_delete,
generate_qr_codes_view=netbox_generate_qr_codes,
)


Expand Down Expand Up @@ -112,6 +123,58 @@ def netbox_pre_deletion_mark(queryset):
queryset.update(deleted_at=datetime.datetime.now(), up_to_date=False)


def netbox_generate_qr_codes(request):
"""Controller for generating qr codes for netboxes"""
if not request.POST.getlist('object'):
new_message(
request,
"You need to select at least one object to generate qr codes for",
Messages.ERROR,
)
return HttpResponseRedirect(reverse('seeddb-room'))

url_dict = dict()
netboxes = Netbox.objects.filter(id__in=request.POST.getlist('object'))

for netbox in netboxes:
url = request.build_absolute_uri(
reverse('ipdevinfo-details-by-id', kwargs={'netbox_id': netbox.id})
)
url_dict[str(netbox)] = url

qr_codes_zip_file = generate_qr_codes_as_zip_file(url_dict=url_dict)

info = NetboxInfo()
query = (
Netbox.objects.select_related("room", "category", "type", "organization")
.prefetch_related("profiles")
.annotate(profile=ArrayAgg("profiles__name"))
)
filter_form = NetboxFilterForm(request.GET)
value_list = (
'sysname',
'room',
'ip',
'category',
'organization',
'profile',
'type__name',
)
return render_list(
request,
query,
value_list,
'seeddb-netbox-edit',
edit_url_attr='pk',
filter_form=filter_form,
template='seeddb/list_netbox.html',
extra_context={
**info.template_context,
**{"qr_codes_zip_file": qr_codes_zip_file},
},
)


def netbox_move(request):
"""Controller for handling a move request"""
info = NetboxInfo()
Expand Down
49 changes: 48 additions & 1 deletion python/nav/web/seeddb/page/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
#
"""Forms and view functions for SeedDB's Room view"""

from django.http import HttpResponseRedirect
from django.urls import reverse

from nav.models.manage import Room
from nav.bulkparse import RoomBulkParser
from nav.bulkimport import RoomImporter

from nav.web.message import new_message, Messages
from nav.web.seeddb import SeeddbInfo, reverse_lazy
from nav.web.seeddb.constants import SEEDDB_EDITABLE_MODELS
from nav.web.seeddb.page import view_switcher
Expand All @@ -31,6 +33,10 @@
from nav.web.seeddb.utils.delete import render_delete
from nav.web.seeddb.utils.move import move
from nav.web.seeddb.utils.bulk import render_bulkimport
from nav.web.utils import (
generate_qr_codes_as_byte_strings,
generate_qr_codes_as_zip_file,
)

from ..forms import RoomForm, RoomFilterForm, RoomMoveForm

Expand All @@ -56,7 +62,11 @@ class RoomInfo(SeeddbInfo):
def room(request):
"""Controller for listing, moving and deleting rooms"""
return view_switcher(
request, list_view=room_list, move_view=room_move, delete_view=room_delete
request,
list_view=room_list,
move_view=room_move,
delete_view=room_delete,
generate_qr_codes_view=room_generate_qr_codes,
)


Expand Down Expand Up @@ -84,6 +94,43 @@ def room_move(request):
)


def room_generate_qr_codes(request):
"""Controller for generating qr codes for rooms"""
if not request.POST.getlist('object'):
new_message(
request,
"You need to select at least one object to generate qr codes for",
Messages.ERROR,
)
return HttpResponseRedirect(reverse('seeddb-room'))

url_dict = dict()
ids = request.POST.getlist('object')

for id in ids:
url = request.build_absolute_uri(reverse('room-info', kwargs={'roomid': id}))
url_dict[id] = url

qr_codes_zip_file = generate_qr_codes_as_zip_file(url_dict=url_dict)

info = RoomInfo()
value_list = ('id', 'location', 'description', 'position', 'data')
query = Room.objects.select_related("location").all()
filter_form = RoomFilterForm(request.GET)
# When we drop Python 3.7 we can use extra_context = info.template_context | {"qr_codes": qr_codes}
return render_list(
request,
query,
value_list,
'seeddb-room-edit',
filter_form=filter_form,
extra_context={
**info.template_context,
**{"qr_codes_zip_file": qr_codes_zip_file},
},
)


def room_delete(request, object_id=None):
"""Controller for deleting rooms. Used in room()"""
info = RoomInfo()
Expand Down
4 changes: 4 additions & 0 deletions python/nav/web/templates/seeddb/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
</div>
{% endif %}

{% if qr_codes_zip_file %}
<a src="{{ qr_codes_zip_file }}" download="nav_qr_codes">Download generated QR Codes</a>
{% endif %}

<div id="tablewrapper" class="notvisible" data-forpage="{{ request.path }}" data-page="{{ active_page }}">
<table id="seeddb-content" class="listtable" width="100%">
<caption>
Expand Down

0 comments on commit afdc234

Please sign in to comment.