Example #1
0
    def assert_contact_is_in_roster(self, jid, account):
        contacts = app.contacts.get_contacts(account, jid)
        # check for all resources
        for contact in contacts:
            iters = self.roster._get_contact_iter(jid, account,
                    model=self.roster.model)

            if jid != app.get_jid_from_account(account):
                # We don't care for groups of SelfContact
                self.assertTrue(len(iters) == len(contact.get_shown_groups()),
                        msg='Contact is not in all his groups')

            # Are we big brother?
            bb_jid = None
            bb_account = None
            family = app.contacts.get_metacontacts_family(account, jid)
            if family:
                nearby_family, bb_jid, bb_account = \
                        self.roster._get_nearby_family_and_big_brother(family, account)

                is_in_nearby_family = (jid, account) in (
                        (data['jid'], data['account']) for data in nearby_family)
                self.assertTrue(is_in_nearby_family,
                        msg='Contact not in his own nearby family')

            is_big_brother = (bb_jid, bb_account) == (jid, account)

            # check for each group tag
            for titerC in iters:
                self.assertTrue(self.roster.model.iter_is_valid(titerC),
                        msg='Contact iter invalid')

                c_model = self.roster.model[titerC]
                # name can be stricked if contact or group is blocked
#                self.assertEqual(contact.get_shown_name(), c_model[self.C_NAME],
#                        msg='Contact name missmatch')
                self.assertEqual(contact.jid, c_model[self.C_JID],
                        msg='Jid missmatch')

                if not self.roster.regroup:
                    self.assertEqual(account, c_model[self.C_ACCOUNT],
                            msg='Account missmatch')

                # Check for correct nesting
                parent_iter = self.roster.model.iter_parent(titerC)
                p_model = self.roster.model[parent_iter]
                if family:
                    if is_big_brother:
                        self.assertTrue(p_model[self.C_TYPE] == 'group',
                                msg='Big Brother is not on top')
                    else:
                        self.assertTrue(p_model[self.C_TYPE] == 'contact',
                                msg='Little Brother brother has no BigB')
                else:
                    if jid == app.get_jid_from_account(account):
                        self.assertTrue(p_model[self.C_TYPE] == 'account',
                                msg='SelfContact is not on top')
                    else:
                        self.assertTrue(p_model[self.C_TYPE] == 'group',
                                msg='Contact not found in a group')
Example #2
0
    def update_context_list(self):
        self._ui.deviceid_store.clear()

        if not len(self._ui.account_store):
            self._ui.ID.set_markup('')
            self._ui.fingerprint_label.set_markup('')
            self._ui.refresh.set_sensitive(False)
            self._ui.cleardevice_button.set_sensitive(False)
            return
        active = self._ui.account_combobox.get_active()
        account = self._ui.account_store[active][0]

        # Set buttons active
        self._ui.refresh.set_sensitive(True)
        if account == 'Local':
            self._ui.cleardevice_button.set_sensitive(False)
        else:
            self._ui.cleardevice_button.set_sensitive(True)

        # Set FPR Label and DeviceID
        omemo = self.plugin.get_omemo(account)
        self._ui.ID.set_markup('<tt>%s</tt>' % omemo.backend.own_device)

        identity_key = omemo.backend.storage.getIdentityKeyPair()
        fpr = get_fingerprint(identity_key, formatted=True)
        self._ui.fingerprint_label.set_markup('<tt>%s</tt>' % fpr)

        own_jid = app.get_jid_from_account(account)
        # Set Device ID List
        for item in omemo.backend.get_devices(own_jid):
            self._ui.deviceid_store.append([item])
Example #3
0
    def __init__(self, jid, account, items):
        self._pep_specific_data, self._retracted = self._extract_info(items)

        self._update_contacts(jid, account)
        if jid == app.get_jid_from_account(account):
            self._update_account(account)
        self._on_receive(jid, account)
