Skip to content

Commit

Permalink
Merge branch 'ghini-1.0-dev' into ghini-1.0, as 1.0.86
Browse files Browse the repository at this point in the history
  • Loading branch information
mfrasca committed Jun 6, 2018
2 parents ad9ce21 + 46663b5 commit 62cf2c8
Show file tree
Hide file tree
Showing 20 changed files with 469 additions and 399 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ env/
build/
develop-eggs/
dist/
ghini-runtime/
downloads/
eggs/
.eggs/
Expand Down
16 changes: 3 additions & 13 deletions bauble/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,7 @@ def pb_release():
gui.progressbar.hide()
gui.set_busy(False)

def main_is_frozen():
"""
Return True if we are running in a py2exe environment, else
return False
"""
return (hasattr(sys, "frozen") or # new py2exe
hasattr(sys, "importers") or # old py2exe
imp.is_frozen("__main__")) # tools/freeze


if main_is_frozen(): # main is frozen
if paths.main_is_frozen(): # main is frozen
# put library.zip first in the path when using py2exe so libxml2
# gets imported correctly,
zipfile = sys.path[-1]
Expand Down Expand Up @@ -240,7 +230,7 @@ def main(uri=None):

# a hack to write stderr and stdout to a file in a py2exe environment
# prevents failed attempts at creating ghini.exe.log
if main_is_frozen():
if paths.main_is_frozen():
_stdout = os.path.join(paths.user_dir(), 'stdout.log')
_stderr = os.path.join(paths.user_dir(), 'stderr.log')
sys.stdout = open(_stdout, 'w')
Expand Down Expand Up @@ -288,7 +278,7 @@ def main(uri=None):

import gtk.gdk
import pygtk
if not main_is_frozen():
if not paths.main_is_frozen():
pygtk.require("2.0")

display = gtk.gdk.display_get_default()
Expand Down
38 changes: 28 additions & 10 deletions bauble/connmgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ def show_message_box():
% type(e), e)


def make_absolute(path):
if path.startswith('./') or path.startswith('.\\'):
path = os.path.join(paths.appdata_dir(), path[2:])
return path


