Python cleanup

This commit is contained in:
Sean Davis 2014-01-25 17:21:53 -05:00
parent 653fc5a108
commit 527fa8cf4c
7 changed files with 359 additions and 280 deletions

View File

@ -21,36 +21,38 @@ from locale import gettext as _
import logging
logger = logging.getLogger('mugshot')
from gi.repository import Gtk, GdkX11, GObject, Gst, GstVideo, GdkPixbuf
from gi.repository import Gtk, GObject, Gst, GdkPixbuf
import cairo
import tempfile, os
import tempfile
import os
from mugshot_lib.CameraDialog import CameraDialog
def draw_message(widget, message, ctx):
"""Draw a message (including newlines) vertically centered on a cairo context."""
"""Draw a message (including newlines) vertically centered on a cairo
context."""
split_msg = message.split('\n')
# Get the height and width of the drawing area.
alloc = widget.get_allocation()
height = alloc.height
width = alloc.width
# Make the background black.
ctx.set_source_rgb(0,0,0)
ctx.set_source_rgb(0, 0, 0)
ctx.paint()
# Set the font details.
font_size = 20
font_color = (255,255,255)
font_color = (255, 255, 255)
font_name = "Sans"
row_spacing = 6
left_spacing = 10
# Get start position
message_height = (len(split_msg)*font_size)+len(split_msg)-1-14
current_pos = (height-message_height)/2
message_height = (len(split_msg) * font_size) + len(split_msg) - 15
current_pos = (height - message_height) / 2
# Draw the message to the drawing area.
ctx.set_source_rgb(*font_color)
@ -59,14 +61,16 @@ def draw_message(widget, message, ctx):
ctx.set_font_size(font_size)
for line in split_msg:
ctx.move_to(left_spacing,current_pos)
ctx.move_to(left_spacing, current_pos)
ctx.show_text(line)
current_pos = current_pos + font_size + row_spacing
class CameraMugshotDialog(CameraDialog):
"""Camera Capturing Dialog"""
__gtype_name__ = "CameraMugshotDialog"
def finish_initializing(self, builder): # pylint: disable=E1002
def finish_initializing(self, builder): # pylint: disable=E1002
"""Set up the camera dialog"""
super(CameraMugshotDialog, self).finish_initializing(builder)
@ -76,7 +80,7 @@ class CameraMugshotDialog(CameraDialog):
# Pack the video widget into the dialog.
vbox = builder.get_object('camera_box')
self.video_window = Gtk.DrawingArea()
self.video_window.connect("realize",self.__on_video_window_realized)
self.video_window.connect("realize", self.__on_video_window_realized)
vbox.pack_start(self.video_window, True, True, 0)
self.video_window.show()
@ -94,9 +98,12 @@ class CameraMugshotDialog(CameraDialog):
else:
devices = []
for device in os.listdir('/dev/'):
if device.startswith('video'): devices.append(device)
logger.error(_('Camera failed to load. Devices: %s') % '; '.join(devices))
self.draw_handler = self.video_window.connect('draw', self.on_failed_draw)
if device.startswith('video'):
devices.append(device)
logger.error(_('Camera failed to load. Devices: %s') %
'; '.join(devices))
self.draw_handler = self.video_window.connect('draw',
self.on_failed_draw)
self.realized = True
# Essential widgets
@ -123,10 +130,13 @@ class CameraMugshotDialog(CameraDialog):
# Redefine on_draw to blank the drawing area next time.
def on_draw(self, widget, ctx):
ctx.set_source_rgb(0,0,0)
"""Redefinition of on_draw to blank the drawing area next time."""
ctx.set_source_rgb(0, 0, 0)
ctx.paint()
# Redefine on_draw once more to do nothing else.
def on_draw(self, widget, ctx):
"""Redefinition of on_draw no longer do anything."""
pass
def play(self):
@ -135,7 +145,8 @@ class CameraMugshotDialog(CameraDialog):
if not self.realized:
self._set_video_window_id()
if not self.realized:
logger.error(_("Cannot display camera output. Ignoring play command"))
logger.error(_("Cannot display camera output."
"Ignoring play command"))
else:
if self.camerabin:
self.camerabin.set_state(Gst.State.PLAYING)
@ -223,7 +234,8 @@ class CameraMugshotDialog(CameraDialog):
if message_name == "prepare-window-handle":
imagesink = message.src
imagesink.set_property("force-aspect-ratio", True)
imagesink.set_window_handle(self.video_window.get_window().get_xid())
imagesink.set_window_handle(
self.video_window.get_window().get_xid())
def __on_video_window_realized(self, widget, data=None):
"""Internal signal handler, used to set up the xid for the drawing area
@ -233,7 +245,7 @@ class CameraMugshotDialog(CameraDialog):
def _set_video_window_id(self):
"""Set the window ID only if not previously configured."""
if not self.realized and self.video_window.get_window() is not None:
x = self.video_window.get_window().get_xid()
self.video_window.get_window().get_xid()
self.realized = True
def on_camera_record_clicked(self, widget):
@ -311,10 +323,10 @@ class CameraMugshotDialog(CameraDialog):
# Calculate a balanced center.
if width > height:
start_x = (width-height)/2
start_x = (width - height) / 2
width = height
else:
start_y = (height-width)/2
start_y = (height - width) / 2
height = width
# Create a new cropped pixbuf.
@ -330,9 +342,11 @@ class CameraMugshotDialog(CameraDialog):
# Signals used by CameraMugshotDialog:
# image-captured: emitted when the camera is done capturing an image.
# apply: emitted when the apply button has been pressed and there is a new file saved for use.
__gsignals__ = {'image-captured' : (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
(GObject.TYPE_PYOBJECT,)),
'apply' : (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (GObject.TYPE_STRING,))
}
# apply: emitted when the apply button has been pressed and there is a
# new file saved for use.
__gsignals__ = {'image-captured': (GObject.SIGNAL_RUN_LAST,
GObject.TYPE_NONE,
(GObject.TYPE_PYOBJECT,)),
'apply': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
(GObject.TYPE_STRING,))
}

View File

@ -28,7 +28,7 @@ import dbus
import tempfile
from gi.repository import Gtk, Gdk, GdkPixbuf # pylint: disable=E0611
from gi.repository import Gtk, GdkPixbuf # pylint: disable=E0611
import logging
logger = logging.getLogger('mugshot')
@ -44,16 +44,18 @@ libreoffice_prefs = os.path.join(home, '.config', 'libreoffice', '4', 'user',
pidgin_prefs = os.path.join(home, '.purple', 'prefs.xml')
faces_dir = '/usr/share/pixmaps/faces/'
def which(command):
'''Use the system command which to get the absolute path for the given
command.'''
command = subprocess.Popen(['which', command], \
command = subprocess.Popen(['which', command],
stdout=subprocess.PIPE).stdout.read().strip()
if command == '':
logger.debug('Command "%s" could not be found.' % command)
return None
return command
def has_running_process(name):
"""Check for a running process, return True if any listings are found."""
command = 'ps -ef | grep " %s" | grep -v "grep" | wc -l' % name
@ -61,6 +63,7 @@ def has_running_process(name):
shell=True).stdout.read().strip()
return int(n) > 0
def has_gstreamer_camerabin_support():
"""Return True if gstreamer1.0 camerabin element is available."""
process = subprocess.Popen(["gst-inspect-1.0", "camerabin"],
@ -69,9 +72,13 @@ def has_gstreamer_camerabin_support():
process.communicate()
has_support = process.returncode == 0
if not has_support:
logger.debug('camerabin element unavailable. Do you have gstreamer1.0-plugins-good installed?')
element = 'camerabin'
plugin = 'gstreamer1.0-plugins-good'
logger.debug('%s element unavailable. '
'Do you have %s installed?' % (element, plugin))
return has_support
def has_gstreamer_camerasrc_support():
"""Return True if gstreamer1.0 v4l2src element is available."""
process = subprocess.Popen(["gst-inspect-1.0", "v4l2src"],
@ -80,9 +87,13 @@ def has_gstreamer_camerasrc_support():
process.communicate()
has_support = process.returncode == 0
if not has_support:
logger.debug('v4l2src element unavailable. Do you have gstreamer1.0-plugins-good installed?')
element = 'v4l2src'
plugin = 'gstreamer1.0-plugins-good'
logger.debug('%s element unavailable. '
'Do you have %s installed?' % (element, plugin))
return has_support
def get_camera_installed():
"""Return True if /dev/video0 exists."""
if not os.path.exists('/dev/video0'):
@ -90,6 +101,7 @@ def get_camera_installed():
return False
return True
def get_has_camera_support():
"""Return True if cameras are fully supported by this application."""
if not get_camera_installed():
@ -102,10 +114,12 @@ def get_has_camera_support():
return False
return True
def detach_cb(menu, widget):
'''Detach a widget from its attached widget.'''
menu.detach()
def get_entry_value(entry_widget):
"""Get the value from one of the Mugshot entries."""
# Get the text from an entry, changing none to ''
@ -114,6 +128,7 @@ def get_entry_value(entry_widget):
value = ''
return value
def get_confirmation_dialog(parent, primary_message, secondary_message,
icon_name=None):
"""Display a confirmation (yes/no) dialog configured with primary and
@ -130,6 +145,7 @@ def get_confirmation_dialog(parent, primary_message, secondary_message,
dialog.destroy()
return response == Gtk.ResponseType.YES
def menu_position(self, menu, data=None, something_else=None):
'''Position a menu at the bottom of its attached widget'''
widget = menu.get_attach_widget()
@ -141,11 +157,13 @@ def menu_position(self, menu, data=None, something_else=None):
y = window_pos[1] + allocation.y + allocation.height
return (x, y, True)
# See mugshot_lib.Window.py for more details about how this class works
class MugshotWindow(Window):
"""Mugshot GtkWindow"""
__gtype_name__ = "MugshotWindow"
def finish_initializing(self, builder): # pylint: disable=E1002
def finish_initializing(self, builder): # pylint: disable=E1002
"""Set up the main window"""
super(MugshotWindow, self).finish_initializing(builder)
self.set_wmclass("Mugshot", "Mugshot")
@ -159,8 +177,8 @@ class MugshotWindow(Window):
self.image_menu.attach_to_widget(self.image_button, detach_cb)
self.image_from_camera = builder.get_object('image_from_camera')
image_from_browse = builder.get_object('image_from_browse')
image_from_browse.set_visible( os.path.exists(faces_dir) and \
len(os.listdir(faces_dir)) > 0 )
image_from_browse.set_visible(os.path.exists(faces_dir) and
len(os.listdir(faces_dir)) > 0)
# Entry widgets (chfn)
self.first_name_entry = builder.get_object('first_name')
@ -222,8 +240,10 @@ class MugshotWindow(Window):
initials = first_name[0]
# If the variables are defined as 'none', use blank for cleanliness.
if home_phone == 'none': home_phone = ''
if office_phone == 'none': office_phone = ''
if home_phone == 'none':
home_phone = ''
if office_phone == 'none':
office_phone = ''
# Get dconf settings
logger.debug('Getting initials, email, and fax from dconf')
@ -270,7 +290,7 @@ class MugshotWindow(Window):
changes."""
logger.debug('Applying changes...')
if self.get_chfn_details_updated():
returns = self.save_chfn_details()
self.save_chfn_details()
if self.get_libreoffice_details_updated():
self.set_libreoffice_data()
@ -315,6 +335,7 @@ class MugshotWindow(Window):
self.image_button.set_active(False)
def on_camera_dialog_apply(self, widget, data=None):
"""Commit changes when apply is clicked."""
self.updated_image = data
self.set_user_image(data)
@ -449,7 +470,7 @@ class MugshotWindow(Window):
child.sendline('')
except pexpect.TIMEOUT:
# Password was incorrect, or sudo rights not granted
logger.debug('Timeout reached, password was incorrect or sudo ' \
logger.debug('Timeout reached, password was incorrect or sudo '
'rights not granted.')
pass
child.close()
@ -624,25 +645,46 @@ class MugshotWindow(Window):
open_prefs.write(line)
if not first_name_updated:
string = '<item oor:path="/org.openoffice.UserProfile/Data"><prop oor:name="givenname" oor:op="fuse"><value>%s</value></prop></item>\n' % first_name
string = \
'<item oor:path="/org.openoffice.UserProfile/Data">'
'<prop oor:name="givenname" oor:op="fuse">'
'<value>%s</value></prop></item>\n' % first_name
open_prefs.write(string)
if not last_name_updated:
string = '<item oor:path="/org.openoffice.UserProfile/Data"><prop oor:name="sn" oor:op="fuse"><value>%s</value></prop></item>\n' % last_name
string = \
'<item oor:path="/org.openoffice.UserProfile/Data">'
'<prop oor:name="sn" oor:op="fuse">'
'<value>%s</value></prop></item>\n' % last_name
open_prefs.write(string)
if not initials_updated:
string = '<item oor:path="/org.openoffice.UserProfile/Data"><prop oor:name="initials" oor:op="fuse"><value>%s</value></prop></item>\n' % initials
string = \
'<item oor:path="/org.openoffice.UserProfile/Data">'
'<prop oor:name="initials" oor:op="fuse">'
'<value>%s</value></prop></item>\n' % initials
open_prefs.write(string)
if not email_updated:
string = '<item oor:path="/org.openoffice.UserProfile/Data"><prop oor:name="mail" oor:op="fuse"><value>%s</value></prop></item>\n' % email
string = \
'<item oor:path="/org.openoffice.UserProfile/Data">'
'<prop oor:name="mail" oor:op="fuse">'
'<value>%s</value></prop></item>\n' % email
open_prefs.write(string)
if not home_phone_updated:
string = '<item oor:path="/org.openoffice.UserProfile/Data"><prop oor:name="homephone" oor:op="fuse"><value>%s</value></prop></item>\n' % home_phone
string = \
'<item oor:path="/org.openoffice.UserProfile/Data">'
'<prop oor:name="homephone" oor:op="fuse">'
'<value>%s</value></prop></item>\n' % home_phone
open_prefs.write(string)
if not office_phone_updated:
string = '<item oor:path="/org.openoffice.UserProfile/Data"><prop oor:name="telephonenumber" oor:op="fuse"><value>%s</value></prop></item>\n' % office_phone
string = \
'<item oor:path="/org.openoffice.UserProfile/Data">'
'<prop oor:name="telephonenumber" oor:op="fuse">'
'<value>%s</value></prop></item>\n' % office_phone
open_prefs.write(string)
if not fax_updated:
string = '<item oor:path="/org.openoffice.UserProfile/Data"><prop oor:name="facsimiletelephonenumber" oor:op="fuse"><value>%s</value></prop></item>\n' % fax
string = \
'<item oor:path="/org.openoffice.UserProfile/Data">'
'<prop oor:name="facsimiletelephonenumber" oor:op="fuse">'
'<value>%s</value></prop></item>\n' % fax
open_prefs.write(string)
open_prefs.write('</oor:items>')
open_prefs.close()
@ -719,12 +761,14 @@ class MugshotWindow(Window):
self.tmpfile = tempfile.NamedTemporaryFile(delete=False)
self.tmpfile.close()
self.updated_image = self.tmpfile.name
self.filechooser_preview_pixbuf.savev(self.updated_image, "png", [], [])
self.filechooser_preview_pixbuf.savev(self.updated_image, "png",
[], [])
logger.debug("Selected %s" % self.updated_image)
self.set_user_image(self.updated_image)
self.chooser.hide()
def on_filechooserdialog_update_preview(self, widget):
"""Update the preview image used in the file chooser."""
filename = widget.get_filename()
if not filename:
self.file_chooser_preview.set_from_icon_name('folder', 128)
@ -743,10 +787,10 @@ class MugshotWindow(Window):
if self.crop_center.get_active():
# Calculate a balanced center.
if width > height:
start_x = (width-height)/2
start_x = (width - height) / 2
width = height
else:
start_y = (height-width)/2
start_y = (height - width) / 2
height = width
elif self.crop_left.get_active():
@ -754,23 +798,26 @@ class MugshotWindow(Window):
if width > height:
width = height
else:
start_y = (height-width)/2
start_y = (height - width) / 2
height = width
elif self.crop_right.get_active():
if width > height:
start_x = width-height
start_x = width - height
width = height
else:
start_y = (height-width)/2
start_y = (height - width) / 2
height = width
# Create a new cropped pixbuf.
self.filechooser_preview_pixbuf = filechooser_pixbuf.new_subpixbuf(start_x, start_y, width, height)
self.filechooser_preview_pixbuf = \
filechooser_pixbuf.new_subpixbuf(start_x, start_y, width, height)
scaled = self.filechooser_preview_pixbuf.scale_simple(128, 128, GdkPixbuf.InterpType.HYPER)
scaled = self.filechooser_preview_pixbuf.scale_simple(128, 128,
GdkPixbuf.InterpType.HYPER)
self.file_chooser_preview.set_from_pixbuf(scaled)
def on_crop_changed(self, widget, data=None):
"""Update the preview image when crop style is modified."""
if widget.get_active():
self.on_filechooserdialog_update_preview(self.chooser)
@ -794,4 +841,3 @@ class MugshotWindow(Window):
"""Enable password submission only when password is not blank."""
self.builder.get_object('password_ok').set_sensitive(
len(widget.get_text()) > 0)

View File

@ -18,7 +18,7 @@
'''Enhances builder connections, provides object to access glade objects'''
from gi.repository import GObject, Gtk # pylint: disable=E0611
from gi.repository import GObject, Gtk # pylint: disable=E0611
import inspect
import functools
@ -46,6 +46,7 @@ class Builder(Gtk.Builder):
'''
def __init__(self):
"""Initialize the builder."""
Gtk.Builder.__init__(self)
self.widgets = {}
self.glade_handler_dict = {}
@ -120,7 +121,7 @@ class Builder(Gtk.Builder):
connection_dict = {}
connection_dict.update(self.glade_handler_dict)
connection_dict.update(callback_handler_dict)
for item in connection_dict.items():
for item in list(connection_dict.items()):
if item[1] is None:
# the handler is missing so reroute to default_handler
handler = functools.partial(
@ -166,17 +167,19 @@ class Builder(Gtk.Builder):
class UiFactory():
''' provides an object with attributes as glade widgets'''
def __init__(self, widget_dict):
"""Initialize the UiFactory."""
self._widget_dict = widget_dict
for (widget_name, widget) in widget_dict.items():
for (widget_name, widget) in list(widget_dict.items()):
setattr(self, widget_name, widget)
# Mangle any non-usable names (like with spaces or dashes)
# into pythonic ones
cannot_message = """cannot bind ui.%s, name already exists
consider using a pythonic name instead of design name '%s'"""
consider_message = """consider using a pythonic name instead of design name '%s'"""
consider_message = """consider using a pythonic name instead of
design name '%s'"""
for (widget_name, widget) in widget_dict.items():
for (widget_name, widget) in list(widget_dict.items()):
pyname = make_pyname(widget_name)
if pyname != widget_name:
if hasattr(self, pyname):
@ -187,7 +190,7 @@ class UiFactory():
def iterator():
'''Support 'for o in self' '''
return iter(widget_dict.values())
return iter(list(widget_dict.values()))
setattr(self, '__iter__', iterator)
def __getitem__(self, name):
@ -212,6 +215,7 @@ def make_pyname(name):
# need to reimplement inspect.getmembers. GObject introspection doesn't
# play nice with it.
def getmembers(obj, check):
"""Reimplementation of getmembers"""
members = []
for k in dir(obj):
try:
@ -260,7 +264,7 @@ def auto_connect_by_name(callback_obj, builder):
callback_handler_dict = dict_from_callback_obj(callback_obj)
for item in builder.widgets.items():
for item in list(builder.widgets.items()):
(widget_name, widget) = item
signal_ids = []
try:
@ -296,7 +300,7 @@ def do_connect(item, signal_name, handler_names,
widget_name, widget = item
for handler_name in handler_names:
target = handler_name in callback_handler_dict.keys()
target = handler_name in list(callback_handler_dict.keys())
connection = (widget_name, signal_name, handler_name)
duplicate = connection in connections
if target and not duplicate:
@ -312,7 +316,7 @@ def log_unconnected_functions(callback_handler_dict, connections):
connected_functions = [x[2] for x in connections]
handler_names = callback_handler_dict.keys()
handler_names = list(callback_handler_dict.keys())
unconnected = [x for x in handler_names if x.startswith('on_')]
for handler_name in connected_functions:

View File

@ -16,13 +16,15 @@
### DO NOT EDIT THIS FILE ###
from gi.repository import Gtk # pylint: disable=E0611
from gi.repository import Gtk # pylint: disable=E0611
import logging
logger = logging.getLogger('mugshot_lib')
from . helpers import get_builder, show_uri, get_help_uri
class CameraDialog(Gtk.Dialog):
"""Camera Dialog"""
__gtype_name__ = "CameraDialog"
def __new__(cls):
@ -54,8 +56,9 @@ class CameraDialog(Gtk.Dialog):
# code for other initialization actions should be added here
def on_btn_close_clicked(self, widget, data=None):
"""Destroy the dialog when closed."""
self.destroy()
def on_btn_help_clicked(self, widget, data=None):
"""Show the help dialog when Help is clicked."""
show_uri(self, "ghelp:%s" % get_help_uri('preferences'))

View File

@ -16,7 +16,7 @@
### DO NOT EDIT THIS FILE ###
from gi.repository import Gio, Gtk # pylint: disable=E0611
from gi.repository import Gio, Gtk # pylint: disable=E0611
import logging
logger = logging.getLogger('mugshot_lib')
@ -24,9 +24,10 @@ import os
from . helpers import get_builder, show_uri, get_help_uri
# This class is meant to be subclassed by MugshotWindow. It provides
# common functions and some boilerplate.
class Window(Gtk.Window):
"""This class is meant to be subclassed by MugshotWindow. It provides
common functions and some boilerplate."""
__gtype_name__ = "Window"
# To construct a new instance of this method, the following notable
@ -60,13 +61,14 @@ class Window(Gtk.Window):
# Get a reference to the builder and set up the signals.
self.builder = builder
self.ui = builder.get_ui(self, True)
self.CameraDialog = None # class
self.camera_dialog = None # instance
self.CameraDialog = None # class
self.camera_dialog = None # instance
self.settings = Gio.Settings("apps.mugshot")
self.settings.connect('changed', self.on_preferences_changed)
def on_help_activate(self, widget, data=None):
"""Show the Help documentation when Help is clicked."""
show_uri(self, "ghelp:%s" % get_help_uri())
def on_menu_camera_activate(self, widget, data=None):
@ -76,8 +78,7 @@ class Window(Gtk.Window):
self.camera_dialog.show()
elif self.CameraDialog is not None:
logger.debug('create new camera_dialog')
self.camera_dialog = self.CameraDialog() # pylint: disable=E1102
#self.camera_dialog.connect('destroy', self.on_camera_dialog_destroyed)
self.camera_dialog = self.CameraDialog() # pylint: disable=E1102
self.camera_dialog.connect('apply', self.on_camera_dialog_apply)
self.camera_dialog.show()
@ -89,5 +90,6 @@ class Window(Gtk.Window):
Gtk.main_quit()
def on_preferences_changed(self, settings, key, data=None):
logger.debug('preference changed: %s = %s' % (key, str(settings.get_value(key))))
"""Log preference updates."""
logger.debug('preference changed: %s = %s' %
(key, str(settings.get_value(key))))

View File

@ -23,7 +23,6 @@ import os
from . mugshotconfig import get_data_file
from . Builder import Builder
from locale import gettext as _
def get_builder(builder_file_name):
"""Return a fully-instantiated Gtk.Builder instance from specified ui
@ -43,25 +42,31 @@ def get_builder(builder_file_name):
return builder
# Owais Lone : To get quick access to icons and stuff.
def get_media_file(media_file_name):
"""Retrieve the filename for the specified file."""
media_filename = get_data_file('media', '%s' % (media_file_name,))
if not os.path.exists(media_filename):
media_filename = None
return "file:///"+media_filename
return "file:///" + media_filename
class NullHandler(logging.Handler):
"""Handle NULL"""
def emit(self, record):
"""Do not emit anything."""
pass
def set_up_logging(opts):
"""Set up the logging formatter."""
# add a handler to prevent basicConfig
root = logging.getLogger()
null_handler = NullHandler()
root.addHandler(null_handler)
formatter = logging.Formatter("%(levelname)s:%(name)s: %(funcName)s() '%(message)s'")
formatter = logging.Formatter("%(levelname)s:%(name)s:"
" %(funcName)s() '%(message)s'")
logger = logging.getLogger('mugshot')
logger_sh = logging.StreamHandler()
@ -80,7 +85,9 @@ def set_up_logging(opts):
if opts.verbose > 1:
lib_logger.setLevel(logging.DEBUG)
def get_help_uri(page=None):
"""Get the URI to be used for Help."""
# help_uri from source tree - default language
here = os.path.dirname(__file__)
help_uri = os.path.abspath(os.path.join(here, '..', 'help', 'C'))
@ -95,11 +102,14 @@ def get_help_uri(page=None):
return help_uri
def show_uri(parent, link):
from gi.repository import Gtk # pylint: disable=E0611
"""Open the URI."""
from gi.repository import Gtk # pylint: disable=E0611
screen = parent.get_screen()
Gtk.show_uri(screen, link, Gtk.get_current_event_time())
def alias(alternative_function_name):
'''see http://www.drdobbs.com/web-development/184406073#l9'''
def decorator(function):

View File

@ -30,7 +30,6 @@ __version__ = '0.1'
import os
from locale import gettext as _
class project_path_not_found(Exception):
"""Raised when we can't find the project directory."""
@ -66,4 +65,5 @@ def get_data_path():
def get_version():
"""Return the program version."""
return __version__