Changes

Jump to navigation Jump to search
new heading for unanswered
Line 262: Line 262:  
[[Image:stream-tube-in-annotate-activity.jpg | How annotate's stream tube will be used]]
 
[[Image:stream-tube-in-annotate-activity.jpg | How annotate's stream tube will be used]]
   −
Notice that the stream tube exists as a complement to the [http://en.wikipedia.org/wiki/Internet_socket socket architecture] used by Unix systems to facilitate internet communication.
+
Notice that the stream tube exists on top of the [http://en.wikipedia.org/wiki/Internet_socket socket architecture] used by Unix systems to facilitate internet communication.
    
==== Step 2: Define or identify the classes you will use to serve data and receive data through your stream tube. ====
 
==== Step 2: Define or identify the classes you will use to serve data and receive data through your stream tube. ====
Line 305: Line 305:     
==== Step 3: Coordinate sharing and joining in your activity using stream tubes and the client/server classes defined above. ====
 
==== Step 3: Coordinate sharing and joining in your activity using stream tubes and the client/server classes defined above. ====
 +
 +
On the sharing instance, the following must happen:
 +
* Once the activity has been shared by the user, the sharing instance should detect the "shared" signal and setup for sharing.
 +
* To setup for sharing, the sharing instance needs to instantiate a new server (in Annotate, this is an AnnotateHTTPServer) that will deliver content to any client activities.
 +
* The newly instantiated server should listen on a given port and that port should be connected to a new stream tube. The stream tube can be created by calling the iface.OfferStreamTube() method.
 +
 +
 +
For the joining activity, it must coordinate several steps once the "joined" signal has been detected:
 +
* The joining activity needs to wait for a valid stream tube that is provided under the service ANNOTATE_STREAM_SERVICE.
 +
* When such a tube is available, the joining activity should specify the path where the downloaded data will be saved.
 +
* Create a listening client on the address and port associated with the stream tube that has been found. In our case, we create a sugar.network.GlibURLDownloader instance that will manage downloading from the stream tube.
 +
 
<pre>
 
<pre>
 
ANNOTATE_STREAM_SERVICE = 'annotate-activity-http'
 
ANNOTATE_STREAM_SERVICE = 'annotate-activity-http'
Line 314: Line 326:     
         ...
 
         ...
      
         #Joining activity needs to know which stream tubes are available for downloading  
 
         #Joining activity needs to know which stream tubes are available for downloading  
Line 372: Line 383:  
     # instance
 
     # instance
 
     def _joined_cb(self, also_self):
 
     def _joined_cb(self, also_self):
        self._update_chat_text('SYSTEM', '_joined_cb()')
   
         self.watch_for_tubes()
 
         self.watch_for_tubes()
 
         self._want_document = True;
 
         self._want_document = True;
Line 380: Line 390:  
     # a stream tube is made available.  
 
     # a stream tube is made available.  
 
     def watch_for_tubes(self):
 
     def watch_for_tubes(self):
        self._update_chat_text('SYSTEM', '_watch_for_tubes()')
   
         tubes_chan = self._shared_activity.telepathy_tubes_chan
 
         tubes_chan = self._shared_activity.telepathy_tubes_chan
   Line 394: Line 403:     
     def _list_tubes_error_cb(self, e):
 
     def _list_tubes_error_cb(self, e):
        self._update_chat_text('System', '_list_tubes_error_cb(): ListTubes() failed: '+str(e))
      
     #### Method _new_tube_cb, which is called once a stream tube is available  
 
     #### Method _new_tube_cb, which is called once a stream tube is available  
Line 400: Line 408:  
     def _new_tube_cb(self, tube_id, initiator, tube_type, service, params,
 
     def _new_tube_cb(self, tube_id, initiator, tube_type, service, params,
 
                     state):
 
                     state):
        self._update_chat_text('SYSTEM', '_new_tube_cb() -- ID:' + str(tube_id) + '; Initiator: ' + str(initiator) + '; tube_type: ' + str(tube_type) + '; Service: ' + str(service))
  −
   
         # If the available tube is the stream tube we set up in sharing activity, then  
 
         # If the available tube is the stream tube we set up in sharing activity, then  
 
         # let's download from it.  
 
         # let's download from it.  
         if service == ANNOTATE_STREAM_SERVICE:
+
         if service == ANNOTATE_STREAM_SERVICE:          
            self._update_chat_text('SYSTEM', 'I could download from that tube')
  −
           
   
             # Add the newly found stream tube to the available tubes we can download from
 
             # Add the newly found stream tube to the available tubes we can download from
 
             self.unused_download_tubes.add(tube_id)
 
             self.unused_download_tubes.add(tube_id)
Line 419: Line 423:  
     # obtained and saved in self.unused_download_tubes.  
 
     # obtained and saved in self.unused_download_tubes.  
 
     def _get_document(self):
 
     def _get_document(self):
        self._update_chat_text('SYSTEM', '_get_document()')
   
         if not self._want_document:
 
         if not self._want_document:
 
             return False
 
             return False
Line 431: Line 434:  
             tube_id = self.unused_download_tubes.pop()
 
             tube_id = self.unused_download_tubes.pop()
 
         except (ValueError, KeyError), e:
 
         except (ValueError, KeyError), e:
            self._update_chat_text('System', 'No tubes to get the document from right now: '+str(e))
   
             return False
 
             return False
   Line 442: Line 444:  
     #### Method _download_result_cb, which is called once downloading is complete.  
 
     #### Method _download_result_cb, which is called once downloading is complete.  
 
     def _download_result_cb(self, getter, tempfile, suggested_name, tube_id):
 
     def _download_result_cb(self, getter, tempfile, suggested_name, tube_id):
        self._update_chat_text('SYSTEM', '_download_result_cb() -- tempfile = ' + tempfile)
   
         del self.unused_download_tubes
 
         del self.unused_download_tubes
  −
        self._update_chat_text('SYSTEM', "Got document %s (%s) from tube %u",
  −
                      tempfile, suggested_name, tube_id)
   
         self.save()
 
         self.save()
   Line 453: Line 451:  
         # FIXME: signal the expected size somehow, so we can draw a progress
 
         # FIXME: signal the expected size somehow, so we can draw a progress
 
         # bar
 
         # bar
         self._update_chat_text("Downloaded " + str(bytes_downloaded) + " bytes from tube " + str(tube_id))
+
         return True;
    
     #### Method _download_error_cb, which is called if there was an error downloading.  
 
     #### Method _download_error_cb, which is called if there was an error downloading.  
Line 466: Line 464:  
         # FIXME: should ideally have the CM listen on a Unix socket
 
         # FIXME: should ideally have the CM listen on a Unix socket
 
         # instead of IPv4 (might be more compatible with Rainbow)
 
         # instead of IPv4 (might be more compatible with Rainbow)
        self._update_chat_text('SYSTEM', '_download_document() -- ' + path)
   
         chan = self._shared_activity.telepathy_tubes_chan
 
         chan = self._shared_activity.telepathy_tubes_chan
 
         iface = chan[telepathy.CHANNEL_TYPE_TUBES]
 
         iface = chan[telepathy.CHANNEL_TYPE_TUBES]
Line 487: Line 484:  
         getter.connect("progress", self._download_progress_cb, tube_id)
 
         getter.connect("progress", self._download_progress_cb, tube_id)
 
         getter.connect("error", self._download_error_cb, tube_id)
 
         getter.connect("error", self._download_error_cb, tube_id)
        self._update_chat_text('System', "Starting download to "+str(path))
   
         getter.start(path)
 
         getter.start(path)
 
         return False
 
         return False
Line 500: Line 496:  
=== Where do I get more information regarding sugar activity sharing and the technologies that support it? ===
 
=== Where do I get more information regarding sugar activity sharing and the technologies that support it? ===
 
* A [[Shared_Sugar_Activities | brief tutorial]] on activity sharing for the OLPC laptop.
 
* A [[Shared_Sugar_Activities | brief tutorial]] on activity sharing for the OLPC laptop.
 +
 +
=== I can't get tubes to work.  Are there unresolved issues? ===
1

edit

Navigation menu