Example #4
0
    def _nec_message_outgoing(self, obj):
        # Send the given message to the active tab.
        # Doesn't return None if error
        if obj.control != self:
            return

        obj.message = helpers.remove_invalid_xml_chars(obj.message)

        conn = app.connections[self.account]

        if not self.session:
            if (not obj.resource
                    and obj.jid != app.get_jid_from_account(self.account)):
                if self.resource:
                    obj.resource = self.resource
                else:
                    obj.resource = self.contact.resource
            sess = conn.find_controlless_session(obj.jid,
                                                 resource=obj.resource)

            if self.resource:
                obj.jid += '/' + self.resource

            if not sess:
                if self.type_id == TYPE_PM:
                    sess = conn.make_new_session(obj.jid, type_='pm')
                else:
                    sess = conn.make_new_session(obj.jid)

            self.set_session(sess)

        obj.session = self.session
Example #5
0
 def _node_not_removed(self, jid, node, msg):
     if jid != app.get_jid_from_account(self.account):
         return
     WarningDialog(
         _('PEP node was not removed'),
         _('PEP node %(node)s was not removed:\n%(message)s') % {
             'node': node, 'message': msg})
Example #6
0
    def __init__(self, account, transient_for=None):
        self.xml = gtkgui_helpers.get_gtk_builder('profile_window.ui')
        self.window = self.xml.get_object('profile_window')
        self.window.set_transient_for(transient_for)
        self.progressbar = self.xml.get_object('progressbar')
        self.statusbar = self.xml.get_object('statusbar')
        self.context_id = self.statusbar.get_context_id('profile')

        self.account = account
        self.jid = app.get_jid_from_account(account)

        self.dialog = None
        self.avatar_mime_type = None
        self.avatar_encoded = None
        self.avatar_sha = None
        self.message_id = self.statusbar.push(self.context_id,
                                              _('Retrieving profileā€¦'))
        self.update_progressbar_timeout_id = GLib.timeout_add(
            100, self.update_progressbar)
        self.remove_statusbar_timeout_id = None

        # Create Image for avatar button
        image = Gtk.Image()
        self.xml.get_object('PHOTO_button').set_image(image)
        self.xml.connect_signals(self)
        app.ged.register_event_handler('vcard-published', ged.GUI1,
                                       self._nec_vcard_published)
        app.ged.register_event_handler('vcard-not-published', ged.GUI1,
                                       self._nec_vcard_not_published)
        self.window.show_all()
        self.xml.get_object('ok_button').grab_focus()
        app.connections[account].request_vcard(self._nec_vcard_received,
                                               self.jid)
Example #7
0
    def replace_roster(self, account_name, roster_version, roster):
        """
        Replace current roster in DB by a new one

        accout_name is the name of the account to change.
        roster_version is the version of the new roster.
        roster is the new version.
        """
        # First we must reset roster_version value to ensure that the server
        # sends back all the roster at the next connexion if the replacement
        # didn't work properly.
        app.config.set_per('accounts', account_name, 'roster_version', '')

        account_jid = app.get_jid_from_account(account_name)
        # Execute get_jid_id() because this ensures on new accounts that the
        # jid_id will be created
        self.get_jid_id(account_jid, type_=JIDConstant.NORMAL_TYPE)

        # Delete old roster
        self.remove_roster(account_jid)

        # Fill roster tables with the new roster
        for jid in roster:
            self.add_or_update_contact(account_jid, jid, roster[jid]['name'],
                roster[jid]['subscription'], roster[jid]['ask'],
                roster[jid]['groups'], commit=False)
        self._timeout_commit()

        # At this point, we are sure the replacement works properly so we can
        # set the new roster_version value.
        app.config.set_per('accounts', account_name, 'roster_version',
            roster_version)
Example #8
0
 def invitable(contact, contact_transport=None):
     return (contact.jid not in self.auto_jids
             and contact.jid != app.get_jid_from_account(account)
             and contact.jid
             not in app.interface.minimized_controls[account]
             and not contact.is_transport()
             and contact_transport in ('jabber', None))
