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: dialogs.ErrorDialog(_('Invalid File'), _('File: ') + file_path) return None if stat[6] == 0: dialogs.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 on_ok(widget): file_path = dialog.get_filename() 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) dialogs.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 dialog2 = dialogs.FTOverwriteConfirmationDialog( _('This file already exists'), _('What do you want to do?'), propose_resume=False, on_response=(on_continue, file_path), transient_for=dialog) dialog2.set_destroy_with_parent(True) else: dirname = os.path.dirname(file_path) if not os.access(dirname, os.W_OK): dialogs.ErrorDialog(_('Directory "%s" is not writable') % \ dirname, _('You do not have permission to create files in ' 'this directory.')) return on_continue(0, file_path)
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.') dialogs.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 if contact.supports(NS_JINGLE_FILE_TRANSFER_5): log.info("contact %s supports jingle file transfer" % (contact.get_full_jid())) app.connections[account].start_file_transfer( contact.get_full_jid(), file_props) self.add_transfer(account, contact, file_props) else: log.info("contact does not support jingle file transfer") file_props.transport_sid = file_props.sid app.connections[account].send_file_request(file_props) self.add_transfer(account, contact, file_props) return True
def on_ok_button_clicked(self, widget): if self.update_progressbar_timeout_id: # Operation in progress return if app.connections[self.account].connected < 2: dialogs.ErrorDialog( _('You are not connected to the server'), _('Without a connection, you can not publish your contact ' 'information.'), transient_for=self.window) return vcard_, sha = self.make_vcard() nick = '' if 'NICKNAME' in vcard_: nick = vcard_['NICKNAME'] app.connections[self.account].send_nickname(nick) if nick == '': app.connections[self.account].retract_nickname() nick = app.config.get_per('accounts', self.account, 'name') app.nicks[self.account] = nick app.connections[self.account].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 on_ok(widget, path_to_file): with open(path_to_file, 'rb') as file: data = file.read() sha = app.interface.save_avatar(data, publish=True) if sha is None: dialogs.ErrorDialog(_('Could not load image'), transient_for=self.window) return self.dialog.destroy() self.dialog = None scale = self.window.get_scale_factor() surface = app.interface.get_avatar(sha, AvatarSize.VCARD, scale) button = self.xml.get_object('PHOTO_button') image = button.get_image() image.set_from_surface(surface) button.show() text_button = self.xml.get_object('NOPHOTO_button') text_button.hide() self.avatar_sha = sha publish = app.interface.get_avatar(sha, publish=True) self.avatar_encoded = base64.b64encode(publish).decode('utf-8') self.avatar_mime_type = 'image/jpeg'
def stage3_submit_form(self, action='execute'): self.data_form_widget.set_sensitive(False) if self.data_form_widget.get_data_form(): df = self.data_form_widget.get_data_form() if not df.is_valid(): dialogs.ErrorDialog( _('Invalid Form'), _('The form is not filled correctly.'), transient_for=self.window) self.data_form_widget.set_sensitive(True) return self.data_form_widget.data_form.type_ = 'submit' else: self.data_form_widget.hide() self.close_button.set_sensitive(True) self.back_button.set_sensitive(False) self.forward_button.set_sensitive(False) self.execute_button.set_sensitive(False) self.finish_button.set_sensitive(False) self.sending_form_progressbar.show() self.setup_pulsing(self.sending_form_progressbar) self.send_command(action)
def on_theme_cell_edited(self, cell, row, new_name): model = self.themes_tree.get_model() iter_ = model.get_iter_from_string(row) old_name = model.get_value(iter_, 0) if old_name == new_name: return if old_name == 'default': dialogs.ErrorDialog( _('You cannot make changes to the default theme'), _('Please create a new clean theme.')) return new_config_name = new_name.replace(' ', '_') if new_config_name in app.config.get_per('themes'): return app.config.add_per('themes', new_config_name) # Copy old theme values old_config_name = old_name.replace(' ', '_') properties = ['textcolor', 'bgcolor', 'font', 'fontattrs'] app.config.add_per('themes', new_config_name) for option in self.options: for property_ in properties: option_name = option + property_ app.config.set_per( 'themes', new_config_name, option_name, app.config.get_per('themes', old_config_name, option_name)) app.config.del_per('themes', old_config_name) if old_config_name == app.config.get('roster_theme'): app.config.set('roster_theme', new_config_name) model.set_value(iter_, 0, new_name) self.current_theme = new_name
def on_ok(widget, account, contact, file_props): file_path = dialog2.get_filename() if os.path.exists(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)) dialogs.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_response(response): if response < 0: return elif response == 100: file_props.offset = dl_size dialog2.destroy() self._start_receive(file_path, account, contact, file_props) dialog = dialogs.FTOverwriteConfirmationDialog( _('This file already exists'), _('What do you want to do?'), propose_resume=not dl_finished, on_response=on_response, transient_for=dialog2) dialog.set_destroy_with_parent(True) return else: 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 dialogs.ErrorDialog(_('Directory "%s" is not writable') % \ dirname, _('You do not have permission to create files ' 'in this directory.')) return dialog2.destroy() self._start_receive(file_path, account, contact, file_props)
def on_ok(target_path): dirname = os.path.dirname(target_path) if not os.access(dirname, os.W_OK): dialogs.ErrorDialog( _('Directory "%s" is not writable') % dirname, _('You do not have permission to ' 'create files in this directory.')) return shutil.copy(filepath, target_path)
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 dialogs.ErrorDialog(_('File transfer stopped'), sectext) self.tree.get_selection().unselect_all()
def on_open_link_in_browser_menuitem_activate(self, menu, data): url = data["url"] if data["encrypted"]: dialogs.ErrorDialog( _('Encrypted file'), _('You cannot open encrypted files in your ' 'browser directly. Try "Open Downloaded File ' 'in Browser" instead.'), transient_for=app.app.get_active_window()) else: helpers.launch_browser_mailer('url', url)
def on_remove_button_clicked(self, widget): (model, iter_) = self.themes_tree.get_selection().get_selected() if not iter_: return if self.current_theme == app.config.get('roster_theme'): dialogs.ErrorDialog(_('You cannot delete your current theme'), _('Pick another theme to use first.')) return self.theme_options_vbox.set_sensitive(False) self.theme_options_table.set_sensitive(False) self.xml.get_object('remove_button').set_sensitive(False) app.config.del_per('themes', self.current_theme) model.remove(iter_)
def on_jid_multi_cellrenderertext_edited(self, cell, path, newtext, treeview, model, field): old = model[path][0] if old == newtext: return try: newtext = helpers.parse_jid(newtext) except helpers.InvalidFormat as s: dialogs.ErrorDialog(_('Invalid JID'), str(s)) return if newtext in field.values: dialogs.ErrorDialog( _('JID already in list'), _('The JID you entered is already in the list. Choose another one.' )) GLib.idle_add(treeview.set_cursor, path) return model[path][0] = newtext values = field.values values[values.index(old)] = newtext field.values = values
def _save_thumbnail(self, thumbpath, mem): size = self.plugin.config['PREVIEW_SIZE'] try: loader = GdkPixbuf.PixbufLoader() loader.write(mem) loader.close() if loader.get_format().get_name() == 'gif': pixbuf = loader.get_animation() else: pixbuf = loader.get_pixbuf() except GLib.GError as error: log.info('Failed to load image using Gdk.Pixbuf') log.debug(error) if not PILLOW_AVAILABLE: log.info('Pillow not available') return # Try Pillow image = Image.open(BytesIO(mem)).convert("RGBA") array = GLib.Bytes.new(image.tobytes()) width, height = image.size pixbuf = GdkPixbuf.Pixbuf.new_from_bytes( array, GdkPixbuf.Colorspace.RGB, True, 8, width, height, width * 4) try: self._create_path(os.path.dirname(thumbpath)) thumbnail = pixbuf if isinstance(pixbuf, GdkPixbuf.PixbufAnimation): if size < pixbuf.get_width() or size < pixbuf.get_height(): resize_gif(mem, thumbpath, (size, size)) thumbnail = self._load_thumbnail(thumbpath) else: self._write_file(thumbpath, mem) else: width, height = self._get_thumbnail_size(pixbuf, size) thumbnail = pixbuf.scale_simple( width, height, GdkPixbuf.InterpType.BILINEAR) thumbnail.savev(thumbpath, 'png', [], []) except Exception as error: dialogs.ErrorDialog( _('Could not save file'), _('Exception raised while saving thumbnail ' 'for image file (see error log for more ' 'information)'), transient_for=app.app.get_active_window()) log.exception(error) return return thumbnail
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') dialogs.ErrorDialog(pritext, _('Format of the date must be ' 'YYYY-MM-DD'), transient_for=self.window) GLib.idle_add(lambda: widget.grab_focus()) return True
def show_dialog(self, parent): secret_keys = app.connections[self.account].ask_gpg_secrete_keys() secret_keys[_('None')] = _('None') if not secret_keys: dialogs.ErrorDialog( _('Failed to get secret keys'), _('There is no OpenPGP secret key available.'), transient_for=parent) return dialog = dialogs.ChooseGPGKeyDialog( _('OpenPGP Key Selection'), _('Choose your OpenPGP key'), secret_keys, self.on_key_selected, transient_for=parent) dialog.window.connect('destroy', self.on_destroy)
def on_join_gc(self, action, param): account = param.get_string() invisible_show = app.SHOW_LIST.index('invisible') if app.connections[account].connected == invisible_show: dialogs.ErrorDialog(_( 'You cannot join a group chat while you are invisible')) return if 'join_gc' in interface.instances[account]: interface.instances[account]['join_gc'].window.present() else: try: interface.instances[account]['join_gc'] = \ dialogs.JoinGroupchatWindow(account) except GajimGeneralException: pass
def _change_date(self, widget): # Get day selected in calendar y, m, d = self.calendar.get_date() py_m = gtkgui_helpers.make_gtk_month_python_month(m) _date = datetime.datetime(y, py_m, d) if widget is self.button_first_day: gtk_m = gtkgui_helpers.make_python_month_gtk_month( self.first_day.month) self.calendar.select_month(gtk_m, self.first_day.year) self.calendar.select_day(self.first_day.day) return elif widget is self.button_last_day: gtk_m = gtkgui_helpers.make_python_month_gtk_month( self.last_day.month) self.calendar.select_month(gtk_m, self.last_day.year) self.calendar.select_day(self.last_day.day) return elif widget is self.button_previous_day: end_date = self.first_day timedelta = datetime.timedelta(days=-1) if end_date >= _date: return elif widget is self.button_next_day: end_date = self.last_day timedelta = datetime.timedelta(days=1) if end_date <= _date: return # Iterate through days until log entry found or # supplied end_date (first_log / last_log) reached logs = None while logs is None: _date = _date + timedelta if _date == end_date: break try: logs = app.logger.get_date_has_logs(self.account, self.jid, _date) except exceptions.PysqliteOperationalError as e: dialogs.ErrorDialog(_('Disk Error'), str(e)) return gtk_month = gtkgui_helpers.make_python_month_gtk_month(_date.month) self.calendar.select_month(gtk_month, _date.year) self.calendar.select_day(_date.day)
def __init__(self): pixs = [] for size in (16, 32, 48, 64, 128): pix = gtkgui_helpers.get_icon_pixmap('org.gajim.Gajim', size) if pix: pixs.append(pix) if pixs: # set the icon to all windows Gtk.Window.set_default_icon_list(pixs) if not os.path.exists(LOG_DB_PATH): dialogs.ErrorDialog(_('Cannot find history logs database'), '%s does not exist.' % LOG_DB_PATH) sys.exit() xml = gtkgui_helpers.get_gtk_builder('history_manager.ui') self.window = xml.get_object('history_manager_window') self.jids_listview = xml.get_object('jids_listview') self.logs_listview = xml.get_object('logs_listview') self.search_results_listview = xml.get_object( 'search_results_listview') self.search_entry = xml.get_object('search_entry') self.logs_scrolledwindow = xml.get_object('logs_scrolledwindow') self.search_results_scrolledwindow = xml.get_object( 'search_results_scrolledwindow') self.welcome_vbox = xml.get_object('welcome_vbox') self.jids_already_in = [] # holds jids that we already have in DB self.AT_LEAST_ONE_DELETION_DONE = False self.con = sqlite.connect(LOG_DB_PATH, timeout=20.0, isolation_level='IMMEDIATE') self.cur = self.con.cursor() self._init_jids_listview() self._init_logs_listview() self._init_search_results_listview() self._fill_jids_listview() self.search_entry.grab_focus() self.window.show_all() xml.connect_signals(self)
def on_remove_account(self, button, account): if app.events.get_events(account): dialogs.ErrorDialog( _('Unread events'), _('Read all pending events before removing this account.'), transient_for=self) return if app.config.get_per('accounts', account, 'is_zeroconf'): # Should never happen as button is insensitive return win_opened = False if app.interface.msg_win_mgr.get_controls(acct=account): win_opened = True elif account in app.interface.instances: for key in app.interface.instances[account]: if (app.interface.instances[account][key] and key != 'remove_account'): win_opened = True break # Detect if we have opened windows for this account def remove(account): if (account in app.interface.instances and 'remove_account' in app.interface.instances[account]): dialog = app.interface.instances[account]['remove_account'] dialog.window.present() else: if account not in app.interface.instances: app.interface.instances[account] = {} app.interface.instances[account]['remove_account'] = \ config.RemoveAccountWindow(account) if win_opened: dialogs.ConfirmationDialog( _('You have opened chat in account %s') % account, _('All chat and groupchat windows will be closed. ' 'Do you want to continue?'), on_response_ok=(remove, account)) else: remove(account)
def on_open_file_in_browser_menuitem_activate(self, menu, data): if os.name == "nt": filepath = "file://" + os.path.abspath(data["filepath"]) else: filepath = "file://" + data["filepath"] if app.config.get('autodetect_browser_mailer') \ or app.config.get('custombrowser') == '': dialogs.ErrorDialog( _('Cannot open downloaded file in browser'), _('You have to set a custom browser executable ' 'in your gajim settings for this to work.'), transient_for=app.app.get_active_window()) return command = app.config.get('custombrowser') command = helpers.build_command(command, filepath) try: helpers.exec_command(command) except Exception: pass
def on_switch(self, switch, param, account): old_state = app.config.get_per('accounts', account, 'active') state = switch.get_active() if old_state == state: return if (account in app.connections and app.connections[account].connected > 0): # connecting or connected dialogs.ErrorDialog( _('You are currently connected to the server'), _('To disable the account, you must be disconnected.'), transient_for=self.parent) switch.set_active(not state) return if state: self.parent.enable_account(account) else: self.parent.disable_account(account) app.config.set_per('accounts', account, 'active', state)
def _download_image(self, account, attributes, encrypted): filepath = attributes['filepaths'][0] thumbpath = attributes['filepaths'][1] key = attributes['key'] iv = attributes['iv'] mem, alt = get_http_file(account, attributes) # Decrypt file if necessary if encrypted: mem = self._aes_decrypt_fast(key, iv, mem) try: # Write file to harddisk self._write_file(filepath, mem) except Exception as e: dialogs.ErrorDialog( _('Could not save file'), _('Exception raised while saving image file' ' (see error log for more information)'), transient_for=app.app.get_active_window()) log.error(str(e)) # Create thumbnail, write it to harddisk and return it return self._save_thumbnail(thumbpath, mem)
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 = gtkgui_helpers.make_gtk_month_python_month(month) try: log_days = app.logger.get_days_with_logs(self.account, self.jid, year, month) except exceptions.PysqliteOperationalError as e: dialogs.ErrorDialog(_('Disk Error'), str(e)) return for date in log_days: widget.mark_day(date.day)