Skip to content
This repository has been archived by the owner on Mar 22, 2018. It is now read-only.

Commit

Permalink
regarding #264. trying to respect literature without breaking too muc…
Browse files Browse the repository at this point in the history
…h of what Bauble has always been doing.
  • Loading branch information
mfrasca committed Jan 8, 2016
1 parent fc9bd75 commit 034ed79
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 129 deletions.
39 changes: 12 additions & 27 deletions bauble/plugins/garden/accession.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,15 +609,16 @@ def validate_stripping(self, key, value):
translations=recvd_type_values),
default=None)

# "id_qual" new in 0.7
# ITF2 - C24 - Rank Qualified Flag - Transfer code: rkql
## B: Below Family; F: Family; G: Genus; S: Species; I: first
## Infraspecific Epithet; J: second Infraspecific Epithet; C: Cultivar;
id_qual_rank = Column(Unicode(10))

# ITF2 - C25 - Identification Qualifier - Transfer code: idql
id_qual = Column(types.Enum(values=['aff.', 'cf.', 'incorrect',
'forsan', 'near', '?', None]),
default=None)

# new in 0.9, this column should contain the name of the column in
# the species table that the id_qual refers to, e.g. genus, sp, etc.
id_qual_rank = Column(Unicode(10))

# "private" new in 0.8b2
private = Column(Boolean, default=False)
species_id = Column(Integer, ForeignKey('species.id'), nullable=False)
Expand Down Expand Up @@ -725,27 +726,11 @@ def species_str(self, authors=False, markup=False):
self.__warned_about_id_qual = True

if self.id_qual:
# copy the species so we don't affect the original
session = db.Session()
species = session.merge(self.species) # , dont_load=True)

# generate the string
if self.id_qual in ('aff.', 'cf.'):
if self.id_qual_rank == 'infrasp':
species.sp = '%s %s' % (species.sp, self.id_qual)
elif self.id_qual_rank:
setattr(species, self.id_qual_rank,
'%s %s' % (self.id_qual,
getattr(species, self.id_qual_rank)))
sp_str = Species.str(species, authors, markup)
elif self.id_qual:
sp_str = '%s(%s)' % (Species.str(species, authors, markup),
self.id_qual)
# clean up and return the string
del species
session.close()
sp_str = self.species.str(
authors, markup, remove_zws=True,
qualification=(self.id_qual_rank, self.id_qual))
else:
sp_str = Species.str(self.species, authors, markup)
sp_str = self.species.str(authors, markup, remove_zws=True)