Example #9
0
    def _print_stanza(self, obj, kind):
        account = app.get_jid_from_account(obj.conn.name)
        stanza = obj.stanza_str
        # Kind must be 'incoming' or 'outgoing'
        if not stanza:
            return

        at_the_end = util.at_the_end(self._ui.scrolled)

        buffer_ = self._ui.textview.get_buffer()
        end_iter = buffer_.get_end_iter()

        type_ = kind
        if stanza.startswith('<presence'):
            type_ = 'presence'
        elif stanza.startswith('<message'):
            type_ = 'message'
        elif stanza.startswith('<iq'):
            type_ = 'iq'
        elif stanza.startswith('<r') or stanza.startswith('<a'):
            type_ = 'stream'

        stanza = '<!-- {kind} {time} ({account}) -->\n{stanza}\n\n'.format(
            kind=kind.capitalize(),
            time=time.strftime('%c'),
            account=account,
            stanza=stanza.replace('><', '>\n<'))
        buffer_.insert_with_tags_by_name(end_iter, stanza, type_, kind)

        if at_the_end:
            GLib.idle_add(util.scroll_to_end, self._ui.scrolled)
Example #10
0
 def request_catalog(self, jid):
     server = app.get_jid_from_account(self._account).split("@")[1]
     iq = nbxmpp.Iq(typ='get', to=server)
     iq.addChild(name='catalog',
                 namespace=nbxmpp.NS_SECLABEL_CATALOG,
                 attrs={'to': jid})
     self._log.info('Request catalog: server: %s, to: %s', server, jid)
     self._con.connection.SendAndCallForResponse(iq, self._catalog_received)
Example #11
0
 def _on_configure_button_clicked(self, _widget):
     selection = self._ui.services_treeview.get_selection()
     if not selection:
         return
     model, iter_ = selection.get_selected()
     node = model[iter_][0]
     our_jid = app.get_jid_from_account(self.account)
     con = app.connections[self.account]
     con.get_module('PubSub').request_pb_configuration(our_jid, node)
Example #12
0
 def _node_removed(self, jid, node):
     if jid != app.get_jid_from_account(self.account):
         return
     model = self._ui.services_treeview.get_model()
     iter_ = model.get_iter_first()
     while iter_:
         if model[iter_][0] == node:
             model.remove(iter_)
             break
         iter_ = model.iter_next(iter_)
Example #13
0
    def send_pb_unsubscribe(self, jid, node, cb, **kwargs):
        if not app.account_is_available(self._account):
            return

        our_jid = app.get_jid_from_account(self._account)
        query = nbxmpp.Iq('set', to=jid)
        pb = query.addChild('pubsub', namespace=Namespace.PUBSUB)
        pb.addChild('unsubscribe', {'node': node, 'jid': our_jid})

        self._con.connection.SendAndCallForResponse(query, cb, kwargs)
Example #14
0
    def _process_message_receipt(self, _con, stanza, properties):
        if not properties.is_receipt:
            return

        if properties.type.is_error:
            if properties.receipt.is_request:
                return
            # Don't propagate this event further
            raise nbxmpp.NodeProcessed

        if (properties.type.is_groupchat or properties.is_self_message
                or properties.is_mam_message
                or properties.is_carbon_message and properties.carbon.is_sent):

            if properties.receipt.is_received:
                # Don't propagate this event further
                raise nbxmpp.NodeProcessed
            return

        if properties.receipt.is_request:
            if not app.settings.get_account_setting(self._account,
                                                    'answer_receipts'):
                return

            if properties.eme is not None:
                # Don't send receipt for message which couldn't be decrypted
                if not properties.is_encrypted:
                    return

            contact = self._get_contact(properties)
            if contact is None:
                return
            self._log.info('Send receipt: %s', properties.jid)
            self._con.connection.send(build_receipt(stanza))
            return

        if properties.receipt.is_received:
            self._log.info('Receipt from %s %s', properties.jid,
                           properties.receipt.id)

            jid = properties.jid
            if not properties.is_muc_pm:
                jid = jid.new_as_bare()

            app.storage.archive.set_marker(
                app.get_jid_from_account(self._account), jid,
                properties.receipt.id, 'received')

            app.nec.push_incoming_event(
                NetworkEvent('receipt-received',
                             account=self._account,
                             jid=jid,
                             receipt_id=properties.receipt.id))

            raise nbxmpp.NodeProcessed
