From: Guillaume Pellerin Date: Fri, 13 Nov 2015 14:35:47 +0000 (+0100) Subject: begin CSV streaming X-Git-Tag: 1.6b~7^2~46^2~3 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=6e75823b7f496408b05be7b9896b06b32a2c09bc;p=telemeta.git begin CSV streaming --- diff --git a/telemeta/util/unicode.py b/telemeta/util/unicode.py index 152a9fad..a21005e7 100644 --- a/telemeta/util/unicode.py +++ b/telemeta/util/unicode.py @@ -50,46 +50,58 @@ def _stringify_list(l, encoding): return [_stringify(s, encoding) for s in l] -class UnicodeWriter(object): +class UnicodeCSVWriter(object): def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): - self.writer = csv.writer(f) self.dialect = dialect self.encoding = encoding self.writer = csv.writer(f, dialect=dialect, **kwds) + self.line = 0 + self.tags = [] + + def write_tags(self, element): + element_dict = element.to_dict_with_more() + + for key in element_dict.keys(): + if not key in self.tags: + self.tags.append(key) + + # code and title on the two first column + self.tags.remove('code') + self.tags.remove('title') + self.tags.sort() + self.tags.insert(0, 'title') + self.tags.insert(0, 'code') + self.writer.writerow(self.tags) + self.line += 1 + print self.tags + + def write_element(self, element): + if self.line == 0: + self.write_tags(element) + row = [] + element_dict = element.to_dict_with_more() + + for tag in self.tags: + if tag in element_dict.keys(): + row.append(element_dict[tag]) + else: + row.append('') + self.writerow(row) + print row def writerow(self, row): self.writer.writerow(_stringify_list(row, self.encoding)) + self.line += 1 def writerows(self, rows): for row in rows: self.writerow(row) -class CSVExport(object): - - def __init__(self, writer): - self.writer = writer - - def write(self, elements): - tags = [] - element_dicts = [e.to_dict_with_more() for e in elements] - for e in element_dicts: - for key in e.keys(): - if not key in tags: - tags.append(key) - # code and title on the two first column - tags.remove('code') - tags.remove('title') - tags.sort() - tags.insert(0, 'title') - tags.insert(0, 'code') - self.writer.writerow(tags) - - for element in element_dicts: - data = [] - for tag in tags: - if tag in element.keys(): - data.append(element[tag]) - else: - data.append('') - self.writer.writerow(data) +class Echo(object): + """An object that implements just the write method of the file-like + interface. + """ + def write(self, value): + """Write the value by returning it, instead of storing in a buffer.""" + return value diff --git a/telemeta/views/core.py b/telemeta/views/core.py index 0ac49103..badd0585 100644 --- a/telemeta/views/core.py +++ b/telemeta/views/core.py @@ -85,7 +85,7 @@ from telemeta.interop.oaidatasource import TelemetaOAIDataSource from telemeta.util.unaccent import unaccent from telemeta.util.unaccent import unaccent_icmp from telemeta.util.logger import Logger -from telemeta.util.unicode import UnicodeWriter, CSVExport +from telemeta.util.unicode import UnicodeCSVWriter, Echo from telemeta.cache import TelemetaCache import pages from telemeta.forms import * diff --git a/telemeta/views/playlist.py b/telemeta/views/playlist.py index 8ee10ef6..f7aca7a0 100644 --- a/telemeta/views/playlist.py +++ b/telemeta/views/playlist.py @@ -85,15 +85,13 @@ class PlaylistView(object): m = PlaylistResource.objects.get(public_id=public_id) m.delete() - def playlist_csv_export(self, request, public_id, resource_type): playlist = Playlist.objects.get(public_id=public_id, author=request.user) resources = PlaylistResource.objects.filter(playlist=playlist) - response = HttpResponse(content_type='text/csv') - response['Content-Disposition'] = 'attachment; filename='+playlist.title+'_'+resource_type+'.csv' - writer = UnicodeWriter(response) - + pseudo_buffer = Echo() + writer = UnicodeCSVWriter(pseudo_buffer) elements = [] + for resource in resources: if resource_type == 'items': if resource.resource_type == 'collection': @@ -114,8 +112,6 @@ class PlaylistView(object): collection = MediaCollection.objects.get(id=resource.resource_id) elements.append(collection) - if elements: - csv = CSVExport(writer) - csv.write(elements) - + response = StreamingHttpResponse((writer.write_element(element) for element in elements), content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename='+playlist.title+'_'+resource_type+'.csv' return response