~ubuntu-branches/ubuntu/precise/pymsn/precise

« back to all changes in this revision

Viewing changes to pymsn/msnp2p/transport/transport_manager.py

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville, Sjoerd Simons, Laurent Bigonville, Jonny Lamb
  • Date: 2008-01-17 18:23:14 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080117182314-lwymmpnk2ut3rvr1
Tags: 0.3.1-0ubuntu1
[ Sjoerd Simons ]
* debian/rules: remove dh_python, it's no longer needed

[ Laurent Bigonville ]
* New upstream release (0.3.1)
* debian/control:
  - Add myself as an Uploaders
  - Add python:Provides for binary package
  - Add python-ctypes and python-crypto to build-deps/deps
* debian/rules: remove binary-install rule
* Add watch file
* remove pycompat file, not needed anymore
* Modify Maintainer value to match the DebianMaintainerField
  specification.

[ Jonny Lamb ]
* Added python-adns to build-deps/deps.
* Added python-pyopenssl to build-deps/deps.
* Updated copyright.
* Upped Standards-Version to 3.7.3.
* Added "XS-Dm-Upload-Allowed: yes" under the request of Sjoerd Simons.
* Added myself to Uploaders.
* Added Homepage to control.
* Added Vcs-Bzr to control.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
#
 
3
# pymsn - a python client library for Msn
 
4
#
 
5
# Copyright (C) 2007 Ali Sabil <asabil@gmail.com>
 
6
#
 
7
# This program is free software; you can redistribute it and/or modify
 
8
# it under the terms of the GNU General Public License as published by
 
9
# the Free Software Foundation; either version 2 of the License, or
 
10
# (at your option) any later version.
 
11
#
 
12
# This program is distributed in the hope that it will be useful,
 
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
# GNU General Public License for more details.
 
16
#
 
17
# You should have received a copy of the GNU General Public License
 
18
# along with this program; if not, write to the Free Software
 
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 
 
21
from pymsn.msnp2p.transport.switchboard import *
 
22
from pymsn.msnp2p.transport.TLP import MessageBlob
 
23
 
 
24
import gobject
 
25
import struct
 
26
import logging
 
27
 
 
28
__all__ = ['P2PTransportManager']
 
29
 
 
30
logger = logging.getLogger('msnp2p:transport')
 
31
 
 
32
 
 
33
class P2PTransportManager(gobject.GObject):
 
34
    __gsignals__ = {
 
35
            "blob-received" : (gobject.SIGNAL_RUN_FIRST,
 
36
                gobject.TYPE_NONE,
 
37
                (object,)),
 
38
 
 
39
            "blob-sent" : (gobject.SIGNAL_RUN_FIRST,
 
40
                gobject.TYPE_NONE,
 
41
                (object,))
 
42
    }
 
43
    
 
44
    def __init__(self, client):
 
45
        gobject.GObject.__init__(self)
 
46
 
 
47
        self._client = client
 
48
        switchboard_manager = self._client._switchboard_manager
 
49
        switchboard_manager.register_handler(SwitchboardP2PTransport, self)
 
50
        self._default_transport = \
 
51
                lambda transport_mgr, peer : \
 
52
                        SwitchboardP2PTransport(client, (peer,), transport_mgr)
 
53
        self._transports = set()
 
54
        self._transport_signals = {}
 
55
        self._signaling_blobs = {} # blob_id => blob
 
56
        self._data_blobs = {} # session_id => blob
 
57
 
 
58
    def _register_transport(self, transport):
 
59
        assert transport not in self._transports, "Trying to register transport twice"
 
60
        self._transports.add(transport)
 
61
        signals = []
 
62
        signals.append(transport.connect("chunk-received", self._on_chunk_received))
 
63
        signals.append(transport.connect("chunk-sent", self._on_chunk_sent))
 
64
        self._transport_signals[transport] = signals
 
65
 
 
66
    def _unregister_transport(self, transport):
 
67
        self._transports.discard(transport)
 
68
        signals = self._transport_signals[transport]
 
69
        for signal in signals:
 
70
            transport.disconnect(signal)
 
71
        del self._transport_signals[transport]
 
72
 
 
73
    def _get_transport(self, peer):
 
74
        for transport in self._transports:
 
75
            if transport.peer == peer:
 
76
                return transport
 
77
        return self._default_transport(self, peer)
 
78
 
 
79
    def _on_chunk_received(self, transport, chunk):
 
80
        session_id = chunk.header.session_id
 
81
        blob_id = chunk.header.blob_id
 
82
 
 
83
        if session_id == 0: # signaling blob
 
84
            if blob_id in self._signaling_blobs:
 
85
                blob = self._signaling_blobs[blob_id]
 
86
            else:
 
87
                # create an in-memory blob
 
88
                blob = MessageBlob(chunk.application_id, "",
 
89
                    chunk.header.blob_size,
 
90
                    session_id, chunk.header.blob_id)
 
91
                self._signaling_blobs[blob_id] = blob
 
92
        else: # data blob
 
93
            if session_id in self._data_blobs:
 
94
                blob = self._data_blobs[session_id]
 
95
                if blob.transferred == 0:
 
96
                    blob.id = chunk.header.blob_id
 
97
            else:
 
98
                # create an in-memory blob
 
99
                blob = MessageBlob(chunk.application_id, "",
 
100
                        chunk.header.blob_size,
 
101
                        session_id, chunk.header.blob_id)
 
102
                self._data_blobs[session_id] = blob
 
103
 
 
104
        blob.append_chunk(chunk)
 
105
        if blob.is_complete():
 
106
            blob.data.seek(0, 0)
 
107
            self.emit("blob-received", blob)
 
108
            if session_id == 0:
 
109
                del self._signaling_blobs[blob_id]
 
110
            else:
 
111
                del self._data_blobs[session_id]
 
112
 
 
113
    def _on_chunk_sent(self, transport, chunk):
 
114
        pass
 
115
 
 
116
    def _on_blob_sent(self, transport, blob):
 
117
        self.emit("blob-sent", blob)
 
118
 
 
119
    def send(self, peer, blob):
 
120
        transport = self._get_transport(peer)
 
121
        transport.send(blob, (self._on_blob_sent, transport, blob))
 
122
 
 
123
    def register_writable_blob(self, blob):
 
124
        if blob.session_id in self._data_blobs:
 
125
            logger.warning("registering already registered blob "\
 
126
                    "with session_id=" + str(session_id))
 
127
            return
 
128
        self._data_blobs[blob.session_id] = blob
 
129
 
 
130
gobject.type_register(P2PTransportManager)