def disconnect(self, reconnect=True, immediately=True): log.info('Start disconnecting zeroconf') if reconnect: if app.account_is_connected(self.name): # we cannot change our status to offline or connecting # after we auth to server self.old_show = STATUS_LIST[self.connected] # random number to show we wait network manager to send # us a reconenct self.time_to_reconnect = 5 else: self.time_to_reconnect = None self.connected = 0 if self.connection: self.connection.disconnect() self.connection = None # stop calling the timeout self.call_resolve_timeout = False app.nec.push_incoming_event(OurShowEvent(None, conn=self, show='offline'))
def join_room(self, room_jid, nick, password, account): if not account: # get the first connected account accounts = app.connections.keys() for acct in accounts: if app.account_is_connected(acct): if not app.connections[acct].is_zeroconf: account = acct break if not account: return if app.connections[account].is_zeroconf: # zeroconf not support groupchats return if not nick: nick = '' app.interface.instances[account]['join_gc'] = \ JoinGroupchatWindow(account, room_jid, nick) else: app.interface.join_gc_room(account, room_jid, nick, password)
def set_priority(self, prio, account): """ set_priority(prio, account). Account is optional - if not specified priority is changed for all accounts. That are synced with global status """ if account: app.config.set_per('accounts', account, 'priority', prio) show = app.SHOW_LIST[app.connections[account].connected] status = app.connections[account].status GLib.idle_add(app.connections[account].change_status, show, status) else: # account not specified, so change prio of all accounts for acc in app.contacts.get_accounts(): if not app.account_is_connected(acc): continue if not app.config.get_per('accounts', acc, 'sync_with_global_status'): continue app.config.set_per('accounts', acc, 'priority', prio) show = app.SHOW_LIST[app.connections[acc].connected] status = app.connections[acc].status GLib.idle_add(app.connections[acc].change_status, show, status)
def subscribe(self, jid, msg=None, name='', groups=None, auto_auth=False): if not app.account_is_connected(self._account): return if groups is None: groups = [] self._log.info('Request Subscription to %s', jid) if auto_auth: self.jids_for_auto_auth.append(jid) infos = {'jid': jid} if name: infos['name'] = name iq = nbxmpp.Iq('set', nbxmpp.NS_ROSTER) query = iq.setQuery() item = query.addChild('item', attrs=infos) for group in groups: item.addChild('group').setData(group) self._con.connection.send(iq) self.send_presence(jid, 'subscribe', status=msg)
def send_file_approval(self, file_props): """ Send iq, confirming that we want to download the file """ # user response to ConfirmationDialog may come after we've disconneted if not app.account_is_connected(self._account): return # file transfer initiated by a jingle session log.info("send_file_approval: jingle session accept") session = self._con.get_module('Jingle').get_jingle_session( file_props.sender, file_props.sid) if not session: return content = None for content_ in session.contents.values(): if content_.transport.sid == file_props.transport_sid: content = content_ break if not content: return if not session.accepted: content = session.get_content('file', content.name) if content.use_security: fingerprint = content.x509_fingerprint if not jingle_xtls.check_cert( app.get_jid_without_resource(file_props.sender), fingerprint): id_ = jingle_xtls.send_cert_request( self._con, file_props.sender) jingle_xtls.key_exchange_pend(id_, content.on_cert_received, []) return session.approve_session() session.approve_content('file', content.name)
def _relog(self, account): if not app.account_is_connected(account): return if account == app.ZEROCONF_ACC_NAME: app.connections[app.ZEROCONF_ACC_NAME].update_details() return def relog(): app.connections[account].disconnect(gracefully=True, reconnect=True, destroy_client=True) ConfirmationDialog( _('Re-Login'), _('Re-Login now?'), _('To apply all changes instantly, you have to re-login.'), [ DialogButton.make('Cancel', text=_('_Later')), DialogButton.make( 'Accept', text=_('_Re-Login'), callback=relog) ], transient_for=self).show()
def _on_send(self, *args): if not app.account_is_connected(self.account): # If offline or connecting ErrorDialog( _('Connection not available'), _('Please make sure you are connected with \'%s\'.') % self.account) return buffer_ = self._ui.input_entry.get_buffer() begin_iter, end_iter = buffer_.get_bounds() stanza = buffer_.get_text(begin_iter, end_iter, True) if stanza: try: node = nbxmpp.Protocol(node=stanza) if node.getNamespace() == UNDECLARED: node.setNamespace(nbxmpp.NS_CLIENT) except Exception as error: ErrorDialog(_('Invalid Node'), str(error)) return app.connections[self.account].connection.send(node) self.last_stanza = stanza buffer_.set_text('')
def _send_socks5_info(self, file_props): """ Send iq for the present streamhosts and proxies """ if not app.account_is_connected(self._account): return receiver = file_props.receiver sender = file_props.sender sha_str = helpers.get_auth_sha(file_props.sid, sender, receiver) file_props.sha_str = sha_str port = app.config.get('file_transfers_port') listener = app.socks5queue.start_listener(port, sha_str, self._result_socks5_sid, file_props) if not listener: file_props.error = -5 app.nec.push_incoming_event( NetworkEvent('file-request-error', conn=self._con, jid=app.get_jid_without_resource(receiver), file_props=file_props, error_msg='')) self._connect_error(file_props.sid, error='not-acceptable', error_type='modify') else: iq = nbxmpp.Iq(to=receiver, typ='set') file_props.request_id = 'id_' + file_props.sid iq.setID(file_props.request_id) query = iq.setTag('query', namespace=nbxmpp.NS_BYTESTREAM) query.setAttr('sid', file_props.sid) self._add_addiditional_streamhosts_to_query(query, file_props) self._add_local_ips_as_streamhosts_to_query(query, file_props) self._add_proxy_streamhosts_to_query(query, file_props) self._add_upnp_igd_as_streamhost_to_query(query, file_props, iq)
def _disco(self, namespace, jid, node, success_cb, error_cb): if success_cb is None: raise ValueError('success_cb is required') if not app.account_is_connected(self._account): return iq = nbxmpp.Iq(typ='get', to=jid, queryNS=namespace) if node: iq.setQuerynode(node) log_str = 'Request info: %s %s' if namespace == nbxmpp.NS_DISCO_ITEMS: log_str = 'Request items: %s %s' log.info(log_str, jid, node or '') # Create weak references so we can pass GUI object methods weak_success_cb = weakref.WeakMethod(success_cb) if error_cb is not None: weak_error_cb = weakref.WeakMethod(error_cb) else: weak_error_cb = None self._con.connection.SendAndCallForResponse( iq, self._disco_response, {'success_cb': weak_success_cb, 'error_cb': weak_error_cb})
def on_ok_button_clicked(self, widget): if self.update_progressbar_timeout_id: # Operation in progress return if not app.account_is_connected(self.account): ErrorDialog( _('You are not connected to the server'), _('Without a connection, you can not publish your contact ' 'information.'), transient_for=self) return vcard_, sha = self.make_vcard() nick = vcard_.get('NICKNAME') or None app.connections[self.account].get_module('UserNickname').set_nickname(nick) if not nick: nick = app.config.get_per('accounts', self.account, 'name') app.nicks[self.account] = nick app.connections[self.account].get_module('VCardTemp').send_vcard( vcard_, sha) self.message_id = self.statusbar.push( self.context_id, _('Sending profile…')) self.progressbar.show() self.update_progressbar_timeout_id = GLib.timeout_add( 100, self.update_progressbar)
def _avatar_publish_result(self, _con, stanza, sha): if stanza.getType() == 'result': current_sha = app.config.get_per('accounts', self._account, 'avatar_sha') if (current_sha != sha and not app.is_invisible(self._account)): if not app.account_is_connected(self._account): return app.config.set_per('accounts', self._account, 'avatar_sha', sha or '') own_jid = self._con.get_own_jid().getStripped() app.contacts.set_avatar(self._account, own_jid, sha) app.interface.update_avatar( self._account, self._con.get_own_jid().getStripped()) self._con.get_module('VCardAvatars').send_avatar_presence( after_publish=True) self._log.info('%s: Published: %s', self._account, sha) self._con.get_module('MUC').update_presence() app.nec.push_incoming_event( NetworkEvent('vcard-published', account=self._account)) elif stanza.getType() == 'error': app.nec.push_incoming_event( NetworkEvent('vcard-not-published', account=self._account))
def make_menu(self, event_button, event_time): """ Create chat with and new message (sub) menus/menuitems """ for m in self.popup_menus: m.destroy() chat_with_menuitem = self.xml.get_object('chat_with_menuitem') single_message_menuitem = self.xml.get_object( 'single_message_menuitem') status_menuitem = self.xml.get_object('status_menu') join_gc_menuitem = self.xml.get_object('join_gc_menuitem') sounds_mute_menuitem = self.xml.get_object('sounds_mute_menuitem') show_roster_menuitem = self.xml.get_object('show_roster_menuitem') if self.single_message_handler_id: single_message_menuitem.handler_disconnect( self.single_message_handler_id) self.single_message_handler_id = None if self.new_chat_handler_id: chat_with_menuitem.disconnect(self.new_chat_handler_id) self.new_chat_handler_id = None sub_menu = Gtk.Menu() self.popup_menus.append(sub_menu) status_menuitem.set_submenu(sub_menu) gc_sub_menu = Gtk.Menu() # gc is always a submenu join_gc_menuitem.set_submenu(gc_sub_menu) # We need our own set of status icons, let's make 'em! iconset = app.config.get('iconset') path = os.path.join(helpers.get_iconset_path(iconset), '16x16') for show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'): uf_show = helpers.get_uf_show(show, use_mnemonic=True) item = Gtk.MenuItem.new_with_mnemonic(uf_show) sub_menu.append(item) item.connect('activate', self.on_show_menuitem_activate, show) item = Gtk.SeparatorMenuItem.new() sub_menu.append(item) item = Gtk.MenuItem.new_with_mnemonic(_('_Change Status Message…')) sub_menu.append(item) item.connect('activate', self.on_change_status_message_activate) connected_accounts = app.get_number_of_connected_accounts() if connected_accounts < 1: item.set_sensitive(False) connected_accounts_with_private_storage = 0 item = Gtk.SeparatorMenuItem.new() sub_menu.append(item) uf_show = helpers.get_uf_show('offline', use_mnemonic=True) item = Gtk.MenuItem.new_with_mnemonic(uf_show) sub_menu.append(item) item.connect('activate', self.on_show_menuitem_activate, 'offline') iskey = connected_accounts > 0 and not (connected_accounts == 1 and app.zeroconf_is_connected()) chat_with_menuitem.set_sensitive(iskey) single_message_menuitem.set_sensitive(iskey) join_gc_menuitem.set_sensitive(iskey) accounts_list = sorted(app.contacts.get_accounts()) # items that get shown whether an account is zeroconf or not if connected_accounts > 1: # 2 or more connections? make submenus account_menu_for_chat_with = Gtk.Menu() chat_with_menuitem.set_submenu(account_menu_for_chat_with) self.popup_menus.append(account_menu_for_chat_with) for account in accounts_list: account_label = app.config.get_per('accounts', account, 'account_label') or account if app.account_is_connected(account): # for chat_with item = Gtk.MenuItem.new_with_label( _('using account %s') % account_label) account_menu_for_chat_with.append(item) item.connect('activate', self.on_new_chat, account) elif connected_accounts == 1: # one account # one account connected, no need to show 'as jid' for account in app.connections: if app.connections[account].connected > 1: # for start chat self.new_chat_handler_id = chat_with_menuitem.connect( 'activate', self.on_new_chat, account) break # No other connected account # menu items that don't apply to zeroconf connections if connected_accounts == 1 or (connected_accounts == 2 and \ app.zeroconf_is_connected()): # only one 'real' (non-zeroconf) account is connected, don't need # submenus for account in app.connections: if app.account_is_connected(account) and \ not app.config.get_per('accounts', account, 'is_zeroconf'): if app.connections[account].private_storage_supported: connected_accounts_with_private_storage += 1 # for single message single_message_menuitem.set_submenu(None) self.single_message_handler_id = single_message_menuitem.\ connect('activate', self.on_single_message_menuitem_activate, account) # join gc app.interface.roster.add_bookmarks_list( gc_sub_menu, account) break # No other account connected else: # 2 or more 'real' accounts are connected, make submenus account_menu_for_single_message = Gtk.Menu() single_message_menuitem.set_submenu( account_menu_for_single_message) self.popup_menus.append(account_menu_for_single_message) for account in accounts_list: account_label = app.config.get_per('accounts', account, 'account_label') or account if app.connections[account].is_zeroconf or \ not app.account_is_connected(account): continue if app.connections[account].private_storage_supported: connected_accounts_with_private_storage += 1 # for single message item = Gtk.MenuItem.new_with_label( _('using account %s') % account_label) item.connect('activate', self.on_single_message_menuitem_activate, account) account_menu_for_single_message.append(item) # join gc gc_item = Gtk.MenuItem.new_with_label( _('using account %s') % account_label) gc_sub_menu.append(gc_item) gc_menuitem_menu = Gtk.Menu() app.interface.roster.add_bookmarks_list( gc_menuitem_menu, account) gc_item.set_submenu(gc_menuitem_menu) gc_sub_menu.show_all() newitem = Gtk.SeparatorMenuItem.new() # separator gc_sub_menu.append(newitem) newitem = Gtk.MenuItem.new_with_mnemonic(_('_Manage Bookmarks…')) newitem.connect( 'activate', app.interface.roster.on_manage_bookmarks_menuitem_activate) gc_sub_menu.append(newitem) if connected_accounts_with_private_storage == 0: newitem.set_sensitive(False) sounds_mute_menuitem.set_active(not app.config.get('sounds_on')) win = app.interface.roster.window if self.show_roster_handler_id: show_roster_menuitem.handler_disconnect( self.show_roster_handler_id) if win.get_property('has-toplevel-focus'): show_roster_menuitem.get_children()[0].set_label(_('Hide _Roster')) self.show_roster_handler_id = show_roster_menuitem.connect( 'activate', self.on_hide_roster_menuitem_activate) else: show_roster_menuitem.get_children()[0].set_label(_('Show _Roster')) self.show_roster_handler_id = show_roster_menuitem.connect( 'activate', self.on_show_roster_menuitem_activate) if os.name == 'nt': if self.added_hide_menuitem is False: self.systray_context_menu.prepend(Gtk.SeparatorMenuItem.new()) item = Gtk.MenuItem.new_with_label(_('Hide this menu')) self.systray_context_menu.prepend(item) self.added_hide_menuitem = True self.systray_context_menu.show_all() self.systray_context_menu.popup(None, None, None, None, 0, event_time)
def func_wrapper(self, *args, **kwargs): # pylint: disable=protected-access if not app.account_is_connected(self._account): self._stored_publish = partial(func, self, *args, **kwargs) return None return func(self, *args, **kwargs)
def update_contact(self, jid, name, groups): if app.account_is_connected(self._account): self.set_item(jid=jid, name=name, groups=groups)
def quit(self, kill_core): if kill_core and app.account_is_connected(self.name): self.disconnect(reconnect=False)
def _make_menu(self, _event_button, event_time): """ Create chat with and new message (sub) menus/menuitems """ for menu in self.popup_menus: menu.destroy() start_chat_menuitem = self._ui.start_chat_menuitem single_message_menuitem = self._ui.single_message_menuitem status_menuitem = self._ui.status_menu sounds_mute_menuitem = self._ui.sounds_mute_menuitem show_roster_menuitem = self._ui.show_roster_menuitem if self._single_message_handler_id: single_message_menuitem.handler_disconnect( self._single_message_handler_id) self._single_message_handler_id = None sub_menu = Gtk.Menu() self.popup_menus.append(sub_menu) status_menuitem.set_submenu(sub_menu) for show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'): uf_show = helpers.get_uf_show(show, use_mnemonic=True) item = Gtk.MenuItem.new_with_mnemonic(uf_show) sub_menu.append(item) item.connect('activate', self._on_show, show) item = Gtk.SeparatorMenuItem.new() sub_menu.append(item) item = Gtk.MenuItem.new_with_mnemonic(_('_Change Status Message…')) sub_menu.append(item) item.connect('activate', self._on_change_status) connected_accounts = app.get_number_of_connected_accounts() if connected_accounts < 1: item.set_sensitive(False) item = Gtk.SeparatorMenuItem.new() sub_menu.append(item) uf_show = helpers.get_uf_show('offline', use_mnemonic=True) item = Gtk.MenuItem.new_with_mnemonic(uf_show) sub_menu.append(item) item.connect('activate', self._on_show, 'offline') is_zeroconf = connected_accounts == 1 and app.zeroconf_is_connected() iskey = connected_accounts > 0 and not is_zeroconf start_chat_menuitem.set_sensitive(iskey) single_message_menuitem.set_sensitive(iskey) accounts_list = sorted(app.contacts.get_accounts()) # menu items that don't apply to zeroconf connections if connected_accounts == 1 or (connected_accounts == 2 and \ app.zeroconf_is_connected()): # only one 'real' (non-zeroconf) account is connected, don't need # submenus for account in app.connections: if app.account_is_connected(account) and \ not app.config.get_per('accounts', account, 'is_zeroconf'): # for single message single_message_menuitem.set_submenu(None) self._single_message_handler_id = single_message_menuitem.\ connect('activate', self._on_single_message, account) break # No other account connected else: # 2 or more 'real' accounts are connected, make submenus account_menu_for_single_message = Gtk.Menu() single_message_menuitem.set_submenu( account_menu_for_single_message) self.popup_menus.append(account_menu_for_single_message) for account in accounts_list: account_label = app.get_account_label(account) if app.connections[account].is_zeroconf or \ not app.account_is_connected(account): continue # for single message item = Gtk.MenuItem.new_with_label( _('using account %s') % account_label) item.connect('activate', self._on_single_message, account) account_menu_for_single_message.append(item) sounds_mute_menuitem.set_active(not app.config.get('sounds_on')) win = app.interface.roster.window if self._show_roster_handler_id: show_roster_menuitem.handler_disconnect( self._show_roster_handler_id) if win.get_property('has-toplevel-focus'): show_roster_menuitem.get_children()[0].set_label( _('Hide _Contact List')) self._show_roster_handler_id = show_roster_menuitem.connect( 'activate', self._on_hide_roster) else: show_roster_menuitem.get_children()[0].set_label( _('Show _Contact List')) self._show_roster_handler_id = show_roster_menuitem.connect( 'activate', self._on_show_roster) if os.name == 'nt': if self.added_hide_menuitem is False: self.systray_context_menu.prepend(Gtk.SeparatorMenuItem.new()) item = Gtk.MenuItem.new_with_label(_('Hide this menu')) self.systray_context_menu.prepend(item) self.added_hide_menuitem = True self.systray_context_menu.show_all() self.systray_context_menu.popup(None, None, None, None, 0, event_time)
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()
def populate(self, contacts, account, typ): """ Populate the Tooltip Grid with data of from the contact """ self.current_row = 0 self.account = account if self.last_widget: self.last_widget.set_vexpand(False) self.clear_tooltip() if account == 'all': # Tooltip for merged accounts row accounts = helpers.get_notification_icon_tooltip_dict() self.spacer_label = '' self.fill_table_with_accounts(accounts) self.tooltip_grid.attach(self.table, 0, 3, 2, 1) self.table.show_all() return if typ == 'account': jid = app.get_jid_from_account(account) contacts = [] connection = app.connections[account] # get our current contact info nbr_on, nbr_total = app.\ contacts.get_nb_online_total_contacts( accounts=[account]) account_name = account if app.account_is_connected(account): account_name += ' (%s/%s)' % (repr(nbr_on), repr(nbr_total)) contact = app.contacts.create_self_contact(jid=jid, account=account, name=account_name, show=connection.get_status(), status=connection.status, resource=connection.server_resource, priority=connection.priority) if app.connections[account].gpg: contact.keyID = app.config.get_per('accounts', connection.name, 'keyid') contacts.append(contact) # if we're online ... if connection.connection: roster = connection.connection.getRoster() # in threadless connection when no roster stanza is sent # 'roster' is None if roster and roster.getItem(jid): resources = roster.getResources(jid) # ...get the contact info for our other online # resources for resource in resources: # Check if we already have this resource found = False for contact_ in contacts: if contact_.resource == resource: found = True break if found: continue show = roster.getShow(jid + '/' + resource) if not show: show = 'online' contact = app.contacts.create_self_contact( jid=jid, account=account, show=show, status=roster.getStatus( jid + '/' + resource), priority=roster.getPriority( jid + '/' + resource), resource=resource) contacts.append(contact) # Username/Account/Groupchat self.prim_contact = app.contacts.get_highest_prio_contact_from_contacts( contacts) self.contact_jid = self.prim_contact.jid name = GLib.markup_escape_text(self.prim_contact.get_shown_name()) name_markup = '<b>{}</b>'.format(name) if app.config.get('mergeaccounts'): color = app.config.get('tooltip_account_name_color') account_name = GLib.markup_escape_text(self.prim_contact.account.name) name_markup += " <span foreground='{}'>({})</span>".format( color, account_name) if account and helpers.jid_is_blocked(account, self.prim_contact.jid): name_markup += _(' [blocked]') try: if self.prim_contact.jid in app.interface.minimized_controls[account]: name_markup += _(' [minimized]') except KeyError: pass self.name.set_markup(name_markup) self.name.show() self.num_resources = 0 # put contacts in dict, where key is priority contacts_dict = {} for contact in contacts: if contact.resource: self.num_resources += 1 priority = int(contact.priority) if priority in contacts_dict: contacts_dict[priority].append(contact) else: contacts_dict[priority] = [contact] if self.num_resources > 1: self.status_label.show() transport = app.get_transport_name_from_jid(self.prim_contact.jid) if transport: file_path = os.path.join(helpers.get_transport_path(transport), '16x16') else: iconset = app.config.get('iconset') if not iconset: iconset = 'dcraven' file_path = os.path.join(helpers.get_iconset_path(iconset), '16x16') contact_keys = sorted(contacts_dict.keys()) contact_keys.reverse() for priority in contact_keys: for acontact in contacts_dict[priority]: icon_name = self._get_icon_name_for_tooltip(acontact) if acontact.status and len(acontact.status) > 25: status = '' add_text = True else: status = acontact.status add_text = False status_line = self.get_status_info(acontact.resource, acontact.priority, acontact.show, status) self.add_status_row(file_path, icon_name, status_line) if add_text: self.add_text_row(acontact.status, 2) self.tooltip_grid.attach(self.table, 0, 3, 2, 1) self.table.show_all() else: # only one resource if contact.show and contact.status: status = contact.status.strip() if status: self.status.set_text(status) self.status.show() self.status_label.show() # PEP Info self._append_pep_info(contact) # JID self.jid.set_text(self.prim_contact.jid) self.jid.show() self.jid_label.show() # contact has only one ressource if self.num_resources == 1 and contact.resource: res = GLib.markup_escape_text(contact.resource) prio = str(contact.priority) self.resource.set_text("{} ({})".format(res, prio)) self.resource.show() self.resource_label.show() if self.prim_contact.jid not in app.gc_connected[account]: if (account and self.prim_contact.sub and self.prim_contact.sub != 'both'): # ('both' is the normal sub so we don't show it) self.sub.set_text(helpers.get_uf_sub(self.prim_contact.sub)) self.sub.show() self.sub_label.show() if self.prim_contact.keyID: keyID = None if len(self.prim_contact.keyID) == 8: keyID = self.prim_contact.keyID elif len(self.prim_contact.keyID) == 16: keyID = self.prim_contact.keyID[8:] if keyID: self.pgp.set_text(keyID) self.pgp.show() self.pgp_label.show() self._set_idle_time(contact) # Avatar pixbuf = app.contacts.get_avatar( account, self.prim_contact.jid, AvatarSize.TOOLTIP) if pixbuf is None: return self.avatar.set_from_pixbuf(pixbuf) self.avatar.show() # Sets the Widget that is at the bottom to expand. # This is needed in case the Picture takes more Space then the Labels i = 1 while i < 15: if self.tooltip_grid.get_child_at(0, i): if self.tooltip_grid.get_child_at(0, i).get_visible(): self.last_widget = self.tooltip_grid.get_child_at(0, i) i += 1 self.last_widget.set_vexpand(True)
def _nec_our_status(self, obj): if app.account_is_connected(obj.conn.name): self._withdraw('connection-failed', obj.conn.name)
def create(self, muc_data): if not app.account_is_connected(self._account): return self._manager.add(muc_data) self._create(muc_data)
def _populate_grid(self, contacts, account, typ): """ Populate the Tooltip Grid with data of from the contact """ self.current_row = 0 self.account = account if self.last_widget: self.last_widget.set_vexpand(False) self.clear_tooltip() if account == 'all': # Tooltip for merged accounts row accounts = helpers.get_notification_icon_tooltip_dict() self.spacer_label = '' self.fill_table_with_accounts(accounts) self._ui.tooltip_grid.attach(self.table, 1, 3, 2, 1) self.table.show_all() return if typ == 'account': jid = app.get_jid_from_account(account) contacts = [] connection = app.connections[account] # get our current contact info nbr_on, nbr_total = app.\ contacts.get_nb_online_total_contacts(accounts=[account]) account_name = app.get_account_label(account) if app.account_is_connected(account): account_name += ' (%s/%s)' % (repr(nbr_on), repr(nbr_total)) contact = app.contacts.create_self_contact( jid=jid, account=account, name=account_name, show=connection.get_status(), status=connection.status, resource=connection.server_resource, priority=connection.priority) contacts.append(contact) # Username/Account/Groupchat self.prim_contact = app.contacts.get_highest_prio_contact_from_contacts( contacts) if self.prim_contact is None: log.error('No contact for Roster tooltip found') log.error('contacts: %s, typ: %s, account: %s', contacts, typ, account) return self.contact_jid = self.prim_contact.jid name = GLib.markup_escape_text(self.prim_contact.get_shown_name()) name_markup = '<b>{}</b>'.format(name) if app.config.get('mergeaccounts'): color = app.config.get('tooltip_account_name_color') account_name = GLib.markup_escape_text(self.prim_contact.account.name) name_markup += " <span foreground='{}'>({})</span>".format( color, account_name) if account and helpers.jid_is_blocked(account, self.prim_contact.jid): name_markup += _(' [blocked]') try: if self.prim_contact.jid in app.interface.minimized_controls[account]: name_markup += _(' [minimized]') except KeyError: pass self._ui.name.set_markup(name_markup) self._ui.name.show() self.num_resources = 0 # put contacts in dict, where key is priority contacts_dict = {} for contact in contacts: if contact.resource: self.num_resources += 1 priority = int(contact.priority) if priority in contacts_dict: contacts_dict[priority].append(contact) else: contacts_dict[priority] = [contact] if self.num_resources > 1: transport = app.get_transport_name_from_jid(self.prim_contact.jid) if transport == 'jabber': transport = None contact_keys = sorted(contacts_dict.keys()) contact_keys.reverse() for priority in contact_keys: for acontact in contacts_dict[priority]: show = self._get_icon_name_for_tooltip(acontact) if acontact.status and len(acontact.status) > 25: status = '' add_text = True else: status = acontact.status add_text = False status_line = self.get_status_info( acontact.resource, acontact.priority, acontact.show, status) self.add_status_row(show, status_line, transport=transport) if add_text: self.add_text_row(acontact.status, 2) self._ui.tooltip_grid.attach(self.table, 1, 3, 2, 1) self.table.show_all() else: # only one resource if contact.show and contact.status: status = contact.status.strip() if status: self._ui.status.set_text(status) self._ui.status.show() # PEP Info self._append_pep_info(contact) # JID self._ui.jid.set_text(self.prim_contact.jid) self._ui.jid.show() # contact has only one resource if self.num_resources == 1 and contact.resource: res = GLib.markup_escape_text(contact.resource) prio = str(contact.priority) self._ui.resource.set_text("{} ({})".format(res, prio)) self._ui.resource.show() self._ui.resource_label.show() if self.prim_contact.jid not in app.gc_connected[account]: if (account and self.prim_contact.sub and self.prim_contact.sub != 'both'): # ('both' is the normal sub so we don't show it) self._ui.sub.set_text(helpers.get_uf_sub(self.prim_contact.sub)) self._ui.sub.show() self._ui.sub_label.show() self._set_idle_time(contact) # Avatar scale = self._ui.tooltip_grid.get_scale_factor() surface = app.contacts.get_avatar( account, self.prim_contact.jid, AvatarSize.TOOLTIP, scale) self._ui.avatar.set_from_surface(surface) self._ui.avatar.show() app.plugin_manager.gui_extension_point( 'roster_tooltip_populate', self, contacts, self._ui.tooltip_grid) # Sets the Widget that is at the bottom to expand. # This is needed in case the Picture takes more Space than the Labels i = 1 while i < 15: if self._ui.tooltip_grid.get_child_at(1, i): if self._ui.tooltip_grid.get_child_at(1, i).get_visible(): self.last_widget = self._ui.tooltip_grid.get_child_at(1, i) i += 1 self.last_widget.set_vexpand(True)
def _nec_our_status(self, event): if app.account_is_connected(event.account): self._withdraw('connection-failed', event.account)
def func_wrapper(self, *args, **kwargs): if not app.account_is_connected(self._account): self._stored_publish = partial(func, self, *args, **kwargs) return return func(self, *args, **kwargs)
def _on_join_clicked(self, *args): account = self.account_combo.get_active_id() nickname = self.nick_entry.get_text() if app.is_invisible(account): app.interface.raise_dialog('join-while-invisible') return server = self.server_combo.get_active_text() room = self.room_entry.get_text() if room == '': ErrorDialog(_('Invalid Group Chat'), _('Please choose a group chat'), transient_for=self) return self.room_jid = '%s@%s' % (room, server) try: self.room_jid = helpers.parse_jid(self.room_jid) except helpers.InvalidFormat as error: ErrorDialog(_('Invalid XMPP Address'), str(error), transient_for=self) return if app.in_groupchat(account, self.room_jid): # If we already in the groupchat, join_gc_room will bring # it to front app.interface.join_gc_room(account, self.room_jid, nickname, '') self.destroy() return if nickname == '': ErrorDialog(_('Invalid Nickname'), _('Please choose a nickname'), transient_for=self) return try: helpers.parse_resource(nickname) except helpers.InvalidFormat as error: ErrorDialog(_('Invalid Nickname'), str(error), transient_for=self) return if not app.account_is_connected(account): ErrorDialog( _('You are not connected to the server'), _('You can not join a group chat unless you are connected.'), transient_for=self) return password = self.password_entry.get_text() self._add_bookmark(account, nickname, password) app.add_recent_groupchat(account, self.room_jid, nickname) if self.automatic: app.automatic_rooms[self.account][self.room_jid] = self.automatic app.interface.join_gc_room(account, self.room_jid, nickname, password) self.destroy()
def send_single_message(self): if not app.account_is_connected(self.account): # if offline or connecting ErrorDialog( _('Connection not available'), _('Please make sure you are connected with "%s".') % self.account) return True if isinstance(self.to, list): sender_list = [] for i in self.to: if i[0].resource: sender_list.append(i[0].jid + '/' + i[0].resource) else: sender_list.append(i[0].jid) else: sender_list = [ j.strip() for j in self._ui.to_entry.get_text().split(',') ] subject = self._ui.subject_entry.get_text() begin, end = self.message_tv_buffer.get_bounds() message = self.message_tv_buffer.get_text(begin, end, True) if self.form_widget: form_node = self.form_widget.get_submit_form() else: form_node = None recipient_list = [] for to_whom_jid in sender_list: if to_whom_jid in self.completion_dict: to_whom_jid = self.completion_dict[to_whom_jid].jid try: to_whom_jid = helpers.parse_jid(to_whom_jid) except helpers.InvalidFormat: ErrorDialog( _('Invalid XMPP Address'), _('It is not possible to send a message to %s, this ' 'XMPP Address is not valid.') % to_whom_jid) return True if '/announce/' in to_whom_jid: con = app.connections[self.account] con.get_module('Announce').set_announce( to_whom_jid, subject, message) continue recipient_list.append(to_whom_jid) app.nec.push_outgoing_event( MessageOutgoingEvent(None, account=self.account, jid=recipient_list, message=message, type_='normal', subject=subject, form_node=form_node)) self._ui.subject_entry.set_text('') # we sent ok, clear the subject self.message_tv_buffer.set_text('') # we sent ok, clear the textview
def unsubscribed(self, jid): if not app.account_is_connected(self._account): return self._log.info('Unsubscribed: %s', jid) self.send_presence(jid, 'unsubscribed')
def set_subject(self, room_jid, subject): if not app.account_is_connected(self._account): return message = nbxmpp.Message(room_jid, typ='groupchat', subject=subject) log.info('Set subject for %s', room_jid) self._con.connection.send(message)
def update_contacts(self, contacts): """ Update multiple roster items """ if app.account_is_connected(self._account): self.set_item_multi(contacts)
def send_pep(self): accounts = app.connections.keys() for account in accounts: if app.account_is_connected(account): self.roster.send_pep(account, self.pep_dict)
def request_last_activity(self): if not app.account_is_connected(self.account): return con = app.connections[self.account] iq = nbxmpp.Iq(to=self.hostname, typ='get', queryNS=nbxmpp.NS_LAST) con.connection.SendAndCallForResponse(iq, self._on_last_activity)