Skip to content

Commit 4771a4b

Browse files
authored
New style io (#18)
* ☔ reproduce #12 * release 0.5.0 🥚 🎡 * 🤝 take latest code from setupmobans and release 0.5.1 🥚 🎡, which carries LICENSE file, pyexcel/pyexcel#103 * 🥚 🎡 release 0.5.2. related to pyexcel/pyexcel#105 * ✨ refuse to write value that will not persist. pyexcel/pyexcel-ods#30 * 🔨 sort import list, code format using black, supreme pep 8 formatter. and update moban to use latest moban 0.3.4 * ✨ use pyexcel-io 0.5.10 * 🔥 replace python 2.6 3.3 with python 3.7-dev * 🥚 🎡 release 0.5.3 * 🔨 minor update * 🤝 apply common templates from pyexcel mobans. moremoban/moban#348 * 👕 update coding style * 📰 add missing files * 📚 pass moban stage * 🔥 no longer to generate test files * ✨ respect moban * 👕 update format.sh * 🤝 synchronize the organisational meta data * 🚀 github actions for moban, pypi release and automatically extract contributors * This is an auto-commit, updating project meta data, such as changelog.rst, contributors.rst * 🤝 update project meta * 🤝 update project meta data * 🎉 new style ods reader * 🎉 new style ods writer * 📚 update changelog * This is an auto-commit, updating project meta data, such as changelog.rst, contributors.rst * 💄 update coding style * 💚 use pyexcel-io v0.6.0 in test Co-authored-by: chfw <[email protected]>
1 parent 0384838 commit 4771a4b

File tree

10 files changed

+86
-100
lines changed

10 files changed

+86
-100
lines changed

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Change log
22
================================================================================
33

4+
0.6.0 - 2020
5+
--------------------------------------------------------------------------------
6+
7+
**added**
8+
9+
#. new style reader and writer plugins. works with pyexcel-io v0.6.0
10+
411
0.5.3 - 27.11.2018
512
--------------------------------------------------------------------------------
613

changelog.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
name: pyexcel-ods3
22
organisation: pyexcel
33
releases:
4+
- changes:
5+
- action: added
6+
details:
7+
- 'new style reader and writer plugins. works with pyexcel-io v0.6.0'
8+
date: 2020
9+
version: 0.6.0
410
- changes:
511
- action: added
612
details:

pyexcel_ods3/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,22 @@
1515

1616
# this line has to be place above all else
1717
# because of dynamic import
18-
from pyexcel_io.plugins import IOPluginInfoChain
18+
from pyexcel_io.plugins import IOPluginInfoChain, IOPluginInfoChainV2
1919

2020
__FILE_TYPE__ = "ods"
21-
IOPluginInfoChain(__name__).add_a_reader(
21+
IOPluginInfoChainV2(__name__).add_a_reader(
2222
relative_plugin_class_path="odsr.ODSBook",
23+
locations=["file", "memory"],
24+
file_types=[__FILE_TYPE__],
25+
stream_type="binary",
26+
).add_a_reader(
27+
relative_plugin_class_path="odsr.ODSBookInContent",
28+
locations=["content"],
2329
file_types=[__FILE_TYPE__],
2430
stream_type="binary",
2531
).add_a_writer(
2632
relative_plugin_class_path="odsw.ODSWriter",
33+
locations=["file", "memory"],
2734
file_types=[__FILE_TYPE__],
2835
stream_type="binary",
2936
)

pyexcel_ods3/odsr.py

Lines changed: 37 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,41 @@
44
55
ods reader
66
7-
:copyright: (c) 2015-2017 by Onni Software Ltd. & its contributors
7+
:copyright: (c) 2015-2020 by Onni Software Ltd. & its contributors
88
:license: New BSD License
99
"""
10-
import ezodf
10+
from io import BytesIO
1111

12+
import ezodf
1213
import pyexcel_io.service as service
13-
from pyexcel_io.book import BookReader
14-
from pyexcel_io.sheet import SheetReader
15-
from pyexcel_io._compact import OrderedDict
14+
from pyexcel_io.plugin_api.abstract_sheet import ISheet
15+
from pyexcel_io.plugin_api.abstract_reader import IReader
1616

1717

18-
class ODSSheet(SheetReader):
18+
class ODSSheet(ISheet):
1919
"""ODS sheet representation"""
2020

2121
def __init__(self, sheet, auto_detect_int=True, **keywords):
22-
SheetReader.__init__(self, sheet, **keywords)
2322
self.auto_detect_int = auto_detect_int
23+
self._native_sheet = sheet
24+
self._keywords = keywords
2425

2526
@property
2627
def name(self):
2728
return self._native_sheet.name
2829

29-
def number_of_rows(self):
30+
def row_iterator(self):
3031
"""
3132
Number of rows in the xls sheet
3233
"""
33-
return self._native_sheet.nrows()
34+
return range(self._native_sheet.nrows())
3435

35-
def number_of_columns(self):
36+
def column_iterator(self, row):
3637
"""
3738
Number of columns in the xls sheet
3839
"""
39-
return self._native_sheet.ncols()
40+
for column in range(self._native_sheet.ncols()):
41+
yield self.cell_value(row, column)
4042

4143
def cell_value(self, row, column):
4244
cell = self._native_sheet.get_cell((row, column))
@@ -63,63 +65,34 @@ def cell_value(self, row, column):
6365
return ret
6466

6567

66-
class ODSBook(BookReader):
67-
"""read a ods book out"""
68-
69-
def open(self, file_name, **keywords):
70-
"""load ods from file"""
71-
BookReader.open(self, file_name, **keywords)
72-
self._load_from_file()
73-
74-
def open_stream(self, file_stream, **keywords):
75-
"""load ods from file stream"""
76-
BookReader.open_stream(self, file_stream, **keywords)
77-
self._load_from_memory()
78-
79-
def read_sheet_by_name(self, sheet_name):
80-
"""read a named sheet"""
81-
rets = [
82-
sheet
83-
for sheet in self._native_book.sheets
84-
if sheet.name == sheet_name
68+
class ODSBook(IReader):
69+
def __init__(self, file_alike_object, file_type, **keywords):
70+
self._native_book = ezodf.opendoc(file_alike_object)
71+
self._keywords = keywords
72+
self.content_array = [
73+
NameObject(sheet.name, sheet) for sheet in self._native_book.sheets
8574
]
86-
if len(rets) == 0:
87-
raise ValueError("%s cannot be found" % sheet_name)
88-
elif len(rets) == 1:
89-
return self.read_sheet(rets[0])
90-
else:
91-
raise ValueError(
92-
"More than 1 sheet named as %s are found" % sheet_name
93-
)
94-
95-
def read_sheet_by_index(self, sheet_index):
96-
"""read a sheet at an index"""
97-
sheets = self._native_book.sheets
98-
length = len(sheets)
99-
if sheet_index < length:
100-
return self.read_sheet(sheets[sheet_index])
101-
else:
102-
raise IndexError(
103-
"Index %d of out bound %d." % (sheet_index, length)
104-
)
105-
106-
def read_all(self):
107-
"""read all available sheets"""
108-
result = OrderedDict()
109-
for sheet in self._native_book.sheets:
110-
data_dict = self.read_sheet(sheet)
111-
result.update(data_dict)
112-
return result
113-
114-
def read_sheet(self, native_sheet):
75+
76+
def read_sheet(self, native_sheet_index):
77+
native_sheet = self.content_array[native_sheet_index].sheet
11578
sheet = ODSSheet(native_sheet, **self._keywords)
116-
return {native_sheet.name: sheet.to_array()}
79+
return sheet
11780

11881
def close(self):
11982
self._native_book = None
12083

121-
def _load_from_file(self):
122-
self._native_book = ezodf.opendoc(self._file_name)
12384

124-
def _load_from_memory(self):
125-
self._native_book = ezodf.opendoc(self._file_stream)
85+
class ODSBookInContent(ODSBook):
86+
"""
87+
Open xlsx as read only mode
88+
"""
89+
90+
def __init__(self, file_content, file_type, **keywords):
91+
io = BytesIO(file_content)
92+
super().__init__(io, file_type, **keywords)
93+
94+
95+
class NameObject(object):
96+
def __init__(self, name, sheet):
97+
self.name = name
98+
self.sheet = sheet

pyexcel_ods3/odsw.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,24 @@
1010
import types
1111

1212
import ezodf
13-
1413
import pyexcel_io.service as service
15-
from pyexcel_io.book import BookWriter
16-
from pyexcel_io.sheet import SheetWriter
1714
from pyexcel_io.constants import MAX_INTEGER
1815
from pyexcel_io.exceptions import IntegerAccuracyLossError
16+
from pyexcel_io.plugin_api.abstract_sheet import ISheetWriter
17+
from pyexcel_io.plugin_api.abstract_writer import IWriter
1918

2019

21-
class ODSSheetWriter(SheetWriter):
20+
class ODSSheetWriter(ISheetWriter):
2221
"""
2322
ODS sheet writer
2423
"""
2524

26-
def set_sheet_name(self, name):
27-
self._native_sheet = ezodf.Sheet(name)
25+
def __init__(self, ods_book, ods_sheet, sheet_name, **keywords):
26+
self._native_book = ods_book
27+
self._native_sheet = ezodf.Sheet(sheet_name)
2828
self.current_row = 0
2929

30-
def set_size(self, size):
30+
def _set_size(self, size):
3131
self._native_sheet.reset(size=size)
3232

3333
def write_row(self, array):
@@ -62,7 +62,7 @@ def write_array(self, table):
6262
if rows < 1:
6363
return
6464
columns = max([len(row) for row in to_write_data])
65-
self.set_size((rows, columns))
65+
self._set_size((rows, columns))
6666
for row in to_write_data:
6767
self.write_row(row)
6868

@@ -74,25 +74,21 @@ def close(self):
7474
self._native_book.sheets += self._native_sheet
7575

7676

77-
class ODSWriter(BookWriter):
77+
class ODSWriter(IWriter):
7878
"""
7979
open document spreadsheet writer
8080
8181
"""
8282

83-
def __init__(self):
84-
BookWriter.__init__(self)
85-
self._native_book = None
86-
87-
def open(self, file_name, **keywords):
83+
def __init__(
84+
self, file_alike_object, file_type, skip_backup=True, **keywords
85+
):
8886
"""open a file for writing ods"""
89-
BookWriter.open(self, file_name, **keywords)
9087
self._native_book = ezodf.newdoc(
91-
doctype="ods", filename=self._file_alike_object
88+
doctype=file_type, filename=file_alike_object
9289
)
9390

94-
skip_backup_flag = self._keywords.get("skip_backup", True)
95-
if skip_backup_flag:
91+
if skip_backup:
9692
self._native_book.backup = False
9793

9894
def create_sheet(self, name):

rnd_requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
https://github.com/pyexcel/pyexcel-ezodf/archive/master.zip
2-
https://github.com/pyexcel/pyexcel-io/archive/v0.5.10.zip
1+
https://github.com/pyexcel/pyexcel-io/archive/dev.zip

tests/test_bug_fixes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
import psutil
66
import pyexcel as pe
7+
from pyexcel_io.exceptions import IntegerAccuracyLossError
78

89
from nose import SkipTest
910
from nose.tools import eq_, raises
10-
from pyexcel_io.exceptions import IntegerAccuracyLossError
1111

1212
IN_TRAVIS = "TRAVIS" in os.environ
1313

tests/test_filter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import os
22

3-
from nose.tools import eq_
43
from pyexcel_io import get_data, save_data
54

5+
from nose.tools import eq_
6+
67

78
class TestFilter:
89
def setUp(self):

tests/test_ods_reader.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77

88
class TestODSReader(ODSCellTypes):
99
def setUp(self):
10-
r = ODSBook()
11-
r.open(os.path.join("tests", "fixtures", "ods_formats.ods"))
10+
r = ODSBook(
11+
os.path.join("tests", "fixtures", "ods_formats.ods"), "ods"
12+
)
1213
self.data = r.read_all()
1314
for key in self.data.keys():
1415
self.data[key] = list(self.data[key])
@@ -17,19 +18,17 @@ def setUp(self):
1718

1819
class TestODSWriter(ODSCellTypes):
1920
def setUp(self):
20-
r = ODSBook()
21-
r.open(
21+
r = ODSBook(
2222
os.path.join("tests", "fixtures", "ods_formats.ods"),
23+
"ods",
2324
skip_empty_rows=True,
2425
)
2526
self.data1 = r.read_all()
2627
self.testfile = "odswriter.ods"
27-
w = ODSWriter()
28-
w.open(self.testfile)
28+
w = ODSWriter(self.testfile, "ods")
2929
w.write(self.data1)
3030
w.close()
31-
r2 = ODSBook()
32-
r2.open(self.testfile)
31+
r2 = ODSBook(self.testfile, "ods")
3332
self.data = r2.read_all()
3433
for key in self.data.keys():
3534
self.data[key] = list(self.data[key])

tests/test_writer.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@ def test_write_book(self):
1313
"Sheet3": [[u"X", u"Y", u"Z"], [1, 4, 7], [2, 5, 8], [3, 6, 9]],
1414
}
1515
self.testfile = "writer.ods"
16-
writer = Writer()
17-
writer.open(self.testfile)
16+
writer = Writer(self.testfile, "ods")
1817
writer.write(self.content)
1918
writer.close()
20-
reader = Reader()
21-
reader.open(self.testfile)
19+
reader = Reader(self.testfile, "ods")
2220
content = reader.read_all()
2321
for key in content.keys():
2422
content[key] = list(content[key])

0 commit comments

Comments
 (0)