pylint sugar.activity, mostly clean
This commit is contained in:
parent
fa90d50cd9
commit
050e9b54c3
@ -71,13 +71,12 @@ from sugar.graphics.icon import Icon
|
|||||||
from sugar.datastore import datastore
|
from sugar.datastore import datastore
|
||||||
from sugar import wm
|
from sugar import wm
|
||||||
from sugar import profile
|
from sugar import profile
|
||||||
from sugar import _sugarbaseext
|
|
||||||
from sugar import _sugarext
|
from sugar import _sugarext
|
||||||
|
|
||||||
_ = lambda msg: gettext.dgettext('sugar', msg)
|
_ = lambda msg: gettext.dgettext('sugar', msg)
|
||||||
|
|
||||||
SCOPE_PRIVATE = "private"
|
SCOPE_PRIVATE = "private"
|
||||||
SCOPE_INVITE_ONLY = "invite" # shouldn't be shown in UI, it's implicit when you invite somebody
|
SCOPE_INVITE_ONLY = "invite" # shouldn't be shown in UI, it's implicit
|
||||||
SCOPE_NEIGHBORHOOD = "public"
|
SCOPE_NEIGHBORHOOD = "public"
|
||||||
|
|
||||||
J_DBUS_SERVICE = 'org.laptop.Journal'
|
J_DBUS_SERVICE = 'org.laptop.Journal'
|
||||||
@ -85,7 +84,8 @@ J_DBUS_PATH = '/org/laptop/Journal'
|
|||||||
J_DBUS_INTERFACE = 'org.laptop.Journal'
|
J_DBUS_INTERFACE = 'org.laptop.Journal'
|
||||||
|
|
||||||
class ActivityToolbar(gtk.Toolbar):
|
class ActivityToolbar(gtk.Toolbar):
|
||||||
"""The Activity toolbar with the Journal entry title, sharing, Keep and Stop buttons
|
"""The Activity toolbar with the Journal entry title, sharing,
|
||||||
|
Keep and Stop buttons
|
||||||
|
|
||||||
All activities should have this toolbar. It is easiest to add it to your
|
All activities should have this toolbar. It is easiest to add it to your
|
||||||
Activity by using the ActivityToolbox.
|
Activity by using the ActivityToolbox.
|
||||||
@ -177,7 +177,8 @@ class ActivityToolbar(gtk.Toolbar):
|
|||||||
|
|
||||||
def __title_changed_cb(self, entry):
|
def __title_changed_cb(self, entry):
|
||||||
if not self._update_title_sid:
|
if not self._update_title_sid:
|
||||||
self._update_title_sid = gobject.timeout_add(1000, self.__update_title_cb)
|
self._update_title_sid = gobject.timeout_add(
|
||||||
|
1000, self.__update_title_cb)
|
||||||
|
|
||||||
def __update_title_cb(self):
|
def __update_title_cb(self):
|
||||||
title = self.title.get_text()
|
title = self.title.get_text()
|
||||||
@ -219,9 +220,9 @@ class EditToolbar(gtk.Toolbar):
|
|||||||
paste -- the paste button
|
paste -- the paste button
|
||||||
separator -- A separator between undo/redo and copy/paste
|
separator -- A separator between undo/redo and copy/paste
|
||||||
|
|
||||||
This class only provides the 'edit' buttons in a standard layout, your activity
|
This class only provides the 'edit' buttons in a standard layout,
|
||||||
will need to either hide buttons which make no sense for your Activity, or you
|
your activity will need to either hide buttons which make no sense for your
|
||||||
need to connect the button events to your own callbacks:
|
Activity, or you need to connect the button events to your own callbacks:
|
||||||
|
|
||||||
## Example from Read.activity:
|
## Example from Read.activity:
|
||||||
# Create the edit toolbar:
|
# Create the edit toolbar:
|
||||||
@ -273,15 +274,15 @@ class EditToolbar(gtk.Toolbar):
|
|||||||
class ActivityToolbox(Toolbox):
|
class ActivityToolbox(Toolbox):
|
||||||
"""Creates the Toolbox for the Activity
|
"""Creates the Toolbox for the Activity
|
||||||
|
|
||||||
By default, the toolbox contains only the ActivityToolbar. After creating the
|
By default, the toolbox contains only the ActivityToolbar. After creating
|
||||||
toolbox, you can add your activity specific toolbars, for example the
|
the toolbox, you can add your activity specific toolbars, for example the
|
||||||
EditToolbar.
|
EditToolbar.
|
||||||
|
|
||||||
To add the ActivityToolbox to your Activity in MyActivity.__init__() do:
|
To add the ActivityToolbox to your Activity in MyActivity.__init__() do:
|
||||||
|
|
||||||
# Create the Toolbar with the ActivityToolbar:
|
# Create the Toolbar with the ActivityToolbar:
|
||||||
toolbox = activity.ActivityToolbox(self)
|
toolbox = activity.ActivityToolbox(self)
|
||||||
... your code, inserting all other toolbars you need, like EditToolbar ...
|
... your code, inserting all other toolbars you need, like EditToolbar
|
||||||
|
|
||||||
# Add the toolbox to the activity frame:
|
# Add the toolbox to the activity frame:
|
||||||
self.set_toolbox(toolbox)
|
self.set_toolbox(toolbox)
|
||||||
@ -299,7 +300,8 @@ class ActivityToolbox(Toolbox):
|
|||||||
return self._activity_toolbar
|
return self._activity_toolbar
|
||||||
|
|
||||||
class Activity(Window, gtk.Container):
|
class Activity(Window, gtk.Container):
|
||||||
"""This is the base Activity class that all other Activities derive from. This is where your activity starts.
|
"""This is the base Activity class that all other Activities derive from.
|
||||||
|
This is where your activity starts.
|
||||||
|
|
||||||
To get a working Activity:
|
To get a working Activity:
|
||||||
0. Derive your Activity from this class:
|
0. Derive your Activity from this class:
|
||||||
@ -453,12 +455,13 @@ class Activity(Window, gtk.Container):
|
|||||||
self.set_title(self._jobject.metadata['title'])
|
self.set_title(self._jobject.metadata['title'])
|
||||||
|
|
||||||
if self._jobject.metadata.has_key('share-scope'):
|
if self._jobject.metadata.has_key('share-scope'):
|
||||||
share_scope = self._jobject.metadata['share-scope']
|
share_scope = self._jobject.metadata['share-scope']
|
||||||
|
|
||||||
elif create_jobject:
|
elif create_jobject:
|
||||||
logging.debug('Creating a jobject.')
|
logging.debug('Creating a jobject.')
|
||||||
self._jobject = datastore.create()
|
self._jobject = datastore.create()
|
||||||
self._jobject.metadata['title'] = _('%s Activity') % get_bundle_name()
|
title = _('%s Activity') % get_bundle_name()
|
||||||
|
self._jobject.metadata['title'] = title
|
||||||
self.set_title(self._jobject.metadata['title'])
|
self.set_title(self._jobject.metadata['title'])
|
||||||
self._jobject.metadata['title_set_by_user'] = '0'
|
self._jobject.metadata['title_set_by_user'] = '0'
|
||||||
self._jobject.metadata['activity'] = self.get_bundle_id()
|
self._jobject.metadata['activity'] = self.get_bundle_id()
|
||||||
@ -475,7 +478,8 @@ class Activity(Window, gtk.Container):
|
|||||||
self._jobject.metadata['icon-color'] = icon_color
|
self._jobject.metadata['icon-color'] = icon_color
|
||||||
|
|
||||||
self._jobject.file_path = ''
|
self._jobject.file_path = ''
|
||||||
# Cannot call datastore.write async for creates: https://dev.laptop.org/ticket/3071
|
# Cannot call datastore.write async for creates:
|
||||||
|
# https://dev.laptop.org/ticket/3071
|
||||||
datastore.write(self._jobject)
|
datastore.write(self._jobject)
|
||||||
else:
|
else:
|
||||||
self._jobject = None
|
self._jobject = None
|
||||||
@ -487,17 +491,20 @@ class Activity(Window, gtk.Container):
|
|||||||
self._activity_id, mesh_instance, share_scope)
|
self._activity_id, mesh_instance, share_scope)
|
||||||
if mesh_instance is not None:
|
if mesh_instance is not None:
|
||||||
# There's already an instance on the mesh, join it
|
# There's already an instance on the mesh, join it
|
||||||
logging.debug("*** Act %s joining existing mesh instance %r", self._activity_id, mesh_instance)
|
logging.debug("*** Act %s joining existing mesh instance %r",
|
||||||
|
self._activity_id, mesh_instance)
|
||||||
self._shared_activity = mesh_instance
|
self._shared_activity = mesh_instance
|
||||||
self._shared_activity.connect('notify::private',
|
self._shared_activity.connect('notify::private',
|
||||||
self.__privacy_changed_cb)
|
self.__privacy_changed_cb)
|
||||||
self._join_id = self._shared_activity.connect("joined", self.__joined_cb)
|
self._join_id = self._shared_activity.connect(
|
||||||
|
"joined", self.__joined_cb)
|
||||||
if not self._shared_activity.props.joined:
|
if not self._shared_activity.props.joined:
|
||||||
self._shared_activity.join()
|
self._shared_activity.join()
|
||||||
else:
|
else:
|
||||||
self.__joined_cb(self._shared_activity, True, None)
|
self.__joined_cb(self._shared_activity, True, None)
|
||||||
elif share_scope != SCOPE_PRIVATE:
|
elif share_scope != SCOPE_PRIVATE:
|
||||||
logging.debug("*** Act %s no existing mesh instance, but used to be shared, will share" % self._activity_id)
|
logging.debug("*** Act %s no existing mesh instance, but used to " \
|
||||||
|
"be shared, will share" % self._activity_id)
|
||||||
# no existing mesh instance, but activity used to be shared, so
|
# no existing mesh instance, but activity used to be shared, so
|
||||||
# restart the share
|
# restart the share
|
||||||
if share_scope == SCOPE_INVITE_ONLY:
|
if share_scope == SCOPE_INVITE_ONLY:
|
||||||
@ -569,7 +576,8 @@ class Activity(Window, gtk.Container):
|
|||||||
store activity related data that doesn't pertain to the current
|
store activity related data that doesn't pertain to the current
|
||||||
execution of the activity and thus cannot go into the DataStore.
|
execution of the activity and thus cannot go into the DataStore.
|
||||||
|
|
||||||
Currently, this will return something like ~/.sugar/default/MyActivityName/
|
Currently, this will return something like
|
||||||
|
~/.sugar/default/MyActivityName/
|
||||||
|
|
||||||
Activities should ONLY save settings, user preferences and other data
|
Activities should ONLY save settings, user preferences and other data
|
||||||
which isn't specific to a journal item here. If (meta-)data is in anyway
|
which isn't specific to a journal item here. If (meta-)data is in anyway
|
||||||
@ -635,7 +643,8 @@ class Activity(Window, gtk.Container):
|
|||||||
def _cleanup_jobject(self):
|
def _cleanup_jobject(self):
|
||||||
if self._jobject:
|
if self._jobject:
|
||||||
if self._owns_file and os.path.isfile(self._jobject.file_path):
|
if self._owns_file and os.path.isfile(self._jobject.file_path):
|
||||||
logging.debug('_cleanup_jobject: removing %r' % self._jobject.file_path)
|
logging.debug('_cleanup_jobject: removing %r' %
|
||||||
|
self._jobject.file_path)
|
||||||
os.remove(self._jobject.file_path)
|
os.remove(self._jobject.file_path)
|
||||||
self._owns_file = False
|
self._owns_file = False
|
||||||
self._jobject.destroy()
|
self._jobject.destroy()
|
||||||
@ -652,8 +661,8 @@ class Activity(Window, gtk.Container):
|
|||||||
# TODO: Find a way of taking a png out of the pixbuf without saving
|
# TODO: Find a way of taking a png out of the pixbuf without saving
|
||||||
# to a temp file. Impementing gtk.gdk.Pixbuf.save_to_buffer in pygtk
|
# to a temp file. Impementing gtk.gdk.Pixbuf.save_to_buffer in pygtk
|
||||||
# would solve this.
|
# would solve this.
|
||||||
fd, file_path = tempfile.mkstemp('.png')
|
fd, file_path = tempfile.mkstemp('.png')[0]
|
||||||
del fd
|
fd.close()
|
||||||
|
|
||||||
pixbuf.save(file_path, 'png')
|
pixbuf.save(file_path, 'png')
|
||||||
f = open(file_path)
|
f = open(file_path)
|
||||||
@ -713,9 +722,10 @@ class Activity(Window, gtk.Container):
|
|||||||
self._owns_file = True
|
self._owns_file = True
|
||||||
self._jobject.file_path = file_path
|
self._jobject.file_path = file_path
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
pass
|
logging.debug('Activity.write_file is not implemented.')
|
||||||
|
|
||||||
# Cannot call datastore.write async for creates: https://dev.laptop.org/ticket/3071
|
# Cannot call datastore.write async for creates:
|
||||||
|
# https://dev.laptop.org/ticket/3071
|
||||||
if self._jobject.object_id is None:
|
if self._jobject.object_id is None:
|
||||||
datastore.write(self._jobject, transfer_ownership=True)
|
datastore.write(self._jobject, transfer_ownership=True)
|
||||||
else:
|
else:
|
||||||
@ -726,7 +736,8 @@ class Activity(Window, gtk.Container):
|
|||||||
error_handler=self.__save_error_cb)
|
error_handler=self.__save_error_cb)
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
"""Request that the activity 'Keep in Journal' the current state of the activity.
|
"""Request that the activity 'Keep in Journal' the current state
|
||||||
|
of the activity.
|
||||||
|
|
||||||
Activities should not override this method. Instead, like save() do any
|
Activities should not override this method. Instead, like save() do any
|
||||||
copy work that needs to be done in write_file()
|
copy work that needs to be done in write_file()
|
||||||
@ -763,7 +774,8 @@ class Activity(Window, gtk.Container):
|
|||||||
self._pservice.disconnect(self._share_id)
|
self._pservice.disconnect(self._share_id)
|
||||||
self._share_id = None
|
self._share_id = None
|
||||||
if not success:
|
if not success:
|
||||||
logging.debug('Share of activity %s failed: %s.' % (self._activity_id, err))
|
logging.debug('Share of activity %s failed: %s.' %
|
||||||
|
(self._activity_id, err))
|
||||||
return
|
return
|
||||||
|
|
||||||
logging.debug('Share of activity %s successful, PS activity is %r.',
|
logging.debug('Share of activity %s successful, PS activity is %r.',
|
||||||
@ -788,7 +800,8 @@ class Activity(Window, gtk.Container):
|
|||||||
buddy_key = self._invites_queue.pop()
|
buddy_key = self._invites_queue.pop()
|
||||||
buddy = self._pservice.get_buddy(buddy_key)
|
buddy = self._pservice.get_buddy(buddy_key)
|
||||||
if buddy:
|
if buddy:
|
||||||
self._shared_activity.invite(buddy, '', self._invite_response_cb)
|
self._shared_activity.invite(
|
||||||
|
buddy, '', self._invite_response_cb)
|
||||||
else:
|
else:
|
||||||
logging.error('Cannot invite %s, no such buddy.' % buddy_key)
|
logging.error('Cannot invite %s, no such buddy.' % buddy_key)
|
||||||
|
|
||||||
@ -854,9 +867,9 @@ class Activity(Window, gtk.Container):
|
|||||||
def close(self, force=False, skip_save=False):
|
def close(self, force=False, skip_save=False):
|
||||||
"""Request that the activity be stopped and saved to the Journal
|
"""Request that the activity be stopped and saved to the Journal
|
||||||
|
|
||||||
Activities should not override this method, but should implement write_file() to
|
Activities should not override this method, but should implement
|
||||||
do any state saving instead. If the application wants to control wether it can
|
write_file() to do any state saving instead. If the application wants
|
||||||
close, it should override can_close().
|
to control wether it can close, it should override can_close().
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not force:
|
if not force:
|
||||||
@ -866,7 +879,7 @@ class Activity(Window, gtk.Container):
|
|||||||
try:
|
try:
|
||||||
if not skip_save:
|
if not skip_save:
|
||||||
self.save()
|
self.save()
|
||||||
except:
|
except Exception:
|
||||||
logging.info(traceback.format_exc())
|
logging.info(traceback.format_exc())
|
||||||
self._display_keep_failed_dialog()
|
self._display_keep_failed_dialog()
|
||||||
return
|
return
|
||||||
|
@ -58,7 +58,7 @@ _children_pid = []
|
|||||||
|
|
||||||
def _sigchild_handler(signum, frame):
|
def _sigchild_handler(signum, frame):
|
||||||
for child_pid in _children_pid:
|
for child_pid in _children_pid:
|
||||||
pid, status = os.waitpid(child_pid, os.WNOHANG)
|
pid = os.waitpid(child_pid, os.WNOHANG)[0]
|
||||||
if pid > 0:
|
if pid > 0:
|
||||||
_children_pid.remove(pid)
|
_children_pid.remove(pid)
|
||||||
|
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
# Boston, MA 02111-1307, USA.
|
# Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
from sugar.presence import presenceservice
|
|
||||||
|
|
||||||
class ActivityHandle(object):
|
class ActivityHandle(object):
|
||||||
"""Data structure storing simple activity metadata"""
|
"""Data structure storing simple activity metadata"""
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -68,16 +68,15 @@ class _ManifestFileList(_DefaultFileList):
|
|||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def _extract_bundle(source_file, dest_dir):
|
def _extract_bundle(source_file, dest_dir):
|
||||||
if not os.path.exists(dest_dir):
|
if not os.path.exists(dest_dir):
|
||||||
os.mkdir(dest_dir)
|
os.mkdir(dest_dir)
|
||||||
|
|
||||||
zf = zipfile.ZipFile(source_file)
|
zf = zipfile.ZipFile(source_file)
|
||||||
|
|
||||||
for i, name in enumerate(zf.namelist()):
|
for name in zf.namelist():
|
||||||
path = os.path.join(dest_dir, name)
|
path = os.path.join(dest_dir, name)
|
||||||
|
if not os.path.exists(os.path.dirname(path)):
|
||||||
if not os.path.exists(os.path.dirname(path)):
|
os.makedirs(os.path.dirname(path))
|
||||||
os.makedirs(os.path.dirname(path))
|
|
||||||
|
|
||||||
outfile = open(path, 'wb')
|
outfile = open(path, 'wb')
|
||||||
outfile.write(zf.read(name))
|
outfile.write(zf.read(name))
|
||||||
@ -132,7 +131,7 @@ def cmd_dev():
|
|||||||
if os.path.islink(bundle_path):
|
if os.path.islink(bundle_path):
|
||||||
print 'ERROR - The bundle has been already setup for development.'
|
print 'ERROR - The bundle has been already setup for development.'
|
||||||
else:
|
else:
|
||||||
print 'ERROR - A bundle with the same name is already installed.'
|
print 'ERROR - A bundle with the same name is already installed.'
|
||||||
|
|
||||||
def _get_file_list(manifest):
|
def _get_file_list(manifest):
|
||||||
if os.path.isfile(manifest):
|
if os.path.isfile(manifest):
|
||||||
|
@ -68,9 +68,12 @@ class ActivityRegistry(gobject.GObject):
|
|||||||
_ACTIVITY_REGISTRY_PATH,
|
_ACTIVITY_REGISTRY_PATH,
|
||||||
follow_name_owner_changes = True)
|
follow_name_owner_changes = True)
|
||||||
self._registry = dbus.Interface(bus_object, _ACTIVITY_REGISTRY_IFACE)
|
self._registry = dbus.Interface(bus_object, _ACTIVITY_REGISTRY_IFACE)
|
||||||
self._registry.connect_to_signal('ActivityAdded', self._activity_added_cb)
|
self._registry.connect_to_signal('ActivityAdded',
|
||||||
self._registry.connect_to_signal('ActivityRemoved', self._activity_removed_cb)
|
self._activity_added_cb)
|
||||||
self._registry.connect_to_signal('ActivityChanged', self._activity_changed_cb)
|
self._registry.connect_to_signal('ActivityRemoved',
|
||||||
|
self._activity_removed_cb)
|
||||||
|
self._registry.connect_to_signal('ActivityChanged',
|
||||||
|
self._activity_changed_cb)
|
||||||
|
|
||||||
# Two caches fo saving some travel across dbus.
|
# Two caches fo saving some travel across dbus.
|
||||||
self._service_name_to_activity_info = {}
|
self._service_name_to_activity_info = {}
|
||||||
@ -90,7 +93,6 @@ class ActivityRegistry(gobject.GObject):
|
|||||||
|
|
||||||
def _get_activities_cb(self, reply_handler, info_list):
|
def _get_activities_cb(self, reply_handler, info_list):
|
||||||
result = []
|
result = []
|
||||||
i = 0
|
|
||||||
for info_dict in info_list:
|
for info_dict in info_list:
|
||||||
result.append(_activity_info_from_dict(info_dict))
|
result.append(_activity_info_from_dict(info_dict))
|
||||||
|
|
||||||
@ -104,12 +106,15 @@ class ActivityRegistry(gobject.GObject):
|
|||||||
|
|
||||||
def get_activities_async(self, reply_handler=None, error_handler=None):
|
def get_activities_async(self, reply_handler=None, error_handler=None):
|
||||||
if not reply_handler:
|
if not reply_handler:
|
||||||
logging.error('Function get_activities_async called without a reply handler. Can not run.')
|
logging.error('Function get_activities_async called' \
|
||||||
|
'without a reply handler. Can not run.')
|
||||||
return
|
return
|
||||||
|
|
||||||
self._registry.GetActivities(
|
self._registry.GetActivities(
|
||||||
reply_handler=lambda info_list:self._get_activities_cb(reply_handler, info_list),
|
reply_handler=lambda info_list: \
|
||||||
error_handler=lambda e:self._get_activities_error_cb(error_handler, e))
|
self._get_activities_cb(reply_handler, info_list),
|
||||||
|
error_handler=lambda e: \
|
||||||
|
self._get_activities_error_cb(error_handler, e))
|
||||||
|
|
||||||
def get_activity(self, service_name):
|
def get_activity(self, service_name):
|
||||||
if self._service_name_to_activity_info.has_key(service_name):
|
if self._service_name_to_activity_info.has_key(service_name):
|
||||||
|
Loading…
Reference in New Issue
Block a user