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 # only for 'chat' messages if obj.receipt_request_tag and obj.mtype == 'chat': receipt = nbxmpp.Message(to=obj.fjid, typ='chat') receipt.setTag('received', namespace='urn:xmpp:receipts', attrs={'id': obj.id_}) if obj.thread_id: receipt.setThread(obj.thread_id) gajim.connections[obj.conn.name].connection.send(receipt, now=True) 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) gajim.connections[obj.conn.name].connection.send(stanza, now=True)
def get_lexer_with_fallback(language, default_lexer): lexer = get_lexer(language) if lexer is None: log.info("Falling back to default lexer for %s.", str(self.config['default_lexer'])) lexer = get_lexer_by_name(default_lexer) return lexer
def try_run(argv, directory): try: p = popen_nt_friendly(argv, directory) out = p.communicate()[0] log.info(out) return p.wait() except Exception, e: return _('Error executing "%(command)s": %(error)s') % { 'command': " ".join(argv), 'error': helpers.decode_string(str(e))}
def try_run(argv, directory): try: p = popen_nt_friendly(argv, directory) out = p.communicate()[0] log.info(out) return p.wait() except Exception, e: return _('Error executing "%(command)s": %(error)s') % { 'command': " ".join(argv), 'error': helpers.decode_string(str(e)) }
def add_plugin(self, plugin_class): ''' :todo: what about adding plug-ins that are already added? Module reload and adding class from reloaded module or ignoring adding plug-in? ''' plugin = plugin_class() if plugin not in self.plugins: if not self._plugin_has_entry_in_global_config(plugin): self._create_plugin_entry_in_global_config(plugin) self.plugins.append(plugin) plugin.active = False else: log.info('Not loading plugin %s v%s from module %s (identified by' ' short name: %s). Plugin already loaded.' % (plugin.name, plugin.version, plugin.__module__, plugin.short_name))
def print_special_text(self, special_text, other_tags, graphics=True, iter_=None): # remove qip bbcode special_text = special_text.rsplit('[/img]')[0] if special_text.startswith('www.'): special_text = 'http://' + special_text if special_text.startswith('ftp.'): special_text = 'ftp://' + special_text parts = urlparse(special_text) if parts.scheme not in ["https", "http", "ftp", "ftps"] or \ not parts.netloc: log.info("Not accepting URL for image preview: %s" % special_text) return buffer_ = self.textview.tv.get_buffer() if not iter_: iter_ = buffer_.get_end_iter() # Detect XHTML-IM link ttt = buffer_.get_tag_table() tags_ = [(ttt.lookup(t) if isinstance(t, str) else t) for t in other_tags] for t in tags_: is_xhtml_link = getattr(t, 'href', None) if is_xhtml_link: break # Show URL, until image is loaded (if ever) repl_start = buffer_.create_mark(None, iter_, True) buffer_.insert_with_tags(iter_, special_text, \ *[(ttt.lookup(t) if isinstance(t, str) else t) for t in ["url"]]) repl_end = buffer_.create_mark(None, iter_, True) # First get the http head request with does not fetch data, just headers gajim.thread_interface(self._get_http_head, [self.textview.account, special_text], self._check_mime_size, [special_text, repl_start, repl_end]) # Don't print the URL in the message window (in the calling function) self.textview.plugin_modified = True
def insert_formatted_code(tb, language, code, mark=None, line_break=False): lexer = None if language is None: log.info( "No Language specified. Falling back to default lexer: %s.", str(self.config['default_lexer'])) lexer = get_lexer(self.config['default_lexer']) else: log.debug("Using lexer for %s.", str(language)) lexer = get_lexer_with_fallback(language, self.config['default_lexer']) if lexer is None: it = tb.get_iter_at_mark(mark) tb.insert(it, '\n') else: tokens = pygments.lex(code, lexer) if line_break: log.debug("Inserting newline before code.") it = tb.get_iter_at_mark(mark) tb.insert(it, '\n') it.forward_char() tb.move_mark(mark, it) formatter = GTKFormatter(start_mark=mark) pygments.format(tokens, formatter, tb) endmark = formatter.get_last_mark() if line_break and not endmark is None: it = tb.get_iter_at_mark(endmark) tb.insert(it, '\n') log.debug("Inserting newline after code.") return tb
def _nec_subscribe_presence_received(self, obj): if self.config['block_subscription_requests'] and \ not gajim.contacts.get_contacts(obj.conn.name, obj.jid): log.info('discarding subscription request from %s' % obj.jid) return True
def _nec_atom_entry_received(self, obj): if self.config['block_pubsub_messages']: log.info('discarding pubdubd message') return True
class Base(object): def __init__(self, plugin, chat_control): self.plugin = plugin self.chat_control = chat_control self.textview = self.chat_control.conv_textview if os.name == 'nt': self.backend = backend else: self.backend = default_backend() def print_special_text(self, special_text, other_tags, graphics=True, iter_=None): # remove qip bbcode special_text = special_text.rsplit('[/img]')[0] if special_text.startswith('www.'): special_text = 'http://' + special_text if special_text.startswith('ftp.'): special_text = 'ftp://' + special_text parts = urlparse(special_text) if parts.scheme not in ["https", "http", "ftp", "ftps"] or \ not parts.netloc: log.info("Not accepting URL for image preview: %s" % special_text) return buffer_ = self.textview.tv.get_buffer() if not iter_: iter_ = buffer_.get_end_iter() # Detect XHTML-IM link ttt = buffer_.get_tag_table() tags_ = [(ttt.lookup(t) if isinstance(t, str) else t) for t in other_tags] for t in tags_: is_xhtml_link = getattr(t, 'href', None) if is_xhtml_link: break # Show URL, until image is loaded (if ever) repl_start = buffer_.create_mark(None, iter_, True) buffer_.insert_with_tags(iter_, special_text, \ *[(ttt.lookup(t) if isinstance(t, str) else t) for t in ["url"]]) repl_end = buffer_.create_mark(None, iter_, True) # First get the http head request with does not fetch data, just headers gajim.thread_interface(self._get_http_head, [self.textview.account, special_text], self._check_mime_size, [special_text, repl_start, repl_end]) # Don't print the URL in the message window (in the calling function) self.textview.plugin_modified = True def _check_mime_size(self, (file_mime, file_size), url, repl_start, repl_end): # Check if mime type is acceptable if file_mime == '' and file_size == 0: log.info( "Failed to load HEAD Request for URL: '%s' (see debug log for more info)" % url) # URL is already displayed return if file_mime.lower() not in ACCEPTED_MIME_TYPES: log.info("Not accepted mime type '%s' for URL: '%s'" % (file_mime.lower(), url)) # URL is already displayed return # Check if file size is acceptable if file_size > self.plugin.config['MAX_FILE_SIZE'] or file_size == 0: log.info("File size (%s) too big or unknown (zero) for URL: '%s'" % (str(file_size), url)) # URL is already displayed return # check for encryption (conversations mode) urlparts = urlparse(url) key = '' iv = '' if len(urlparts.fragment): fragment = [] for i in range(0, len(urlparts.fragment), 2): fragment.append(chr(int(urlparts.fragment[i:i + 2], 16))) fragment = ''.join(fragment) key = fragment[16:] iv = fragment[:16] # decrypt if the encryption parameters are correct if len(urlparts.fragment) and len(key) == 32 and len(iv) == 16: def _decryptor( (mem, alt), url, file_mime, repl_start, repl_end, key, iv): if not mem: log.error('Could not download image for URL: %s -- %s' % (url, alt)) return # start self._decrypt_url() in own thread and self._update_img() afterwards gajim.thread_interface( self._decrypt_url, [(mem, alt), key, iv, url], self._update_img, [url, file_mime, repl_start, repl_end, True]) # Start downloading image (_decryptor is callback when download has finished) gajim.thread_interface(self._download_image, [ self.textview.account, { 'src': url, 'max_size': self.plugin.config['MAX_FILE_SIZE'] } ], _decryptor, [url, file_mime, repl_start, repl_end, key, iv])
'src': url, 'max_size': self.plugin.config['MAX_FILE_SIZE'] } ], _decryptor, [url, file_mime, repl_start, repl_end, key, iv]) else: # Start downloading image (self._update_img() is callback when download has finished) gajim.thread_interface(self._download_image, [ self.textview.account, { 'src': url, 'max_size': self.plugin.config['MAX_FILE_SIZE'] } ], self._update_img, [url, file_mime, repl_start, repl_end]) def _decrypt_url(self, (mem, alt), key, iv, url): try: log.info("Before decrypt image") if decryption_available: log.info("Fast decrypt") mem = self.aes_decrypt_fast(key, iv, mem) else: log.info("Slow decrypt") mem = aes_decrypt(key, iv, mem) log.info("After decrypt image") except Exception: log.error( 'Could not decrypt image for URL (exception raised): %s' % url) raise if not mem or not len(mem): log.error('Could not decrypt image for URL: %s' % url) return (None, alt) return (mem, alt)
def scan_dir_for_plugins(path, scan_dirs=True, package=False): r''' Scans given directory for plugin classes. :param path: directory to scan for plugins :type path: str :param scan_dirs: folders inside path are processed as modules :type scan_dirs: boolean :param package: if path points to a single package folder :type package: boolean :return: list of found plugin classes (subclasses of `GajimPlugin` :rtype: [] of class objects :note: currently it only searches for plugin classes in '\*.py' files present in given direcotory `path` (no recursion here) :todo: add scanning zipped modules ''' from plugins.plugins_i18n import _ plugins_found = [] conf = configparser.ConfigParser() fields = ('name', 'short_name', 'version', 'description', 'authors', 'homepage') if not os.path.isdir(path): return plugins_found if package: path, package_name = os.path.split(path) dir_list = [package_name] else: dir_list = os.listdir(path) sys.path.insert(0, path) for elem_name in dir_list: file_path = os.path.join(path, elem_name) if os.path.isfile(file_path) and fnmatch.fnmatch(file_path, '*.py'): module_name = os.path.splitext(elem_name)[0] elif os.path.isdir(file_path) and scan_dirs: module_name = elem_name file_path += os.path.sep else: continue manifest_path = os.path.join(os.path.dirname(file_path), 'manifest.ini') if scan_dirs and (not os.path.isfile(manifest_path)): continue # read metadata from manifest.ini conf.remove_section('info') with open(manifest_path, encoding='utf-8') as conf_file: try: conf.read_file(conf_file) except configparser.Error: log.warning(("Plugin {plugin} not loaded, error loading" " manifest").format(plugin=elem_name) , exc_info=True) continue min_v = conf.get('info', 'min_gajim_version', fallback=None) max_v = conf.get('info', 'max_gajim_version', fallback=None) gajim_v = gajim.config.get('version').split('-', 1)[0] gajim_v_cmp = parse_version(gajim_v) if min_v and gajim_v_cmp < parse_version(min_v): log.warning(('Plugin {plugin} not loaded, newer version of' 'gajim required: {gajim_v} < {min_v}').format( plugin=elem_name, gajim_v=gajim_v, min_v=min_v )) continue if max_v and gajim_v_cmp > parse_version(max_v): log.warning(('Plugin {plugin} not loaded, plugin incompatible ' 'with current version of gajim: ' '{gajim_v} > {max_v}').format( plugin=elem_name, gajim_v=gajim_v, max_v=max_v )) continue module = None try: if module_name in sys.modules: from imp import reload log.info('Reloading %s', module_name) module = reload(sys.modules[module_name]) else: log.info('Loading %s', module_name) module = __import__(module_name) except Exception as error: log.warning( "While trying to load {plugin}, exception occurred".format(plugin=elem_name), exc_info=sys.exc_info() ) continue if module is None: continue log.debug('Attributes processing started') for module_attr_name in [attr_name for attr_name in dir(module) if not (attr_name.startswith('__') or attr_name.endswith('__'))]: module_attr = getattr(module, module_attr_name) log.debug('%s : %s' % (module_attr_name, module_attr)) try: if not issubclass(module_attr, GajimPlugin) or \ module_attr is GajimPlugin: continue log.debug('is subclass of GajimPlugin') module_attr.__path__ = os.path.abspath( os.path.dirname(file_path)) for option in fields: if conf.get('info', option) is '': raise configparser.NoOptionError('field empty') if option == 'description': setattr(module_attr, option, _(conf.get('info', option))) continue setattr(module_attr, option, conf.get('info', option)) plugins_found.append(module_attr) except TypeError: # set plugin localization try: module_attr._ = _ except AttributeError: pass except configparser.NoOptionError: # all fields are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. all fields are required!')) except configparser.NoSectionError: # info section are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. info section are required!')) except configparser.MissingSectionHeaderError: # info section are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. section are required!')) return plugins_found