Modules: Use LogAdapter
- Make all modules inherit from BaseModule - Use LogAdapter in BaseModule
This commit is contained in:
parent
6e672c9911
commit
0eb75eb73d
41 changed files with 556 additions and 678 deletions
|
@ -19,18 +19,15 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
from gajim.common.i18n import _
|
from gajim.common.i18n import _
|
||||||
from gajim.common.modules import dataforms
|
|
||||||
|
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules import dataforms
|
||||||
log = logging.getLogger('gajim.c.m.commands')
|
from gajim.common.modules.base import BaseModule
|
||||||
|
|
||||||
|
|
||||||
class AdHocCommand:
|
class AdHocCommand:
|
||||||
|
@ -298,13 +295,15 @@ class LeaveGroupchatsCommand(AdHocCommand):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class AdHocCommands:
|
class AdHocCommands(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._execute_command_received, 'set', nbxmpp.NS_COMMANDS)
|
StanzaHandler(name='iq',
|
||||||
|
callback=self._execute_command_received,
|
||||||
|
typ='set',
|
||||||
|
ns=nbxmpp.NS_COMMANDS),
|
||||||
]
|
]
|
||||||
|
|
||||||
# a list of all commands exposed: node -> command class
|
# a list of all commands exposed: node -> command class
|
||||||
|
@ -350,7 +349,7 @@ class AdHocCommands:
|
||||||
try:
|
try:
|
||||||
jid = helpers.get_full_jid_from_iq(stanza)
|
jid = helpers.get_full_jid_from_iq(stanza)
|
||||||
except helpers.InvalidFormat:
|
except helpers.InvalidFormat:
|
||||||
log.warning('Invalid JID: %s, ignoring it', stanza.getFrom())
|
self._log.warning('Invalid JID: %s, ignoring it', stanza.getFrom())
|
||||||
return
|
return
|
||||||
node = stanza.getTagAttr('query', 'node')
|
node = stanza.getTagAttr('query', 'node')
|
||||||
|
|
||||||
|
@ -393,17 +392,17 @@ class AdHocCommands:
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _execute_command_received(self, _con, stanza):
|
def _execute_command_received(self, _con, stanza, _properties):
|
||||||
jid = helpers.get_full_jid_from_iq(stanza)
|
jid = helpers.get_full_jid_from_iq(stanza)
|
||||||
|
|
||||||
cmd = stanza.getTag('command')
|
cmd = stanza.getTag('command')
|
||||||
if cmd is None:
|
if cmd is None:
|
||||||
log.error('Malformed stanza (no command node) %s', stanza)
|
self._log.error('Malformed stanza (no command node) %s', stanza)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
node = cmd.getAttr('node')
|
node = cmd.getAttr('node')
|
||||||
if node is None:
|
if node is None:
|
||||||
log.error('Malformed stanza (no node attr) %s', stanza)
|
self._log.error('Malformed stanza (no node attr) %s', stanza)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
sessionid = cmd.getAttr('sessionid')
|
sessionid = cmd.getAttr('sessionid')
|
||||||
|
@ -414,12 +413,12 @@ class AdHocCommands:
|
||||||
self._con.connection.send(
|
self._con.connection.send(
|
||||||
nbxmpp.Error(
|
nbxmpp.Error(
|
||||||
stanza, nbxmpp.NS_STANZAS + ' item-not-found'))
|
stanza, nbxmpp.NS_STANZAS + ' item-not-found'))
|
||||||
log.warning('Comand %s does not exist: %s', node, jid)
|
self._log.warning('Comand %s does not exist: %s', node, jid)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
newcmd = self._commands[node]
|
newcmd = self._commands[node]
|
||||||
if not newcmd.is_visible_for(self.is_same_jid(jid)):
|
if not newcmd.is_visible_for(self.is_same_jid(jid)):
|
||||||
log.warning('Command not visible for jid: %s', jid)
|
self._log.warning('Command not visible for jid: %s', jid)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
# generate new sessionid
|
# generate new sessionid
|
||||||
|
@ -430,14 +429,14 @@ class AdHocCommands:
|
||||||
rc = obj.execute(stanza)
|
rc = obj.execute(stanza)
|
||||||
if rc:
|
if rc:
|
||||||
self._sessions[(jid, sessionid, node)] = obj
|
self._sessions[(jid, sessionid, node)] = obj
|
||||||
log.info('Comand %s executed: %s', node, jid)
|
self._log.info('Comand %s executed: %s', node, jid)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
else:
|
else:
|
||||||
# the command is already running, check for it
|
# the command is already running, check for it
|
||||||
magictuple = (jid, sessionid, node)
|
magictuple = (jid, sessionid, node)
|
||||||
if magictuple not in self._sessions:
|
if magictuple not in self._sessions:
|
||||||
# we don't have this session... ha!
|
# we don't have this session... ha!
|
||||||
log.warning('Invalid session %s', magictuple)
|
self._log.warning('Invalid session %s', magictuple)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
action = cmd.getAttr('action')
|
action = cmd.getAttr('action')
|
||||||
|
@ -461,7 +460,7 @@ class AdHocCommands:
|
||||||
# the command probably doesn't handle invoked action...
|
# the command probably doesn't handle invoked action...
|
||||||
# stop the session, return error
|
# stop the session, return error
|
||||||
del self._sessions[magictuple]
|
del self._sessions[magictuple]
|
||||||
log.warning('Wrong action %s %s', node, jid)
|
self._log.warning('Wrong action %s %s', node, jid)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
# delete the session if rc is False
|
# delete the session if rc is False
|
||||||
|
@ -474,7 +473,7 @@ class AdHocCommands:
|
||||||
"""
|
"""
|
||||||
Request the command list.
|
Request the command list.
|
||||||
"""
|
"""
|
||||||
log.info('Request Command List: %s', jid)
|
self._log.info('Request Command List: %s', jid)
|
||||||
query = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_DISCO_ITEMS)
|
query = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_DISCO_ITEMS)
|
||||||
query.setQuerynode(nbxmpp.NS_COMMANDS)
|
query.setQuerynode(nbxmpp.NS_COMMANDS)
|
||||||
|
|
||||||
|
@ -483,7 +482,7 @@ class AdHocCommands:
|
||||||
|
|
||||||
def _command_list_received(self, stanza):
|
def _command_list_received(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
AdHocCommandError(None, conn=self._con,
|
AdHocCommandError(None, conn=self._con,
|
||||||
|
@ -497,7 +496,7 @@ class AdHocCommands:
|
||||||
(t.getAttr('node'), t.getAttr('name')) for t in items
|
(t.getAttr('node'), t.getAttr('name')) for t in items
|
||||||
]
|
]
|
||||||
|
|
||||||
log.info('Received: %s', commandlist)
|
self._log.info('Received: %s', commandlist)
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
AdHocCommandListReceived(
|
AdHocCommandListReceived(
|
||||||
None, conn=self._con, commandlist=commandlist))
|
None, conn=self._con, commandlist=commandlist))
|
||||||
|
@ -507,7 +506,7 @@ class AdHocCommands:
|
||||||
"""
|
"""
|
||||||
Send the command with data form. Wait for reply
|
Send the command with data form. Wait for reply
|
||||||
"""
|
"""
|
||||||
log.info('Send Command: %s %s %s %s', jid, node, session_id, action)
|
self._log.info('Send Command: %s %s %s %s', jid, node, session_id, action)
|
||||||
stanza = nbxmpp.Iq(typ='set', to=jid)
|
stanza = nbxmpp.Iq(typ='set', to=jid)
|
||||||
cmdnode = stanza.addChild('command',
|
cmdnode = stanza.addChild('command',
|
||||||
namespace=nbxmpp.NS_COMMANDS,
|
namespace=nbxmpp.NS_COMMANDS,
|
||||||
|
@ -525,13 +524,13 @@ class AdHocCommands:
|
||||||
|
|
||||||
def _action_response_received(self, stanza):
|
def _action_response_received(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
AdHocCommandError(None, conn=self._con,
|
AdHocCommandError(None, conn=self._con,
|
||||||
error=stanza.getError()))
|
error=stanza.getError()))
|
||||||
return
|
return
|
||||||
log.info('Received action response')
|
self._log.info('Received action response')
|
||||||
command = stanza.getTag('command')
|
command = stanza.getTag('command')
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
AdHocCommandActionResponse(
|
AdHocCommandActionResponse(
|
||||||
|
@ -541,7 +540,7 @@ class AdHocCommands:
|
||||||
"""
|
"""
|
||||||
Send the command with action='cancel'
|
Send the command with action='cancel'
|
||||||
"""
|
"""
|
||||||
log.info('Cancel: %s %s %s', jid, node, session_id)
|
self._log.info('Cancel: %s %s %s', jid, node, session_id)
|
||||||
stanza = nbxmpp.Iq(typ='set', to=jid)
|
stanza = nbxmpp.Iq(typ='set', to=jid)
|
||||||
stanza.addChild('command', namespace=nbxmpp.NS_COMMANDS,
|
stanza.addChild('command', namespace=nbxmpp.NS_COMMANDS,
|
||||||
attrs={
|
attrs={
|
||||||
|
@ -553,12 +552,11 @@ class AdHocCommands:
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
stanza, self._cancel_result_received)
|
stanza, self._cancel_result_received)
|
||||||
|
|
||||||
@staticmethod
|
def _cancel_result_received(self, stanza):
|
||||||
def _cancel_result_received(stanza):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.warning('Error: %s', stanza.getError())
|
self._log.warning('Error: %s', stanza.getError())
|
||||||
else:
|
else:
|
||||||
log.info('Cancel successful')
|
self._log.info('Cancel successful')
|
||||||
|
|
||||||
|
|
||||||
class AdHocCommandError(NetworkIncomingEvent):
|
class AdHocCommandError(NetworkIncomingEvent):
|
||||||
|
|
|
@ -18,15 +18,11 @@ from typing import Any
|
||||||
from typing import Dict # pylint: disable=unused-import
|
from typing import Dict # pylint: disable=unused-import
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from nbxmpp.util import is_error_result
|
from nbxmpp.util import is_error_result
|
||||||
|
|
||||||
from gajim.common.types import ConnectionT
|
from gajim.common.types import ConnectionT
|
||||||
from gajim.common.modules.base import BaseModule
|
from gajim.common.modules.base import BaseModule
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.annotations')
|
|
||||||
|
|
||||||
|
|
||||||
class Annotations(BaseModule):
|
class Annotations(BaseModule):
|
||||||
|
|
||||||
|
|
|
@ -26,29 +26,33 @@ from nbxmpp.structs import StanzaHandler
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.modules.util import LogAdapter
|
from gajim.common.modules.util import LogAdapter
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.base')
|
|
||||||
|
|
||||||
|
|
||||||
class BaseModule:
|
class BaseModule:
|
||||||
|
|
||||||
_nbxmpp_extends = ''
|
_nbxmpp_extends = ''
|
||||||
_nbxmpp_methods = [] # type: List[str]
|
_nbxmpp_methods = [] # type: List[str]
|
||||||
|
|
||||||
def __init__(self, con, logger=None):
|
def __init__(self, con, *args, plugin=False, **kwargs):
|
||||||
self._con = con
|
self._con = con
|
||||||
self._account = con.name
|
self._account = con.name
|
||||||
if logger is not None:
|
self._log = self._set_logger(plugin)
|
||||||
self._log = LogAdapter(logger, {'account': self._account})
|
|
||||||
self._nbxmpp_callbacks = {} # type: Dict[str, Any]
|
self._nbxmpp_callbacks = {} # type: Dict[str, Any]
|
||||||
self._stored_publish = None # type: Callable
|
self._stored_publish = None # type: Callable
|
||||||
self.handlers = [] # type: List[str]
|
self.handlers = [] # type: List[str]
|
||||||
|
|
||||||
|
def _set_logger(self, plugin):
|
||||||
|
logger_name = 'gajim.c.m.%s'
|
||||||
|
if plugin:
|
||||||
|
logger_name = 'gajim.p.%s'
|
||||||
|
logger_name = logger_name % self.__class__.__name__.lower()
|
||||||
|
logger = logging.getLogger(logger_name)
|
||||||
|
return LogAdapter(logger, {'account': self._account})
|
||||||
|
|
||||||
def __getattr__(self, key):
|
def __getattr__(self, key):
|
||||||
if key not in self._nbxmpp_methods:
|
if key not in self._nbxmpp_methods:
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
if not app.account_is_connected(self._account):
|
if not app.account_is_connected(self._account):
|
||||||
log.warning('Account %s not connected, cant use %s',
|
self._log.warning('Account not connected, cant use %s', key)
|
||||||
self._account, key)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
module = self._con.connection.get_module(self._nbxmpp_extends)
|
module = self._con.connection.get_module(self._nbxmpp_extends)
|
||||||
|
@ -60,8 +64,7 @@ class BaseModule:
|
||||||
|
|
||||||
def _nbxmpp(self, module_name=None):
|
def _nbxmpp(self, module_name=None):
|
||||||
if not app.account_is_connected(self._account):
|
if not app.account_is_connected(self._account):
|
||||||
log.warning('Account %s not connected, cant use nbxmpp method',
|
self._log.warning('Account not connected, cant use nbxmpp method')
|
||||||
self._account)
|
|
||||||
return Mock()
|
return Mock()
|
||||||
|
|
||||||
if module_name is None:
|
if module_name is None:
|
||||||
|
@ -81,5 +84,5 @@ class BaseModule:
|
||||||
def send_stored_publish(self):
|
def send_stored_publish(self):
|
||||||
if self._stored_publish is None:
|
if self._stored_publish is None:
|
||||||
return
|
return
|
||||||
log.info('Send stored publish')
|
self._log.info('Send stored publish')
|
||||||
self._stored_publish()
|
self._stored_publish()
|
||||||
|
|
|
@ -20,31 +20,35 @@ from base64 import b64decode
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common import configpaths
|
from gajim.common import configpaths
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.bob')
|
log = logging.getLogger('gajim.c.m.bob')
|
||||||
|
|
||||||
|
|
||||||
class BitsOfBinary:
|
class BitsOfBinary(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._answer_bob_request, 'get', nbxmpp.NS_BOB)
|
StanzaHandler(name='iq',
|
||||||
|
callback=self._answer_bob_request,
|
||||||
|
typ='get',
|
||||||
|
ns=nbxmpp.NS_BOB),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Used to track which cids are in-flight.
|
# Used to track which cids are in-flight.
|
||||||
self.awaiting_cids = {}
|
self.awaiting_cids = {}
|
||||||
|
|
||||||
def _answer_bob_request(self, _con, stanza):
|
def _answer_bob_request(self, _con, stanza, _properties):
|
||||||
log.info('Request from %s for BoB data', stanza.getFrom())
|
self._log.info('Request from %s for BoB data', stanza.getFrom())
|
||||||
iq = stanza.buildReply('error')
|
iq = stanza.buildReply('error')
|
||||||
err = nbxmpp.ErrorNode(nbxmpp.ERR_ITEM_NOT_FOUND)
|
err = nbxmpp.ErrorNode(nbxmpp.ERR_ITEM_NOT_FOUND)
|
||||||
iq.addChild(node=err)
|
iq.addChild(node=err)
|
||||||
log.info('Sending item-not-found')
|
self._log.info('Sending item-not-found')
|
||||||
self._con.connection.send(iq)
|
self._con.connection.send(iq)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,8 @@
|
||||||
|
|
||||||
# XEP-0191: Blocking Command
|
# XEP-0191: Blocking Command
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
from nbxmpp.util import is_error_result
|
from nbxmpp.util import is_error_result
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
@ -24,8 +23,6 @@ from gajim.common.nec import NetworkEvent
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
from gajim.common.modules.base import BaseModule
|
from gajim.common.modules.base import BaseModule
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.blocking')
|
|
||||||
|
|
||||||
|
|
||||||
class Blocking(BaseModule):
|
class Blocking(BaseModule):
|
||||||
|
|
||||||
|
@ -42,7 +39,10 @@ class Blocking(BaseModule):
|
||||||
self.blocked = []
|
self.blocked = []
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._blocking_push_received, 'set', nbxmpp.NS_BLOCKING)
|
StanzaHandler(name='iq',
|
||||||
|
callback=self._blocking_push_received,
|
||||||
|
typ='set',
|
||||||
|
ns=nbxmpp.NS_BLOCKING),
|
||||||
]
|
]
|
||||||
|
|
||||||
self._register_callback('get_blocking_list',
|
self._register_callback('get_blocking_list',
|
||||||
|
@ -60,18 +60,18 @@ class Blocking(BaseModule):
|
||||||
account=self._account,
|
account=self._account,
|
||||||
feature=nbxmpp.NS_BLOCKING))
|
feature=nbxmpp.NS_BLOCKING))
|
||||||
|
|
||||||
log.info('Discovered blocking: %s', from_)
|
self._log.info('Discovered blocking: %s', from_)
|
||||||
|
|
||||||
def _blocking_list_received(self, result):
|
def _blocking_list_received(self, result):
|
||||||
if is_error_result(result):
|
if is_error_result(result):
|
||||||
log.info('Error: %s', result)
|
self._log.info('Error: %s', result)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.blocked = result.blocking_list
|
self.blocked = result.blocking_list
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
BlockingEvent(None, conn=self._con, changed=self.blocked))
|
BlockingEvent(None, conn=self._con, changed=self.blocked))
|
||||||
|
|
||||||
def _blocking_push_received(self, _con, stanza):
|
def _blocking_push_received(self, _con, stanza, _properties):
|
||||||
reply = stanza.buildReply('result')
|
reply = stanza.buildReply('result')
|
||||||
childs = reply.getChildren()
|
childs = reply.getChildren()
|
||||||
for child in childs:
|
for child in childs:
|
||||||
|
@ -89,7 +89,7 @@ class Blocking(BaseModule):
|
||||||
self.blocked = []
|
self.blocked = []
|
||||||
for jid in self.blocked:
|
for jid in self.blocked:
|
||||||
self._presence_probe(jid)
|
self._presence_probe(jid)
|
||||||
log.info('Unblock all Push')
|
self._log.info('Unblock all Push')
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
|
@ -100,7 +100,7 @@ class Blocking(BaseModule):
|
||||||
continue
|
continue
|
||||||
self.blocked.remove(jid)
|
self.blocked.remove(jid)
|
||||||
self._presence_probe(jid)
|
self._presence_probe(jid)
|
||||||
log.info('Unblock Push: %s', jid)
|
self._log.info('Unblock Push: %s', jid)
|
||||||
|
|
||||||
block = stanza.getTag('block', namespace=nbxmpp.NS_BLOCKING)
|
block = stanza.getTag('block', namespace=nbxmpp.NS_BLOCKING)
|
||||||
if block is not None:
|
if block is not None:
|
||||||
|
@ -111,7 +111,7 @@ class Blocking(BaseModule):
|
||||||
changed_list.append(jid)
|
changed_list.append(jid)
|
||||||
self.blocked.append(jid)
|
self.blocked.append(jid)
|
||||||
self._set_contact_offline(jid)
|
self._set_contact_offline(jid)
|
||||||
log.info('Block Push: %s', jid)
|
self._log.info('Block Push: %s', jid)
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
BlockingEvent(None, conn=self._con, changed=changed_list))
|
BlockingEvent(None, conn=self._con, changed=changed_list))
|
||||||
|
@ -124,7 +124,7 @@ class Blocking(BaseModule):
|
||||||
contact.show = 'offline'
|
contact.show = 'offline'
|
||||||
|
|
||||||
def _presence_probe(self, jid: str) -> None:
|
def _presence_probe(self, jid: str) -> None:
|
||||||
log.info('Presence probe: %s', jid)
|
self._log.info('Presence probe: %s', jid)
|
||||||
# Send a presence Probe to get the current Status
|
# Send a presence Probe to get the current Status
|
||||||
probe = nbxmpp.Presence(jid, 'probe', frm=self._con.get_own_jid())
|
probe = nbxmpp.Presence(jid, 'probe', frm=self._con.get_own_jid())
|
||||||
self._nbxmpp().send(probe)
|
self._nbxmpp().send(probe)
|
||||||
|
|
|
@ -18,7 +18,6 @@ from typing import Any
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import logging
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
@ -33,9 +32,6 @@ from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.modules.util import event_node
|
from gajim.common.modules.util import event_node
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.bookmarks')
|
|
||||||
|
|
||||||
|
|
||||||
class Bookmarks(BaseModule):
|
class Bookmarks(BaseModule):
|
||||||
|
|
||||||
_nbxmpp_extends = 'Bookmarks'
|
_nbxmpp_extends = 'Bookmarks'
|
||||||
|
@ -69,14 +65,15 @@ class Bookmarks(BaseModule):
|
||||||
bookmarks = properties.pubsub_event.data
|
bookmarks = properties.pubsub_event.data
|
||||||
|
|
||||||
if not properties.is_self_message:
|
if not properties.is_self_message:
|
||||||
log.warning('%s has an open access bookmarks node', properties.jid)
|
self._log.warning('%s has an open access bookmarks node',
|
||||||
|
properties.jid)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self._pubsub_support() or not self.conversion:
|
if not self._pubsub_support() or not self.conversion:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._request_in_progress:
|
if self._request_in_progress:
|
||||||
log.info('Ignore update, pubsub request in progress')
|
self._log.info('Ignore update, pubsub request in progress')
|
||||||
return
|
return
|
||||||
|
|
||||||
old_bookmarks = self._convert_to_set(self._bookmarks)
|
old_bookmarks = self._convert_to_set(self._bookmarks)
|
||||||
|
@ -89,7 +86,7 @@ class Bookmarks(BaseModule):
|
||||||
if nbxmpp.NS_BOOKMARK_CONVERSION not in features:
|
if nbxmpp.NS_BOOKMARK_CONVERSION not in features:
|
||||||
return
|
return
|
||||||
self._conversion = True
|
self._conversion = True
|
||||||
log.info('Discovered Bookmarks Conversion: %s', from_)
|
self._log.info('Discovered Bookmarks Conversion: %s', from_)
|
||||||
|
|
||||||
def _act_on_changed_bookmarks(self, old_bookmarks):
|
def _act_on_changed_bookmarks(self, old_bookmarks):
|
||||||
new_bookmarks = self._convert_to_set(self._bookmarks)
|
new_bookmarks = self._convert_to_set(self._bookmarks)
|
||||||
|
@ -100,7 +97,7 @@ class Bookmarks(BaseModule):
|
||||||
join = [jid for jid, autojoin in changed if autojoin]
|
join = [jid for jid, autojoin in changed if autojoin]
|
||||||
bookmarks = []
|
bookmarks = []
|
||||||
for jid in join:
|
for jid in join:
|
||||||
log.info('Schedule autojoin in 10s for: %s', jid)
|
self._log.info('Schedule autojoin in 10s for: %s', jid)
|
||||||
bookmarks.append(self.get_bookmark_from_jid(jid))
|
bookmarks.append(self.get_bookmark_from_jid(jid))
|
||||||
# If another client creates a MUC, the MUC is locked until the
|
# If another client creates a MUC, the MUC is locked until the
|
||||||
# configuration is finished. Give the user some time to finish
|
# configuration is finished. Give the user some time to finish
|
||||||
|
@ -163,7 +160,7 @@ class Bookmarks(BaseModule):
|
||||||
|
|
||||||
def _bookmarks_received(self, bookmarks):
|
def _bookmarks_received(self, bookmarks):
|
||||||
if is_error_result(bookmarks):
|
if is_error_result(bookmarks):
|
||||||
log.info('Error: %s', bookmarks)
|
self._log.info('Error: %s', bookmarks)
|
||||||
bookmarks = []
|
bookmarks = []
|
||||||
|
|
||||||
self._request_in_progress = False
|
self._request_in_progress = False
|
||||||
|
@ -202,7 +199,7 @@ class Bookmarks(BaseModule):
|
||||||
# auto-joined on re-connection
|
# auto-joined on re-connection
|
||||||
if bookmark.jid not in app.gc_connected[self._account]:
|
if bookmark.jid not in app.gc_connected[self._account]:
|
||||||
# we are not already connected
|
# we are not already connected
|
||||||
log.info('Autojoin Bookmark: %s', bookmark.jid)
|
self._log.info('Autojoin Bookmark: %s', bookmark.jid)
|
||||||
minimize = app.config.get_per('rooms', bookmark.jid,
|
minimize = app.config.get_per('rooms', bookmark.jid,
|
||||||
'minimize_on_autojoin', True)
|
'minimize_on_autojoin', True)
|
||||||
app.interface.join_gc_room(
|
app.interface.join_gc_room(
|
||||||
|
@ -237,8 +234,8 @@ class Bookmarks(BaseModule):
|
||||||
return self.get_bookmark_from_jid(jid) is not None
|
return self.get_bookmark_from_jid(jid) is not None
|
||||||
|
|
||||||
def purge_pubsub_bookmarks(self) -> None:
|
def purge_pubsub_bookmarks(self) -> None:
|
||||||
log.info('Purge/Delete Bookmarks on PubSub, '
|
self._log.info('Purge/Delete Bookmarks on PubSub, '
|
||||||
'because publish options are not available')
|
'because publish options are not available')
|
||||||
self._con.get_module('PubSub').send_pb_purge('', 'storage:bookmarks')
|
self._con.get_module('PubSub').send_pb_purge('', 'storage:bookmarks')
|
||||||
self._con.get_module('PubSub').send_pb_delete('', 'storage:bookmarks')
|
self._con.get_module('PubSub').send_pb_delete('', 'storage:bookmarks')
|
||||||
|
|
||||||
|
|
|
@ -17,22 +17,18 @@
|
||||||
|
|
||||||
# XEP-0115: Entity Capabilities
|
# XEP-0115: Entity Capabilities
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
from nbxmpp.structs import StanzaHandler
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import caps_cache
|
from gajim.common import caps_cache
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.caps')
|
|
||||||
|
|
||||||
|
|
||||||
class Caps:
|
class Caps(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
StanzaHandler(name='presence',
|
StanzaHandler(name='presence',
|
||||||
|
@ -57,8 +53,9 @@ class Caps:
|
||||||
node = properties.entity_caps.node
|
node = properties.entity_caps.node
|
||||||
caps_hash = properties.entity_caps.ver
|
caps_hash = properties.entity_caps.ver
|
||||||
|
|
||||||
log.info('Received from %s, type: %s, method: %s, node: %s, hash: %s',
|
self._log.info(
|
||||||
jid, properties.type, hash_method, node, caps_hash)
|
'Received from %s, type: %s, method: %s, node: %s, hash: %s',
|
||||||
|
jid, properties.type, hash_method, node, caps_hash)
|
||||||
|
|
||||||
client_caps = self._create_suitable_client_caps(
|
client_caps = self._create_suitable_client_caps(
|
||||||
node, caps_hash, hash_method, jid)
|
node, caps_hash, hash_method, jid)
|
||||||
|
@ -85,7 +82,7 @@ class Caps:
|
||||||
if contact is not None:
|
if contact is not None:
|
||||||
contact.client_caps = client_caps
|
contact.client_caps = client_caps
|
||||||
else:
|
else:
|
||||||
log.info('Received Caps from unknown contact %s', from_)
|
self._log.info('Received Caps from unknown contact %s', from_)
|
||||||
|
|
||||||
def _get_contact_or_gc_contact_for_jid(self, from_):
|
def _get_contact_or_gc_contact_for_jid(self, from_):
|
||||||
contact = app.contacts.get_contact_from_full_jid(self._account,
|
contact = app.contacts.get_contact_from_full_jid(self._account,
|
||||||
|
@ -106,7 +103,7 @@ class Caps:
|
||||||
|
|
||||||
contact = self._get_contact_or_gc_contact_for_jid(from_)
|
contact = self._get_contact_or_gc_contact_for_jid(from_)
|
||||||
if not contact:
|
if not contact:
|
||||||
log.info('Received Disco from unknown contact %s', from_)
|
self._log.info('Received Disco from unknown contact %s', from_)
|
||||||
return
|
return
|
||||||
|
|
||||||
lookup = contact.client_caps.get_cache_lookup_strategy()
|
lookup = contact.client_caps.get_cache_lookup_strategy()
|
||||||
|
@ -126,7 +123,7 @@ class Caps:
|
||||||
node = caps_hash = hash_method = None
|
node = caps_hash = hash_method = None
|
||||||
contact.client_caps = self._create_suitable_client_caps(
|
contact.client_caps = self._create_suitable_client_caps(
|
||||||
node, caps_hash, hash_method)
|
node, caps_hash, hash_method)
|
||||||
log.warning(
|
self._log.warning(
|
||||||
'Computed and retrieved caps hash differ. Ignoring '
|
'Computed and retrieved caps hash differ. Ignoring '
|
||||||
'caps of contact %s', contact.get_full_jid())
|
'caps of contact %s', contact.get_full_jid())
|
||||||
|
|
||||||
|
|
|
@ -14,21 +14,15 @@
|
||||||
|
|
||||||
# XEP-0280: Message Carbons
|
# XEP-0280: Message Carbons
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.carbons')
|
|
||||||
|
|
||||||
|
|
||||||
class Carbons:
|
class Carbons(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
self.supported = False
|
self.supported = False
|
||||||
|
|
||||||
|
@ -37,16 +31,16 @@ class Carbons:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.supported = True
|
self.supported = True
|
||||||
log.info('Discovered carbons: %s', from_)
|
self._log.info('Discovered carbons: %s', from_)
|
||||||
|
|
||||||
if app.config.get_per('accounts', self._account,
|
if app.config.get_per('accounts', self._account,
|
||||||
'enable_message_carbons'):
|
'enable_message_carbons'):
|
||||||
iq = nbxmpp.Iq('set')
|
iq = nbxmpp.Iq('set')
|
||||||
iq.setTag('enable', namespace=nbxmpp.NS_CARBONS)
|
iq.setTag('enable', namespace=nbxmpp.NS_CARBONS)
|
||||||
log.info('Activate')
|
self._log.info('Activate')
|
||||||
self._con.connection.send(iq)
|
self._con.connection.send(iq)
|
||||||
else:
|
else:
|
||||||
log.warning('Carbons deactivated (user setting)')
|
self._log.warning('Carbons deactivated (user setting)')
|
||||||
|
|
||||||
|
|
||||||
def get_instance(*args, **kwargs):
|
def get_instance(*args, **kwargs):
|
||||||
|
|
|
@ -21,23 +21,23 @@ from typing import Optional
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import logging
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
from gajim.common.const import Chatstate as State
|
from gajim.common.const import Chatstate as State
|
||||||
from gajim.common.modules.misc import parse_delay
|
from gajim.common.modules.misc import parse_delay
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.connection_handlers_events import MessageOutgoingEvent
|
from gajim.common.connection_handlers_events import MessageOutgoingEvent
|
||||||
from gajim.common.connection_handlers_events import GcMessageOutgoingEvent
|
from gajim.common.connection_handlers_events import GcMessageOutgoingEvent
|
||||||
|
|
||||||
from gajim.common.types import ContactT
|
from gajim.common.types import ContactT
|
||||||
from gajim.common.types import ConnectionT
|
from gajim.common.types import ConnectionT
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.chatstates')
|
|
||||||
|
|
||||||
INACTIVE_AFTER = 60
|
INACTIVE_AFTER = 60
|
||||||
PAUSED_AFTER = 10
|
PAUSED_AFTER = 10
|
||||||
|
@ -63,13 +63,13 @@ def parse_chatstate(stanza: nbxmpp.Message) -> Optional[str]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class Chatstate:
|
class Chatstate(BaseModule):
|
||||||
def __init__(self, con: ConnectionT) -> None:
|
def __init__(self, con: ConnectionT) -> None:
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('presence', self._presence_received),
|
StanzaHandler(name='presence',
|
||||||
|
callback=self._presence_received),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Our current chatstate with a specific contact
|
# Our current chatstate with a specific contact
|
||||||
|
@ -90,7 +90,7 @@ class Chatstate:
|
||||||
def enabled(self, value):
|
def enabled(self, value):
|
||||||
if self._enabled == value:
|
if self._enabled == value:
|
||||||
return
|
return
|
||||||
log.info('Chatstate module %s', 'enabled' if value else 'disabled')
|
self._log.info('Chatstate module %s', 'enabled' if value else 'disabled')
|
||||||
self._enabled = value
|
self._enabled = value
|
||||||
|
|
||||||
if value:
|
if value:
|
||||||
|
@ -106,7 +106,8 @@ class Chatstate:
|
||||||
@ensure_enabled
|
@ensure_enabled
|
||||||
def _presence_received(self,
|
def _presence_received(self,
|
||||||
_con: ConnectionT,
|
_con: ConnectionT,
|
||||||
stanza: nbxmpp.Presence) -> None:
|
stanza: nbxmpp.Presence,
|
||||||
|
_properties: Any) -> None:
|
||||||
if stanza.getType() not in ('unavailable', 'error'):
|
if stanza.getType() not in ('unavailable', 'error'):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ class Chatstate:
|
||||||
self._last_mouse_activity.pop(jid, None)
|
self._last_mouse_activity.pop(jid, None)
|
||||||
self._last_keyboard_activity.pop(jid, None)
|
self._last_keyboard_activity.pop(jid, None)
|
||||||
|
|
||||||
log.info('Reset chatstate for %s', jid)
|
self._log.info('Reset chatstate for %s', jid)
|
||||||
|
|
||||||
app.nec.push_outgoing_event(
|
app.nec.push_outgoing_event(
|
||||||
NetworkEvent('chatstate-received',
|
NetworkEvent('chatstate-received',
|
||||||
|
@ -166,7 +167,7 @@ class Chatstate:
|
||||||
return
|
return
|
||||||
|
|
||||||
contact.chatstate = chatstate
|
contact.chatstate = chatstate
|
||||||
log.info('Recv: %-10s - %s', chatstate, event.fjid)
|
self._log.info('Recv: %-10s - %s', chatstate, event.fjid)
|
||||||
app.nec.push_outgoing_event(
|
app.nec.push_outgoing_event(
|
||||||
NetworkEvent('chatstate-received',
|
NetworkEvent('chatstate-received',
|
||||||
account=self._account,
|
account=self._account,
|
||||||
|
@ -207,7 +208,7 @@ class Chatstate:
|
||||||
else:
|
else:
|
||||||
# Contact not found, maybe we left the group chat
|
# Contact not found, maybe we left the group chat
|
||||||
# or the contact was removed from the roster
|
# or the contact was removed from the roster
|
||||||
log.info(
|
self._log.info(
|
||||||
'Contact %s not found, reset chatstate', jid)
|
'Contact %s not found, reset chatstate', jid)
|
||||||
self._chatstates.pop(jid, None)
|
self._chatstates.pop(jid, None)
|
||||||
self._last_mouse_activity.pop(jid, None)
|
self._last_mouse_activity.pop(jid, None)
|
||||||
|
@ -275,9 +276,9 @@ class Chatstate:
|
||||||
if setting == 'disabled':
|
if setting == 'disabled':
|
||||||
# Send a last 'active' state after user disabled chatstates
|
# Send a last 'active' state after user disabled chatstates
|
||||||
if current_state is not None:
|
if current_state is not None:
|
||||||
log.info('Disabled for %s', contact.jid)
|
self._log.info('Disabled for %s', contact.jid)
|
||||||
log.info('Send last state: %-10s - %s',
|
self._log.info('Send last state: %-10s - %s',
|
||||||
State.ACTIVE, contact.jid)
|
State.ACTIVE, contact.jid)
|
||||||
|
|
||||||
event_attrs = {'account': self._account,
|
event_attrs = {'account': self._account,
|
||||||
'jid': contact.jid,
|
'jid': contact.jid,
|
||||||
|
@ -301,15 +302,15 @@ class Chatstate:
|
||||||
# which are not allowed to see our status
|
# which are not allowed to see our status
|
||||||
if not contact.is_pm_contact:
|
if not contact.is_pm_contact:
|
||||||
if contact and contact.sub in ('to', 'none'):
|
if contact and contact.sub in ('to', 'none'):
|
||||||
log.info('Contact not subscribed: %s', contact.jid)
|
self._log.info('Contact not subscribed: %s', contact.jid)
|
||||||
return
|
return
|
||||||
|
|
||||||
if contact.show == 'offline':
|
if contact.show == 'offline':
|
||||||
log.info('Contact offline: %s', contact.jid)
|
self._log.info('Contact offline: %s', contact.jid)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not contact.supports(nbxmpp.NS_CHATSTATES):
|
if not contact.supports(nbxmpp.NS_CHATSTATES):
|
||||||
log.info('Chatstates not supported: %s', contact.jid)
|
self._log.info('Chatstates not supported: %s', contact.jid)
|
||||||
return
|
return
|
||||||
|
|
||||||
if state in (State.ACTIVE, State.COMPOSING):
|
if state in (State.ACTIVE, State.COMPOSING):
|
||||||
|
@ -322,7 +323,7 @@ class Chatstate:
|
||||||
if current_state == state:
|
if current_state == state:
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Send: %-10s - %s', state, contact.jid)
|
self._log.info('Send: %-10s - %s', state, contact.jid)
|
||||||
|
|
||||||
event_attrs = {'account': self._account,
|
event_attrs = {'account': self._account,
|
||||||
'jid': contact.jid,
|
'jid': contact.jid,
|
||||||
|
|
|
@ -14,25 +14,19 @@
|
||||||
|
|
||||||
# XEP-0083: Nested Roster Groups
|
# XEP-0083: Nested Roster Groups
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.delimiter')
|
from gajim.common.modules.base import BaseModule
|
||||||
|
|
||||||
|
|
||||||
class Delimiter:
|
class Delimiter(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
self.available = False
|
self.available = False
|
||||||
|
|
||||||
self.delimiter = '::'
|
self.delimiter = '::'
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
def get_roster_delimiter(self):
|
def get_roster_delimiter(self):
|
||||||
log.info('Request')
|
self._log.info('Request')
|
||||||
node = nbxmpp.Node('storage', attrs={'xmlns': 'roster:delimiter'})
|
node = nbxmpp.Node('storage', attrs={'xmlns': 'roster:delimiter'})
|
||||||
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVATE, payload=node)
|
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVATE, payload=node)
|
||||||
|
|
||||||
|
@ -41,11 +35,11 @@ class Delimiter:
|
||||||
|
|
||||||
def _delimiter_received(self, stanza):
|
def _delimiter_received(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Request error: %s', stanza.getError())
|
self._log.info('Request error: %s', stanza.getError())
|
||||||
else:
|
else:
|
||||||
delimiter = stanza.getQuery().getTagData('roster')
|
delimiter = stanza.getQuery().getTagData('roster')
|
||||||
self.available = True
|
self.available = True
|
||||||
log.info('Delimiter received: %s', delimiter)
|
self._log.info('Delimiter received: %s', delimiter)
|
||||||
if delimiter:
|
if delimiter:
|
||||||
self.delimiter = delimiter
|
self.delimiter = delimiter
|
||||||
else:
|
else:
|
||||||
|
@ -54,7 +48,7 @@ class Delimiter:
|
||||||
self._con.connect_machine()
|
self._con.connect_machine()
|
||||||
|
|
||||||
def set_roster_delimiter(self):
|
def set_roster_delimiter(self):
|
||||||
log.info('Set delimiter')
|
self._log.info('Set delimiter')
|
||||||
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVATE)
|
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVATE)
|
||||||
roster = iq.getQuery().addChild('roster', namespace='roster:delimiter')
|
roster = iq.getQuery().addChild('roster', namespace='roster:delimiter')
|
||||||
roster.setData('::')
|
roster.setData('::')
|
||||||
|
@ -62,10 +56,9 @@ class Delimiter:
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._set_delimiter_response)
|
iq, self._set_delimiter_response)
|
||||||
|
|
||||||
@staticmethod
|
def _set_delimiter_response(self, stanza):
|
||||||
def _set_delimiter_response(stanza):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Store error: %s', stanza.getError())
|
self._log.info('Store error: %s', stanza.getError())
|
||||||
|
|
||||||
|
|
||||||
def get_instance(*args, **kwargs):
|
def get_instance(*args, **kwargs):
|
||||||
|
|
|
@ -14,28 +14,32 @@
|
||||||
|
|
||||||
# XEP-0030: Service Discovery
|
# XEP-0030: Service Discovery
|
||||||
|
|
||||||
import logging
|
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
from gajim.common.caps_cache import muc_caps_cache
|
from gajim.common.caps_cache import muc_caps_cache
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.connection_handlers_events import InformationEvent
|
from gajim.common.connection_handlers_events import InformationEvent
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.discovery')
|
|
||||||
|
|
||||||
|
class Discovery(BaseModule):
|
||||||
class Discovery:
|
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._answer_disco_info, 'get', nbxmpp.NS_DISCO_INFO),
|
StanzaHandler(name='iq',
|
||||||
('iq', self._answer_disco_items, 'get', nbxmpp.NS_DISCO_ITEMS),
|
callback=self._answer_disco_info,
|
||||||
|
typ='get',
|
||||||
|
ns=nbxmpp.NS_DISCO_INFO),
|
||||||
|
StanzaHandler(name='iq',
|
||||||
|
callback=self._answer_disco_items,
|
||||||
|
typ='get',
|
||||||
|
ns=nbxmpp.NS_DISCO_ITEMS),
|
||||||
]
|
]
|
||||||
|
|
||||||
def disco_contact(self, jid, node=None):
|
def disco_contact(self, jid, node=None):
|
||||||
|
@ -60,7 +64,7 @@ class Discovery:
|
||||||
log_str = 'Request info: %s %s'
|
log_str = 'Request info: %s %s'
|
||||||
if namespace == nbxmpp.NS_DISCO_ITEMS:
|
if namespace == nbxmpp.NS_DISCO_ITEMS:
|
||||||
log_str = 'Request items: %s %s'
|
log_str = 'Request items: %s %s'
|
||||||
log.info(log_str, jid, node or '')
|
self._log.info(log_str, jid, node or '')
|
||||||
|
|
||||||
# Create weak references so we can pass GUI object methods
|
# Create weak references so we can pass GUI object methods
|
||||||
weak_success_cb = weakref.WeakMethod(success_cb)
|
weak_success_cb = weakref.WeakMethod(success_cb)
|
||||||
|
@ -77,7 +81,7 @@ class Discovery:
|
||||||
if error_cb is not None:
|
if error_cb is not None:
|
||||||
error_cb()(stanza.getFrom(), stanza.getError())
|
error_cb()(stanza.getFrom(), stanza.getError())
|
||||||
else:
|
else:
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
return
|
return
|
||||||
|
|
||||||
from_ = stanza.getFrom()
|
from_ = stanza.getFrom()
|
||||||
|
@ -90,10 +94,9 @@ class Discovery:
|
||||||
items = self.parse_items_response(stanza)
|
items = self.parse_items_response(stanza)
|
||||||
success_cb()(from_, node, items)
|
success_cb()(from_, node, items)
|
||||||
else:
|
else:
|
||||||
log.warning('Wrong query namespace: %s', stanza)
|
self._log.warning('Wrong query namespace: %s', stanza)
|
||||||
|
|
||||||
@classmethod
|
def parse_items_response(self, stanza):
|
||||||
def parse_items_response(cls, stanza):
|
|
||||||
payload = stanza.getQueryPayload()
|
payload = stanza.getQueryPayload()
|
||||||
items = []
|
items = []
|
||||||
for item in payload:
|
for item in payload:
|
||||||
|
@ -102,12 +105,12 @@ class Discovery:
|
||||||
continue
|
continue
|
||||||
attr = item.getAttrs()
|
attr = item.getAttrs()
|
||||||
if 'jid' not in attr:
|
if 'jid' not in attr:
|
||||||
log.warning('No jid attr in disco items: %s', stanza)
|
self._log.warning('No jid attr in disco items: %s', stanza)
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
attr['jid'] = helpers.parse_jid(attr['jid'])
|
attr['jid'] = helpers.parse_jid(attr['jid'])
|
||||||
except helpers.InvalidFormat:
|
except helpers.InvalidFormat:
|
||||||
log.warning('Invalid jid attr in disco items: %s', stanza)
|
self._log.warning('Invalid jid attr in disco items: %s', stanza)
|
||||||
continue
|
continue
|
||||||
items.append(attr)
|
items.append(attr)
|
||||||
return items
|
return items
|
||||||
|
@ -144,7 +147,7 @@ class Discovery:
|
||||||
self.disco_items(server, success_cb=self._server_items_received)
|
self.disco_items(server, success_cb=self._server_items_received)
|
||||||
|
|
||||||
def _server_items_received(self, _from, _node, items):
|
def _server_items_received(self, _from, _node, items):
|
||||||
log.info('Server items received')
|
self._log.info('Server items received')
|
||||||
for item in items:
|
for item in items:
|
||||||
if 'node' in item:
|
if 'node' in item:
|
||||||
# Only disco components
|
# Only disco components
|
||||||
|
@ -154,7 +157,7 @@ class Discovery:
|
||||||
|
|
||||||
def _server_items_info_received(self, from_, *args):
|
def _server_items_info_received(self, from_, *args):
|
||||||
from_ = from_.getStripped()
|
from_ = from_.getStripped()
|
||||||
log.info('Server item info received: %s', from_)
|
self._log.info('Server item info received: %s', from_)
|
||||||
self._parse_transports(from_, *args)
|
self._parse_transports(from_, *args)
|
||||||
try:
|
try:
|
||||||
self._con.get_module('MUC').pass_disco(from_, *args)
|
self._con.get_module('MUC').pass_disco(from_, *args)
|
||||||
|
@ -172,7 +175,7 @@ class Discovery:
|
||||||
|
|
||||||
def _account_info_received(self, from_, *args):
|
def _account_info_received(self, from_, *args):
|
||||||
from_ = from_.getStripped()
|
from_ = from_.getStripped()
|
||||||
log.info('Account info received: %s', from_)
|
self._log.info('Account info received: %s', from_)
|
||||||
|
|
||||||
self._con.get_module('MAM').pass_disco(from_, *args)
|
self._con.get_module('MAM').pass_disco(from_, *args)
|
||||||
self._con.get_module('PEP').pass_disco(from_, *args)
|
self._con.get_module('PEP').pass_disco(from_, *args)
|
||||||
|
@ -189,7 +192,7 @@ class Discovery:
|
||||||
self.disco_info(server, success_cb=self._server_info_received)
|
self.disco_info(server, success_cb=self._server_info_received)
|
||||||
|
|
||||||
def _server_info_received(self, from_, *args):
|
def _server_info_received(self, from_, *args):
|
||||||
log.info('Server info received: %s', from_)
|
self._log.info('Server info received: %s', from_)
|
||||||
|
|
||||||
self._con.get_module('SecLabels').pass_disco(from_, *args)
|
self._con.get_module('SecLabels').pass_disco(from_, *args)
|
||||||
self._con.get_module('Blocking').pass_disco(from_, *args)
|
self._con.get_module('Blocking').pass_disco(from_, *args)
|
||||||
|
@ -213,8 +216,8 @@ class Discovery:
|
||||||
if category not in ('gateway', 'headline'):
|
if category not in ('gateway', 'headline'):
|
||||||
continue
|
continue
|
||||||
transport_type = identity.get('type')
|
transport_type = identity.get('type')
|
||||||
log.info('Found transport: %s %s %s',
|
self._log.info('Found transport: %s %s %s',
|
||||||
from_, category, transport_type)
|
from_, category, transport_type)
|
||||||
jid = str(from_)
|
jid = str(from_)
|
||||||
if jid not in app.transport_type:
|
if jid not in app.transport_type:
|
||||||
app.transport_type[jid] = transport_type
|
app.transport_type[jid] = transport_type
|
||||||
|
@ -225,9 +228,9 @@ class Discovery:
|
||||||
else:
|
else:
|
||||||
self._con.available_transports[transport_type] = [jid]
|
self._con.available_transports[transport_type] = [jid]
|
||||||
|
|
||||||
def _answer_disco_items(self, _con, stanza):
|
def _answer_disco_items(self, _con, stanza, _properties):
|
||||||
from_ = stanza.getFrom()
|
from_ = stanza.getFrom()
|
||||||
log.info('Answer disco items to %s', from_)
|
self._log.info('Answer disco items to %s', from_)
|
||||||
|
|
||||||
if self._con.get_module('AdHocCommands').command_items_query(stanza):
|
if self._con.get_module('AdHocCommands').command_items_query(stanza):
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
@ -242,9 +245,9 @@ class Discovery:
|
||||||
self._con.get_module('AdHocCommands').command_list_query(stanza)
|
self._con.get_module('AdHocCommands').command_list_query(stanza)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
def _answer_disco_info(self, _con, stanza):
|
def _answer_disco_info(self, _con, stanza, _properties):
|
||||||
from_ = stanza.getFrom()
|
from_ = stanza.getFrom()
|
||||||
log.info('Answer disco info %s', from_)
|
self._log.info('Answer disco info %s', from_)
|
||||||
if str(from_).startswith('echo.'):
|
if str(from_).startswith('echo.'):
|
||||||
# Service that echos all stanzas, ignore it
|
# Service that echos all stanzas, ignore it
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
@ -277,27 +280,26 @@ class Discovery:
|
||||||
return
|
return
|
||||||
|
|
||||||
iq = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_DISCO_INFO)
|
iq = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_DISCO_INFO)
|
||||||
log.info('Request MUC info %s', jid)
|
self._log.info('Request MUC info %s', jid)
|
||||||
|
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._muc_info_response, {'callback': callback})
|
iq, self._muc_info_response, {'callback': callback})
|
||||||
|
|
||||||
@staticmethod
|
def _muc_info_response(self, _con, stanza, callback):
|
||||||
def _muc_info_response(_con, stanza, callback):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
error = stanza.getError()
|
error = stanza.getError()
|
||||||
if error == 'item-not-found':
|
if error == 'item-not-found':
|
||||||
# Groupchat does not exist
|
# Groupchat does not exist
|
||||||
log.info('MUC does not exist: %s', stanza.getFrom())
|
self._log.info('MUC does not exist: %s', stanza.getFrom())
|
||||||
callback()
|
callback()
|
||||||
else:
|
else:
|
||||||
log.info('MUC disco error: %s', error)
|
self._log.info('MUC disco error: %s', error)
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
InformationEvent(
|
InformationEvent(
|
||||||
None, dialog_name='unable-join-groupchat', args=error))
|
None, dialog_name='unable-join-groupchat', args=error))
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('MUC info received: %s', stanza.getFrom())
|
self._log.info('MUC info received: %s', stanza.getFrom())
|
||||||
muc_caps_cache.append(stanza)
|
muc_caps_cache.append(stanza)
|
||||||
callback()
|
callback()
|
||||||
|
|
||||||
|
|
|
@ -14,26 +14,27 @@
|
||||||
|
|
||||||
# XEP-0202: Entity Time
|
# XEP-0202: Entity Time
|
||||||
|
|
||||||
import logging
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.modules.date_and_time import parse_datetime
|
from gajim.common.modules.date_and_time import parse_datetime
|
||||||
from gajim.common.modules.date_and_time import create_tzinfo
|
from gajim.common.modules.date_and_time import create_tzinfo
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.entity_time')
|
|
||||||
|
|
||||||
|
class EntityTime(BaseModule):
|
||||||
class EntityTime:
|
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._answer_request, 'get', nbxmpp.NS_TIME_REVISED),
|
StanzaHandler(name='iq',
|
||||||
|
callback=self._answer_request,
|
||||||
|
typ='get',
|
||||||
|
ns=nbxmpp.NS_TIME_REVISED),
|
||||||
]
|
]
|
||||||
|
|
||||||
def request_entity_time(self, jid, resource):
|
def request_entity_time(self, jid, resource):
|
||||||
|
@ -48,54 +49,52 @@ class EntityTime:
|
||||||
iq = nbxmpp.Iq(to=jid, typ='get')
|
iq = nbxmpp.Iq(to=jid, typ='get')
|
||||||
iq.addChild('time', namespace=nbxmpp.NS_TIME_REVISED)
|
iq.addChild('time', namespace=nbxmpp.NS_TIME_REVISED)
|
||||||
|
|
||||||
log.info('Requested: %s', jid)
|
self._log.info('Requested: %s', jid)
|
||||||
|
|
||||||
self._con.connection.SendAndCallForResponse(iq, self._result_received)
|
self._con.connection.SendAndCallForResponse(iq, self._result_received)
|
||||||
|
|
||||||
def _result_received(self, stanza):
|
def _result_received(self, stanza):
|
||||||
time_info = None
|
time_info = None
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
else:
|
else:
|
||||||
time_info = self._extract_info(stanza)
|
time_info = self._extract_info(stanza)
|
||||||
|
|
||||||
log.info('Received: %s %s',
|
self._log.info('Received: %s %s', stanza.getFrom(), time_info)
|
||||||
stanza.getFrom(), time_info)
|
|
||||||
|
|
||||||
app.nec.push_incoming_event(NetworkEvent('time-result-received',
|
app.nec.push_incoming_event(NetworkEvent('time-result-received',
|
||||||
conn=self._con,
|
conn=self._con,
|
||||||
jid=stanza.getFrom(),
|
jid=stanza.getFrom(),
|
||||||
time_info=time_info))
|
time_info=time_info))
|
||||||
|
|
||||||
@staticmethod
|
def _extract_info(self, stanza):
|
||||||
def _extract_info(stanza):
|
|
||||||
time_ = stanza.getTag('time')
|
time_ = stanza.getTag('time')
|
||||||
if not time_:
|
if not time_:
|
||||||
log.warning('No time node: %s', stanza)
|
self._log.warning('No time node: %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
tzo = time_.getTag('tzo').getData()
|
tzo = time_.getTag('tzo').getData()
|
||||||
if not tzo:
|
if not tzo:
|
||||||
log.warning('Wrong tzo node: %s', stanza)
|
self._log.warning('Wrong tzo node: %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
remote_tz = create_tzinfo(tz_string=tzo)
|
remote_tz = create_tzinfo(tz_string=tzo)
|
||||||
if remote_tz is None:
|
if remote_tz is None:
|
||||||
log.warning('Wrong tzo node: %s', stanza)
|
self._log.warning('Wrong tzo node: %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
utc_time = time_.getTag('utc').getData()
|
utc_time = time_.getTag('utc').getData()
|
||||||
date_time = parse_datetime(utc_time, check_utc=True)
|
date_time = parse_datetime(utc_time, check_utc=True)
|
||||||
if date_time is None:
|
if date_time is None:
|
||||||
log.warning('Wrong timezone defintion: %s %s',
|
self._log.warning('Wrong timezone defintion: %s %s',
|
||||||
utc_time, stanza.getFrom())
|
utc_time, stanza.getFrom())
|
||||||
return
|
return
|
||||||
|
|
||||||
date_time = date_time.astimezone(remote_tz)
|
date_time = date_time.astimezone(remote_tz)
|
||||||
return date_time.strftime('%c %Z')
|
return date_time.strftime('%c %Z')
|
||||||
|
|
||||||
def _answer_request(self, _con, stanza):
|
def _answer_request(self, _con, stanza, _properties):
|
||||||
log.info('%s asked for the time', stanza.getFrom())
|
self._log.info('%s asked for the time', stanza.getFrom())
|
||||||
if app.config.get_per('accounts', self._account, 'send_time_info'):
|
if app.config.get_per('accounts', self._account, 'send_time_info'):
|
||||||
iq = stanza.buildReply('result')
|
iq = stanza.buildReply('result')
|
||||||
time_ = iq.setTag('time', namespace=nbxmpp.NS_TIME_REVISED)
|
time_ = iq.setTag('time', namespace=nbxmpp.NS_TIME_REVISED)
|
||||||
|
@ -105,12 +104,12 @@ class EntityTime:
|
||||||
zone = -(time.timezone, time.altzone)[isdst] / 60.0
|
zone = -(time.timezone, time.altzone)[isdst] / 60.0
|
||||||
tzo = (zone / 60, abs(zone % 60))
|
tzo = (zone / 60, abs(zone % 60))
|
||||||
time_.setTagData('tzo', '%+03d:%02d' % (tzo))
|
time_.setTagData('tzo', '%+03d:%02d' % (tzo))
|
||||||
log.info('Answer: %s %s', formated_time, '%+03d:%02d' % (tzo))
|
self._log.info('Answer: %s %s', formated_time, '%+03d:%02d' % (tzo))
|
||||||
else:
|
else:
|
||||||
iq = stanza.buildReply('error')
|
iq = stanza.buildReply('error')
|
||||||
err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
|
err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
|
||||||
iq.addChild(node=err)
|
iq.addChild(node=err)
|
||||||
log.info('Send service-unavailable')
|
self._log.info('Send service-unavailable')
|
||||||
self._con.connection.send(iq)
|
self._con.connection.send(iq)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
|
|
|
@ -14,22 +14,16 @@
|
||||||
|
|
||||||
# XEP-0100: Gateway Interaction
|
# XEP-0100: Gateway Interaction
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.gateway')
|
|
||||||
|
|
||||||
|
|
||||||
class Gateway:
|
class Gateway(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
def unsubscribe(self, agent):
|
def unsubscribe(self, agent):
|
||||||
if not app.account_is_connected(self._account):
|
if not app.account_is_connected(self._account):
|
||||||
|
@ -43,7 +37,7 @@ class Gateway:
|
||||||
|
|
||||||
def _on_unsubscribe_result(self, stanza):
|
def _on_unsubscribe_result(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
return
|
return
|
||||||
|
|
||||||
agent = stanza.getFrom().getBare()
|
agent = stanza.getFrom().getBare()
|
||||||
|
@ -51,8 +45,8 @@ class Gateway:
|
||||||
for jid in app.contacts.get_jid_list(self._account):
|
for jid in app.contacts.get_jid_list(self._account):
|
||||||
if jid.endswith('@' + agent):
|
if jid.endswith('@' + agent):
|
||||||
jid_list.append(jid)
|
jid_list.append(jid)
|
||||||
log.info('Removing contact %s due to unregistered transport %s',
|
self._log.info('Removing contact %s due to'
|
||||||
jid, agent)
|
' unregistered transport %s', jid, agent)
|
||||||
self._con.get_module('Presence').unsubscribe(jid)
|
self._con.get_module('Presence').unsubscribe(jid)
|
||||||
# Transport contacts can't have 2 resources
|
# Transport contacts can't have 2 resources
|
||||||
if jid in app.to_be_removed[self._account]:
|
if jid in app.to_be_removed[self._account]:
|
||||||
|
|
|
@ -14,22 +14,18 @@
|
||||||
|
|
||||||
# XEP-0070: Verifying HTTP Requests via XMPP
|
# XEP-0070: Verifying HTTP Requests via XMPP
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
from nbxmpp.structs import StanzaHandler
|
from nbxmpp.structs import StanzaHandler
|
||||||
from nbxmpp.protocol import NS_HTTP_AUTH
|
from nbxmpp.protocol import NS_HTTP_AUTH
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.http_auth')
|
|
||||||
|
|
||||||
|
|
||||||
class HTTPAuth:
|
class HTTPAuth(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
StanzaHandler(name='message',
|
StanzaHandler(name='message',
|
||||||
|
@ -47,7 +43,7 @@ class HTTPAuth:
|
||||||
if not properties.is_http_auth:
|
if not properties.is_http_auth:
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Auth request received')
|
self._log.info('Auth request received')
|
||||||
auto_answer = app.config.get_per(
|
auto_answer = app.config.get_per(
|
||||||
'accounts', self._account, 'http_auth')
|
'accounts', self._account, 'http_auth')
|
||||||
if auto_answer in ('yes', 'no'):
|
if auto_answer in ('yes', 'no'):
|
||||||
|
@ -66,14 +62,14 @@ class HTTPAuth:
|
||||||
|
|
||||||
def build_http_auth_answer(self, stanza, answer):
|
def build_http_auth_answer(self, stanza, answer):
|
||||||
if answer == 'yes':
|
if answer == 'yes':
|
||||||
log.info('Auth request approved')
|
self._log.info('Auth request approved')
|
||||||
confirm = stanza.getTag('confirm')
|
confirm = stanza.getTag('confirm')
|
||||||
reply = stanza.buildReply('result')
|
reply = stanza.buildReply('result')
|
||||||
if stanza.getName() == 'message':
|
if stanza.getName() == 'message':
|
||||||
reply.addChild(node=confirm)
|
reply.addChild(node=confirm)
|
||||||
self._con.connection.send(reply)
|
self._con.connection.send(reply)
|
||||||
elif answer == 'no':
|
elif answer == 'no':
|
||||||
log.info('Auth request denied')
|
self._log.info('Auth request denied')
|
||||||
err = nbxmpp.Error(stanza, nbxmpp.protocol.ERR_NOT_AUTHORIZED)
|
err = nbxmpp.Error(stanza, nbxmpp.protocol.ERR_NOT_AUTHORIZED)
|
||||||
self._con.connection.send(err)
|
self._con.connection.send(err)
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ from urllib.request import Request, urlopen
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
import io
|
import io
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
from nbxmpp import NS_HTTPUPLOAD
|
from nbxmpp import NS_HTTPUPLOAD
|
||||||
|
@ -34,6 +33,7 @@ from gajim.common import app
|
||||||
from gajim.common import ged
|
from gajim.common import ged
|
||||||
from gajim.common.i18n import _
|
from gajim.common.i18n import _
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.connection_handlers_events import InformationEvent
|
from gajim.common.connection_handlers_events import InformationEvent
|
||||||
from gajim.common.connection_handlers_events import MessageOutgoingEvent
|
from gajim.common.connection_handlers_events import MessageOutgoingEvent
|
||||||
from gajim.common.connection_handlers_events import GcMessageOutgoingEvent
|
from gajim.common.connection_handlers_events import GcMessageOutgoingEvent
|
||||||
|
@ -41,18 +41,12 @@ from gajim.common.connection_handlers_events import GcMessageOutgoingEvent
|
||||||
if sys.platform in ('win32', 'darwin'):
|
if sys.platform in ('win32', 'darwin'):
|
||||||
import certifi
|
import certifi
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.httpupload')
|
|
||||||
|
|
||||||
|
|
||||||
NS_HTTPUPLOAD_0 = NS_HTTPUPLOAD + ':0'
|
NS_HTTPUPLOAD_0 = NS_HTTPUPLOAD + ':0'
|
||||||
|
|
||||||
|
|
||||||
class HTTPUpload:
|
class HTTPUpload(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
self.available = False
|
self.available = False
|
||||||
self.component = None
|
self.component = None
|
||||||
|
@ -86,7 +80,7 @@ class HTTPUpload:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.component = from_
|
self.component = from_
|
||||||
log.info('Discovered component: %s', from_)
|
self._log.info('Discovered component: %s', from_)
|
||||||
|
|
||||||
for form in data:
|
for form in data:
|
||||||
form_dict = form.asDict()
|
form_dict = form.asDict()
|
||||||
|
@ -98,10 +92,10 @@ class HTTPUpload:
|
||||||
break
|
break
|
||||||
|
|
||||||
if self.max_file_size is None:
|
if self.max_file_size is None:
|
||||||
log.warning('%s does not provide maximum file size', self._account)
|
self._log.warning('Component does not provide maximum file size')
|
||||||
else:
|
else:
|
||||||
log.info('%s has a maximum file size of: %s MiB',
|
self._log.info('Component has a maximum file size of: %s MiB',
|
||||||
self._account, self.max_file_size / (1024 * 1024))
|
self.max_file_size / (1024 * 1024))
|
||||||
|
|
||||||
self.available = True
|
self.available = True
|
||||||
|
|
||||||
|
@ -151,7 +145,7 @@ class HTTPUpload:
|
||||||
mime = mimetypes.MimeTypes().guess_type(path)[0]
|
mime = mimetypes.MimeTypes().guess_type(path)[0]
|
||||||
if not mime:
|
if not mime:
|
||||||
mime = 'application/octet-stream' # fallback mime type
|
mime = 'application/octet-stream' # fallback mime type
|
||||||
log.info("Detected MIME type of file: %s", mime)
|
self._log.info("Detected MIME type of file: %s", mime)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
file = File(path, contact, mime=mime, encryption=encryption,
|
file = File(path, contact, mime=mime, encryption=encryption,
|
||||||
|
@ -159,7 +153,7 @@ class HTTPUpload:
|
||||||
session=session, groupchat=groupchat)
|
session=session, groupchat=groupchat)
|
||||||
app.interface.show_httpupload_progress(file)
|
app.interface.show_httpupload_progress(file)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
log.exception('Error while loading file')
|
self._log.exception('Error while loading file')
|
||||||
self.raise_information_event('open-file-error2', str(error))
|
self.raise_information_event('open-file-error2', str(error))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -181,7 +175,7 @@ class HTTPUpload:
|
||||||
def _request_slot(self, file):
|
def _request_slot(self, file):
|
||||||
GLib.idle_add(self.raise_progress_event, 'request', file)
|
GLib.idle_add(self.raise_progress_event, 'request', file)
|
||||||
iq = self._build_request(file)
|
iq = self._build_request(file)
|
||||||
log.info("Sending request for slot")
|
self._log.info("Sending request for slot")
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._received_slot, {'file': file})
|
iq, self._received_slot, {'file': file})
|
||||||
|
|
||||||
|
@ -218,12 +212,12 @@ class HTTPUpload:
|
||||||
return stanza.getErrorMsg()
|
return stanza.getErrorMsg()
|
||||||
|
|
||||||
def _received_slot(self, _con, stanza, file):
|
def _received_slot(self, _con, stanza, file):
|
||||||
log.info("Received slot")
|
self._log.info("Received slot")
|
||||||
if stanza.getType() == 'error':
|
if stanza.getType() == 'error':
|
||||||
self.raise_progress_event('close', file)
|
self.raise_progress_event('close', file)
|
||||||
self.raise_information_event('request-upload-slot-error',
|
self.raise_information_event('request-upload-slot-error',
|
||||||
self.get_slot_error_message(stanza))
|
self.get_slot_error_message(stanza))
|
||||||
log.error(stanza)
|
self._log.error(stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -243,8 +237,8 @@ class HTTPUpload:
|
||||||
raise ValueError('Newline in header data')
|
raise ValueError('Newline in header data')
|
||||||
file.headers[name] = data
|
file.headers[name] = data
|
||||||
except Exception:
|
except Exception:
|
||||||
log.error("Got invalid stanza: %s", stanza)
|
self._log.error("Got invalid stanza: %s", stanza)
|
||||||
log.exception('Error')
|
self._log.exception('Error')
|
||||||
self.raise_progress_event('close', file)
|
self.raise_progress_event('close', file)
|
||||||
self.raise_information_event('request-upload-slot-error2')
|
self.raise_information_event('request-upload-slot-error2')
|
||||||
return
|
return
|
||||||
|
@ -258,13 +252,13 @@ class HTTPUpload:
|
||||||
try:
|
try:
|
||||||
file.stream = StreamFileWithProgress(file)
|
file.stream = StreamFileWithProgress(file)
|
||||||
except Exception:
|
except Exception:
|
||||||
log.exception('Error')
|
self._log.exception('Error')
|
||||||
self.raise_progress_event('close', file)
|
self.raise_progress_event('close', file)
|
||||||
self.raise_information_event('open-file-error')
|
self.raise_information_event('open-file-error')
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Uploading file to %s', file.put)
|
self._log.info('Uploading file to %s', file.put)
|
||||||
log.info('Please download from %s', file.get)
|
self._log.info('Please download from %s', file.get)
|
||||||
|
|
||||||
thread = threading.Thread(target=self._upload_file, args=(file,))
|
thread = threading.Thread(target=self._upload_file, args=(file,))
|
||||||
thread.daemon = True
|
thread.daemon = True
|
||||||
|
@ -279,14 +273,14 @@ class HTTPUpload:
|
||||||
|
|
||||||
request = Request(
|
request = Request(
|
||||||
file.put, data=file.stream, headers=file.headers, method='PUT')
|
file.put, data=file.stream, headers=file.headers, method='PUT')
|
||||||
log.info("Opening Urllib upload request...")
|
self._log.info("Opening Urllib upload request...")
|
||||||
|
|
||||||
if not app.config.get_per(
|
if not app.config.get_per(
|
||||||
'accounts', self._account, 'httpupload_verify'):
|
'accounts', self._account, 'httpupload_verify'):
|
||||||
context = ssl.create_default_context()
|
context = ssl.create_default_context()
|
||||||
context.check_hostname = False
|
context.check_hostname = False
|
||||||
context.verify_mode = ssl.CERT_NONE
|
context.verify_mode = ssl.CERT_NONE
|
||||||
log.warning('CERT Verification disabled')
|
self._log.warning('CERT Verification disabled')
|
||||||
transfer = urlopen(request, timeout=30, context=context)
|
transfer = urlopen(request, timeout=30, context=context)
|
||||||
else:
|
else:
|
||||||
if sys.platform in ('win32', 'darwin'):
|
if sys.platform in ('win32', 'darwin'):
|
||||||
|
@ -295,23 +289,23 @@ class HTTPUpload:
|
||||||
else:
|
else:
|
||||||
transfer = urlopen(request, timeout=30)
|
transfer = urlopen(request, timeout=30)
|
||||||
file.stream.close()
|
file.stream.close()
|
||||||
log.info('Urllib upload request done, response code: %s',
|
self._log.info('Urllib upload request done, response code: %s',
|
||||||
transfer.getcode())
|
transfer.getcode())
|
||||||
GLib.idle_add(self._upload_complete, transfer.getcode(), file)
|
GLib.idle_add(self._upload_complete, transfer.getcode(), file)
|
||||||
return
|
return
|
||||||
except UploadAbortedException as exc:
|
except UploadAbortedException as exc:
|
||||||
log.info(exc)
|
self._log.info(exc)
|
||||||
error_msg = exc
|
error_msg = exc
|
||||||
except urllib.error.URLError as exc:
|
except urllib.error.URLError as exc:
|
||||||
if isinstance(exc.reason, ssl.SSLError):
|
if isinstance(exc.reason, ssl.SSLError):
|
||||||
error_msg = exc.reason.reason
|
error_msg = exc.reason.reason
|
||||||
if error_msg == 'CERTIFICATE_VERIFY_FAILED':
|
if error_msg == 'CERTIFICATE_VERIFY_FAILED':
|
||||||
log.exception('Certificate verify failed')
|
self._log.exception('Certificate verify failed')
|
||||||
else:
|
else:
|
||||||
log.exception('URLError')
|
self._log.exception('URLError')
|
||||||
error_msg = exc.reason
|
error_msg = exc.reason
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
log.exception("Exception during upload")
|
self._log.exception("Exception during upload")
|
||||||
error_msg = exc
|
error_msg = exc
|
||||||
GLib.idle_add(self.raise_progress_event, 'close', file)
|
GLib.idle_add(self.raise_progress_event, 'close', file)
|
||||||
GLib.idle_add(self._on_upload_error, file, error_msg)
|
GLib.idle_add(self._on_upload_error, file, error_msg)
|
||||||
|
@ -319,7 +313,7 @@ class HTTPUpload:
|
||||||
def _upload_complete(self, response_code, file):
|
def _upload_complete(self, response_code, file):
|
||||||
self.raise_progress_event('close', file)
|
self.raise_progress_event('close', file)
|
||||||
if 200 <= response_code < 300:
|
if 200 <= response_code < 300:
|
||||||
log.info("Upload completed successfully")
|
self._log.info("Upload completed successfully")
|
||||||
message = file.get
|
message = file.get
|
||||||
if file.user_data:
|
if file.user_data:
|
||||||
message += '#' + file.user_data
|
message += '#' + file.user_data
|
||||||
|
@ -339,8 +333,8 @@ class HTTPUpload:
|
||||||
automatic_message=False, session=file.session))
|
automatic_message=False, session=file.session))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
log.error('Got unexpected http upload response code: %s',
|
self._log.error('Got unexpected http upload response code: %s',
|
||||||
response_code)
|
response_code)
|
||||||
self.raise_information_event('httpupload-response-error',
|
self.raise_information_event('httpupload-response-error',
|
||||||
response_code)
|
response_code)
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
# Iq handler
|
# Iq handler
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
from nbxmpp.const import Error
|
from nbxmpp.const import Error
|
||||||
from nbxmpp.structs import StanzaHandler
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
@ -23,15 +21,12 @@ from nbxmpp.structs import StanzaHandler
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
from gajim.common.file_props import FilesProp
|
from gajim.common.file_props import FilesProp
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.iq')
|
class Iq(BaseModule):
|
||||||
|
|
||||||
|
|
||||||
class Iq:
|
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
StanzaHandler(name='iq',
|
StanzaHandler(name='iq',
|
||||||
|
@ -41,7 +36,7 @@ class Iq:
|
||||||
]
|
]
|
||||||
|
|
||||||
def _iq_error_received(self, _con, _stanza, properties):
|
def _iq_error_received(self, _con, _stanza, properties):
|
||||||
log.info('Error: %s', properties.error)
|
self._log.info('Error: %s', properties.error)
|
||||||
if properties.error.type in (Error.JID_MALFORMED,
|
if properties.error.type in (Error.JID_MALFORMED,
|
||||||
Error.FORBIDDEN,
|
Error.FORBIDDEN,
|
||||||
Error.NOT_ACCEPTABLE):
|
Error.NOT_ACCEPTABLE):
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
# XEP-0012: Last Activity
|
# XEP-0012: Last Activity
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
from nbxmpp.structs import StanzaHandler
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
|
@ -23,8 +21,6 @@ from gajim.common import app
|
||||||
from gajim.common import idle
|
from gajim.common import idle
|
||||||
from gajim.common.modules.base import BaseModule
|
from gajim.common.modules.base import BaseModule
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.last_activity')
|
|
||||||
|
|
||||||
|
|
||||||
class LastActivity(BaseModule):
|
class LastActivity(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
|
@ -38,7 +34,7 @@ class LastActivity(BaseModule):
|
||||||
]
|
]
|
||||||
|
|
||||||
def _answer_request(self, _con, stanza, properties):
|
def _answer_request(self, _con, stanza, properties):
|
||||||
log.info('Request from %s', properties.jid)
|
self._log.info('Request from %s', properties.jid)
|
||||||
|
|
||||||
allow_send = app.config.get_per(
|
allow_send = app.config.get_per(
|
||||||
'accounts', self._account, 'send_idle_time')
|
'accounts', self._account, 'send_idle_time')
|
||||||
|
@ -47,7 +43,7 @@ class LastActivity(BaseModule):
|
||||||
query = iq.setQuery()
|
query = iq.setQuery()
|
||||||
seconds = idle.Monitor.get_idle_sec()
|
seconds = idle.Monitor.get_idle_sec()
|
||||||
query.attrs['seconds'] = seconds
|
query.attrs['seconds'] = seconds
|
||||||
log.info('Respond with seconds: %s', seconds)
|
self._log.info('Respond with seconds: %s', seconds)
|
||||||
else:
|
else:
|
||||||
iq = stanza.buildReply('error')
|
iq = stanza.buildReply('error')
|
||||||
err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
|
err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
# XEP-0313: Message Archive Management
|
# XEP-0313: Message Archive Management
|
||||||
|
|
||||||
import logging
|
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
@ -34,14 +33,12 @@ from gajim.common.modules.misc import parse_delay
|
||||||
from gajim.common.modules.misc import parse_oob
|
from gajim.common.modules.misc import parse_oob
|
||||||
from gajim.common.modules.misc import parse_correction
|
from gajim.common.modules.misc import parse_correction
|
||||||
from gajim.common.modules.util import get_eme_message
|
from gajim.common.modules.util import get_eme_message
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.archiving')
|
|
||||||
|
|
||||||
|
|
||||||
class MAM:
|
class MAM(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
StanzaHandler(name='message',
|
StanzaHandler(name='message',
|
||||||
|
@ -65,14 +62,14 @@ class MAM:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.available = True
|
self.available = True
|
||||||
log.info('Discovered MAM %s: %s', self.archiving_namespace, from_)
|
self._log.info('Discovered MAM %s: %s', self.archiving_namespace, from_)
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
NetworkEvent('feature-discovered',
|
NetworkEvent('feature-discovered',
|
||||||
account=self._account,
|
account=self._account,
|
||||||
feature=self.archiving_namespace))
|
feature=self.archiving_namespace))
|
||||||
|
|
||||||
def _from_valid_archive(self, stanza, properties):
|
def _from_valid_archive(self, _stanza, properties):
|
||||||
if properties.type.is_groupchat:
|
if properties.type.is_groupchat:
|
||||||
expected_archive = properties.jid
|
expected_archive = properties.jid
|
||||||
else:
|
else:
|
||||||
|
@ -107,15 +104,16 @@ class MAM:
|
||||||
stanza=stanza))
|
stanza=stanza))
|
||||||
|
|
||||||
if not self._from_valid_archive(stanza, properties):
|
if not self._from_valid_archive(stanza, properties):
|
||||||
log.warning('Message from invalid archive %s',
|
self._log.warning('Message from invalid archive %s',
|
||||||
properties.mam.archive)
|
properties.mam.archive)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
log.info('Received message from archive: %s', properties.mam.archive)
|
self._log.info('Received message from archive: %s',
|
||||||
|
properties.mam.archive)
|
||||||
if not self._is_valid_request(properties):
|
if not self._is_valid_request(properties):
|
||||||
log.warning('Invalid MAM Message: unknown query id %s',
|
self._log.warning('Invalid MAM Message: unknown query id %s',
|
||||||
properties.mam.query_id)
|
properties.mam.query_id)
|
||||||
log.debug(stanza)
|
self._log.debug(stanza)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
event_attrs = {}
|
event_attrs = {}
|
||||||
|
@ -136,8 +134,8 @@ class MAM:
|
||||||
stanza_id,
|
stanza_id,
|
||||||
message_id,
|
message_id,
|
||||||
groupchat=groupchat):
|
groupchat=groupchat):
|
||||||
log.info('Found duplicate with stanza-id: %s, message-id: %s',
|
self._log.info('Found duplicate with stanza-id: %s, '
|
||||||
stanza_id, message_id)
|
'message-id: %s', stanza_id, message_id)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
event_attrs.update(
|
event_attrs.update(
|
||||||
|
@ -204,7 +202,7 @@ class MAM:
|
||||||
def _decryption_finished(self, event):
|
def _decryption_finished(self, event):
|
||||||
if not event.msgtxt:
|
if not event.msgtxt:
|
||||||
# For example Chatstates, Receipts, Chatmarkers
|
# For example Chatstates, Receipts, Chatmarkers
|
||||||
log.debug(event.message.getProperties())
|
self._log.debug(event.message.getProperties())
|
||||||
return
|
return
|
||||||
|
|
||||||
user_timestamp = parse_delay(event.stanza)
|
user_timestamp = parse_delay(event.stanza)
|
||||||
|
@ -225,14 +223,14 @@ class MAM:
|
||||||
if event.self_message:
|
if event.self_message:
|
||||||
# Self messages can only be deduped with origin-id
|
# Self messages can only be deduped with origin-id
|
||||||
if event.origin_id is None:
|
if event.origin_id is None:
|
||||||
log.warning('Self message without origin-id found')
|
self._log.warning('Self message without origin-id found')
|
||||||
return
|
return
|
||||||
stanza_id = event.origin_id
|
stanza_id = event.origin_id
|
||||||
|
|
||||||
if event.namespace == nbxmpp.NS_MAM_1:
|
if event.namespace == nbxmpp.NS_MAM_1:
|
||||||
if app.logger.search_for_duplicate(
|
if app.logger.search_for_duplicate(
|
||||||
self._account, with_, event.timestamp, event.msgtxt):
|
self._account, with_, event.timestamp, event.msgtxt):
|
||||||
log.info('Found duplicate with fallback for mam:1')
|
self._log.info('Found duplicate with fallback for mam:1')
|
||||||
return
|
return
|
||||||
|
|
||||||
app.logger.insert_into_logs(self._account,
|
app.logger.insert_into_logs(self._account,
|
||||||
|
@ -258,20 +256,19 @@ class MAM:
|
||||||
self._mam_query_ids[jid] = query_id
|
self._mam_query_ids[jid] = query_id
|
||||||
return query_id
|
return query_id
|
||||||
|
|
||||||
@staticmethod
|
def _parse_iq(self, stanza):
|
||||||
def _parse_iq(stanza):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.error('Error on MAM query: %s', stanza.getError())
|
self._log.error('Error on MAM query: %s', stanza.getError())
|
||||||
raise InvalidMamIQ
|
raise InvalidMamIQ
|
||||||
|
|
||||||
fin = stanza.getTag('fin')
|
fin = stanza.getTag('fin')
|
||||||
if fin is None:
|
if fin is None:
|
||||||
log.error('Malformed MAM query result received: %s', stanza)
|
self._log.error('Malformed MAM query result received: %s', stanza)
|
||||||
raise InvalidMamIQ
|
raise InvalidMamIQ
|
||||||
|
|
||||||
set_ = fin.getTag('set', namespace=nbxmpp.NS_RSM)
|
set_ = fin.getTag('set', namespace=nbxmpp.NS_RSM)
|
||||||
if set_ is None:
|
if set_ is None:
|
||||||
log.error(
|
self._log.error(
|
||||||
'Malformed MAM query result received (no "set" Node): %s',
|
'Malformed MAM query result received (no "set" Node): %s',
|
||||||
stanza)
|
stanza)
|
||||||
raise InvalidMamIQ
|
raise InvalidMamIQ
|
||||||
|
@ -288,7 +285,7 @@ class MAM:
|
||||||
|
|
||||||
def request_archive_count(self, start_date, end_date):
|
def request_archive_count(self, start_date, end_date):
|
||||||
jid = self._con.get_own_jid().getStripped()
|
jid = self._con.get_own_jid().getStripped()
|
||||||
log.info('Request archive count from: %s', jid)
|
self._log.info('Request archive count from: %s', jid)
|
||||||
query_id = self._get_query_id(jid)
|
query_id = self._get_query_id(jid)
|
||||||
query = self._get_archive_query(
|
query = self._get_archive_query(
|
||||||
query_id, start=start_date, end=end_date, max_=0)
|
query_id, start=start_date, end=end_date, max_=0)
|
||||||
|
@ -306,7 +303,7 @@ class MAM:
|
||||||
self._mam_query_ids.pop(jid)
|
self._mam_query_ids.pop(jid)
|
||||||
|
|
||||||
count = set_.getTagData('count')
|
count = set_.getTagData('count')
|
||||||
log.info('Received archive count: %s', count)
|
self._log.info('Received archive count: %s', count)
|
||||||
app.nec.push_incoming_event(ArchivingCountReceived(
|
app.nec.push_incoming_event(ArchivingCountReceived(
|
||||||
None, query_id=query_id, count=count))
|
None, query_id=query_id, count=count))
|
||||||
|
|
||||||
|
@ -314,7 +311,7 @@ class MAM:
|
||||||
own_jid = self._con.get_own_jid().getStripped()
|
own_jid = self._con.get_own_jid().getStripped()
|
||||||
|
|
||||||
if own_jid in self._mam_query_ids:
|
if own_jid in self._mam_query_ids:
|
||||||
log.warning('MAM request for %s already running', own_jid)
|
self._log.warning('MAM request for %s already running', own_jid)
|
||||||
return
|
return
|
||||||
|
|
||||||
archive = app.logger.get_archive_infos(own_jid)
|
archive = app.logger.get_archive_infos(own_jid)
|
||||||
|
@ -331,12 +328,12 @@ class MAM:
|
||||||
start_date = None
|
start_date = None
|
||||||
query_id = self._get_query_id(own_jid)
|
query_id = self._get_query_id(own_jid)
|
||||||
if mam_id:
|
if mam_id:
|
||||||
log.info('MAM query after: %s', mam_id)
|
self._log.info('MAM query after: %s', mam_id)
|
||||||
query = self._get_archive_query(query_id, after=mam_id)
|
query = self._get_archive_query(query_id, after=mam_id)
|
||||||
else:
|
else:
|
||||||
# First Start, we request the last week
|
# First Start, we request the last week
|
||||||
start_date = datetime.utcnow() - timedelta(days=7)
|
start_date = datetime.utcnow() - timedelta(days=7)
|
||||||
log.info('First start: query archive start: %s', start_date)
|
self._log.info('First start: query archive start: %s', start_date)
|
||||||
query = self._get_archive_query(query_id, start=start_date)
|
query = self._get_archive_query(query_id, start=start_date)
|
||||||
|
|
||||||
if own_jid in self._catch_up_finished:
|
if own_jid in self._catch_up_finished:
|
||||||
|
@ -346,7 +343,7 @@ class MAM:
|
||||||
def request_archive_on_muc_join(self, jid):
|
def request_archive_on_muc_join(self, jid):
|
||||||
archive = app.logger.get_archive_infos(jid)
|
archive = app.logger.get_archive_infos(jid)
|
||||||
threshold = get_sync_threshold(jid, archive)
|
threshold = get_sync_threshold(jid, archive)
|
||||||
log.info('Threshold for %s: %s', jid, threshold)
|
self._log.info('Threshold for %s: %s', jid, threshold)
|
||||||
query_id = self._get_query_id(jid)
|
query_id = self._get_query_id(jid)
|
||||||
start_date = None
|
start_date = None
|
||||||
if archive is None or archive.last_mam_id is None:
|
if archive is None or archive.last_mam_id is None:
|
||||||
|
@ -354,14 +351,15 @@ class MAM:
|
||||||
# Depending on what a MUC saves, there could be thousands
|
# Depending on what a MUC saves, there could be thousands
|
||||||
# of Messages even in just one day.
|
# of Messages even in just one day.
|
||||||
start_date = datetime.utcnow() - timedelta(days=1)
|
start_date = datetime.utcnow() - timedelta(days=1)
|
||||||
log.info('First join: query archive %s from: %s', jid, start_date)
|
self._log.info('First join: query archive %s from: %s',
|
||||||
|
jid, start_date)
|
||||||
query = self._get_archive_query(
|
query = self._get_archive_query(
|
||||||
query_id, jid=jid, start=start_date)
|
query_id, jid=jid, start=start_date)
|
||||||
|
|
||||||
elif threshold == SyncThreshold.NO_THRESHOLD:
|
elif threshold == SyncThreshold.NO_THRESHOLD:
|
||||||
# Not our first join and no threshold set
|
# Not our first join and no threshold set
|
||||||
log.info('Request from archive: %s, after mam-id %s',
|
self._log.info('Request from archive: %s, after mam-id %s',
|
||||||
jid, archive.last_mam_id)
|
jid, archive.last_mam_id)
|
||||||
query = self._get_archive_query(
|
query = self._get_archive_query(
|
||||||
query_id, jid=jid, after=archive.last_mam_id)
|
query_id, jid=jid, after=archive.last_mam_id)
|
||||||
|
|
||||||
|
@ -370,22 +368,22 @@ class MAM:
|
||||||
# last join and check against threshold
|
# last join and check against threshold
|
||||||
last_timestamp = archive.last_muc_timestamp
|
last_timestamp = archive.last_muc_timestamp
|
||||||
if last_timestamp is None:
|
if last_timestamp is None:
|
||||||
log.info('No last muc timestamp found ( mam:1? )')
|
self._log.info('No last muc timestamp found ( mam:1? )')
|
||||||
last_timestamp = 0
|
last_timestamp = 0
|
||||||
|
|
||||||
last = datetime.utcfromtimestamp(float(last_timestamp))
|
last = datetime.utcfromtimestamp(float(last_timestamp))
|
||||||
if datetime.utcnow() - last > timedelta(days=threshold):
|
if datetime.utcnow() - last > timedelta(days=threshold):
|
||||||
# To much time has elapsed since last join, apply threshold
|
# To much time has elapsed since last join, apply threshold
|
||||||
start_date = datetime.utcnow() - timedelta(days=threshold)
|
start_date = datetime.utcnow() - timedelta(days=threshold)
|
||||||
log.info('Too much time elapsed since last join, '
|
self._log.info('Too much time elapsed since last join, '
|
||||||
'request from: %s, threshold: %s',
|
'request from: %s, threshold: %s',
|
||||||
start_date, threshold)
|
start_date, threshold)
|
||||||
query = self._get_archive_query(
|
query = self._get_archive_query(
|
||||||
query_id, jid=jid, start=start_date)
|
query_id, jid=jid, start=start_date)
|
||||||
else:
|
else:
|
||||||
# Request from last mam-id
|
# Request from last mam-id
|
||||||
log.info('Request from archive %s after %s:',
|
self._log.info('Request from archive %s after %s:',
|
||||||
jid, archive.last_mam_id)
|
jid, archive.last_mam_id)
|
||||||
query = self._get_archive_query(
|
query = self._get_archive_query(
|
||||||
query_id, jid=jid, after=archive.last_mam_id)
|
query_id, jid=jid, after=archive.last_mam_id)
|
||||||
|
|
||||||
|
@ -410,7 +408,7 @@ class MAM:
|
||||||
|
|
||||||
last = set_.getTagData('last')
|
last = set_.getTagData('last')
|
||||||
if last is None:
|
if last is None:
|
||||||
log.info('End of MAM query, no items retrieved')
|
self._log.info('End of MAM query, no items retrieved')
|
||||||
self._catch_up_finished.append(jid)
|
self._catch_up_finished.append(jid)
|
||||||
self._mam_query_ids.pop(jid)
|
self._mam_query_ids.pop(jid)
|
||||||
return
|
return
|
||||||
|
@ -434,17 +432,16 @@ class MAM:
|
||||||
jid, oldest_mam_timestamp=start_date.timestamp())
|
jid, oldest_mam_timestamp=start_date.timestamp())
|
||||||
|
|
||||||
self._catch_up_finished.append(jid)
|
self._catch_up_finished.append(jid)
|
||||||
log.info('End of MAM query, last mam id: %s', last)
|
self._log.info('End of MAM query, last mam id: %s', last)
|
||||||
|
|
||||||
def request_archive_interval(self, start_date, end_date, after=None,
|
def request_archive_interval(self, start_date, end_date, after=None,
|
||||||
query_id=None):
|
query_id=None):
|
||||||
jid = self._con.get_own_jid().getStripped()
|
jid = self._con.get_own_jid().getStripped()
|
||||||
if after is None:
|
if after is None:
|
||||||
log.info('Request intervall from %s to %s from %s',
|
self._log.info('Request intervall from %s to %s from %s',
|
||||||
start_date, end_date, jid)
|
start_date, end_date, jid)
|
||||||
else:
|
else:
|
||||||
log.info('Query page after %s from %s',
|
self._log.info('Query page after %s from %s', after, jid)
|
||||||
after, jid)
|
|
||||||
if query_id is None:
|
if query_id is None:
|
||||||
query_id = self._get_query_id(jid)
|
query_id = self._get_query_id(jid)
|
||||||
self._mam_query_ids[jid] = query_id
|
self._mam_query_ids[jid] = query_id
|
||||||
|
@ -477,14 +474,14 @@ class MAM:
|
||||||
None, query_id=query_id))
|
None, query_id=query_id))
|
||||||
app.logger.set_archive_infos(
|
app.logger.set_archive_infos(
|
||||||
jid, oldest_mam_timestamp=timestamp)
|
jid, oldest_mam_timestamp=timestamp)
|
||||||
log.info('End of MAM request, no items retrieved')
|
self._log.info('End of MAM request, no items retrieved')
|
||||||
return
|
return
|
||||||
|
|
||||||
complete = fin.getAttr('complete')
|
complete = fin.getAttr('complete')
|
||||||
if complete != 'true':
|
if complete != 'true':
|
||||||
self.request_archive_interval(start_date, end_date, last, query_id)
|
self.request_archive_interval(start_date, end_date, last, query_id)
|
||||||
else:
|
else:
|
||||||
log.info('Request finished')
|
self._log.info('Request finished')
|
||||||
app.logger.set_archive_infos(
|
app.logger.set_archive_infos(
|
||||||
jid, oldest_mam_timestamp=timestamp)
|
jid, oldest_mam_timestamp=timestamp)
|
||||||
app.nec.push_incoming_event(ArchivingIntervalFinished(
|
app.nec.push_incoming_event(ArchivingIntervalFinished(
|
||||||
|
@ -534,7 +531,7 @@ class MAM:
|
||||||
jid = self._con.get_own_jid().getStripped()
|
jid = self._con.get_own_jid().getStripped()
|
||||||
if jid not in self._catch_up_finished:
|
if jid not in self._catch_up_finished:
|
||||||
return
|
return
|
||||||
log.info('Save: %s: %s, %s', jid, stanza_id, timestamp)
|
self._log.info('Save: %s: %s, %s', jid, stanza_id, timestamp)
|
||||||
if stanza_id is None:
|
if stanza_id is None:
|
||||||
# mam:1
|
# mam:1
|
||||||
app.logger.set_archive_infos(jid, last_muc_timestamp=timestamp)
|
app.logger.set_archive_infos(jid, last_muc_timestamp=timestamp)
|
||||||
|
@ -544,7 +541,7 @@ class MAM:
|
||||||
jid, last_mam_id=stanza_id, last_muc_timestamp=timestamp)
|
jid, last_mam_id=stanza_id, last_muc_timestamp=timestamp)
|
||||||
|
|
||||||
def request_mam_preferences(self):
|
def request_mam_preferences(self):
|
||||||
log.info('Request MAM preferences')
|
self._log.info('Request MAM preferences')
|
||||||
iq = nbxmpp.Iq('get', self.archiving_namespace)
|
iq = nbxmpp.Iq('get', self.archiving_namespace)
|
||||||
iq.setQuery('prefs')
|
iq.setQuery('prefs')
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
|
@ -552,15 +549,15 @@ class MAM:
|
||||||
|
|
||||||
def _preferences_received(self, stanza):
|
def _preferences_received(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
app.nec.push_incoming_event(MAMPreferenceError(
|
app.nec.push_incoming_event(MAMPreferenceError(
|
||||||
None, conn=self._con, error=stanza.getError()))
|
None, conn=self._con, error=stanza.getError()))
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Received MAM preferences')
|
self._log.info('Received MAM preferences')
|
||||||
prefs = stanza.getTag('prefs', namespace=self.archiving_namespace)
|
prefs = stanza.getTag('prefs', namespace=self.archiving_namespace)
|
||||||
if prefs is None:
|
if prefs is None:
|
||||||
log.error('Malformed stanza (no prefs node): %s', stanza)
|
self._log.error('Malformed stanza (no prefs node): %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
rules = []
|
rules = []
|
||||||
|
@ -593,11 +590,11 @@ class MAM:
|
||||||
|
|
||||||
def _preferences_saved(self, stanza):
|
def _preferences_saved(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
app.nec.push_incoming_event(MAMPreferenceError(
|
app.nec.push_incoming_event(MAMPreferenceError(
|
||||||
None, conn=self._con, error=stanza.getError()))
|
None, conn=self._con, error=stanza.getError()))
|
||||||
else:
|
else:
|
||||||
log.info('Preferences saved')
|
self._log.info('Preferences saved')
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
MAMPreferenceSaved(None, conn=self._con))
|
MAMPreferenceSaved(None, conn=self._con))
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
# Message handler
|
# Message handler
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
from nbxmpp.structs import StanzaHandler
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
@ -28,6 +27,7 @@ from gajim.common.nec import NetworkIncomingEvent
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
from gajim.common.helpers import AdditionalDataDict
|
from gajim.common.helpers import AdditionalDataDict
|
||||||
from gajim.common.const import KindConstant
|
from gajim.common.const import KindConstant
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.modules.util import get_eme_message
|
from gajim.common.modules.util import get_eme_message
|
||||||
from gajim.common.modules.security_labels import parse_securitylabel
|
from gajim.common.modules.security_labels import parse_securitylabel
|
||||||
from gajim.common.modules.user_nickname import parse_nickname
|
from gajim.common.modules.user_nickname import parse_nickname
|
||||||
|
@ -40,13 +40,9 @@ from gajim.common.modules.misc import parse_xhtml
|
||||||
from gajim.common.connection_handlers_events import MessageErrorEvent
|
from gajim.common.connection_handlers_events import MessageErrorEvent
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.message')
|
class Message(BaseModule):
|
||||||
|
|
||||||
|
|
||||||
class Message:
|
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
StanzaHandler(name='message',
|
StanzaHandler(name='message',
|
||||||
|
@ -67,7 +63,7 @@ class Message:
|
||||||
if self._message_namespaces & set(stanza.getProperties()):
|
if self._message_namespaces & set(stanza.getProperties()):
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Received from %s', stanza.getFrom())
|
self._log.info('Received from %s', stanza.getFrom())
|
||||||
|
|
||||||
app.nec.push_incoming_event(NetworkEvent(
|
app.nec.push_incoming_event(NetworkEvent(
|
||||||
'raw-message-received',
|
'raw-message-received',
|
||||||
|
@ -96,7 +92,7 @@ class Message:
|
||||||
# Check groupchat messages for duplicates,
|
# Check groupchat messages for duplicates,
|
||||||
# We do this because of MUC History messages
|
# We do this because of MUC History messages
|
||||||
if (properties.type.is_groupchat or
|
if (properties.type.is_groupchat or
|
||||||
properties.is_self_message or
|
properties.is_self_message or
|
||||||
properties.is_muc_pm):
|
properties.is_muc_pm):
|
||||||
if properties.type.is_groupchat:
|
if properties.type.is_groupchat:
|
||||||
archive_jid = stanza.getFrom().getStripped()
|
archive_jid = stanza.getFrom().getStripped()
|
||||||
|
@ -309,11 +305,10 @@ class Message:
|
||||||
self._con.get_module('MAM').save_archive_id(
|
self._con.get_module('MAM').save_archive_id(
|
||||||
event.room_jid, event.stanza_id, event.timestamp)
|
event.room_jid, event.stanza_id, event.timestamp)
|
||||||
|
|
||||||
@staticmethod
|
def _check_for_mam_compliance(self, room_jid, stanza_id):
|
||||||
def _check_for_mam_compliance(room_jid, stanza_id):
|
|
||||||
namespace = caps_cache.muc_caps_cache.get_mam_namespace(room_jid)
|
namespace = caps_cache.muc_caps_cache.get_mam_namespace(room_jid)
|
||||||
if stanza_id is None and namespace == nbxmpp.NS_MAM_2:
|
if stanza_id is None and namespace == nbxmpp.NS_MAM_2:
|
||||||
log.warning('%s announces mam:2 without stanza-id', room_jid)
|
self._log.warning('%s announces mam:2 without stanza-id', room_jid)
|
||||||
|
|
||||||
def _get_unique_id(self, properties):
|
def _get_unique_id(self, properties):
|
||||||
if properties.is_self_message:
|
if properties.is_self_message:
|
||||||
|
|
|
@ -14,27 +14,22 @@
|
||||||
|
|
||||||
# XEP-0209: Metacontacts
|
# XEP-0209: Metacontacts
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.metacontacts')
|
|
||||||
|
|
||||||
|
|
||||||
class MetaContacts:
|
class MetaContacts(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
self.available = False
|
self.available = False
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
def get_metacontacts(self):
|
def get_metacontacts(self):
|
||||||
log.info('Request')
|
self._log.info('Request')
|
||||||
node = nbxmpp.Node('storage', attrs={'xmlns': 'storage:metacontacts'})
|
node = nbxmpp.Node('storage', attrs={'xmlns': 'storage:metacontacts'})
|
||||||
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVATE, payload=node)
|
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVATE, payload=node)
|
||||||
|
|
||||||
|
@ -43,12 +38,12 @@ class MetaContacts:
|
||||||
|
|
||||||
def _metacontacts_received(self, stanza):
|
def _metacontacts_received(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Request error: %s', stanza.getError())
|
self._log.info('Request error: %s', stanza.getError())
|
||||||
else:
|
else:
|
||||||
self.available = True
|
self.available = True
|
||||||
meta_list = self._parse_metacontacts(stanza)
|
meta_list = self._parse_metacontacts(stanza)
|
||||||
|
|
||||||
log.info('Received: %s', meta_list)
|
self._log.info('Received: %s', meta_list)
|
||||||
|
|
||||||
app.nec.push_incoming_event(NetworkEvent(
|
app.nec.push_incoming_event(NetworkEvent(
|
||||||
'metacontacts-received', conn=self._con, meta_list=meta_list))
|
'metacontacts-received', conn=self._con, meta_list=meta_list))
|
||||||
|
@ -94,14 +89,13 @@ class MetaContacts:
|
||||||
if 'order' in data:
|
if 'order' in data:
|
||||||
dict_['order'] = data['order']
|
dict_['order'] = data['order']
|
||||||
meta.addChild(name='meta', attrs=dict_)
|
meta.addChild(name='meta', attrs=dict_)
|
||||||
log.info('Store: %s', tags_list)
|
self._log.info('Store: %s', tags_list)
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._store_response_received)
|
iq, self._store_response_received)
|
||||||
|
|
||||||
@staticmethod
|
def _store_response_received(self, stanza):
|
||||||
def _store_response_received(stanza):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Store error: %s', stanza.getError())
|
self._log.info('Store error: %s', stanza.getError())
|
||||||
|
|
||||||
|
|
||||||
def get_instance(*args, **kwargs):
|
def get_instance(*args, **kwargs):
|
||||||
|
|
|
@ -103,7 +103,7 @@ class MUC(BaseModule):
|
||||||
if identity.get('type') != 'text':
|
if identity.get('type') != 'text':
|
||||||
continue
|
continue
|
||||||
if nbxmpp.NS_MUC in features:
|
if nbxmpp.NS_MUC in features:
|
||||||
log.info('Discovered MUC: %s', from_)
|
self._log.info('Discovered MUC: %s', from_)
|
||||||
# TODO: make this nicer
|
# TODO: make this nicer
|
||||||
self._con.muc_jid['jabber'] = from_
|
self._con.muc_jid['jabber'] = from_
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
@ -122,7 +122,7 @@ class MUC(BaseModule):
|
||||||
if password is not None:
|
if password is not None:
|
||||||
muc_x.setTagData('password', password)
|
muc_x.setTagData('password', password)
|
||||||
|
|
||||||
log.debug('Send MUC join presence:\n%s', presence)
|
self._log.debug('Send MUC join presence:\n%s', presence)
|
||||||
|
|
||||||
self._con.connection.send(presence)
|
self._con.connection.send(presence)
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ class MUC(BaseModule):
|
||||||
for contact in app.contacts.get_gc_contact_list(
|
for contact in app.contacts.get_gc_contact_list(
|
||||||
self._account, properties.jid.getBare()):
|
self._account, properties.jid.getBare()):
|
||||||
contact.presence = PresenceType.UNAVAILABLE
|
contact.presence = PresenceType.UNAVAILABLE
|
||||||
log.info('MUC destroyed: %s', properties.jid.getBare())
|
self._log.info('MUC destroyed: %s', properties.jid.getBare())
|
||||||
self._raise_muc_event('muc-destroyed', properties)
|
self._raise_muc_event('muc-destroyed', properties)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -183,19 +183,19 @@ class MUC(BaseModule):
|
||||||
app.contacts.remove_gc_contact(self._account, contact)
|
app.contacts.remove_gc_contact(self._account, contact)
|
||||||
contact.name = properties.muc_user.nick
|
contact.name = properties.muc_user.nick
|
||||||
app.contacts.add_gc_contact(self._account, contact)
|
app.contacts.add_gc_contact(self._account, contact)
|
||||||
log.info('Nickname changed: %s to %s',
|
self._log.info('Nickname changed: %s to %s',
|
||||||
properties.jid,
|
properties.jid,
|
||||||
properties.muc_user.nick)
|
properties.muc_user.nick)
|
||||||
self._raise_muc_event('muc-nickname-changed', properties)
|
self._raise_muc_event('muc-nickname-changed', properties)
|
||||||
return
|
return
|
||||||
|
|
||||||
if contact is None and properties.type.is_available:
|
if contact is None and properties.type.is_available:
|
||||||
self._add_new_muc_contact(properties)
|
self._add_new_muc_contact(properties)
|
||||||
if properties.is_muc_self_presence:
|
if properties.is_muc_self_presence:
|
||||||
log.info('Self presence: %s', properties.jid)
|
self._log.info('Self presence: %s', properties.jid)
|
||||||
self._raise_muc_event('muc-self-presence', properties)
|
self._raise_muc_event('muc-self-presence', properties)
|
||||||
else:
|
else:
|
||||||
log.info('User joined: %s', properties.jid)
|
self._log.info('User joined: %s', properties.jid)
|
||||||
self._raise_muc_event('muc-user-joined', properties)
|
self._raise_muc_event('muc-user-joined', properties)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -226,39 +226,39 @@ class MUC(BaseModule):
|
||||||
if contact is None:
|
if contact is None:
|
||||||
# If contact is None, its probably that a user left from a not
|
# If contact is None, its probably that a user left from a not
|
||||||
# insync MUC, can happen on older servers
|
# insync MUC, can happen on older servers
|
||||||
log.warning('Unknown contact left groupchat: %s',
|
self._log.warning('Unknown contact left groupchat: %s',
|
||||||
properties.jid)
|
properties.jid)
|
||||||
else:
|
else:
|
||||||
# We remove the contact from the MUC, but there could be
|
# We remove the contact from the MUC, but there could be
|
||||||
# a PrivateChatControl open, so we update the contacts presence
|
# a PrivateChatControl open, so we update the contacts presence
|
||||||
contact.presence = properties.type
|
contact.presence = properties.type
|
||||||
app.contacts.remove_gc_contact(self._account, contact)
|
app.contacts.remove_gc_contact(self._account, contact)
|
||||||
log.info('User %s left', properties.jid)
|
self._log.info('User %s left', properties.jid)
|
||||||
self._raise_muc_event('muc-user-left', properties)
|
self._raise_muc_event('muc-user-left', properties)
|
||||||
return
|
return
|
||||||
|
|
||||||
if contact.affiliation != properties.affiliation:
|
if contact.affiliation != properties.affiliation:
|
||||||
contact.affiliation = properties.affiliation
|
contact.affiliation = properties.affiliation
|
||||||
log.info('Affiliation changed: %s %s',
|
self._log.info('Affiliation changed: %s %s',
|
||||||
properties.jid,
|
properties.jid,
|
||||||
properties.affiliation)
|
properties.affiliation)
|
||||||
self._raise_muc_event('muc-user-affiliation-changed', properties)
|
self._raise_muc_event('muc-user-affiliation-changed', properties)
|
||||||
|
|
||||||
if contact.role != properties.role:
|
if contact.role != properties.role:
|
||||||
contact.role = properties.role
|
contact.role = properties.role
|
||||||
log.info('Role changed: %s %s',
|
self._log.info('Role changed: %s %s',
|
||||||
properties.jid,
|
properties.jid,
|
||||||
properties.role)
|
properties.role)
|
||||||
self._raise_muc_event('muc-user-role-changed', properties)
|
self._raise_muc_event('muc-user-role-changed', properties)
|
||||||
|
|
||||||
if (contact.status != properties.status or
|
if (contact.status != properties.status or
|
||||||
contact.show != properties.show):
|
contact.show != properties.show):
|
||||||
contact.status = properties.status
|
contact.status = properties.status
|
||||||
contact.show = properties.show
|
contact.show = properties.show
|
||||||
log.info('Show/Status changed: %s %s %s',
|
self._log.info('Show/Status changed: %s %s %s',
|
||||||
properties.jid,
|
properties.jid,
|
||||||
properties.status,
|
properties.status,
|
||||||
properties.show)
|
properties.show)
|
||||||
self._raise_muc_event('muc-user-status-show-changed', properties)
|
self._raise_muc_event('muc-user-status-show-changed', properties)
|
||||||
|
|
||||||
def _raise_muc_event(self, event_name, properties):
|
def _raise_muc_event(self, event_name, properties):
|
||||||
|
@ -364,7 +364,7 @@ class MUC(BaseModule):
|
||||||
if contact is None:
|
if contact is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Captcha challenge received from %s', properties.jid)
|
self._log.info('Captcha challenge received from %s', properties.jid)
|
||||||
store_bob_data(properties.captcha.bob_data)
|
store_bob_data(properties.captcha.bob_data)
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
|
@ -378,8 +378,8 @@ class MUC(BaseModule):
|
||||||
if not properties.is_muc_config_change:
|
if not properties.is_muc_config_change:
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Received config change: %s %s',
|
self._log.info('Received config change: %s %s',
|
||||||
properties.jid, properties.muc_status_codes)
|
properties.jid, properties.muc_status_codes)
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
NetworkEvent('muc-config-changed',
|
NetworkEvent('muc-config-changed',
|
||||||
account=self._account,
|
account=self._account,
|
||||||
|
@ -393,8 +393,8 @@ class MUC(BaseModule):
|
||||||
if helpers.ignore_contact(self._account, data.from_):
|
if helpers.ignore_contact(self._account, data.from_):
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
log.info('Invite declined from: %s, reason: %s',
|
self._log.info('Invite declined from: %s, reason: %s',
|
||||||
data.from_, data.reason)
|
data.from_, data.reason)
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
NetworkEvent('muc-decline',
|
NetworkEvent('muc-decline',
|
||||||
|
@ -407,11 +407,11 @@ class MUC(BaseModule):
|
||||||
if helpers.ignore_contact(self._account, data.from_):
|
if helpers.ignore_contact(self._account, data.from_):
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
log.info('Invite from: %s, to: %s', data.from_, data.muc)
|
self._log.info('Invite from: %s, to: %s', data.from_, data.muc)
|
||||||
|
|
||||||
if app.in_groupchat(self._account, data.muc):
|
if app.in_groupchat(self._account, data.muc):
|
||||||
# We are already in groupchat. Ignore invitation
|
# We are already in groupchat. Ignore invitation
|
||||||
log.info('We are already in this room')
|
self._log.info('We are already in this room')
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
|
|
|
@ -19,17 +19,12 @@ from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common.types import ConnectionT
|
from gajim.common.types import ConnectionT
|
||||||
from gajim.common.modules.base import BaseModule
|
from gajim.common.modules.base import BaseModule
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.pep')
|
|
||||||
|
|
||||||
|
|
||||||
class PEP(BaseModule):
|
class PEP(BaseModule):
|
||||||
def __init__(self, con: ConnectionT) -> None:
|
def __init__(self, con: ConnectionT) -> None:
|
||||||
BaseModule.__init__(self, con)
|
BaseModule.__init__(self, con)
|
||||||
|
@ -45,7 +40,7 @@ class PEP(BaseModule):
|
||||||
for identity in identities:
|
for identity in identities:
|
||||||
if identity['category'] == 'pubsub':
|
if identity['category'] == 'pubsub':
|
||||||
if identity.get('type') == 'pep':
|
if identity.get('type') == 'pep':
|
||||||
log.info('Discovered PEP support: %s', from_)
|
self._log.info('Discovered PEP support: %s', from_)
|
||||||
self.supported = True
|
self.supported = True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,28 +17,29 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import logging
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
from gajim.common.types import ConnectionT
|
from gajim.common.types import ConnectionT
|
||||||
from gajim.common.types import ContactsT
|
from gajim.common.types import ContactsT
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.ping')
|
|
||||||
|
|
||||||
|
|
||||||
class Ping:
|
class Ping(BaseModule):
|
||||||
def __init__(self, con: ConnectionT) -> None:
|
def __init__(self, con: ConnectionT) -> None:
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
self._timeout_id = None
|
self._timeout_id = None
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._answer_request, 'get', nbxmpp.NS_PING),
|
StanzaHandler(name='iq',
|
||||||
|
callback=self._answer_request,
|
||||||
|
typ='get',
|
||||||
|
ns=nbxmpp.NS_PING),
|
||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -51,7 +52,7 @@ class Ping:
|
||||||
if not app.account_is_connected(self._account):
|
if not app.account_is_connected(self._account):
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Send keepalive')
|
self._log.info('Send keepalive')
|
||||||
|
|
||||||
seconds = app.config.get_per('accounts', self._account,
|
seconds = app.config.get_per('accounts', self._account,
|
||||||
'time_for_ping_alive_answer')
|
'time_for_ping_alive_answer')
|
||||||
|
@ -62,14 +63,15 @@ class Ping:
|
||||||
self._keepalive_received)
|
self._keepalive_received)
|
||||||
|
|
||||||
def _keepalive_received(self, _stanza: nbxmpp.Iq) -> None:
|
def _keepalive_received(self, _stanza: nbxmpp.Iq) -> None:
|
||||||
log.info('Received keepalive')
|
self._log.info('Received keepalive')
|
||||||
self.remove_timeout()
|
self.remove_timeout()
|
||||||
|
|
||||||
def _reconnect(self) -> None:
|
def _reconnect(self) -> None:
|
||||||
if not app.account_is_connected(self._account):
|
if not app.account_is_connected(self._account):
|
||||||
return
|
return
|
||||||
# We haven't got the pong in time, disco and reconnect
|
# We haven't got the pong in time, disco and reconnect
|
||||||
log.warning('No reply received for keepalive ping. Reconnecting...')
|
self._log.warning('No reply received for keepalive ping. '
|
||||||
|
'Reconnecting...')
|
||||||
self._con.disconnect(immediately=True)
|
self._con.disconnect(immediately=True)
|
||||||
|
|
||||||
def send_ping(self, contact: ContactsT) -> None:
|
def send_ping(self, contact: ContactsT) -> None:
|
||||||
|
@ -79,7 +81,7 @@ class Ping:
|
||||||
to = contact.get_full_jid()
|
to = contact.get_full_jid()
|
||||||
iq = self._get_ping_iq(to)
|
iq = self._get_ping_iq(to)
|
||||||
|
|
||||||
log.info('Send ping to %s', to)
|
self._log.info('Send ping to %s', to)
|
||||||
|
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._pong_received, {'ping_time': time.time(),
|
iq, self._pong_received, {'ping_time': time.time(),
|
||||||
|
@ -94,13 +96,13 @@ class Ping:
|
||||||
ping_time: int,
|
ping_time: int,
|
||||||
contact: ContactsT) -> None:
|
contact: ContactsT) -> None:
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
PingErrorEvent(None, conn=self._con, contact=contact))
|
PingErrorEvent(None, conn=self._con, contact=contact))
|
||||||
return
|
return
|
||||||
diff = round(time.time() - ping_time, 2)
|
diff = round(time.time() - ping_time, 2)
|
||||||
log.info('Received pong from %s after %s seconds',
|
self._log.info('Received pong from %s after %s seconds',
|
||||||
stanza.getFrom(), diff)
|
stanza.getFrom(), diff)
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
PingReplyEvent(None, conn=self._con,
|
PingReplyEvent(None, conn=self._con,
|
||||||
contact=contact,
|
contact=contact,
|
||||||
|
@ -108,19 +110,20 @@ class Ping:
|
||||||
|
|
||||||
def _answer_request(self,
|
def _answer_request(self,
|
||||||
_con: ConnectionT,
|
_con: ConnectionT,
|
||||||
stanza: nbxmpp.Iq) -> None:
|
stanza: nbxmpp.Iq,
|
||||||
|
_properties: Any) -> None:
|
||||||
iq = stanza.buildReply('result')
|
iq = stanza.buildReply('result')
|
||||||
ping = iq.getTag('ping')
|
ping = iq.getTag('ping')
|
||||||
if ping is not None:
|
if ping is not None:
|
||||||
iq.delChild(ping)
|
iq.delChild(ping)
|
||||||
self._con.connection.send(iq)
|
self._con.connection.send(iq)
|
||||||
log.info('Send pong to %s', stanza.getFrom())
|
self._log.info('Send pong to %s', stanza.getFrom())
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
def remove_timeout(self) -> None:
|
def remove_timeout(self) -> None:
|
||||||
if self._timeout_id is None:
|
if self._timeout_id is None:
|
||||||
return
|
return
|
||||||
log.info('Remove ping timeout')
|
self._log.info('Remove ping timeout')
|
||||||
GLib.source_remove(self._timeout_id)
|
GLib.source_remove(self._timeout_id)
|
||||||
self._timeout_id = None
|
self._timeout_id = None
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
# Presence handler
|
# Presence handler
|
||||||
|
|
||||||
import logging
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
@ -27,14 +26,12 @@ from gajim.common.nec import NetworkEvent
|
||||||
from gajim.common.const import KindConstant
|
from gajim.common.const import KindConstant
|
||||||
from gajim.common.const import ShowConstant
|
from gajim.common.const import ShowConstant
|
||||||
from gajim.common.helpers import prepare_and_validate_gpg_keyID
|
from gajim.common.helpers import prepare_and_validate_gpg_keyID
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.presence')
|
|
||||||
|
|
||||||
|
|
||||||
class Presence:
|
class Presence(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
StanzaHandler(name='presence',
|
StanzaHandler(name='presence',
|
||||||
|
@ -70,10 +67,10 @@ class Presence:
|
||||||
# Already handled in MUC module
|
# Already handled in MUC module
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Received from %s', properties.jid)
|
self._log.info('Received from %s', properties.jid)
|
||||||
|
|
||||||
if properties.type == PresenceType.ERROR:
|
if properties.type == PresenceType.ERROR:
|
||||||
log.info('Error: %s %s', properties.jid, properties.error)
|
self._log.info('Error: %s %s', properties.jid, properties.error)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._account == 'Local':
|
if self._account == 'Local':
|
||||||
|
@ -93,8 +90,8 @@ class Presence:
|
||||||
contacts = app.contacts.get_jid_list(self._account)
|
contacts = app.contacts.get_jid_list(self._account)
|
||||||
if properties.jid.getBare() not in contacts and not properties.is_self_bare:
|
if properties.jid.getBare() not in contacts and not properties.is_self_bare:
|
||||||
# Handle only presence from roster contacts
|
# Handle only presence from roster contacts
|
||||||
log.warning('Unknown presence received')
|
self._log.warning('Unknown presence received')
|
||||||
log.warning(stanza)
|
self._log.warning(stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
key_id = ''
|
key_id = ''
|
||||||
|
@ -151,7 +148,7 @@ class Presence:
|
||||||
# Update contact
|
# Update contact
|
||||||
contact_list = app.contacts.get_contacts(self._account, jid)
|
contact_list = app.contacts.get_contacts(self._account, jid)
|
||||||
if not contact_list:
|
if not contact_list:
|
||||||
log.warning('No contact found')
|
self._log.warning('No contact found')
|
||||||
return
|
return
|
||||||
|
|
||||||
event.contact_list = contact_list
|
event.contact_list = contact_list
|
||||||
|
@ -162,7 +159,7 @@ class Presence:
|
||||||
if contact is None:
|
if contact is None:
|
||||||
contact = app.contacts.get_first_contact_from_jid(self._account, jid)
|
contact = app.contacts.get_first_contact_from_jid(self._account, jid)
|
||||||
if contact is None:
|
if contact is None:
|
||||||
log.warning('First contact not found')
|
self._log.warning('First contact not found')
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._is_resource_known(contact_list) and not app.jid_is_transport(jid):
|
if self._is_resource_known(contact_list) and not app.jid_is_transport(jid):
|
||||||
|
@ -255,9 +252,10 @@ class Presence:
|
||||||
is_transport = app.jid_is_transport(fjid)
|
is_transport = app.jid_is_transport(fjid)
|
||||||
auto_auth = app.config.get_per('accounts', self._account, 'autoauth')
|
auto_auth = app.config.get_per('accounts', self._account, 'autoauth')
|
||||||
|
|
||||||
log.info('Received Subscribe: %s, transport: %s, '
|
self._log.info('Received Subscribe: %s, transport: %s, '
|
||||||
'auto_auth: %s, user_nick: %s',
|
'auto_auth: %s, user_nick: %s',
|
||||||
properties.jid, is_transport, auto_auth, properties.nickname)
|
properties.jid, is_transport,
|
||||||
|
auto_auth, properties.nickname)
|
||||||
|
|
||||||
if is_transport and fjid in self._con.agent_registrations:
|
if is_transport and fjid in self._con.agent_registrations:
|
||||||
self._con.agent_registrations[fjid]['sub_received'] = True
|
self._con.agent_registrations[fjid]['sub_received'] = True
|
||||||
|
@ -285,7 +283,7 @@ class Presence:
|
||||||
def _subscribed_received(self, _con, _stanza, properties):
|
def _subscribed_received(self, _con, _stanza, properties):
|
||||||
jid = properties.jid.getBare()
|
jid = properties.jid.getBare()
|
||||||
resource = properties.jid.getResource()
|
resource = properties.jid.getResource()
|
||||||
log.info('Received Subscribed: %s', properties.jid)
|
self._log.info('Received Subscribed: %s', properties.jid)
|
||||||
if jid in self.automatically_added:
|
if jid in self.automatically_added:
|
||||||
self.automatically_added.remove(jid)
|
self.automatically_added.remove(jid)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
@ -295,13 +293,12 @@ class Presence:
|
||||||
conn=self._con, jid=jid, resource=resource))
|
conn=self._con, jid=jid, resource=resource))
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
@staticmethod
|
def _unsubscribe_received(self, _con, _stanza, properties):
|
||||||
def _unsubscribe_received(_con, _stanza, properties):
|
self._log.info('Received Unsubscribe: %s', properties.jid)
|
||||||
log.info('Received Unsubscribe: %s', properties.jid)
|
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
def _unsubscribed_received(self, _con, _stanza, properties):
|
def _unsubscribed_received(self, _con, _stanza, properties):
|
||||||
log.info('Received Unsubscribed: %s', properties.jid)
|
self._log.info('Received Unsubscribed: %s', properties.jid)
|
||||||
app.nec.push_incoming_event(NetworkEvent(
|
app.nec.push_incoming_event(NetworkEvent(
|
||||||
'unsubscribed-presence-received',
|
'unsubscribed-presence-received',
|
||||||
conn=self._con, jid=properties.jid.getBare()))
|
conn=self._con, jid=properties.jid.getBare()))
|
||||||
|
@ -310,13 +307,13 @@ class Presence:
|
||||||
def subscribed(self, jid):
|
def subscribed(self, jid):
|
||||||
if not app.account_is_connected(self._account):
|
if not app.account_is_connected(self._account):
|
||||||
return
|
return
|
||||||
log.info('Subscribed: %s', jid)
|
self._log.info('Subscribed: %s', jid)
|
||||||
self.send_presence(jid, 'subscribed')
|
self.send_presence(jid, 'subscribed')
|
||||||
|
|
||||||
def unsubscribed(self, jid):
|
def unsubscribed(self, jid):
|
||||||
if not app.account_is_connected(self._account):
|
if not app.account_is_connected(self._account):
|
||||||
return
|
return
|
||||||
log.info('Unsubscribed: %s', jid)
|
self._log.info('Unsubscribed: %s', jid)
|
||||||
self.send_presence(jid, 'unsubscribed')
|
self.send_presence(jid, 'unsubscribed')
|
||||||
|
|
||||||
def unsubscribe(self, jid, remove_auth=True):
|
def unsubscribe(self, jid, remove_auth=True):
|
||||||
|
@ -329,7 +326,7 @@ class Presence:
|
||||||
if j.startswith(jid):
|
if j.startswith(jid):
|
||||||
app.config.del_per('contacts', j)
|
app.config.del_per('contacts', j)
|
||||||
else:
|
else:
|
||||||
log.info('Unsubscribe from %s', jid)
|
self._log.info('Unsubscribe from %s', jid)
|
||||||
self._con.getRoster().unsubscribe(jid)
|
self._con.getRoster().unsubscribe(jid)
|
||||||
self._con.getRoster().set_item(jid)
|
self._con.getRoster().set_item(jid)
|
||||||
|
|
||||||
|
@ -339,7 +336,7 @@ class Presence:
|
||||||
if groups is None:
|
if groups is None:
|
||||||
groups = []
|
groups = []
|
||||||
|
|
||||||
log.info('Request Subscription to %s', jid)
|
self._log.info('Request Subscription to %s', jid)
|
||||||
|
|
||||||
if auto_auth:
|
if auto_auth:
|
||||||
self.jids_for_auto_auth.append(jid)
|
self.jids_for_auto_auth.append(jid)
|
||||||
|
@ -388,7 +385,7 @@ class Presence:
|
||||||
if not app.account_is_connected(self._account):
|
if not app.account_is_connected(self._account):
|
||||||
return
|
return
|
||||||
presence = self.get_presence(*args, **kwargs)
|
presence = self.get_presence(*args, **kwargs)
|
||||||
log.debug('Send presence:\n%s', presence)
|
self._log.debug('Send presence:\n%s', presence)
|
||||||
self._con.connection.send(presence)
|
self._con.connection.send(presence)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,24 +14,20 @@
|
||||||
|
|
||||||
# XEP-0016: Privacy Lists
|
# XEP-0016: Privacy Lists
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.connection_handlers_events import InformationEvent
|
from gajim.common.connection_handlers_events import InformationEvent
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.privacylists')
|
class PrivacyLists(BaseModule):
|
||||||
|
|
||||||
|
|
||||||
class PrivacyLists:
|
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.default_list = None
|
self.default_list = None
|
||||||
self.active_list = None
|
self.active_list = None
|
||||||
|
@ -41,7 +37,10 @@ class PrivacyLists:
|
||||||
self.blocked_all = False
|
self.blocked_all = False
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._list_push_received, 'set', nbxmpp.NS_PRIVACY)
|
StanzaHandler(name='iq',
|
||||||
|
callback=self._list_push_received,
|
||||||
|
typ='set',
|
||||||
|
ns=nbxmpp.NS_PRIVACY),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.supported = False
|
self.supported = False
|
||||||
|
@ -51,14 +50,14 @@ class PrivacyLists:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.supported = True
|
self.supported = True
|
||||||
log.info('Discovered XEP-0016: Privacy Lists: %s', from_)
|
self._log.info('Discovered XEP-0016: Privacy Lists: %s', from_)
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
NetworkEvent('feature-discovered',
|
NetworkEvent('feature-discovered',
|
||||||
account=self._account,
|
account=self._account,
|
||||||
feature=nbxmpp.NS_PRIVACY))
|
feature=nbxmpp.NS_PRIVACY))
|
||||||
|
|
||||||
def _list_push_received(self, _con, stanza):
|
def _list_push_received(self, _con, stanza, _properties):
|
||||||
result = stanza.buildReply('result')
|
result = stanza.buildReply('result')
|
||||||
result.delChild(result.getTag('query'))
|
result.delChild(result.getTag('query'))
|
||||||
self._con.connection.send(result)
|
self._con.connection.send(result)
|
||||||
|
@ -66,13 +65,13 @@ class PrivacyLists:
|
||||||
for list_ in stanza.getQueryPayload():
|
for list_ in stanza.getQueryPayload():
|
||||||
if list_.getName() == 'list':
|
if list_.getName() == 'list':
|
||||||
name = list_.getAttr('name')
|
name = list_.getAttr('name')
|
||||||
log.info('Received Push: %s', name)
|
self._log.info('Received Push: %s', name)
|
||||||
self.get_privacy_list(name)
|
self.get_privacy_list(name)
|
||||||
|
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
def get_privacy_lists(self, callback=None):
|
def get_privacy_lists(self, callback=None):
|
||||||
log.info('Request lists')
|
self._log.info('Request lists')
|
||||||
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVACY)
|
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVACY)
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._privacy_lists_received, {'callback': callback})
|
iq, self._privacy_lists_received, {'callback': callback})
|
||||||
|
@ -82,7 +81,7 @@ class PrivacyLists:
|
||||||
new_default = None
|
new_default = None
|
||||||
result = nbxmpp.isResultNode(stanza)
|
result = nbxmpp.isResultNode(stanza)
|
||||||
if not result:
|
if not result:
|
||||||
log.warning('List not available: %s', stanza.getError())
|
self._log.warning('List not available: %s', stanza.getError())
|
||||||
else:
|
else:
|
||||||
for list_ in stanza.getQueryPayload():
|
for list_ in stanza.getQueryPayload():
|
||||||
name = list_.getAttr('name')
|
name = list_.getAttr('name')
|
||||||
|
@ -93,13 +92,13 @@ class PrivacyLists:
|
||||||
else:
|
else:
|
||||||
lists.append(name)
|
lists.append(name)
|
||||||
|
|
||||||
log.info('Received lists: %s', lists)
|
self._log.info('Received lists: %s', lists)
|
||||||
|
|
||||||
# Download default list if we dont have it
|
# Download default list if we dont have it
|
||||||
if self.default_list != new_default:
|
if self.default_list != new_default:
|
||||||
self.default_list = new_default
|
self.default_list = new_default
|
||||||
if new_default is not None:
|
if new_default is not None:
|
||||||
log.info('Found new default list: %s', new_default)
|
self._log.info('Found new default list: %s', new_default)
|
||||||
self.get_privacy_list(new_default)
|
self.get_privacy_list(new_default)
|
||||||
|
|
||||||
if callback:
|
if callback:
|
||||||
|
@ -113,7 +112,7 @@ class PrivacyLists:
|
||||||
lists=lists))
|
lists=lists))
|
||||||
|
|
||||||
def get_privacy_list(self, name):
|
def get_privacy_list(self, name):
|
||||||
log.info('Request list: %s', name)
|
self._log.info('Request list: %s', name)
|
||||||
list_ = nbxmpp.Node('list', {'name': name})
|
list_ = nbxmpp.Node('list', {'name': name})
|
||||||
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVACY, payload=[list_])
|
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVACY, payload=[list_])
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
|
@ -121,7 +120,7 @@ class PrivacyLists:
|
||||||
|
|
||||||
def _privacy_list_received(self, stanza):
|
def _privacy_list_received(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.warning('List not available: %s', stanza.getError())
|
self._log.warning('List not available: %s', stanza.getError())
|
||||||
return
|
return
|
||||||
|
|
||||||
rules = []
|
rules = []
|
||||||
|
@ -138,11 +137,11 @@ class PrivacyLists:
|
||||||
|
|
||||||
item['child'] = childs
|
item['child'] = childs
|
||||||
if len(item) not in (3, 5):
|
if len(item) not in (3, 5):
|
||||||
log.warning('Wrong count of attrs: %s', stanza)
|
self._log.warning('Wrong count of attrs: %s', stanza)
|
||||||
continue
|
continue
|
||||||
rules.append(item)
|
rules.append(item)
|
||||||
|
|
||||||
log.info('Received list: %s', name)
|
self._log.info('Received list: %s', name)
|
||||||
|
|
||||||
if name == self.default_list:
|
if name == self.default_list:
|
||||||
self._default_list_received(rules)
|
self._default_list_received(rules)
|
||||||
|
@ -151,11 +150,11 @@ class PrivacyLists:
|
||||||
None, conn=self._con, list_name=name, rules=rules))
|
None, conn=self._con, list_name=name, rules=rules))
|
||||||
|
|
||||||
def del_privacy_list(self, name):
|
def del_privacy_list(self, name):
|
||||||
log.info('Remove list: %s', name)
|
self._log.info('Remove list: %s', name)
|
||||||
|
|
||||||
def _del_privacy_list_result(stanza):
|
def _del_privacy_list_result(stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.warning('List deletion failed: %s', stanza.getError())
|
self._log.warning('List deletion failed: %s', stanza.getError())
|
||||||
app.nec.push_incoming_event(InformationEvent(
|
app.nec.push_incoming_event(InformationEvent(
|
||||||
None, dialog_name='privacy-list-error', args=name))
|
None, dialog_name='privacy-list-error', args=name))
|
||||||
else:
|
else:
|
||||||
|
@ -176,7 +175,7 @@ class PrivacyLists:
|
||||||
node.setTag(child)
|
node.setTag(child)
|
||||||
item.pop('child', None)
|
item.pop('child', None)
|
||||||
node.setTag('item', item)
|
node.setTag('item', item)
|
||||||
log.info('Update list: %s %s', name, rules)
|
self._log.info('Update list: %s %s', name, rules)
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._default_result_handler, {})
|
iq, self._default_result_handler, {})
|
||||||
|
|
||||||
|
@ -217,7 +216,7 @@ class PrivacyLists:
|
||||||
roster.draw_group(rule['value'], self._account)
|
roster.draw_group(rule['value'], self._account)
|
||||||
|
|
||||||
def set_active_list(self, name=None):
|
def set_active_list(self, name=None):
|
||||||
log.info('Set active list: %s', name)
|
self._log.info('Set active list: %s', name)
|
||||||
attr = {}
|
attr = {}
|
||||||
if name:
|
if name:
|
||||||
attr['name'] = name
|
attr['name'] = name
|
||||||
|
@ -227,7 +226,7 @@ class PrivacyLists:
|
||||||
iq, self._default_result_handler, {})
|
iq, self._default_result_handler, {})
|
||||||
|
|
||||||
def set_default_list(self, name=None):
|
def set_default_list(self, name=None):
|
||||||
log.info('Set default list: %s', name)
|
self._log.info('Set default list: %s', name)
|
||||||
attr = {}
|
attr = {}
|
||||||
if name:
|
if name:
|
||||||
attr['name'] = name
|
attr['name'] = name
|
||||||
|
@ -236,10 +235,9 @@ class PrivacyLists:
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._default_result_handler, {})
|
iq, self._default_result_handler, {})
|
||||||
|
|
||||||
@staticmethod
|
def _default_result_handler(self, _con, stanza):
|
||||||
def _default_result_handler(_con, stanza):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.warning('Operation failed: %s', stanza.getError())
|
self._log.warning('Operation failed: %s', stanza.getError())
|
||||||
|
|
||||||
def _build_invisible_rule(self):
|
def _build_invisible_rule(self):
|
||||||
node = nbxmpp.Node('list', {'name': 'invisible'})
|
node = nbxmpp.Node('list', {'name': 'invisible'})
|
||||||
|
@ -267,7 +265,7 @@ class PrivacyLists:
|
||||||
return iq
|
return iq
|
||||||
|
|
||||||
def set_invisible_rule(self, callback=None, **kwargs):
|
def set_invisible_rule(self, callback=None, **kwargs):
|
||||||
log.info('Update invisible list')
|
self._log.info('Update invisible list')
|
||||||
iq = self._build_invisible_rule()
|
iq = self._build_invisible_rule()
|
||||||
if callback is None:
|
if callback is None:
|
||||||
callback = self._default_result_handler
|
callback = self._default_result_handler
|
||||||
|
@ -285,7 +283,7 @@ class PrivacyLists:
|
||||||
def block_gc_contact(self, jid):
|
def block_gc_contact(self, jid):
|
||||||
if jid in self.blocked_contacts:
|
if jid in self.blocked_contacts:
|
||||||
return
|
return
|
||||||
log.info('Block GC contact: %s', jid)
|
self._log.info('Block GC contact: %s', jid)
|
||||||
|
|
||||||
if self.default_list is None:
|
if self.default_list is None:
|
||||||
self.default_list = 'block'
|
self.default_list = 'block'
|
||||||
|
@ -311,7 +309,7 @@ class PrivacyLists:
|
||||||
if self.default_list is None:
|
if self.default_list is None:
|
||||||
self.default_list = 'block'
|
self.default_list = 'block'
|
||||||
for contact in contact_list:
|
for contact in contact_list:
|
||||||
log.info('Block contacts: %s', contact.jid)
|
self._log.info('Block contacts: %s', contact.jid)
|
||||||
contact.show = 'offline'
|
contact.show = 'offline'
|
||||||
self._con.send_custom_status('offline', message, contact.jid)
|
self._con.send_custom_status('offline', message, contact.jid)
|
||||||
max_order = self._get_max_blocked_list_order()
|
max_order = self._get_max_blocked_list_order()
|
||||||
|
@ -333,7 +331,7 @@ class PrivacyLists:
|
||||||
|
|
||||||
self.blocked_contacts.remove(jid)
|
self.blocked_contacts.remove(jid)
|
||||||
|
|
||||||
log.info('Unblock GC contact: %s', jid)
|
self._log.info('Unblock GC contact: %s', jid)
|
||||||
for rule in self.blocked_list:
|
for rule in self.blocked_list:
|
||||||
if (rule['action'] != 'deny' or
|
if (rule['action'] != 'deny' or
|
||||||
rule['type'] != 'jid' or
|
rule['type'] != 'jid' or
|
||||||
|
@ -358,7 +356,7 @@ class PrivacyLists:
|
||||||
new_blocked_list = []
|
new_blocked_list = []
|
||||||
to_unblock = []
|
to_unblock = []
|
||||||
for contact in contact_list:
|
for contact in contact_list:
|
||||||
log.info('Unblock contacts: %s', contact.jid)
|
self._log.info('Unblock contacts: %s', contact.jid)
|
||||||
to_unblock.append(contact.jid)
|
to_unblock.append(contact.jid)
|
||||||
if contact.jid in self.blocked_contacts:
|
if contact.jid in self.blocked_contacts:
|
||||||
self.blocked_contacts.remove(contact.jid)
|
self.blocked_contacts.remove(contact.jid)
|
||||||
|
@ -393,7 +391,7 @@ class PrivacyLists:
|
||||||
return
|
return
|
||||||
self.blocked_groups.append(group)
|
self.blocked_groups.append(group)
|
||||||
|
|
||||||
log.info('Block group: %s', group)
|
self._log.info('Block group: %s', group)
|
||||||
|
|
||||||
if self.default_list is None:
|
if self.default_list is None:
|
||||||
self.default_list = 'block'
|
self.default_list = 'block'
|
||||||
|
@ -420,7 +418,7 @@ class PrivacyLists:
|
||||||
return
|
return
|
||||||
self.blocked_groups.remove(group)
|
self.blocked_groups.remove(group)
|
||||||
|
|
||||||
log.info('Unblock group: %s', group)
|
self._log.info('Unblock group: %s', group)
|
||||||
new_blocked_list = []
|
new_blocked_list = []
|
||||||
for rule in self.blocked_list:
|
for rule in self.blocked_list:
|
||||||
if (rule['action'] != 'deny' or
|
if (rule['action'] != 'deny' or
|
||||||
|
@ -446,7 +444,7 @@ class PrivacyLists:
|
||||||
self._con.send_custom_status(show, self._con.status, contact.jid)
|
self._con.send_custom_status(show, self._con.status, contact.jid)
|
||||||
|
|
||||||
def _presence_probe(self, jid):
|
def _presence_probe(self, jid):
|
||||||
log.info('Presence probe: %s', jid)
|
self._log.info('Presence probe: %s', jid)
|
||||||
# Send a presence Probe to get the current Status
|
# Send a presence Probe to get the current Status
|
||||||
probe = nbxmpp.Presence(jid, 'probe', frm=self._con.get_own_jid())
|
probe = nbxmpp.Presence(jid, 'probe', frm=self._con.get_own_jid())
|
||||||
self._con.connection.send(probe)
|
self._con.connection.send(probe)
|
||||||
|
|
|
@ -20,23 +20,17 @@
|
||||||
|
|
||||||
# XEP-0060: Publish-Subscribe
|
# XEP-0060: Publish-Subscribe
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.modules import dataforms
|
from gajim.common.modules import dataforms
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.pubsub')
|
|
||||||
|
|
||||||
|
|
||||||
class PubSub:
|
class PubSub(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
self.publish_options = False
|
self.publish_options = False
|
||||||
|
|
||||||
|
@ -45,7 +39,7 @@ class PubSub:
|
||||||
# Remove stored bookmarks accessible to everyone.
|
# Remove stored bookmarks accessible to everyone.
|
||||||
self._con.get_module('Bookmarks').purge_pubsub_bookmarks()
|
self._con.get_module('Bookmarks').purge_pubsub_bookmarks()
|
||||||
return
|
return
|
||||||
log.info('Discovered Pubsub publish options: %s', from_)
|
self._log.info('Discovered Pubsub publish options: %s', from_)
|
||||||
self.publish_options = True
|
self.publish_options = True
|
||||||
|
|
||||||
def send_pb_subscription_query(self, jid, cb, **kwargs):
|
def send_pb_subscription_query(self, jid, cb, **kwargs):
|
||||||
|
@ -209,7 +203,7 @@ class PubSub:
|
||||||
configure = pubsub.addChild('configure', {'node': node})
|
configure = pubsub.addChild('configure', {'node': node})
|
||||||
configure.addChild(node=form)
|
configure.addChild(node=form)
|
||||||
|
|
||||||
log.info('Send node config for %s', node)
|
self._log.info('Send node config for %s', node)
|
||||||
self._con.connection.SendAndCallForResponse(query, cb, kwargs)
|
self._con.connection.SendAndCallForResponse(query, cb, kwargs)
|
||||||
|
|
||||||
def request_pb_configuration(self, jid, node):
|
def request_pb_configuration(self, jid, node):
|
||||||
|
@ -220,46 +214,45 @@ class PubSub:
|
||||||
pubsub = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
|
pubsub = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
|
||||||
pubsub.addChild('configure', {'node': node})
|
pubsub.addChild('configure', {'node': node})
|
||||||
|
|
||||||
log.info('Request node config for %s', node)
|
self._log.info('Request node config for %s', node)
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
query, self._received_pb_configuration, {'node': node})
|
query, self._received_pb_configuration, {'node': node})
|
||||||
|
|
||||||
def _received_pb_configuration(self, _con, stanza, node):
|
def _received_pb_configuration(self, _con, stanza, node):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.warning('Error: %s', stanza.getError())
|
self._log.warning('Error: %s', stanza.getError())
|
||||||
return
|
return
|
||||||
|
|
||||||
pubsub = stanza.getTag('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
|
pubsub = stanza.getTag('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
|
||||||
if pubsub is None:
|
if pubsub is None:
|
||||||
log.warning('Malformed PubSub configure '
|
self._log.warning('Malformed PubSub configure '
|
||||||
'stanza (no pubsub node): %s', stanza)
|
'stanza (no pubsub node): %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
configure = pubsub.getTag('configure')
|
configure = pubsub.getTag('configure')
|
||||||
if configure is None:
|
if configure is None:
|
||||||
log.warning('Malformed PubSub configure '
|
self._log.warning('Malformed PubSub configure '
|
||||||
'stanza (no configure node): %s', stanza)
|
'stanza (no configure node): %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
if configure.getAttr('node') != node:
|
if configure.getAttr('node') != node:
|
||||||
log.warning('Malformed PubSub configure '
|
self._log.warning('Malformed PubSub configure '
|
||||||
'stanza (wrong node): %s', stanza)
|
'stanza (wrong node): %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
form = configure.getTag('x', namespace=nbxmpp.NS_DATA)
|
form = configure.getTag('x', namespace=nbxmpp.NS_DATA)
|
||||||
if form is None:
|
if form is None:
|
||||||
log.warning('Malformed PubSub configure '
|
self._log.warning('Malformed PubSub configure '
|
||||||
'stanza (no form): %s', stanza)
|
'stanza (no form): %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
app.nec.push_incoming_event(PubSubConfigReceivedEvent(
|
app.nec.push_incoming_event(PubSubConfigReceivedEvent(
|
||||||
None, conn=self._con, node=node,
|
None, conn=self._con, node=node,
|
||||||
form=dataforms.extend_form(node=form)))
|
form=dataforms.extend_form(node=form)))
|
||||||
|
|
||||||
@staticmethod
|
def _default_callback(self, _con, stanza, *args, **kwargs):
|
||||||
def _default_callback(_con, stanza, *args, **kwargs):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.warning('Error: %s', stanza.getError())
|
self._log.warning('Error: %s', stanza.getError())
|
||||||
|
|
||||||
|
|
||||||
class PubSubConfigReceivedEvent(NetworkIncomingEvent):
|
class PubSubConfigReceivedEvent(NetworkIncomingEvent):
|
||||||
|
|
|
@ -14,22 +14,16 @@
|
||||||
|
|
||||||
# XEP-0184: Message Delivery Receipts
|
# XEP-0184: Message Delivery Receipts
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.receipts')
|
|
||||||
|
|
||||||
|
|
||||||
class Receipts:
|
class Receipts(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
def delegate(self, event):
|
def delegate(self, event):
|
||||||
request = event.stanza.getTag('request',
|
request = event.stanza.getTag('request',
|
||||||
|
@ -68,7 +62,7 @@ class Receipts:
|
||||||
return
|
return
|
||||||
|
|
||||||
receipt = self._build_answer_receipt(from_, receipt_id)
|
receipt = self._build_answer_receipt(from_, receipt_id)
|
||||||
log.info('Answer %s', receipt_id)
|
self._log.info('Answer %s', receipt_id)
|
||||||
self._con.connection.send(receipt)
|
self._con.connection.send(receipt)
|
||||||
|
|
||||||
def _get_contact(self, event):
|
def _get_contact(self, event):
|
||||||
|
@ -92,9 +86,9 @@ class Receipts:
|
||||||
def _receipt_received(self, event, received):
|
def _receipt_received(self, event, received):
|
||||||
receipt_id = received.getAttr('id')
|
receipt_id = received.getAttr('id')
|
||||||
if receipt_id is None:
|
if receipt_id is None:
|
||||||
log.warning('Receipt without ID: %s', event.stanza)
|
self._log.warning('Receipt without ID: %s', event.stanza)
|
||||||
return
|
return
|
||||||
log.info('Received %s', receipt_id)
|
self._log.info('Received %s', receipt_id)
|
||||||
|
|
||||||
jid = event.jid
|
jid = event.jid
|
||||||
if event.muc_pm:
|
if event.muc_pm:
|
||||||
|
|
|
@ -14,23 +14,18 @@
|
||||||
|
|
||||||
# XEP-0077: In-Band Registration
|
# XEP-0077: In-Band Registration
|
||||||
|
|
||||||
import logging
|
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.modules.bits_of_binary import parse_bob_data
|
from gajim.common.modules.bits_of_binary import parse_bob_data
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.register')
|
|
||||||
|
|
||||||
|
class Register(BaseModule):
|
||||||
class Register:
|
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
self.agent_registrations = {}
|
self.agent_registrations = {}
|
||||||
|
|
||||||
|
@ -46,20 +41,19 @@ class Register:
|
||||||
|
|
||||||
weak_success_cb = weakref.WeakMethod(success_cb)
|
weak_success_cb = weakref.WeakMethod(success_cb)
|
||||||
weak_error_cb = weakref.WeakMethod(error_cb)
|
weak_error_cb = weakref.WeakMethod(error_cb)
|
||||||
log.info('Send password change')
|
self._log.info('Send password change')
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._change_password_response, {'success_cb': weak_success_cb,
|
iq, self._change_password_response, {'success_cb': weak_success_cb,
|
||||||
'error_cb': weak_error_cb})
|
'error_cb': weak_error_cb})
|
||||||
|
|
||||||
@staticmethod
|
def _change_password_response(self, _con, stanza, success_cb, error_cb):
|
||||||
def _change_password_response(_con, stanza, success_cb, error_cb):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
error = stanza.getErrorMsg()
|
error = stanza.getErrorMsg()
|
||||||
log.info('Error: %s', error)
|
self._log.info('Error: %s', error)
|
||||||
if error_cb() is not None:
|
if error_cb() is not None:
|
||||||
error_cb()(error)
|
error_cb()(error)
|
||||||
else:
|
else:
|
||||||
log.info('Password changed')
|
self._log.info('Password changed')
|
||||||
if success_cb() is not None:
|
if success_cb() is not None:
|
||||||
success_cb()()
|
success_cb()()
|
||||||
|
|
||||||
|
@ -91,7 +85,7 @@ class Register:
|
||||||
success_cb, error_cb):
|
success_cb, error_cb):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
error = stanza.getErrorMsg()
|
error = stanza.getErrorMsg()
|
||||||
log.info('Error: %s', error)
|
self._log.info('Error: %s', error)
|
||||||
if error_cb() is not None:
|
if error_cb() is not None:
|
||||||
error_cb()(error)
|
error_cb()(error)
|
||||||
return
|
return
|
||||||
|
@ -117,15 +111,14 @@ class Register:
|
||||||
iq, self._register_info_response, {'success_cb': weak_success_cb,
|
iq, self._register_info_response, {'success_cb': weak_success_cb,
|
||||||
'error_cb': weak_error_cb})
|
'error_cb': weak_error_cb})
|
||||||
|
|
||||||
@staticmethod
|
def _register_info_response(self, _con, stanza, success_cb, error_cb):
|
||||||
def _register_info_response(_con, stanza, success_cb, error_cb):
|
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
error = stanza.getErrorMsg()
|
error = stanza.getErrorMsg()
|
||||||
log.info('Error: %s', error)
|
self._log.info('Error: %s', error)
|
||||||
if error_cb() is not None:
|
if error_cb() is not None:
|
||||||
error_cb()(error)
|
error_cb()(error)
|
||||||
else:
|
else:
|
||||||
log.info('Register form received')
|
self._log.info('Register form received')
|
||||||
parse_bob_data(stanza.getQuery())
|
parse_bob_data(stanza.getQuery())
|
||||||
form = stanza.getQuery().getTag('x', namespace=nbxmpp.NS_DATA)
|
form = stanza.getQuery().getTag('x', namespace=nbxmpp.NS_DATA)
|
||||||
is_form = form is not None
|
is_form = form is not None
|
||||||
|
|
|
@ -14,34 +14,36 @@
|
||||||
|
|
||||||
# Roster
|
# Roster
|
||||||
|
|
||||||
import logging
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.roster')
|
|
||||||
|
|
||||||
RosterItem = namedtuple('RosterItem', 'jid data')
|
RosterItem = namedtuple('RosterItem', 'jid data')
|
||||||
|
|
||||||
|
|
||||||
class Roster:
|
class Roster(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._roster_push_received, 'set', nbxmpp.NS_ROSTER),
|
StanzaHandler(name='iq',
|
||||||
('presence', self._presence_received)
|
callback=self._roster_push_received,
|
||||||
|
typ='set',
|
||||||
|
ns=nbxmpp.NS_ROSTER),
|
||||||
|
StanzaHandler(name='presence',
|
||||||
|
callback=self._presence_received),
|
||||||
]
|
]
|
||||||
|
|
||||||
self._data = {}
|
self._data = {}
|
||||||
self._set = None
|
self._set = None
|
||||||
|
|
||||||
def load_roster(self):
|
def load_roster(self):
|
||||||
log.info('Load from database')
|
self._log.info('Load from database')
|
||||||
account_jid = self._con.get_own_jid().getStripped()
|
account_jid = self._con.get_own_jid().getStripped()
|
||||||
data = app.logger.get_roster(account_jid)
|
data = app.logger.get_roster(account_jid)
|
||||||
if data:
|
if data:
|
||||||
|
@ -57,7 +59,7 @@ class Roster:
|
||||||
groups=item['groups'],
|
groups=item['groups'],
|
||||||
avatar_sha=item['avatar_sha']))
|
avatar_sha=item['avatar_sha']))
|
||||||
else:
|
else:
|
||||||
log.info('Database empty, reset roster version')
|
self._log.info('Database empty, reset roster version')
|
||||||
app.config.set_per(
|
app.config.set_per(
|
||||||
'accounts', self._account, 'roster_version', '')
|
'accounts', self._account, 'roster_version', '')
|
||||||
|
|
||||||
|
@ -74,26 +76,26 @@ class Roster:
|
||||||
version = app.config.get_per(
|
version = app.config.get_per(
|
||||||
'accounts', self._account, 'roster_version')
|
'accounts', self._account, 'roster_version')
|
||||||
|
|
||||||
log.info('Requested from server')
|
self._log.info('Requested from server')
|
||||||
iq = nbxmpp.Iq('get', nbxmpp.NS_ROSTER)
|
iq = nbxmpp.Iq('get', nbxmpp.NS_ROSTER)
|
||||||
if version is not None:
|
if version is not None:
|
||||||
iq.setTagAttr('query', 'ver', version)
|
iq.setTagAttr('query', 'ver', version)
|
||||||
log.info('Request version: %s', version)
|
self._log.info('Request version: %s', version)
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._roster_received)
|
iq, self._roster_received)
|
||||||
|
|
||||||
def _roster_received(self, stanza):
|
def _roster_received(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.warning('Unable to retrive roster: %s', stanza.getError())
|
self._log.warning('Unable to retrive roster: %s', stanza.getError())
|
||||||
else:
|
else:
|
||||||
log.info('Received Roster')
|
self._log.info('Received Roster')
|
||||||
received_from_server = False
|
received_from_server = False
|
||||||
if stanza.getTag('query') is not None:
|
if stanza.getTag('query') is not None:
|
||||||
# clear Roster
|
# clear Roster
|
||||||
self._data = {}
|
self._data = {}
|
||||||
version = self._parse_roster(stanza)
|
version = self._parse_roster(stanza)
|
||||||
|
|
||||||
log.info('New version: %s', version)
|
self._log.info('New version: %s', version)
|
||||||
app.logger.replace_roster(self._account, version, self._data)
|
app.logger.replace_roster(self._account, version, self._data)
|
||||||
|
|
||||||
received_from_server = True
|
received_from_server = True
|
||||||
|
@ -106,13 +108,13 @@ class Roster:
|
||||||
|
|
||||||
self._con.connect_machine()
|
self._con.connect_machine()
|
||||||
|
|
||||||
def _roster_push_received(self, _con, stanza):
|
def _roster_push_received(self, _con, stanza, _properties):
|
||||||
log.info('Push received')
|
self._log.info('Push received')
|
||||||
|
|
||||||
sender = stanza.getFrom()
|
sender = stanza.getFrom()
|
||||||
if sender is not None:
|
if sender is not None:
|
||||||
if not self._con.get_own_jid().bareMatch(sender):
|
if not self._con.get_own_jid().bareMatch(sender):
|
||||||
log.warning('Wrong JID %s', stanza.getFrom())
|
self._log.warning('Wrong JID %s', stanza.getFrom())
|
||||||
return
|
return
|
||||||
|
|
||||||
push_items, version = self._parse_push(stanza)
|
push_items, version = self._parse_push(stanza)
|
||||||
|
@ -135,7 +137,7 @@ class Roster:
|
||||||
account_jid, item.jid, attrs['name'],
|
account_jid, item.jid, attrs['name'],
|
||||||
attrs['subscription'], attrs['ask'], attrs['groups'])
|
attrs['subscription'], attrs['ask'], attrs['groups'])
|
||||||
|
|
||||||
log.info('New version: %s', version)
|
self._log.info('New version: %s', version)
|
||||||
app.config.set_per(
|
app.config.set_per(
|
||||||
'accounts', self._account, 'roster_version', version)
|
'accounts', self._account, 'roster_version', version)
|
||||||
|
|
||||||
|
@ -148,7 +150,7 @@ class Roster:
|
||||||
for item in query.getTags('item'):
|
for item in query.getTags('item'):
|
||||||
jid = item.getAttr('jid')
|
jid = item.getAttr('jid')
|
||||||
self._data[jid] = self._get_item_attrs(item, update=False)
|
self._data[jid] = self._get_item_attrs(item, update=False)
|
||||||
log.info('Item %s: %s', jid, self._data[jid])
|
self._log.info('Item %s: %s', jid, self._data[jid])
|
||||||
return version
|
return version
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -186,7 +188,7 @@ class Roster:
|
||||||
for item in query.getTags('item'):
|
for item in query.getTags('item'):
|
||||||
push_items.append(self._update_roster_item(item))
|
push_items.append(self._update_roster_item(item))
|
||||||
for item in push_items:
|
for item in push_items:
|
||||||
log.info('Push: %s', item)
|
self._log.info('Push: %s', item)
|
||||||
return push_items, version
|
return push_items, version
|
||||||
|
|
||||||
def _update_roster_item(self, item):
|
def _update_roster_item(self, item):
|
||||||
|
@ -211,7 +213,7 @@ class Roster:
|
||||||
attrs={'id': stanza.getID()})
|
attrs={'id': stanza.getID()})
|
||||||
self._con.connection.send(iq)
|
self._con.connection.send(iq)
|
||||||
|
|
||||||
def _presence_received(self, _con, pres):
|
def _presence_received(self, _con, pres, _properties):
|
||||||
'''
|
'''
|
||||||
Add contacts that request subscription to our internal
|
Add contacts that request subscription to our internal
|
||||||
roster and also to the database. The contact is put into the
|
roster and also to the database. The contact is put into the
|
||||||
|
@ -227,7 +229,7 @@ class Roster:
|
||||||
if jid in self._data:
|
if jid in self._data:
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Add Contact from presence %s', jid)
|
self._log.info('Add Contact from presence %s', jid)
|
||||||
self._data[jid] = {'name': None,
|
self._data[jid] = {'name': None,
|
||||||
'ask': None,
|
'ask': None,
|
||||||
'subscription':
|
'subscription':
|
||||||
|
|
|
@ -14,32 +14,34 @@
|
||||||
|
|
||||||
# XEP-0144: Roster Item Exchange
|
# XEP-0144: Roster Item Exchange
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
from gajim.common.i18n import _
|
from gajim.common.i18n import _
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.roster_item_exchange')
|
|
||||||
|
|
||||||
|
|
||||||
class RosterItemExchange:
|
class RosterItemExchange(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self.received_item, 'set', nbxmpp.NS_ROSTERX),
|
StanzaHandler(name='iq',
|
||||||
('message', self.received_item, '', nbxmpp.NS_ROSTERX)
|
callback=self.received_item,
|
||||||
|
typ='set',
|
||||||
|
ns=nbxmpp.NS_ROSTERX),
|
||||||
|
StanzaHandler(name='message',
|
||||||
|
callback=self.received_item,
|
||||||
|
ns=nbxmpp.NS_ROSTERX),
|
||||||
]
|
]
|
||||||
|
|
||||||
def received_item(self, _con, stanza):
|
def received_item(self, _con, stanza, _properties):
|
||||||
# stanza can be a message or a iq
|
# stanza can be a message or a iq
|
||||||
|
|
||||||
log.info('Received roster items from %s', stanza.getFrom())
|
self._log.info('Received roster items from %s', stanza.getFrom())
|
||||||
|
|
||||||
exchange_items_list = {}
|
exchange_items_list = {}
|
||||||
items_list = stanza.getTag(
|
items_list = stanza.getTag(
|
||||||
|
@ -55,8 +57,8 @@ class RosterItemExchange:
|
||||||
try:
|
try:
|
||||||
jid = helpers.parse_jid(item.getAttr('jid'))
|
jid = helpers.parse_jid(item.getAttr('jid'))
|
||||||
except helpers.InvalidFormat:
|
except helpers.InvalidFormat:
|
||||||
log.warning('Invalid JID: %s, ignoring it',
|
self._log.warning('Invalid JID: %s, ignoring it',
|
||||||
item.getAttr('jid'))
|
item.getAttr('jid'))
|
||||||
continue
|
continue
|
||||||
name = item.getAttr('name')
|
name = item.getAttr('name')
|
||||||
contact = app.contacts.get_contact(self._account, jid)
|
contact = app.contacts.get_contact(self._account, jid)
|
||||||
|
@ -81,7 +83,7 @@ class RosterItemExchange:
|
||||||
if not exchange_items_list:
|
if not exchange_items_list:
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
log.info('Items: %s', exchange_items_list)
|
self._log.info('Items: %s', exchange_items_list)
|
||||||
|
|
||||||
app.nec.push_incoming_event(RosterItemExchangeEvent(
|
app.nec.push_incoming_event(RosterItemExchangeEvent(
|
||||||
None, conn=self._con,
|
None, conn=self._con,
|
||||||
|
@ -115,7 +117,7 @@ class RosterItemExchange:
|
||||||
xdata.addChild(name='item', attrs={'action': 'add',
|
xdata.addChild(name='item', attrs={'action': 'add',
|
||||||
'jid': contact.jid,
|
'jid': contact.jid,
|
||||||
'name': name})
|
'name': name})
|
||||||
log.info('Send contact: %s %s', contact.jid, name)
|
self._log.info('Send contact: %s %s', contact.jid, name)
|
||||||
self._con.connection.send(stanza)
|
self._con.connection.send(stanza)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,25 +14,19 @@
|
||||||
|
|
||||||
# XEP-0055: Jabber Search
|
# XEP-0055: Jabber Search
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.search')
|
|
||||||
|
|
||||||
|
|
||||||
class Search:
|
class Search(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
def request_search_fields(self, jid):
|
def request_search_fields(self, jid):
|
||||||
log.info('Request search fields from %s', jid)
|
self._log.info('Request search fields from %s', jid)
|
||||||
iq = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_SEARCH)
|
iq = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_SEARCH)
|
||||||
self._con.connection.SendAndCallForResponse(iq, self._fields_received)
|
self._con.connection.SendAndCallForResponse(iq, self._fields_received)
|
||||||
|
|
||||||
|
@ -41,10 +35,10 @@ class Search:
|
||||||
is_dataform = False
|
is_dataform = False
|
||||||
|
|
||||||
if nbxmpp.isResultNode(stanza):
|
if nbxmpp.isResultNode(stanza):
|
||||||
log.info('Received search fields from %s', stanza.getFrom())
|
self._log.info('Received search fields from %s', stanza.getFrom())
|
||||||
tag = stanza.getTag('query', namespace=nbxmpp.NS_SEARCH)
|
tag = stanza.getTag('query', namespace=nbxmpp.NS_SEARCH)
|
||||||
if tag is None:
|
if tag is None:
|
||||||
log.info('Invalid stanza: %s', stanza)
|
self._log.info('Invalid stanza: %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
data = tag.getTag('x', namespace=nbxmpp.NS_DATA)
|
data = tag.getTag('x', namespace=nbxmpp.NS_DATA)
|
||||||
|
@ -55,7 +49,7 @@ class Search:
|
||||||
for i in stanza.getQueryPayload():
|
for i in stanza.getQueryPayload():
|
||||||
data[i.getName()] = i.getData()
|
data[i.getName()] = i.getData()
|
||||||
else:
|
else:
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
SearchFormReceivedEvent(None, conn=self._con,
|
SearchFormReceivedEvent(None, conn=self._con,
|
||||||
|
@ -78,10 +72,10 @@ class Search:
|
||||||
is_dataform = False
|
is_dataform = False
|
||||||
|
|
||||||
if nbxmpp.isResultNode(stanza):
|
if nbxmpp.isResultNode(stanza):
|
||||||
log.info('Received result from %s', stanza.getFrom())
|
self._log.info('Received result from %s', stanza.getFrom())
|
||||||
tag = stanza.getTag('query', namespace=nbxmpp.NS_SEARCH)
|
tag = stanza.getTag('query', namespace=nbxmpp.NS_SEARCH)
|
||||||
if tag is None:
|
if tag is None:
|
||||||
log.info('Invalid stanza: %s', stanza)
|
self._log.info('Invalid stanza: %s', stanza)
|
||||||
return
|
return
|
||||||
|
|
||||||
data = tag.getTag('x', namespace=nbxmpp.NS_DATA)
|
data = tag.getTag('x', namespace=nbxmpp.NS_DATA)
|
||||||
|
@ -96,7 +90,7 @@ class Search:
|
||||||
field[i.getName()] = i.getData()
|
field[i.getName()] = i.getData()
|
||||||
data.append(field)
|
data.append(field)
|
||||||
else:
|
else:
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
SearchResultReceivedEvent(None, conn=self._con,
|
SearchResultReceivedEvent(None, conn=self._con,
|
||||||
|
|
|
@ -14,22 +14,16 @@
|
||||||
|
|
||||||
# XEP-0258: Security Labels in XMPP
|
# XEP-0258: Security Labels in XMPP
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.security_labels')
|
|
||||||
|
|
||||||
|
|
||||||
class SecLabels:
|
class SecLabels(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
self._catalogs = {}
|
self._catalogs = {}
|
||||||
self.supported = False
|
self.supported = False
|
||||||
|
@ -39,7 +33,7 @@ class SecLabels:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.supported = True
|
self.supported = True
|
||||||
log.info('Discovered security labels: %s', from_)
|
self._log.info('Discovered security labels: %s', from_)
|
||||||
|
|
||||||
def request_catalog(self, jid):
|
def request_catalog(self, jid):
|
||||||
server = app.get_jid_from_account(self._account).split("@")[1]
|
server = app.get_jid_from_account(self._account).split("@")[1]
|
||||||
|
@ -47,13 +41,13 @@ class SecLabels:
|
||||||
iq.addChild(name='catalog',
|
iq.addChild(name='catalog',
|
||||||
namespace=nbxmpp.NS_SECLABEL_CATALOG,
|
namespace=nbxmpp.NS_SECLABEL_CATALOG,
|
||||||
attrs={'to': jid})
|
attrs={'to': jid})
|
||||||
log.info('Request catalog: server: %s, to: %s', server, jid)
|
self._log.info('Request catalog: server: %s, to: %s', server, jid)
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._catalog_received)
|
iq, self._catalog_received)
|
||||||
|
|
||||||
def _catalog_received(self, stanza):
|
def _catalog_received(self, stanza):
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
return
|
return
|
||||||
|
|
||||||
query = stanza.getTag('catalog', namespace=nbxmpp.NS_SECLABEL_CATALOG)
|
query = stanza.getTag('catalog', namespace=nbxmpp.NS_SECLABEL_CATALOG)
|
||||||
|
@ -73,8 +67,8 @@ class SecLabels:
|
||||||
catalog = (labels, label_list, default)
|
catalog = (labels, label_list, default)
|
||||||
self._catalogs[to] = catalog
|
self._catalogs[to] = catalog
|
||||||
|
|
||||||
log.info('Received catalog: %s', to)
|
self._log.info('Received catalog: %s', to)
|
||||||
log.debug(catalog)
|
self._log.debug(catalog)
|
||||||
|
|
||||||
app.nec.push_incoming_event(SecLabelCatalog(
|
app.nec.push_incoming_event(SecLabelCatalog(
|
||||||
None, account=self._account, jid=to, catalog=catalog))
|
None, account=self._account, jid=to, catalog=catalog))
|
||||||
|
|
|
@ -14,24 +14,24 @@
|
||||||
|
|
||||||
# XEP-0092: Software Version
|
# XEP-0092: Software Version
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
from nbxmpp.structs import StanzaHandler
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.helpers import get_os_info
|
from gajim.common.helpers import get_os_info
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.software_version')
|
|
||||||
|
|
||||||
|
|
||||||
class SoftwareVersion:
|
class SoftwareVersion(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
('iq', self._answer_request, 'get', nbxmpp.NS_VERSION),
|
StanzaHandler(name='iq',
|
||||||
|
callback=self._answer_request,
|
||||||
|
typ='get',
|
||||||
|
ns=nbxmpp.NS_VERSION),
|
||||||
]
|
]
|
||||||
|
|
||||||
def request_os_info(self, jid, resource):
|
def request_os_info(self, jid, resource):
|
||||||
|
@ -45,23 +45,23 @@ class SoftwareVersion:
|
||||||
jid += '/' + resource
|
jid += '/' + resource
|
||||||
iq = nbxmpp.Iq(to=jid, typ='get', queryNS=nbxmpp.NS_VERSION)
|
iq = nbxmpp.Iq(to=jid, typ='get', queryNS=nbxmpp.NS_VERSION)
|
||||||
|
|
||||||
log.info('Requested: %s', jid)
|
self._log.info('Requested: %s', jid)
|
||||||
|
|
||||||
self._con.connection.SendAndCallForResponse(iq, self._result_received)
|
self._con.connection.SendAndCallForResponse(iq, self._result_received)
|
||||||
|
|
||||||
def _result_received(self, stanza):
|
def _result_received(self, stanza):
|
||||||
client_info, os_info = None, None
|
client_info, os_info = None, None
|
||||||
if not nbxmpp.isResultNode(stanza):
|
if not nbxmpp.isResultNode(stanza):
|
||||||
log.info('Error: %s', stanza.getError())
|
self._log.info('Error: %s', stanza.getError())
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
client_info, os_info = self._extract_info(stanza)
|
client_info, os_info = self._extract_info(stanza)
|
||||||
except Exception:
|
except Exception:
|
||||||
log.exception('Error')
|
self._log.exception('Error')
|
||||||
log.error(stanza)
|
self._log.error(stanza)
|
||||||
|
|
||||||
log.info('Received: %s %s %s',
|
self._log.info('Received: %s %s %s',
|
||||||
stanza.getFrom(), client_info, os_info)
|
stanza.getFrom(), client_info, os_info)
|
||||||
|
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
VersionResultReceivedEvent(None, conn=self._con,
|
VersionResultReceivedEvent(None, conn=self._con,
|
||||||
|
@ -80,8 +80,8 @@ class SoftwareVersion:
|
||||||
os_info = os_info.getData()
|
os_info = os_info.getData()
|
||||||
return client_info, os_info
|
return client_info, os_info
|
||||||
|
|
||||||
def _answer_request(self, _con, stanza):
|
def _answer_request(self, _con, stanza, _properties):
|
||||||
log.info('%s asked for the software version', stanza.getFrom())
|
self._log.info('%s asked for the software version', stanza.getFrom())
|
||||||
if app.config.get_per('accounts', self._account, 'send_os_info'):
|
if app.config.get_per('accounts', self._account, 'send_os_info'):
|
||||||
os_info = get_os_info()
|
os_info = get_os_info()
|
||||||
iq = stanza.buildReply('result')
|
iq = stanza.buildReply('result')
|
||||||
|
@ -89,12 +89,12 @@ class SoftwareVersion:
|
||||||
query.setTagData('name', 'Gajim')
|
query.setTagData('name', 'Gajim')
|
||||||
query.setTagData('version', app.version)
|
query.setTagData('version', app.version)
|
||||||
query.setTagData('os', os_info)
|
query.setTagData('os', os_info)
|
||||||
log.info('Answer: Gajim %s %s', app.version, os_info)
|
self._log.info('Answer: Gajim %s %s', app.version, os_info)
|
||||||
else:
|
else:
|
||||||
iq = stanza.buildReply('error')
|
iq = stanza.buildReply('error')
|
||||||
err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
|
err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
|
||||||
iq.addChild(node=err)
|
iq.addChild(node=err)
|
||||||
log.info('Send service-unavailable')
|
self._log.info('Send service-unavailable')
|
||||||
self._con.connection.send(iq)
|
self._con.connection.send(iq)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
@ -28,8 +26,6 @@ from gajim.common.modules.util import event_node
|
||||||
from gajim.common.modules.util import store_publish
|
from gajim.common.modules.util import store_publish
|
||||||
from gajim.common.const import PEPEventType
|
from gajim.common.const import PEPEventType
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.user_activity')
|
|
||||||
|
|
||||||
|
|
||||||
class UserActivity(BaseModule):
|
class UserActivity(BaseModule):
|
||||||
|
|
||||||
|
@ -69,7 +65,7 @@ class UserActivity(BaseModule):
|
||||||
|
|
||||||
@store_publish
|
@store_publish
|
||||||
def set_activity(self, activity):
|
def set_activity(self, activity):
|
||||||
log.info('Send %s', activity)
|
self._log.info('Send %s', activity)
|
||||||
self._nbxmpp('Activity').set_activity(activity)
|
self._nbxmpp('Activity').set_activity(activity)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
# XEP-0084: User Avatar
|
# XEP-0084: User Avatar
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
from nbxmpp.util import is_error_result
|
from nbxmpp.util import is_error_result
|
||||||
|
|
||||||
|
@ -23,8 +21,6 @@ from gajim.common import app
|
||||||
from gajim.common.modules.base import BaseModule
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.modules.util import event_node
|
from gajim.common.modules.util import event_node
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.user_avatar')
|
|
||||||
|
|
||||||
|
|
||||||
class UserAvatar(BaseModule):
|
class UserAvatar(BaseModule):
|
||||||
|
|
||||||
|
@ -46,7 +42,7 @@ class UserAvatar(BaseModule):
|
||||||
|
|
||||||
if empty:
|
if empty:
|
||||||
# Remove avatar
|
# Remove avatar
|
||||||
log.info('Remove: %s', jid)
|
self._log.info('Remove: %s', jid)
|
||||||
app.contacts.set_avatar(self._account, jid, None)
|
app.contacts.set_avatar(self._account, jid, None)
|
||||||
app.logger.set_avatar_sha(own_jid, jid, None)
|
app.logger.set_avatar_sha(own_jid, jid, None)
|
||||||
app.interface.update_avatar(self._account, jid)
|
app.interface.update_avatar(self._account, jid)
|
||||||
|
@ -58,19 +54,19 @@ class UserAvatar(BaseModule):
|
||||||
sha = app.contacts.get_avatar_sha(self._account, jid)
|
sha = app.contacts.get_avatar_sha(self._account, jid)
|
||||||
|
|
||||||
if sha == data.id:
|
if sha == data.id:
|
||||||
log.info('Avatar already known: %s %s', jid, data.id)
|
self._log.info('Avatar already known: %s %s', jid, data.id)
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Request: %s %s', jid, data.id)
|
self._log.info('Request: %s %s', jid, data.id)
|
||||||
self._nbxmpp('UserAvatar').request_avatar(
|
self._nbxmpp('UserAvatar').request_avatar(
|
||||||
jid, data.id, callback=self._avatar_received)
|
jid, data.id, callback=self._avatar_received)
|
||||||
|
|
||||||
def _avatar_received(self, result):
|
def _avatar_received(self, result):
|
||||||
if is_error_result(result):
|
if is_error_result(result):
|
||||||
log.info('Error: %s', result)
|
self._log.info('Error: %s', result)
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Received Avatar: %s %s', result.jid, result.sha)
|
self._log.info('Received Avatar: %s %s', result.jid, result.sha)
|
||||||
app.interface.save_avatar(result.data)
|
app.interface.save_avatar(result.data)
|
||||||
|
|
||||||
if self._con.get_own_jid().bareMatch(result.jid):
|
if self._con.get_own_jid().bareMatch(result.jid):
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
# XEP-0080: User Location
|
# XEP-0080: User Location
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
@ -25,8 +23,6 @@ from gajim.common.modules.util import event_node
|
||||||
from gajim.common.modules.util import store_publish
|
from gajim.common.modules.util import store_publish
|
||||||
from gajim.common.const import PEPEventType
|
from gajim.common.const import PEPEventType
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.user_location')
|
|
||||||
|
|
||||||
|
|
||||||
class UserLocation(BaseModule):
|
class UserLocation(BaseModule):
|
||||||
|
|
||||||
|
@ -66,7 +62,7 @@ class UserLocation(BaseModule):
|
||||||
|
|
||||||
@store_publish
|
@store_publish
|
||||||
def set_location(self, location):
|
def set_location(self, location):
|
||||||
log.info('Send %s', location)
|
self._log.info('Send %s', location)
|
||||||
self._nbxmpp('Location').set_location(location)
|
self._nbxmpp('Location').set_location(location)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
@ -28,8 +26,6 @@ from gajim.common.modules.util import event_node
|
||||||
from gajim.common.modules.util import store_publish
|
from gajim.common.modules.util import store_publish
|
||||||
from gajim.common.const import PEPEventType
|
from gajim.common.const import PEPEventType
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.user_mood')
|
|
||||||
|
|
||||||
|
|
||||||
class UserMood(BaseModule):
|
class UserMood(BaseModule):
|
||||||
|
|
||||||
|
@ -69,7 +65,7 @@ class UserMood(BaseModule):
|
||||||
|
|
||||||
@store_publish
|
@store_publish
|
||||||
def set_mood(self, mood):
|
def set_mood(self, mood):
|
||||||
log.info('Send %s', mood)
|
self._log.info('Send %s', mood)
|
||||||
self._nbxmpp('Mood').set_mood(mood)
|
self._nbxmpp('Mood').set_mood(mood)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
@ -26,8 +24,6 @@ from gajim.common.nec import NetworkEvent
|
||||||
from gajim.common.modules.base import BaseModule
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.modules.util import event_node
|
from gajim.common.modules.util import event_node
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.user_nickname')
|
|
||||||
|
|
||||||
|
|
||||||
class UserNickname(BaseModule):
|
class UserNickname(BaseModule):
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
@ -28,8 +26,6 @@ from gajim.common.modules.util import event_node
|
||||||
from gajim.common.modules.util import store_publish
|
from gajim.common.modules.util import store_publish
|
||||||
from gajim.common.const import PEPEventType
|
from gajim.common.const import PEPEventType
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.user_tune')
|
|
||||||
|
|
||||||
|
|
||||||
class UserTune(BaseModule):
|
class UserTune(BaseModule):
|
||||||
|
|
||||||
|
@ -69,7 +65,7 @@ class UserTune(BaseModule):
|
||||||
|
|
||||||
@store_publish
|
@store_publish
|
||||||
def set_tune(self, tune):
|
def set_tune(self, tune):
|
||||||
log.info('Send %s', tune)
|
self._log.info('Send %s', tune)
|
||||||
self._nbxmpp('Tune').set_tune(tune)
|
self._nbxmpp('Tune').set_tune(tune)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
# XEP-0153: vCard-Based Avatars
|
# XEP-0153: vCard-Based Avatars
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import logging
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
@ -26,14 +25,12 @@ from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
from gajim.common import configpaths
|
from gajim.common import configpaths
|
||||||
from gajim.common.const import RequestAvatar
|
from gajim.common.const import RequestAvatar
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
log = logging.getLogger('gajim.c.m.vcard.avatars')
|
|
||||||
|
|
||||||
|
|
||||||
class VCardAvatars:
|
class VCardAvatars(BaseModule):
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
self._requested_shas = []
|
self._requested_shas = []
|
||||||
|
|
||||||
self.handlers = [
|
self.handlers = [
|
||||||
|
@ -52,7 +49,7 @@ class VCardAvatars:
|
||||||
return
|
return
|
||||||
path = Path(configpaths.get('AVATAR')) / sha
|
path = Path(configpaths.get('AVATAR')) / sha
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
log.info('Missing own avatar, reset sha')
|
self._log.info('Missing own avatar, reset sha')
|
||||||
app.config.set_per('accounts', self._account, 'avatar_sha', '')
|
app.config.set_per('accounts', self._account, 'avatar_sha', '')
|
||||||
|
|
||||||
def _presence_received(self, _con, _stanza, properties):
|
def _presence_received(self, _con, _stanza, properties):
|
||||||
|
@ -87,13 +84,13 @@ class VCardAvatars:
|
||||||
jid = properties.jid.getBare()
|
jid = properties.jid.getBare()
|
||||||
if properties.avatar_state == AvatarState.EMPTY:
|
if properties.avatar_state == AvatarState.EMPTY:
|
||||||
# Empty <photo/> tag, means no avatar is advertised
|
# Empty <photo/> tag, means no avatar is advertised
|
||||||
log.info('%s has no avatar published', properties.jid)
|
self._log.info('%s has no avatar published', properties.jid)
|
||||||
app.config.set_per('accounts', self._account, 'avatar_sha', '')
|
app.config.set_per('accounts', self._account, 'avatar_sha', '')
|
||||||
app.contacts.set_avatar(self._account, jid, None)
|
app.contacts.set_avatar(self._account, jid, None)
|
||||||
app.interface.update_avatar(self._account, jid)
|
app.interface.update_avatar(self._account, jid)
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('Update: %s %s', jid, properties.avatar_sha)
|
self._log.info('Update: %s %s', jid, properties.avatar_sha)
|
||||||
current_sha = app.config.get_per(
|
current_sha = app.config.get_per(
|
||||||
'accounts', self._account, 'avatar_sha')
|
'accounts', self._account, 'avatar_sha')
|
||||||
|
|
||||||
|
@ -107,21 +104,21 @@ class VCardAvatars:
|
||||||
properties.avatar_sha)
|
properties.avatar_sha)
|
||||||
app.interface.update_avatar(self._account, jid)
|
app.interface.update_avatar(self._account, jid)
|
||||||
else:
|
else:
|
||||||
log.info('Request : %s', jid)
|
self._log.info('Request : %s', jid)
|
||||||
self._con.get_module('VCardTemp').request_vcard(
|
self._con.get_module('VCardTemp').request_vcard(
|
||||||
RequestAvatar.SELF)
|
RequestAvatar.SELF)
|
||||||
else:
|
else:
|
||||||
log.info('Avatar already known: %s %s',
|
self._log.info('Avatar already known: %s %s',
|
||||||
jid, properties.avatar_sha)
|
jid, properties.avatar_sha)
|
||||||
|
|
||||||
def _update_received(self, properties, room=False):
|
def _update_received(self, properties, room=False):
|
||||||
jid = properties.jid.getBare()
|
jid = properties.jid.getBare()
|
||||||
if properties.avatar_state == AvatarState.EMPTY:
|
if properties.avatar_state == AvatarState.EMPTY:
|
||||||
# Empty <photo/> tag, means no avatar is advertised
|
# Empty <photo/> tag, means no avatar is advertised
|
||||||
log.info('%s has no avatar published', properties.jid)
|
self._log.info('%s has no avatar published', properties.jid)
|
||||||
|
|
||||||
# Remove avatar
|
# Remove avatar
|
||||||
log.debug('Remove: %s', jid)
|
self._log.debug('Remove: %s', jid)
|
||||||
app.contacts.set_avatar(self._account, jid, None)
|
app.contacts.set_avatar(self._account, jid, None)
|
||||||
acc_jid = self._con.get_own_jid().getStripped()
|
acc_jid = self._con.get_own_jid().getStripped()
|
||||||
if not room:
|
if not room:
|
||||||
|
@ -129,12 +126,13 @@ class VCardAvatars:
|
||||||
app.interface.update_avatar(
|
app.interface.update_avatar(
|
||||||
self._account, jid, room_avatar=room)
|
self._account, jid, room_avatar=room)
|
||||||
else:
|
else:
|
||||||
log.info('Update: %s %s', properties.jid, properties.avatar_sha)
|
self._log.info('Update: %s %s',
|
||||||
|
properties.jid, properties.avatar_sha)
|
||||||
current_sha = app.contacts.get_avatar_sha(self._account, jid)
|
current_sha = app.contacts.get_avatar_sha(self._account, jid)
|
||||||
|
|
||||||
if properties.avatar_sha == current_sha:
|
if properties.avatar_sha == current_sha:
|
||||||
log.info('Avatar already known: %s %s',
|
self._log.info('Avatar already known: %s %s',
|
||||||
jid, properties.avatar_sha)
|
jid, properties.avatar_sha)
|
||||||
return
|
return
|
||||||
|
|
||||||
if room:
|
if room:
|
||||||
|
@ -164,17 +162,17 @@ class VCardAvatars:
|
||||||
self._account, properties.jid.getBare(), nick)
|
self._account, properties.jid.getBare(), nick)
|
||||||
|
|
||||||
if gc_contact is None:
|
if gc_contact is None:
|
||||||
log.error('no gc contact found: %s', nick)
|
self._log.error('no gc contact found: %s', nick)
|
||||||
return
|
return
|
||||||
|
|
||||||
if properties.avatar_state == AvatarState.EMPTY:
|
if properties.avatar_state == AvatarState.EMPTY:
|
||||||
# Empty <photo/> tag, means no avatar is advertised, remove avatar
|
# Empty <photo/> tag, means no avatar is advertised, remove avatar
|
||||||
log.info('%s has no avatar published', nick)
|
self._log.info('%s has no avatar published', nick)
|
||||||
log.debug('Remove: %s', nick)
|
self._log.debug('Remove: %s', nick)
|
||||||
gc_contact.avatar_sha = None
|
gc_contact.avatar_sha = None
|
||||||
app.interface.update_avatar(contact=gc_contact)
|
app.interface.update_avatar(contact=gc_contact)
|
||||||
else:
|
else:
|
||||||
log.info('Update: %s %s', nick, properties.avatar_sha)
|
self._log.info('Update: %s %s', nick, properties.avatar_sha)
|
||||||
path = os.path.join(configpaths.get('AVATAR'),
|
path = os.path.join(configpaths.get('AVATAR'),
|
||||||
properties.avatar_sha)
|
properties.avatar_sha)
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
|
@ -187,12 +185,12 @@ class VCardAvatars:
|
||||||
return
|
return
|
||||||
|
|
||||||
if gc_contact.avatar_sha != properties.avatar_sha:
|
if gc_contact.avatar_sha != properties.avatar_sha:
|
||||||
log.info('%s changed their Avatar: %s',
|
self._log.info('%s changed their Avatar: %s',
|
||||||
nick, properties.avatar_sha)
|
nick, properties.avatar_sha)
|
||||||
gc_contact.avatar_sha = properties.avatar_sha
|
gc_contact.avatar_sha = properties.avatar_sha
|
||||||
app.interface.update_avatar(contact=gc_contact)
|
app.interface.update_avatar(contact=gc_contact)
|
||||||
else:
|
else:
|
||||||
log.info('Avatar already known: %s', nick)
|
self._log.info('Avatar already known: %s', nick)
|
||||||
|
|
||||||
def send_avatar_presence(self, force=False, after_publish=False):
|
def send_avatar_presence(self, force=False, after_publish=False):
|
||||||
if self._con.avatar_conversion:
|
if self._con.avatar_conversion:
|
||||||
|
@ -202,7 +200,7 @@ class VCardAvatars:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
if self.avatar_advertised and not force:
|
if self.avatar_advertised and not force:
|
||||||
log.debug('Avatar already advertised')
|
self._log.debug('Avatar already advertised')
|
||||||
return
|
return
|
||||||
|
|
||||||
show = helpers.get_xmpp_show(app.SHOW_LIST[self._con.connected])
|
show = helpers.get_xmpp_show(app.SHOW_LIST[self._con.connected])
|
||||||
|
@ -219,8 +217,8 @@ class VCardAvatars:
|
||||||
if self._con.get_module('VCardTemp').own_vcard_received:
|
if self._con.get_module('VCardTemp').own_vcard_received:
|
||||||
sha = app.config.get_per('accounts', self._account, 'avatar_sha')
|
sha = app.config.get_per('accounts', self._account, 'avatar_sha')
|
||||||
own_jid = self._con.get_own_jid()
|
own_jid = self._con.get_own_jid()
|
||||||
log.info('Send avatar presence to: %s %s',
|
self._log.info('Send avatar presence to: %s %s',
|
||||||
node.getTo() or own_jid, sha or 'no sha advertised')
|
node.getTo() or own_jid, sha or 'no sha advertised')
|
||||||
update.setTagData('photo', sha)
|
update.setTagData('photo', sha)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
import binascii
|
import binascii
|
||||||
import base64
|
import base64
|
||||||
import logging
|
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
|
@ -25,17 +24,13 @@ from gajim.common import app
|
||||||
from gajim.common.const import RequestAvatar
|
from gajim.common.const import RequestAvatar
|
||||||
from gajim.common.nec import NetworkEvent
|
from gajim.common.nec import NetworkEvent
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
|
from gajim.common.modules.base import BaseModule
|
||||||
from gajim.common.connection_handlers_events import InformationEvent
|
from gajim.common.connection_handlers_events import InformationEvent
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.m.vcard')
|
|
||||||
|
|
||||||
|
class VCardTemp(BaseModule):
|
||||||
class VCardTemp:
|
|
||||||
def __init__(self, con):
|
def __init__(self, con):
|
||||||
self._con = con
|
BaseModule.__init__(self, con)
|
||||||
self._account = con.name
|
|
||||||
|
|
||||||
self.handlers = []
|
|
||||||
|
|
||||||
self._own_vcard = None
|
self._own_vcard = None
|
||||||
self.own_vcard_received = False
|
self.own_vcard_received = False
|
||||||
|
@ -47,7 +42,7 @@ class VCardTemp:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.supported = True
|
self.supported = True
|
||||||
log.info('Discovered vcard-temp: %s', from_)
|
self._log.info('Discovered vcard-temp: %s', from_)
|
||||||
|
|
||||||
app.nec.push_incoming_event(NetworkEvent('feature-discovered',
|
app.nec.push_incoming_event(NetworkEvent('feature-discovered',
|
||||||
account=self._account,
|
account=self._account,
|
||||||
|
@ -98,7 +93,7 @@ class VCardTemp:
|
||||||
iq.setQuery('vCard').setNamespace(nbxmpp.NS_VCARD)
|
iq.setQuery('vCard').setNamespace(nbxmpp.NS_VCARD)
|
||||||
|
|
||||||
own_jid = self._con.get_own_jid().getStripped()
|
own_jid = self._con.get_own_jid().getStripped()
|
||||||
log.info('Request: %s, expected sha: %s', jid or own_jid, sha)
|
self._log.info('Request: %s, expected sha: %s', jid or own_jid, sha)
|
||||||
|
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._parse_vcard, {'callback': callback, 'expected_sha': sha})
|
iq, self._parse_vcard, {'callback': callback, 'expected_sha': sha})
|
||||||
|
@ -124,7 +119,7 @@ class VCardTemp:
|
||||||
else:
|
else:
|
||||||
iq2.addChild(i).setData(vcard[i])
|
iq2.addChild(i).setData(vcard[i])
|
||||||
|
|
||||||
log.info('Upload avatar: %s %s', self._account, sha)
|
self._log.info('Upload avatar: %s %s', self._account, sha)
|
||||||
|
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._avatar_publish_result, {'sha': sha})
|
iq, self._avatar_publish_result, {'sha': sha})
|
||||||
|
@ -136,7 +131,7 @@ class VCardTemp:
|
||||||
photo.addChild('TYPE', payload='image/png')
|
photo.addChild('TYPE', payload='image/png')
|
||||||
photo.addChild('BINVAL', payload=data)
|
photo.addChild('BINVAL', payload=data)
|
||||||
|
|
||||||
log.info('Upload avatar: %s', room_jid)
|
self._log.info('Upload avatar: %s', room_jid)
|
||||||
self._con.connection.SendAndCallForResponse(
|
self._con.connection.SendAndCallForResponse(
|
||||||
iq, self._upload_room_avatar_result)
|
iq, self._upload_room_avatar_result)
|
||||||
|
|
||||||
|
@ -162,7 +157,7 @@ class VCardTemp:
|
||||||
self._account, self._con.get_own_jid().getStripped())
|
self._account, self._con.get_own_jid().getStripped())
|
||||||
self._con.get_module('VCardAvatars').send_avatar_presence(
|
self._con.get_module('VCardAvatars').send_avatar_presence(
|
||||||
after_publish=True)
|
after_publish=True)
|
||||||
log.info('%s: Published: %s', self._account, sha)
|
self._log.info('%s: Published: %s', self._account, sha)
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
VcardPublishedEvent(None, conn=self._con))
|
VcardPublishedEvent(None, conn=self._con))
|
||||||
|
|
||||||
|
@ -170,8 +165,7 @@ class VCardTemp:
|
||||||
app.nec.push_incoming_event(
|
app.nec.push_incoming_event(
|
||||||
VcardNotPublishedEvent(None, conn=self._con))
|
VcardNotPublishedEvent(None, conn=self._con))
|
||||||
|
|
||||||
@staticmethod
|
def _get_vcard_photo(self, vcard, jid):
|
||||||
def _get_vcard_photo(vcard, jid):
|
|
||||||
try:
|
try:
|
||||||
photo = vcard['PHOTO']['BINVAL']
|
photo = vcard['PHOTO']['BINVAL']
|
||||||
except (KeyError, AttributeError, TypeError):
|
except (KeyError, AttributeError, TypeError):
|
||||||
|
@ -185,7 +179,7 @@ class VCardTemp:
|
||||||
try:
|
try:
|
||||||
photo_decoded = base64.b64decode(photo.encode('utf-8'))
|
photo_decoded = base64.b64decode(photo.encode('utf-8'))
|
||||||
except binascii.Error as error:
|
except binascii.Error as error:
|
||||||
log.warning('Invalid avatar for %s: %s', jid, error)
|
self._log.warning('Invalid avatar for %s: %s', jid, error)
|
||||||
return None, None
|
return None, None
|
||||||
avatar_sha = hashlib.sha1(photo_decoded).hexdigest()
|
avatar_sha = hashlib.sha1(photo_decoded).hexdigest()
|
||||||
|
|
||||||
|
@ -205,14 +199,14 @@ class VCardTemp:
|
||||||
stanza_error = stanza.getError()
|
stanza_error = stanza.getError()
|
||||||
if stanza_error in ('service-unavailable', 'item-not-found',
|
if stanza_error in ('service-unavailable', 'item-not-found',
|
||||||
'not-allowed'):
|
'not-allowed'):
|
||||||
log.info('vCard not available: %s %s', frm_jid, stanza_error)
|
self._log.info('vCard not available: %s %s', frm_jid, stanza_error)
|
||||||
callback(jid, resource, room, {}, expected_sha)
|
callback(jid, resource, room, {}, expected_sha)
|
||||||
return
|
return
|
||||||
|
|
||||||
vcard_node = stanza.getTag('vCard', namespace=nbxmpp.NS_VCARD)
|
vcard_node = stanza.getTag('vCard', namespace=nbxmpp.NS_VCARD)
|
||||||
if vcard_node is None:
|
if vcard_node is None:
|
||||||
log.info('vCard not available: %s', frm_jid)
|
self._log.info('vCard not available: %s', frm_jid)
|
||||||
log.debug(stanza)
|
self._log.debug(stanza)
|
||||||
return
|
return
|
||||||
vcard = self._node_to_dict(vcard_node)
|
vcard = self._node_to_dict(vcard_node)
|
||||||
|
|
||||||
|
@ -232,14 +226,14 @@ class VCardTemp:
|
||||||
def _on_own_avatar_received(self, jid, _resource, _room, vcard, *args):
|
def _on_own_avatar_received(self, jid, _resource, _room, vcard, *args):
|
||||||
avatar_sha, photo_decoded = self._get_vcard_photo(vcard, jid)
|
avatar_sha, photo_decoded = self._get_vcard_photo(vcard, jid)
|
||||||
|
|
||||||
log.info('Received own vcard, avatar sha is: %s', avatar_sha)
|
self._log.info('Received own vcard, avatar sha is: %s', avatar_sha)
|
||||||
|
|
||||||
self._own_vcard = vcard
|
self._own_vcard = vcard
|
||||||
self.own_vcard_received = True
|
self.own_vcard_received = True
|
||||||
|
|
||||||
if avatar_sha is None:
|
if avatar_sha is None:
|
||||||
# No avatar found in vcard
|
# No avatar found in vcard
|
||||||
log.info('No avatar found')
|
self._log.info('No avatar found')
|
||||||
app.config.set_per('accounts', self._account, 'avatar_sha', '')
|
app.config.set_per('accounts', self._account, 'avatar_sha', '')
|
||||||
app.contacts.set_avatar(self._account, jid, avatar_sha)
|
app.contacts.set_avatar(self._account, jid, avatar_sha)
|
||||||
self._con.get_module('VCardAvatars').send_avatar_presence(
|
self._con.get_module('VCardAvatars').send_avatar_presence(
|
||||||
|
@ -265,12 +259,12 @@ class VCardTemp:
|
||||||
expected_sha):
|
expected_sha):
|
||||||
avatar_sha, photo_decoded = self._get_vcard_photo(vcard, jid)
|
avatar_sha, photo_decoded = self._get_vcard_photo(vcard, jid)
|
||||||
if expected_sha != avatar_sha:
|
if expected_sha != avatar_sha:
|
||||||
log.warning('Avatar mismatch: %s %s', jid, avatar_sha)
|
self._log.warning('Avatar mismatch: %s %s', jid, avatar_sha)
|
||||||
return
|
return
|
||||||
|
|
||||||
app.interface.save_avatar(photo_decoded)
|
app.interface.save_avatar(photo_decoded)
|
||||||
|
|
||||||
log.info('Received: %s %s', jid, avatar_sha)
|
self._log.info('Received: %s %s', jid, avatar_sha)
|
||||||
app.contacts.set_avatar(self._account, jid, avatar_sha)
|
app.contacts.set_avatar(self._account, jid, avatar_sha)
|
||||||
app.interface.update_avatar(self._account, jid, room_avatar=True)
|
app.interface.update_avatar(self._account, jid, room_avatar=True)
|
||||||
|
|
||||||
|
@ -281,21 +275,21 @@ class VCardTemp:
|
||||||
|
|
||||||
avatar_sha, photo_decoded = self._get_vcard_photo(vcard, request_jid)
|
avatar_sha, photo_decoded = self._get_vcard_photo(vcard, request_jid)
|
||||||
if expected_sha != avatar_sha:
|
if expected_sha != avatar_sha:
|
||||||
log.warning('Received: avatar mismatch: %s %s',
|
self._log.warning('Received: avatar mismatch: %s %s',
|
||||||
request_jid, avatar_sha)
|
request_jid, avatar_sha)
|
||||||
return
|
return
|
||||||
|
|
||||||
app.interface.save_avatar(photo_decoded)
|
app.interface.save_avatar(photo_decoded)
|
||||||
|
|
||||||
# Received vCard from a contact
|
# Received vCard from a contact
|
||||||
if room:
|
if room:
|
||||||
log.info('Received: %s %s', resource, avatar_sha)
|
self._log.info('Received: %s %s', resource, avatar_sha)
|
||||||
contact = app.contacts.get_gc_contact(self._account, jid, resource)
|
contact = app.contacts.get_gc_contact(self._account, jid, resource)
|
||||||
if contact is not None:
|
if contact is not None:
|
||||||
contact.avatar_sha = avatar_sha
|
contact.avatar_sha = avatar_sha
|
||||||
app.interface.update_avatar(contact=contact)
|
app.interface.update_avatar(contact=contact)
|
||||||
else:
|
else:
|
||||||
log.info('Received: %s %s', jid, avatar_sha)
|
self._log.info('Received: %s %s', jid, avatar_sha)
|
||||||
own_jid = self._con.get_own_jid().getStripped()
|
own_jid = self._con.get_own_jid().getStripped()
|
||||||
app.logger.set_avatar_sha(own_jid, jid, avatar_sha)
|
app.logger.set_avatar_sha(own_jid, jid, avatar_sha)
|
||||||
app.contacts.set_avatar(self._account, jid, avatar_sha)
|
app.contacts.set_avatar(self._account, jid, avatar_sha)
|
||||||
|
|
Loading…
Add table
Reference in a new issue