Skip to content

Commit

Permalink
Move CSV Export to settings
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanmajoor committed Mar 11, 2024
1 parent 9e8bd20 commit 703c361
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
17 changes: 15 additions & 2 deletions binder/plugins/views/csvexport.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class CsvExportSettings:
"""

def __init__(self, withs, column_map, file_name=None, default_file_name='download', multi_value_delimiter=' ',
extra_permission=None, extra_params={}, csv_adapter=RequestAwareAdapter):
extra_permission=None, extra_params={}, csv_adapter=RequestAwareAdapter, limit=10000):
"""
@param withs: String[] An array of all the withs that are necessary for this csv export
@param column_map: Tuple[] An array, with all columns of the csv file in order. Each column is represented by a tuple
Expand All @@ -195,6 +195,8 @@ def __init__(self, withs, column_map, file_name=None, default_file_name='downloa
@param extra_permission: String When set, an extra binder permission check will be done on this permission.
@param csv_adapter: Class. Either an object extending
@param response_type_mapping: Mapping between the parameter used in the custom response type
@param limit: Limit for amount of items in the csv. This is a fail save that you do not bring down the server with
a big query
"""
self.withs = withs
self.column_map = column_map
Expand All @@ -204,7 +206,18 @@ def __init__(self, withs, column_map, file_name=None, default_file_name='downloa
self.extra_permission = extra_permission
self.extra_params = extra_params
self.csv_adapter = csv_adapter
self._limit = limit

@property
def limit(self):
if self._limit is None:
return 'none'
return self._limit

@limit.setter
def limit(self, value):

self._limit = value
def _generate_csv_file(self, request: HttpRequest, file_adapter: CsvFileAdapter):

# Sometimes we want to add an extra permission check before a csv file can be downloaded. This checks if the
Expand All @@ -216,7 +229,7 @@ def _generate_csv_file(self, request: HttpRequest, file_adapter: CsvFileAdapter)
mutable = request.POST._mutable
request.GET._mutable = True
request.GET['page'] = 1
request.GET['limit'] = 10000
request.GET['limit'] = self.csv_settings.limit
request.GET['with'] = ",".join(self.csv_settings.withs)
for key, value in self.csv_settings.extra_params.items():
request.GET[key] = value
Expand Down
57 changes: 57 additions & 0 deletions tests/plugins/test_csvexport.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from django.contrib.auth.models import User

from ..testapp.models import Picture, Animal, Caretaker
from ..testapp.views import PictureView
import csv
import openpyxl

Expand Down Expand Up @@ -146,3 +147,59 @@ def test_context_aware_download_xlsx(self):
[self.pictures[1].id, str(self.pictures[1].animal_id), (self.pictures[1].id ** 2)])
self.assertEqual(list(_values[3]),
[self.pictures[2].id, str(self.pictures[2].animal_id), (self.pictures[2].id ** 2)])

def test_csv_export_custom_limit(self):
old_limit = PictureView.csv_settings.limit;
PictureView.csv_settings.limit = 1
response = self.client.get('/picture/download/')
self.assertEqual(200, response.status_code)
response_data = csv.reader(io.StringIO(response.content.decode("utf-8")))

# Header
self.assertEqual(next(response_data), ['picture identifier', 'animal identifier', 'squared picture identifier'])
# 1 REcord
self.assertIsNotNone(next(response_data))

# EOF
with self.assertRaises(StopIteration):
self.assertIsNone(next(response_data))

###### Limit 2
PictureView.csv_settings.limit = 2
response = self.client.get('/picture/download/')
self.assertEqual(200, response.status_code)
response_data = csv.reader(io.StringIO(response.content.decode("utf-8")))

# Header
self.assertEqual(next(response_data), ['picture identifier', 'animal identifier', 'squared picture identifier'])
# 1 REcord
self.assertIsNotNone(next(response_data))
# 2 Records
self.assertIsNotNone(next(response_data))
# EOF
with self.assertRaises(StopIteration):
self.assertIsNone(next(response_data))

PictureView.csv_settings.limit = old_limit;

def test_csv_settings_limit_none_working(self):
# Limit None should download everything

old_limit = PictureView.csv_settings.limit;
PictureView.csv_settings.limit = None
response = self.client.get('/picture/download/')
self.assertEqual(200, response.status_code)
response_data = csv.reader(io.StringIO(response.content.decode("utf-8")))

# Header
self.assertEqual(next(response_data), ['picture identifier', 'animal identifier', 'squared picture identifier'])
# 3 REcords, everything we have in the database
self.assertIsNotNone(next(response_data))
self.assertIsNotNone(next(response_data))
self.assertIsNotNone(next(response_data))

# EOF
with self.assertRaises(StopIteration):
self.assertIsNone(next(response_data))

PictureView.csv_settings.limit = old_limit;

0 comments on commit 703c361

Please sign in to comment.