Package kenozooid :: Module uddf

Module uddf

source code

The kenozooid.uddf module provides support for parsing, searching and manipulation of data stored in UDDF files.

The functions implemented in this module can be divided into the following categories

Searching functions use XPath expressions (queries) to find data. Each tag name in an query should be prefixed with 'uddf:' string to indicate UDDF namespace, i.e. 'uddf:diver', 'uddf:waypoint' - appropriate namespace mapping for this prefix is defined for each XPath call.

The result of parsing or search of data is usually iterator of XML nodes or data records (named tuples in Python terms).

Module lxml is used for XML parsing and querying with XPath. Full capabilities of underlying libxml2 library is used by design. The ElementTree XML data model is used for XML nodes.

Classes
  RangeError
Error raised when a range cannot be parsed.
  NodeCopier
UDDF dcument node copier.
Functions
 
parse(f, ver_check=True)
Parse XML file and return document object.
source code
 
find(f, query, **params)
Find XML nodes in UDDF file using XPath query.
source code
 
xp(node, query)
Find items with XPath query.
source code
 
xp_first(node, query)
Get first element found with XPath query.
source code
 
xp_last(node, query)
Get last element found with XPath query.
source code
 
find_data(name, node, fields, queries, parsers, nquery=None)
Find data records starting from specified XML node.
source code
 
dive_data(node, fields=None, queries=None, parsers=None)
Specialized function to return record of a dive data.
source code
 
dive_profile(node, fields=None, queries=None, parsers=None)
Specialized function to return generator of dive profiles records.
source code
 
gas_data(node, fields=None, queries=None, parsers=None) source code
 
dump_data(node, fields=None, queries=None, parsers=None)
Get dive computer dump data.
source code
 
buddy_data(node, fields=None, queries=None, parsers=None)
Get dive buddy data.
source code
 
site_data(node, fields=None, queries=None, parsers=None)
Get dive site data.
source code
 
parse_range(s)
Parse textual representation of number range into Python expression.
source code
 
in_range(ctx, pos, nodes)
XPath expression function to restrict position of a node to be within numeric range.
source code
 
create(datetime=datetime.now())
fixme: obsolete
source code
 
set_data(node, queries, formatters=None, **data)
Set data of nodes or attributes using XPath queries relative to specified XML node.
source code
 
create_node(path, parent=None, append=True)
TODO: get rid of parent, does not make sense
source code
 
create_dive_data(node=None, queries=None, formatters=None, **data)
Create dive data.
source code
 
create_buddy_data(node, queries=None, formatters=None, **data)
Create buddy data.
source code
 
create_site_data(node, queries=None, formatters=None, **data)
Create dive site data.
source code
 
create_uddf(datetime=datetime.now(), equipment=None, gases=None, dives=None, dump=None)
Create UDDF XML data.
source code
 
create_dives(dives, equipment=None)
Create dives UDDF XML data.
source code
 
create_dive(dive, equipment=None)
Create dive UDDF XML data.
source code
 
create_dive_samples(samples, mode=None)
Create dive samples UDDF XML data.
source code
 
create_gas(gas)
Create gas UDDF XML data.
source code
 
create_dc_data(dc_id, model)
Create dive computer UDDF XML data.
source code
 
create_dump_data(dc_id, datetime, data)
Create dive computer dump UDDF XML data.
source code
 
save(doc, fout, validate=True)
Save UDDF XML data into a file.
source code
 
remove_nodes(node, query, **params)
Remove nodes from XML document using XPath query.
source code
 
reorder(doc)
fixme: obsolete
source code
 
gen_id(value=None)
Generate id for a value.
source code
 
xml_file_copy(f)
Iterator of raw XML data from a file to data into dirty.xml nodes.
source code
 
get_version(f)
Get major version of UDDF file.
source code
Variables
  log = logging.getLogger('kenozooid.uddf')
  FORMAT_ID = 'id-{}'
  FMT_F = partial(str.format, '{0:.1f}')
  FMT_F2 = partial(str.format, '{0:.2f}')
  FMT_I = lambda v:
  FMT_DT = lambda dt:
  XPath = partial(et.XPath, namespaces= _NSMAP)
  XP_DEFAULT_DIVE_DATA = XPath('uddf:informationbeforedive/uddf:...
  XP_DEFAULT_PROFILE_DATA = XPath('uddf:depth/text()'), XPath('u...
  XP_DEFAULT_GAS_DATA = XPath('@id'), XPath('uddf:name/text()'),...
  XP_WAYPOINT = XPath('./uddf:samples/uddf:waypoint')
  XP_MIX = XPath('/uddf:uddf/uddf:gasdefinitions/uddf:mix')
  XP_DEFAULT_DUMP_DATA = XPath('uddf:link/@ref'), XPath('../../u...
  XP_DEFAULT_BUDDY_DATA = XPath('@id'), XPath('uddf:personal/udd...
  XP_DEFAULT_SITE_DATA = XPath('@id'), XPath('uddf:name/text()')...
  XP_FIND_BUDDY = XPath('/uddf:uddf/uddf:diver/uddf:buddy[' '@id...
  XP_FIND_SITE = XPath('/uddf:uddf/uddf:divesite/uddf:site[' '@i...
  XP_FIND_DIVES = XPath('/uddf:uddf/uddf:profiledata' '/uddf:rep...
  XP_FIND_DIVE_GASES = XPath('/uddf:uddf/uddf:gasdefinitions' '/...
  ns = et.FunctionNamespace(None)
  DEFAULT_FMT_DIVE_PROFILE = {'depth': lambda d: str.format('{0:...
  UDDF_BASIC = "...
Function Details

parse(f, ver_check=True)

source code 

Parse XML file and return document object.

File to parse can be anything supported by lxml library.

If file to parse is file name and ends with '.bz2', then it is treated as file compressed with bzip2.

Parameters:
  • f - File to parse.
  • ver_check - Check version of UDDF file.

find(f, query, **params)

source code 

Find XML nodes in UDDF file using XPath query.

UDDF file can be a file name, file object, URL and basically everything
what is supported by `lxml` library.

File to parse can be a file name ending with '.bz2'. It is treated as
file compressed with bzip2.

:Parameters:
 f
    UDDF file to parse.
 query
    XPath expression or XPath object.
 params
    XPath query parameters.

.. seealso:: :py:func:`XPath`, :py:func:`parse`

xp(node, query)

source code 

Find items with XPath query.

The query is performed using UDDF namespace.

Iterator of items (strings, nodes) found by query is returned.

:Parameters:
 node
    Document node or query starting node.
 query
    XPath query.

.. seealso::
    lxml.etree.Element.xpath

xp_first(node, query)

source code 

Get first element found with XPath query.

The query is performed using UDDF namespace.

First element is returned or None if it is not found.

:Parameters:
 node
    Document node or query starting node.
 query
    XPath query.

.. seealso::
    lxml.etree.Element.xpath

xp_last(node, query)

source code 

Get last element found with XPath query.

The query is performed using UDDF namespace.

Last element is returned or None if it is not found.

:Parameters:
 node
    Document node or query starting node.
 query
    XPath query.

.. seealso::
    lxml.etree.Element.xpath

find_data(name, node, fields, queries, parsers, nquery=None)

source code 

Find data records starting from specified XML node.

A record type (namedtuple) is created with specified fields. The data
of a record is retrieved with XPath expression objects, which is
converted from string to appropriate type using parsers.

A parser can be any type or function, i.e. `float`, `int` or
`dateutil.parser.parse`.

If XML node is too high to execture XPath expression objects, then the
basis for field queries can be relocated with `nquery` parameter. If
`nquery` parameter is not specified, then only one record is returned.
Otherwise it is generator of records.

The length of fields, field queries and field parsers should be the same.

:Parameters:
 name
    Name of the record to be created.
 node
    XML node.
 fields
    Names of fields to be created in a record.
 queries
    XPath expression objects for each field to retrieve its value.
 parsers
    Parsers of field values to be created in a record.
 nquery
    XPath expression object to relocate from node to more appropriate
    position in XML document for record data retrieval.

.. seealso:: :py:func:`dive_data`, :py:func:`dive_profile`

dive_data(node, fields=None, queries=None, parsers=None)

source code 

Specialized function to return record of a dive data.

At the moment record of dive data contains dive start time only, by
default. It should be enhanced in the future to return more rich data
record.

Dive record data can be reconfigured with optional fields, field
queries and field parsers parameters.

:Parameters:
 node
    XML node.
 fields
    Names of fields to be created in a record.
 queries
    XPath expression object for each field to retrieve its value.
 parsers
    Parsers field values to be created in a record.

.. seealso:: :py:func:`find_data`

dive_profile(node, fields=None, queries=None, parsers=None)

source code 

Specialized function to return generator of dive profiles records.

By default, dive profile record contains following fields

time
    dive time in seconds
depth
    dive depth in meters
temp
    temperature in Kelvins

Dive profile record data can be reconfigured with optional fields,
field queries and field parsers parameters.

:Parameters:
 node
    XML node.
 fields
    Names of fields to be created in a record.
 queries
    XPath expression objects for each field to retrieve its value.
 parsers
    Parsers of field values to be created in a record.

.. seealso:: :py:func:`find_data`

dump_data(node, fields=None, queries=None, parsers=None)

source code 

Get dive computer dump data.

The following data is returned

dc_id
    Dive computer id.
dc_model
    Dive computer model information.
datetime
    Date and time when dive computer dump was obtained.
data
    Dive computer dump data.

:Parameters:
 node
    XML node.
 fields
    Names of fields to be created in a record.
 queries
    XPath expression objects for each field to retrieve its value.
 parsers
    Parsers of field values to be created in a record.

.. seealso:: :py:func:`find_data`

buddy_data(node, fields=None, queries=None, parsers=None)

source code 

Get dive buddy data.

The following data is returned by default

id
    Buddy id.
fname
    Buddy first name.
mname
    Buddy middle name.
lname
    Buddy last name.
org
    Organization, which a buddy is member of.
number
    Member number id in the organisation.

:Parameters:
 node
    XML node.
 fields
    Names of fields to be created in a record.
 queries
    XPath expression objects for each field to retrieve its value.
 parsers
    Parsers of field values to be created in a record.

.. seealso:: :py:func:`find_data`

site_data(node, fields=None, queries=None, parsers=None)

source code 

Get dive site data.

The following data is returned by default

id
    Dive site id.
name
    Dive site name.
location
    Dive site location.
x
    Dive site longitude.
y
    Dive site latitude.

:Parameters:
 node
    XML node.
 fields
    Names of fields to be created in a record.
 queries
    XPath expression objects for each field to retrieve its value.
 parsers
    Parsers of field values to be created in a record.

.. seealso:: :py:func:`find_data`

parse_range(s)

source code 

Parse textual representation of number range into Python expression.

Examples of a ranges

>>> parse_range('1-3,5')
'1 <= n and n <= 3 or n == 5'
>>> parse_range('-3,10')
'n <= 3 or n == 10'

Example of infinite range

>>> parse_range('20-')
'20 <= n'
Parameters:
  • s - Textual representation of number range.

in_range(ctx, pos, nodes)

source code 

XPath expression function to restrict position of a node to be within
numeric range.

:Parameters:
 ctx
    XPath context object.
 pos
    Node position.
 nodes
    Number range, i.e. "2-3".

.. seealso:: :py:func:`parse_range`

create(datetime=datetime.now())

source code 

fixme: obsolete

Create basic UDDF structure.

Parameters:
  • datetime - Timestamp of file creation, current time by default.

set_data(node, queries, formatters=None, **data)

source code 

Set data of nodes or attributes using XPath queries relative to specified XML node.

The data values are converted to string with formatters functions.

Parameters:
  • node - XML node.
  • queries - Path-like expressions of XML structure to be created.
  • formatters - Data formatters.
  • data - Data values to be set within XML document.

create_node(path, parent=None, append=True)

source code 

TODO: get rid of parent, does not make sense

Create a hierarchy of nodes using XML nodes path specification.

Path is a string of node names separated by slash character, i.e. a/b/c creates:

<a><b><c/></b><a>

If parent node is specified and some part of node hierarchy already exists then only non-existant nodes are created, i.e. if parent is 'x' node in

<x><y/></x>

then path 'x/z' modifies XML document as follows

<x><y/><z/></x>
Parameters:
  • path - Hierarchy of nodes.
  • parent - Optional parent node.

create_dive_data(node=None, queries=None, formatters=None, **data)

source code 
Create dive data.
Parameters:
  • node - Base node (UDDF root node).
  • queries - Path-like expressions of XML structure to be created.
  • formatters - Dive data formatters.
  • data - Dive data.

create_buddy_data(node, queries=None, formatters=None, **data)

source code 
Create buddy data.
Parameters:
  • node - Base node (UDDF root node).
  • queries - Path-like expressions of XML structure to be created.
  • formatters - Buddy data formatters.
  • data - Buddy data.

create_site_data(node, queries=None, formatters=None, **data)

source code 
Create dive site data.
Parameters:
  • node - Base node (UDDF root node).
  • queries - Path-like expressions of XML structure to be created.
  • formatters - Dive site data formatters.
  • data - Dive site data.

create_uddf(datetime=datetime.now(), equipment=None, gases=None, dives=None, dump=None)

source code 
Create UDDF XML data.
Parameters:
  • datetime - Timestamp of UDDF creation.
  • equipment - Diver's (owner) equipment XML data (see create_dc_data).
  • gases - List of gases used by the dives.
  • dives - Dives XML data (see create_dives).
  • dump - Dive computer dump XML data (see create_dump_data).

create_dives(dives, equipment=None)

source code 
Create dives UDDF XML data.
Parameters:
  • dives - Iterable of dive tuples.
  • equipment - List of used equipment references.

create_dive(dive, equipment=None)

source code 
Create dive UDDF XML data.
Parameters:
  • dive - Dive to render as XML.
  • equipment - List of used equipment references.

create_dive_samples(samples, mode=None)

source code 
Create dive samples UDDF XML data.
Parameters:
  • samples - Iterable of tuples of dive samples.
  • mode - Dive mode, i.e. opencircuit, closedcircuit.

create_gas(gas)

source code 
Create gas UDDF XML data.
Parameters:
  • gas - Gas information to render as XML.

create_dc_data(dc_id, model)

source code 
Create dive computer UDDF XML data.
Parameters:
  • dc_id - Dive computer id.
  • model - Dive computer model.

create_dump_data(dc_id, datetime, data)

source code 
Create dive computer dump UDDF XML data.
Parameters:
  • dc_id - Dive computer id.
  • datetime - Date and time when the dump was created.
  • data - Dive computer binary data.

save(doc, fout, validate=True)

source code 

Save UDDF XML data into a file.

If output file is file name ending with '.bz2', then it is compressed with bzip2.

The UDDF XML data can be ElementTree XML object or iterable of strings.

If output file exists then backup file with .bak extension is created.

Parameters:
  • doc - UDDF XML data.
  • fout - Output file.
  • validate - Validate UDDF file after saving if True.

remove_nodes(node, query, **params)

source code 
Remove nodes from XML document using XPath query.
Parameters:
  • node - Starting XML node for XPath query.
  • query - XPath query to find nodes to remove.
  • params - XPath query parameters.

reorder(doc)

source code 

fixme: obsolete

Reorder and cleanup dives in UDDF document.

Following operations are being performed

  • dives are sorted by dive start time
  • duplicate dives and repetition groups are removed
Parameters:
  • doc - UDDF document.

gen_id(value=None)

source code 

Generate id for a value.

If value is specified then id is MD5 hash of value. If not specified, then id is generated with UUID 4.

The returned id is a string prefixed with id- to make it XML compliant.

xml_file_copy(f)

source code 
Iterator of raw XML data from a file to data into dirty.xml nodes.
Parameters:
  • f - File containing XML data.

get_version(f)

source code 

Get major version of UDDF file.

Tuple (major, minor) is returned, i.e. (3, 0), (3, 1), etc.

Parameters:
  • f - File to check.

Variables Details

XP_DEFAULT_DIVE_DATA

Value:
XPath('uddf:informationbeforedive/uddf:divenumber/text()'), XPath('udd\
f:informationbeforedive/uddf:datetime/text()'), XPath('uddf:informatio\
nafterdive/uddf:greatestdepth/text()'), XPath('uddf:informationafterdi\
ve/uddf:diveduration/text()'), XPath('uddf:informationafterdive/uddf:l\
owesttemperature/text()'), XPath('uddf:informationafterdive/uddf:avera\
gedepth/text()'), XPath('uddf:samples/uddf:waypoint/uddf:divemode[1]/@\
type'), None,

XP_DEFAULT_PROFILE_DATA

Value:
XPath('uddf:depth/text()'), XPath('uddf:divetime/text()'), XPath('uddf\
:temperature/text()'), XPath('uddf:setpo2/text()'), XPath('uddf:setpo2\
/@setby'), XPath('uddf:decostop/@duration'), XPath('uddf:decostop/@dec\
odepth'), XPath('uddf:alarm/text()'), XPath('uddf:switchmix/@ref'),

XP_DEFAULT_GAS_DATA

Value:
XPath('@id'), XPath('uddf:name/text()'), XPath('uddf:o2/text()'), XPat\
h('uddf:he/text()'),

XP_DEFAULT_DUMP_DATA

Value:
XPath('uddf:link/@ref'), XPath('../../uddf:diver/uddf:owner//uddf:dive\
computer[' '@id = //uddf:divecomputerdump[position()]/uddf:link/@ref' \
']/uddf:model/text()'), XPath('uddf:datetime/text()'), XPath('uddf:dcd\
ump/text()'),

XP_DEFAULT_BUDDY_DATA

Value:
XPath('@id'), XPath('uddf:personal/uddf:firstname/text()'), XPath('udd\
f:personal/uddf:middlename/text()'), XPath('uddf:personal/uddf:lastnam\
e/text()'), XPath('uddf:personal/uddf:membership/@organisation'), XPat\
h('uddf:personal/uddf:membership/@memberid'),

XP_DEFAULT_SITE_DATA

Value:
XPath('@id'), XPath('uddf:name/text()'), XPath('uddf:geography/uddf:lo\
cation/text()'), XPath('uddf:geography/uddf:longitude/text()'), XPath(\
'uddf:geography/uddf:latitude/text()'),

XP_FIND_BUDDY

Value:
XPath('/uddf:uddf/uddf:diver/uddf:buddy[' '@id = $buddy' ' or uddf:per\
sonal/uddf:membership/@memberid = $buddy' ' or uddf:personal/uddf:memb\
ership/@organisation = $buddy' ' or contains(uddf:personal/uddf:firstn\
ame/text(), $buddy)' ' or contains(uddf:personal/uddf:lastname/text(),\
 $buddy)' ']')

XP_FIND_SITE

Value:
XPath('/uddf:uddf/uddf:divesite/uddf:site[' '@id = $site' ' or contain\
s(uddf:name/text(), $site)' ' or contains(uddf:geography/uddf:location\
/text(), $site)' ']')

XP_FIND_DIVES

Value:
XPath('/uddf:uddf/uddf:profiledata' '/uddf:repetitiongroup/uddf:dive[i\
n-range(position(), $nodes)' ' and in-range(uddf:informationbeforedive\
/uddf:divenumber/text(), $dives)]')

XP_FIND_DIVE_GASES

Value:
XPath('/uddf:uddf/uddf:gasdefinitions' '/uddf:mix[@id=/uddf:uddf/uddf:\
profiledata/uddf:repetitiongroup' '/uddf:dive[in-range(position(), $no\
des)]' '/uddf:samples/uddf:waypoint/uddf:switchmix/@ref]')

DEFAULT_FMT_DIVE_PROFILE

Value:
{'depth': lambda d: str.format('{0:.1f}', max(d, 0)), 'temp': partial(\
str.format, '{0:.1f}'),}

UDDF_BASIC

Value:
"""\
<uddf xmlns="http://www.streit.cc/uddf/3.2/" version="3.2.0">
<generator>
    <name>kenozooid</name>
    <manufacturer id='kenozooid'>
      <name>Kenozooid Team</name>
      <contact>
        <homepage>http://wrobell.dcmod.org/kenozooid/</homepage>
...