• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OpenDataServices / flatten-tool / 6507626273

13 Oct 2023 11:25AM UTC coverage: 42.006% (-53.7%) from 95.72%
6507626273

Pull #433

github

odscjames
New "Geo" optional dependencies

https://github.com/OpenDataServices/flatten-tool/issues/424
Pull Request #433: New "Geo" optional dependencies

38 of 38 new or added lines in 6 files covered. (100.0%)

1466 of 3490 relevant lines covered (42.01%)

4.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

21.43
/flattentool/ODSReader.py
1
# Copyright 2011 Marco Conti
2

3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6

7
#     http://www.apache.org/licenses/LICENSE-2.0
8

9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

15
# Thanks to grt for the fixes
16
# https://github.com/marcoconti83/read-ods-with-odfpy
17

18
from collections import OrderedDict
10✔
19
from datetime import datetime
10✔
20

21
import odf.opendocument
10✔
22
from odf.table import Table, TableCell, TableRow
10✔
23

24
# Backport for datetime.fromisoformat, which is new in Python 3.7
25
try:
10✔
26
    _ = datetime.fromisoformat
10✔
27
except AttributeError:
×
28
    import backports.datetime_fromisoformat
×
29

30
    backports.datetime_fromisoformat.MonkeyPatch.patch_fromisoformat()
×
31

32

33
# http://stackoverflow.com/a/4544699/1846474
34
class GrowingList(list):
10✔
35
    def __setitem__(self, index, value):
10✔
36
        if index >= len(self):
×
37
            self.extend([None] * (index + 1 - len(self)))
×
38
        list.__setitem__(self, index, value)
×
39

40

41
class ODSReader:
10✔
42

43
    # loads the file
44
    def __init__(self, file, clonespannedcolumns=None):
10✔
45
        self.clonespannedcolumns = clonespannedcolumns
×
46
        self.doc = odf.opendocument.load(file)
×
47
        self.SHEETS = OrderedDict()
×
48
        for sheet in self.doc.spreadsheet.getElementsByType(Table):
×
49
            self.readSheet(sheet)
×
50

51
    # reads a sheet in the sheet dictionary, storing each sheet as an
52
    # array (rows) of arrays (columns)
53
    def readSheet(self, sheet):
10✔
54
        name = sheet.getAttribute("name")
×
55
        rows = sheet.getElementsByType(TableRow)
×
56
        arrRows = []
×
57

58
        # for each row
59
        for row in rows:
×
60
            row_comment = ""  # noqa
×
61
            arrCells = GrowingList()
×
62
            cells = row.getElementsByType(TableCell)
×
63

64
            # for each cell
65
            count = 0
×
66
            for cell in cells:
×
67
                # repeated value?
68
                repeat = cell.getAttribute("numbercolumnsrepeated")
×
69
                if not repeat:
×
70
                    repeat = 1
×
71
                    spanned = int(cell.getAttribute("numbercolumnsspanned") or 0)
×
72
                    # clone spanned cells
73
                    if self.clonespannedcolumns is not None and spanned > 1:
×
74
                        repeat = spanned
×
75

76
                for rr in range(int(repeat)):  # repeated?
×
77
                    if str(cell):
×
78
                        value_type = cell.attributes.get(
×
79
                            (
80
                                "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
81
                                "value-type",
82
                            )
83
                        )
84
                        if value_type == "float":
×
85
                            value = cell.attributes.get(
×
86
                                (
87
                                    "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
88
                                    "value",
89
                                )
90
                            )
91
                            if "." in str(value):
×
92
                                arrCells[count] = float(value)
×
93
                            else:
94
                                arrCells[count] = int(value)
×
95
                        elif value_type == "date":
×
96
                            date_value = cell.attributes.get(
×
97
                                (
98
                                    "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
99
                                    "date-value",
100
                                )
101
                            )
102
                            # fromisoformat assumes microseconds appear as 3 or
103
                            # 6 digits, whereas ods drops trailing 0s, so can
104
                            # have 1-6 digits, so pad some extra 0s
105
                            if "." in date_value:
×
106
                                date_value = date_value.ljust(26, "0")
×
107
                            arrCells[count] = datetime.fromisoformat(date_value)
×
108
                        else:
109
                            arrCells[count] = str(cell)
×
110
                    count += 1
×
111

112
            arrRows.append(arrCells)
×
113

114
        self.SHEETS[name] = arrRows
×
115

116
    # returns a sheet as an array (rows) of arrays (columns)
117
    def getSheet(self, name):
10✔
118
        return self.SHEETS[name]
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc