core, jp: component handling + client handling refactoring:
- SàT can now handle components
- plugin have now a "modes" key in PLUGIN_INFO where they declare if they can be used with clients and or components. They default to be client only.
- components are really similar to clients, but with some changes in behaviour:
* component has "entry point", which is a special plugin with a componentStart method, which is called just after component is connected
* trigger end with a different suffixes (e.g. profileConnected vs profileConnectedComponent), so a plugin which manage both clients and components can have different workflow
* for clients, only triggers of plugins handling client mode are launched
* for components, only triggers of plugins needed in dependencies are launched. They all must handle component mode.
* component have a sendHistory attribute (False by default) which can be set to True to allow saving sent messages into history
* for convenience, "client" is still used in method even if it can now be a component
* a new "component" boolean attribute tells if we have a component or a client
* components have to add themselve Message protocol
* roster and presence protocols are not added for components
* component default port is 5347 (which is Prosody's default port)
- asyncCreateProfile has been renamed for profileCreate, both to follow new naming convention and to prepare the transition to fully asynchronous bridge
- createProfile has a new "component" attribute. When used to create a component, it must be set to a component entry point
- jp: added --component argument to profile/create
- disconnect bridge method is now asynchronous, this way frontends can know when disconnection is finished
- new PI_* constants for PLUGIN_INFO values (not used everywhere yet)
- client/component connection workflow has been moved to their classes instead of being a host methods
- host.messageSend is now client.sendMessage, and former client.sendMessage is now client.sendMessageData.
- identities are now handled in client.identities list, so it can be updated dynamically by plugins (in the future, frontends should be able to update them too through bridge)
- profileConnecting* profileConnected* profileDisconnected* and getHandler now all use client instead of profile
This commit is contained in:
parent
9b2923f161
commit
97337202cb
43 changed files with 839 additions and 523 deletions
|
|
@ -41,11 +41,11 @@ PLUGIN_INFO = {
|
|||
class ExportCommandProtocol(protocol.ProcessProtocol):
|
||||
""" Try to register an account with prosody """
|
||||
|
||||
def __init__(self, parent, target, options, profile):
|
||||
def __init__(self, parent, client, target, options):
|
||||
self.parent = parent
|
||||
self.target = target
|
||||
self.options = options
|
||||
self.profile = profile
|
||||
self.client = client
|
||||
|
||||
def _clean(self, data):
|
||||
if not data:
|
||||
|
|
@ -58,10 +58,10 @@ class ExportCommandProtocol(protocol.ProcessProtocol):
|
|||
log.info("connectionMade :)")
|
||||
|
||||
def outReceived(self, data):
|
||||
self.parent.host.messageSend(self.target, {'': self._clean(data)}, no_trigger=True, profile_key=self.profile)
|
||||
self.client.sendMessage(self.target, {'': self._clean(data)}, no_trigger=True)
|
||||
|
||||
def errReceived(self, data):
|
||||
self.parent.host.messageSend(self.target, {'': self._clean(data)}, no_trigger=True, profile_key=self.profile)
|
||||
self.client.sendMessage(self.target, {'': self._clean(data)}, no_trigger=True)
|
||||
|
||||
def processEnded(self, reason):
|
||||
log.info (u"process finished: %d" % (reason.value.exitCode,))
|
||||
|
|
@ -81,8 +81,9 @@ class ExportCommandProtocol(protocol.ProcessProtocol):
|
|||
|
||||
class CommandExport(object):
|
||||
"""Command export plugin: export a command to an entity"""
|
||||
#XXX: This plugin can be potentially dangerous if we don't trust entities linked
|
||||
# this is specially true if we have other triggers.
|
||||
# XXX: This plugin can be potentially dangerous if we don't trust entities linked
|
||||
# this is specially true if we have other triggers.
|
||||
# FIXME: spawned should be a client attribute, not a class one
|
||||
|
||||
def __init__(self, host):
|
||||
log.info(_("Plugin command export initialization"))
|
||||
|
|
@ -96,10 +97,10 @@ class CommandExport(object):
|
|||
@param entity: jid.JID attached to the process
|
||||
@param process: process to remove"""
|
||||
try:
|
||||
processes_set = self.spawned[(entity, process.profile)]
|
||||
processes_set = self.spawned[(entity, process.client.profile)]
|
||||
processes_set.discard(process)
|
||||
if not processes_set:
|
||||
del(self.spawned[(entity, process.profile)])
|
||||
del(self.spawned[(entity, process.client.profile)])
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
|
@ -140,11 +141,7 @@ class CommandExport(object):
|
|||
- pty: if set, launch in a pseudo terminal
|
||||
- continue: continue normal MessageReceived handling
|
||||
"""
|
||||
profile = self.host.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
log.warning(u"Unknown profile [%s]" % (profile,))
|
||||
return
|
||||
|
||||
client = self.host.getClient(profile_key)
|
||||
for target in targets:
|
||||
try:
|
||||
_jid = jid.JID(target)
|
||||
|
|
@ -154,7 +151,7 @@ class CommandExport(object):
|
|||
except (RuntimeError, jid.InvalidFormat, AttributeError):
|
||||
log.info(u"invalid target ignored: %s" % (target,))
|
||||
continue
|
||||
process_prot = ExportCommandProtocol(self, _jid, options, profile)
|
||||
self.spawned.setdefault((_jid, profile),set()).add(process_prot)
|
||||
process_prot = ExportCommandProtocol(self, client, _jid, options)
|
||||
self.spawned.setdefault((_jid, client.profile),set()).add(process_prot)
|
||||
reactor.spawnProcess(process_prot, command, args, usePTY = process_prot.boolOption('pty'))
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class LangDetect(object):
|
|||
self.host = host
|
||||
host.memory.updateParams(PARAMS)
|
||||
host.trigger.add("MessageReceived", self.MessageReceivedTrigger)
|
||||
host.trigger.add("messageSend", self.MessageSendTrigger)
|
||||
host.trigger.add("sendMessage", self.MessageSendTrigger)
|
||||
|
||||
def addLanguage(self, mess_data):
|
||||
message = mess_data['message']
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class Exp_Parrot(object):
|
|||
"""Parrot mode plugin: repeat messages from one entity or MUC room to another one"""
|
||||
# XXX: This plugin can be potentially dangerous if we don't trust entities linked
|
||||
# this is specially true if we have other triggers.
|
||||
# messageSendTrigger avoid other triggers execution, it's deactivated to allow
|
||||
# sendMessageTrigger avoid other triggers execution, it's deactivated to allow
|
||||
# /unparrot command in text commands plugin.
|
||||
# FIXME: potentially unsecure, specially with e2e encryption
|
||||
|
||||
|
|
@ -51,13 +51,13 @@ class Exp_Parrot(object):
|
|||
log.info(_("Plugin Parrot initialization"))
|
||||
self.host = host
|
||||
host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=100)
|
||||
#host.trigger.add("messageSend", self.messageSendTrigger, priority=100)
|
||||
#host.trigger.add("sendMessage", self.sendMessageTrigger, priority=100)
|
||||
try:
|
||||
self.host.plugins[C.TEXT_CMDS].registerTextCommands(self)
|
||||
except KeyError:
|
||||
log.info(_(u"Text commands not available"))
|
||||
|
||||
#def messageSendTrigger(self, client, mess_data, treatments):
|
||||
#def sendMessageTrigger(self, client, mess_data, treatments):
|
||||
# """ Deactivate other triggers if recipient is in parrot links """
|
||||
# try:
|
||||
# _links = client.parrot_links
|
||||
|
|
@ -103,7 +103,7 @@ class Exp_Parrot(object):
|
|||
|
||||
linked = _links[from_jid.userhostJID()]
|
||||
|
||||
self.host.messageSend(jid.JID(unicode(linked)), message, None, "auto", no_trigger=True, profile_key=profile)
|
||||
client.sendMessage(jid.JID(unicode(linked)), message, None, "auto", no_trigger=True)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ class MiscAccount(object):
|
|||
if profile.lower() in self.getConfig('reserved_list'):
|
||||
return defer.fail(Failure(exceptions.ConflictError))
|
||||
|
||||
d = self.host.memory.asyncCreateProfile(profile, password)
|
||||
d = self.host.memory.createProfile(profile, password)
|
||||
d.addCallback(lambda dummy: self.profileCreated(password, jid_s, profile))
|
||||
return d
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ class FilePlugin(object):
|
|||
has_feature = yield self.host.hasFeature(namespace, peer_jid, profile)
|
||||
if has_feature:
|
||||
log.info(u"{name} method will be used to send the file".format(name=method_name))
|
||||
progress_id = yield defer.maybeDeferred(callback, peer_jid, filepath, filename, file_desc, profile)
|
||||
progress_id = yield callback(peer_jid, filepath, filename, file_desc, profile)
|
||||
defer.returnValue({'progress': progress_id})
|
||||
msg = u"Can't find any method to send file to {jid}".format(jid=peer_jid.full())
|
||||
log.warning(msg)
|
||||
|
|
|
|||
|
|
@ -65,14 +65,13 @@ class GroupBlog(object):
|
|||
|
||||
## plugin management methods ##
|
||||
|
||||
def getHandler(self, profile):
|
||||
def getHandler(self, client):
|
||||
return GroupBlog_handler()
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def profileConnected(self, profile):
|
||||
client = self.host.getClient(profile)
|
||||
def profileConnected(self, client):
|
||||
try:
|
||||
yield self.host.checkFeatures((NS_PUBSUB_GROUPBLOG,), profile=profile)
|
||||
yield self.host.checkFeatures((NS_PUBSUB_GROUPBLOG,), profile=client.profile)
|
||||
except exceptions.FeatureNotFound:
|
||||
client.server_groupblog_available = False
|
||||
log.warning(_(u"Server is not able to manage item-access pubsub, we can't use group blog"))
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ class IPPlugin(object):
|
|||
self._external_ip_cache = None
|
||||
self._local_ip_cache = None
|
||||
|
||||
def getHandler(self, profile):
|
||||
def getHandler(self, client):
|
||||
return IPPlugin_handler()
|
||||
|
||||
def refreshIP(self):
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ PLUGIN_INFO = {
|
|||
MAILDIR_PATH = "Maildir"
|
||||
CATEGORY = D_("Mail Server")
|
||||
NAME = D_('Block "normal" messages propagation')
|
||||
# FIXME: (very) old and (very) experimental code, need a big cleaning/review
|
||||
# FIXME: (very) old and (very) experimental code, need a big cleaning/review or to be deprecated
|
||||
|
||||
|
||||
class MaildirError(Exception):
|
||||
|
|
@ -82,8 +82,9 @@ class MaildirBox(object):
|
|||
#the triggers
|
||||
host.trigger.add("MessageReceived", self.messageReceivedTrigger)
|
||||
|
||||
def profileConnected(self, profile):
|
||||
"""Called on profile connection, create profile data"""
|
||||
def profileConnected(self, client):
|
||||
"""Called on client connection, create profile data"""
|
||||
profile = client.profile
|
||||
self.data[profile] = PersistentBinaryDict("plugin_maildir", profile)
|
||||
self.__mailboxes[profile] = {}
|
||||
|
||||
|
|
@ -93,8 +94,9 @@ class MaildirBox(object):
|
|||
self.data[profile]["INBOX"] = {"cur_idx": 0}
|
||||
self.data[profile].load().addCallback(dataLoaded)
|
||||
|
||||
def profileDisconnected(self, profile):
|
||||
def profileDisconnected(self, client):
|
||||
"""Called on profile disconnection, free profile's resources"""
|
||||
profile = client.profile
|
||||
del self.__mailboxes[profile]
|
||||
del self.data[profile]
|
||||
|
||||
|
|
|
|||
|
|
@ -683,7 +683,7 @@ class RoomGame(object):
|
|||
"""
|
||||
return self._sendElements(to_jid, [(elem, attrs, content)], profile)
|
||||
|
||||
def getHandler(self, profile):
|
||||
def getHandler(self, client):
|
||||
return RoomGameHandler(self)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ class SatSmtpMessage(object):
|
|||
"""handle end of message"""
|
||||
mail = Parser().parsestr("\n".join(self.message))
|
||||
try:
|
||||
self.host._messageSend(parseaddr(mail['to'].decode('utf-8', 'replace'))[1], mail.get_payload().decode('utf-8', 'replace'), # TODO: manage other charsets
|
||||
self.host._sendMessage(parseaddr(mail['to'].decode('utf-8', 'replace'))[1], mail.get_payload().decode('utf-8', 'replace'), # TODO: manage other charsets
|
||||
subject=mail['subject'].decode('utf-8', 'replace'), mess_type='normal', profile_key=self.profile)
|
||||
except:
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class TextCommands(object):
|
|||
log.info(_("Text commands initialization"))
|
||||
self.host = host
|
||||
# this is internal command, so we set high priority
|
||||
host.trigger.add("messageSend", self.messageSendTrigger, priority=1000000)
|
||||
host.trigger.add("sendMessage", self.sendMessageTrigger, priority=1000000)
|
||||
self._commands = {}
|
||||
self._whois = []
|
||||
self.registerTextCommands(self)
|
||||
|
|
@ -168,12 +168,12 @@ class TextCommands(object):
|
|||
self._whois.append((priority, callback))
|
||||
self._whois.sort(key=lambda item: item[0], reverse=True)
|
||||
|
||||
def messageSendTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments):
|
||||
def sendMessageTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments):
|
||||
"""Install SendMessage command hook """
|
||||
pre_xml_treatments.addCallback(self._messageSendCmdHook, client)
|
||||
pre_xml_treatments.addCallback(self._sendMessageCmdHook, client)
|
||||
return True
|
||||
|
||||
def _messageSendCmdHook(self, mess_data, client):
|
||||
def _sendMessageCmdHook(self, mess_data, client):
|
||||
""" Check text commands in message, and react consequently
|
||||
|
||||
msg starting with / are potential command. If a command is found, it is executed, else and help message is sent
|
||||
|
|
@ -181,7 +181,7 @@ class TextCommands(object):
|
|||
commands can abord message sending (if they return anything evaluating to False), or continue it (if they return True), eventually after modifying the message
|
||||
an "unparsed" key is added to message, containing part of the message not yet parsed
|
||||
commands can be deferred or not
|
||||
@param mess_data(dict): data comming from messageSend trigger
|
||||
@param mess_data(dict): data comming from sendMessage trigger
|
||||
@param profile: %(doc_profile)s
|
||||
"""
|
||||
try:
|
||||
|
|
@ -254,7 +254,7 @@ class TextCommands(object):
|
|||
def _contextValid(self, mess_data, cmd_data):
|
||||
"""Tell if a command can be used in the given context
|
||||
|
||||
@param mess_data(dict): message data as given in messageSend trigger
|
||||
@param mess_data(dict): message data as given in sendMessage trigger
|
||||
@param cmd_data(dict): command data as returned by self._parseDocString
|
||||
@return (bool): True if command can be used in this context
|
||||
"""
|
||||
|
|
@ -290,7 +290,7 @@ class TextCommands(object):
|
|||
mess_data["type"] = C.MESS_TYPE_INFO
|
||||
mess_data["message"] = {'': message}
|
||||
mess_data["extra"]["info_type"] = info_type
|
||||
self.host.messageSendToBridge(mess_data, client)
|
||||
self.host.sendMessageToBridge(mess_data, client)
|
||||
|
||||
def cmd_whois(self, client, mess_data):
|
||||
"""show informations on entity
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class UploadPlugin(object):
|
|||
continue # no entity managing this extension found
|
||||
|
||||
log.info(u"{name} method will be used to upload the file".format(name=method_name))
|
||||
progress_id_d, download_d = yield defer.maybeDeferred(upload_cb, filepath, filename, upload_jid, options, client.profile)
|
||||
progress_id_d, download_d = yield upload_cb(filepath, filename, upload_jid, options, client.profile)
|
||||
progress_id = yield progress_id_d
|
||||
defer.returnValue((progress_id, download_d))
|
||||
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ class Welcome(object):
|
|||
self.host = host
|
||||
host.memory.updateParams(PARAMS)
|
||||
|
||||
def profileConnected(self, profile):
|
||||
def profileConnected(self, client):
|
||||
# XXX: if you wan to try first_start again, you'll have to remove manually
|
||||
# the welcome value from your profile params in sat.db
|
||||
welcome = self.host.memory.params.getParamA(WELCOME_PARAM_NAME, WELCOME_PARAM_CATEGORY, use_default=False, profile_key=profile)
|
||||
welcome = self.host.memory.params.getParamA(WELCOME_PARAM_NAME, WELCOME_PARAM_CATEGORY, use_default=False, profile_key=client.profile)
|
||||
if welcome is None:
|
||||
first_start = True
|
||||
welcome = True
|
||||
|
|
@ -82,10 +82,10 @@ class Welcome(object):
|
|||
|
||||
if welcome:
|
||||
xmlui = xml_tools.note(WELCOME_MSG, WELCOME_MSG_TITLE)
|
||||
self.host.actionNew({'xmlui': xmlui.toXml()}, profile=profile)
|
||||
self.host.memory.setParam(WELCOME_PARAM_NAME, C.BOOL_FALSE, WELCOME_PARAM_CATEGORY, profile_key=profile)
|
||||
self.host.actionNew({'xmlui': xmlui.toXml()}, profile=client.profile)
|
||||
self.host.memory.setParam(WELCOME_PARAM_NAME, C.BOOL_FALSE, WELCOME_PARAM_CATEGORY, profile_key=client.profile)
|
||||
|
||||
self.host.trigger.point("WELCOME", first_start, welcome, profile)
|
||||
self.host.trigger.point("WELCOME", first_start, welcome, client.profile)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class Context(potr.context.Context):
|
|||
def inject(self, msg_str, appdata=None):
|
||||
"""Inject encrypted data in the stream
|
||||
|
||||
if appdata is not None, we are sending a message in sendMessageFinishTrigger
|
||||
if appdata is not None, we are sending a message in sendMessageDataTrigger
|
||||
stanza will be injected directly if appdata is None, else we just update the element
|
||||
and follow normal workflow
|
||||
@param msg_str(str): encrypted message body
|
||||
|
|
@ -103,7 +103,7 @@ class Context(potr.context.Context):
|
|||
'extra': {},
|
||||
'timestamp': time.time(),
|
||||
}
|
||||
self.host.generateMessageXML(mess_data)
|
||||
client.generateMessageXML(mess_data)
|
||||
client.send(mess_data['xml'])
|
||||
else:
|
||||
message_elt = appdata[u'xml']
|
||||
|
|
@ -234,8 +234,8 @@ class OTR(object):
|
|||
self._p_hints = host.plugins[u'XEP-0334']
|
||||
self._p_carbons = host.plugins[u'XEP-0280']
|
||||
host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=100000)
|
||||
host.trigger.add("messageSend", self.messageSendTrigger, priority=100000)
|
||||
host.trigger.add("sendMessageFinish", self._sendMessageFinishTrigger)
|
||||
host.trigger.add("sendMessage", self.sendMessageTrigger, priority=100000)
|
||||
host.trigger.add("sendMessageData", self._sendMessageDataTrigger)
|
||||
host.bridge.addMethod("skipOTR", ".plugin", in_sign='s', out_sign='', method=self._skipOTR) # FIXME: must be removed, must be done on per-message basis
|
||||
host.bridge.addSignal("otrState", ".plugin", signature='sss') # args: state, destinee_jid, profile
|
||||
host.importMenu((OTR_MENU, D_(u"Start/Refresh")), self._otrStartRefresh, security_limit=0, help_string=D_(u"Start or refresh an OTR session"), type_=C.MENU_SINGLE)
|
||||
|
|
@ -255,26 +255,24 @@ class OTR(object):
|
|||
self.skipped_profiles.add(profile)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def profileConnected(self, profile):
|
||||
if profile in self.skipped_profiles:
|
||||
def profileConnected(self, client):
|
||||
if client.profile in self.skipped_profiles:
|
||||
return
|
||||
client = self.host.getClient(profile)
|
||||
ctxMng = client._otr_context_manager = ContextManager(self.host, client)
|
||||
client._otr_data = persistent.PersistentBinaryDict(NS_OTR, profile)
|
||||
client._otr_data = persistent.PersistentBinaryDict(NS_OTR, client.profile)
|
||||
yield client._otr_data.load()
|
||||
encrypted_priv_key = client._otr_data.get(PRIVATE_KEY, None)
|
||||
if encrypted_priv_key is not None:
|
||||
priv_key = yield self.host.memory.decryptValue(encrypted_priv_key, profile)
|
||||
priv_key = yield self.host.memory.decryptValue(encrypted_priv_key, client.profile)
|
||||
ctxMng.account.privkey = potr.crypt.PK.parsePrivateKey(priv_key.decode('hex'))[0]
|
||||
else:
|
||||
ctxMng.account.privkey = None
|
||||
ctxMng.account.loadTrusts()
|
||||
|
||||
def profileDisconnected(self, profile):
|
||||
if profile in self.skipped_profiles:
|
||||
self.skipped_profiles.remove(profile)
|
||||
def profileDisconnected(self, client):
|
||||
if client.profile in self.skipped_profiles:
|
||||
self.skipped_profiles.remove(client.profile)
|
||||
return
|
||||
client = self.host.getClient(profile)
|
||||
for context in client._otr_context_manager.contexts.values():
|
||||
context.disconnect()
|
||||
del client._otr_context_manager
|
||||
|
|
@ -454,7 +452,7 @@ class OTR(object):
|
|||
jid = from_jid.full()))
|
||||
|
||||
feedback=D_(u"WARNING: received unencrypted data in a supposedly encrypted context"),
|
||||
client.feedback(from_jid.full(), feedback)
|
||||
client.feedback(from_jid, feedback)
|
||||
except StopIteration:
|
||||
return data
|
||||
else:
|
||||
|
|
@ -505,7 +503,7 @@ class OTR(object):
|
|||
post_treat.addCallback(self._receivedTreatment, client)
|
||||
return True
|
||||
|
||||
def _sendMessageFinishTrigger(self, client, mess_data):
|
||||
def _sendMessageDataTrigger(self, client, mess_data):
|
||||
if not 'OTR' in mess_data:
|
||||
return
|
||||
otrctx = mess_data['OTR']
|
||||
|
|
@ -532,9 +530,11 @@ class OTR(object):
|
|||
else:
|
||||
feedback = D_(u"Your message was not sent because your correspondent closed the encrypted conversation on his/her side. "
|
||||
u"Either close your own side, or refresh the session.")
|
||||
client.feedback(to_jid.full(), feedback)
|
||||
log.warning(_(u"Message discarded because closed encryption channel"))
|
||||
client.feedback(to_jid, feedback)
|
||||
raise failure.Failure(exceptions.CancelError(u'Cancelled by OTR plugin'))
|
||||
|
||||
def messageSendTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments):
|
||||
def sendMessageTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments):
|
||||
if mess_data['type'] == 'groupchat':
|
||||
return True
|
||||
if client.profile in self.skipped_profiles: # FIXME: should not be done on a per-profile basis
|
||||
|
|
@ -546,7 +546,7 @@ class OTR(object):
|
|||
if otrctx.state != potr.context.STATE_PLAINTEXT:
|
||||
self._p_hints.addHint(mess_data, self._p_hints.HINT_NO_COPY)
|
||||
self._p_hints.addHint(mess_data, self._p_hints.HINT_NO_PERMANENT_STORE)
|
||||
mess_data['OTR'] = otrctx # this indicate that encryption is needed in sendMessageFinish trigger
|
||||
mess_data['OTR'] = otrctx # this indicate that encryption is needed in sendMessageData trigger
|
||||
if not mess_data['to'].resource: # if not resource was given, we force it here
|
||||
mess_data['to'] = to_jid
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class XEP_0020(object):
|
|||
def __init__(self, host):
|
||||
log.info(_("Plugin XEP_0020 initialization"))
|
||||
|
||||
def getHandler(self, profile):
|
||||
def getHandler(self, client):
|
||||
return XEP_0020_handler()
|
||||
|
||||
def getFeatureElt(self, elt):
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ class XEP_0033(object):
|
|||
log.info(_("Extended Stanza Addressing plugin initialization"))
|
||||
self.host = host
|
||||
self.internal_data = {}
|
||||
host.trigger.add("messageSend", self.messageSendTrigger, trigger.TriggerManager.MIN_PRIORITY)
|
||||
host.trigger.add("sendMessage", self.sendMessageTrigger, trigger.TriggerManager.MIN_PRIORITY)
|
||||
host.trigger.add("MessageReceived", self.messageReceivedTrigger)
|
||||
|
||||
def messageSendTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments):
|
||||
def sendMessageTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments):
|
||||
"""Process the XEP-0033 related data to be sent"""
|
||||
profile = client.profile
|
||||
|
||||
|
|
@ -124,9 +124,9 @@ class XEP_0033(object):
|
|||
client = self.host.profiles[profile]
|
||||
d = defer.Deferred()
|
||||
if not skip_send:
|
||||
d.addCallback(client.sendMessage)
|
||||
d.addCallback(client.sendMessageData)
|
||||
d.addCallback(self.host.messageAddToHistory, client)
|
||||
d.addCallback(self.host.messageSendToBridge, client)
|
||||
d.addCallback(self.host.sendMessageToBridge, client)
|
||||
d.addErrback(lambda failure: failure.trap(exceptions.CancelError))
|
||||
return d.callback(mess_data)
|
||||
|
||||
|
|
@ -181,8 +181,8 @@ class XEP_0033(object):
|
|||
post_treat.addCallback(post_treat_addr, addresses.children)
|
||||
return True
|
||||
|
||||
def getHandler(self, profile):
|
||||
return XEP_0033_handler(self, profile)
|
||||
def getHandler(self, client):
|
||||
return XEP_0033_handler(self, client.profile)
|
||||
|
||||
|
||||
class XEP_0033_handler(XMPPHandler):
|
||||
|
|
|
|||
|
|
@ -104,11 +104,10 @@ class XEP_0045(object):
|
|||
host.trigger.add("presence_available", self.presenceTrigger)
|
||||
host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=1000000)
|
||||
|
||||
def profileConnected(self, profile):
|
||||
def profileConnected(self, client):
|
||||
def assign_service(service):
|
||||
client = self.host.getClient(profile)
|
||||
client.muc_service = service
|
||||
return self.getMUCService(profile=profile).addCallback(assign_service)
|
||||
return self.getMUCService(profile=client.profile).addCallback(assign_service)
|
||||
|
||||
def MessageReceivedTrigger(self, client, message_elt, post_treat):
|
||||
if message_elt.getAttribute("type") == C.MESS_TYPE_GROUPCHAT:
|
||||
|
|
@ -477,9 +476,8 @@ class XEP_0045(object):
|
|||
self.checkRoomJoined(client, room_jid)
|
||||
return client._muc_client.subject(room_jid, subject)
|
||||
|
||||
def getHandler(self, profile):
|
||||
def getHandler(self, client):
|
||||
# create a MUC client and associate it with profile' session
|
||||
client = self.host.getClient(profile)
|
||||
muc_client = client._muc_client = SatMUCClient(self)
|
||||
return muc_client
|
||||
|
||||
|
|
@ -886,7 +884,7 @@ class SatMUCClient(muc.MUCClient):
|
|||
"timestamp": time.time(),
|
||||
}
|
||||
self.host.messageAddToHistory(mess_data, self.parent)
|
||||
self.host.messageSendToBridge(mess_data, self.parent)
|
||||
self.host.sendMessageToBridge(mess_data, self.parent)
|
||||
|
||||
|
||||
def userLeftRoom(self, room, user):
|
||||
|
|
@ -925,7 +923,7 @@ class SatMUCClient(muc.MUCClient):
|
|||
"timestamp": time.time(),
|
||||
}
|
||||
self.host.messageAddToHistory(mess_data, self.parent)
|
||||
self.host.messageSendToBridge(mess_data, self.parent)
|
||||
self.host.sendMessageToBridge(mess_data, self.parent)
|
||||
|
||||
def userChangedNick(self, room, user, new_nick):
|
||||
self.host.bridge.mucRoomUserChangedNick(room.roomJID.userhost(), user.nick, new_nick, self.parent.profile)
|
||||
|
|
|
|||
|
|
@ -69,11 +69,10 @@ class XEP_0047(object):
|
|||
log.info(_("In-Band Bytestreams plugin initialization"))
|
||||
self.host = host
|
||||
|
||||
def getHandler(self, profile):
|
||||
def getHandler(self, client):
|
||||
return XEP_0047_handler(self)
|
||||
|
||||
def profileConnected(self, profile):
|
||||
client = self.host.getClient(profile)
|
||||
def profileConnected(self, client):
|
||||
client.xep_0047_current_stream = {} # key: stream_id, value: data(dict)
|
||||
|
||||
def _timeOut(self, sid, client):
|
||||
|
|
|
|||
|
|
@ -73,14 +73,13 @@ class XEP_0048(object):
|
|||
log.info(_("Text commands not available"))
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def profileConnected(self, profile):
|
||||
client = self.host.getClient(profile)
|
||||
local = client.bookmarks_local = PersistentBinaryDict(NS_BOOKMARKS, profile)
|
||||
def profileConnected(self, client):
|
||||
local = client.bookmarks_local = PersistentBinaryDict(NS_BOOKMARKS, client.profile)
|
||||
yield local.load()
|
||||
if not local:
|
||||
local[XEP_0048.MUC_TYPE] = dict()
|
||||
local[XEP_0048.URL_TYPE] = dict()
|
||||
private = yield self._getServerBookmarks('private', profile)
|
||||
private = yield self._getServerBookmarks('private', client.profile)
|
||||
pubsub = client.bookmarks_pubsub = None
|
||||
|
||||
for bookmarks in (local, private, pubsub):
|
||||
|
|
|
|||
|
|
@ -221,15 +221,15 @@ class XEP_0050(object):
|
|||
self.__requesting_id = host.registerCallback(self._requestingEntity, with_data=True)
|
||||
host.importMenu((D_("Service"), D_("Commands")), self._commandsMenu, security_limit=2, help_string=D_("Execute ad-hoc commands"))
|
||||
|
||||
def getHandler(self, profile):
|
||||
def getHandler(self, client):
|
||||
return XEP_0050_handler(self)
|
||||
|
||||
def profileConnected(self, profile):
|
||||
self.addAdHocCommand(self._statusCallback, _("Status"), profile_key=profile)
|
||||
def profileConnected(self, client):
|
||||
self.addAdHocCommand(self._statusCallback, _("Status"), profile_key=client.profile)
|
||||
|
||||
def profileDisconnected(self, profile):
|
||||
def profileDisconnected(self, client):
|
||||
try:
|
||||
del self.answering[profile]
|
||||
del self.answering[client.profile]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue