Ticket #4242: 0001-Send-to-Fried-from-Journal-fixed-SL-4242.2.patch

File 0001-Send-to-Fried-from-Journal-fixed-SL-4242.2.patch, 7.5 KB (added by humitos, 11 years ago)

v2 - with a better commit message (that's the only change)

  • src/jarabe/model/filetransfer.py

    From 1495b80f0f49e9d90e609309507a05fa584e715f Mon Sep 17 00:00:00 2001
    From: Manuel Kaufmann <humitos@gmail.com>
    Date: Wed, 5 Dec 2012 18:00:32 -0300
    Subject: [PATCH sugar] "Send to Fried" from Journal fixed SL #4242
    
     - Fix some issues related to the port to Gio (introspected): argument
       numbers and order and method names.
    
     - Use 'Gio.InputStream.read_bytes_async'[1] and
       'Gio.OutputStream.write_bytes_async' instead of '.read_async'[2] and
       'write_async' to transfer the data.
    
       This is done because there is no way to pass the correct buffer
       argument to those functions from Python. So, Gio provides helper
       functions (like 'read_bytes'[3]) to make this easier from language
       bindings. From its documentation:
    
       "Like g_input_stream_read(), this tries to read count bytes from
       the stream in a blocking fashion. However, rather than reading into
       a user-supplied buffer, this will create a new GBytes containing
       the data that was read. This may be easier to use from language
       bindings."
    
       [1] http://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-bytes-async
       [2] http://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-async
       [3] http://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-bytes
    
    Signed-off-by: Manuel Kaufmann <humitos@gmail.com>
    ---
     src/jarabe/model/filetransfer.py | 70 ++++++++++++++++++++++++----------------
     1 file changed, 42 insertions(+), 28 deletions(-)
    
    diff --git a/src/jarabe/model/filetransfer.py b/src/jarabe/model/filetransfer.py
    index 820df74..c4dd518 100644
    a b import socket 
    2020
    2121from gi.repository import GObject
    2222from gi.repository import Gio
     23from gi.repository import GLib
    2324import dbus
    2425from telepathy.interfaces import CONNECTION_INTERFACE_REQUESTS, CHANNEL
    2526from telepathy.constants import CONNECTION_HANDLE_TYPE_CONTACT,     \
    from sugar3 import dispatch 
    3334from jarabe.util.telepathy import connection_watcher
    3435from jarabe.model import neighborhood
    3536
     37# Avoid "Fatal Python error: GC object already tracked"
     38# http://stackoverflow.com/questions/7496629/gstreamer-appsrc-causes-random-crashes
     39GObject.threads_init()
    3640
    3741FT_STATE_NONE = 0
    3842FT_STATE_PENDING = 1
    class StreamSplicer(GObject.GObject): 
    7377        self._pending_buffers = []
    7478
    7579    def start(self):
    76         self._input_stream.read_async(self._CHUNK_SIZE, self.__read_async_cb,
    77                                       GObject.PRIORITY_LOW)
    78 
    79     def __read_async_cb(self, input_stream, result):
    80         data = input_stream.read_finish(result)
    81 
    82         if not data:
    83             logging.debug('closing input stream')
    84             self._input_stream.close()
     80        self._input_stream.read_bytes_async(
     81            self._CHUNK_SIZE, GLib.PRIORITY_LOW,
     82            None, self.__read_async_cb, None)
     83
     84    def __read_async_cb(self, input_stream, result, user_data):
     85        data = input_stream.read_bytes_finish(result)
     86
     87        if data is None:
     88            # TODO: an error occured. Report something
     89            logging.error('An error occured in the file transfer.')
     90        elif data.get_size() == 0:
     91            # We read the file completely
     92            logging.debug('Closing input stream. Reading finished.')
     93            self._input_stream.close(None)
    8594        else:
     95            logging.debug('Data received (bytes): %s', data.get_size())
    8696            self._pending_buffers.append(data)
    87             self._input_stream.read_async(self._CHUNK_SIZE,
    88                                             self.__read_async_cb,
    89                                             GObject.PRIORITY_LOW)
     97            self._input_stream.read_bytes_async(
     98                self._CHUNK_SIZE, GLib.PRIORITY_LOW,
     99                None, self.__read_async_cb, None)
    90100        self._write_next_buffer()
    91101
    92102    def __write_async_cb(self, output_stream, result, user_data):
    93         count_ = output_stream.write_finish(result)
     103        size = output_stream.write_bytes_finish(result)
     104        logging.debug('Size written (bytes): %s', size)
    94105
    95106        if not self._pending_buffers and \
    96107                not self._output_stream.has_pending() and \
    97108                not self._input_stream.has_pending():
    98             logging.debug('closing output stream')
    99             output_stream.close()
     109            logging.debug('Closing output stream. Writing finished.')
     110            output_stream.close(None)
    100111            self.emit('finished')
    101112        else:
    102113            self._write_next_buffer()
    class StreamSplicer(GObject.GObject): 
    104115    def _write_next_buffer(self):
    105116        if self._pending_buffers and not self._output_stream.has_pending():
    106117            data = self._pending_buffers.pop(0)
    107             # TODO: we pass the buffer as user_data because of
    108             # http://bugzilla.gnome.org/show_bug.cgi?id=564102
    109             self._output_stream.write_async(data, self.__write_async_cb,
    110                                             GObject.PRIORITY_LOW,
    111                                             user_data=data)
     118            self._output_stream.write_bytes_async(
     119                data, GLib.PRIORITY_LOW, None,
     120                self.__write_async_cb, None)
    112121
    113122
    114123class BaseFileTransfer(GObject.GObject):
    class IncomingFileTransfer(BaseFileTransfer): 
    215224            # close the fd when it goes out of scope
    216225            self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    217226            self._socket.connect(self._socket_address)
    218             input_stream = Gio.unix.InputStream(self._socket.fileno(), True)
     227            input_stream = Gio.UnixInputStream.new(self._socket.fileno(), True)
    219228
    220             destination_file = Gio.File(self.destination_path)
     229            destination_file = Gio.File.new_for_path(self.destination_path)
    221230            if self.initial_offset == 0:
    222                 output_stream = destination_file.create()
     231                output_stream = destination_file.create(
     232                    Gio.FileCreateFlags.PRIVATE, None)
    223233            else:
    224234                output_stream = destination_file.append_to()
    225235
    class OutgoingFileTransfer(BaseFileTransfer): 
    277287            # closes the fd when it goes out of scope
    278288            self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    279289            self._socket.connect(self._socket_address)
    280             output_stream = Gio.unix.OutputStream(self._socket.fileno(), True)
     290            output_stream = Gio.UnixOutputStream.new(
     291                self._socket.fileno(), True)
    281292
    282293            logging.debug('opening %s for reading', self._file_name)
    283             input_stream = Gio.File(self._file_name).read()
     294            input_stream = Gio.File.new_for_path(self._file_name).read(None)
    284295            if self.initial_offset > 0:
    285296                input_stream.skip(self.initial_offset)
    286297
    def file_transfer_available(): 
    356367if __name__ == '__main__':
    357368    import tempfile
    358369
    359     test_file_name = '/home/tomeu/isos/Soas2-200904031934.iso'
    360     test_input_stream = Gio.File(test_file_name).read()
    361     test_output_stream = Gio.File(tempfile.mkstemp()[1]).append_to()
     370    test_file_name = '/home/humitos/test.py'
     371    test_temp_file = tempfile.mkstemp()[1]
     372    print test_temp_file
     373    test_input_stream = Gio.File.new_for_path(test_file_name).read(None)
     374    test_output_stream = Gio.File.new_for_path(test_temp_file)\
     375        .append_to(Gio.FileCreateFlags.PRIVATE, None)
    362376
    363377    # TODO: Use splice_async when it gets implemented
    364378    splicer = StreamSplicer(test_input_stream, test_output_stream)