def init(self): self.description = _('Install and upgrade plugins for Gajim') self.config_dialog = PluginInstallerPluginConfigDialog(self) self.config_default_values = { 'check_update': (True, ''), 'auto_update': (False, ''), 'auto_update_feedback': (True, '') } self.gui_extension_points = {'plugin_window': (self.on_activate, None)} self.window = None self.spinner = None self.available_plugins_model = None self.timeout_id = 0 self.connected_ids = {}
def init(self): self.description = _( 'Flashing keyboard led when there are unread messages.') self.config_dialog = FlashingKeyboardPluginConfigDialog(self) self.config_default_values = { 'command1': ("xset led named 'Scroll Lock'", ''), 'command2': ("xset -led named 'Scroll Lock'", ''), 'flash': (True, ''), } self.is_active = None self.timeout = 500 self.timeout_off = int(self.timeout / 2) self.id_0 = None
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: GLib.idle_add( self._raise_error_dialog, _('Could not save file'), _('Exception raised while saving image file' ' (see error log for more information)')) log.error(str(e)) # Create thumbnail, write to disk and return it return self._save_thumbnail(thumbpath, mem)
def init(self): self.description = _('Allows you to adjust the height' ' of the new message input field.') self.config_dialog = MsgBoxSizePluginConfigDialog(self) self.gui_extension_points = { 'chat_control_base': (self.connect_with_chat_control, self.disconnect_from_chat_control) } self.config_default_values = { 'Do_not_resize': (False, ''), 'Minimum_lines': (2, ''), } self.chat_control = None self.controls = []
class WelcomePage(Gtk.Box): type_ = Gtk.AssistantPageType.INTRO title = _('Welcome') complete = True def __init__(self): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.set_spacing(18) title_label = Gtk.Label(label=_('Setup OpenPGP')) text_label = Gtk.Label( label=_('Gajim will now try to setup OpenPGP for you')) self.add(title_label) self.add(text_label)
def on_preset_button_clicked(self, widget): def on_ok(preset_name): if preset_name == '': return preset = {} for name in self.plugin.config_default_values: if name == 'presets': continue widget = self.xml.get_object(name) preset[name] = widget.get_text() preset = {preset_name: preset} presets = dict(list(self.plugin.config['presets'].items()) + \ list(preset.items())) if preset_name not in list(self.plugin.config['presets'].keys()): iter_ = self.preset_liststore.append((preset_name, )) self.plugin.config['presets'] = presets self.set_modal(False) InputDialog(_('Save as Preset'), _('Please type a name for this preset'), 'default', is_modal=True, ok_handler=on_ok)
def _try_install(zip_filename): try: plugin = app.plugin_manager.install_from_zip(zip_filename) except PluginsystemError as er_type: error_text = str(er_type) if error_text == _('Plugin already exists'): _on_plugin_exists(zip_filename) return WarningDialog(error_text, '"%s"' % zip_filename, self) return if not plugin: _show_warn_dialog() return
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=_('Setup successful')) label.get_style_context().add_class('bold16') label.set_valign(Gtk.Align.START) self.add(icon) self.add(label)
def installed_plugins_toggled_cb(self, cell, path): is_active = self.installed_plugins_model[path][Column.ACTIVE] plugin = self.installed_plugins_model[path][Column.PLUGIN] if is_active: app.plugin_manager.deactivate_plugin(plugin) else: try: app.plugin_manager.activate_plugin(plugin) except GajimPluginActivateException as e: WarningDialog(_('Plugin failed'), str(e), transient_for=self.window) return self.installed_plugins_model[path][Column.ACTIVE] = not is_active
def __init__(self, plugin, account): Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) self._con = app.connections[account] self._plugin = plugin self._label = Gtk.Label() self._button = Gtk.Button(label=_('Assign Key')) self._button.get_style_context().add_class('suggested-action') self._button.set_halign(Gtk.Align.CENTER) self._button.set_margin_top(18) self._button.connect('clicked', self._on_assign) self._load_key() self.add(self._label) self.add(self._button) self.show_all()
def _on_not_trusted(event): NewConfirmationCheckDialog( _('Untrusted PGP key'), _('Untrusted PGP key'), _('The PGP key used to encrypt this chat is not ' 'trusted. Do you really want to encrypt this ' 'message?'), _('_Do not ask me again'), [ DialogButton.make( 'Cancel', text=_('_No'), callback=event.on_no), DialogButton.make( 'OK', text=_('_Encrypt Anyway'), callback=event.on_yes) ]).show()
def get_client_data(self, name, node): client_data = self.get(node) if client_data is None: return _('Unknown'), 'xmpp-client-unknown' if client_data.variations is None: client_name, icon_name = client_data.default return client_name, 'xmpp-client-%s' % icon_name variations = get_variations(name) for var in variations: try: return var, 'xmpp-client-%s' % client_data.variations[var] except KeyError: pass client_name, icon_name = client_data.default return client_name, 'xmpp-client-%s' % icon_name
def __init__(self, iter_start, iter_end, buffer_, widget, png_dpi): Thread.__init__(self) self.code = iter_start.get_text(iter_end) self.mark_name = 'LatexRendererMark%s' % str(random.randint(0, 1000)) self.mark = buffer_.create_mark(self.mark_name, iter_start, True) self.buffer_ = buffer_ self.widget = widget self.png_dpi = png_dpi # delete code and show message 'processing' self.buffer_.delete(iter_start, iter_end) # iter_start.forward_char() self.buffer_.insert(iter_start, _('Processing LaTeX')) self.start() # start background processing
def _installed_plugin_toggled(self, _cell, path): is_active = self.installed_plugins_model[path][Column.ACTIVE] plugin = self.installed_plugins_model[path][Column.PLUGIN] if is_active: app.plugin_manager.deactivate_plugin(plugin) else: try: app.plugin_manager.activate_plugin(plugin) except GajimPluginActivateException as e: WarningDialog(_('Plugin failed'), str(e), transient_for=self) return self._ui.configure_plugin_button.set_sensitive( plugin.config_dialog is not None and not is_active) self.installed_plugins_model[path][Column.ACTIVE] = not is_active
def do_draw(self, widget, cr): cr.set_source_rgb(1.0, 1.0, 1.0) layout = PangoCairo.create_layout(cr) text_height = layout.get_pixel_extents()[1].height (width, height) = self.win.get_size() row_height = (height - text_height) // self.rows col_width = width // self.cols cr.set_source_rgb(0, 0, 0) cr.set_line_width(2) for x in range(1, self.cols): cr.move_to(col_width * x, 0) cr.line_to(col_width * x, height - text_height) for x in range(1, self.rows): cr.move_to(0, row_height * x) cr.line_to(width, row_height * x) cr.stroke() cr.move_to(0, height - text_height) if self.state == 'None': if self.session.is_my_turn(): txt = _('It\'s your turn') else: txt = _('It\'s %(name)s\'s turn') % {'name': self.session.name} elif self.state == 'won': txt = _('You won !') elif self.state == 'lost': txt = _('You lost !') elif self.state == 'resign': # Other part resigned txt = _('%(name)s capitulated') % {'name': self.session.name} elif self.state == 'cheated': # Other part cheated txt = _('%(name)s cheated') % {'name': self.session.name} else: # Draw txt = _('It\'s a draw') layout.set_text(txt, -1) # Inform Pango to re-layout the text with the new transformation PangoCairo.update_layout(cr, layout) PangoCairo.show_layout(cr, layout) for i in range(self.rows): for j in range(self.cols): if self.board[i][j] == 'x': self.draw_x(cr, i, j, row_height, col_width) elif self.board[i][j] == 'o': self.draw_o(cr, i, j, row_height, col_width)
def stop_whiteboard(self, reason=None): conn = app.connections[self.chat_control.account] self.sid = None session = conn.get_module('Jingle').get_jingle_session(self.jid, media='xhtml') if session: session.end_session() self.enable_action(False) if reason: txt = _('Whiteboard stopped: %(reason)s') % {'reason': reason} self.chat_control.add_status_message(txt) if not self.whiteboard: return hbox = self.chat_control.xml.get_object('chat_control_hbox') if self.whiteboard.hbox in hbox.get_children(): if hasattr(self.whiteboard, 'hbox'): hbox.remove(self.whiteboard.hbox) self.whiteboard = None
def init(self): self.description = _('Clickable nicknames ' 'in the conversation textview.') self.config_dialog = None self.gui_extension_points = { 'chat_control_base': (self.connect_with_chat_control, self.disconnect_from_chat_control) } self.is_active = None self.gc_controls = {} self.tag_names = [] colors = app.config.get('gc_nicknames_colors') colors = colors.split(':') for i, color in enumerate(colors): tagname = 'gc_nickname_color_' + str(i) self.tag_names.append(tagname)
def create_button(self): actions_hbox = self.chat_control.xml.get_object('hbox') self.button = Gtk.MenuButton(label=None, stock=None, use_underline=True) self.button.get_style_context().add_class( 'chatcontrol-actionbar-button') self.button.set_property('relief', Gtk.ReliefStyle.NONE) self.button.set_property('can-focus', False) img = Gtk.Image() img_path = self.plugin.local_file_path('quick_replies.png') pixbuf = GdkPixbuf.Pixbuf.new_from_file(img_path) img.set_from_pixbuf(pixbuf) self.button.set_image(img) self.button.set_tooltip_text(_('Quick replies')) actions_hbox.pack_start(self.button, False, False , 0) actions_hbox.reorder_child(self.button, len(actions_hbox.get_children()) - 2) self.button.show()
def on_test_button_clicked(self, widget): """ performs very simple checks (check if executable is in PATH) """ self.show_result(_('Test Latex Binary')) exitcode = try_run(['latex', '-version'], None) if exitcode != 0: self.show_result(_(' No LaTeX binary found in PATH')) else: self.show_result(_(' OK')) self.show_result(_('Test dvipng')) exitcode = try_run(['dvipng', '--version'], None) if exitcode != 0: self.show_result(_(' No dvipng binary found in PATH')) else: self.show_result(_(' OK')) self.show_result(_('Test ImageMagick')) exitcode = try_run(['convert', '-version'], None) if exitcode != 0: self.show_result(_(' No convert binary found in PATH')) else: self.show_result(_(' OK'))
def init(self): self.description = _('Allows to block some kind of incoming messages') self.config_dialog = AntiSpamPluginConfigDialog(self) self.gui_extension_points = {} self.events_handlers = { 'atom-entry-received': (ged.POSTCORE, self._nec_atom_entry_received), 'message-received': (ged.PRECORE, self._nec_message_received_received), 'decrypted-message-received': (ged.PRECORE, self._nec_decrypted_message_received_received), 'subscribe-presence-received': (ged.POSTCORE, self._nec_subscribe_presence_received), 'message-outgoing': (ged.OUT_PRECORE, self._nec_message_outgoing) } self.config_default_values = { 'block_pubsub_messages': (False, 'If True, Gajim will block incoming messages from pubsub.'), 'disable_xhtml_muc': (False, ''), 'disable_xhtml_pm': (False, ''), 'block_subscription_requests': (False, ''), 'msgtxt_limit': (-1, ''), 'msgtxt_question': ('Please answer: 12 x 12 =', ''), 'msgtxt_answer': ('', ''), 'antispam_for_conference': (False, ''), 'conference_white_list': ([], ''), # conference private chat jid's 'block_domains': ('', ''), # comma separated list of domain names to block } # List of outgoing jid's # Needs to avoid chat of two anti spam plugins # Contain all jid's where are you initiate a chat self.outgoing_jids = [] self.block_domains = [ h.strip() for h in self.config['block_domains'].split(",") if len(h.strip()) ]
def install_from_zip(self, zip_filename, owerwrite=None): ''' Install plugin from zip and return plugin ''' try: zip_file = zipfile.ZipFile(zip_filename) except zipfile.BadZipfile: # it is not zip file raise PluginsystemError(_('Archive corrupted')) except IOError: raise PluginsystemError(_('Archive empty')) if zip_file.testzip(): # CRC error raise PluginsystemError(_('Archive corrupted')) dirs = [] manifest = None for filename in zip_file.namelist(): if filename.startswith('.') or filename.startswith('/') or \ ('/' not in filename): # members not safe raise PluginsystemError(_('Archive is malformed')) if filename.endswith('/') and filename.find('/', 0, -1) < 0: dirs.append(filename.strip('/')) if 'manifest.ini' in filename.split('/')[1]: manifest = True if not manifest: return if len(dirs) > 1: raise PluginsystemError(_('Archive is malformed')) user_dir = configpaths.get('PLUGINS_USER') plugin_dir = os.path.join(user_dir, dirs[0]) if os.path.isdir(plugin_dir): # Plugin dir already exists if not owerwrite: raise PluginsystemError(_('Plugin already exists')) self.uninstall_plugin(self.get_plugin_by_path(plugin_dir)) zip_file.extractall(user_dir) zip_file.close() plugins = self.scan_dir_for_plugins(plugin_dir, package=True) if not plugins: return self.add_plugin(plugins[0]) plugin = self.plugins[-1] return plugin
def init(self): self.description = _('Allows user to tweak roster window appearance ' '(eg. make it compact).') self.config_default_values = { 'hide_status_combo': (False, ''), 'use_ctr_m': (False, ''), 'menu_visible': (True, ''), 'quick_status': (False, ''), 'contact_status_subs': (False, ''), } self.events_handlers = { 'our-show': (ged.GUI2, self.our_show), 'pep-received': (ged.GUI2, self.pep_received) } self.gui_extension_points = { 'roster_draw_contact': (self.roster_draw_contact, self.disconnect_roster_draw_contact), } self.roster = app.interface.roster self.config_dialog = RosterTweaksPluginConfigDialog(self)
def send_question(self, obj, jid): if obj.mtype != 'chat' and obj.mtype != 'normal': log.info('Anti_spam wrong message type: %s', obj.mtype) return question = self.config['msgtxt_question'] log.info('Anti_spam enabled for %s, question: %s', jid, question) message = _('Antispam enabled. Please answer the question. The message must only ' + \ 'contain the answer. (Messages sent before the correct answer, will be lost): ') \ + question if obj.mtype == 'chat': stanza = nbxmpp.Message(to=jid, body=message, typ=obj.mtype) else: # for 'normal' type stanza = nbxmpp.Message(to=jid, body=message, subject='Antispam enabled', typ=obj.mtype) app.connections[obj.conn.name].connection.send(stanza)
def _try_install(zip_filename): try: plugin = app.plugin_manager.install_from_zip(zip_filename) except PluginsystemError as er_type: error_text = str(er_type) if error_text == _('Plugin already exists'): _on_plugin_exists(zip_filename) return WarningDialog(error_text, '"%s"' % zip_filename, self.window) return if not plugin: show_warn_dialog() return model = self.installed_plugins_model iter_ = model.append([ plugin, plugin.name, False, plugin.activatable, self.get_plugin_icon(plugin) ]) sel = self.installed_plugins_treeview.get_selection() sel.select_iter(iter_)
def create_buttons(self): # create /me button actions_hbox = self.chat_control.xml.get_object('hbox') self.button = Gtk.Button(label=None, stock=None, use_underline=False) self.button.get_style_context().add_class( 'chatcontrol-actionbar-button') self.button.set_relief(Gtk.ReliefStyle.NONE) self.button.set_property('can-focus', False) img = Gtk.Image() img_path = self.plugin.local_file_path('gui_for_me.png') pixbuf = GdkPixbuf.Pixbuf.new_from_file(img_path) img.set_from_pixbuf(pixbuf) self.button.set_image(img) self.button.set_tooltip_text(_('Insert /me to conversation input box,' ' at cursor position')) actions_hbox.pack_start(self.button, False, False , 0) actions_hbox.reorder_child(self.button, len(actions_hbox.get_children()) - 3) id_ = self.button.connect('clicked', self.on_me_button_clicked) self.chat_control.handlers[id_] = self.button self.button.show()
def init(self): self.description = _('PGP encryption as per XEP-0027') if ERROR_MSG: self.activatable = False self.available_text = ERROR_MSG return self.config_dialog = None self.encryption_name = 'PGP' self.allow_zeroconf = True self.gui_extension_points = { 'encrypt' + self.encryption_name: (self._encrypt_message, None), 'decrypt': (self._message_received, None), 'send_message' + self.encryption_name: ( self._before_sendmessage, None), 'encryption_dialog' + self.encryption_name: ( self.on_encryption_button_clicked, None), 'encryption_state' + self.encryption_name: ( self.encryption_state, None)} self.decrypt_queue = queue.Queue() self.thread = None
def _display_installed_plugin_info(self, plugin): self._ui.plugin_name_label.set_text(plugin.name) self._ui.plugin_version_label.set_text(plugin.version) self._ui.plugin_authors_label.set_text(plugin.authors) markup = '<a href="%s">%s</a>' % (plugin.homepage, plugin.homepage) self._ui.plugin_homepage_linkbutton.set_markup(markup) if plugin.available_text: text = _('Warning: %s') % plugin.available_text self._ui.available_text_label.set_text(text) self._ui.available_text.show() # Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=710888 self._ui.available_text.queue_resize() else: self._ui.available_text.hide() self._ui.description.set_text(plugin.description) self._ui.uninstall_plugin_button.set_sensitive(True) self._ui.configure_plugin_button.set_sensitive( plugin.config_dialog is not None and plugin.active)
def check_state(key_id, account): error = None if key_id.endswith('MISMATCH'): verification_status = _('''Contact's identity NOT verified''') info = _('The contact\'s key (%s) <b>does not match</b> the key ' 'assigned in Gajim.') % key_id[:8] elif not key_id: # No key assigned nor a key is used by remote contact verification_status = _('No OpenPGP key assigned') info = _('No OpenPGP key is assigned to this contact. So you cannot' ' encrypt messages.') else: error = app.connections[account].gpg.encrypt('test', [key_id])[1] if error: verification_status = _('''Contact's identity NOT verified''') info = _('OpenPGP key is assigned to this contact, but <b>you ' 'do not trust their key</b>, so message <b>cannot</b> be ' 'encrypted. Use your OpenPGP client to trust their key.') else: verification_status = _('''Contact's identity verified''') info = _('OpenPGP Key is assigned to this contact, and you ' 'trust their key, so messages will be encrypted.') return (verification_status, info)
def init(self): self.description = _('Highlights message entry field in chat window ' 'when given length of message is exceeded.') self.config_dialog = LengthNotifierPluginConfigDialog(self) self.gui_extension_points = { 'chat_control': (self.connect_with_chat_control, self.disconnect_from_chat_control) } self.config_default_values = { 'MESSAGE_WARNING_LENGTH': (140, 'Message length at which notification is invoked.'), 'WARNING_COLOR': ('#F0DB3E', 'Background color of text entry field in chat window when notification is invoked.' ), 'JIDS': ([], 'JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). If empty plugin is used with every JID. [not implemented]' ) }
def init(self): self.description = _('Clickable Juick links , Juick nicks, ' 'preview Juick picturs.\nThe key combination alt + up in the ' 'textbox allow insert the number of last message ' '(comment or topic).') self.config_dialog = JuickPluginConfigDialog(self) self.gui_extension_points = { 'chat_control_base': (self.connect_with_chat_control, self.disconnect_from_chat_control), 'print_special_text': (self.print_special_text, self.print_special_text1),} self.config_default_values = {'SHOW_AVATARS': (False, ''), 'AVATAR_SIZE': (20, 'Avatar size(10-32)'), 'avatars_old': (2419200, 'Update avatars ' 'who are older 28 days'), 'SHOW_PREVIEW': (False, ''), 'PREVIEW_SIZE': (150, 'Preview size(10-512)'), 'LINK_COLOR': ('#B8833E', 'Juick link color'), 'SHOW_TAG_BUTTON': (True, ''), 'ONLY_AUTHOR_AVATAR': (True, ''), 'ONLY_FIRST_AVATAR': (False, ''), 'MENUITEM1': ('tune', ''), 'MENUITEM_TEXT1': ('*tune', ''), 'MENUITEM2': ('geo', ''), 'MENUITEM_TEXT2': ('*geo', ''), 'MENUITEM3': ('gajim', ''), 'MENUITEM_TEXT3': ('*gajim', ''), 'MENUITEM4': ('me', ''), 'MENUITEM_TEXT4': ('/me', ''), 'MENUITEM5': ('', ''), 'MENUITEM_TEXT5': ('', ''), 'MENUITEM6': ('', ''), 'MENUITEM_TEXT6': ('', ''), 'MENUITEM7': ('', ''), 'MENUITEM_TEXT7': ('', ''), 'MENUITEM8': ('', ''), 'MENUITEM_TEXT8': ('', ''), 'MENUITEM9': ('', ''), 'MENUITEM_TEXT9': ('', ''), 'MENUITEM10': ('', ''), 'MENUITEM_TEXT10': ('', ''), } self.chat_control = None self.controls = [] self.conn = None self.cache_path = os.path.join(configpaths.get('AVATAR'), 'juick') if not os.path.isdir(self.cache_path): os.makedirs(self.cache_path)