Commit a2d7283e authored by Philipp Hörist's avatar Philipp Hörist

Refactor AdHocCommands into own module

parent 78d16c44
......@@ -25,12 +25,12 @@
# FIXME: think if we need caching command list. it may be wrong if there will
# be entities that often change the list, it may be slow to fetch it every time
from gi.repository import GLib
from gi.repository import Gtk
import nbxmpp
from gajim.common import app
from gajim.common import dataforms
from gajim.common import ged
from gajim import gtkgui_helpers
from gajim import dialogs
......@@ -55,7 +55,7 @@ class CommandWindow:
"""
# an account object
self.account = app.connections[account]
self._con = app.connections[account]
self.jid = jid
self.commandnode = commandnode
self.data_form_widget = None
......@@ -87,6 +87,14 @@ class CommandWindow:
column = Gtk.TreeViewColumn("Command", renderer, text=0)
self.command_treeview.append_column(column)
app.ged.register_event_handler(
'adhoc-command-error', ged.CORE, self._on_command_error)
app.ged.register_event_handler(
'adhoc-command-list', ged.CORE, self._on_command_list)
app.ged.register_event_handler('adhoc-command-action-response',
ged.CORE,
self._on_action_response)
self.initiate()
def initiate(self):
......@@ -157,8 +165,13 @@ class CommandWindow:
return False
def on_adhoc_commands_window_destroy(self, *anything):
# TODO: do all actions that are needed to remove this object from memory
pass
app.ged.remove_event_handler(
'adhoc-command-error', ged.CORE, self._on_command_error)
app.ged.remove_event_handler(
'adhoc-command-list', ged.CORE, self._on_command_list)
app.ged.remove_event_handler('adhoc-command-action-response',
ged.CORE,
self._on_action_response)
def on_adhoc_commands_window_delete_event(self, *anything):
if self.stage_window_delete_cb:
......@@ -190,7 +203,7 @@ class CommandWindow:
self.finish_button.set_sensitive(False)
# request command list
self.request_command_list()
self._con.get_module('AdHocCommands').request_command_list(self.jid)
self.retrieving_commands_spinner.start()
# setup the callbacks
......@@ -304,7 +317,8 @@ class CommandWindow:
return
def on_yes(button):
self.send_cancel()
self._con.get_module('AdHocCommands').send_cancel(
self.jid, self.commandnode, self.sessionid)
dialog.destroy()
cb()
......@@ -371,7 +385,9 @@ class CommandWindow:
self.finish_button.set_sensitive(False)
self.sending_form_spinner.start()
self.send_command(action)
self._con.get_module('AdHocCommands').send_command(
self.jid, self.commandnode, self.sessionid,
self.data_form_widget.data_form, action)
def stage3_next_form(self, command):
if not isinstance(command, nbxmpp.Node):
......@@ -527,85 +543,15 @@ class CommandWindow:
def stage5_restart_button_clicked(self, widget):
self.restart()
# handling xml stanzas
def request_command_list(self):
"""
Request the command list. Change stage on delivery
"""
query = nbxmpp.Iq(typ='get', to=nbxmpp.JID(self.jid),
queryNS=nbxmpp.NS_DISCO_ITEMS)
query.setQuerynode(nbxmpp.NS_COMMANDS)
def callback(response):
'''Called on response to query.'''
# FIXME: move to connection_handlers.py
# is error => error stage
error = response.getError()
if error:
# extracting error description
self.stage5(errorid=error)
return
# no commands => no commands stage
# commands => command selection stage
query = response.getTag('query')
if query and query.getAttr('node') == nbxmpp.NS_COMMANDS:
items = query.getTags('item')
else:
items = []
if len(items)==0:
self.commandlist = []
self.stage4()
else:
self.commandlist = [(t.getAttr('node'), t.getAttr('name')) \
for t in items]
self.stage2()
self.account.connection.SendAndCallForResponse(query, callback)
def send_command(self, action='execute'):
"""
Send the command with data form. Wait for reply
"""
# create the stanza
assert action in ('execute', 'prev', 'next', 'complete')
stanza = nbxmpp.Iq(typ='set', to=self.jid)
cmdnode = stanza.addChild('command', namespace=nbxmpp.NS_COMMANDS,
attrs={'node':self.commandnode, 'action':action})
def _on_command_error(self, obj):
self.stage5(errorid=obj.error)
if self.sessionid:
cmdnode.setAttr('sessionid', self.sessionid)
if self.data_form_widget.data_form:
cmdnode.addChild(node=self.data_form_widget.data_form.get_purged())
def callback(response):
# FIXME: move to connection_handlers.py
err = response.getError()
if err:
self.stage5(errorid = err)
else:
self.stage3_next_form(response.getTag('command'))
self.account.connection.SendAndCallForResponse(stanza, callback)
def send_cancel(self):
"""
Send the command with action='cancel'
"""
assert self.commandnode
if self.sessionid and self.account.connection:
# we already have sessionid, so the service sent at least one reply.
stanza = nbxmpp.Iq(typ='set', to=self.jid)
stanza.addChild('command', namespace=nbxmpp.NS_COMMANDS, attrs={
'node':self.commandnode,
'sessionid':self.sessionid,
'action':'cancel'
})
self.account.connection.send(stanza)
def _on_command_list(self, obj):
self.commandlist = obj.commandlist
if not self.commandlist:
self.stage4()
else:
# we did not received any reply from service;
# FIXME: we should wait and then send cancel; for now we do nothing
pass
self.stage2()
def _on_action_response(self, obj):
self.stage3_next_form(obj.command)
......@@ -42,7 +42,6 @@ from gajim.common import helpers
from gajim.common import app
from gajim.common import jingle_xtls
from gajim.common.caps_cache import muc_caps_cache
from gajim.common.commands import ConnectionCommands
from gajim.common.protocol.caps import ConnectionCaps
from gajim.common.protocol.bytestream import ConnectionSocks5Bytestream
from gajim.common.protocol.bytestream import ConnectionIBBytestream
......@@ -218,7 +217,7 @@ class ConnectionDisco:
if not self.connection or self.connected < 2:
return
if self.commandItemsQuery(con, iq_obj):
if self.get_module('AdHocCommands').command_items_query(iq_obj):
raise nbxmpp.NodeProcessed
node = iq_obj.getTagAttr('query', 'node')
if node is None:
......@@ -226,7 +225,7 @@ class ConnectionDisco:
self.connection.send(result)
raise nbxmpp.NodeProcessed
if node == nbxmpp.NS_COMMANDS:
self.commandListQuery(con, iq_obj)
self.get_module('AdHocCommands').command_list_query(iq_obj)
raise nbxmpp.NodeProcessed
def _DiscoverInfoGetCB(self, con, iq_obj):
......@@ -235,7 +234,7 @@ class ConnectionDisco:
return
node = iq_obj.getQuerynode()
if self.commandInfoQuery(con, iq_obj):
if self.get_module('AdHocCommands').command_info_query(iq_obj):
raise nbxmpp.NodeProcessed
id_ = iq_obj.getAttr('id')
......@@ -743,14 +742,12 @@ class ConnectionHandlersBase:
return sess
class ConnectionHandlers(ConnectionArchive313,
ConnectionSocks5Bytestream, ConnectionDisco,
ConnectionCommands, ConnectionCaps,
ConnectionSocks5Bytestream, ConnectionDisco, ConnectionCaps,
ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
def __init__(self):
ConnectionArchive313.__init__(self)
ConnectionSocks5Bytestream.__init__(self)
ConnectionIBBytestream.__init__(self)
ConnectionCommands.__init__(self)
# Handle presences BEFORE caps
app.nec.register_incoming_event(PresenceReceivedEvent)
......@@ -1339,8 +1336,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
nbxmpp.NS_MUC_ADMIN)
con.RegisterHandler('iq', self._SecLabelCB, 'result',
nbxmpp.NS_SECLABEL_CATALOG)
con.RegisterHandler('iq', self._CommandExecuteCB, 'set',
nbxmpp.NS_COMMANDS)
con.RegisterHandler('iq', self._DiscoverInfoGetCB, 'get',
nbxmpp.NS_DISCO_INFO)
con.RegisterHandler('iq', self._DiscoverItemsGetCB, 'get',
......
......@@ -18,6 +18,8 @@ from pathlib import Path
log = logging.getLogger('gajim.c.m')
ZEROCONF_MODULES = ['adhoc_commands']
imported_modules = []
_modules = {}
......@@ -31,12 +33,26 @@ for file in Path(__file__).parent.iterdir():
if file.stem == 'pep':
# Register the PEP module first, because other modules
# depend on it
imported_modules.insert(0, module)
imported_modules.insert(0, (module, file.stem))
else:
imported_modules.append(module)
imported_modules.append((module, file.stem))
class ModuleMock:
def __init__(self, name):
self._name = name
# HTTPUpload
self.available = False
# Blocking
self.blocked = []
# Privacy Lists
self.blocked_contacts = []
self.blocked_groups = []
self.blocked_all = False
def __getattr__(self, key):
def _mock(self, *args, **kwargs):
return
......@@ -48,7 +64,11 @@ def register(con, *args, **kwargs):
return
_modules[con.name] = {}
for module in imported_modules:
instance, name = module.get_instance(con, *args, **kwargs)
mod, name = module
if con.name == 'Local':
if name not in ZEROCONF_MODULES:
continue
instance, name = mod.get_instance(con, *args, **kwargs)
_modules[con.name][name] = instance
......@@ -60,7 +80,7 @@ def get(account, name):
try:
return _modules[account][name]
except KeyError:
return ModuleMock()
return ModuleMock(name)
def get_handlers(con):
......
......@@ -26,7 +26,6 @@
import nbxmpp
from gajim.common import app
from gajim.common.commands import ConnectionCommands
from gajim.common.protocol.bytestream import ConnectionSocks5BytestreamZeroconf
from gajim.common.connection_handlers_events import ZeroconfMessageReceivedEvent
......@@ -49,13 +48,12 @@ class ConnectionVcard:
class ConnectionHandlersZeroconf(ConnectionVcard,
ConnectionSocks5BytestreamZeroconf, ConnectionCommands,
ConnectionSocks5BytestreamZeroconf,
connection_handlers.ConnectionHandlersBase,
connection_handlers.ConnectionJingle):
def __init__(self):
ConnectionVcard.__init__(self)
ConnectionSocks5BytestreamZeroconf.__init__(self)
ConnectionCommands.__init__(self)
connection_handlers.ConnectionJingle.__init__(self)
connection_handlers.ConnectionHandlersBase.__init__(self)
......@@ -82,13 +80,13 @@ connection_handlers.ConnectionJingle):
if not self.connection or self.connected < 2:
return
if self.commandItemsQuery(con, iq_obj):
if self.get_module('AdHocCommands').command_items_query(iq_obj):
raise nbxmpp.NodeProcessed
node = iq_obj.getTagAttr('query', 'node')
if node is None:
result = iq_obj.buildReply('result')
self.connection.send(result)
raise nbxmpp.NodeProcessed
if node==nbxmpp.NS_COMMANDS:
self.commandListQuery(con, iq_obj)
if node == nbxmpp.NS_COMMANDS:
self.get_module('AdHocCommands').command_list_query(iq_obj)
raise nbxmpp.NodeProcessed
......@@ -47,6 +47,7 @@ from gi.repository import GLib
from gajim.common.connection import CommonConnection
from gajim.common import app
from gajim.common import ged
from gajim.common import modules
from gajim.common.zeroconf import client_zeroconf
from gajim.common.zeroconf import zeroconf
from gajim.common.zeroconf.connection_handlers_zeroconf import *
......@@ -69,6 +70,9 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
CommonConnection.__init__(self, name)
self.is_zeroconf = True
# Register all modules
modules.register(self)
app.ged.register_event_handler('message-outgoing', ged.OUT_CORE,
self._nec_message_outgoing)
app.ged.register_event_handler('stanza-message-outgoing', ged.OUT_CORE,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment