def _on_send(self, *args): if not self._selected_send_account: return if not app.account_is_connected(self._selected_send_account): # If offline or connecting ErrorDialog( _('Connection not available'), _('Please make sure you are connected with \'%s\'.') % self._selected_send_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.Node(node=stanza) except Exception as error: ErrorDialog(_('Invalid Node'), str(error)) return if node.getName() in ('message', 'presence', 'iq'): # Parse stanza again if its a message, presence or iq and # set jabber:client as toplevel namespace # Use type Protocol so nbxmpp counts the stanza for # stream management node = nbxmpp.Protocol(node=stanza, attrs={'xmlns': 'jabber:client'}) app.connections[self._selected_send_account].connection.send(node) self.last_stanza = stanza buffer_.set_text('')
def on_server_entry_focus_out(self, widget, event): if self.ignore_events: return (model, iter_) = self.selection.get_selected() if not iter_: return server = widget.get_text() if not server: return if '@' in server: ErrorDialog( _('Invalid server'), _('Character not allowed'), transient_for=self._ui.manage_bookmarks_window) widget.set_text(server.replace('@', '')) room = self._ui.room_entry.get_text().strip() if not room: return room_jid = room + '@' + server.strip() try: room_jid = helpers.parse_jid(room_jid) except helpers.InvalidFormat: ErrorDialog( _('Invalid server'), _('Character not allowed'), transient_for=self._ui.manage_bookmarks_window) self._ui.server_entry.set_text( model[iter_][Row.ROOM_JID].split('@')[1]) return True model[iter_][Row.ROOM_JID] = room_jid
def get_send_file_props(self, account, contact, file_path, file_name, file_desc=''): """ Create new file_props object and set initial file transfer properties in it """ if os.path.isfile(file_path): stat = os.stat(file_path) else: ErrorDialog(_('Invalid File'), _('File: ') + file_path) return None if stat[6] == 0: ErrorDialog( _('Invalid File'), _('It is not possible to send empty files')) return None file_props = FilesProp.getNewFileProp( account, sid=helpers.get_random_string_16()) mod_date = os.path.getmtime(file_path) file_props.file_name = file_path file_props.name = file_name file_props.date = self.__convert_date(mod_date) file_props.type_ = 's' file_props.desc = file_desc file_props.elapsed_time = 0 file_props.size = stat[6] file_props.sender = account file_props.receiver = contact file_props.tt_account = account return file_props
def _disco_info_received(self, result): if is_error_result(result): ErrorDialog(_('Wrong server'), _('%s is not a group chat server') % result.jid, transient_for=self) return if nbxmpp.NS_MUC not in result.features: ErrorDialog(_('Wrong server'), _('%s is not a group chat server') % result.jid, transient_for=self) return jid = str(result.jid) if jid in app.interface.instances[self.account]['disco']: app.interface.instances[self.account]['disco'][jid].window.\ present() else: try: # Object will add itself to the window dict ServiceDiscoveryWindow(self.account, jid, initial_identities=[ DiscoIdentity(category='conference', type='text', name=None) ]) except GajimGeneralException: pass
def _on_accepted(account, contact, file_props, file_path): if os.path.exists(file_path): app.config.set('last_save_dir', os.path.dirname(file_path)) # Check if we have write permissions if not os.access(file_path, os.W_OK): file_name = GLib.markup_escape_text( os.path.basename(file_path)) ErrorDialog( _('Cannot overwrite existing file \'%s\'' % file_name), _('A file with this name already exists and you do ' 'not have permission to overwrite it.')) return stat = os.stat(file_path) dl_size = stat.st_size file_size = file_props.size dl_finished = dl_size >= file_size def _on_resume(): if not dl_finished: file_props.offset = dl_size self._start_receive( file_path, account, contact, file_props) def _on_replace(): self._start_receive( file_path, account, contact, file_props) def _on_cancel(): con.get_module('Bytestream').send_file_rejection( file_props) NewConfirmationDialog( _('File Transfer Conflict'), _('File already exists'), _('Resume download or replace file?'), [DialogButton.make('Cancel', callback=_on_cancel), DialogButton.make('OK', text=_('Resume _Download'), callback=_on_resume), DialogButton.make('Accept', text=_('Replace _File'), callback=_on_replace)]).show() # File does not exist yet dirname = os.path.dirname(file_path) if not os.access(dirname, os.W_OK) and os.name != 'nt': # read-only bit is used to mark special folder under # windows, not to mark that a folder is read-only. # See ticket #3587 ErrorDialog( _('Directory \'%s\' is not writable') % dirname, _('You do not have permissions to create files ' 'in this directory.')) return self._start_receive(file_path, account, contact, file_props)
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) 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)) self._ui.subject_entry.set_text('') # we sent ok, clear the subject self._message_tv_buffer.set_text('') # we sent ok, clear the textview return False
def _before_sendmessage(chat_control): account = chat_control.account if not chat_control.contact.keyID: ErrorDialog( _('No OpenPGP key assigned'), _('No OpenPGP key is assigned to this contact. So you cannot ' 'encrypt messages with OpenPGP.')) chat_control.sendmessage = False elif not app.config.get_per('accounts', account, 'keyid'): ErrorDialog( _('No OpenPGP key assigned'), _('No OpenPGP key is assigned to your account. So you cannot ' 'encrypt messages with OpenPGP.')) chat_control.sendmessage = False
def _check_file(self, filename): filesize = os.path.getsize(filename) # in bytes invalid_file = False msg = '' if os.path.isfile(filename): stat = os.stat(filename) if stat[6] == 0: invalid_file = True msg = _('File is empty') else: invalid_file = True msg = _('File does not exist') if filesize < 60000: file_ = open(filename, "rb") img = urllib.parse.quote(base64.standard_b64encode( file_.read()), '') if len(img) > 60000: invalid_file = True msg = _('File too big') file_.close() else: invalid_file = True msg = _('File too big') if invalid_file: ErrorDialog(_('Could not load image'), msg) return return img
def _on_remove_theme(self, *args): store, iter_ = self._theme_treeview.get_selection().get_selected() if iter_ is None: return theme = store[iter_][Column.THEME] if theme == app.config.get('roster_theme'): ErrorDialog(_('Active Theme'), _('You tried to delete the currently active theme. ' 'Please switch to a different theme first.'), transient_for=self) return def _remove_theme(): app.css_config.remove_theme(theme) store.remove(iter_) first = store.get_iter_first() if first is None: self._remove_theme_button.set_sensitive(False) self._add_option_button.set_sensitive(False) self._clear_options() NewConfirmationDialog( _('Delete'), _('Delete Theme'), _('Do you want to permanently delete this theme?'), [ DialogButton.make('Cancel'), DialogButton.make('Delete', callback=_remove_theme) ], transient_for=self).show()
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 send_message(self, message, xhtml=None, process_commands=True, attention=False): """ Call this method to send the message """ message = helpers.remove_invalid_xml_chars(message) if not message: return # We need to make sure that we can still send through the room and that # the recipient did not go away if self.gc_contact.presence.is_unavailable: ErrorDialog( _('Sending private message failed'), #in second %s code replaces with nickname _('You are no longer in group chat "%(room)s" or ' '"%(nick)s" has left.') % { 'room': self.room_name, 'nick': self.gc_contact.name}, transient_for=self.parent_win.window) return ChatControl.send_message(self, message, xhtml=xhtml, process_commands=process_commands, attention=attention)
def __init__(self, account): # 'account' can be None if we are about to create our first one if not account or app.connections[account].connected < 2: ErrorDialog( _('You are not connected to the server'), _('Without a connection, you can not synchronise your contacts.' )) raise GajimGeneralException('You are not connected to the server') self.account = account self.xml = get_builder('synchronise_select_account_dialog.ui') self.dialog = self.xml.get_object('synchronise_select_account_dialog') self.dialog.set_transient_for(app.get_app_window('AccountsWindow')) self.accounts_treeview = self.xml.get_object('accounts_treeview') model = Gtk.ListStore(str, str, bool) self.accounts_treeview.set_model(model) # columns renderer = Gtk.CellRendererText() self.accounts_treeview.insert_column_with_attributes(-1, _('Name'), renderer, text=0) renderer = Gtk.CellRendererText() self.accounts_treeview.insert_column_with_attributes(-1, _('Server'), renderer, text=1) self.xml.connect_signals(self) self.init_accounts() self.dialog.show_all()
def on_room_entry_changed(self, widget): if self.ignore_events: return (model, iter_) = self.selection.get_selected() if not iter_: return room = widget.get_text() if not room: return if '@' in room: room, server = room.split('@', 1) widget.set_text(room) if server: self._ui.server_entry.set_text(server) self._ui.server_entry.grab_focus() server = self._ui.server_entry.get_text().strip() if not server: return room_jid = room.strip() + '@' + server try: room_jid = helpers.parse_jid(room_jid) except helpers.InvalidFormat: ErrorDialog( _('Invalid Group Chat'), _('Character not allowed'), transient_for=self._ui.manage_bookmarks_window) return True model[iter_][Row.ROOM_JID] = room_jid
def on_add_button_clicked(self, widget): """ When Subscribe button is clicked """ jid = self.uid_entry.get_text().strip() if not jid: ErrorDialog( _('%s Missing') % self.uid_label.get_text(), _('You must supply the %s of the new contact.' % self.uid_label.get_text())) return model = self.protocol_combobox.get_model() row = self.protocol_combobox.get_active_iter() type_ = model[row][2] if type_ != 'jabber': model = self.protocol_jid_combobox.get_model() row = self.protocol_jid_combobox.get_active() transport = model[row][0] if self.account and not self.jid_escaped: self.adding_jid = (jid, transport, type_) con = app.connections[self.account] con.get_module('Gateway').request_gateway_prompt( transport, jid) else: jid = jid.replace('@', '%') + '@' + transport self._add_jid(jid, type_) else: self._add_jid(jid, type_)
def send_file(self, account, contact, file_path, file_desc=''): """ Start the real transfer(upload) of the file """ if gtkgui_helpers.file_is_locked(file_path): pritext = _('Gajim can not read this file') sextext = _('Another process is using this file.') ErrorDialog(pritext, sextext) return if isinstance(contact, str): if contact.find('/') == -1: return (jid, resource) = contact.split('/', 1) contact = app.contacts.create_contact(jid=jid, account=account, resource=resource) file_name = os.path.split(file_path)[1] file_props = self.get_send_file_props(account, contact, file_path, file_name, file_desc) if file_props is None: return False app.connections[account].get_module('Jingle').start_file_transfer( contact.get_full_jid(), file_props) self.add_transfer(account, contact, file_props) return True
def __init__(self): log_db_path = configpaths.get('LOG_DB') if not os.path.exists(log_db_path): ErrorDialog(_('Cannot find history logs database'), _('%s does not exist.') % log_db_path) sys.exit() self._ui = get_builder('history_manager.ui') Gtk.Window.set_default_icon_list( get_app_icon_list(self._ui.history_manager_window)) self.jids_already_in = [] # holds jids that we already have in DB self.AT_LEAST_ONE_DELETION_DONE = False self.con = sqlite3.connect(log_db_path, timeout=20.0, isolation_level='IMMEDIATE') self.con.execute("PRAGMA secure_delete=1") self.cur = self.con.cursor() self._init_jids_listview() self._init_logs_listview() self._init_search_results_listview() self._fill_jids_listview() self._ui.search_entry.grab_focus() self._ui.history_manager_window.show_all() self._ui.connect_signals(self)
def on_calendar_month_changed(self, widget): """ Ask for days in this month, if they have logs it bolds them (marks them) """ if not self.jid: return year, month, _day = widget.get_date() # integers if year < 1900: widget.select_month(0, 1900) widget.select_day(1) return widget.clear_marks() month = python_month(month) try: log_days = app.logger.get_days_with_logs( self.account, self.jid, year, month) except exceptions.PysqliteOperationalError as error: ErrorDialog(_('Disk Error'), str(error)) return for date in log_days: widget.mark_day(date.day)
def on_ok(target_path): dirname = os.path.dirname(target_path) if not os.access(dirname, os.W_OK): ErrorDialog(_('Directory \'%s\' is not writable') % dirname, _('You do not have the proper permissions to ' 'create files in this directory.'), transient_for=app.app.get_active_window()) return shutil.copy(filepath, target_path)
def _items_received(self, result): if is_error_result(result): ErrorDialog('Error', to_user_string(result)) return jid = result.jid.getBare() for item in result.items: if item.jid == jid and item.node is not None: self.treestore.append([item.node])
def show_stopped(self, jid, file_props, error_msg=''): if file_props.type_ == 'r': file_name = os.path.basename(file_props.file_name) else: file_name = file_props.name sectext = '\t' + _('Filename: %s') % GLib.markup_escape_text(file_name) sectext += '\n\t' + _('Recipient: %s') % jid if error_msg: sectext += '\n\t' + _('Error message: %s') % error_msg ErrorDialog(_('File transfer stopped'), sectext) self._ui.transfers_list.get_selection().unselect_all()
def _on_create_clicked(self, *args): if not app.account_is_connected(self._account): ErrorDialog(_('Not Connected'), _('You have to be connected to create a group chat.')) return room_jid = self._ui.address_entry.get_text() self._set_processing_state(True) con = app.connections[self._account] con.get_module('Discovery').disco_info( room_jid, callback=self._disco_info_received)
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 _on_save_avatar(file_path): if os.path.exists(file_path): # Check if we have write permissions if not os.access(file_path, os.W_OK): file_name = os.path.basename(file_path) ErrorDialog( _('Cannot overwrite existing file \'%s\'' % file_name), _('A file with this name already exists and you do ' 'not have permission to overwrite it.')) return app.config.set('last_save_dir', os.path.dirname(file_path)) if isinstance(avatar, str): # We got a SHA pixbuf = app.interface.avatar_storage.pixbuf_from_filename(avatar) else: # We got a pixbuf pixbuf = avatar extension = os.path.splitext(file_path)[1] if not extension: # Silently save as Jpeg image image_format = 'png' file_path += '.png' else: image_format = extension[1:] # remove leading dot # Save image try: pixbuf.savev(file_path, image_format, [], []) except Exception as error: log.error('Error saving avatar: %s', error) if os.path.exists(file_path): os.remove(file_path) new_file_path = '.'.join(file_path.split('.')[:-1]) + '.png' def _on_ok(file_path, pixbuf): pixbuf.savev(file_path, 'png', [], []) NewConfirmationDialog( _('Error While Saving'), _('Extension not supported'), _('Image cannot be saved in %(type)s format.\n' 'Save as %(new_filename)s?') % { 'type': image_format, 'new_filename': new_file_path }, [ DialogButton.make('Cancel'), DialogButton.make('OK', text=_('_Save'), callback=_on_ok, args=[new_file_path, pixbuf]) ]).show()
def on_BDAY_entry_focus_out_event(self, widget, event): txt = widget.get_text() if not txt: return try: time.strptime(txt, '%Y-%m-%d') except ValueError: if not widget.is_focus(): pritext = _('Wrong date format') ErrorDialog(pritext, _('Format of the date must be YYYY-MM-DD'), transient_for=self) GLib.idle_add(widget.grab_focus) return True
def on_new_privacy_list_button_clicked(self, widget): name = self.new_privacy_list_entry.get_text() if not name: ErrorDialog(_('Invalid List Name'), _('You must enter a name to create a privacy list.'), transient_for=self.window) return key_name = 'privacy_list_%s' % name if key_name in app.interface.instances[self.account]: app.interface.instances[self.account][key_name].window.present() else: app.interface.instances[self.account][key_name] = \ PrivacyListWindow(self.account, name, 'NEW') self.new_privacy_list_entry.set_text('')
def _before_sendmessage(chat_control): account = chat_control.account jid = chat_control.contact.jid con = app.connections[account] try: valid = con.get_module('PGPLegacy').has_valid_key_assigned(jid) except KeyMismatch as announced_key_id: ErrorDialog( _('PGP Key mismatch'), _('The contact\'s key (%s) <b>does not match</b> the key ' 'assigned in Gajim.') % announced_key_id) chat_control.sendmessage = False return if not valid: ErrorDialog(_('No OpenPGP key assigned'), _('No OpenPGP key is assigned to this contact.')) chat_control.sendmessage = False elif con.get_module('PGPLegacy').get_own_key_data() is None: ErrorDialog(_('No OpenPGP key assigned'), _('No OpenPGP key is assigned to your account.')) chat_control.sendmessage = False
def _on_theme_name_edit(self, renderer, path, new_name): iter_ = self._theme_store.get_iter(path) old_name = self._theme_store[iter_][Column.THEME] if new_name == 'default': ErrorDialog(_('Invalid Name'), _('Name <b>default</b> is not allowed'), transient_for=self) return if ' ' in new_name: ErrorDialog(_('Invalid Name'), _('Spaces are not allowed'), transient_for=self) return if new_name == '': return result = app.css_config.rename_theme(old_name, new_name) if result is False: return self._theme_store.set_value(iter_, Column.THEME, new_name)
def _before_sendmessage(self, chat_control): account = chat_control.account jid = chat_control.contact.jid con = app.connections[account] if not con.get_module('OpenPGP').secret_key_available: from openpgp.gtk.wizard import KeyWizard KeyWizard(self, account, chat_control) return keys = con.get_module('OpenPGP').get_keys(jid) if not keys: ErrorDialog(_('Not Trusted'), _('There was no trusted and active key found')) chat_control.sendmessage = False
def save_account(self, login, server, savepass, password, anonymous=False): if self.account in app.connections: ErrorDialog( _('Account name is in use'), _('You already have an account using this name.')) return con = connection.Connection(self.account) con.password = password config = self.get_config(login, server, savepass, password, anonymous) if not self.modify: con.new_account(self.account, config) return app.connections[self.account] = con self.create_vars(config)
def on_nick_entry_changed(self, widget): if self.ignore_events: return (model, iter_) = self.selection.get_selected() if iter_: nick = self._ui.nick_entry.get_text() try: nick = helpers.parse_resource(nick) except helpers.InvalidFormat: ErrorDialog( _('Invalid nickname'), _('Character not allowed'), transient_for=self._ui.manage_bookmarks_window) self._ui.nick_entry.set_text(model[iter_][Row.NICK]) return True model[iter_][Row.NICK] = nick