comparison frontends/quick_frontend/quick_app.py @ 66:8147b4f40809

SàT: multi-profile: DBus signals and frontend adaptation (first draft) - Quick App: new single_profile parameter in __init__ (default: yes), used to tell if the application use only one profile at the time or not - Quick App: new __check_profile method, tell if the profile is used by the current frontend - Quick App: new methods plug_profile, unplug_profile and clear_profile, must be called by the frontend to tell which profiles to use - DBus Bridge: new methods getProfileName, getProfilesList and createProfile
author Goffi <goffi@goffi.org>
date Wed, 03 Feb 2010 23:35:57 +1100
parents d46f849664aa
children 9b842086d915
comparison
equal deleted inserted replaced
65:d35c5edab53f 66:8147b4f40809
25 import pdb 25 import pdb
26 26
27 class QuickApp(): 27 class QuickApp():
28 """This class contain the main methods needed for the frontend""" 28 """This class contain the main methods needed for the frontend"""
29 29
30 def __init__(self): 30 def __init__(self, single_profile=True):
31 self.rosterList = {} 31 self.rosterList = {}
32 self.profiles = {}
33 self.single_profile = single_profile
32 34
33 ## bridge ## 35 ## bridge ##
34 self.bridge=DBusBridgeFrontend() 36 self.bridge=DBusBridgeFrontend()
35 self.bridge.register("connected", self.connected) 37 self.bridge.register("connected", self.connected)
36 self.bridge.register("disconnected", self.disconnected) 38 self.bridge.register("disconnected", self.disconnected)
43 self.bridge.register("updatedValue", self.updatedValue, "request") 45 self.bridge.register("updatedValue", self.updatedValue, "request")
44 self.bridge.register("askConfirmation", self.askConfirmation, "request") 46 self.bridge.register("askConfirmation", self.askConfirmation, "request")
45 self.bridge.register("actionResult", self.actionResult, "request") 47 self.bridge.register("actionResult", self.actionResult, "request")
46 self.bridge.register("actionResultExt", self.actionResult, "request") 48 self.bridge.register("actionResultExt", self.actionResult, "request")
47 49
48 ###now we get the essential params###
49 self.whoami=JID(self.bridge.getParamA("JabberID","Connection"))
50 self.watched=self.bridge.getParamA("Watched", "Misc").split() #TODO: put this in a plugin
51
52 ## misc ##
53 self.current_action_ids = set() 50 self.current_action_ids = set()
54 self.current_action_ids_cb = {} 51 self.current_action_ids_cb = {}
55 self.onlineContact = set() #FIXME: temporary 52
56 53 def __check_profile(self, profile):
57 if self.bridge.isConnected(): 54 """Tell if the profile is currently followed by the application"""
55 return profile in self.profiles.keys()
56
57 def plug_profile(self, profile_key='@DEFAULT@'):
58 """Tell application which profile must be used"""
59 if self.single_profile and self.profiles:
60 error('There is already one profile plugged (we are in single profile mode) !')
61 return
62 profile = self.bridge.getProfileName(profile_key)
63 if not profile:
64 error("The profile asked doesn't exist")
65 if self.profiles.has_key(profile):
66 warning("The profile is already plugged")
67 return
68 self.profiles[profile]={}
69 if self.single_profile:
70 self.profile = profile
71
72 ###now we get the essential params###
73 self.profiles[profile]['whoami']=JID(self.bridge.getParamA("JabberID","Connection", profile))
74 self.profiles[profile]['watched']=self.bridge.getParamA("Watched", "Misc", profile).split() #TODO: put this in a plugin
75
76 ## misc ##
77 self.profiles[profile]['onlineContact'] = set() #FIXME: temporary
78
79 #TODO: managed multi-profiles here
80 if self.bridge.isConnected(profile):
58 self.setStatusOnline(True) 81 self.setStatusOnline(True)
59 else: 82 else:
60 self.setStatusOnline(False) 83 self.setStatusOnline(False)
61 return 84 return
62 85
63 ### now we fill the contact list ### 86 ### now we fill the contact list ###
64 for contact in self.bridge.getContacts(): 87 for contact in self.bridge.getContacts(profile):
65 self.newContact(contact[0], contact[1], contact[2]) 88 self.newContact(contact[0], contact[1], contact[2], profile)
66 89
67 presences = self.bridge.getPresenceStatus() 90 presences = self.bridge.getPresenceStatus(profile)
68 for contact in presences: 91 for contact in presences:
69 for res in presences[contact]: 92 for res in presences[contact]:
70 jabber_id = contact+('/'+res if res else '') 93 jabber_id = contact+('/'+res if res else '')
71 show = presences[contact][res][0] 94 show = presences[contact][res][0]
72 priority = presences[contact][res][1] 95 priority = presences[contact][res][1]
73 statuses = presences[contact][res][2] 96 statuses = presences[contact][res][2]
74 self.presenceUpdate(jabber_id, show, priority, statuses) 97 self.presenceUpdate(jabber_id, show, priority, statuses, profile)
75 98
76 waitingSub = self.bridge.getWaitingSub() 99 waitingSub = self.bridge.getWaitingSub(profile)
77 for sub in waitingSub: 100 for sub in waitingSub:
78 self.subscribe(waitingSub[sub], sub) 101 self.subscribe(waitingSub[sub], sub, profile)
79 102
80 103 def unplug_profile(self, profile):
81 def connected(self): 104 """Tell the application to not follow anymore the profile"""
105 if not profile in self.profiles:
106 warning ("This profile is not plugged")
107 return
108 self.profiles.remove(profile)
109
110 def clear_profile(self):
111 self.profiles.clear()
112
113 def connected(self, profile):
82 """called when the connection is made""" 114 """called when the connection is made"""
115 if not self.__check_profile(profile):
116 return
83 debug("Connected") 117 debug("Connected")
84 self.setStatusOnline(True) 118 self.setStatusOnline(True)
85 119
86 def disconnected(self): 120 def disconnected(self, profile):
87 """called when the connection is closed""" 121 """called when the connection is closed"""
122 if not self.__check_profile(profile):
123 return
88 debug("Disconnected") 124 debug("Disconnected")
89 self.CM.clear() 125 self.CM.clear()
90 self.contactList.clear_contacts() 126 self.contactList.clear_contacts()
91 self.setStatusOnline(False) 127 self.setStatusOnline(False)
92 128
93 def newContact(self, JabberId, attributes, groups): 129 def newContact(self, JabberId, attributes, groups, profile):
130 if not self.__check_profile(profile):
131 return
94 entity=JID(JabberId) 132 entity=JID(JabberId)
95 self.rosterList[entity.short]=(dict(attributes), list(groups)) 133 self.rosterList[entity.short]=(dict(attributes), list(groups))
96 134
97 def newMessage(self, from_jid, msg, type, to_jid): 135 def newMessage(self, from_jid, msg, type, to_jid, profile):
136 if not self.__check_profile(profile):
137 return
98 sender=JID(from_jid) 138 sender=JID(from_jid)
99 addr=JID(to_jid) 139 addr=JID(to_jid)
100 win = addr if sender.short == self.whoami.short else sender 140 win = addr if sender.short == self.profiles[profile]['whoami'].short else sender
101 self.chat_wins[win.short].printMessage(sender, msg) 141 self.current_action_ids = set()
142 self.current_action_ids_cb = {}
143 self.chat_wins[win.short].printMessage(sender, msg, profile)
102 144
103 def setStatusOnline(self, online=True): 145 def setStatusOnline(self, online=True):
104 pass 146 pass
105 147
106 def presenceUpdate(self, jabber_id, show, priority, statuses): 148 def presenceUpdate(self, jabber_id, show, priority, statuses, profile):
149 if not self.__check_profile(profile):
150 return
151 print "check ok"
107 debug ("presence update for %s (show=%s, statuses=%s)", jabber_id, show, statuses); 152 debug ("presence update for %s (show=%s, statuses=%s)", jabber_id, show, statuses);
108 from_jid=JID(jabber_id) 153 from_jid=JID(jabber_id)
109 debug ("from_jid.short=%s whoami.short=%s", from_jid.short, self.whoami.short) 154 debug ("from_jid.short=%s whoami.short=%s", from_jid.short, self.profiles[profile]['whoami'].short)
110 155
111 if from_jid.short==self.whoami.short: 156 if from_jid.short==self.profiles[profile]['whoami'].short:
112 if not type: 157 if not type:
113 self.setStatusOnline(True) 158 self.setStatusOnline(True)
114 elif type=="unavailable": 159 elif type=="unavailable":
115 self.setStatusOnline(False) 160 self.setStatusOnline(False)
116 return 161 return
122 if self.rosterList[from_jid.short][0].has_key("name"): 167 if self.rosterList[from_jid.short][0].has_key("name"):
123 name=self.rosterList[from_jid.short][0]["name"] 168 name=self.rosterList[from_jid.short][0]["name"]
124 groups=self.rosterList[from_jid.short][1] 169 groups=self.rosterList[from_jid.short][1]
125 170
126 #FIXME: must be moved in a plugin 171 #FIXME: must be moved in a plugin
127 if from_jid.short in self.watched and not from_jid.short in self.onlineContact: 172 if from_jid.short in self.profiles[profile]['watched'] and not from_jid.short in self.profiles[profile]['onlineContact']:
128 self.showAlert("Watched jid [%s] is connected !" % from_jid.short) 173 self.showAlert("Watched jid [%s] is connected !" % from_jid.short)
129 174
130 self.onlineContact.add(from_jid) #FIXME onlineContact is useless with CM, must be removed 175 self.profiles[profile]['onlineContact'].add(from_jid) #FIXME onlineContact is useless with CM, must be removed
131 self.CM.add(from_jid) 176 self.CM.add(from_jid)
132 self.CM.update(from_jid, 'name', name) 177 self.CM.update(from_jid, 'name', name)
133 self.CM.update(from_jid, 'show', show) 178 self.CM.update(from_jid, 'show', show)
134 self.CM.update(from_jid, 'statuses', statuses) 179 self.CM.update(from_jid, 'statuses', statuses)
135 self.CM.update(from_jid, 'groups', groups) 180 self.CM.update(from_jid, 'groups', groups)
138 self.CM.update(from_jid, 'nick', cache['nick']) 183 self.CM.update(from_jid, 'nick', cache['nick'])
139 if cache.has_key('avatar'): 184 if cache.has_key('avatar'):
140 self.CM.update(from_jid, 'avatar', self.bridge.getAvatarFile(cache['avatar'])) 185 self.CM.update(from_jid, 'avatar', self.bridge.getAvatarFile(cache['avatar']))
141 self.contactList.replace(from_jid) 186 self.contactList.replace(from_jid)
142 187
143 if show=="unavailable" and from_jid in self.onlineContact: 188 if show=="unavailable" and from_jid in self.profiles[profile]['onlineContact']:
144 self.onlineContact.remove(from_jid) 189 self.profiles[profile]['onlineContact'].remove(from_jid)
145 self.CM.remove(from_jid) 190 self.CM.remove(from_jid)
146 if not self.CM.isConnected(from_jid): 191 if not self.CM.isConnected(from_jid):
147 self.contactList.disconnect(from_jid) 192 self.contactList.disconnect(from_jid)
148 193
149 def subscribe(self, type, raw_jid): 194 def subscribe(self, type, raw_jid, profile):
150 """Called when a subsciption maangement signal is received""" 195 """Called when a subsciption maangement signal is received"""
196 if not self.__check_profile(profile):
197 return
151 entity = JID(raw_jid) 198 entity = JID(raw_jid)
152 if type=="subscribed": 199 if type=="subscribed":
153 # this is a subscription confirmation, we just have to inform user 200 # this is a subscription confirmation, we just have to inform user
154 self.showDialog("The contact %s has accepted your subscription" % entity.short, 'Subscription confirmation') 201 self.showDialog("The contact %s has accepted your subscription" % entity.short, 'Subscription confirmation')
155 elif type=="unsubscribed": 202 elif type=="unsubscribed":
167 raise NotImplementedError 214 raise NotImplementedError
168 215
169 def showAlert(self, message): 216 def showAlert(self, message):
170 pass #FIXME 217 pass #FIXME
171 218
172 def paramUpdate(self, name, value, namespace): 219 def paramUpdate(self, name, value, namespace, profile):
220 if not self.__check_profile(profile):
221 return
173 debug("param update: [%s] %s = %s", namespace, name, value) 222 debug("param update: [%s] %s = %s", namespace, name, value)
174 if (namespace,name) == ("Connection", "JabberID"): 223 if (namespace,name) == ("Connection", "JabberID"):
175 debug ("Changing ID to %s", value) 224 debug ("Changing ID to %s", value)
176 self.whoami=JID(value) 225 self.profiles[profile]['whoami']=JID(value)
177 elif (namespace,name) == ("Misc", "Watched"): 226 elif (namespace,name) == ("Misc", "Watched"):
178 self.watched=value.split() 227 self.profiles[profile]['watched']=value.split()
179 228
180 def contactDeleted(self, jid): 229 def contactDeleted(self, jid, profile):
230 if not self.__check_profile(profile):
231 return
181 target = JID(jid) 232 target = JID(jid)
182 self.CM.remove(target) 233 self.CM.remove(target)
183 self.contactList.remove(self.CM.get_full(target)) 234 self.contactList.remove(self.CM.get_full(target))
184 try: 235 try:
185 self.onlineContact.remove(target.short) 236 self.profiles[profile]['onlineContact'].remove(target.short)
186 except KeyError: 237 except KeyError:
187 pass 238 pass
188 239
189 def updatedValue(self, name, data): 240 def updatedValue(self, name, data, profile):
190 if name == "profile_nick": 241 if not self.__check_profile(profile):
242 return
243 if name == "card_nick":
191 target = JID(data['jid']) 244 target = JID(data['jid'])
192 self.CM.update(target, 'nick', data['nick']) 245 self.CM.update(target, 'nick', data['nick'])
193 self.contactList.replace(target) 246 self.contactList.replace(target)
194 elif name == "profile_avatar": 247 elif name == "card_avatar":
195 target = JID(data['jid']) 248 target = JID(data['jid'])
196 filename = self.bridge.getAvatarFile(data['avatar']) 249 filename = self.bridge.getAvatarFile(data['avatar'])
197 self.CM.update(target, 'avatar', filename) 250 self.CM.update(target, 'avatar', filename)
198 self.contactList.replace(target) 251 self.contactList.replace(target)
199 252