Example #15
0
 def _on_delete_button_clicked(self, _widget):
     selection = self._ui.services_treeview.get_selection()
     if not selection:
         return
     model, iter_ = selection.get_selected()
     node = model[iter_][0]
     our_jid = app.get_jid_from_account(self.account)
     con = app.connections[self.account]
     con.get_module('PubSub').send_pb_delete(our_jid, node,
                                             on_ok=self._node_removed,
                                             on_fail=self._node_not_removed)
Example #16
0
    def send_pb_unsubscribe(self, jid, node, cb, *args, **kwargs):
        if not self.connection or self.connected < 2:
            return
        our_jid = app.get_jid_from_account(self.name)
        query = nbxmpp.Iq('set', to=jid)
        pb = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
        pb.addChild('unsubscribe', {'node': node, 'jid': our_jid})

        id_ = self.connection.send(query)

        self.__callbacks[id_] = (cb, args, kwargs)
Example #17
0
    def _on_remove_success(self, res):
        # action of unregistration has failed, we don't remove the account
        # Error message is send by connect_and_auth()
        if not res:
            ConfirmationDialogDoubleRadio(
                _('Connection to server %s failed') % self.account,
                _('What would you like to do?'),
                _('Remove only from Gajim'),
                _('Don\'t remove anything. I\'ll try again later'),
                on_response_ok=self.on_remove_response_ok,
                is_modal=False,
                transient_for=self._ui.remove_account_window)
            return
        # Close all opened windows
        app.interface.roster.close_all(self.account, force=True)
        if self.account in app.connections:
            app.connections[self.account].disconnect(reconnect=False)
            app.connections[self.account].cleanup()
            del app.connections[self.account]
        app.logger.remove_roster(app.get_jid_from_account(self.account))
        # Delete password must be before del_per() because it calls set_per()
        # which would recreate the account with defaults values if not found
        passwords.delete_password(self.account)
        app.config.del_per('accounts', self.account)
        del app.interface.instances[self.account]
        if self.account in app.nicks:
            del app.interface.minimized_controls[self.account]
            del app.nicks[self.account]
            del app.block_signed_in_notifications[self.account]
            del app.groups[self.account]
            app.contacts.remove_account(self.account)
            del app.gc_connected[self.account]
            del app.automatic_rooms[self.account]
            del app.to_be_removed[self.account]
            del app.newly_added[self.account]
            del app.sleeper_state[self.account]
            del app.last_message_time[self.account]
            del app.status_before_autoaway[self.account]
            del app.gajim_optional_features[self.account]
            del app.caps_hash[self.account]
        if len(app.connections
               ) >= 2:  # Do not merge accounts if only one exists
            app.interface.roster.regroup = app.config.get('mergeaccounts')
        else:
            app.interface.roster.regroup = False
        app.interface.roster.setup_and_draw_roster()
        app.app.remove_account_actions(self.account)
        gui_menu_builder.build_accounts_menu()

        window = app.get_app_window('AccountsWindow')
        if window is not None:
            window.remove_account(self.account)
        self._ui.remove_account_window.destroy()
Example #18
0
    def get_own_jid(self):
        """
        Return the last full JID we received on a bind event.
        In case we were never connected it returns the bare JID from config.
        """
        if self._client is not None:
            jid = self._client.get_bound_jid()
            if jid is not None:
                return jid

        # This returns the bare jid
        return nbxmpp.JID.from_string(app.get_jid_from_account(self._account))
