Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/messenger.py
blob: e7edbdf545c782a21482da8840a7ba605a3fc658 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#
#    Copyright (C) 2007, One Laptop Per Child
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

import logging
import os
import dbus
from dbus.gobject_service import ExportedGObject
import base64

SERVICE = "org.laptop.WebActivity"
IFACE = SERVICE
PATH = "/org/laptop/WebActivity"

_logger = logging.getLogger('messenger')

class Messenger(ExportedGObject):
    def __init__(self, tube, is_initiator, model, owner):
        ExportedGObject.__init__(self, tube, PATH)
        self.tube = tube
        self.is_initiator = is_initiator
        self.members = []
        self.entered = False
        self.model = model
        self.owner = owner
        self.tube.watch_participants(self.participant_change_cb)

    def participant_change_cb(self, added, removed):
        _logger.debug('Participants change add=%s    rem=%s' %(added, removed))
        for handle, bus_name in added:
            _logger.debug('Add member handle=%s  bus_name=%s' %(str(handle), str(bus_name)))
            self.members.append(bus_name)
                    
        for handle, bus_name in removed:
            _logger.debug('Remove member handle=%s  bus_name=%s' %(str(handle), str(bus_name)))
            try:
                self.members.remove(bus_name)
            except ValueError:
                # already absent
                pass        
                
        if not self.entered:
            self.tube.add_signal_receiver(self._add_link_receiver, '_add_link', IFACE, path=PATH, sender_keyword='sender',
                                           byte_arrays=True)
            if self.is_initiator:
                _logger.debug('Initialising a new shared browser, I am %s .'%self.tube.get_unique_name())                
            else:               
                # sync with other members
                self.bus_name = self.tube.get_unique_name()
                _logger.debug('Joined I am %s .'%self.bus_name)                
                for member in self.members:
                    if member != self.bus_name:
                        _logger.debug('Get info from %s' %member)
                        self.tube.get_object(member, PATH).sync_with_members(self.model.get_links_ids(), dbus_interface=IFACE, reply_handler=self.reply_sync, error_handler=lambda e:self.error_sync(e, 'transfering file'))
                                                                         
        self.entered = True
        
    def reply_sync(self, a_ids):
        a_ids.pop()                    
        for link in self.model.links:
            if link['hash'] not in a_ids:
                if link['deleted'] == 0:
                    self.tube.get_object(sender, PATH).send_link(link['hash'], link['url'], link['title'], link['color'],
                                                                 link['owner'], base64.b64encode(link['thumb']))
            
    def error_sync(self, e, when):    
        _logger.error('Error %s: %s'%(when, e))

    @dbus.service.method(dbus_interface=IFACE, in_signature='as', out_signature='as', sender_keyword='sender')
    def sync_with_members(self, b_ids, sender=None):
        '''Sync with members '''
        b_ids.pop()
        # links the caller wants from me
        for link in self.model.links:
            if link['hash'] not in b_ids:
                if link['deleted'] == 0:
                    self.tube.get_object(sender, PATH).send_link(link['hash'], link['url'], link['title'], link['color'],
                                                                 link['owner'], base64.b64encode(link['thumb']))
        a_ids = self.model.get_links_ids()
        a_ids.append('')
        # links I want from the caller
        return a_ids                        
        
    @dbus.service.method(dbus_interface=IFACE, in_signature='ssssss', out_signature='')
    def send_link(self, id, url, title, color, owner, buffer):
        '''Send link'''
        _logger.debug('Received data for link.')
        a_ids = self.model.get_links_ids()
        print a_ids
        if id not in a_ids:
            thumb = base64.b64decode(buffer)
            self.model.add_link(url, title, thumb, owner, color)
                    
    @dbus.service.signal(IFACE, signature='sssss')
    def _add_link(self, url, title, color, owner, thumb):        
        '''Signal to send the link information (add)'''
        _logger.debug('Add Link: %s '%url)
        
    def _add_link_receiver(self, url, title, color, owner, thumb, sender=None):
        '''Member sent a link'''
        handle = self.tube.bus_name_to_handle[sender]            
        if self.tube.self_handle != handle:
            buffer = base64.b64decode(thumb)
            self.model.add_link(url, title, buffer, owner, color)            
            _logger.debug('Added link: %s to linkbar.'%(url))