From 5b7e817db20c7492d501901b79c2b7f2585e407f Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 21 Sep 2010 02:42:08 -0400 Subject: [PATCH 01/20] Only CSV Left. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index c0333e7..387a807 100644 --- a/README.rst +++ b/README.rst @@ -131,7 +131,7 @@ If you'd like to contribute, simply fork `the repository`_, commit your changes Roadmap ------- -- Import datasets from CSV, JSON, YAML +- Import datasets from CSV. - Release CLI Interface - Auto-detect import format - Add possible other exports (SQL?) From 5a993ac281f5dbfd0cee2039c61af0701e5fa323 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:49:14 -0400 Subject: [PATCH 02/20] Working on it. --- tablib/core.py | 138 ++++++++++++++++++++----------------------------- 1 file changed, 56 insertions(+), 82 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 551a326..2c9811a 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -1,7 +1,10 @@ # -*- coding: utf-8 -*- -""" Tablib - Core Library -""" +# _____ ______ ______ _________ +# __ /_______ ____ /_ ___ /_ _____ ______ / +# _ __/_ __ `/__ __ \__ __ \_ _ \_ __ / +# / /_ / /_/ / _ /_/ /_ /_/ // __// /_/ / +# \__/ \__,_/ /_.___/ /_.___/ \___/ \__,_/ import csv @@ -11,6 +14,8 @@ import simplejson as json import xlwt import yaml +from tablib.formats import formats + __title__ = 'tablib' __version__ = '0.7.1' @@ -24,22 +29,20 @@ class Dataset(object): """Epic Tabular-Dataset object. """ def __init__(self, *args, **kwargs): - self._data = None - self._saved_file = None - self._saved_format = None self._data = list(args) self.__headers = None try: self.headers = kwargs['headers'] - except KeyError: + except KeyError, why: self.headers = None try: self.title = kwargs['title'] - except KeyError: + except KeyError, why: self.title = None + self._register_formats() def __len__(self): return self.height @@ -71,6 +74,16 @@ class Dataset(object): except AttributeError: return '' + + @classmethod + def _register_formats(cls): + """Adds format properties.""" + for fmt in formats: + try: + setattr(cls, fmt.title, property(fmt.export_set)) + except Exception, why: + pass + def _validate(self, row=None, col=None, safety=False): """Assures size of every row in dataset is of proper proportions.""" @@ -105,6 +118,7 @@ class Dataset(object): return data + @property def height(self): """Returns the height of the Dataset.""" @@ -116,12 +130,13 @@ class Dataset(object): """Returns the width of the Dataset.""" try: return len(self._data[0]) - except IndexError: + except IndexError, why: try: return len(self.headers) - except TypeError: + except TypeError, e: return 0 - + + @property def headers(self): """Headers property.""" @@ -135,7 +150,7 @@ class Dataset(object): if collection: try: self.__headers = list(collection) - except TypeError: + except TypeError, why: raise TypeError else: self.__headers = None @@ -146,42 +161,21 @@ class Dataset(object): """Returns python dict of Dataset.""" return self._package() - - @property - def json(self): - """Returns JSON representation of Dataset.""" - return json.dumps(self.dict) - - @property - def yaml(self): - """Returns YAML representation of Dataset.""" - return yaml.dump(self.dict) - - @property - def csv(self): - """Returns CSV representation of Dataset.""" - stream = cStringIO.StringIO() - _csv = csv.writer(stream) - - for row in self._package(dicts=False): - _csv.writerow(row) - - return stream.getvalue() - - @property - def xls(self): - """Returns XLS representation of Dataset.""" - - workb = xlwt.Workbook(encoding='utf8') - works = workb.add_sheet(self.title if self.title else 'Tabbed Dataset') - - for i, row in enumerate(self._package(dicts=False)): - for j, col in enumerate(row): - works.write(i, j, col) - - stream = cStringIO.StringIO() - workb.save(stream) - return stream.getvalue() + + @dict.setter + def dict(self, pickle): + """Returns python dict of Dataset.""" + if not len(pickle): + return + if isinstance(pickle[0], list): + for row in pickle: + self.append(row) + elif isinstance(pickle[0], dict): + self.headers = pickle[0].keys() + for row in pickle: + self.append(row.values()) + else: + raise UnsupportedFormat def append(self, row=None, col=None): @@ -223,10 +217,24 @@ class Databook(object): def __init__(self, sets=[]): self._datasets = sets + self._register_formats() def __repr__(self): - return '' + try: + return '<%s databook>' % (self.title.lower()) + except AttributeError: + return '' + + + @classmethod + def _register_formats(cls): + """Adds format properties.""" + for fmt in formats.formats: + try: + setattr(cls, fmt.title, property(fmt.export_book)) + except Exception, why: + pass def add_sheet(self, dataset): @@ -252,40 +260,6 @@ class Databook(object): """The number of the Datasets within DataBook.""" return len(self._datasets) - @property - def xls(self): - """Returns XLS representation of DataBook.""" - - - workb = xlwt.Workbook(encoding='utf8') - - for i, dset in enumerate(self._datasets): - works = workb.add_sheet(dset.title if dset.title else 'Sheet%s' % (i)) - - #for row in self._package(dicts=False): - for i, row in enumerate(dset._package(dicts=False)): - for j, col in enumerate(row): - works.write(i, j, col) - - - stream = cStringIO.StringIO() - workb.save(stream) - return stream.getvalue() - - - @property - def json(self): - """Returns JSON representation of Databook.""" - - return json.dumps(self._package()) - - - @property - def yaml(self): - """Returns YAML representation of Databook.""" - - return yaml.dump(self._package()) - class InvalidDatasetType(Exception): From 63d025888aeaf61022524f09d520e4b29687bdc5 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:49:21 -0400 Subject: [PATCH 03/20] Added format importers. --- tablib/formats/__init__.py | 11 ++++++++++ tablib/formats/_csv.py | 41 +++++++++++++++++++++++++++++++++++++ tablib/formats/_json.py | 32 +++++++++++++++++++++++++++++ tablib/formats/_xls.py | 42 ++++++++++++++++++++++++++++++++++++++ tablib/formats/_yaml.py | 27 ++++++++++++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 tablib/formats/__init__.py create mode 100644 tablib/formats/_csv.py create mode 100644 tablib/formats/_json.py create mode 100644 tablib/formats/_xls.py create mode 100644 tablib/formats/_yaml.py diff --git a/tablib/formats/__init__.py b/tablib/formats/__init__.py new file mode 100644 index 0000000..b9c7451 --- /dev/null +++ b/tablib/formats/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- + +""" Tablib - formats +""" + +import _csv as csv +import _json as json +import _xls as xls +import _yaml as yaml + +formats = (csv, json, xls, yaml) diff --git a/tablib/formats/_csv.py b/tablib/formats/_csv.py new file mode 100644 index 0000000..0554976 --- /dev/null +++ b/tablib/formats/_csv.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +import cStringIO +import csv +import os + +import simplejson as json + +import tablib + + +title = 'csv' +extentions = ('csv',) + + + +def export_set(dataset): + """Returns CSV representation of Dataset.""" + stream = cStringIO.StringIO() + _csv = csv.writer(stream) + + for row in dataset._package(dicts=False): + _csv.writerow(row) + + return stream.getvalue() + + +def import_set(in_stream, headers=True): + """Returns dataset from CSV stream.""" + + data = tablib.core.Dataset() + + rows = csv.reader(in_stream.split()) + for i, row in enumerate(rows): + + if (i == 1) and (headers): + data.headers = row + else: + data.append(row) + + return data \ No newline at end of file diff --git a/tablib/formats/_json.py b/tablib/formats/_json.py new file mode 100644 index 0000000..acbaf57 --- /dev/null +++ b/tablib/formats/_json.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +import simplejson as json +import tablib.core + +title = 'json' +extentions = ('json', 'jsn') + + +def export_set(dataset): + """Returns JSON representation of Dataset.""" + return json.dumps(dataset.dict) + + +def export_book(databook): + """Returns JSON representation of Databook.""" + + return json.dumps(databook._package()) + + +def detect(contents): + """Return True if contets are JSON.""" + return False + + +def import_set(in_stream): + """Returns dataset from JSON stream.""" + data = tablib.core.Dataset() + data.dict = json.loads(in_stream) + + return data + diff --git a/tablib/formats/_xls.py b/tablib/formats/_xls.py new file mode 100644 index 0000000..67bd31c --- /dev/null +++ b/tablib/formats/_xls.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +import xlwt +import cStringIO + + +title = 'xls' +extentions = ('xls') + + +def export_set(dataset): + """Returns XLS representation of Dataset.""" + + wb = xlwt.Workbook(encoding='utf8') + ws = wb.add_sheet(dataset.title if dataset.title else 'Tabbed Dataset') + + for i, row in enumerate(dataset._package(dicts=False)): + for j, col in enumerate(row): + ws.write(i, j, col) + + stream = cStringIO.StringIO() + wb.save(stream) + return stream.getvalue() + + +def export_book(databook): + """Returns XLS representation of DataBook.""" + + wb = xlwt.Workbook(encoding='utf8') + + for i, dset in enumerate(databook._datasets): + ws = wb.add_sheet(dset.title if dset.title else 'Sheet%s' % (i)) + + #for row in self._package(dicts=False): + for i, row in enumerate(dset._package(dicts=False)): + for j, col in enumerate(row): + ws.write(i, j, col) + + + stream = cStringIO.StringIO() + wb.save(stream) + return stream.getvalue() \ No newline at end of file diff --git a/tablib/formats/_yaml.py b/tablib/formats/_yaml.py new file mode 100644 index 0000000..35c2bf2 --- /dev/null +++ b/tablib/formats/_yaml.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +import yaml +import tablib + +title = 'yaml' +extentions = ('yaml', 'yml') + + + +def export_set(dataset): + """Returns YAML representation of Dataset.""" + return yaml.dump(dataset.dict) + + +def export_book(databook): + """Returns YAML representation of Databook.""" + return yaml.dump(databook._package()) + + +def import_set(in_stream): + """Returns dataset from YAML stream.""" + + data = tablib.core.Dataset() + data.dict = yaml.load(in_stream) + + return data \ No newline at end of file From cab63e02c873ffa86a4688342d35ae72ca321625 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:53:13 -0400 Subject: [PATCH 04/20] Module namespace change. --- tablib/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tablib/core.py b/tablib/core.py index 2c9811a..52a8faa 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -230,7 +230,7 @@ class Databook(object): @classmethod def _register_formats(cls): """Adds format properties.""" - for fmt in formats.formats: + for fmt in formats: try: setattr(cls, fmt.title, property(fmt.export_book)) except Exception, why: From 4c0c879d657b0d8c791135de8e5b8420bf410a96 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:53:19 -0400 Subject: [PATCH 05/20] Updated tests. --- test_tablib.py | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/test_tablib.py b/test_tablib.py index 959a01c..0f79a20 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -181,6 +181,45 @@ class TablibTestCase(unittest.TestCase): data.csv data.xls - + + def test_book_export_no_exceptions(self): + """Test that varoius exports don't error out.""" + + book = tablib.Databook() + book.add_sheet(data) + + book.json + book.yaml + book.xls + + + def test_json_import(self): + """Generate and import JSON serialization.""" + data.append(self.john) + new_data = tablib.formats.json.import_set(str(data.json)) + + new_data.headers = self.headers + new_data = tablib.formats.json.import_set(str(new_data.json)) + + def test_yaml_import(self): + """Generate and import YAML serialization.""" + data.append(self.john) + new_data = tablib.formats.yaml.import_set(str(data.json)) + + new_data.headers = self.headers + new_data = tablib.formats.yaml.import_set(str(new_data.json)) + + def test_csv_import(self): + """Generate and import CSV serialization.""" + data.append(self.john) + data.append(self.george) + data.headers = self.headers +# new_data = tablib.formats.csv.import_set(str(data.csv)) + +# new_data.headers = self.headers + new_data = tablib.formats.csv.import_set(str(data.csv)) +# print new_data + + if __name__ == '__main__': unittest.main() From b1d282744cfcc20fd5fc7478e64832b6b484cdfb Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:57:42 -0400 Subject: [PATCH 06/20] Docstring updates. --- tablib/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tablib/core.py b/tablib/core.py index 52a8faa..bc1cbbf 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -246,6 +246,7 @@ class Databook(object): def _package(self): + """Packages Databook for delivery.""" collector = [] for dset in self._datasets: collector.append(dict( From 942dd3dadfc8de2956b1179b0d4ae608e68fc64c Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:58:40 -0400 Subject: [PATCH 07/20] Added tablib core docstring placeholder. --- tablib/core.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index bc1cbbf..508d8c9 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -1,11 +1,7 @@ # -*- coding: utf-8 -*- -# _____ ______ ______ _________ -# __ /_______ ____ /_ ___ /_ _____ ______ / -# _ __/_ __ `/__ __ \__ __ \_ _ \_ __ / -# / /_ / /_/ / _ /_/ /_ /_/ // __// /_/ / -# \__/ \__,_/ /_.___/ /_.___/ \___/ \__,_/ - +""" Tablib - core. +""" import csv import cStringIO @@ -34,12 +30,12 @@ class Dataset(object): try: self.headers = kwargs['headers'] - except KeyError, why: + except KeyError: self.headers = None try: self.title = kwargs['title'] - except KeyError, why: + except KeyError: self.title = None self._register_formats() @@ -81,7 +77,7 @@ class Dataset(object): for fmt in formats: try: setattr(cls, fmt.title, property(fmt.export_set)) - except Exception, why: + except Exception: pass @@ -130,10 +126,10 @@ class Dataset(object): """Returns the width of the Dataset.""" try: return len(self._data[0]) - except IndexError, why: + except IndexError: try: return len(self.headers) - except TypeError, e: + except TypeError: return 0 @@ -150,7 +146,7 @@ class Dataset(object): if collection: try: self.__headers = list(collection) - except TypeError, why: + except TypeError: raise TypeError else: self.__headers = None @@ -233,7 +229,7 @@ class Databook(object): for fmt in formats: try: setattr(cls, fmt.title, property(fmt.export_book)) - except Exception, why: + except Exception: pass From 8d7e5732cd95c23cfa5947342312e7e519f8e311 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:59:02 -0400 Subject: [PATCH 08/20] Typo. --- tablib/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tablib/core.py b/tablib/core.py index 508d8c9..3f79a36 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -234,7 +234,7 @@ class Databook(object): def add_sheet(self, dataset): - """Add given dataset .""" + """Adds given dataset.""" if type(dataset) is Dataset: self._datasets.append(dataset) else: From 80cb42e8dd787a2ceffb37fe7a2380a97d000f4e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 06:20:34 -0400 Subject: [PATCH 09/20] Archaic imports in place! --- tablib/formats/_csv.py | 2 +- tablib/formats/_json.py | 21 ++++++++++++++------- tablib/formats/_yaml.py | 15 ++++++++++++++- test_tablib.py | 10 ++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/tablib/formats/_csv.py b/tablib/formats/_csv.py index 0554976..a66f2e0 100644 --- a/tablib/formats/_csv.py +++ b/tablib/formats/_csv.py @@ -33,7 +33,7 @@ def import_set(in_stream, headers=True): rows = csv.reader(in_stream.split()) for i, row in enumerate(rows): - if (i == 1) and (headers): + if (i == 0) and (headers): data.headers = row else: data.append(row) diff --git a/tablib/formats/_json.py b/tablib/formats/_json.py index acbaf57..18885c7 100644 --- a/tablib/formats/_json.py +++ b/tablib/formats/_json.py @@ -14,19 +14,26 @@ def export_set(dataset): def export_book(databook): """Returns JSON representation of Databook.""" - return json.dumps(databook._package()) - - -def detect(contents): - """Return True if contets are JSON.""" - return False - + def import_set(in_stream): """Returns dataset from JSON stream.""" + data = tablib.core.Dataset() data.dict = json.loads(in_stream) return data + +def import_book(in_stream): + """Returns databook from JSON stream.""" + + book = tablib.core.Databook() + for sheet in json.loads(in_stream): + data = tablib.core.Dataset() + data.title = sheet['title'] + data.dict = sheet['data'] + book.add_sheet(data) + + return book \ No newline at end of file diff --git a/tablib/formats/_yaml.py b/tablib/formats/_yaml.py index 35c2bf2..d54e29a 100644 --- a/tablib/formats/_yaml.py +++ b/tablib/formats/_yaml.py @@ -24,4 +24,17 @@ def import_set(in_stream): data = tablib.core.Dataset() data.dict = yaml.load(in_stream) - return data \ No newline at end of file + return data + + +def import_book(in_stream): + """Returns databook from YAML stream.""" + + book = tablib.core.Databook() + for sheet in yaml.load(in_stream): + data = tablib.core.Dataset() + data.title = sheet['title'] + data.dict = sheet['data'] + book.add_sheet(data) + + return book \ No newline at end of file diff --git a/test_tablib.py b/test_tablib.py index 0f79a20..6758daa 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -200,6 +200,11 @@ class TablibTestCase(unittest.TestCase): new_data.headers = self.headers new_data = tablib.formats.json.import_set(str(new_data.json)) + + book = tablib.Databook() + book.add_sheet(new_data) + new_book = tablib.formats.json.import_book(str(book.json)) + def test_yaml_import(self): """Generate and import YAML serialization.""" @@ -208,6 +213,11 @@ class TablibTestCase(unittest.TestCase): new_data.headers = self.headers new_data = tablib.formats.yaml.import_set(str(new_data.json)) + + book = tablib.Databook() + book.add_sheet(new_data) + new_book = tablib.formats.yaml.import_book(str(book.yaml)) + def test_csv_import(self): """Generate and import CSV serialization.""" From a9c7a5067dffa9f5d67708941c0eefca7aa7c203 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 06:22:40 -0400 Subject: [PATCH 10/20] Added dataset wipe. --- tablib/core.py | 6 ++++++ test_tablib.py | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/tablib/core.py b/tablib/core.py index 3f79a36..e368bab 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -204,6 +204,12 @@ class Dataset(object): self._data.insert(i, tuple(row)) elif col: pass + + + def wipe(self): + """Erases all data from Dataset.""" + self._data = list() + self.__headers = None class Databook(object): diff --git a/test_tablib.py b/test_tablib.py index 6758daa..54ab6f3 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -230,6 +230,21 @@ class TablibTestCase(unittest.TestCase): new_data = tablib.formats.csv.import_set(str(data.csv)) # print new_data + def test_wipe(self): + """Purge a dataset.""" + + new_row = (1, 2, 3) + data.append(new_row) + + # Verify width/data + self.assertTrue(data.width == len(new_row)) + self.assertTrue(data[0] == new_row) + + data.wipe() + new_row = (1, 2, 3, 4) + data.append(new_row) + self.assertTrue(data.width == len(new_row)) + self.assertTrue(data[0] == new_row) if __name__ == '__main__': unittest.main() From 4f035caf1b8bf9f6f0f594682651f55d192f5a68 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 10:40:59 -0400 Subject: [PATCH 11/20] Added dataset wipe. --- test_tablib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_tablib.py b/test_tablib.py index 54ab6f3..6b4efa8 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -224,9 +224,9 @@ class TablibTestCase(unittest.TestCase): data.append(self.john) data.append(self.george) data.headers = self.headers -# new_data = tablib.formats.csv.import_set(str(data.csv)) + new_data = tablib.formats.csv.import_set(str(data.csv)) -# new_data.headers = self.headers + new_data.headers = self.headers new_data = tablib.formats.csv.import_set(str(data.csv)) # print new_data From dfa26a7d53097c32283f2876be2e0b1ecf1b312f Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 10:49:06 -0400 Subject: [PATCH 12/20] Typos. --- test_tablib.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_tablib.py b/test_tablib.py index 6b4efa8..73f8efc 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -228,7 +228,7 @@ class TablibTestCase(unittest.TestCase): new_data.headers = self.headers new_data = tablib.formats.csv.import_set(str(data.csv)) -# print new_data + def test_wipe(self): """Purge a dataset.""" @@ -245,6 +245,7 @@ class TablibTestCase(unittest.TestCase): data.append(new_row) self.assertTrue(data.width == len(new_row)) self.assertTrue(data[0] == new_row) + if __name__ == '__main__': unittest.main() From 4117503ed5f2229c54df68bc9ab339f7ea7cb36d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 15:23:01 -0400 Subject: [PATCH 13/20] Elegant imports in place! --- tablib/core.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index e368bab..9500d20 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -76,8 +76,12 @@ class Dataset(object): """Adds format properties.""" for fmt in formats: try: - setattr(cls, fmt.title, property(fmt.export_set)) - except Exception: + try: + setattr(cls, fmt.title, property(fmt.export_set, fmt.import_set)) + except AttributeError: + setattr(cls, fmt.title, property(fmt.export_set)) + + except AttributeError: pass @@ -234,8 +238,12 @@ class Databook(object): """Adds format properties.""" for fmt in formats: try: - setattr(cls, fmt.title, property(fmt.export_book)) - except Exception: + try: + setattr(cls, fmt.title, property(fmt.export_book, fmt.import_book)) + except AttributeError: + setattr(cls, fmt.title, property(fmt.export_book)) + + except AttributeError: pass From 65836d5acea764584540082b45d8d58dac2bd52e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 15:24:16 -0400 Subject: [PATCH 14/20] Updated elegant imports for instance properties. Data wipes. --- tablib/formats/_csv.py | 10 ++++------ tablib/formats/_json.py | 8 +++----- tablib/formats/_xls.py | 2 +- tablib/formats/_yaml.py | 8 +++----- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/tablib/formats/_csv.py b/tablib/formats/_csv.py index a66f2e0..6dba44b 100644 --- a/tablib/formats/_csv.py +++ b/tablib/formats/_csv.py @@ -25,17 +25,15 @@ def export_set(dataset): return stream.getvalue() -def import_set(in_stream, headers=True): +def import_set(dset, in_stream, headers=True): """Returns dataset from CSV stream.""" - data = tablib.core.Dataset() + dset.wipe() rows = csv.reader(in_stream.split()) for i, row in enumerate(rows): if (i == 0) and (headers): - data.headers = row + dset.headers = row else: - data.append(row) - - return data \ No newline at end of file + dset.append(row) diff --git a/tablib/formats/_json.py b/tablib/formats/_json.py index 18885c7..d60cd21 100644 --- a/tablib/formats/_json.py +++ b/tablib/formats/_json.py @@ -17,13 +17,11 @@ def export_book(databook): return json.dumps(databook._package()) -def import_set(in_stream): +def import_set(dset, in_stream): """Returns dataset from JSON stream.""" - data = tablib.core.Dataset() - data.dict = json.loads(in_stream) - - return data + dset.wipe() + dset.dict = json.loads(in_stream) def import_book(in_stream): diff --git a/tablib/formats/_xls.py b/tablib/formats/_xls.py index 67bd31c..979fa62 100644 --- a/tablib/formats/_xls.py +++ b/tablib/formats/_xls.py @@ -5,7 +5,7 @@ import cStringIO title = 'xls' -extentions = ('xls') +extentions = ('xls',) def export_set(dataset): diff --git a/tablib/formats/_yaml.py b/tablib/formats/_yaml.py index d54e29a..6cec90c 100644 --- a/tablib/formats/_yaml.py +++ b/tablib/formats/_yaml.py @@ -18,13 +18,11 @@ def export_book(databook): return yaml.dump(databook._package()) -def import_set(in_stream): +def import_set(dset): """Returns dataset from YAML stream.""" - data = tablib.core.Dataset() - data.dict = yaml.load(in_stream) - - return data + dset.wipe() + dset.dict = yaml.load(in_stream) def import_book(in_stream): From 99154aa6d615555baef8cf850db780f6e93585d0 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 15:24:59 -0400 Subject: [PATCH 15/20] Merge branches 'feature/import-seamless' and 'feature/imports' into feature/imports From 59ccc0b4224c383d55bbab8535c4e8e74cf46c99 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 15:39:09 -0400 Subject: [PATCH 16/20] YAML input support. --- tablib/formats/_yaml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tablib/formats/_yaml.py b/tablib/formats/_yaml.py index 6cec90c..74d9155 100644 --- a/tablib/formats/_yaml.py +++ b/tablib/formats/_yaml.py @@ -18,7 +18,7 @@ def export_book(databook): return yaml.dump(databook._package()) -def import_set(dset): +def import_set(dset, in_stream): """Returns dataset from YAML stream.""" dset.wipe() From 7623bfe7b09817b3d64e234d630c225b5b3d0bba Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 15:40:05 -0400 Subject: [PATCH 17/20] Updated tests for set imports. --- test_tablib.py | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/test_tablib.py b/test_tablib.py index 73f8efc..cb8549c 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -193,41 +193,43 @@ class TablibTestCase(unittest.TestCase): book.xls - def test_json_import(self): + def test_json_import_set(self): """Generate and import JSON serialization.""" data.append(self.john) - new_data = tablib.formats.json.import_set(str(data.json)) + data.append(self.george) + data.headers = self.headers - new_data.headers = self.headers - new_data = tablib.formats.json.import_set(str(new_data.json)) - - book = tablib.Databook() - book.add_sheet(new_data) - new_book = tablib.formats.json.import_book(str(book.json)) + _json = data.json + + data.json = _json + + self.assertEqual(_json, data.json) - def test_yaml_import(self): + def test_yaml_import_set(self): """Generate and import YAML serialization.""" data.append(self.john) - new_data = tablib.formats.yaml.import_set(str(data.json)) + data.append(self.george) + data.headers = self.headers - new_data.headers = self.headers - new_data = tablib.formats.yaml.import_set(str(new_data.json)) - - book = tablib.Databook() - book.add_sheet(new_data) - new_book = tablib.formats.yaml.import_book(str(book.yaml)) + _yaml = data.yaml + + data.yaml = _yaml + + self.assertEqual(_yaml, data.yaml) - def test_csv_import(self): + def test_csv_import_set(self): """Generate and import CSV serialization.""" data.append(self.john) data.append(self.george) data.headers = self.headers - new_data = tablib.formats.csv.import_set(str(data.csv)) - new_data.headers = self.headers - new_data = tablib.formats.csv.import_set(str(data.csv)) + _csv = data.csv + + data.csv = _csv + + self.assertEqual(_csv, data.csv) def test_wipe(self): From f1bdf43aab2e6c6a2641fd52086918e3fa0e5b42 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 15:50:06 -0400 Subject: [PATCH 18/20] Book wiper. --- tablib/core.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tablib/core.py b/tablib/core.py index 9500d20..849e4bc 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -232,7 +232,10 @@ class Databook(object): except AttributeError: return '' - + def wipe(self): + """Wipe book clean.""" + self._datasets = [] + @classmethod def _register_formats(cls): """Adds format properties.""" From a73bbe16450054e4238018a68f97319d1da60d8f Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 15:56:20 -0400 Subject: [PATCH 19/20] Elegant databook importers. --- tablib/formats/_json.py | 8 +++----- tablib/formats/_yaml.py | 9 ++++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/tablib/formats/_json.py b/tablib/formats/_json.py index d60cd21..c2dd524 100644 --- a/tablib/formats/_json.py +++ b/tablib/formats/_json.py @@ -24,14 +24,12 @@ def import_set(dset, in_stream): dset.dict = json.loads(in_stream) -def import_book(in_stream): +def import_book(dbook, in_stream): """Returns databook from JSON stream.""" - book = tablib.core.Databook() + dbook.wipe() for sheet in json.loads(in_stream): data = tablib.core.Dataset() data.title = sheet['title'] data.dict = sheet['data'] - book.add_sheet(data) - - return book \ No newline at end of file + dbook.add_sheet(data) diff --git a/tablib/formats/_yaml.py b/tablib/formats/_yaml.py index 74d9155..665e06d 100644 --- a/tablib/formats/_yaml.py +++ b/tablib/formats/_yaml.py @@ -25,14 +25,13 @@ def import_set(dset, in_stream): dset.dict = yaml.load(in_stream) -def import_book(in_stream): +def import_book(dbook, in_stream): """Returns databook from YAML stream.""" - book = tablib.core.Databook() + dbook.wipe() + for sheet in yaml.load(in_stream): data = tablib.core.Dataset() data.title = sheet['title'] data.dict = sheet['data'] - book.add_sheet(data) - - return book \ No newline at end of file + dbook.add_sheet(data) \ No newline at end of file From b5f0cf9d374bceb57d5a5900a77ca0fa1930563a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 15:56:43 -0400 Subject: [PATCH 20/20] Tests elegant book imports. --- test_tablib.py | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/test_tablib.py b/test_tablib.py index cb8549c..67b693d 100755 --- a/test_tablib.py +++ b/test_tablib.py @@ -13,8 +13,10 @@ class TablibTestCase(unittest.TestCase): def setUp(self): """Create simple data set with headers.""" - global data + + global data, book data = tablib.Dataset() + book = tablib.Databook() self.headers = ('first_name', 'last_name', 'gpa') self.john = ('John', 'Adams', 90) @@ -194,7 +196,7 @@ class TablibTestCase(unittest.TestCase): def test_json_import_set(self): - """Generate and import JSON serialization.""" + """Generate and import JSON set serialization.""" data.append(self.john) data.append(self.george) data.headers = self.headers @@ -204,10 +206,24 @@ class TablibTestCase(unittest.TestCase): data.json = _json self.assertEqual(_json, data.json) - + + + def test_json_import_book(self): + """Generate and import JSON book serialization.""" + data.append(self.john) + data.append(self.george) + data.headers = self.headers + + book.add_sheet(data) + _json = book.json + + book.json = _json + + self.assertEqual(_json, book.json) + def test_yaml_import_set(self): - """Generate and import YAML serialization.""" + """Generate and import YAML set serialization.""" data.append(self.john) data.append(self.george) data.headers = self.headers @@ -217,10 +233,24 @@ class TablibTestCase(unittest.TestCase): data.yaml = _yaml self.assertEqual(_yaml, data.yaml) + + + def test_yaml_import_book(self): + """Generate and import YAML book serialization.""" + data.append(self.john) + data.append(self.george) + data.headers = self.headers + + book.add_sheet(data) + _yaml = book.yaml + + book.yaml = _yaml + + self.assertEqual(_yaml, book.yaml) def test_csv_import_set(self): - """Generate and import CSV serialization.""" + """Generate and import CSV set serialization.""" data.append(self.john) data.append(self.george) data.headers = self.headers