comparison frontends/quick_frontend/quick_app.py @ 51:8c67ea98ab91

frontend improved to take into account new SàT features - quick_frontend: better use of contact management, it now manages nicks, avatars, and connected status - quick_frontend: disconnect and remove are now 2 separate methods for contact list - wix: new contact list using HTML items, and showing avatars. Groups are not showed for now - wix: contact status now use tuples, to keep order, human readable status and color of contact - wix: contact list is updated when avatar or nick is found - wix: fixed 'question' dialog, which is renamed in 'yes/no' - wix: action result are now ignored for unkwnown id - sortilege refactored to work again
author Goffi <goffi@goffi.org>
date Thu, 07 Jan 2010 00:17:27 +1100
parents c2b131e4e262
children 6455fb62ff83
comparison
equal deleted inserted replaced
50:daa1f01a5332 51:8c67ea98ab91
20 """ 20 """
21 21
22 from logging import debug, info, error 22 from logging import debug, info, error
23 from tools.jid import JID 23 from tools.jid import JID
24 from sat_bridge_frontend.DBus import DBusBridgeFrontend 24 from sat_bridge_frontend.DBus import DBusBridgeFrontend
25 from quick_frontend.quick_contact_management import QuickContactManagement 25 import pdb
26
27 26
28 class QuickApp(): 27 class QuickApp():
29 """This class contain the main methods needed for the frontend""" 28 """This class contain the main methods needed for the frontend"""
30 29
31 def __init__(self): 30 def __init__(self):
32 self.rosterList = {} 31 self.rosterList = {}
33 self.CM = QuickContactManagement() #a short name if more handy
34 32
35 ## bridge ## 33 ## bridge ##
36 self.bridge=DBusBridgeFrontend() 34 self.bridge=DBusBridgeFrontend()
37 self.bridge.register("newContact", self.newContact) 35 self.bridge.register("newContact", self.newContact)
38 self.bridge.register("newMessage", self.newMessage) 36 self.bridge.register("newMessage", self.newMessage)
39 self.bridge.register("presenceUpdate", self.presenceUpdate) 37 self.bridge.register("presenceUpdate", self.presenceUpdate)
38 self.bridge.register("subscribe", self.subscribe)
40 self.bridge.register("paramUpdate", self.paramUpdate) 39 self.bridge.register("paramUpdate", self.paramUpdate)
41 self.bridge.register("contactDeleted", self.contactDeleted) 40 self.bridge.register("contactDeleted", self.contactDeleted)
41 self.bridge.register("updatedValue", self.updatedValue, "request")
42 self.bridge.register("askConfirmation", self.askConfirmation, "request") 42 self.bridge.register("askConfirmation", self.askConfirmation, "request")
43 self.bridge.register("actionResult", self.actionResult, "request") 43 self.bridge.register("actionResult", self.actionResult, "request")
44 self.bridge.register("actionResultExt", self.actionResult, "request") 44 self.bridge.register("actionResultExt", self.actionResult, "request")
45 45
46 ###now we get the essential params### 46 ###now we get the essential params###
57 57
58 ### now we fill the contact list ### 58 ### now we fill the contact list ###
59 for contact in self.bridge.getContacts(): 59 for contact in self.bridge.getContacts():
60 self.newContact(contact[0], contact[1], contact[2]) 60 self.newContact(contact[0], contact[1], contact[2])
61 61
62 for status in self.bridge.getPresenceStatus(): 62 presences = self.bridge.getPresenceStatus()
63 self.presenceUpdate(status[0], status[1], status[2], status[3], status[4]) 63 for contact in presences:
64 for res in presences[contact]:
65 jabber_id = contact+('/'+res if res else '')
66 show = presences[contact][res][0]
67 priority = presences[contact][res][1]
68 statuses = presences[contact][res][2]
69 self.presenceUpdate(jabber_id, show, priority, statuses)
70
71 waitingSub = self.bridge.getWaitingSub()
72 for sub in waitingSub:
73 self.subscribe(waitingSub[sub], sub)
64 74
65 75
66 def newContact(self, JabberId, attributes, groups): 76 def newContact(self, JabberId, attributes, groups):
67 jid=JID(JabberId) 77 entity=JID(JabberId)
68 self.rosterList[jid.short]=(dict(attributes), list(groups)) 78 self.rosterList[entity.short]=(dict(attributes), list(groups))
69 79
70 def newMessage(self, from_jid, msg, type, to_jid): 80 def newMessage(self, from_jid, msg, type, to_jid):
71 sender=JID(from_jid) 81 sender=JID(from_jid)
72 addr=JID(to_jid) 82 addr=JID(to_jid)
73 win = addr if sender.short == self.whoami.short else sender 83 win = addr if sender.short == self.whoami.short else sender
74 self.chat_wins[win.short].printMessage(sender, msg) 84 self.chat_wins[win.short].printMessage(sender, msg)
75 85
76 def setStatusOnline(self, online=True): 86 def setStatusOnline(self, online=True):
77 pass 87 pass
78 88
79 def presenceUpdate(self, jabber_id, type, show, status, priority): 89 def presenceUpdate(self, jabber_id, show, priority, statuses):
80 debug ("presence update for %s (type=%s, show=%s, status=%s)", jabber_id, type, show, status); 90 debug ("presence update for %s (show=%s, statuses=%s)", jabber_id, show, statuses);
81 jid=JID(jabber_id) 91 from_jid=JID(jabber_id)
82 debug ("jid.short=%s whoami.short=%s", jid.short, self.whoami.short) 92 debug ("from_jid.short=%s whoami.short=%s", from_jid.short, self.whoami.short)
83 93
84 ### subscription management ### 94 if from_jid.short==self.whoami.short:
85 if type=="subscribed":
86 # this is a subscription confirmation, we just have to inform user
87 self.showDialog("The contact %s has accepted your subscription" % jid.short, 'Subscription confirmation')
88 return
89 elif type=="unsubscribed":
90 # this is a subscription refusal, we just have to inform user
91 self.showDialog("The contact %s has refused your subscription" % jid.short, 'Subscription refusal', 'error')
92 return
93 elif type=="subscribe":
94 # this is a subscrition request, we have to ask for user confirmation
95 answer = self.showDialog("The contact %s wants to subscribe to your presence.\nDo you accept ?" % jid.short, 'Subscription confirmation', 'question')
96 if answer:
97 self.bridge.setPresence(type="subscribed", to=jid.short)
98 else:
99 self.bridge.setPresence(type="unsubscribed", to=jid.short)
100 return
101 ### subscription management end ###
102
103 if jid.short==self.whoami.short:
104 if not type: 95 if not type:
105 self.setStatusOnline(True) 96 self.setStatusOnline(True)
106 elif type=="unavailable": 97 elif type=="unavailable":
107 self.setStatusOnline(False) 98 self.setStatusOnline(False)
108 return 99 return
109 100
110 if not type: 101 if show != 'unavailable':
111 name="" 102 name=""
112 group="" 103 group=""
113 if self.rosterList.has_key(jid.short): 104 if self.rosterList.has_key(from_jid.short):
114 if self.rosterList[jid.short][0].has_key("name"): 105 if self.rosterList[from_jid.short][0].has_key("name"):
115 name=self.rosterList[jid.short][0]["name"] 106 name=self.rosterList[from_jid.short][0]["name"]
116 if self.rosterList[jid.short][0].has_key("show"): 107 if len(self.rosterList[from_jid.short][1]):
117 name=self.rosterList[jid.short][0]["show"] 108 group=self.rosterList[from_jid.short][1][0]
118 if self.rosterList[jid.short][0].has_key("status"):
119 name=self.rosterList[jid.short][0]["status"]
120 if len(self.rosterList[jid.short][1]):
121 group=self.rosterList[jid.short][1][0]
122 109
123 #FIXME: must be moved in a plugin 110 #FIXME: must be moved in a plugin
124 if jid.short in self.watched and not jid.short in self.onlineContact: 111 if from_jid.short in self.watched and not from_jid.short in self.onlineContact:
125 self.showAlert("Watched jid [%s] is connected !" % jid.short) 112 self.showAlert("Watched jid [%s] is connected !" % from_jid.short)
126 113
127 self.onlineContact.add(jid) #FIXME onlineContact is useless with CM, must be removed 114 self.onlineContact.add(from_jid) #FIXME onlineContact is useless with CM, must be removed
128 self.CM.add(jid) 115 self.CM.add(from_jid)
129 self.contactList.replace(jid, show=show, status=status, name=name, group=group) 116 self.CM.update(from_jid, 'name', name)
117 self.CM.update(from_jid, 'show', show)
118 self.CM.update(from_jid, 'statuses', statuses)
119 self.CM.update(from_jid, 'group', group)
120 cache = self.bridge.getProfileCache(from_jid)
121 if cache.has_key('nick'):
122 self.CM.update(from_jid, 'nick', cache['nick'])
123 if cache.has_key('avatar'):
124 self.CM.update(from_jid, 'avatar', self.bridge.getAvatarFile(cache['avatar']))
125 self.contactList.replace(from_jid)
130 126
127 if show=="unavailable" and from_jid in self.onlineContact:
128 self.onlineContact.remove(from_jid)
129 self.CM.remove(from_jid)
130 if not self.CM.isConnected(from_jid):
131 self.contactList.disconnect(from_jid)
131 132
132 if type=="unavailable" and jid in self.onlineContact: 133 def subscribe(self, type, raw_jid):
133 self.onlineContact.remove(jid) 134 """Called when a subsciption maangement signal is received"""
134 self.CM.remove(jid) 135 entity = JID(raw_jid)
135 self.contactList.remove(jid) 136 if type=="subscribed":
136 137 # this is a subscription confirmation, we just have to inform user
138 self.showDialog("The contact %s has accepted your subscription" % entity.short, 'Subscription confirmation')
139 elif type=="unsubscribed":
140 # this is a subscription refusal, we just have to inform user
141 self.showDialog("The contact %s has refused your subscription" % entity.short, 'Subscription refusal', 'error')
142 elif type=="subscribe":
143 # this is a subscriptionn request, we have to ask for user confirmation
144 answer = self.showDialog("The contact %s wants to subscribe to your presence.\nDo you accept ?" % entity.short, 'Subscription confirmation', 'yes/no')
145 if answer:
146 self.bridge.subscription("subscribed", entity.short)
147 else:
148 self.bridge.subscribed("unsubscribed", entity.short)
137 149
138 def showDialog(self, message, title, type="info"): 150 def showDialog(self, message, title, type="info"):
139 raise NotImplementedError 151 raise NotImplementedError
140 152
141 def showAlert(self, message): 153 def showAlert(self, message):
149 elif (namespace,name) == ("Misc", "Watched"): 161 elif (namespace,name) == ("Misc", "Watched"):
150 self.watched=value.split() 162 self.watched=value.split()
151 163
152 def contactDeleted(self, jid): 164 def contactDeleted(self, jid):
153 target = JID(jid) 165 target = JID(jid)
166 self.CM.remove(target)
167 self.contactList.remove(self.CM.get_full(target))
154 try: 168 try:
155 self.onlineContact.remove(target.short) 169 self.onlineContact.remove(target.short)
156 except KeyError: 170 except KeyError:
157 pass 171 pass
158 self.contactList.remove(self.CM.get_full(jid)) 172
159 self.CM.remove(target) 173 def updatedValue(self, name, data):
160 174 print "toto"
175 print "updatedValue", name, data
176 if name == "profile_nick":
177 target = JID(data['jid'])
178 self.CM.update(target, 'nick', data['nick'])
179 self.contactList.replace(target)
180 elif name == "profile_avatar":
181 target = JID(data['jid'])
182 filename = self.bridge.getAvatarFile(data['avatar'])
183 self.CM.update(target, 'avatar', filename)
184 self.contactList.replace(target)
185
161 def askConfirmation(self, type, id, data): 186 def askConfirmation(self, type, id, data):
162 raise NotImplementedError 187 raise NotImplementedError
163 188
164 def actionResult(self, type, id, data): 189 def actionResult(self, type, id, data):
165 raise NotImplementedError 190 raise NotImplementedError