import codecs
import csv
import os
import openpyxl
import six
import xlrd
from django.conf import settings
from django.utils.encoding import force_text
from django.utils.translation import gettext_lazy as _
from shuup.utils.excs import Problem
[docs]
class RowYielder:
[docs]
def __init__(self, sheet_or_data):
self.sheet_or_data = sheet_or_data
[docs]
class XLSRowYielder(RowYielder):
def __iter__(self):
for y in range(self.sheet_or_data.nrows):
yield self.transform_values(self.sheet_or_data.row_values(y))
[docs]
class XLSXRowYielder(RowYielder):
def __iter__(self):
for row in self.sheet_or_data.rows:
yield self.transform_values([(force_text(cell.value) if cell.value else None) for cell in row])
[docs]
def process_data(rows):
headers = []
got_data = set()
data = []
if not len(data):
for y, row in enumerate(rows):
if not any(row): # Ignore any fully cleared rows
continue
if y == 0:
headers = [x.lower().strip() for x in row if x]
continue
datum = dict(zip(headers, row))
got_data.update({h for (h, d) in six.iteritems(datum) if d})
data.append(datum)
row_limit = getattr(settings, "IMPORT_MAX_ROWS", 1000)
if len(data) > row_limit:
raise Problem(_("Can't import more than %s rows from one file.") % row_limit)
return (data, got_data)
[docs]
def py2_read_file(data, filename):
got_data = set()
data = []
with open(filename) as f:
dialect = csv.Sniffer().sniff(f.read(20480))
f.seek(0)
for _x, row in enumerate(csv.DictReader(f, dialect=dialect)):
got_data.update({h.lower() for (h, d) in six.iteritems(row) if d})
data.append({k.lower(): v if v else None for k, v in six.iteritems(row)})
return data, got_data
[docs]
def py3_read_file(data, filename):
got_data = set()
data = []
bytes = min(32, os.path.getsize(filename))
raw = open(filename, "rb").read(bytes)
if raw.startswith(codecs.BOM_UTF8):
encoding = "utf-8-sig"
else:
encoding = "utf-8"
with open(filename, encoding=encoding) as f:
dialect = csv.Sniffer().sniff(f.read(20480))
f.seek(0)
for _x, row in enumerate(csv.DictReader(f, dialect=dialect)):
got_data.update({h.lower() for (h, d) in six.iteritems(row) if d})
data.append({k.lower(): v if v else None for k, v in six.iteritems(row)})
return data, got_data