Skip to content

Commit

Permalink
Merge branch 'ghini-1.0-dev' into ghini-1.0, as 1.0.85
Browse files Browse the repository at this point in the history
  • Loading branch information
mfrasca committed May 31, 2018
2 parents 4078f97 + 31e1f26 commit ad9ce21
Show file tree
Hide file tree
Showing 74 changed files with 3,980 additions and 3,468 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
*.deb

# PyInstaller
# Usually these files are written by a python script from a template
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Ghini
======

.. |travis| image:: https://travis-ci.org/Ghini/ghini.desktop.svg?branch=ghini-1.0-dev
.. |pypi| image:: https://img.shields.io/pypi/v/bauble.svg
.. |pypi| image:: https://img.shields.io/pypi/v/ghini.desktop.svg
.. |coveralls| image:: https://coveralls.io/repos/Ghini/ghini.desktop/badge.svg?branch=ghini-1.0-dev&service=github

======== ======== ============
Expand Down
1 change: 1 addition & 0 deletions bauble/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ def main(uri=None):
sentry_client = Client('https://59105d22a4ad49158796088c26bf8e4c:'
'00268114ed47460b94ce2b1b0b2a4a20@'
'app.getsentry.com/45704')
sentry_client.name = hex(hash(sentry_client.name) + 2**64)[2:-1]
handler = SentryHandler(sentry_client)
logging.getLogger().addHandler(handler)
handler.setLevel(logging.WARNING)
Expand Down
1 change: 1 addition & 0 deletions bauble/plugins/garden/institution.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ def get_sentry_handler(self):
sentry_client = Client('https://59105d22a4ad49158796088c26bf8e4c:'
'00268114ed47460b94ce2b1b0b2a4a20@'
'app.getsentry.com/45704')
sentry_client.name = hex(hash(sentry_client.name) + 2**64)[2:-1]
return SentryHandler(sentry_client)

def on_inst_register_clicked(self, *args, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion bauble/plugins/garden/picture_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def do_import(self): # step 2
epgn, epsp = unicode(row[binomial_col] + ' sp').split(' ')[:2]
filename = unicode(row[filename_col])
complete_plant_code = unicode(row[accno_col])
accession_code, plant_code = complete_plant_code.rsplit(Plant.get_delimiter(), 2)
accession_code, plant_code = complete_plant_code.rsplit(Plant.get_delimiter(), 1)

# create or retrieve genus and species
genus = session.query(Genus).filter_by(epithet=epgn).one()
Expand Down
22 changes: 13 additions & 9 deletions bauble/plugins/imex/csv_.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ def do_insert():
transaction.rollback()
raise
except Exception, e:
logger.error(e)
logger.error("%s(%s)" % (type(e).__name__, e))
logger.error(traceback.format_exc())
transaction.rollback()
self.__error = True
Expand Down Expand Up @@ -591,8 +591,6 @@ def start(self, path=None):
raise ValueError(_("CSVExporter: path does not exist.\n%s") % path)

try:
# TODO: should we support exporting other metadata
# besides db.metadata
bauble.task.queue(self.__export_task(path))
except Exception, e:
logger.debug(e)
Expand All @@ -609,7 +607,7 @@ def __export_task(self, path):
'<b>%(table)s</b> table already exists.\n\n<i>Would '
'you like to continue?</i>')\
% {'filename': filename, 'table': table.name}
if utils.yes_no_dialog(msg):
if not utils.yes_no_dialog(msg): # if NO: return
return

def replace(s):
Expand All @@ -625,13 +623,16 @@ def write_csv(filename, rows):
f.close()

update_every = 30
spinner = u'⣄⡆⠇⠋⠙⠸⢰⣠'
for table in db.metadata.sorted_tables:
filename = filename_template % table.name
steps_so_far += 1
spinner_index = 0
fraction = float(steps_so_far)/float(ntables)
pb_set_fraction(fraction)
msg = _('exporting %(table)s table to %(filename)s')\
% {'table': table.name, 'filename': filename}
msg = msg + ' ' + spinner[spinner_index]
bauble.task.set_message(msg)
logger.info("exporting %s" % table.name)

Expand All @@ -648,9 +649,15 @@ def write_csv(filename, rows):
rows.append(table.c.keys()) # append col names
ctr = 0
for row in results:
values = map(replace, row.values())
rows.append(values)
try:
rows.append(map(replace, row.values()))
except:
import traceback
logger.error(traceback.format_exc())
if ctr == update_every:
spinner_index = (spinner_index + 1) % len(spinner)
msg = msg[:-1] + spinner[spinner_index]
bauble.task.set_message(msg)
yield
ctr = 0
ctr += 1
Expand Down Expand Up @@ -705,6 +712,3 @@ class CSVExportTool(pluginmgr.Tool):
def start(cls):
c = CSVExporter()
c.start()


