Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0115.py @ 594:e629371a28d3
Fix pep8 support in src/plugins.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 18 Jan 2013 17:55:35 +0100 |
parents | beaf6bec2fcd |
children | 84a6e83157c2 |
comparison
equal
deleted
inserted
replaced
593:70bae685d05c | 594:e629371a28d3 |
---|---|
40 except ImportError: | 40 except ImportError: |
41 from wokkel.subprotocols import XMPPHandler | 41 from wokkel.subprotocols import XMPPHandler |
42 | 42 |
43 PRESENCE = '/presence' | 43 PRESENCE = '/presence' |
44 NS_ENTITY_CAPABILITY = 'http://jabber.org/protocol/caps' | 44 NS_ENTITY_CAPABILITY = 'http://jabber.org/protocol/caps' |
45 CAPABILITY_UPDATE = PRESENCE + '/c[@xmlns="' + NS_ENTITY_CAPABILITY + '"]' | 45 CAPABILITY_UPDATE = PRESENCE + '/c[@xmlns="' + NS_ENTITY_CAPABILITY + '"]' |
46 | 46 |
47 PLUGIN_INFO = { | 47 PLUGIN_INFO = { |
48 "name": "XEP 0115 Plugin", | 48 "name": "XEP 0115 Plugin", |
49 "import_name": "XEP-0115", | 49 "import_name": "XEP-0115", |
50 "type": "XEP", | 50 "type": "XEP", |
51 "protocols": ["XEP-0115"], | 51 "protocols": ["XEP-0115"], |
52 "dependencies": [], | 52 "dependencies": [], |
53 "main": "XEP_0115", | 53 "main": "XEP_0115", |
54 "handler": "yes", | 54 "handler": "yes", |
55 "description": _("""Implementation of entity capabilities""") | 55 "description": _("""Implementation of entity capabilities""") |
56 } | 56 } |
57 | |
57 | 58 |
58 class HashGenerationError(Exception): | 59 class HashGenerationError(Exception): |
59 pass | 60 pass |
61 | |
60 | 62 |
61 class ByteIdentity(object): | 63 class ByteIdentity(object): |
62 """This class manage identity as bytes (needed for i;octet sort), | 64 """This class manage identity as bytes (needed for i;octet sort), |
63 it is used for the hash generation""" | 65 it is used for the hash generation""" |
64 | 66 |
72 def __str__(self): | 74 def __str__(self): |
73 return "%s/%s/%s/%s" % (self.category, self.idType, self.lang, self.name) | 75 return "%s/%s/%s/%s" % (self.category, self.idType, self.lang, self.name) |
74 | 76 |
75 | 77 |
76 class XEP_0115(object): | 78 class XEP_0115(object): |
77 cap_hash = None #capabilities hash is class variable as it is common to all profiles | 79 cap_hash = None # capabilities hash is class variable as it is common to all profiles |
78 #TODO: this code is really dirty, need to clean it and try to move it to Wokkel | 80 #TODO: this code is really dirty, need to clean it and try to move it to Wokkel |
79 | 81 |
80 def __init__(self, host): | 82 def __init__(self, host): |
81 info(_("Plugin XEP_0115 initialization")) | 83 info(_("Plugin XEP_0115 initialization")) |
82 self.host = host | 84 self.host = host |
83 host.trigger.add("Disco Handled", self.checkHash) | 85 host.trigger.add("Disco Handled", self.checkHash) |
84 self.hash_cache = PersistentBinaryDict(NS_ENTITY_CAPABILITY) #key = hash or jid, value = features | 86 self.hash_cache = PersistentBinaryDict(NS_ENTITY_CAPABILITY) # key = hash or jid, value = features |
85 self.hash_cache.load() | 87 self.hash_cache.load() |
86 self.jid_hash = {} #jid to hash mapping, map to a discoInfo features if the hash method is unknown | 88 self.jid_hash = {} # jid to hash mapping, map to a discoInfo features if the hash method is unknown |
87 | 89 |
88 def checkHash(self, profile): | 90 def checkHash(self, profile): |
89 if not XEP_0115.cap_hash: | 91 if not XEP_0115.cap_hash: |
90 XEP_0115.cap_hash = self.generateHash(profile) | 92 XEP_0115.cap_hash = self.generateHash(profile) |
91 else: | 93 else: |
95 def getHandler(self, profile): | 97 def getHandler(self, profile): |
96 return XEP_0115_handler(self, profile) | 98 return XEP_0115_handler(self, profile) |
97 | 99 |
98 def presenceHack(self, profile): | 100 def presenceHack(self, profile): |
99 """modify SatPresenceProtocol to add capabilities data""" | 101 """modify SatPresenceProtocol to add capabilities data""" |
100 client=self.host.getClient(profile) | 102 client = self.host.getClient(profile) |
101 presenceInst = client.presence | 103 presenceInst = client.presence |
102 c_elt = domish.Element((NS_ENTITY_CAPABILITY,'c')) | 104 c_elt = domish.Element((NS_ENTITY_CAPABILITY, 'c')) |
103 c_elt['hash']='sha-1' | 105 c_elt['hash'] = 'sha-1' |
104 c_elt['node']='http://wiki.goffi.org/wiki/Salut_%C3%A0_Toi' | 106 c_elt['node'] = 'http://wiki.goffi.org/wiki/Salut_%C3%A0_Toi' |
105 c_elt['ver']=XEP_0115.cap_hash | 107 c_elt['ver'] = XEP_0115.cap_hash |
106 presenceInst._c_elt = c_elt | 108 presenceInst._c_elt = c_elt |
107 if "_legacy_send" in dir(presenceInst): | 109 if "_legacy_send" in dir(presenceInst): |
108 debug('capabilities already added to presence instance') | 110 debug('capabilities already added to presence instance') |
109 return | 111 return |
112 | |
110 def hacked_send(self, obj): | 113 def hacked_send(self, obj): |
111 obj.addChild(self._c_elt) | 114 obj.addChild(self._c_elt) |
112 self._legacy_send(obj) | 115 self._legacy_send(obj) |
113 new_send = types.MethodType(hacked_send, presenceInst, presenceInst.__class__) | 116 new_send = types.MethodType(hacked_send, presenceInst, presenceInst.__class__) |
114 presenceInst._legacy_send = presenceInst.send | 117 presenceInst._legacy_send = presenceInst.send |
115 presenceInst.send = new_send | 118 presenceInst.send = new_send |
116 | 119 |
117 | |
118 def generateHash(self, profile_key="@DEFAULT@"): | 120 def generateHash(self, profile_key="@DEFAULT@"): |
119 """This method generate a sha1 hash as explained in xep-0115 #5.1 | 121 """This method generate a sha1 hash as explained in xep-0115 #5.1 |
120 it then store it in XEP_0115.cap_hash""" | 122 it then store it in XEP_0115.cap_hash""" |
121 profile = self.host.memory.getProfileName(profile_key) | 123 profile = self.host.memory.getProfileName(profile_key) |
122 if not profile: | 124 if not profile: |
123 error ('Requesting hash for an inexistant profile') | 125 error('Requesting hash for an inexistant profile') |
124 raise HashGenerationError | 126 raise HashGenerationError |
125 | 127 |
126 client = self.host.getClient(profile_key) | 128 client = self.host.getClient(profile_key) |
127 if not client: | 129 if not client: |
128 error ('Requesting hash for an inexistant client') | 130 error('Requesting hash for an inexistant client') |
129 raise HashGenerationError | 131 raise HashGenerationError |
130 | 132 |
131 def generateHash_2(services, profile): | 133 def generateHash_2(services, profile): |
132 _s=[] | 134 _s = [] |
133 byte_identities = [ByteIdentity(identity) for identity in filter(lambda x:isinstance(x,disco.DiscoIdentity),services)] #FIXME: lang must be managed here | 135 byte_identities = [ByteIdentity(identity) for identity in filter(lambda x: isinstance(x, disco.DiscoIdentity), services)] # FIXME: lang must be managed here |
134 byte_identities.sort(key=lambda i:i.lang) | 136 byte_identities.sort(key=lambda i: i.lang) |
135 byte_identities.sort(key=lambda i:i.idType) | 137 byte_identities.sort(key=lambda i: i.idType) |
136 byte_identities.sort(key=lambda i:i.category) | 138 byte_identities.sort(key=lambda i: i.category) |
137 for identity in byte_identities: | 139 for identity in byte_identities: |
138 _s.append(str(identity)) | 140 _s.append(str(identity)) |
139 _s.append('<') | 141 _s.append('<') |
140 byte_features = [feature.encode('utf-8') for feature in filter(lambda x:isinstance(x,disco.DiscoFeature),services)] | 142 byte_features = [feature.encode('utf-8') for feature in filter(lambda x: isinstance(x, disco.DiscoFeature), services)] |
141 byte_features.sort() #XXX: the default sort has the same behaviour as the requested RFC 4790 i;octet sort | 143 byte_features.sort() # XXX: the default sort has the same behaviour as the requested RFC 4790 i;octet sort |
142 for feature in byte_features: | 144 for feature in byte_features: |
143 _s.append(feature) | 145 _s.append(feature) |
144 _s.append('<') | 146 _s.append('<') |
145 #TODO: manage XEP-0128 data form here | 147 #TODO: manage XEP-0128 data form here |
146 XEP_0115.cap_hash = b64encode(sha1(''.join(_s)).digest()) | 148 XEP_0115.cap_hash = b64encode(sha1(''.join(_s)).digest()) |
147 debug(_('Capability hash generated: [%s]') % XEP_0115.cap_hash) | 149 debug(_('Capability hash generated: [%s]') % XEP_0115.cap_hash) |
148 self.presenceHack(profile) | 150 self.presenceHack(profile) |
149 | 151 |
150 services = client.discoHandler.info(client.jid, client.jid, '').addCallback(generateHash_2, profile) | 152 services = client.discoHandler.info(client.jid, client.jid, '').addCallback(generateHash_2, profile) |
153 | |
151 | 154 |
152 class XEP_0115_handler(XMPPHandler): | 155 class XEP_0115_handler(XMPPHandler): |
153 implements(iwokkel.IDisco) | 156 implements(iwokkel.IDisco) |
154 | 157 |
155 def __init__(self, plugin_parent, profile): | 158 def __init__(self, plugin_parent, profile): |
174 self.plugin_parent.hash_cache[key] = discoResult.features | 177 self.plugin_parent.hash_cache[key] = discoResult.features |
175 else: | 178 else: |
176 #No key, that means unknown hash method | 179 #No key, that means unknown hash method |
177 self.plugin_parent.jid_hash[from_jid] = discoResult.features | 180 self.plugin_parent.jid_hash[from_jid] = discoResult.features |
178 | 181 |
179 | |
180 def update(self, presence): | 182 def update(self, presence): |
181 """ | 183 """ |
182 Manage the capabilities of the entity | 184 Manage the capabilities of the entity |
183 Check if we know the version of this capatilities | 185 Check if we know the version of this capatilities |
184 and get the capibilities if necessary | 186 and get the capibilities if necessary |
185 """ | 187 """ |
186 from_jid = jid.JID(presence['from']) | 188 from_jid = jid.JID(presence['from']) |
187 c_elem = filter (lambda x:x.name == "c", presence.elements())[0] #We only want the "c" element | 189 c_elem = filter(lambda x: x.name == "c", presence.elements())[0] # We only want the "c" element |
188 try: | 190 try: |
189 ver=c_elem['ver'] | 191 ver = c_elem['ver'] |
190 hash=c_elem['hash'] | 192 hash = c_elem['hash'] |
191 node=c_elem['node'] | 193 node = c_elem['node'] |
192 except KeyError: | 194 except KeyError: |
193 warning('Received invalid capabilities tag') | 195 warning('Received invalid capabilities tag') |
194 return | 196 return |
195 if not from_jid in self.plugin_parent.jid_hash: | 197 if not from_jid in self.plugin_parent.jid_hash: |
196 if ver in self.plugin_parent.hash_cache: | 198 if ver in self.plugin_parent.hash_cache: |
197 #we know that hash, we just link it with the jid | 199 #we know that hash, we just link it with the jid |
198 self.plugin_parent.jid_hash[from_jid] = ver | 200 self.plugin_parent.jid_hash[from_jid] = ver |
199 else: | 201 else: |
200 if hash!='sha-1': | 202 if hash != 'sha-1': |
201 #unknown hash method | 203 #unknown hash method |
202 warning('Unknown hash for entity capabilities: [%s]' % hash) | 204 warning('Unknown hash for entity capabilities: [%s]' % hash) |
203 self.parent.disco.requestInfo(from_jid).addCallback(self._updateCache, from_jid, ver if hash=='sha-1' else None ) | 205 self.parent.disco.requestInfo(from_jid).addCallback(self._updateCache, from_jid, ver if hash == 'sha-1' else None) |
204 #TODO: me must manage the full algorithm described at XEP-0115 #5.4 part 3 | 206 #TODO: me must manage the full algorithm described at XEP-0115 #5.4 part 3 |
205 |