def test_dive_enum(self): """ Test enumerating dives """ kl.enum_dives([self.fin]) r = ku.find(self.fin, '//uddf:dive//uddf:divenumber/text()') self.assertEquals(['1', '2', '3'], list(r))
def __call__(self, args): """ Execute command for list of dive sites in UDDF file. """ import kenozooid.uddf as ku fmt = '{0:4}: {1.id:10} {1.location:20} {1.name:20}' if args.site: query = ku.XP_FIND_SITE else: query = '//uddf:site' files = args.input for fin in files: nodes = ku.find(fin, query, site=args.site) print('{}:'.format(fin)) for i, n in enumerate(nodes): n = ku.site_data(n) coords = '' if n.x is not None: coords = ' {0.x: #.9},{0.y: #.9}'.format(n) print(nformat(fmt, i + 1, n) + coords)
def test_dive_reenum(self): """ Test re-enumerating dives """ kl.enum_dives([self.fin]) r = ku.find(self.fin, '//uddf:dive//uddf:divenumber/text()') assert ['1', '2', '3'] == list(r) d = kd.Dive(datetime=datetime(2010, 1, 2, 5, 7), depth=33.0, duration=3540) kl.add_dive(d, self.fin) kl.enum_dives([self.fin]) # re-enumerate r = ku.find(self.fin, '//uddf:dive//uddf:divenumber/text()') self.assertEquals(['1', '2', '3', '4'], list(r))
def test_dive_copy_gases_retain(self): """ Test copying dives with no gas data to existing logbook """ fl = '{}/dive_copy_logbook.uddf'.format(self.tdir) kl.copy_dives([self.fin], ['1'], None, fl) # copy gases in kl.copy_dives([self.fin], ['2'], None, fl) # copy no gases nodes = ku.find(fl, '//uddf:dive') dn = next(nodes) # 1st dive shall have gases self.assertEquals(('air', 'ean39'), tuple(ku.xp(dn, './/uddf:switchmix/@ref'))) # gas definition section shall be intact nodes = ku.find(fl, '//uddf:gasdefinitions') self.assertTrue(next(nodes) is not None)
def test_dive_copy_with_no_gases(self): """ Test copying dives having no gas data """ fl = '{}/dive_copy_logbook.uddf'.format(self.tdir) kl.copy_dives([self.fin], ['2'], None, fl) nodes = ku.find(fl, '//uddf:dive') dn = next(nodes) self.assertEquals([], list(ku.xp(dn, './/uddf:switchmix/@ref')))
def test_dive_copy_existing(self): """ Test copying existing dive """ fl = '{}/dive_copy_logbook.uddf'.format(self.tdir) kl.copy_dives([self.fin], ['1'], None, fl) kl.copy_dives([self.fin], ['1'], None, fl) # try to duplicate nodes = ku.find(fl, '//uddf:dive') dn = next(nodes) self.assertTrue(next(nodes, None) is None)
def test_dive_copy_with_gases(self): """ Test dive copying with gas data """ fl = '{}/dive_copy_logbook.uddf'.format(self.tdir) kl.copy_dives([self.fin], ['1'], None, fl) nodes = ku.find(fl, '//uddf:dive') dn = next(nodes) self.assertEquals(('air', 'ean39'), tuple(ku.xp(dn, './/uddf:switchmix/@ref')))
def test_dive_copy_with_buddies(self): """ Test dive copying with dive buddies """ fl = '{}/dive_copy_logbook.uddf'.format(self.tdir) kl.copy_dive(self.fin, 2, fl) nodes = ku.find(fl, '//uddf:dive') dn = next(nodes) self.assertEquals('2010-10-30T13:24:43', ku.xp_first(dn, './/uddf:datetime/text()')) self.assertEquals(('b1', 'b2'), tuple(ku.xp(dn, './/uddf:link/@ref')))
def test_dive_copy_with_buddy(self): """ Test copying a dive with a buddy """ fl = '{}/dive_copy_logbook.uddf'.format(self.tdir) kl.copy_dive(self.fin, 1, fl) nodes = ku.find(fl, '//uddf:dive') dn = next(nodes) self.assertEquals('2009-09-19T13:10:23', ku.xp_first(dn, './/uddf:datetime/text()')) self.assertEquals('b1', ku.xp_first(dn, './/uddf:link/@ref'))
def enum_dives(files, total=1): """ Enumerate dives with day dive number (when UDDF 3.2 is introduced) and total dive number. :Parameters: files Collection of UDDF files having dives to enumerate. total Start of total dive number. """ fields = ('id', 'date') queries = ( ku.XPath('@id'), ku.XPath('uddf:informationbeforedive/uddf:datetime/text()'), ) parsers = (str, lambda dt: ku.dparse(dt).date()) fnodes = ((f, n) for f in files for n in ku.find(f, ku.XP_FIND_DIVES, nodes=None, dives=None)) data = ((f, ku.dive_data(n, fields, queries, parsers)) for f, n in fnodes) data = ( (item[0], item[1].id, item[1].date) for item in data) # flatten data data = sorted(data, key=itemgetter(2)) # enumerate dives with _day_ dive number and flatten the groups data = ichain( enumerate(g, 1) for k, g in itertools.groupby(data, itemgetter(2))) # enumerate dives with total dive number and transform into # { (f, id) => (n, k) } cache = dict( ((v[0], v[1]), (n, k)) for n, (k, v) in enumerate(data, total)) # update data for f in files: doc = ku.parse(f) for n in ku.XP_FIND_DIVES(doc, nodes=None, dives=None): id = n.get('id') dnn = ku.xp_first(n, 'uddf:informationbeforedive/uddf:divenumber') if dnn is None: pn = ku.xp_first( n, 'uddf:informationbeforedive/uddf:internaldivenumber') if pn is None: pn = ku.xp_first( n, 'uddf:informationbeforedive/uddf:datetime') *_, dnn = ku.create_node('uddf:divenumber') pn.addprevious(dnn) dnn.text = str(cache[f, id][0]) ku.save(doc.getroot(), f)
def test_dive_copy(self): """ Test copying dive """ fl = '{}/dive_copy_logbook.uddf'.format(self.tdir) kl.copy_dives([self.fin], ['1'], None, fl) nodes = ku.find(fl, '//uddf:dive') dn = next(nodes) self.assertTrue(next(nodes, None) is None) self.assertEquals('2009-09-19T13:10:23', ku.xp_first(dn, './/uddf:datetime/text()')) self.assertEquals('30.2', ku.xp_first(dn, './/uddf:greatestdepth/text()')) self.assertEquals('20', ku.xp_first(dn, './/uddf:diveduration/text()'))
def test_dive_add_with_buddy(self): """ Test adding dive with time, depth, duration and buddy """ f = '{}/dive_add_buddy.uddf'.format(self.tdir) doc = ku.create() ku.create_buddy_data(doc, id='b1', fname='F', lname='N') ku.save(doc, f) d = kd.Dive(datetime=datetime(2010, 1, 2, 5, 7), depth=33.0, duration=3540) kl.add_dive(d, f, qbuddies=['b1']) nodes = ku.find(f, '//uddf:dive') dn = next(nodes) self.assertEquals('b1', ku.xp_first(dn, './/uddf:link/@ref'))
def test_dive_add_with_site(self): """ Test adding dive with time, depth, duration and dive site """ f = '{}/dive_add_site.uddf'.format(self.tdir) doc = ku.create() ku.create_site_data(doc, id='s1', location='L1', name='N1') ku.save(doc, f) d = kd.Dive(datetime=datetime(2010, 1, 2, 5, 7), depth=33.0, duration=3102) kl.add_dive(d, f, qsite='s1') nodes = ku.find(f, '//uddf:dive') dn = next(nodes) self.assertEquals('s1', ku.xp_first(dn, './/uddf:link/@ref'))
def find_dive_gas_nodes(files, nodes=None): """ Find gas nodes referenced by dives in UDDF files using optional node ranges as search parameter. The collection of gas nodes is returned. :Parameters: files Collection of UDDF files. nodes Numeric ranges of nodes, `None` if all nodes. .. seealso:: :py:func:`parse_range` """ nodes = [] if nodes is None else nodes data = (ku.find(f, ku.XP_FIND_DIVE_GASES, nodes=q) \ for q, f in lzip(nodes, files)) nodes_by_id = ((n.get('id'), n) for n in ichain(data)) return dict(nodes_by_id).values()
def test_dive_add(self): """ Test adding dive with time, depth and duration """ f = '{}/dive_add.uddf'.format(self.tdir) d = kd.Dive(datetime=datetime(2010, 1, 2, 5, 7), depth=33.0, duration=3540) kl.add_dive(d, f) nodes = ku.find(f, '//uddf:dive') dn = next(nodes) self.assertTrue(next(nodes, None) is None) self.assertEquals('2010-01-02T05:07:00', ku.xp_first(dn, './/uddf:datetime/text()')) self.assertEquals('33.0', ku.xp_first(dn, './/uddf:greatestdepth/text()')) self.assertEquals('3540', ku.xp_first(dn, './/uddf:diveduration/text()'))
def __call__(self, args): """ Execute command for list of dive buddies in UDDF file. """ import kenozooid.uddf as ku fmt = '{0:4}: {1.id:10} {1.fname:10} {1.lname:20}' \ ' {1.org:5} {1.number:11}' if args.buddy: query = ku.XP_FIND_BUDDY else: query = '//uddf:buddy' files = args.input for fin in files: nodes = ku.find(fin, query, buddy=args.buddy) print('{}:'.format(fin)) for i, n in enumerate(nodes): b = ku.buddy_data(n) print(nformat(fmt, i + 1, b))
def find_dive_nodes(files, nodes=None, dives=None): """ Find dive nodes in UDDF files using optional numeric ranges or total dive number as search parameters. The collection of dive nodes is returned. :Parameters: files Collection of UDDF files. nodes Numeric ranges of nodes, `None` if all nodes. dives Numeric range of total dive number, `None` if any dive. .. seealso:: :py:func:`parse_range` .. seealso:: :py:func:`find_dives` """ nodes = [] if nodes is None else nodes data = (ku.find(f, ku.XP_FIND_DIVES, nodes=q, dives=dives) \ for q, f in lzip(nodes, files)) return ichain(data)
def add_dive(dive, lfile, qsite=None, qbuddies=()): """ Add new dive to logbook file. The logbook file is created if it does not exist. If dive number is specified and dive cannot be found then ValueError exception is thrown. :Parameters: dive Dive data. lfile Logbook file. qsite Dive site search term. qbuddies Buddy search terms. """ if os.path.exists(lfile): doc = et.parse(lfile).getroot() else: doc = ku.create() if qbuddies is None: qbuddies = [] site_id = None if qsite: nodes = ku.find(lfile, ku.XP_FIND_SITE, site=qsite) n = next(nodes, None) if n is None: raise ValueError('Cannot find dive site in logbook file') if next(nodes, None) is not None: raise ValueError('Found more than one dive site') site_id = n.get('id') buddy_ids = [] log.debug('looking for buddies {}'.format(qbuddies)) for qb in qbuddies: log.debug('looking for buddy {}'.format(qb)) nodes = ku.find(lfile, ku.XP_FIND_BUDDY, buddy=qb) n = next(nodes, None) if n is None: raise ValueError('Cannot find buddy {} in logbook file'.format(qb)) if next(nodes, None) is not None: raise ValueError('Found more than one buddy for {}'.format(qb)) buddy_ids.append(n.get('id')) log.debug('creating dive data') ku.create_dive_data(doc, datetime=dive.datetime, depth=dive.depth, duration=dive.duration, site=site_id, buddies=buddy_ids) ku.reorder(doc) ku.save(doc, lfile)