Make Service Registration a Gtk.Assistant
- Move all xmpp Register methods into the register module
This commit is contained in:
		
							parent
							
								
									99ec800856
								
							
						
					
					
						commit
						043e764896
					
				
					 13 changed files with 287 additions and 230 deletions
				
			
		| 
						 | 
				
			
			@ -792,11 +792,6 @@ class Connection(CommonConnection, ConnectionHandlers):
 | 
			
		|||
                        None, dialog_name='invalid-answer',
 | 
			
		||||
                        kwargs={'name': data[0], 'error': data[3]}))
 | 
			
		||||
                    return
 | 
			
		||||
                is_form = data[2]
 | 
			
		||||
                conf = data[1]
 | 
			
		||||
                app.nec.push_incoming_event(RegisterAgentInfoReceivedEvent(
 | 
			
		||||
                    None, conn=self, agent=data[0], config=conf,
 | 
			
		||||
                    is_form=is_form))
 | 
			
		||||
 | 
			
		||||
    def _select_next_host(self, hosts):
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,61 +54,6 @@ log = logging.getLogger('gajim.c.connection_handlers')
 | 
			
		|||
# kind of events we can wait for an answer
 | 
			
		||||
AGENT_REMOVED = 'agent_removed'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ConnectionDisco:
 | 
			
		||||
 | 
			
		||||
    def request_register_agent_info(self, agent):
 | 
			
		||||
        if not self.connection or self.connected < 2:
 | 
			
		||||
            return None
 | 
			
		||||
        iq = nbxmpp.Iq('get', nbxmpp.NS_REGISTER, to=agent)
 | 
			
		||||
        id_ = self.connection.getAnID()
 | 
			
		||||
        iq.setID(id_)
 | 
			
		||||
        # Wait the answer during 30 secondes
 | 
			
		||||
        self.awaiting_timeouts[app.idlequeue.current_time() + 30] = (id_,
 | 
			
		||||
            _('Registration information for transport %s has not arrived in '
 | 
			
		||||
            'time') % agent)
 | 
			
		||||
        self.connection.SendAndCallForResponse(iq, self._ReceivedRegInfo,
 | 
			
		||||
            {'agent': agent})
 | 
			
		||||
 | 
			
		||||
    def _agent_registered_cb(self, con, resp, agent):
 | 
			
		||||
        if resp.getType() == 'result':
 | 
			
		||||
            app.nec.push_incoming_event(InformationEvent(
 | 
			
		||||
                None, dialog_name='agent-register-success', args=agent))
 | 
			
		||||
            self.get_module('Presence').subscribe(agent, auto_auth=True)
 | 
			
		||||
            self.agent_registrations[agent]['roster_push'] = True
 | 
			
		||||
            if self.agent_registrations[agent]['sub_received']:
 | 
			
		||||
                p = nbxmpp.Presence(agent, 'subscribed')
 | 
			
		||||
                p = self.add_sha(p)
 | 
			
		||||
                self.connection.send(p)
 | 
			
		||||
        if resp.getType() == 'error':
 | 
			
		||||
            app.nec.push_incoming_event(InformationEvent(
 | 
			
		||||
                None, dialog_name='agent-register-error', 
 | 
			
		||||
                kwargs={'agent': agent,
 | 
			
		||||
                        'error': resp.getError(),
 | 
			
		||||
                        'error_msg': resp.getErrorMsg()}))
 | 
			
		||||
 | 
			
		||||
    def register_agent(self, agent, info, is_form=False):
 | 
			
		||||
        if not self.connection or self.connected < 2:
 | 
			
		||||
            return
 | 
			
		||||
        if is_form:
 | 
			
		||||
            iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER, to=agent)
 | 
			
		||||
            query = iq.setQuery()
 | 
			
		||||
            info.setAttr('type', 'submit')
 | 
			
		||||
            query.addChild(node=info)
 | 
			
		||||
            self.connection.SendAndCallForResponse(iq,
 | 
			
		||||
                self._agent_registered_cb, {'agent': agent})
 | 
			
		||||
        else:
 | 
			
		||||
            # fixed: blocking
 | 
			
		||||
            nbxmpp.features_nb.register(self.connection, agent, info,
 | 
			
		||||
                self._agent_registered_cb, {'agent': agent})
 | 
			
		||||
        self.agent_registrations[agent] = {'roster_push': False,
 | 
			
		||||
            'sub_received': False}
 | 
			
		||||
 | 
			
		||||
    def _ReceivedRegInfo(self, con, resp, agent):
 | 
			
		||||
        nbxmpp.features_nb._ReceivedRegInfo(con, resp, agent)
 | 
			
		||||
        self._IqCB(con, resp)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# basic connection handlers used here and in zeroconf
 | 
			
		||||
