Mercurial > libervia-backend
diff src/core/sat_main.py @ 944:e1842ebcb2f3
core, plugin XEP-0115: discovery refactoring:
- hashing algorithm of XEP-0115 has been including in core
- our own hash is still calculated by XEP-0115 and can be regenerated with XEP_0115.recalculateHash
- old discovery methods have been removed. Now the following methods are used:
- hasFeature: tell if a feature is available for an entity
- getDiscoInfos: self explaining
- getDiscoItems: self explaining
- findServiceEntities: return all available items of an entity which given (category, type)
- findFeaturesSet: search for a set of features in entity + entity's items
all these methods are asynchronous, and manage cache automatically
- XEP-0115 manage in a better way hashes, and now use a trigger for presence instead of monkey patch
- new FeatureNotFound exception, when we want to do something which is not available
- refactored client initialisation sequence, removed client.initialized Deferred
- added constant APP_URL
- test_plugin_xep_0033.py has been temporarly deactivated, the time to adapt it
- lot of cleaning
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 28 Mar 2014 18:07:22 +0100 |
parents | 71926ec2114d |
children | b4cd968e30fb |
line wrap: on
line diff
--- a/src/core/sat_main.py Fri Mar 28 18:07:17 2014 +0100 +++ b/src/core/sat_main.py Fri Mar 28 18:07:22 2014 +0100 @@ -43,11 +43,6 @@ from glob import glob from uuid import uuid4 -try: - from twisted.words.protocols.xmlstream import XMPPHandler -except ImportError: - from wokkel.subprotocols import XMPPHandler - ### logging configuration FIXME: put this elsewhere ### logging.basicConfig(level=logging.DEBUG, format='%(message)s') @@ -217,16 +212,6 @@ info(_("already connected !")) return defer.succeed("None") - if profile in self.profiles: - # avoid the following error when self.connect() is called twice for the same profile within a short time period: - # Jumping into debugger for post-mortem of exception ''SatXMPPClient' object has no attribute 'discoHandler'': - # > /usr/local/lib/python2.7/dist-packages/sat/plugins/plugin_xep_0115.py(151)generateHash() - # -> services = client.discoHandler.info(client.jid, client.jid, '').addCallback(generateHash_2, profile) - # This is a strange issue that is often happening on my system since libervia is being run as a twisted plugin. - # FIXME: properly find the problem an fix it - debug("being connected...") - return defer.succeed("None") - def afterMemoryInit(ignore): """This part must be called when we have loaded individual parameters from memory""" try: @@ -262,17 +247,20 @@ debug(_("setting plugins parents")) + plugin_conn_cb = [] for plugin in self.plugins.iteritems(): if plugin[1].is_handler: plugin[1].getHandler(profile).setHandlerParent(current) connected_cb = getattr(plugin[1], "profileConnected", None) if connected_cb: - connected_cb(profile) + plugin_conn_cb.append(connected_cb) current.startService() d = current.getConnectionDeferred() - d.addCallback(lambda x: current.roster.got_roster) # we want to be sure that we got the roster + d.addCallback(lambda dummy: current.roster.got_roster) # we want to be sure that we got the roster + for callback in plugin_conn_cb: + d.addCallback(lambda dummy: callback(profile)) return d self.memory.startProfileSession(profile) @@ -360,14 +348,6 @@ raise exceptions.ProfileKeyUnknownError return [self.profiles[profile]] - def getClientHostJid(self, profile_key): - """Convenient method to get the client host from profile key - @return: host jid or None if it doesn't exist""" - profile = self.memory.getProfileName(profile_key) - if not profile: - return None - return self.profiles[profile].getHostJid() - def registerNewAccount(self, login, password, email, server, port=5222, id_=None, profile_key=C.PROF_KEY_NONE): """Connect to a server and create a new account using in-band registration""" profile = self.memory.getProfileName(profile_key) @@ -623,113 +603,26 @@ self.profiles[profile].roster.removeItem(to_jid) self.profiles[profile].presence.unsubscribe(to_jid) - def requestServerDisco(self, feature, jid_=None, cache_only=False, profile_key="@NONE"): - """Discover if a server or its items offer a given feature - @param feature: the feature to check - @param jid_: the jid of the server, local server if None - @param cache_only: expect the result to be in cache and don't actually make any request. - This can be used anytime for requesting a feature on the local server because the data are cached for sure. - @result: the Deferred entity jid offering the feature, or None - - """ - profile = self.memory.getProfileName(profile_key) - - if not profile: - return defer.succeed(None) - if jid_ is None: - jid_ = self.getClientHostJid(profile) - cache_only = True - hasServerFeature = lambda entity: entity if self.memory.hasServerFeature(feature, entity, profile) else None - def haveItemsFeature(dummy=None): - entities = self.memory.getAllServerIdentities(jid_, profile) - if entities is None: - return None # no cached data for this server - for entity in entities: - if hasServerFeature(entity): - return entity - return None # data are cached but no entity was found - - entity = hasServerFeature(jid_) or haveItemsFeature() - if entity: - return defer.succeed(entity) - elif entity is False or cache_only: - return defer.succeed(None) + ## Discovery ## + # discovery methods are shortcuts to self.memory.disco + # the main difference with client.disco is that self.memory.disco manage cache - # data for this server are not in cache - disco = self.profiles[profile].disco - - def errback(failure, method, jid_, profile): - # the target server is not reachable - logging.error("disco.%s on %s failed! [%s]" % (method.func_name, jid_.userhost(), profile)) - logging.error("reason: %s" % failure.getErrorMessage()) - if method == disco.requestInfo: - features = self.memory.server_features.setdefault(profile, {}) - features.setdefault(jid_, []) - elif method == disco.requestItems: - identities = self.memory.server_identities.setdefault(profile, {}) - identities.setdefault(jid_, {}) - return failure + def hasFeature(self, *args, **kwargs): + return self.memory.disco.hasFeature(*args, **kwargs) - def callback(d): - if hasServerFeature(jid_): - return jid_ - else: - d2 = disco.requestItems(jid_).addCallback(self.serverDiscoItems, disco, jid_, profile) - d2.addErrback(errback, disco.requestItems, jid_, profile) - return d2.addCallback(haveItemsFeature) - - d = disco.requestInfo(jid_).addCallback(self.serverDisco, jid_, profile) - d.addCallbacks(callback, errback, [], errbackArgs=[disco.requestInfo, jid_, profile]) - return d - - ## callbacks ## + def getDiscoInfos(self, *args, **kwargs): + return self.memory.disco.getInfos(*args, **kwargs) - def serverDisco(self, disco, jid_=None, profile=None): - """xep-0030 Discovery Protocol. - @param disco: result of the disco info query - @param jid_: the jid of the target server - @param profile: profile of the user - """ - if jid_ is None: - jid_ = self.getClientHostJid(profile) - debug(_("Requested disco info on %s") % jid_) - for feature in disco.features: - debug(_("Feature found: %s") % feature) - self.memory.addServerFeature(feature, jid_, profile) - for cat, type_ in disco.identities: - debug(_("Identity found: [%(category)s/%(type)s] %(identity)s") - % {'category': cat, 'type': type_, 'identity': disco.identities[(cat, type_)]}) + def getDiscoItems(self, *args, **kwargs): + return self.memory.disco.getItems(*args, **kwargs) - def serverDiscoItems(self, disco_result, disco_client, jid_, profile, initialized=None): - """xep-0030 Discovery Protocol. - @param disco_result: result of the disco item querry - @param disco_client: SatDiscoProtocol instance - @param jid_: the jid of the target server - @param profile: profile of the user - @param initialized: deferred which must be chained when everything is done""" + def findServiceEntities(self, *args, **kwargs): + return self.memory.disco.findServiceEntities(*args, **kwargs) - def _check_entity_cb(result, entity, jid_, profile): - debug(_("Requested disco info on %s") % entity) - for category, type_ in result.identities: - debug(_('Identity added: (%(category)s,%(type)s) ==> %(entity)s [%(profile)s]') - % {'category': category, 'type': type_, 'entity': entity, 'profile': profile}) - self.memory.addServerIdentity(category, type_, entity, jid_, profile) - for feature in result.features: - self.memory.addServerFeature(feature, entity, profile) + def findFeaturesSet(self, *args, **kwargs): + return self.memory.disco.findFeaturesSet(*args, **kwargs) - def _errback(result, entity, jid_, profile): - warning(_("Can't get information on identity [%(entity)s] for profile [%(profile)s]") % {'entity': entity, 'profile': profile}) - - defer_list = [] - for item in disco_result._items: - if item.entity.full().count('.') == 1: # XXX: workaround for a bug on jabberfr, tmp - warning(_('Using jabberfr workaround, be sure your domain has at least two levels (e.g. "example.tld", not "example" alone)')) - continue - args = [item.entity, jid_, profile] - defer_list.append(disco_client.requestInfo(item.entity).addCallbacks(_check_entity_cb, _errback, args, None, args)) - if initialized: - defer.DeferredList(defer_list).chainDeferred(initialized) ## Generic HMI ##