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

Commit

Permalink
implements the top_level_count method. defaults to {classname:1}
Browse files Browse the repository at this point in the history
close #235
  • Loading branch information
mfrasca committed Dec 24, 2015
1 parent 4b40dd2 commit 79c7cdb
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 6 deletions.
7 changes: 3 additions & 4 deletions bauble/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ def __init__(cls, classname, bases, dict_):
default=sa.func.now(),
onupdate=sa.func.now())
cls.__mapper_args__ = {'extension': HistoryExtension()}
if 'top_level_count' not in dict_:
cls.top_level_count = lambda x: {classname: 1}
super(MapperBase, cls).__init__(classname, bases, dict_)


Expand Down Expand Up @@ -252,13 +254,10 @@ def open(uri, verify=True, show_error_dialogs=False):
global engine
new_engine = None

# use the SingletonThreadPool so that we always use the same
# connection in a thread, not sure how this is different than
# the threadlocal strategy but it doesn't cause as many lockups
import sqlalchemy.pool as pool
new_engine = sa.create_engine(uri, echo=SQLALCHEMY_DEBUG,
implicit_returning=False,
poolclass=pool.SingletonThreadPool)
poolclass=pool.NullPool)
# TODO: there is a problem here: the code may cause an exception, but we
# immediately loose the 'new_engine', which should know about the
# encoding used in the exception string.
Expand Down
5 changes: 5 additions & 0 deletions bauble/plugins/garden/accession.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,11 @@ def retrieve(cls, session, keys):
except:
return None

def top_level_count(self):
return {(1, 'Accession'): 1,
(2, 'Planting'): len(self.plants),
(3, 'Living plant'): sum(p.quantity for p in self.plants)}


from bauble.plugins.garden.plant import Plant, PlantEditor

Expand Down
5 changes: 5 additions & 0 deletions bauble/plugins/garden/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ def retrieve(cls, session, keys):
except:
return None

def top_level_count(self):
return {(1, 'Location'): 1,
(2, 'Planting'): len(self.plants),
(3, 'Living plant'): sum(p.quantity for p in self.plants)}


def mergevalues(value1, value2, formatter):
"""return the common value
Expand Down
12 changes: 12 additions & 0 deletions bauble/plugins/plants/family.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,18 @@ def correct_field_names(cls, keys):
keys[internal] = keys[exchange]
del keys[exchange]

def top_level_count(self):
return {(1, 'Family'): 1} # NOPE - this has to wait
species = [s for g in self.genera for s in g.species]
accessions = [a for s in species for a in s.accessions]
plants = [p for a in accessions for p in a.plants]
return {(1, 'Family'): 1,
(2, 'Genus'): len(self.genera),
(3, 'Species'): len(species),
(4, 'Accession'): len(accessions),
(5, 'Planting'): len(plants),
(6, 'Living plant'): sum(p.quantity for p in plants)}


## defining the latin alias to the class.
Familia = Family
Expand Down
9 changes: 9 additions & 0 deletions bauble/plugins/plants/genus.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,15 @@ def compute_serializable_fields(cls, session, keys):
raise error.NoResultException()
return result

def top_level_count(self):
accessions = [a for s in self.species for a in s.accessions]
plants = [p for a in accessions for p in a.plants]
return {(1, 'Genus'): 1,
(2, 'Species'): len(self.species),
(3, 'Accession'): len(accessions),
(4, 'Planting'): len(plants),
(5, 'Living plant'): sum(p.quantity for p in plants)}


class GenusNote(db.Base):
"""
Expand Down
7 changes: 7 additions & 0 deletions bauble/plugins/plants/species_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,13 @@ def compute_serializable_fields(cls, session, keys):
raise error.NoResultException()
return result

def top_level_count(self):
plants = [p for a in self.accessions for p in a.plants]
return {(1, 'Species'): 1,
(2, 'Accession'): len(self.accessions),
(3, 'Planting'): len(plants),
(4, 'Living plant'): sum(p.quantity for p in plants)}


class SpeciesNote(db.Base, db.Serializable):
"""
Expand Down
44 changes: 42 additions & 2 deletions bauble/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import gtk
import gobject
import pango
import threading

from bauble.i18n import _
from pyparsing import ParseException
Expand Down Expand Up @@ -357,6 +358,44 @@ def update(self, row):
self.dynamic_box.show_all()


class CountResultsTask(threading.Thread):
def __init__(self, klass, ids,
group=None, verbose=None, **kwargs):
super(CountResultsTask, self).__init__(
group=group, target=None, name=None, verbose=verbose)
self.klass = klass
self.ids = ids

def run(self):
session = db.Session()
## we really need a new session
session.close()
session = db.Session()
klass = self.klass
d = {}
for ndx in self.ids:
item = session.query(klass).filter(klass.id == ndx).one()
for k, v in item.top_level_count().items():
d[k] = v + d.get(k, 0)
result = []
for k, v in sorted(d.items()):
if isinstance(k, tuple):
k = k[1]
result.append("%s: %d" % (k, v))
value = _("top level count: %s") % (", ".join(result))
if bauble.gui:
def callback(text):
statusbar = bauble.gui.widgets.statusbar
sbcontext_id = statusbar.get_context_id('searchview.nresults')
statusbar.pop(sbcontext_id)
statusbar.push(sbcontext_id, text)
gobject.idle_add(callback, value)
else:
logger.debug("showing text %s", value)
## we should not leave the session around
session.close()


class SearchView(pluginmgr.View):
"""
The SearchView is the main view for Bauble. It manages the search
Expand Down Expand Up @@ -740,8 +779,9 @@ def search(self, text):
return
else:
statusbar.pop(sbcontext_id)
statusbar.push(sbcontext_id,
_("%s search results") % len(results))
statusbar.push(sbcontext_id, _('counting results...'))
CountResultsTask(results[0].__class__,
[i.id for i in results]).start()
self.results_view.set_cursor(0)
gobject.idle_add(lambda: self.results_view.scroll_to_cell(0))

Expand Down

0 comments on commit 79c7cdb

Please sign in to comment.