class ConnectionHandlersBase:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
| 
						 | 
				
			
			@ -443,7 +388,7 @@ class ConnectionHandlersBase:
 | 
			
		|||
 | 
			
		||||
        return sess
 | 
			
		||||
 | 
			
		||||
class ConnectionHandlers(ConnectionSocks5Bytestream, ConnectionDisco,
 | 
			
		||||
class ConnectionHandlers(ConnectionSocks5Bytestream,
 | 
			
		||||
                         ConnectionHandlersBase,
 | 
			
		||||
                         ConnectionJingle, ConnectionIBBytestream):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -868,10 +868,6 @@ class SignedInEvent(nec.NetworkIncomingEvent):
 | 
			
		|||
    name = 'signed-in'
 | 
			
		||||
    base_network_events = []
 | 
			
		||||
 | 
			
		||||
class RegisterAgentInfoReceivedEvent(nec.NetworkIncomingEvent):
 | 
			
		||||
    name = 'register-agent-info-received'
 | 
			
		||||
    base_network_events = []
 | 
			
		||||
 | 
			
		||||
class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
 | 
			
		||||
    name = 'file-request-received'
 | 
			
		||||
    base_network_events = []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,8 @@ class Register:
 | 
			
		|||
 | 
			
		||||
        self.handlers = []
 | 
			
		||||
 | 
			
		||||
        self.agent_registrations = {}
 | 
			
		||||
 | 
			
		||||
    def change_password(self, password, success_cb, error_cb):
 | 
			
		||||
        if not app.account_is_connected(self._account):
 | 
			
		||||
            return
 | 
			
		||||
| 
						 | 
				
			
			@ -52,11 +54,87 @@ class Register:
 | 
			
		|||
        if not nbxmpp.isResultNode(stanza):
 | 
			
		||||
            error = stanza.getErrorMsg()
 | 
			
		||||
            log.info('Error: %s', error)
 | 
			
		||||
            if error_cb() is not None:
 | 
			
		||||
                error_cb()(error)
 | 
			
		||||
        else:
 | 
			
		||||
            log.info('Password changed')
 | 
			
		||||
            if success_cb() is not None:
 | 
			
		||||
                success_cb()()
 | 
			
		||||
 | 
			
		||||
    def register_agent(self, agent, form, is_form, success_cb, error_cb):
 | 
			
		||||
        if not app.account_is_connected(self._account):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        weak_success_cb = weakref.WeakMethod(success_cb)
 | 
			
		||||
        weak_error_cb = weakref.WeakMethod(error_cb)
 | 
			
		||||
 | 
			
		||||
        iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER, to=agent)
 | 
			
		||||
        if is_form:
 | 
			
		||||
            query = iq.setQuery()
 | 
			
		||||
            form.setAttr('type', 'submit')
 | 
			
		||||
            query.addChild(node=form)
 | 
			
		||||
        else:
 | 
			
		||||
            for field in form.keys():
 | 
			
		||||
                iq.setTag('query').setTagData(field, form[field])
 | 
			
		||||
 | 
			
		||||
        self._con.connection.SendAndCallForResponse(
 | 
			
		||||
            iq, self._register_agent_response, {'agent': agent,
 | 
			
		||||
                                                'success_cb': weak_success_cb,
 | 
			
		||||
                                                'error_cb': weak_error_cb})
 | 
			
		||||
 | 
			
		||||
        self.agent_registrations[agent] = {'roster_push': False,
 | 
			
		||||
                                           'sub_received': False}
 | 
			
		||||
 | 
			
		||||
    def _register_agent_response(self, con, stanza, agent,
 | 
			
		||||
                                 success_cb, error_cb):
 | 
			
		||||
        if not nbxmpp.isResultNode(stanza):
 | 
			
		||||
            error = stanza.getErrorMsg()
 | 
			
		||||
            log.info('Error: %s', error)
 | 
			
		||||
            if error_cb() is not None:
 | 
			
		||||
                error_cb()(error)
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        self._con.get_module('Presence').subscribe(agent, auto_auth=True)
 | 
			
		||||
 | 
			
		||||
        self.agent_registrations[agent]['roster_push'] = True
 | 
			
		||||
        if self.agent_registrations[agent]['sub_received']:
 | 
			
		||||
            self._con.get_module('Presence').subscribed(agent)
 | 
			
		||||
 | 
			
		||||
        if success_cb() is not None:
 | 
			
		||||
            success_cb()()
 | 
			
		||||
 | 
			
		||||
    def get_register_form(self, jid, success_cb, error_cb):
 | 
			
		||||
        if not app.account_is_connected(self._account):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        weak_success_cb = weakref.WeakMethod(success_cb)
 | 
			
		||||
        weak_error_cb = weakref.WeakMethod(error_cb)
 | 
			
		||||
 | 
			
		||||
        iq = nbxmpp.Iq('get', nbxmpp.NS_REGISTER, to=jid)
 | 
			
		||||
        self._con.connection.SendAndCallForResponse(
 | 
			
		||||
            iq, self._register_info_response, {'success_cb': weak_success_cb,
 | 
			
		||||
                                               'error_cb': weak_error_cb})
 | 
			
		||||
 | 
			
		||||
    def _register_info_response(self, con, stanza, success_cb, error_cb):
 | 
			
		||||
        if not nbxmpp.isResultNode(stanza):
 | 
			
		||||
            error = stanza.getErrorMsg()
 | 
			
		||||
            log.info('Error: %s', error)
 | 
			
		||||
            if error_cb() is not None:
 | 
			
		||||
                error_cb()(error)
 | 
			
		||||
        else:
 | 
			
		||||
            log.info('Register form received')
 | 
			
		||||
            form = stanza.getQuery().getTag('x', namespace=nbxmpp.NS_DATA)
 | 
			
		||||
            is_form = form is not None
 | 
			
		||||
            if not is_form:
 | 
			
		||||
                form = {}
 | 
			
		||||
                for field in stanza.getQueryPayload():
 | 
			
		||||
                    if not isinstance(field, nbxmpp.Node):
 | 
			
		||||
                        continue
 | 
			
		||||
                    form[field.getName()] = field.getData()
 | 
			
		||||
 | 
			
		||||
            if success_cb() is not None:
 | 
			
		||||
                success_cb()(form, is_form)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_instance(*args, **kwargs):
 | 
			
		||||
    return Register(*args, **kwargs), 'Register'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1486,57 +1486,6 @@ class FakeDataForm(Gtk.Table, object):
 | 
			
		|||
            self.infos[name] = self.entries[name].get_text()
 | 
			
		||||
        return self.infos
 | 
			
		||||
 | 
			
		||||
