From 17e90e71e5406fc8621c254e58ae6cf169e38c34 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 02:54:43 -0400 Subject: [PATCH 01/46] test --- test.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test.py diff --git a/test.py b/test.py new file mode 100644 index 0000000..0f021e4 --- /dev/null +++ b/test.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +import tablib + +data = tablib.Dataset() + +data.headers = ['a', 'b', 'c'] +data.append([1,2,3]) +data.append([1,2,3]) + +print data.dict + +new_data = tablib.formats.json.import_set(str(data.json)) +#print new_data.yaml + + + +# data.headers = ['one', 'two', 'three'] +# print data.dict \ No newline at end of file From fbe6fe161254a780ca47d0424f46069d0c34c352 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 02:55:21 -0400 Subject: [PATCH 02/46] fix old push --- test.py | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 test.py diff --git a/test.py b/test.py deleted file mode 100644 index 0f021e4..0000000 --- a/test.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -import tablib - -data = tablib.Dataset() - -data.headers = ['a', 'b', 'c'] -data.append([1,2,3]) -data.append([1,2,3]) - -print data.dict - -new_data = tablib.formats.json.import_set(str(data.json)) -#print new_data.yaml - - - -# data.headers = ['one', 'two', 'three'] -# print data.dict \ No newline at end of file From b8f923f8c5713da12ffbf42bd3794f3cef2674bc Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:03:01 -0400 Subject: [PATCH 03/46] added Luke Lee to Authors --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 722a130..3d48743 100644 --- a/AUTHORS +++ b/AUTHORS @@ -10,4 +10,4 @@ Development Lead Patches and Suggestions ``````````````````````` -- A Lucky Someone \ No newline at end of file +- Luke Lee \ No newline at end of file From fbabb430ca7159cf0570193704367234e4c2b90b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:04:36 -0400 Subject: [PATCH 04/46] small setup.py fix --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 8816512..dc8142b 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,6 @@ def publish(): """Publish to PyPi""" os.system("python setup.py sdist upload") - if sys.argv[-1] == "publish": publish() sys.exit() From 579dbf0cc0686d568cb1386ccbbd81837c90e49b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:43:39 -0400 Subject: [PATCH 05/46] Added docstring. Removed unneeded import. --- tablib/core.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 0167c34..fae4547 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -1,21 +1,17 @@ # -*- coding: utf-8 -*- -# _____ ______ ______ _________ -# __ /_______ ____ /_ ___ /_ _____ ______ / -# _ __/_ __ `/__ __ \__ __ \_ _ \_ __ / -# / /_ / /_/ / _ /_/ /_ /_/ // __// /_/ / -# \__/ \__,_/ /_.___/ /_.___/ \___/ \__,_/ +""" Tablib - Core Library +""" import csv import cStringIO -import random import simplejson as json import xlwt import yaml -from helpers import * +from helpers import Struct # __all__ = ['Dataset', 'DataBook'] From 0e6bd079cc05cc3d7312a2c6e002d1d536ab7da1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:43:45 -0400 Subject: [PATCH 06/46] Improved docstring. --- tablib/helpers.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tablib/helpers.py b/tablib/helpers.py index 0a91e56..a3b94b3 100644 --- a/tablib/helpers.py +++ b/tablib/helpers.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- +""" Tablib - General Helpers. +""" + import sys From 703b1da04cf3b3c883b26ad9746b16e59da377d3 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:45:22 -0400 Subject: [PATCH 07/46] General cleanups for pylint. --- tablib/core.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index fae4547..1022e07 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -11,12 +11,8 @@ import simplejson as json import xlwt import yaml -from helpers import Struct - -# __all__ = ['Dataset', 'DataBook'] - -__name__ = 'tablib' +__title__ = 'tablib' __version__ = '0.7.1' __build__ = 0x000701 __author__ = 'Kenneth Reitz' @@ -36,12 +32,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 @@ -120,10 +116,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 @property From 8d6a52aaf5d228fa48d55f0133ea52e93537683e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:49:31 -0400 Subject: [PATCH 08/46] Cleanups for pylint. --- tablib/core.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 1022e07..f0eb43d 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -129,13 +129,13 @@ class Dataset(object): @headers.setter - def headers(self, collection): + def headers_set(self, collection): """Validating headers setter.""" self._validate(collection) if collection: try: self.__headers = list(collection) - except TypeError, why: + except TypeError: raise TypeError else: self.__headers = None @@ -260,19 +260,19 @@ class Databook(object): """Returns XLS representation of DataBook.""" - wb = xlwt.Workbook(encoding='utf8') + workb = xlwt.Workbook(encoding='utf8') for i, dset in enumerate(self._datasets): - ws = wb.add_sheet(dset.title if dset.title else 'Sheet%s' % (i)) + 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): - ws.write(i, j, col) + works.write(i, j, col) stream = cStringIO.StringIO() - wb.save(stream) + workb.save(stream) return stream.getvalue() From c3fa29a166bc91c202eee6faa432283b14fc46f3 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:51:56 -0400 Subject: [PATCH 09/46] Added public method for pylint. --- tablib/helpers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tablib/helpers.py b/tablib/helpers.py index a3b94b3..31b4558 100644 --- a/tablib/helpers.py +++ b/tablib/helpers.py @@ -15,6 +15,10 @@ class Struct(object): def __getitem__(self, key): return getattr(self, key, None) + def dictionary(self): + """Returns dictionary representation of object.""" + return self.__dict__ + def piped(): """Returns piped input via stdin, else False.""" From c01b66a16a84bd171dde1d22be39fea595e87ed4 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:53:20 -0400 Subject: [PATCH 10/46] Moving that back. --- tablib/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tablib/core.py b/tablib/core.py index f0eb43d..b8c147c 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -129,7 +129,7 @@ class Dataset(object): @headers.setter - def headers_set(self, collection): + def headers(self, collection): """Validating headers setter.""" self._validate(collection) if collection: From 93fb89b8b6915a277c66df458e9dd7b47a5a4be8 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 04:58:24 -0400 Subject: [PATCH 11/46] Cleanup * imports. --- tablib/__init__.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tablib/__init__.py b/tablib/__init__.py index 5d20240..cf38bc5 100644 --- a/tablib/__init__.py +++ b/tablib/__init__.py @@ -1 +1,7 @@ -from core import * \ No newline at end of file +from tablib.core import ( + Databook, Dataset, InvalidDatasetType, + InvalidDimensions, UnsupportedFormat +) + +""" Tablib. +""" \ No newline at end of file From e52b8dd329903f96206a28dc0c0b1ab6ef455166 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:01:05 -0400 Subject: [PATCH 12/46] Added methods to struct for pylint. --- tablib/helpers.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tablib/helpers.py b/tablib/helpers.py index 31b4558..f75c466 100644 --- a/tablib/helpers.py +++ b/tablib/helpers.py @@ -19,6 +19,15 @@ class Struct(object): """Returns dictionary representation of object.""" return self.__dict__ + def items(self): + """Returns items within object.""" + return self.__dict__.items() + + def keys(self): + """Returns keys within object.""" + return self.__dict__.keys() + + def piped(): """Returns piped input via stdin, else False.""" From 4bb4a05bcbb044a9eaaac2e1e7eb11b41d3d9739 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:02:58 -0400 Subject: [PATCH 13/46] Longer varnames for pylint. --- tablib/core.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index b8c147c..bd07f10 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -172,15 +172,15 @@ class Dataset(object): def xls(self): """Returns XLS representation of Dataset.""" - wb = xlwt.Workbook(encoding='utf8') - ws = wb.add_sheet(self.title if self.title else 'Tabbed 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): - ws.write(i, j, col) + works.write(i, j, col) stream = cStringIO.StringIO() - wb.save(stream) + workb.save(stream) return stream.getvalue() From 121cf46aec71486645031e73343c7f24f4c603ad Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:04:51 -0400 Subject: [PATCH 14/46] Corrected always-false condition. --- tablib/core.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index bd07f10..551a326 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -226,10 +226,7 @@ class Databook(object): def __repr__(self): - try: - return '<%s databook>' % (self.title.lower()) - except AttributeError: - return '' + return '' def add_sheet(self, dataset): From 82f3d84c7dfff4e31e36a645c3ff7d07a564df8f Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:06:04 -0400 Subject: [PATCH 15/46] Added docstring. --- tablib/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tablib/__init__.py b/tablib/__init__.py index cf38bc5..fadd8dd 100644 --- a/tablib/__init__.py +++ b/tablib/__init__.py @@ -1,7 +1,8 @@ +""" Tablib. +""" + from tablib.core import ( Databook, Dataset, InvalidDatasetType, InvalidDimensions, UnsupportedFormat ) -""" Tablib. -""" \ No newline at end of file From f9c168e4bc9194228982f631e31331264a180119 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:08:35 -0400 Subject: [PATCH 16/46] Added coverage bin. --- .coverage | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .coverage diff --git a/.coverage b/.coverage new file mode 100644 index 0000000..1bfb85e --- /dev/null +++ b/.coverage @@ -0,0 +1,4 @@ +}q(U collectorqU coverage v3.4qUlinesq}q(U1/Users/kreitz/repos/private/tablib/test_tablib.pyq]q(KKKK K KKKKKKKKKKKK K#K%K&K)K*K-K1K2K4K7K:K;K=K?KAKBKEKFKGKIKLKOKQKSKTKUKXK[K]K^K`KaKcKeKhKkKlKmKnKoKpKsKwKxKyKzK{K~KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeU5/Users/kreitz/repos/private/tablib/tablib/__init__.pyq]q KaU1/Users/kreitz/repos/private/tablib/tablib/core.pyq +]q (K +K K KKKKKKKKKKKK K"K#K$K%K&K'K)K*K+K,K.K/K0K1K4K8K9K:K;K Date: Tue, 21 Sep 2010 02:42:08 -0400 Subject: [PATCH 17/46] 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 ac1666e3aea58c410b74a85ede2f2549212f571e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:14:07 -0400 Subject: [PATCH 18/46] removing garbage --- .coverage | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .coverage diff --git a/.coverage b/.coverage deleted file mode 100644 index 1bfb85e..0000000 --- a/.coverage +++ /dev/null @@ -1,4 +0,0 @@ -}q(U collectorqU coverage v3.4qUlinesq}q(U1/Users/kreitz/repos/private/tablib/test_tablib.pyq]q(KKKK K KKKKKKKKKKKK K#K%K&K)K*K-K1K2K4K7K:K;K=K?KAKBKEKFKGKIKLKOKQKSKTKUKXK[K]K^K`KaKcKeKhKkKlKmKnKoKpKsKwKxKyKzK{K~KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKeU5/Users/kreitz/repos/private/tablib/tablib/__init__.pyq]q KaU1/Users/kreitz/repos/private/tablib/tablib/core.pyq -]q (K -K K KKKKKKKKKKKK K"K#K$K%K&K'K)K*K+K,K.K/K0K1K4K8K9K:K;K Date: Sat, 25 Sep 2010 05:17:03 -0400 Subject: [PATCH 19/46] Pylint preps. --- tablib/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tablib/core.py b/tablib/core.py index 551a326..4342ebe 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -238,6 +238,7 @@ class Databook(object): def _package(self): + """Packages Databook for delivery.""" collector = [] for dset in self._datasets: collector.append(dict( From 5a993ac281f5dbfd0cee2039c61af0701e5fa323 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 05:49:14 -0400 Subject: [PATCH 20/46] 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 21/46] 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 22/46] 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 23/46] 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 24/46] 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 25/46] 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 26/46] 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 27/46] 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 28/46] 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 29/46] 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 30/46] 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 31/46] 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 32/46] 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 33/46] 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 34/46] 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 35/46] 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 36/46] 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 37/46] 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 38/46] 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 From 07ac723971152198a1a4367d5e15a58aa9977204 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 16:46:52 -0400 Subject: [PATCH 39/46] Readme update for imports. --- README.rst | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 387a807..9eca8d0 100644 --- a/README.rst +++ b/README.rst @@ -15,12 +15,17 @@ Tablib is a format-agnostic tabular dataset library, written in Python. Output formats supported: -- Excel -- JSON -- YAML -- CSV +- Excel (Sets + Books) +- JSON (Sets + Books) +- YAML (Sets + Books) +- CSV (Sets) + +Import formats supported: + +- JSON (Sets + Books) +- YAML (Sets + Books) +- CSV (Sets) -At this time, Tablib supports the **export** of it's powerful Dataset object instances into any of the above formats. Import is underway. Note that tablib *purposefully* excludes XML support. It always will. From d5515c17b80a4f8cf030b014eff331e1a2fb0538 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 16:47:04 -0400 Subject: [PATCH 40/46] Removed useless imports. --- tablib/core.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 849e4bc..fb9861a 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -3,13 +3,6 @@ """ Tablib - core. """ -import csv -import cStringIO - -import simplejson as json -import xlwt -import yaml - from tablib.formats import formats From 7505d8d985459f4050a9cd720f0a9b8fb516e639 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 16:49:21 -0400 Subject: [PATCH 41/46] Adding docstrings for pylint coverage. --- tablib/core.py | 2 +- tablib/formats/_csv.py | 3 +++ tablib/formats/_json.py | 3 +++ tablib/formats/_xls.py | 3 +++ tablib/formats/_yaml.py | 5 +++++ 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tablib/core.py b/tablib/core.py index fb9861a..168d664 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -""" Tablib - core. +""" Tablib - Core Library. """ from tablib.formats import formats diff --git a/tablib/formats/_csv.py b/tablib/formats/_csv.py index 6dba44b..8b19da7 100644 --- a/tablib/formats/_csv.py +++ b/tablib/formats/_csv.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- +""" Tablib - CSV Support. +""" + import cStringIO import csv import os diff --git a/tablib/formats/_json.py b/tablib/formats/_json.py index c2dd524..1f92b58 100644 --- a/tablib/formats/_json.py +++ b/tablib/formats/_json.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- +""" Tablib - JSON Support +""" + import simplejson as json import tablib.core diff --git a/tablib/formats/_xls.py b/tablib/formats/_xls.py index 979fa62..1a739af 100644 --- a/tablib/formats/_xls.py +++ b/tablib/formats/_xls.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- +""" Tablib - XLS Support. +""" + import xlwt import cStringIO diff --git a/tablib/formats/_yaml.py b/tablib/formats/_yaml.py index 665e06d..4cac8aa 100644 --- a/tablib/formats/_yaml.py +++ b/tablib/formats/_yaml.py @@ -1,8 +1,13 @@ # -*- coding: utf-8 -*- +""" Tablib - YAML Support. +""" + import yaml import tablib + + title = 'yaml' extentions = ('yaml', 'yml') From 66867527d2d3da934b62efb65f1c587b037566f6 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 16:51:09 -0400 Subject: [PATCH 42/46] Format import cleanups. --- tablib/core.py | 2 +- tablib/formats/__init__.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tablib/core.py b/tablib/core.py index 168d664..b557e3e 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -3,7 +3,7 @@ """ Tablib - Core Library. """ -from tablib.formats import formats +from tablib.formats import FORMATS as formats __title__ = 'tablib' diff --git a/tablib/formats/__init__.py b/tablib/formats/__init__.py index b9c7451..e8c9007 100644 --- a/tablib/formats/__init__.py +++ b/tablib/formats/__init__.py @@ -3,9 +3,9 @@ """ Tablib - formats """ -import _csv as csv -import _json as json -import _xls as xls -import _yaml as yaml +import tablib.formats._csv as csv +import tablib.formats._json as json +import tablib.formats._xls as xls +import tablib.formats._yaml as yaml -formats = (csv, json, xls, yaml) +FORMATS = (csv, json, xls, yaml) From 86d84b555dbc531f8c941e8481803d48b0d55448 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 16:53:33 -0400 Subject: [PATCH 43/46] Import cleanup. --- tablib/formats/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tablib/formats/__init__.py b/tablib/formats/__init__.py index e8c9007..b22a959 100644 --- a/tablib/formats/__init__.py +++ b/tablib/formats/__init__.py @@ -3,9 +3,9 @@ """ Tablib - formats """ -import tablib.formats._csv as csv -import tablib.formats._json as json -import tablib.formats._xls as xls -import tablib.formats._yaml as yaml +import _csv as csv +import _json as json +import _xls as xls +import _yaml as yaml FORMATS = (csv, json, xls, yaml) From 969d9d957d73e942220200a2786f761f2791d51d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 16:59:27 -0400 Subject: [PATCH 44/46] Version Bump (to v0.8.0) --- setup.py | 2 +- tablib/core.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index dc8142b..0c95cb4 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ if sys.argv[-1] == "publish": setup( name='tablib', - version='0.7.1', + version='0.8.0', description='Format agnostic tabular data library (XLS, JSON, YAML, CSV)', long_description=open('README.rst').read() + '\n\n' + open('HISTORY.rst').read(), diff --git a/tablib/core.py b/tablib/core.py index b557e3e..cdaf0d5 100644 --- a/tablib/core.py +++ b/tablib/core.py @@ -7,8 +7,8 @@ from tablib.formats import FORMATS as formats __title__ = 'tablib' -__version__ = '0.7.1' -__build__ = 0x000701 +__version__ = '0.8.0' +__build__ = 0x000800 __author__ = 'Kenneth Reitz' __license__ = 'MIT' __copyright__ = 'Copyright 2010 Kenneth Reitz' From f8899106297606d391fcdfa1a75c276bc7ed272d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 17:12:50 -0400 Subject: [PATCH 45/46] Big documentation update. --- README.rst | 50 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 9eca8d0..df59abb 100644 --- a/README.rst +++ b/README.rst @@ -26,9 +26,16 @@ Import formats supported: - YAML (Sets + Books) - CSV (Sets) - Note that tablib *purposefully* excludes XML support. It always will. +Overview +-------- + +`tablib.Dataset()` + A Dataset is a table of tabular data. It may or may not have a header row. They can be build and maniuplated as raw Python datatypes (Lists of tuples|dictonaries). Datasets can be imported from JSON, YAML, and CSV; they can be exported to Excel (XLS), JSON, YAML, and CSV. + +`tablib.Databook()` + A Databook is a set of Datasets. The most common form of a Databook is an Excel file with multiple spreadsheets. Databooks can be imported from JSON and YAML; they can be exported to Excel (XLS), JSON, and YAML. Usage ----- @@ -69,6 +76,9 @@ Easily delete rows: :: >>> del data[1] +Exports +------- + Drumroll please........... JSON! @@ -114,8 +124,41 @@ EXCEL! >>> open('people.xls', 'wb').write(data.xls) It's that easy. + +Imports! +-------- + +JSON +++++ + +:: + + >>> data.json = '[{"last_name": "Adams","age": 90,"first_name": "John"}]' + >>> print data[0] + ('John', 'Adams', 90) + + +YAML +++++ +:: + + >>> data.yaml = '- {age: 90, first_name: John, last_name: Adams}' + >>> print data[0] + ('John', 'Adams', 90) + +CSV ++++ +:: + + >>> data.yaml = 'age, first_name, last_name\n90, John, Adams' + >>> print data[0] + ('John', 'Adams', 90) - + >>> print data.yaml + - {age: 90, first_name: John, last_name: Adams} + + + Installation ------------ @@ -136,13 +179,10 @@ If you'd like to contribute, simply fork `the repository`_, commit your changes Roadmap ------- -- Import datasets from CSV. - Release CLI Interface - Auto-detect import format - Add possible other exports (SQL?) -- Possibly plugin-ify format architecture - Ability to assign types to rows (set, regex=, &c.) -- Plugin support .. _`the repository`: http://github.com/kennethreitz/tablib .. _AUTHORS: http://github.com/kennethreitz/tablib/blob/master/AUTHORS From 8136f4b09eac5ed160fd49ec70f2c1338df6ec8d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 25 Sep 2010 17:18:48 -0400 Subject: [PATCH 46/46] Updated history for v0.8.0. --- HISTORY.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index d4b58d4..06d8257 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,13 @@ History ======= +0.8.0 (2010-09-25) +------------------ +* New format plugin system! +* Imports! ELEGANT Imports! +* Tests. Lots of tests. + + 0.7.1 (2010-09-20) ------------------