Example #19
0
    def _message_error_received(self, _con, _stanza, properties):
        log.info(properties.error)

        app.storage.archive.set_message_error(
            app.get_jid_from_account(self.name), properties.jid, properties.id,
            properties.error)

        app.nec.push_incoming_event(
            NetworkEvent('message-error',
                         account=self.name,
                         jid=properties.jid,
                         message_id=properties.id,
                         error=properties.error))
 def discover_ft_proxies(self):
     cfg_proxies = app.config.get_per('accounts', self.name,
                                      'file_transfer_proxies')
     our_jid = helpers.parse_jid(app.get_jid_from_account(self.name) + \
         '/' + self.server_resource)
     testit = app.config.get_per('accounts', self.name,
                                 'test_ft_proxies_on_startup')
     if cfg_proxies:
         proxies = [e.strip() for e in cfg_proxies.split(',')]
         for proxy in proxies:
             app.proxy65_manager.resolve(proxy,
                                         self.connection,
                                         our_jid,
                                         testit=testit)
Example #21
0
    def assert_account_is_in_roster(self, acc):
        titerA = self.roster._get_account_iter(acc, model=self.roster.model)
        self.assertTrue(self.roster.model.iter_is_valid(titerA),
                msg='Account iter is invalid')

        acc_model = self.roster.model[titerA]
        self.assertEqual(acc_model[self.C_TYPE], 'account',
                msg='No account found')

        if not self.roster.regroup:
            self.assertEqual(acc_model[self.C_ACCOUNT], acc,
                    msg='Account not found')

            self_jid = app.get_jid_from_account(acc)
            self.assertEqual(acc_model[self.C_JID], self_jid,
                    msg='Account JID not found in account row')
Example #22
0
 def account_info(self, account):
     """
     Show info on account: resource, jid, nick, prio, message
     """
     result = {}
     if account in app.connections:
         # account is valid
         con = app.connections[account]
         result['status'] = con.status
         result['name'] = con.name
         result['jid'] = app.get_jid_from_account(con.name)
         result['message'] = con.status_message
         result['priority'] = str(con.priority)
         result['resource'] = app.settings.get_account_setting(con.name,
                                                               'resource')
     return result
Example #23
0
 def account_info(self, account):
     """
     Show info on account: resource, jid, nick, prio, message
     """
     result = {}
     if account in app.connections:
         # account is valid
         con = app.connections[account]
         index = con.connected
         result['status'] = app.SHOW_LIST[index]
         result['name'] = con.name
         result['jid'] = app.get_jid_from_account(con.name)
         result['message'] = con.status
         result['priority'] = str(con.priority)
         result['resource'] = app.config.get_per('accounts', con.name,
                                                 'resource')
     return result
Example #24
0
    def _message_error_received(self, _con, _stanza, properties):
        jid = properties.jid.copy()
        if not properties.is_muc_pm:
            jid.setBare()

        self._log.info(properties.error)

        app.logger.set_message_error(app.get_jid_from_account(self._account),
                                     jid, properties.id, properties.error)

        app.nec.push_incoming_event(
            NetworkEvent('message-error',
                         account=self._account,
                         jid=jid,
                         room_jid=jid,
                         message_id=properties.id,
                         error=properties.error))
Example #25
0
    def _raise_event(self, name, properties):
        self._log.info('%s: %s %s', name, properties.jid, properties.marker.id)

        jid = properties.jid
        if not properties.is_muc_pm and not properties.type.is_groupchat:
            jid = properties.jid.bare

        app.storage.archive.set_marker(app.get_jid_from_account(self._account),
                                       jid, properties.marker.id, 'displayed')

        app.nec.push_outgoing_event(
            NetworkEvent(name,
                         account=self._account,
                         jid=jid,
                         properties=properties,
                         type=properties.type,
                         is_muc_pm=properties.is_muc_pm,
                         marker_id=properties.marker.id))