class ServiceRegistrationWindow:
 | 
			
		||||
    """
 | 
			
		||||
    Class for Service registration window. Window that appears when we want to
 | 
			
		||||
    subscribe to a service if is_form we use dataforms_widget else we use
 | 
			
		||||
    service_registarion_window
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, service, infos, account, is_form):
 | 
			
		||||
        self.service = service
 | 
			
		||||
        self.account = account
 | 
			
		||||
        self.is_form = is_form
 | 
			
		||||
        self.xml = gtkgui_helpers.get_gtk_builder('service_registration_window.ui')
 | 
			
		||||
        self.window = self.xml.get_object('service_registration_window')
 | 
			
		||||
        self.window.set_transient_for(app.interface.roster.window)
 | 
			
		||||
        if self.is_form:
 | 
			
		||||
            dataform = dataforms.ExtendForm(node = infos)
 | 
			
		||||
            self.data_form_widget = dataforms_widget.DataFormWidget(dataform)
 | 
			
		||||
            if self.data_form_widget.title:
 | 
			
		||||
                self.window.set_title('%s - Gajim' % self.data_form_widget.title)
 | 
			
		||||
            grid = self.xml.get_object('grid')
 | 
			
		||||
            grid.attach(self.data_form_widget, 0, 0, 2, 1)
 | 
			
		||||
        else:
 | 
			
		||||
            if 'registered' in infos:
 | 
			
		||||
                self.window.set_title(_('Edit %s') % service)
 | 
			
		||||
            else:
 | 
			
		||||
                self.window.set_title(_('Register to %s') % service)
 | 
			
		||||
            self.data_form_widget = FakeDataForm(infos)
 | 
			
		||||
            grid = self.xml.get_object('grid')
 | 
			
		||||
            grid.attach(self.data_form_widget, 0, 0, 2, 1)
 | 
			
		||||
 | 
			
		||||
        self.xml.connect_signals(self)
 | 
			
		||||
        self.window.show_all()
 | 
			
		||||
 | 
			
		||||
    def on_cancel_button_clicked(self, widget):
 | 
			
		||||
        self.window.destroy()
 | 
			
		||||
 | 
			
		||||
    def on_ok_button_clicked(self, widget):
 | 
			
		||||
        # send registration info to the core
 | 
			
		||||
        if self.is_form:
 | 
			
		||||
            form = self.data_form_widget.data_form
 | 
			
		||||
            app.connections[self.account].register_agent(self.service,
 | 
			
		||||
                    form, True) # True is for is_form
 | 
			
		||||
        else:
 | 
			
		||||
            infos = self.data_form_widget.get_infos()
 | 
			
		||||
            if 'instructions' in infos:
 | 
			
		||||
                del infos['instructions']
 | 
			
		||||
            if 'registered' in infos:
 | 
			
		||||
                del infos['registered']
 | 
			
		||||
            app.connections[self.account].register_agent(self.service, infos)
 | 
			
		||||
 | 
			
		||||
        self.window.destroy()
 | 
			
		||||
 | 
			
		||||
class GroupchatConfigWindow:
 | 
			
		||||
 | 
			
		||||
    def __init__(self, account, room_jid, form=None):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,96 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!-- Generated with glade 3.18.3 -->
 | 
			
		||||
<interface>
 | 
			
		||||
  <requires lib="gtk+" version="3.12"/>
 | 
			
		||||
  <object class="GtkImage" id="image1">
 | 
			
		||||
    <property name="visible">True</property>
 | 
			
		||||
    <property name="can_focus">False</property>
 | 
			
		||||
    <property name="stock">gtk-apply</property>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkImage" id="image2">
 | 
			
		||||
    <property name="visible">True</property>
 | 
			
		||||
    <property name="can_focus">False</property>
 | 
			
		||||
    <property name="stock">gtk-cancel</property>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkWindow" id="service_registration_window">
 | 
			
		||||
    <property name="can_focus">False</property>
 | 
			
		||||
    <property name="border_width">6</property>
 | 
			
		||||
    <property name="title" translatable="yes">Register to</property>
 | 
			
		||||
    <property name="type_hint">dialog</property>
 | 
			
		||||
    <child>
 | 
			
		||||
      <object class="GtkBox" id="vbox12">
 | 
			
		||||
        <property name="visible">True</property>
 | 
			
		||||
        <property name="can_focus">False</property>
 | 
			
		||||
        <property name="orientation">vertical</property>
 | 
			
		||||
        <property name="spacing">6</property>
 | 
			
		||||
        <child>
 | 
			
		||||
          <object class="GtkGrid" id="grid">
 | 
			
		||||
            <property name="visible">True</property>
 | 
			
		||||
            <property name="can_focus">False</property>
 | 
			
		||||
            <property name="row_spacing">6</property>
 | 
			
		||||
            <property name="column_spacing">6</property>
 | 
			
		||||
            <child>
 | 
			
		||||
              <placeholder/>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <placeholder/>
 | 
			
		||||
            </child>
 | 
			
		||||
          </object>
 | 
			
		||||
          <packing>
 | 
			
		||||
            <property name="expand">False</property>
 | 
			
		||||
            <property name="fill">True</property>
 | 
			
		||||
            <property name="position">0</property>
 | 
			
		||||
          </packing>
 | 
			
		||||
        </child>
 | 
			
		||||
        <child>
 | 
			
		||||
          <object class="GtkButtonBox" id="hbuttonbox5">
 | 
			
		||||
            <property name="visible">True</property>
 | 
			
		||||
            <property name="can_focus">False</property>
 | 
			
		||||
            <property name="spacing">12</property>
 | 
			
		||||
            <property name="layout_style">end</property>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="cancel_button">
 | 
			
		||||
                <property name="label" translatable="yes">_Cancel</property>
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="receives_default">False</property>
 | 
			
		||||
                <property name="image">image2</property>
 | 
			
		||||
                <property name="use_underline">True</property>
 | 
			
		||||
                <signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="expand">False</property>
 | 
			
		||||
                <property name="fill">False</property>
 | 
			
		||||
                <property name="position">0</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="ok_button">
 | 
			
		||||
                <property name="label" translatable="yes">_OK</property>
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="can_default">True</property>
 | 
			
		||||
                <property name="has_default">True</property>
 | 
			
		||||
                <property name="receives_default">False</property>
 | 
			
		||||
                <property name="image">image1</property>
 | 
			
		||||
                <property name="use_underline">True</property>
 | 
			
		||||
                <signal name="clicked" handler="on_ok_button_clicked" swapped="no"/>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="expand">False</property>
 | 
			
		||||
                <property name="fill">False</property>
 | 
			
		||||
                <property name="position">1</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
          </object>
 | 
			
		||||
          <packing>
 | 
			
		||||
            <property name="expand">False</property>
 | 
			
		||||
            <property name="fill">True</property>
 | 
			
		||||
            <property name="position">1</property>
 | 
			
		||||
          </packing>
 | 
			
		||||
        </child>
 | 
			
		||||
      </object>
 | 
			
		||||
    </child>
 | 
			
		||||
  </object>
 | 
			
		||||
</interface>
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +59,7 @@ from gajim import groups
 | 
			
		|||
from gajim import adhoc_commands
 | 
			
		||||
from gajim import search_window
 | 
			
		||||
from gajim import gui_menu_builder
 | 
			
		||||
from gajim.gtk import ServiceRegistration
 | 
			
		||||
 | 
			
		||||
from gajim.common import app
 | 
			
		||||
import nbxmpp
 | 
			
		||||
| 
						 | 
				
			
			@ -1355,7 +1356,7 @@ class ToplevelAgentBrowser(AgentBrowser):
 | 
			
		|||
            return
 | 
			
		||||
        jid = model[iter_][0]
 | 
			
		||||
        if jid:
 | 
			
		||||
            app.connections[self.account].request_register_agent_info(jid)
 | 
			
		||||
            ServiceRegistration(self.account, jid)
 | 
			
		||||
            self.window.destroy(chain=True)
 | 
			
		||||
 | 
			
		||||
    def on_join_button_clicked(self, widget):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,3 +66,4 @@ from gajim.gtk.bookmarks import ManageBookmarksWindow
 | 
			
		|||
from gajim.gtk.profile import ProfileWindow
 | 
			
		||||
from gajim.gtk.features import FeaturesDialog
 | 
			
		||||
from gajim.gtk.account_wizard import AccountCreationWizard
 | 
			
		||||
from gajim.gtk.service_registration import ServiceRegistration
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -209,7 +209,8 @@ class AddNewContactWindow(Gtk.ApplicationWindow):
 | 
			
		|||
        model = self.protocol_jid_combobox.get_model()
 | 
			
		||||
        row = self.protocol_jid_combobox.get_active()
 | 
			
		||||
        jid = model[row][0]
 | 
			
		||||
        app.connections[self.account].request_register_agent_info(jid)
 | 
			
		||||
        from gajim.gtk import ServiceRegistration
 | 
			
		||||
        ServiceRegistration(self.account, jid)
 | 
			
		||||
 | 
			
		||||
    def _on_key_press(self, widget, event):
 | 
			
		||||
        if event.keyval == Gdk.KEY_Escape:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,10 +13,10 @@
 | 
			
		|||
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
from gi.repository import Gtk
 | 
			
		||||
from gi.repository import Gdk
 | 
			
		||||
 | 
			
		||||
from gajim.common import app
 | 
			
		||||
from gajim.common import helpers
 | 
			
		||||
from gajim.common.modules import dataforms
 | 
			
		||||
from gajim.gtk.util import get_builder
 | 
			
		||||
from gajim.gtk.util import load_icon
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										198
									
								
								gajim/gtk/service_registration.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								gajim/gtk/service_registration.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,198 @@
 | 
			
		|||
# This file is part of Gajim.
 | 
			
		||||
#
 | 
			
		||||
# Gajim is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published
 | 
			
		||||
# by the Free Software Foundation; version 3 only.
 | 
			
		||||
#
 | 
			
		||||
# Gajim is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
from enum import IntEnum
 | 
			
		||||
 | 
			
		||||
from gi.repository import Gtk
 | 
			
		||||
 | 
			
		||||
from gajim.common import app
 | 
			
		||||
from gajim.common.modules import dataforms
 | 
			
		||||
 | 
			
		||||
log = logging.getLogger('gajim.gtk.registration')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Page(IntEnum):
 | 
			
		||||
    REQUEST = 0
 | 
			
		||||
    FORM = 1
 | 
			
		||||
    SENDING = 2
 | 
			
		||||
    SUCCESS = 3
 | 
			
		||||
    ERROR = 4
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ServiceRegistration(Gtk.Assistant):
 | 
			
		||||
    def __init__(self, account, agent):
 | 
			
		||||
        Gtk.Assistant.__init__(self)
 | 
			
		||||
 | 
			
		||||
        self._con = app.connections[account]
 | 
			
		||||
        self._agent = agent
 | 
			
		||||
        self._account = account
 | 
			
		||||
        self._data_form_widget = None
 | 
			
		||||
        self._is_form = None
 | 
			
		||||
 | 
			
		||||
        self.set_application(app.app)
 | 
			
		||||
        self.set_resizable(True)
 | 
			
		||||
        self.set_position(Gtk.WindowPosition.CENTER)
 | 
			
		||||
 | 
			
		||||
        self.set_default_size(500, 300)
 | 
			
		||||
        self.get_style_context().add_class('dialog-margin')
 | 
			
		||||
 | 
			
		||||
        request = RequestPage()
 | 
			
		||||
        self.append_page(request)
 | 
			
		||||
        self.set_page_type(request, Gtk.AssistantPageType.INTRO)
 | 
			
		||||
 | 
			
		||||
        form = FormPage()
 | 
			
		||||
        self.append_page(form)
 | 
			
		||||
        self.set_page_type(form, Gtk.AssistantPageType.INTRO)
 | 
			
		||||
        self.set_page_complete(form, True)
 | 
			
		||||
 | 
			
		||||
        sending = SendingPage()
 | 
			
		||||
        self.append_page(sending)
 | 
			
		||||
        self.set_page_type(sending, Gtk.AssistantPageType.PROGRESS)
 | 
			
		||||
 | 
			
		||||
        success = SuccessfulPage()
 | 
			
		||||
        self.append_page(success)
 | 
			
		||||
        self.set_page_type(success, Gtk.AssistantPageType.SUMMARY)
 | 
			
		||||
        self.set_page_complete(success, True)
 | 
			
		||||
 | 
			
		||||
        error = ErrorPage()
 | 
			
		||||
        self.append_page(error)
 | 
			
		||||
        self.set_page_type(error, Gtk.AssistantPageType.SUMMARY)
 | 
			
		||||
        self.set_page_complete(error, True)
 | 
			
		||||
 | 
			
		||||
        self.connect('prepare', self._on_page_change)
 | 
			
		||||
        self.connect('cancel', self._on_cancel)
 | 
			
		||||
        self.connect('close', self._on_cancel)
 | 
			
		||||
 | 
			
		||||
        self.show_all()
 | 
			
		||||
 | 
			
		||||
    def _on_page_change(self, assistant, page):
 | 
			
		||||
        if self.get_current_page() == Page.REQUEST:
 | 
			
		||||
            self._con.get_module('Register').get_register_form(
 | 
			
		||||
                self._agent, self._on_get_success, self._on_error)
 | 
			
		||||
        elif self.get_current_page() == Page.SENDING:
 | 
			
		||||
            self._register()
 | 
			
		||||
            self.commit()
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
    def _on_get_success(self, form, is_form):
 | 
			
		||||
        log.info('Show Form page')
 | 
			
		||||
        self._is_form = is_form
 | 
			
		||||
        if is_form:
 | 
			
		||||
            from gajim import dataforms_widget
 | 
			
		||||
            dataform = dataforms.ExtendForm(node=form)
 | 
			
		||||
            self._data_form_widget = dataforms_widget.DataFormWidget(dataform)
 | 
			
		||||
            if self._data_form_widget.title:
 | 
			
		||||
                self.set_title('%s - Gajim' % self._data_form_widget.title)
 | 
			
		||||
        else:
 | 
			
		||||
            if 'registered' in form:
 | 
			
		||||
                self.set_title(_('Edit %s') % self._agent)
 | 
			
		||||
            else:
 | 
			
		||||
                self.set_title(_('Register to %s') % self._agent)
 | 
			
		||||
            from gajim import config
 | 
			
		||||
            self._data_form_widget = config.FakeDataForm(form)
 | 
			
		||||
 | 
			
		||||
        page = self.get_nth_page(Page.FORM)
 | 
			
		||||
        page.pack_start(self._data_form_widget, True, True, 0)
 | 
			
		||||
        self._data_form_widget.show()
 | 
			
		||||
        self.set_current_page(Page.FORM)
 | 
			
		||||
 | 
			
		||||
    def _on_error(self, error_text):
 | 
			
		||||
        log.info('Show Error page')
 | 
			
		||||
        page = self.get_nth_page(Page.ERROR)
 | 
			
		||||
        page.set_text(error_text)
 | 
			
		||||
        self.set_current_page(Page.ERROR)
 | 
			
		||||
 | 
			
		||||
    def _on_cancel(self, widget):
 | 
			
		||||
        self.destroy()
 | 
			
		||||
 | 
			
		||||
    def _register(self):
 | 
			
		||||
        log.info('Show Sending page')
 | 
			
		||||
        if self._is_form:
 | 
			
		||||
            form = self._data_form_widget.data_form
 | 
			
		||||
        else:
 | 
			
		||||
            form = self._data_form_widget.get_infos()
 | 
			
		||||
            if 'instructions' in form:
 | 
			
		||||
                del form['instructions']
 | 
			
		||||
            if 'registered' in form:
 | 
			
		||||
                del form['registered']
 | 
			
		||||
 | 
			
		||||
        self._con.get_module('Register').register_agent(
 | 
			
		||||
            self._agent,
 | 
			
		||||
            form,
 | 
			
		||||
            self._is_form,
 | 
			
		||||
            self._on_register_success,
 | 
			
		||||
            self._on_error)
 | 
			
		||||
 | 
			
		||||
    def _on_register_success(self):
 | 
			
		||||
        log.info('Show Success page')
 | 
			
		||||
        self.set_current_page(Page.SUCCESS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RequestPage(Gtk.Box):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__(orientation=Gtk.Orientation.VERTICAL)
 | 
			
		||||
        self.set_spacing(18)
 | 
			
		||||
        spinner = Gtk.Spinner()
 | 
			
		||||
        self.pack_start(spinner, True, True, 0)
 | 
			
		||||
        spinner.start()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SendingPage(RequestPage):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FormPage(Gtk.Box):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__(orientation=Gtk.Orientation.VERTICAL)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SuccessfulPage(Gtk.Box):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__(orientation=Gtk.Orientation.VERTICAL)
 | 
			
		||||
        self.set_spacing(12)
 | 
			
		||||
        self.set_homogeneous(True)
 | 
			
		||||
 | 
			
		||||
        icon = Gtk.Image.new_from_icon_name('object-select-symbolic',
 | 
			
		||||
                                            Gtk.IconSize.DIALOG)
 | 
			
		||||
        icon.get_style_context().add_class('success-color')
 | 
			
		||||
        icon.set_valign(Gtk.Align.END)
 | 
			
		||||
        label = Gtk.Label(label=_('Registration successful'))
 | 
			
		||||
        label.get_style_context().add_class('bold16')
 | 
			
		||||
        label.set_valign(Gtk.Align.START)
 | 
			
		||||
 | 
			
		||||
        self.add(icon)
 | 
			
		||||
        self.add(label)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ErrorPage(Gtk.Box):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__(orientation=Gtk.Orientation.VERTICAL)
 | 
			
		||||
        self.set_spacing(12)
 | 
			
		||||
        self.set_homogeneous(True)
 | 
			
		||||
 | 
			
		||||
        icon = Gtk.Image.new_from_icon_name('dialog-error-symbolic',
 | 
			
		||||
                                            Gtk.IconSize.DIALOG)
 | 
			
		||||
        icon.get_style_context().add_class('error-color')
 | 
			
		||||
        icon.set_valign(Gtk.Align.END)
 | 
			
		||||
        self._label = Gtk.Label()
 | 
			
		||||
        self._label.get_style_context().add_class('bold16')
 | 
			
		||||
        self._label.set_valign(Gtk.Align.START)
 | 
			
		||||
 | 
			
		||||
        self.add(icon)
 | 
			
		||||
        self.add(self._label)
 | 
			
		||||
 | 
			
		||||
    def set_text(self, text):
 | 
			
		||||
        self._label.set_text(text)
 | 
			
		||||
| 
						 | 
				
			
			@ -580,17 +580,6 @@ class Interface:
 | 
			
		|||
                'unsubscribed', 'gajim-unsubscribed',
 | 
			
		||||
                event_type, obj.jid)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def handle_event_register_agent_info(obj):
 | 
			
		||||
        # ('REGISTER_AGENT_INFO', account, (agent, infos, is_form))
 | 
			
		||||
        # info in a dataform if is_form is True
 | 
			
		||||
        if obj.is_form or 'instructions' in obj.config:
 | 
			
		||||
            config.ServiceRegistrationWindow(obj.agent, obj.config,
 | 
			
		||||
                obj.conn.name, obj.is_form)
 | 
			
		||||
        else:
 | 
			
		||||
            ErrorDialog(_('Contact with "%s" cannot be established') % \
 | 
			
		||||
                obj.agent, _('Check your connection or try again later.'))
 | 
			
		||||
 | 
			
		||||
    def handle_event_gc_config(self, obj):
 | 
			
		||||
        #('GC_CONFIG', account, (jid, form_node))  config is a dict
 | 
			
		||||
        account = obj.conn.name
 | 
			
		||||
| 
						 | 
				
			
			@ -1565,7 +1554,6 @@ class Interface:
 | 
			
		|||
            'password-required': [self.handle_event_password_required],
 | 
			
		||||
            'plain-connection': [self.handle_event_plain_connection],
 | 
			
		||||
            'presence-received': [self.handle_event_presence],
 | 
			
		||||
            'register-agent-info-received': [self.handle_event_register_agent_info],
 | 
			
		||||
            'roster-info': [self.handle_event_roster_info],
 | 
			
		||||
            'roster-item-exchange-received': \
 | 
			
		||||
                [self.handle_event_roster_item_exchange],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,6 +71,7 @@ from gajim.gtk import AddNewContactWindow
 | 
			
		|||
from gajim.gtk import ManagePEPServicesWindow
 | 
			
		||||
from gajim.gtk import ManageBookmarksWindow
 | 
			
		||||
from gajim.gtk import AccountCreationWizard
 | 
			
		||||
from gajim.gtk import ServiceRegistration
 | 
			
		||||
 | 
			
		||||
from gajim.common.const import AvatarSize
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2790,7 +2791,7 @@ class RosterWindow:
 | 
			
		|||
        """
 | 
			
		||||
        When we want to modify the agent registration
 | 
			
		||||
        """
 | 
			
		||||
        app.connections[account].request_register_agent_info(contact.jid)
 | 
			
		||||
        ServiceRegistration(account, contact.jid)
 | 
			
		||||
 | 
			
		||||
    def on_remove_agent(self, widget, list_):
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue