Changeset - 59b088b57362
[Not reviewed]
0 2 0
Brett Smith - 4 years ago 2020-07-29 20:58:57
brettcsmith@brettcsmith.org
reports: Add BaseODS.set_properties() method.
2 files changed with 63 insertions and 0 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/reports/core.py
Show inline comments
...
 
@@ -26,23 +26,26 @@ import urllib.parse as urlparse
 

	
 
import babel.core  # type:ignore[import]
 
import babel.numbers  # type:ignore[import]
 

	
 
import odf.config  # type:ignore[import]
 
import odf.element  # type:ignore[import]
 
import odf.meta  # type:ignore[import]
 
import odf.number  # type:ignore[import]
 
import odf.opendocument  # type:ignore[import]
 
import odf.style  # type:ignore[import]
 
import odf.table  # type:ignore[import]
 
import odf.text  # type:ignore[import]
 

	
 
from decimal import Decimal
 
from pathlib import Path
 

	
 
from beancount.core import amount as bc_amount
 
from odf.namespaces import TOOLSVERSION  # type:ignore[import]
 

	
 
from ..cliutil import VERSION
 
from .. import data
 
from .. import filters
 
from .. import rtutil
 

	
 
from typing import (
 
    cast,
...
 
@@ -558,12 +561,13 @@ class BaseODS(BaseSpreadsheet[RT, ST], metaclass=abc.ABCMeta):
 
        self.currency_fmt_key = 'accounting'
 
        self._name_counter = itertools.count(1)
 
        self._style_cache: MutableMapping[str, odf.style.Style] = {}
 
        self.document = odf.opendocument.OpenDocumentSpreadsheet()
 
        self.init_settings()
 
        self.init_styles()
 
        self.set_properties()
 
        self.sheet = self.use_sheet("Report")
 

	
 
    ### Low-level document tree manipulation
 
    # The *intent* is that you only need to use these if you're adding new
 
    # methods to manipulate document settings or styles.
 

	
...
 
@@ -1043,12 +1047,27 @@ class BaseODS(BaseSpreadsheet[RT, ST], metaclass=abc.ABCMeta):
 
                styles, odf.style.Style, name=f'{textalign.title()}Text',
 
            )
 
            aligned_style.setAttribute('family', 'table-cell')
 
            aligned_style.addElement(odf.style.ParagraphProperties(textalign=textalign))
 
            setattr(self, f'style_{textalign}text', aligned_style)
 

	
 
    ### Properties
 

	
 
    def set_properties(self, *,
 
                       created: Optional[datetime.datetime]=None,
 
                       generator: str='conservancy_beancount',
 
    ) -> None:
 
        if created is None:
 
            created = datetime.datetime.now()
 
        created_elem = self.ensure_child(self.document.meta, odf.meta.CreationDate)
 
        created_elem.childNodes.clear()
 
        created_elem.addText(created.isoformat())
 
        generator_elem = self.ensure_child(self.document.meta, odf.meta.Generator)
 
        generator_elem.childNodes.clear()
 
        generator_elem.addText(f'{generator}/{VERSION} {TOOLSVERSION}')
 

	
 
    ### Rows and cells
 

	
 
    def add_row(self, *cells: odf.table.TableCell, **attrs: Any) -> odf.table.TableRow:
 
        row = odf.table.TableRow(**attrs)
 
        for cell in cells:
 
            row.addElement(cell)
tests/test_reports_spreadsheet.py
Show inline comments
...
 
@@ -14,18 +14,20 @@
 
# You should have received a copy of the GNU Affero General Public License
 
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 

	
 
import datetime
 
import io
 
import itertools
 
import re
 

	
 
import pytest
 

	
 
import babel.core
 
import babel.numbers
 
import odf.config
 
import odf.meta
 
import odf.number
 
import odf.style
 
import odf.table
 
import odf.text
 

	
 
from decimal import Decimal
...
 
@@ -701,6 +703,48 @@ def test_ods_writer_copy_element(ods_writer):
 
    assert actual1 is not child1
 
    assert actual2 is not child2
 
    actual_a, = actual1.childNodes
 
    assert actual_a.getAttribute('href') == 'linkhref'
 
    assert actual_a.text == 'linktext'
 
    assert actual2.text == 'para2'
 

	
 
def test_ods_writer_default_properties(ods_writer):
 
    meta = ods_writer.document.meta
 
    yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
 
    creation_date_elem = get_child(meta, odf.meta.CreationDate)
 
    creation_date = datetime.datetime.strptime(
 
        creation_date_elem.text, '%Y-%m-%dT%H:%M:%S.%f',
 
    )
 
    assert creation_date > yesterday
 
    generator = get_child(meta, odf.meta.Generator)
 
    assert re.match(r'conservancy_beancount/\d+\.\d+', generator.text)
 

	
 
def test_ods_writer_set_properties(ods_writer):
 
    ctime = datetime.datetime(2009, 9, 19, 9, 49, 59)
 
    ods_writer.set_properties(created=ctime, generator='testgen')
 
    meta = ods_writer.document.meta
 
    creation_date_elem = get_child(meta, odf.meta.CreationDate)
 
    assert creation_date_elem.text == ctime.isoformat()
 
    generator = get_child(meta, odf.meta.Generator)
 
    assert re.match(r'testgen/\d+\.\d+', generator.text)
 

	
 
@pytest.mark.parametrize('value,exptype', [
 
    (1, 'float'),
 
    (12.34, 'float'),
 
    (Decimal('5.99'), 'float'),
 
    (datetime.date(2009, 8, 17), 'date'),
 
    (datetime.datetime(2009, 8, 17, 18, 38, 58), 'date'),
 
    (True, 'boolean'),
 
    (False, 'boolean'),
 
    ('foo', None)
 
])
 
def test_ods_writer_set_custom_property(ods_writer, value, exptype):
 
    cprop = ods_writer.set_custom_property('cprop', value)
 
    assert cprop.getAttribute('name') == 'cprop'
 
    assert cprop.getAttribute('valuetype') == exptype
 
    if exptype == 'boolean':
 
        expected = str(value).lower()
 
    elif exptype == 'date':
 
        expected = value.isoformat()
 
    else:
 
        expected = str(value)
 
    assert cprop.text == expected
0 comments (0 inline, 0 general)