示例#1
0
 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))
示例#2
0
    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)
示例#3
0
    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))
示例#4
0
    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)
示例#5
0
    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')))
示例#6
0
    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)
示例#7
0
    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')))
示例#8
0
    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')))
示例#9
0
    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'))
示例#10
0
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)
示例#11
0
    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()'))
示例#12
0
    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'))
示例#13
0
    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'))
示例#14
0
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()
示例#15
0
    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()'))
示例#16
0
    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))
示例#17
0
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)
示例#18
0
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)