예제 #1
0
 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
예제 #2
0
    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)
예제 #3
0
    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
예제 #4
0
 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)
예제 #5
0
        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'
예제 #6
0
    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)
예제 #7
0
 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
예제 #8
0
        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)
예제 #9
0
 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)
예제 #10
0
 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()
예제 #11
0
 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)
예제 #12
0
 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_)
예제 #13
0
    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
예제 #14
0
    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
예제 #15
0
 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
예제 #16
0
    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)
예제 #17
0
 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
예제 #18
0
    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)
예제 #19
0
    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)
예제 #20
0
    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)
예제 #21
0
 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
예제 #22
0
    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)
예제 #23
0
    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)
예제 #24
0
    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)