class ConnMgrPresenter(GenericEditorPresenter):
"""
The main class that starts the connection manager GUI.
Expand Down Expand Up @@ -265,7 +271,7 @@ def __init__(self, view=None):
except:
pass

from bauble import main_is_frozen
from bauble.paths import main_is_frozen
# Don't check for new versions if we are in a py2exe environment
if not main_is_frozen():
from threading import Thread
Expand All @@ -283,6 +289,7 @@ def on_file_btnbrowse_clicked(self, *args):
buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,
gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
last_folder=last_folder, target='file_entry')
self.replace_leading_appdata('file_entry')

def on_pictureroot_btnbrowse_clicked(self, *args):
previously = self.view.widget_get_value('pictureroot_entry')
Expand All @@ -293,6 +300,7 @@ def on_pictureroot_btnbrowse_clicked(self, *args):
buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,
gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
last_folder=last_folder, target='pictureroot_entry')
self.replace_leading_appdata('pictureroot_entry')

def on_pictureroot2_btnbrowse_clicked(self, *args):
previously = self.view.widget_get_value('pictureroot2_entry')
Expand All @@ -303,6 +311,14 @@ def on_pictureroot2_btnbrowse_clicked(self, *args):
buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,
gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
last_folder=last_folder, target='pictureroot2_entry')
self.replace_leading_appdata('pictureroot2_entry')

def replace_leading_appdata(self, entry):
value = self.view.widget_get_value(entry).replace('\\', '/')
if value.startswith(paths.appdata_dir().replace('\\', '/')):
value = os.path.join('.', value[len(paths.appdata_dir()) + 1:])
value = os.path.join(*value.split('/'))
self.view.widget_set_value(entry, value)

def refresh_view(self):
GenericEditorPresenter.refresh_view(self)
Expand Down Expand Up @@ -345,8 +361,8 @@ def on_dialog_response(self, dialog, response, data=None):
if not valid:
self.view.run_message_dialog(msg, gtk.MESSAGE_ERROR)
if valid:
## picture root is also made available in global setting
prefs.prefs[prefs.picture_root_pref] = settings['pictures']
# ghini grabs pictures location from global setting
prefs.prefs[prefs.picture_root_pref] = make_absolute(settings['pictures'])
self.save_current_to_prefs()
elif response == gtk.RESPONSE_CANCEL or \
response == gtk.RESPONSE_DELETE_EVENT:
Expand Down Expand Up @@ -486,6 +502,10 @@ def on_name_combo_changed(self, combo, data=None):
self.refresh_view()
self.prev_connection_name = self.connection_name

self.replace_leading_appdata('file_entry')
self.replace_leading_appdata('pictureroot_entry')
self.replace_leading_appdata('pictureroot2_entry')

def get_passwd(self, title=_("Enter your password"), before_main=False):
"""
Show a dialog with and entry and return the value entered.
Expand All @@ -507,7 +527,7 @@ def parameters_to_uri(self, params):
import copy
subs = copy.copy(params)
if params['type'].lower() == "sqlite":
filename = params['file'].replace('\\', '/')
filename = make_absolute(params['file'].replace('\\', '/'))
uri = "sqlite:///" + filename
return uri
subs['type'] = params['type'].lower()
Expand Down Expand Up @@ -545,7 +565,7 @@ def check_parameters_valid(self, params):
msg = None
## first check connection parameters, then pictures path
if params['type'] == 'SQLite':
filename = params['file']
filename = make_absolute(params['file'])
if not os.path.exists(filename):
path, f = os.path.split(filename)
if not os.access(path, os.R_OK):
Expand Down Expand Up @@ -583,7 +603,7 @@ def check_parameters_valid(self, params):
return valid, msg
## now check the params['pictures']
# if it's a file, things are not OK
root = params['pictures']
root = make_absolute(params['pictures'])
thumbs = os.path.join(root, 'thumbs')
# root should exist as a directory
if os.path.exists(root):
Expand All @@ -608,10 +628,8 @@ def get_params(self, new=None):
if self.dbtype == 'SQLite':
if self.use_defaults is True:
name = new or self.connection_name
self.filename = os.path.join(
paths.appdata_dir(), name + '.db')
self.pictureroot = os.path.join(
paths.appdata_dir(), name)
self.filename = os.path.join('.', name + '.db')
self.pictureroot = os.path.join('.', name)
result = {'file': self.filename,
'default': self.use_defaults,
'pictures': self.pictureroot}
Expand Down
38 changes: 32 additions & 6 deletions bauble/paths.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2005,2006,2007,2008,2009 Brett Adams <brett@belizebotanic.org>
# Copyright (c) 2012-2016 Mario Frasca <mario@anche.no>
# Copyright (c) 2012-2016,2018 Mario Frasca <mario@anche.no>
# Copyright (c) 2016 Ross Demuth <rossdemuth123@gmail.com>
#
# This file is part of ghini.desktop.
Expand All @@ -26,13 +26,13 @@
"""
import os
import sys
import logging
logger = logging.getLogger(__name__)


def main_is_frozen():
"""
Returns True/False if Ghini is being run from a py2exe
executable. This method duplicates bauble.main_is_frozen in order
to make paths.py not depend on any other Bauble modules.
"""tell whether Ghini is being run from a py2exe executable.
"""
import imp
return (hasattr(sys, "frozen") or # new py2exe
Expand Down Expand Up @@ -116,7 +116,9 @@ def appdata_dir():
"""
if sys.platform == "win32":
if 'APPDATA' in os.environ:
if is_portable_installation():
d = os.path.join(main_dir(), 'Appdata')
elif 'APPDATA' in os.environ:
d = os.path.join(os.environ["APPDATA"], "Bauble")
elif 'USERPROFILE' in os.environ:
d = os.path.join(os.environ['USERPROFILE'], 'Application Data',
Expand All @@ -139,3 +141,27 @@ def appdata_dir():
raise Exception('Could not get path for user settings: '
'unsupported platform')
return os.path.abspath(d)


def is_portable_installation():
'''tell whether ghini is running on a USB stick
only relevant on Windows
if the installation_dir contains a writable appdata.dir, then we are
running on a USB stick, and we are keeping appdata there.
'''

if sys.platform != "win32":
return False
if not main_is_frozen():
return False
try:
test_file_name = os.path.join(main_dir(), 'Appdata', 'temp.tmp')
with open(test_file_name, "w+") as f:
f.write("test")
os.remove(test_file_name)
return True
except:
return False
3 changes: 1 addition & 2 deletions bauble/pluginmgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@ def load(path=None):
"""

if path is None:
if bauble.main_is_frozen():
#path = os.path.join(paths.lib_dir(), 'library.zip')
if paths.main_is_frozen():
path = os.path.join(paths.main_dir(), 'library.zip')
else:
path = os.path.join(paths.lib_dir(), 'plugins')
Expand Down
1 change: 1 addition & 0 deletions bauble/plugins/tag/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ def edit_callback(tags):
presenter.session.rollback()
else:
presenter.commit_changes()
tags_menu_manager.reset()
presenter.cleanup()
return error_state

Expand Down
7 changes: 4 additions & 3 deletions bauble/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -1012,10 +1012,10 @@ def on_select(self, menuitem, prop):

submenu = menuitem.get_submenu()
if len(submenu.get_children()) == 0:
map(submenu.append, self._get_prop_menuitems(prop.mapper))
map(submenu.append, self._get_prop_menuitems(prop.mapper, prop))
submenu.show_all()

def _get_prop_menuitems(self, mapper):
def _get_prop_menuitems(self, mapper, container=None):
# When looping over iterate_properties leave out properties that
# start with underscore since they are considered private. Separate
# properties in column_properties and relation_properties
Expand All @@ -1024,7 +1024,7 @@ def _get_prop_menuitems(self, mapper):
filter(lambda x: isinstance(x, ColumnProperty)
and not x.key.startswith('_'),
mapper.iterate_properties),
key=lambda k: k.key)
key=lambda k: (k.key!='id', not k.key.endswith('_id'), k.key))
relation_properties = sorted(
filter(lambda x: isinstance(x, RelationProperty)
and not x.key.startswith('_'),
Expand All @@ -1046,6 +1046,7 @@ def _get_prop_menuitems(self, mapper):
item.set_submenu(submenu)
item.connect('select', self.on_select, prop)
items.append(item)

return items


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.85" # :bump
version = "1.0.86" # :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.85 # :bump
Version=1.0.86 # :bump
Comment=An application for managing botanical collections
Terminal=False
Icon=ghini
Expand Down
Loading

0 comments on commit 62cf2c8

Please sign in to comment.