Skip to content

Commit

Permalink
Merge pull request #106 from dimagi/sk/unicode-csv
Browse files Browse the repository at this point in the history
encode headings in csv writer
  • Loading branch information
snopoke authored Oct 8, 2018
2 parents fce79de + ecd0a33 commit bd884b1
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 11 deletions.
21 changes: 13 additions & 8 deletions commcare_export/writers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import csv
import datetime
import io
import logging
import sys
import zipfile
from itertools import chain

import alembic
import csv342 as csv
import six
import sqlalchemy
from six import StringIO, u
from six import u

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -82,17 +82,22 @@ def write_table(self, table):
if self.archive is None:
raise Exception('Attempt to write to a closed CsvWriter')

tempfile = StringIO()
def _encode_row(row):
return [
val.encode('utf-8') if isinstance(val, bytes) else val
for val in row
]

tempfile = io.StringIO()
writer = csv.writer(tempfile, dialect=csv.excel)
writer.writerow(table['headings'])
writer.writerow(_encode_row(table['headings']))
for row in table['rows']:
writer.writerow([val.encode('utf-8') if isinstance(val, six.text_type) else val
for val in row])
writer.writerow(_encode_row(row))

# TODO: make this a polite zip and put everything in a subfolder with the same basename
# as the zipfile
self.archive.writestr('%s.csv' % self.zip_safe_name(table['name']),
tempfile.getvalue())
tempfile.getvalue().encode('utf-8'))

def __exit__(self, exc_type, exc_val, exc_tb):
self.archive.close()
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ def run_tests(self):
'sqlalchemy',
'pytz',
'sqlalchemy-migrate',
'backoff'
'backoff',
'csv342'
],
tests_require = ['pytest', 'psycopg2', 'mock'],
cmdclass = {'test': PyTest},
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
import csv
import csv342 as csv
import os
import unittest
from argparse import Namespace
Expand Down
27 changes: 26 additions & 1 deletion tests/test_writers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import, division, generators, nested_scopes

import csv342 as csv
import datetime
import io
import tempfile
import zipfile

import openpyxl
import pytest
import sqlalchemy

from commcare_export.writers import SqlTableWriter, JValueTableWriter, Excel2007TableWriter
from commcare_export.writers import SqlTableWriter, JValueTableWriter, Excel2007TableWriter, CsvTableWriter


@pytest.fixture()
Expand Down Expand Up @@ -100,6 +103,28 @@ def _check_Excel2007TableWriter_output(self, filename):
['4', '日本', '6'],
]

def test_CsvTableWriter(self):
with tempfile.NamedTemporaryFile() as file:
with CsvTableWriter(file=file) as writer:
writer.write_table({
'name': 'foo',
'headings': ['a', 'bjørn', 'c'],
'rows': [
[1, '2', 3],
[4, '日本', 6],
]
})

with zipfile.ZipFile(file.name, 'r') as output_zip:
with output_zip.open('foo.csv') as csv_file:
output = csv.reader(io.TextIOWrapper(csv_file, encoding='utf-8'))

assert [row for row in output] == [
['a', 'bjørn', 'c'],
['1', '2', '3'],
['4', '日本', '6'],
]


@pytest.mark.dbtest
class TestSQLWriters(object):
Expand Down

0 comments on commit bd884b1

Please sign in to comment.