Example #26
0
    def pep_received(self, obj):
        if obj.jid != app.get_jid_from_account(obj.conn.name):
            return

        pep_dict = app.connections[obj.conn.name].pep
        if obj.pep_type == 'mood':
            img = self.xml.get_object('mood_image')
            if 'mood' in pep_dict:
                pixbuf = gtkgui_helpers.get_pep_as_pixbuf(pep_dict['mood'])
                img.set_from_pixbuf(pixbuf)
            else:
                img.set_from_stock('gtk-stop', Gtk.IconSize.MENU)
        if obj.pep_type == 'activity':
            img = self.xml.get_object('activity_image')
            if 'activity' in pep_dict:
                pb = gtkgui_helpers.get_pep_as_pixbuf(pep_dict['activity'])
                img.set_from_pixbuf(pb)
            else:
                img.set_from_stock('gtk-stop', Gtk.IconSize.MENU)
Example #27
0
    def __init__(self, account):
        Gtk.ApplicationWindow.__init__(self)
        EventHelper.__init__(self)
        self.set_application(app.app)
        self.set_position(Gtk.WindowPosition.CENTER)
        self.set_show_menubar(False)
        self.set_title(_('Profile'))

        self.connect('destroy', self.on_profile_window_destroy)
        self.connect('key-press-event', self.on_profile_window_key_press_event)

        self.xml = get_builder('profile_window.ui')
        self.add(self.xml.get_object('profile_box'))
        self.progressbar = self.xml.get_object('progressbar')
        self.statusbar = self.xml.get_object('statusbar')
        self.context_id = self.statusbar.get_context_id('profile')

        self.account = account
        self.jid = app.get_jid_from_account(account)
        account_label = app.config.get_per('accounts', account,
                                           'account_label')
        self.set_value('account_label', account_label)

        self.dialog = None
        self.avatar_mime_type = None
        self.avatar_encoded = None
        self.avatar_sha = None
        self.message_id = self.statusbar.push(self.context_id,
                                              _('Retrieving profileā€¦'))
        self.update_progressbar_timeout_id = GLib.timeout_add(
            100, self.update_progressbar)
        self.remove_statusbar_timeout_id = None

        self.xml.connect_signals(self)
        self.register_events([
            ('vcard-published', ged.GUI1, self._nec_vcard_published),
            ('vcard-not-published', ged.GUI1, self._nec_vcard_not_published),
        ])

        self.show_all()
        self.xml.get_object('ok_button').grab_focus()
        app.connections[account].get_module('VCardTemp').request_vcard(
            self._nec_vcard_received, self.jid)
Example #28
0
    def _process_message_receipt(self, _con, stanza, properties):
        if not properties.is_receipt:
            return

        if (properties.type.is_groupchat or properties.is_self_message
                or properties.is_mam_message
                or properties.is_carbon_message and properties.carbon.is_sent):

            if properties.receipt.is_received:
                # Don't propagate this event further
                raise nbxmpp.NodeProcessed
            return

        if properties.receipt.is_request:
            if not app.config.get_per('accounts', self._account,
                                      'answer_receipts'):
                return
            contact = self._get_contact(properties)
            if contact is None:
                return
            self._log.info('Send receipt: %s', properties.jid)
            self._con.connection.send(build_receipt(stanza))
            return

        if properties.receipt.is_received:
            self._log.info('Receipt from %s %s', properties.jid,
                           properties.receipt.id)

            jid = properties.jid.copy()
            if not properties.is_muc_pm:
                jid.setBare()

            app.logger.set_marker(app.get_jid_from_account(self._account), jid,
                                  properties.receipt.id, 'received')

            app.nec.push_incoming_event(
                NetworkEvent('receipt-received',
                             account=self._account,
                             jid=jid,
                             receipt_id=properties.receipt.id))

            raise nbxmpp.NodeProcessed