self.__cached_species_str[(markup, authors)] = sp_str
return sp_str
Expand Down Expand Up @@ -971,7 +956,7 @@ def species_cell_data_func(column, renderer, model, treeiter, data=None):
"""
v = model[treeiter][0]
renderer.set_property(
'text', '%s (%s)' % (Species.str(v, authors=True), v.genus.family))
'text', '%s (%s)' % (v.str(authors=True), v.genus.family))


class VoucherPresenter(editor.GenericEditorPresenter):
Expand Down Expand Up @@ -1198,7 +1183,7 @@ def sp_get_completions(text):
def sp_cell_data_func(col, cell, model, treeiter, data=None):
v = model[treeiter][0]
cell.set_property('text', '%s (%s)' %
(Species.str(v, authors=True),
(v.str(authors=True),
v.genus.family))

ver_prev_taxon_entry = self.widgets.ver_prev_taxon_entry
Expand Down
4 changes: 2 additions & 2 deletions bauble/plugins/garden/plant.py
Original file line number Diff line number Diff line change
Expand Up @@ -765,13 +765,13 @@ def on_select(value):
# new accession, fixes bug #103946
self.view.widgets.acc_species_label.set_markup('')
if value is not None:
sp_str = Species.str(self.model.accession.species, markup=True)
sp_str = self.model.accession.species.str(markup=True)
self.view.widgets.acc_species_label.set_markup(sp_str)
self.view.widgets.plant_code_entry.emit('changed')
self.assign_completions_handler('plant_acc_entry', acc_get_completions,
on_select=on_select)
if self.model.accession:
sp_str = Species.str(self.model.accession.species, markup=True)
sp_str = self.model.accession.species.str(markup=True)
else:
sp_str = ''
self.view.widgets.acc_species_label.set_markup(sp_str)
Expand Down
184 changes: 142 additions & 42 deletions bauble/plugins/garden/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,79 +877,179 @@ def test_details_editor(self):
e.start()


class AccessionTests(GardenTestCase):
class AccessionQualifiedTaxon(GardenTestCase):

def __init__(self, *args):
super(AccessionTests, self).__init__(*args)
super(AccessionQualifiedTaxon, self).__init__(*args)

def setUp(self):
super(AccessionTests, self).setUp()
super(AccessionQualifiedTaxon, self).setUp()
self.sp3 = Species(genus=self.genus, sp=u'grusonii',
infrasp1_rank=u'var.', infrasp1=u'albispinus')
self.session.add(self.sp3)
self.session.commit()
self.ac1 = self.create(Accession, species=self.species, code=u'1')
self.ac2 = self.create(Accession, species=self.sp3, code=u'2')

def tearDown(self):
super(AccessionTests, self).tearDown()
super(AccessionQualifiedTaxon, self).tearDown()

def test_species_str(self):
"""
Test Accession.species_str()
"""
acc = self.create(Accession, species=self.species, code=u'1')
def test_species_str_plain(self):
s = u'Echinocactus grusonii'
sp_str = self.ac1.species_str()
self.assertEquals(remove_zws(sp_str), s)

s = u'<i>Echinocactus</i> <i>grusonii</i> var. <i>albispinus</i>'
sp_str = self.ac2.species_str(markup=True)
self.assertEquals(remove_zws(sp_str), s)

def test_species_str_without_zws(self):
s = u'Echinocactus grusonii'
sp_str = self.species.str(remove_zws=True)
self.assertEquals(sp_str, s)
s = u'Echinocactus grusonii var. albispinus'
sp_str = self.sp3.str(remove_zws=True)
self.assertEquals(sp_str, s)
s = u'<i>Echinocactus</i> <i>grusonii</i> var. <i>albispinus</i>'
sp_str = self.sp3.str(remove_zws=True, markup=True)
self.assertEquals(sp_str, s)

def test_species_str_with_qualification_too_deep(self):
self.ac1.id_qual = u'?'
self.ac1.id_qual_rank = u'infrasp'
s = u'<i>Echinocactus</i> <i>grusonii</i>'
sp_str = self.ac1.species_str(markup=True)
self.assertEquals(remove_zws(sp_str), s)
s = u'Echinocactus grusonii'
sp_str = acc.species_str()
sp_str = self.ac1.species_str()
self.assertEquals(sp_str, s)

self.ac1.id_qual = 'cf.'
self.ac1.id_qual_rank = 'infrasp'
s = u'Echinocactus grusonii'
sp_str = self.ac1.species_str()
self.assertEquals(remove_zws(sp_str), s)

def test_species_str_with_qualification_correct(self):
self.ac1.id_qual = u'?'
self.ac1.id_qual_rank = u'sp'
s = u'<i>Echinocactus</i> ? <i>grusonii</i>'
sp_str = self.ac1.species_str(markup=True)
self.assertEquals(remove_zws(sp_str), s)

# aff. before qualified epithet
self.ac1.id_qual = 'aff.'
self.ac1.id_qual_rank = u'genus'
s = u'aff. <i>Echinocactus</i> <i>grusonii</i>'
sp_str = self.ac1.species_str(markup=True)
self.assertEquals(remove_zws(sp_str), s)

acc.id_qual = '?'
s = u'Echinocactus grusonii(?)'
sp_str = acc.species_str()
self.ac1.id_qual_rank = u'sp'
s = u'<i>Echinocactus</i> aff. <i>grusonii</i>'
sp_str = self.ac1.species_str(markup=True)
self.assertEquals(remove_zws(sp_str), s)

acc.id_qual = 'aff.'
acc.id_qual_rank = u'sp'
self.ac2.id_qual = 'aff.'
self.ac2.id_qual_rank = u'infrasp'
s = u'<i>Echinocactus</i> <i>grusonii</i> aff. var. <i>albispinus</i>'
sp_str = self.ac2.species_str(markup=True)
self.assertEquals(remove_zws(sp_str), s)

self.ac1.id_qual = 'cf.'
self.ac1.id_qual_rank = u'sp'
s = u'<i>Echinocactus</i> cf. <i>grusonii</i>'
sp_str = self.ac1.species_str(markup=True)
self.assertEquals(remove_zws(sp_str), s)

self.ac1.id_qual = 'aff.'
self.ac1.id_qual_rank = u'sp'
s = u'Echinocactus aff. grusonii'
sp_str = acc.species_str()
sp_str = self.ac1.species_str()
self.assertEquals(remove_zws(sp_str), s)

self.ac1.id_qual = 'forsan'
self.ac1.id_qual_rank = u'sp'
s = u'Echinocactus forsan grusonii'
sp_str = self.ac1.species_str()
self.assertEquals(remove_zws(sp_str), s)

## add cultivar to species and refer to it as cf.
self.ac1.species.set_infrasp(1, u'cv.', u'Cultivar')
self.ac1.id_qual = u'cf.'
self.ac1.id_qual_rank = u'infrasp'
s = u"Echinocactus grusonii cf. 'Cultivar'"
sp_str = self.ac1.species_str()
self.assertEquals(remove_zws(sp_str), s)

# here species.infrasp is None but we still allow the string
acc.id_qual = 'cf.'
acc.id_qual_rank = 'infrasp'
s = u'Echinocactus grusonii cf.' # ' None'
sp_str = acc.species_str()
def test_species_str_qualification_appended(self):
# previously, if the id_qual is set but the id_qual_rank isn't then
# we would get an error. now we just log a warning and append it
#
# self.ac1.id_qual = 'aff.'
# self.ac1.id_qual_rank = None
# self.assertRaises(CheckConditionError, self.ac1.species_str)

self.ac1.id_qual = None
self.ac1.id_qual = '?'
s = u'Echinocactus grusonii (?)'
sp_str = self.ac1.species_str()
self.assertEquals(remove_zws(sp_str), s)

# species.infrasp is still none but these just get pasted on
# the end so it doesn't matter
acc.id_qual = 'incorrect'
acc.id_qual_rank = 'infrasp'
s = u'Echinocactus grusonii(incorrect)'
sp_str = acc.species_str()
self.ac1.id_qual = 'incorrect'
self.ac1.id_qual_rank = 'infrasp'
s = u'Echinocactus grusonii (incorrect)'
sp_str = self.ac1.species_str()
self.assertEquals(remove_zws(sp_str), s)

acc.id_qual = 'forsan'
acc.id_qual_rank = u'sp'
s = u'Echinocactus grusonii(forsan)'
sp_str = acc.species_str()
self.ac1.id_qual = 'incorrect'
self.ac1.id_qual_rank = 'sp'
s = u'<i>Echinocactus</i> <i>grusonii</i> (incorrect)'
sp_str = self.ac1.species_str(markup=True)
self.assertEquals(remove_zws(sp_str), s)

acc.species.set_infrasp(1, u'cv.', u'Cultivar')
acc.id_qual = u'cf.'
acc.id_qual_rank = u'infrasp'
def test_species_str_is_cached(self):
self.ac1.species.set_infrasp(1, u'cv.', u'Cultivar')
self.ac1.id_qual = u'cf.'
self.ac1.id_qual_rank = u'infrasp'
s = u"Echinocactus grusonii cf. 'Cultivar'"
sp_str = acc.species_str()
sp_str = self.ac1.species_str()
self.assertEquals(remove_zws(sp_str), s)

# test that the cached string is returned

# have to commit because the cached string won't be returned
# on dirty species
self.session.commit()
s2 = acc.species_str()
s2 = self.ac1.species_str()
self.assertEquals(id(sp_str), id(s2))

# this used to test that if the id_qual was set but the
# id_qual_rank wasn't then we would get an error. now we just
# show an warning and put the id_qual on the end of the string
# acc.id_qual = 'aff.'
# acc.id_qual_rank = None
# self.assertRaises(CheckConditionError, acc.species_str)
def test_species_str_be_specific_in_infraspecific(self):
'be specific qualifying infraspecific identification - still unused'
## add to species with variety and refer to it as cf.
self.sp3.set_infrasp(2, u'cv.', u'Cultivar')
self.ac2.id_qual = u'cf.'
self.ac2.id_qual_rank = u'cv.'
s = u"Echinocactus grusonii var. albispinus cf. 'Cultivar'"
sp_str = self.ac2.species_str()
self.assertEquals(remove_zws(sp_str), s)

self.ac2.id_qual = u'cf.'
self.ac2.id_qual_rank = u'var.'
s = u"Echinocactus grusonii var. cf. albispinus 'Cultivar'"
sp_str = self.ac2.species_str()
self.assertEquals(remove_zws(sp_str), s)


class AccessionTests(GardenTestCase):

def __init__(self, *args):
super(AccessionTests, self).__init__(*args)

def setUp(self):
super(AccessionTests, self).setUp()

def tearDown(self):
super(AccessionTests, self).tearDown()

def test_delete(self):
"""
Expand Down
4 changes: 2 additions & 2 deletions bauble/plugins/plants/species.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def update(self, row):
box = gtk.EventBox()
label = gtk.Label()
label.set_alignment(0, .5)
label.set_markup(Species.str(accepted, markup=True, authors=True))
label.set_markup(accepted.str(markup=True, authors=True))
box.add(label)
utils.make_label_clickable(label, on_label_clicked, accepted)
syn_box.pack_start(box, expand=False, fill=False)
Expand All @@ -261,7 +261,7 @@ def update(self, row):
box = gtk.EventBox()
label = gtk.Label()
label.set_alignment(0, .5)
label.set_markup(Species.str(syn, markup=True, authors=True))
label.set_markup(syn.str(markup=True, authors=True))
box.add(label)
utils.make_label_clickable(label, on_label_clicked, syn)
syn_box.pack_start(box, expand=False, fill=False)
Expand Down
6 changes: 3 additions & 3 deletions bauble/plugins/plants/species_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ def refresh_fullname_label(self, widget=None):
if len(self.problems) > 0 or self.model.genus is None:
self.view.set_label('sp_fullname_label', '--')
return
sp_str = Species.str(self.model, markup=True, authors=True)
sp_str = self.model.str(markup=True, authors=True)
self.view.set_label('sp_fullname_label', sp_str)
if self.model.genus is not None:
genus = self.model.genus
Expand All @@ -450,7 +450,7 @@ def refresh_fullname_label(self, widget=None):
msg = _("This binomial name is already in your collection"
", as %s.\n\n"
"Are you sure you want to insert it again?") % \
Species.str(omonym, authors=True, markup=True)
omonym.str(authors=True, markup=True)

def on_response(button, response):
self.view.remove_box(self.omonym_box)
Expand Down Expand Up @@ -1015,7 +1015,7 @@ def on_remove_button_clicked(self, button, data=None):
path, col = tree.get_cursor()
tree_model = tree.get_model()
value = tree_model[tree_model.get_iter(path)][0]
s = Species.str(value.synonym, markup=True)
s = value.synonym.str(markup=True)
msg = 'Are you sure you want to remove %s as a synonym to the ' \
'current species?\n\n<i>Note: This will not remove the species '\
'%s from the database.</i>' % (s, s)
Expand Down

0 comments on commit 034ed79

Please sign in to comment.