# TODO: add support to import from the command line
2 changes: 1 addition & 1 deletion bauble/plugins/plants/taxonomy_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def __init__(self, *args, **kwargs):
super(BatchTaxonomicCheckPresenter, self).__init__(*args, **kwargs)
self.refresh_visible_frame()
self.tick_off_list = self.view.widgets.liststore2
self.binomials = [item.str(item, remove_zws=True)
self.binomials = [item.str(remove_zws=True)
for item in self.model.selection
if isinstance(item, Species) and item.sp != '']

Expand Down
12 changes: 9 additions & 3 deletions bauble/plugins/report/mako/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,14 @@ def install(cls, import_defaults=True):
cls.plugin_dir = os.path.join(paths.appdata_dir(), "templates", "mako")
if not os.path.exists(cls.plugin_dir):
os.mkdir(cls.plugin_dir)
cls.templates = []
src_dir = os.path.join(paths.lib_dir(), "plugins", "report", 'mako', 'templates')
for template in list(os.walk(src_dir))[0][2]:
if template.endswith('~'):
continue
if template.startswith('__'):
continue
cls.templates.append(template)

@classmethod
def init(cls):
Expand All @@ -384,9 +392,7 @@ def init(cls):
cls.install() # plugins still not versioned...

src_dir = os.path.join(paths.lib_dir(), "plugins", "report", 'mako', 'templates')
for template in os.listdir(src_dir):
if template.endswith('~'):
continue
for template in cls.templates:
src = os.path.join(src_dir, template)
dst = os.path.join(cls.plugin_dir, template)
if not os.path.exists(dst) and os.path.exists(src):
Expand Down
6 changes: 1 addition & 5 deletions bauble/plugins/report/mako/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,7 @@ def test_format_all_templates(self):
"""
plants = self.session.query(Plant).all()
td = os.path.join(os.path.dirname(__file__), 'templates')
for tn in os.listdir(td):
if tn.endswith('~'):
continue
if tn.startswith('__init__.'):
continue
for tn in MakoFormatterPlugin.templates:
filename = os.path.join(td, tn)
report = MakoFormatterPlugin.format(plants, template=filename)
self.assertTrue(isinstance(report, basestring))
Expand Down
29 changes: 27 additions & 2 deletions bauble/plugins/tag/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,39 @@ def build_menu(self):
has_tags = query.first()
if has_tags:
tags_menu.append(gtk.SeparatorMenuItem())
submenu = {'': [None, tags_menu]} # menuitem and submenu
# corresponding to full item
# path; it is a list because it
# needs to be mutable
def confirm_attach_path(parts):
full_path = ''
parent = tags_menu
while parts:
name = parts.pop()
full_path += name
if full_path not in submenu:
item = gtk.ImageMenuItem(name)
parent.append(item)
submenu[full_path] = [item, None]
if submenu[full_path][1] is None:
take_this = gtk.Menu()
submenu[full_path] = [item, take_this]
item.set_submenu(take_this)
parent = submenu[full_path]
full_path += '/'
try:
for tag in query:
item = gtk.ImageMenuItem(tag.tag)
path = tag.tag.split('/')
tail = path.pop()
head = '/'.join(path)
item = gtk.ImageMenuItem(tail)
submenu[tag.tag] = [item, None]
item.set_image(None)
item.set_always_show_image(True)
self.item_list[tag.tag] = item
item.connect("activate", self.item_activated, tag.tag)
tags_menu.append(item)
confirm_attach_path(path)
submenu[head][1].append(item)
except Exception:
logger.debug(traceback.format_exc())
msg = _('Could not create the tags menus')
Expand Down
50 changes: 50 additions & 0 deletions bauble/test/test_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,53 @@ def test_set_visible_get_visible(self):
view.widget_set_visible('noconnectionlabel', False)
self.assertFalse(view.widget_get_visible('noconnectionlabel'))
self.assertFalse(view.widgets.noconnectionlabel.get_visible())


from dateutil.parser import parse as parse_date
import datetime
import unittest
class TimeStampParserTests(unittest.TestCase):

def test_date_parser_generic(self):
import dateutil
print(help(dateutil.tz))
target = parse_date('2019-01-18 18:20 +0500')
result = parse_date('18 January 2019 18:20 +0500')
self.assertEquals(result, target)
result = parse_date('18:20, 18 January 2019 +0500')
self.assertEquals(result, target)
result = parse_date('18:20+0500, 18 January 2019')
self.assertEquals(result, target)
result = parse_date('18:20+0500, 18 Jan 2019')
self.assertEquals(result, target)
result = parse_date('18:20+0500, 2019-01-18')
self.assertEquals(result, target)
result = parse_date('18:20+0500, 1/18 2019')
self.assertEquals(result, target)
result = parse_date('18:20+0500, 18/1 2019')
self.assertEquals(result, target)

def test_date_parser_ambiguous(self):
## defaults to European: day, month, year - FAILS
#result = parse_date('5 1 4')
#self.assertEquals(result, datetime.datetime(2004, 1, 5, 0, 0))
# explicit, American: month, day, year
result = parse_date('5 1 4', dayfirst=False, yearfirst=False)
self.assertEquals(result, datetime.datetime(2004, 5, 1, 0, 0))
# explicit, European: day, month, year
result = parse_date('5 1 4', dayfirst=True, yearfirst=False)
self.assertEquals(result, datetime.datetime(2004, 1, 5, 0, 0))
# explicit, Japanese: year, month, day (month, day, year)
result = parse_date('5 1 4', dayfirst=False, yearfirst=True)
self.assertEquals(result, datetime.datetime(2005, 1, 4, 0, 0))
## explicit, illogical: year, day, month - FAILS
#result = parse_date('5 1 4', dayfirst=True, yearfirst=True)
#self.assertEquals(result, datetime.datetime(2005, 4, 1, 0, 0))

def test_date_parser_365(self):
target = datetime.datetime(2014, 1, 1, 20)
result = parse_date('2014-01-01 20')
self.assertEquals(result, target)
target = parse_date('2014-01-01 20:00 +0000')
result = parse_date('2014-01-01 20+0')
self.assertEquals(result, target)
4 changes: 2 additions & 2 deletions bauble/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -771,8 +771,8 @@ def on_help_menu_about(self, widget, data=None):
about.set_copyright(_(u'Copyright © by its contributors.'))

import codecs
with codecs.open(os.path.join(paths.installation_dir(), 'share',
'LICENSE.ghini')) as f:
with codecs.open(os.path.join(paths.installation_dir(), 'share', 'ghini',
'LICENSE')) as f:
license = f.read()
about.set_license(license) # not translated
about.set_comments(_('This version installed on: %s\n'
Expand Down
2 changes: 1 addition & 1 deletion bauble/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
# The Ghini version.
# major, minor, revision version tuple

version = "1.0.82" # :bump
version = "1.0.85" # :bump
2 changes: 1 addition & 1 deletion data/ghini.desktop
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[Desktop Entry]
Encoding=UTF-8
Name=Ghini
Version=1.0.82 # :bump
Version=1.0.85 # :bump
Comment=An application for managing botanical collections
Terminal=False
Icon=ghini
Expand Down
47 changes: 47 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
ghini.desktop (1.0.85-1) unstable; urgency=medium

* merging with upstream.

-- Mario Frasca <[email protected]> Thu, 31 May 2018 11:20:00 -0500

ghini.desktop (1.0.84-1) unstable; urgency=medium

* merging with upstream.

-- Mario Frasca <[email protected]> Fri, 25 May 2018 10:30:00 -0500

ghini.desktop (1.0.83-2) unstable; urgency=medium

* updating to upstream, which is now mostly compatible with Python3

-- Mario Frasca <[email protected]> Fri, 25 May 2018 10:28:27 -0500

ghini.desktop (1.0.83-1) unstable; urgency=medium

* Initial release

-- Mario Frasca <[email protected]> Fri, 18 May 2018 10:28:27 -0500

bauble (1.0.56-4) unstable; urgency=medium

* correcting timestamp and shortening comment

-- Mario Frasca <[email protected]> Thu, 17 May 2018 18:32:24 -0500

bauble (1.0.56-3) unstable; urgency=medium

* correcting bauble.desktop (removing redundant encoding and adding keywords); and control (priority: optional).

-- Mario Frasca <[email protected]> Thu, 17 May 2018 17:08:58 -0500

bauble (1.0.56-2) unstable; urgency=medium

* solving QA issues that became visible after uploading to mentors.

-- Mario Frasca <[email protected]> Thu, 17 May 2018 17:08:58 -0500

bauble (1.0.56-1) unstable; urgency=medium

* Initial release (Closes: #755185)

-- Mario Frasca <[email protected]> Thu, 17 May 2018 13:18:11 -0500
18 changes: 18 additions & 0 deletions debian/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Source: ghini.desktop
Section: science
Priority: optional
Maintainer: Mario Frasca <[email protected]>
Build-Depends: debhelper (>= 9), python:any
Standards-Version: 3.9.8
Homepage: https://ghini.github.io

Package: ghini.desktop
Architecture: all
Depends: python-fibra, python-dateutil, python-pyqrcode, xdg-utils, python-egenix-mxdatetime, python-sqlalchemy (>= 0.6), python-lxml (>= 2.0), python-pyparsing, python-gtk2 (>= 2.12), librsvg2-common, python-glade2, python-gdata (>= 1.1.1), python-mako (>= 0.2.2), python-pysqlite2 (>= 2.3.2) | python-mysqldb | python-psycopg2, python:any (>= 2.7.5-5~)
Recommends: python-mysqldb | python-psycopg2
Description: biodiversity collection manager software application
Bauble is a software application to help you manage a collection of
botanical specimens. It is intended to be used by botanic gardens,
herbaria, arboreta, etc. to manage their collection information.
It is a open, free, cross-platform alternative to BG-Base and
similar software.
42 changes: 42 additions & 0 deletions debian/copyright
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: ghini.desktop
Source: <http://github.com/Ghini/ghini.desktop>

Files: *
Copyright: 2004-2011 Brett Adams
2014-2018 Mario Frasca
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

Files: debian/*
Copyright: 2018 Mario Frasca <[email protected]>
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
Loading

0 comments on commit ad9ce21

Please sign in to comment.