Changes

Jump to navigation Jump to search
deletions and
Line 1: Line 1: −
<noinclude>{{Developers}}{{TOCright}}</noinclude>
+
<noinclude>{{Developers}}</noinclude>__TOC__
    
Sugar activities are usually written in Python using the [http://api.sugarlabs.org/ Python Activity API]. This page documents the underlying mechanism that all activities need to conform to. Activities can be written in any language, as long as it can connect to D-Bus and provide an X11 interface. The discussion below tries to be language-agnostic.
 
Sugar activities are usually written in Python using the [http://api.sugarlabs.org/ Python Activity API]. This page documents the underlying mechanism that all activities need to conform to. Activities can be written in any language, as long as it can connect to D-Bus and provide an X11 interface. The discussion below tries to be language-agnostic.
Line 187: Line 187:  
  (results,count) = datastore.find(query, properties)
 
  (results,count) = datastore.find(query, properties)
   −
It returns the matching object's metadata as array of dictionaries, and a count of matching items (the array may have fewer items if the query was limited). In addition to the usual metadata items, each dictionary will include the object id at key 'uid', the mountpoint of the item at key 'mountpoint', and possibly a 'filename' if requested.
+
It returns the matching object's metadata as array of dictionaries, and a count of matching items (the array may have fewer items if the query was limited). In addition to the usual metadata items, each dictionary will include the object id at key 'uid', <strike>the mountpoint of the item at key 'mountpoint',</strike> and possibly a 'filename' if requested.
    
The '''properties''' argument is an array of strings. It defines which keys to include in the results. You should only specify the keys you actually need. If you pass an empty array here, all the metadata would be returned, which for a Journal with hundreds of entries and previews could amount to multiple megabytes of data.  
 
The '''properties''' argument is an array of strings. It defines which keys to include in the results. You should only specify the keys you actually need. If you pass an empty array here, all the metadata would be returned, which for a Journal with hundreds of entries and previews could amount to multiple megabytes of data.  
Line 199: Line 199:  
: 'order_by': sort key (or array of keys) to order results by, to reverse order use '-key' <i>(but see note below)</i>
 
: 'order_by': sort key (or array of keys) to order results by, to reverse order use '-key' <i>(but see note below)</i>
 
: 'limit', 'offset': return only limit results starting at offset
 
: 'limit', 'offset': return only limit results starting at offset
: 'mountpoints': array of [[#Mount Points|mountpoint ids]] to search (or all if not specified)
+
: <strike>'mountpoints': array of [[#Mount Points|mountpoint ids]] to search (or all if not specified) </strike>
 
: 'include_files': if true, generate files as if get_filename() had been called for each item. In results, a property 'filename' will be added.
 
: 'include_files': if true, generate files as if get_filename() had been called for each item. In results, a property 'filename' will be added.
   Line 246: Line 246:  
===Choosing Objects===
 
===Choosing Objects===
 
Call this method to bring up the Chooser dialog (which looks like a small journal overlayed on your activity):
 
Call this method to bring up the Chooser dialog (which looks like a small journal overlayed on your activity):
  chooser_id = org.laptop.Journal.ChooseObject(xid, what_filter)                      # only xid arg supported in Sugar 0.82!
+
 
The xid should be your activity's X window handle, or <tt>0</tt>. The filter says what type of Journal entries is preselected in the drop-down menu (''this parameter was added in Sugar 0.83''). It's a string containing either a bundle id (e.g., <tt>'my.organization.MyActivity'</tt>), or one of the generic data types (<tt>'Text', 'Image', 'Video', 'Audio', 'Link'</tt> [http://git.sugarlabs.org/projects/sugar-base/repos/mainline/blobs/master/src/sugar/mime.py#line32 definition]), or an empty string for no filter. The call returns immediately with a string chooser_id. You need to watch these signals which get emitted when an item is chosen or the dialog is canceled:
+
  chooser_id = org.laptop.Journal.ChooseObject(xid:s, what_filter:s)                      # in Sugar 0.82 this had only one argument
  ObjectChooserResponse(chooser_id, object_id)
+
 
  ObjectChooserCancelled(chooser_id)
+
The xid should be your activity's X window handle, or <tt>0</tt>. The filter says what type of Journal entries is preselected in the drop-down menu (''this parameter was added in Sugar 0.83''). It's a string containing either a bundle id (e.g., <tt>'my.organization.MyActivity'</tt>), or one of the generic data types (<tt>'Text', 'Image', 'Video', 'Audio', 'Link'</tt> [http://git.sugarlabs.org/projects/sugar-base/repos/mainline/blobs/master/src/sugar/mime.py#line32 definition]), or an empty string for no filter. The call returns immediately with a string chooser_id. You need to watch the following signals which get emitted when an item is chosen or the dialog is cancelled:
The object_id received in an ObjectChooserResponse signal then can be used to open the corresponding [[#Keeping and Resuming|datastore object]].
+
 
 +
  ObjectChooserResponse(chooser_id:s, object_id_or_path:s)
 +
  ObjectChooserCancelled(chooser_id:s)
 +
 
 +
The chooser_id can be tested to see if this signal was in response to our own request. This is important if the user opens two file choosers at the same time (possibly in two different activities). If the user closes the chooser without selecting anything, the ObjectChooserCancelled signal is sent. Otherwise, the ObjectChooserResponse signal will be sent, and its object_id_or_path string argument is either an object id or a file path. To distinguish between the two cases, check if the first character is a slash (<tt>'/'</tt>). If it indeed begins with a slash, then this is an absolute path to a file, which can be opened directly. Otherwise, if the first character is not a slash, then object_id_or_path is an object id, which can be used to open the corresponding [[#Keeping and Resuming|datastore object]].
    
===Focusing Objects===
 
===Focusing Objects===
Line 257: Line 261:  
  org.laptop.Journal.ShowObject(object_id)
 
  org.laptop.Journal.ShowObject(object_id)
   −
Switches to the Journal activity and shows the selected object.
+
Switches to the Journal activity and shows the "detail view" of the selected object.
 +
 
 +
This can be used to, e.g., open a URL (create a URL object in the journal then call this) or to view source code (store the source code as text file, then call ShowObject() on it).
   −
This can be used to, e.g., open a URL (create a URL object in the journal then call this) or to view source code (store the source code as text file in the journal then call ShowObject() on it).
+
Note: since Sugar 0.84, you also can give the full path to an existing file instead of an object id. If the user resumes that file, it will be copied to the Journal first and then opened using the chosen activity. <i>This seems to be of limited usefulness and is documented here just for completeness</i>
    
<s>To focus on multiple objects: <code>org.laptop.Journal.FocusSearch(query)</code></s> ''Removed in Sugar 0.83''
 
<s>To focus on multiple objects: <code>org.laptop.Journal.FocusSearch(query)</code></s> ''Removed in Sugar 0.83''
    
==Mount Points==
 
==Mount Points==
 +
<strike>
 
Devices are represented as mount points in the datastore. If no mountpoint is explicitly specified, the main datastore (Journal) is used.
 
Devices are represented as mount points in the datastore. If no mountpoint is explicitly specified, the main datastore (Journal) is used.
   Line 276: Line 283:     
Large files to be stored on an external device should be placed at the uri of the mount point (see [[#External Media|external media]]).
 
Large files to be stored on an external device should be placed at the uri of the mount point (see [[#External Media|external media]]).
 +
</strike>
   −
'''Note:''' ''This only works as described in Sugar up to 0.82. The functions do exist in later Sugar versions, but do not return useful data.''
+
'''Note:''' ''This only works as described in Sugar up to 0.82. The functions do exist in later Sugar versions, but do not return useful data. Use the [[#External Media|external media API]] instead.''
    
=Security=
 
=Security=
Line 304: Line 312:  
;$SUGAR_ACTIVITY_ROOT/data/: This directory is used similar to a traditional home directory, for persistent activity data such as configuration files. Make sure files in there are group readable and writable (see [[#Users and Groups|users and groups]]). The directory itself is group-writable. Files stored here will survive reboots and OS upgrades.
 
;$SUGAR_ACTIVITY_ROOT/data/: This directory is used similar to a traditional home directory, for persistent activity data such as configuration files. Make sure files in there are group readable and writable (see [[#Users and Groups|users and groups]]). The directory itself is group-writable. Files stored here will survive reboots and OS upgrades.
   −
;$SUGAR_ACTIVITY_ROOT/tmp/: This directory is used similar to a /tmp directory, being backed by RAM. It may be as small as 1 MB. This directory is deleted when the activity exits (specifically,  as soon as all children of the activity's first process die). This directory is ''only'' accessible to the activity and its children; not even to Sugar.
+
;$SUGAR_ACTIVITY_ROOT/tmp/: This directory is used similar to a /tmp directory, being backed by RAM if [[olpc:Rainbow|Rainbow]] is present. It may be as small as 1 MB. With [[olpc:Rainbow|Rainbow]], this directory is deleted when the activity exits (specifically,  as soon as all children of the activity's first process die). This directory is ''only'' accessible to the activity and its children; not even to Sugar.
   −
;$SUGAR_ACTIVITY_ROOT/instance/: This directory is used similar to a /var/tmp directory, being backed by flash rather than by RAM. It is unique per instance. It is used for transfer to and from the datastore (see [[#Keeping and Resuming|keeping and resuming]]). This directory is deleted when the activity exits (specifically,  as soon as all children of the activity's first process die)
+
;$SUGAR_ACTIVITY_ROOT/instance/: This directory is used similar to a /var/tmp directory, being backed by flash rather than by RAM. It is unique per instance. It is used for transfer to and from the datastore (see [[#Keeping and Resuming|keeping and resuming]]). With [[olpc:Rainbow|Rainbow]], this directory is deleted when the activity exits (specifically,  as soon as all children of the activity's first process die).
    
As of version 8.2, all the activity root directories are created in /home/olpc/isolation and can be examined there with the Terminal activity. However, activities MUST use the $SUGAR_ACTIVITY_ROOT variable because the isolation directory layout is expected to change.
 
As of version 8.2, all the activity root directories are created in /home/olpc/isolation and can be examined there with the Terminal activity. However, activities MUST use the $SUGAR_ACTIVITY_ROOT variable because the isolation directory layout is expected to change.
Line 316: Line 324:  
=== External Media ===
 
=== External Media ===
   −
External media (USB drives, SD cards) are auto-mounted by the Journal and appear in /media/*. No access restrictions are applied currently (up to release 8.2). If activities use these external media directly (rather than through the Journal, see [[#Mount Points|mount points]]), they need to take care of ensuring data integrity since the user may (and will) remove the medium at any time.
+
External media (USB drives, SD cards) are auto-mounted by the Journal. No access restrictions are applied currently. If activities use these external volumes directly, they need to take care of ensuring data integrity since the user may (and will) remove the medium at any time.
 +
 
 +
Depending on the Linux distro version, the volumes appear as /mnt/*, /media/*, /run/media/$USER/*, or in other places. Sugar up to version 0.82 provided an API to access their [[#Mount Points|mount points]]. Nowadays you should use general Linux API to find the volumes. The recommended way is using the [http://developer.gnome.org/gio/stable/GVolumeMonitor.html GNOME Volume Monitor] with a fallback to [http://www.freedesktop.org/wiki/Software/hal HAL] (there is an example in the [http://git.sugarlabs.org/backup/mainline/blobs/master/backup.py#line671 Backup activity]).
    
== Signing ==
 
== Signing ==
Line 334: Line 344:  
Collaboration plays a large role in Sugar. Still, the presence and sharing APIs are still somewhat rough. There are attempts to explain sharing, see [[olpc:Activity sharing|Activity sharing]]. The following are the bare essentials.
 
Collaboration plays a large role in Sugar. Still, the presence and sharing APIs are still somewhat rough. There are attempts to explain sharing, see [[olpc:Activity sharing|Activity sharing]]. The following are the bare essentials.
   −
''Note: The Presence Service has been deprecated. Activities need to talk to [[Telepathy]] directly instead. Details on that will be added to this page soonish''
+
''Note: The Presence Service has been deprecated. Activities need to talk to [[Telepathy]] directly instead. See [[#Collaboration|below]] for details''
    +
<strike>
 
==General==
 
==General==
   Line 390: Line 401:  
  BuddyJoined (o: buddy)
 
  BuddyJoined (o: buddy)
 
  BuddyLeft (o: buddy)
 
  BuddyLeft (o: buddy)
 +
 +
</strike>
    
==Tubes==
 
==Tubes==
Line 471: Line 484:  
== Startup ==
 
== Startup ==
   −
On startup, an activity needs to check all the currently available connections if there is already a "room" for it. If so, it needs to be joined (see [[#Joining|below]]). The GetActivity method checks for the room given an activity_id:
+
On startup, an activity needs to check all the currently available connections if there is already a "room" for it. The GetActivity method checks for the room given an activity_id:
    
  for connection in connections:
 
  for connection in connections:
Line 483: Line 496:  
  METHOD SetProperties(room:u, properties:a{sv}) => ()
 
  METHOD SetProperties(room:u, properties:a{sv}) => ()
 
  SIGNAL ActivityPropertiesChanged(room:u, properties:a{sv})
 
  SIGNAL ActivityPropertiesChanged(room:u, properties:a{sv})
 +
 +
If a room is found, the activity needs to join it immediately (see [[#Joining|below]]). Otherwise, a normal "unshared" activity startup should commence.
    
== Joining ==
 
== Joining ==

Navigation menu