def _event_dispatcher(self, realm, event, data): CommonConnection._event_dispatcher(self, realm, event, data) if realm == '': if event == nbxmpp.transports.DATA_ERROR: thread_id = data[1] frm = data[0] session = self.get_or_create_session(frm, thread_id) error_message = _( 'Connection to host could not be established: ' 'Timeout while sending data.') app.nec.push_incoming_event( MessageErrorEvent(None, conn=self, fjid=frm, error_code=-1, error_msg=error_message, msg=None, time_=None, session=session, zeroconf=True))
def __init__(self): Page.__init__(self) self.complete = False self.title = _('Create New Account') self._ui = get_builder('account_wizard.ui') self._ui.server_comboboxtext_sign_up_entry.set_activates_default(True) self._create_server_completion() self._ui.recommendation_link1.connect('activate-link', self._on_activate_link) self._ui.recommendation_link2.connect('activate-link', self._on_activate_link) self._ui.visit_server_button.connect('clicked', self._on_visit_server) self._ui.server_comboboxtext_sign_up_entry.connect( 'changed', self._set_complete) self.pack_start(self._ui.signup_grid, True, True, 0) self.show_all()
def fill_contact_page(self): self.xml.get_object('nickname_label').set_markup( '<b><span size="x-large">' + self.contact.get_shown_name() + '</span></b>') self.xml.get_object('local_jid_label').set_text(self.contact.jid) resources = '%s (%s)' % (self.contact.resource, str( self.contact.priority)) uf_resources = self.contact.resource + _(' resource with priority ')\ + str(self.contact.priority) if not self.contact.status: self.contact.status = '' self.xml.get_object('resource_prio_label').set_text(resources) resource_prio_label_eventbox = self.xml.get_object( 'resource_prio_label_eventbox') resource_prio_label_eventbox.set_tooltip_text(uf_resources) self.fill_status_label()
def _on_add(self, *args): page_name = self._ui.stack.get_visible_child_name() if page_name == 'outcast': affiliation_edit, jid_edit = self._allowed_to_edit('outcast') text = None affiliation = 'outcast' else: affiliation_edit, jid_edit = self._allowed_to_edit('member') text = _('Member') affiliation = 'member' treeview = self._get_current_treeview() iter_ = treeview.get_model().append( [None, None, None, affiliation, text, affiliation_edit, jid_edit]) # Scroll to added row path = treeview.get_model().get_path(iter_) treeview.scroll_to_cell(path, None, False, 0, 0) treeview.get_selection().unselect_all() treeview.get_selection().select_path(path)
def generate(self): try: self.errnum = self.conn.connection.Connection.ssl_errnum except AttributeError: self.errnum = 0 # we don't have an errnum self.ssl_msg = '' if self.errnum > 0: self.ssl_msg = SSLError.get( self.errnum, _('Unknown SSL error: %d') % self.errnum) self.ssl_cert = '' self.ssl_fingerprint_sha1 = '' self.ssl_fingerprint_sha256 = '' if self.conn.connection.Connection.ssl_certificate: cert = self.conn.connection.Connection.ssl_certificate self.ssl_cert = OpenSSL.crypto.dump_certificate( OpenSSL.crypto.FILETYPE_PEM, cert).decode('utf-8') self.ssl_fingerprint_sha1 = cert.digest('sha1').decode('utf-8') self.ssl_fingerprint_sha256 = cert.digest('sha256').decode('utf-8') return True
def connect(self, show='online', msg=''): self.get_config_values_or_default() if not self.connection: self.connection = client_zeroconf.ClientZeroconf(self) if not zeroconf.test_zeroconf(): app.nec.push_incoming_event(OurShowEvent(None, conn=self, show='offline')) self.status = 'offline' app.nec.push_incoming_event(ConnectionLostEvent(None, conn=self, title=_('Could not connect to "%s"') % self.name, msg=_('Please check if Avahi or Bonjour is installed.'))) self.disconnect() return result = self.connection.connect(show, msg) if not result: app.nec.push_incoming_event(OurShowEvent(None, conn=self, show='offline')) self.status = 'offline' if result is False: app.nec.push_incoming_event(ConnectionLostEvent(None, conn=self, title=_('Could not start local service'), msg=_('Unable to bind to port %d.' % self.port))) else: # result is None app.nec.push_incoming_event(ConnectionLostEvent(None, conn=self, title=_('Could not start local service'), msg=_('Please check if avahi/bonjour-daemon is running.'))) self.disconnect() return else: self.connection.announce() self.roster = self.connection.getRoster() app.nec.push_incoming_event(NetworkEvent('roster-received', conn=self, roster=self.roster.copy(), received_from_server=True)) # display contacts already detected and resolved for jid in self.roster.keys(): app.nec.push_incoming_event(NetworkEvent( 'roster-info', conn=self, jid=jid, nickname=self.roster.getName(jid), sub='both', ask='no', groups=self.roster.getGroups(jid), avatar_sha=None)) self._on_presence(jid) self.connected = STATUS_LIST.index(show) # refresh all contacts data every five seconds self.call_resolve_timeout = True GLib.timeout_add_seconds(5, self._on_resolve_timeout) return True
def __init__(self, button_callback): Page.__init__(self) self.title = _('Add Account') self._button_callback = button_callback self._ui = get_builder('account_wizard.ui') self._ui.log_in_address_entry.connect('activate', self._on_address_entry_activate) self._ui.log_in_address_entry.connect('changed', self._on_address_changed) self._ui.log_in_password_entry.connect('changed', self._set_complete) self._ui.log_in_password_entry.connect( 'activate', self._on_password_entry_activate) self._create_server_completion() self._ui.log_in_button.connect('clicked', self._on_login) self._ui.sign_up_button.connect('clicked', self._on_signup) self.pack_start(self._ui.login_box, True, True, 0) self.show_all()
def on_ok(path_to_file): data, sha = app.interface.avatar_storage.prepare_for_publish( path_to_file) if sha is None: ErrorDialog(_('Could not load image'), transient_for=self) return scale = self.get_scale_factor() surface = app.interface.avatar_storage.surface_from_filename( sha, AvatarSize.VCARD, scale) button = self.xml.get_object('PHOTO_button') image = self.xml.get_object('PHOTO_image') image.set_from_surface(surface) button.show() text_button = self.xml.get_object('NOPHOTO_button') text_button.hide() self.avatar_sha = sha self.avatar_encoded = base64.b64encode(data).decode('utf-8') self.avatar_mime_type = 'image/png'
def __init__(self): Gtk.ApplicationWindow.__init__(self) self.set_name('ManageProxies') self.set_application(app.app) self.set_position(Gtk.WindowPosition.CENTER) self.set_default_size(500, -1) self.set_show_menubar(False) self.set_title(_('Manage Proxies')) self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.set_modal(True) self._ui = get_builder('manage_proxies.ui') self.add(self._ui.box) self._init_list() self._block_signal = False self.connect_after('key-press-event', self._on_key_press) self.connect('destroy', self._on_destroy) self._ui.connect_signals(self) self.show_all()
def _on_select_clicked(self, *args): model, iter_ = self._ui.account_view.get_selection().get_selected() if iter_ is not None: account = model[iter_][1] elif len(self._accounts) == 1: account = self._accounts[0][0] else: return selected_row = self._global_search_listbox.get_selected_row() if selected_row is None: return if not app.account_is_connected(account): self._show_error_page( _('You can not join a group chat ' 'unless you are connected.')) return self._redirected = False self._disco_muc(account, selected_row.jid)
class SuccessfulPage(Gtk.Box): type_ = Gtk.AssistantPageType.SUMMARY title = _('Registration successful') complete = True 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)
def _init_moods(self): self._ui.no_mood_button.set_mode(False) self._ui.no_mood_button.connect( 'clicked', self._on_mood_button_clicked, None) x_position = 1 y_position = 0 # Order them first moods = [] for mood in MOODS: moods.append(mood) moods.sort() for mood in moods: image = Gtk.Image.new_from_icon_name( 'mood-%s' % mood, Gtk.IconSize.MENU) self._mood_btns[mood] = Gtk.RadioButton() self._mood_btns[mood].join_group(self._ui.no_mood_button) self._mood_btns[mood].set_mode(False) self._mood_btns[mood].add(image) self._mood_btns[mood].set_relief(Gtk.ReliefStyle.NONE) self._mood_btns[mood].set_tooltip_text(MOODS[mood]) self._mood_btns[mood].connect( 'clicked', self._on_mood_button_clicked, mood) self._ui.moods_grid.attach( self._mood_btns[mood], x_position, y_position, 1, 1) # Calculate the next position x_position += 1 if x_position >= 11: x_position = 0 y_position += 1 if self._pep_dict['mood'] in MOODS: self._mood_btns[self._pep_dict['mood']].set_active(True) self._ui.mood_label.set_text(MOODS[self._pep_dict['mood']]) else: self._ui.mood_label.set_text(_('No mood selected'))
def __init__(self, account, connection, cert, error_num): Gtk.ApplicationWindow.__init__(self) self.set_name('SSLErrorDialog') self.set_application(app.app) self.set_show_menubar(False) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_title(_('SSL Certificate Verification Error')) self._ui = get_builder('ssl_error_dialog.ui') self.add(self._ui.ssl_error_box) self.account = account self._error_num = error_num self._con = connection self._cert = cert self._server = app.config.get_per('accounts', self.account, 'hostname') self._process_error() self._ui.connect_signals(self) self.show_all()
def _delete_logs(self, liststore, list_of_paths): paths_len = len(list_of_paths) if paths_len == 0: # nothing is selected return def on_ok(): # delete rows from db that match log_line_id list_of_rowrefs = [] for path in list_of_paths: # make them treerowrefs (it's needed) list_of_rowrefs.append( Gtk.TreeRowReference.new(liststore, path)) for rowref in list_of_rowrefs: path = rowref.get_path() if path is None: continue log_line_id = liststore[path][0] del liststore[path] # remove from UI # remove from db self.cur.execute( ''' DELETE FROM logs WHERE log_line_id = ? ''', (log_line_id, )) self.con.commit() self.AT_LEAST_ONE_DELETION_DONE = True NewConfirmationDialog( _('Delete'), ngettext('Delete Message', 'Delete Messages', paths_len), ngettext('Do you want to permanently delete this message', 'Do you want to permanently delete these messages', paths_len), [ DialogButton.make('Cancel'), DialogButton.make('Delete', callback=on_ok) ], transient_for=self._ui.history_manager_window).show()
def _create_service(self): txt = {} # remove empty keys for key, val in self.txt.items(): if val: txt[key] = val txt['port.p2pj'] = self.port txt['version'] = 1 txt['txtvers'] = 1 # replace gajim's show messages with compatible ones if 'status' in self.txt: txt['status'] = self._replace_show(self.txt['status']) else: txt['status'] = 'avail' self.txt = txt try: self._service_sdref = DNSServiceRegister( flags=kDNSServiceFlagsNoAutoRename, name=self.name, regtype=self.stype, port=self.port, txtRecord=TXTRecord(self.txt, strict=True), callBack=self.service_added_callback) log.info('Publishing service %s of type %s', self.name, self.stype) ready = select.select([self._service_sdref], [], []) if self._service_sdref in ready[0]: DNSServiceProcessResult(self._service_sdref) except BonjourError as error: if error.errorCode == kDNSServiceErr_ServiceNotRunning: log.info('Service not running') else: self._error_cb(_('Error while adding service. %s') % error) self.disconnect()
def second_step(self, request): # check if the data is correct try: form = dataforms.SimpleDataForm( extend=request.getTag('command').getTag('x')) except Exception: self.bad_request(request) return False try: presencetype = form['presence-type'].value if presencetype not in ('chat', 'online', 'away', 'xa', 'dnd', 'offline'): self.bad_request(request) return False except Exception: # KeyError if there's no presence-type field in form or # AttributeError if that field is of wrong type self.bad_request(request) return False try: presencedesc = form['presence-desc'].value except Exception: # same exceptions as in last comment presencedesc = '' response, cmd = self.build_response(request, status='completed') cmd.addChild('note', {}, _('The status has been changed.')) # if going offline, we need to push response so it won't go into # queue and disappear self.connection.connection.send(response, now=presencetype == 'offline') # send new status app.interface.roster.send_status(self.connection.name, presencetype, presencedesc) return False # finish the session
def _inhibit_sleep(self, connection): '''Obtain a sleep delay inhibitor from logind''' if self._inhibit_fd is not None: # Something is wrong, we have an inhibitor fd, and we are asking for # yet another one. log.warning('Trying to obtain a sleep inhibitor ' 'while already holding one.') ret, ret_fdlist = connection.call_with_unix_fd_list_sync( 'org.freedesktop.login1', '/org/freedesktop/login1', 'org.freedesktop.login1.Manager', 'Inhibit', GLib.Variant('(ssss)', ( 'sleep', 'org.gajim.Gajim', _('Disconnect from the network'), 'delay' # Inhibitor will delay but not block sleep )), GLib.VariantType.new('(h)'), Gio.DBusCallFlags.NONE, -1, None, None) log.info('Inhibit sleep') self._inhibit_fd = ret_fdlist.get(ret.unpack()[0])
def service_resolved_callback(self, sdRef, flags, interfaceIndex, errorCode, fullname, hosttarget, port, txtRecord): if errorCode != pybonjour.kDNSServiceErr_NoError: log.error('Error in service_resolved_callback: %s', str(errorCode)) return self.resolved_contacts[hosttarget] = (fullname, port, txtRecord) try: getaddrinfo_sdRef = \ pybonjour.DNSServiceGetAddrInfo( interfaceIndex=interfaceIndex, hostname=hosttarget, callBack=self.getaddrinfo_callback) while not self.queried: ready = select.select([getaddrinfo_sdRef], [], [], resolve_timeout) if getaddrinfo_sdRef not in ready[0]: log.warning('GetAddrInfo timed out') break pybonjour.DNSServiceProcessResult(getaddrinfo_sdRef) else: self.queried.pop() except pybonjour.BonjourError as error: if error.errorCode == pybonjour.kDNSServiceErr_ServiceNotRunning: log.info('Service not running') else: self.error_CB(_('Error while adding service. %s') % error) finally: if getaddrinfo_sdRef: getaddrinfo_sdRef.close() self.resolved.append(True)
def _on_affiliations_received(self, result, affiliation): if is_error_result(result): log.info('Error while requesting %s affiliations: %s', affiliation, result) return if affiliation == 'outcast': self._ui.stack.get_child_by_name('outcast').show() for jid, attrs in result.users.items(): affiliation_edit, jid_edit = self._allowed_to_edit(affiliation) if affiliation == 'outcast': reason = attrs.get('reason') self._ui.outcast_store.append( [str(jid), reason, None, affiliation, None, affiliation_edit, jid_edit]) self._affiliations[jid] = {'affiliation': affiliation, 'reason': reason} else: nick = attrs.get('nick') role = attrs.get('role') self._ui.affiliation_store.append( [str(jid), nick, role, affiliation, _(affiliation.capitalize()), affiliation_edit, jid_edit]) self._affiliations[jid] = {'affiliation': affiliation, 'nick': nick} if role is not None: self._ui.role_column.set_visible(True)
def _set_remove_button_state(self, sensitive, selected_affiliations): if self._own_affiliation not in ('admin', 'owner'): self._ui.remove_button.set_sensitive(False) return self._ui.remove_button.set_tooltip_text('') if not sensitive: self._ui.remove_button.set_sensitive(False) return if self._own_affiliation == 'owner': self._ui.remove_button.set_sensitive(True) return if set(['owner', 'admin']).intersection(selected_affiliations): self._ui.remove_button.set_sensitive(False) self._ui.remove_button.set_tooltip_text( _('You are not allowed to modify the affiliation ' 'of Admins and Owners')) return self._ui.remove_button.set_sensitive(True)
def _delete(self): for jid in self.exchange_list: groups = '' is_in_roster = True contact = app.contacts.get_contact_with_highest_priority( self.account, jid) name = self.exchange_list[jid][0] if not contact: is_in_roster = False num_list = len(self.exchange_list[jid][1]) current = 0 for group in self.exchange_list[jid][1]: current += 1 if current == num_list: groups = groups + group else: groups = groups + group + ', ' if is_in_roster: self.show_all() iter_ = self.model.append() self.model.set(iter_, 0, True, 1, jid, 2, name, 3, groups) self._ui.accept_button.set_label(_('Delete'))
def __init__(self, field, form_grid, options): self._field = field self._form_grid = form_grid self._validate_source_id = None self._read_only = options.get('read-only', False) self._label = Gtk.Label(label=field.label) self._label.set_single_line_mode(False) self._label.set_line_wrap(True) self._label.set_line_wrap_mode(Pango.WrapMode.WORD) self._label.set_width_chars(15) self._label.set_xalign(bool(options.get('right_align'))) self._label.set_tooltip_text(field.description) self._warning_image = Gtk.Image.new_from_icon_name( 'dialog-warning-symbolic', Gtk.IconSize.MENU) self._warning_image.get_style_context().add_class('warning-color') self._warning_image.set_no_show_all(True) self._warning_image.set_valign(Gtk.Align.CENTER) self._warning_image.set_tooltip_text(_('Required')) self._warning_box = Gtk.Box() self._warning_box.set_size_request(16, -1) self._warning_box.add(self._warning_image)
def _nec_acc_is_not_ok(self, obj): """ Account creation failed """ # We receive events from all accounts from GED if obj.conn.name != self.account: return self.back_button.show() self.cancel_button.show() self.go_online_checkbutton.hide() self.show_vcard_checkbutton.hide() del app.connections[self.account] if self.account in app.config.get_per('accounts'): app.config.del_per('accounts', self.account) img = self.xml.get_object('finish_image') img.set_from_icon_name("dialog-error", Gtk.IconSize.DIALOG) finish_text = '<big><b>%s</b></big>\n\n%s' % (_( 'An error occurred during account creation'), obj.reason) self.finish_label.set_markup(finish_text) self.notebook.set_current_page(6) # show finish page if self.update_progressbar_timeout_id is not None: GLib.source_remove(self.update_progressbar_timeout_id)
def __init__(self): Gtk.ListBoxRow.__init__(self) self.set_selectable(False) self.set_activatable(False) self.get_style_context().add_class('start-chat-row') self._text = _('%s group chats found') self._count = 0 self._spinner = Gtk.Spinner() self._spinner.start() self._count_label = Gtk.Label(label=self._text % 0) self._count_label.get_style_context().add_class('bold') self._finished_image = Gtk.Image.new_from_icon_name( 'emblem-ok-symbolic', Gtk.IconSize.MENU) self._finished_image.get_style_context().add_class('success-color') self._finished_image.set_no_show_all(True) box = Gtk.Box() box.set_spacing(6) box.add(self._finished_image) box.add(self._spinner) box.add(self._count_label) self.add(box) self.show_all()
def second_step(self, request): # check if the data is correct try: form = dataforms.SimpleDataForm( extend=request.getTag('command').getTag('x')) except Exception: self.bad_request(request) return False try: gc = form['groupchats'].values except Exception: # KeyError if there's no groupchats in form self.bad_request(request) return False account = self.connection.name try: for room_jid in gc: gc_control = app.interface.msg_win_mgr.get_gc_control( room_jid, account) if not gc_control: minimized_controls = app.interface.minimized_controls gc_control = minimized_controls[account][room_jid] gc_control.shutdown() app.interface.roster.remove_groupchat(room_jid, account) continue gc_control.parent_win.remove_tab(gc_control, None, force=True) except Exception: # KeyError if there's no such room opened self.bad_request(request) return False response, cmd = self.build_response(request, status='completed') note = _('You left the following group chats:') for room_jid in gc: note += '\n\t' + room_jid cmd.addChild('note', {}, note) self.connection.connection.send(response) return False
def set_warning(self, domain, cert, errors): # Clear list self._cert = cert self._domain = domain self._ui.error_list.foreach(self._ui.error_list.remove) unknown_error = _('Unknown TLS error \'%s\'') for error in errors: error_text = GIO_TLS_ERRORS.get(error, unknown_error % error) box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) image = Gtk.Image.new_from_icon_name('dialog-warning-symbolic', Gtk.IconSize.LARGE_TOOLBAR) image.get_style_context().add_class('warning-color') label = Gtk.Label(label=error_text) label.set_line_wrap(True) label.set_xalign(0) label.set_selectable(True) box.add(image) box.add(label) box.show_all() self._ui.error_list.add(box) self._ui.trust_cert_checkbutton.set_visible( Gio.TlsCertificateFlags.UNKNOWN_CA in errors)
def __init__(self, account): Gtk.ApplicationWindow.__init__(self) self.set_application(app.app) self.set_position(Gtk.WindowPosition.CENTER) self.set_show_menubar(False) self.set_name('PEPConfig') self.set_default_size(500, 350) self.set_resizable(True) self.set_transient_for(app.interface.roster.window) self._ui = get_builder('manage_pep_services_window.ui') self.add(self._ui.manage_pep_services) self.account = account self.set_title(_('PEP Service Configuration (%s)') % self.account) self._con = app.connections[self.account] self._init_services() self._ui.services_treeview.get_selection().connect( 'changed', self._on_services_selection_changed) self.show_all() self.connect('key-press-event', self._on_key_press_event) self._ui.connect_signals(self)
def _on_last_activity(self, stanza): if 'server_info' not in app.interface.instances[self.account]: # Window got closed in the meantime return if not nbxmpp.isResultNode(stanza): log.warning('Received malformed result: %s', stanza) return if stanza.getQueryNS() != nbxmpp.NS_LAST: log.warning('Wrong namespace on result: %s', stanza) return try: seconds = int(stanza.getQuery().getAttr('seconds')) except (ValueError, TypeError, AttributeError): log.exception('Received malformed last activity result') else: delta = timedelta(seconds=seconds) hours = 0 if seconds >= 3600: hours = delta.seconds // 3600 self.uptime = _('%(days)s days, %(hours)s hours') % { 'days': delta.days, 'hours': hours } self.update(self.get_infos, self.info_listbox)
class ErrorPage(Gtk.Box): type_ = Gtk.AssistantPageType.SUMMARY title = _('Registration failed') complete = True 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)
def _subscribe_received(self, _con, _stanza, properties): jid = properties.jid.getBare() fjid = str(properties.jid) is_transport = app.jid_is_transport(fjid) auto_auth = app.config.get_per('accounts', self._account, 'autoauth') self._log.info( 'Received Subscribe: %s, transport: %s, ' 'auto_auth: %s, user_nick: %s', properties.jid, is_transport, auto_auth, properties.nickname) if is_transport and fjid in self._con.agent_registrations: self._con.agent_registrations[fjid]['sub_received'] = True if not self._con.agent_registrations[fjid]['roster_push']: # We'll reply after roster push result raise nbxmpp.NodeProcessed if auto_auth or is_transport or jid in self.jids_for_auto_auth: self.send_presence(fjid, 'subscribed') self._log.info('Auto respond with subscribed: %s', jid) return status = (properties.status or _('I would like to add you to my roster.')) app.nec.push_incoming_event( NetworkEvent('subscribe-presence-received', conn=self._con, jid=jid, fjid=fjid, status=status, user_nick=properties.nickname, is_transport=is_transport)) raise nbxmpp.NodeProcessed