Example #29
0
    def __init__(self, plugin, contact, transient, windows, groupchat=False):
        super().__init__(title=_('OMEMO Fingerprints'),
                         destroy_with_parent=True)

        self.set_transient_for(transient)
        self.set_resizable(True)
        self.set_default_size(500, 450)

        self.get_style_context().add_class('omemo-key-dialog')

        self._groupchat = groupchat
        self._contact = contact
        self._windows = windows
        self._account = self._contact.account.name
        self._plugin = plugin
        self._omemo = self._plugin.get_omemo(self._account)
        self._own_jid = app.get_jid_from_account(self._account)
        self._show_inactive = False

        path = self._plugin.local_file_path('gtk/key.ui')
        self._ui = get_builder(path)

        self._ui.header.set_text(_('Fingerprints for %s') % self._contact.jid)

        omemo_img_path = self._plugin.local_file_path('omemo.png')
        self._ui.omemo_image.set_from_file(omemo_img_path)

        self._ui.list.set_filter_func(self._filter_func, None)
        self._ui.list.set_sort_func(self._sort_func, None)

        self._identity_key = self._omemo.backend.storage.getIdentityKeyPair()
        ownfpr_format = get_fingerprint(self._identity_key, formatted=True)
        self._ui.own_fingerprint.set_text(ownfpr_format)

        self.get_content_area().add(self._ui.grid)

        self.update()
        self._load_qrcode()
        self._ui.connect_signals(self)
        self.connect('destroy', self._on_destroy)
        self.show_all()
Example #30
0
    def _add_jid(self, jid, type_):
        # check if jid is conform to RFC and stringprep it
        try:
            jid = helpers.parse_jid(jid)
        except helpers.InvalidFormat as s:
            pritext = _('Invalid User ID')
            ErrorDialog(pritext, str(s))
            return

        # No resource in jid
        if jid.find('/') >= 0:
            pritext = _('Invalid User ID')
            ErrorDialog(pritext, _('The user ID must not contain a resource.'))
            return

        if jid == app.get_jid_from_account(self.account):
            pritext = _('Invalid User ID')
            ErrorDialog(pritext,
                        _('You cannot add yourself to your contact list.'))
            return

        if not app.account_is_connected(self.account):
            ErrorDialog(_('Account Offline'),
                        _('Your account must be online to add new contacts.'))
            return

        nickname = self.nickname_entry.get_text() or ''
        # get value of account combobox, if account was not specified
        if not self.account:
            model = self.account_combobox.get_model()
            index = self.account_combobox.get_active()
            self.account = model[index][1]

        # Check if jid is already in roster
        if jid in app.contacts.get_jid_list(self.account):
            c = app.contacts.get_first_contact_from_jid(self.account, jid)
            if _('Not in contact list') not in c.groups and c.sub in ('both',
                                                                      'to'):
                ErrorDialog(_('Contact Already in Contact List'),
                            _('This contact is already in your contact list.'))
                return

        if type_ == 'jabber':
            message_buffer = self.message_textview.get_buffer()
            start_iter = message_buffer.get_start_iter()
            end_iter = message_buffer.get_end_iter()
            message = message_buffer.get_text(start_iter, end_iter, True)
            if self.save_message_checkbutton.get_active():
                msg = helpers.to_one_line(message)
                app.config.set_per('accounts', self.account,
                                   'subscription_request_msg', msg)
        else:
            message = ''
        group = self.group_comboboxentry.get_child().get_text()
        groups = []
        if group:
            groups = [group]
        auto_auth = self.auto_authorize_checkbutton.get_active()
        app.interface.roster.req_sub(self,
                                     jid,
                                     message,
                                     self.account,
                                     groups=groups,
                                     nickname=nickname,
                                     auto_auth=auto_auth)
        self.destroy()