コード例 #1
0
ファイル: anti_spam.py プロジェクト: Ape/gajim-plugins
    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)
コード例 #2
0
 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
コード例 #3
0
ファイル: latex.py プロジェクト: gajim/gajim-plugins
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))}
コード例 #4
0
ファイル: latex.py プロジェクト: lheckemann/gajim-plugins
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))
        }
コード例 #5
0
ファイル: pluginmanager.py プロジェクト: irl/gajim
    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))
コード例 #6
0
    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
コード例 #7
0
ファイル: pluginmanager.py プロジェクト: lheckemann/gajim
    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))
コード例 #8
0
        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
コード例 #9
0
 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
コード例 #10
0
 def _nec_atom_entry_received(self, obj):
     if self.config['block_pubsub_messages']:
         log.info('discarding pubdubd message')
         return True
コード例 #11
0
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])
コード例 #12
0
                    '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)
コード例 #13
0
ファイル: anti_spam.py プロジェクト: gajim/gajim-plugins
 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
コード例 #14
0
ファイル: anti_spam.py プロジェクト: gajim/gajim-plugins
 def _nec_atom_entry_received(self, obj):
     if self.config['block_pubsub_messages']:
         log.info('discarding pubdubd message')
         return True
コード例 #15
0
    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