コード例 #1
0
 def on_yes(checked):
     if checked:
         obj.conn.gpg.always_trust.append(obj.keyID)
     app.thread_interface(
         self.get_gpg(account).encrypt,
         [obj.message, key_list, True],
         _on_encrypted, [])
コード例 #2
0
    def _check_mime_size(self, tuple_arg,
                         url, weburl, repl_start, repl_end, filepaths,
                         key, iv, encrypted):
        file_mime, file_size = tuple_arg
        # Check if mime type is acceptable
        if not file_mime or not file_size:
            log.info("Failed to load HEAD Request for URL: '%s' "
                     "mime: %s, size: %s", url, file_mime, file_size)
            # 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
        max_size = int(self.plugin.config['MAX_FILE_SIZE'])
        if file_size > max_size or file_size == 0:
            log.info("File size (%s) too big or unknown (zero) for URL: '%s'",
                     file_size, url)
            # URL is already displayed
            return

        attributes = {'src': url,
                      'verify': self.plugin.config['VERIFY'],
                      'max_size': max_size,
                      'filepaths': filepaths,
                      'key': key,
                      'iv': iv}

        app.thread_interface(
            self._download_image, [self.textview.account,
                                   attributes, encrypted],
            self._update_img, [weburl, repl_start, repl_end,
                               filepaths[0], encrypted])
コード例 #3
0
ファイル: helpers.py プロジェクト: slokhorst/gajim
def exec_command(command, use_shell=False, posix=True):
    """
    execute a command. if use_shell is True, we run the command as is it was
    typed in a console. So it may be dangerous if you are not sure about what
    is executed.
    """
    if use_shell:
        subprocess.Popen('%s &' % command, shell=True).wait()
    else:
        args = shlex.split(command, posix=posix)
        process = subprocess.Popen(args)
        app.thread_interface(process.wait)
コード例 #4
0
    def _encrypt_message(self, conn, obj, callback):
        account = conn.name
        if not obj.message:
            # We only encrypt the actual message
            self._finished_encrypt(obj, callback=callback)
            return

        if obj.keyID == 'UNKNOWN':
            error = _('Neither the remote presence is signed, nor a key was '
                      'assigned.')
        elif obj.keyID.endswith('MISMATCH'):
            error = _('The contact\'s key (%s) does not match the key assigned '
                      'in Gajim.' % obj.keyID[:8])
        else:
            my_key_id = app.config.get_per('accounts', account, 'keyid')
            key_list = [obj.keyID, my_key_id]

            def _on_encrypted(output):
                msgenc, error = output
                if error.startswith('NOT_TRUSTED'):
                    def on_yes(checked):
                        if checked:
                            obj.conn.gpg.always_trust.append(obj.keyID)
                        app.thread_interface(
                            self.get_gpg(account).encrypt,
                            [obj.message, key_list, True],
                            _on_encrypted, [])

                    def on_no():
                        self._finished_encrypt(
                            obj, msgenc=msgenc, error=error, conn=conn)

                    YesNoDialog(
                        _('Untrusted OpenPGP key'),
                        _('The OpenPGP key used to encrypt this chat is not '
                          'trusted. Do you really want to encrypt this '
                          'message?'),
                        checktext=_('_Do not ask me again'),
                        on_response_yes=on_yes,
                        on_response_no=on_no)
                else:
                    self._finished_encrypt(
                        obj, msgenc=msgenc, error=error, conn=conn,
                        callback=callback)
            app.thread_interface(
                self.get_gpg(account).encrypt,
                [obj.message, key_list, False],
                _on_encrypted, [])
            return
        self._finished_encrypt(conn, obj, error=error)
コード例 #5
0
    def _process_img(self, attrs, loaded=None):
        '''Process a img tag.
        '''
        mem = ''
        pixbuf = None
        replace_mark = None
        replace_tags = None

        try:
            if attrs['src'].startswith('data:image/'):
                # The "data" URL scheme http://tools.ietf.org/html/rfc2397
                import base64
                img = attrs['src'].split(',')[1]
                mem = base64.standard_b64decode(
                    urllib.parse.unquote(img).encode('utf-8'))
            elif loaded is not None:
                (mem, alt, replace_mark, replace_tags) = loaded
            else:
                if self.conv_textview:
                    img_mark = self.textbuf.create_mark(None, self.iter, True)
                    app.thread_interface(
                        helpers.download_image,
                        [self.conv_textview.account, attrs], self._update_img,
                        [attrs, img_mark,
                         self._get_style_tags()])
                    alt = attrs.get('alt', '')
                    if alt:
                        alt += '\n'
                    alt += _('Loading')
                    pixbuf = load_icon('image-missing',
                                       self.textview,
                                       pixbuf=True)
            if mem:
                # Caveat: GdkPixbuf is known not to be safe to load
                # images from network... this program is now potentially
                # hackable ;)
                loader = GdkPixbuf.PixbufLoader()
                dims = [0, 0]

                def height_cb(length):
                    dims[1] = length

                def width_cb(length):
                    dims[0] = length

                # process width and height attributes
                width = attrs.get('width')
                height = attrs.get('height')
                # override with width and height styles
                for attr, val in style_iter(attrs.get('style', '')):
                    if attr == 'width':
                        width = val
                    elif attr == 'height':
                        height = val
                if width:
                    self._parse_length(width, False, False, 1, 1000, width_cb)
                if height:
                    self._parse_length(height, False, False, 1, 1000,
                                       height_cb)

                def set_size(_pixbuf, width_, height_, dims):
                    """
                    FIXME: Floats should be relative to the whole textview, and
                    resize with it. This needs new pifbufs for every resize,
                    GdkPixbuf.Pixbuf.scale_simple or similar.
                    """
                    if isinstance(dims[0], float):
                        dims[0] = int(dims[0] * width_)
                    elif not dims[0]:
                        dims[0] = width_
                    if isinstance(dims[1], float):
                        dims[1] = int(dims[1] * height_)
                    if not dims[1]:
                        dims[1] = height_
                    loader.set_size(*dims)

                if width or height:
                    loader.connect('size-prepared', set_size, dims)
                loader.write(mem)
                loader.close()
                pixbuf = loader.get_pixbuf()
                alt = attrs.get('alt', '')
            working_iter = self.iter
            if replace_mark is not None:
                working_iter = self.textbuf.get_iter_at_mark(replace_mark)
                next_iter = working_iter.copy()
                next_iter.forward_char()
                self.textbuf.delete(working_iter, next_iter)
                self.textbuf.delete_mark(replace_mark)
            if pixbuf is not None:
                if replace_mark:
                    tags = replace_tags
                else:
                    tags = self._get_style_tags()
                if tags:
                    tmpmark = self.textbuf.create_mark(None, working_iter,
                                                       True)
                self.textbuf.insert_pixbuf(working_iter, pixbuf)
                self.starting = False
                if tags:
                    start = self.textbuf.get_iter_at_mark(tmpmark)
                    for tag in tags:
                        self.textbuf.apply_tag(tag, start, working_iter)
                    self.textbuf.delete_mark(tmpmark)
            else:
                self._insert_text('[IMG: %s]' % alt, working_iter)
        except Exception as ex:
            log.error('Error loading image %s', str(ex))
            pixbuf = None
            alt = attrs.get('alt', 'Broken image')
            try:
                loader.close()
            except Exception:
                pass
        return pixbuf
コード例 #6
0
ファイル: plugin.py プロジェクト: dreamsxin/gajim-plugins
 def print_special_text(self, special_text, other_tags, graphics, additional_data, iter_):
     self.textview.plugin_modified = True
     buffer_ = self.textview.tv.get_buffer()
     if not iter_:
         iter_ = buffer_.get_end_iter()
     if app.interface.sharp_slash_re.match(special_text):
         # insert post num #123456//
         tag = self.get_iter_and_tag('sharp_slash', buffer_)
         buffer_.insert_with_tags(iter_, special_text, tag)
         self.last_juick_num = special_text
         return
     if app.interface.juick_nick_re.match(special_text):
         # insert juick nick @nickname////
         tag = self.get_iter_and_tag('juick_nick', buffer_)
         mark = buffer_.create_mark(None, iter_, True)
         nick = special_text[1:].rstrip(':')
         buffer_.insert_with_tags(iter_, special_text, tag)
         # insert avatars
         if not self.plugin.config['SHOW_AVATARS']:
             return
         b_nick = buffer_.get_text(buffer_.get_start_iter(),
             buffer_.get_iter_at_mark(mark),False)
         if self.plugin.config['ONLY_AUTHOR_AVATAR'] and not \
         special_text.endswith(':') and b_nick[-9:] not in ('Subscribed to '
         ):
             return
         if self.plugin.config['ONLY_FIRST_AVATAR']:
             if b_nick[-9:] not in ('Reply by ', 'message from ', 'ended by ',
             'Subscribed to '):
                 if b_nick[-2] != app.config.get('after_nickname'):
                     return
                 elif b_nick[-1] == '\n':
                     return
         conn = app.connections[self.chat_control.account]
         if not conn.connected:
             return
         # search id in the db
         query = "select nick, id from person where nick = :nick"
         self.plugin.cursor.execute(query, {'nick':nick})
         db_item = self.plugin.cursor.fetchone()
         if db_item:
             # nick in the db
             pixbuf = self.get_avatar(db_item[1], nick, True)
             if not pixbuf:
                 return
             end_iter = buffer_.get_iter_at_mark(mark)
             anchor = buffer_.create_child_anchor(end_iter)
             img = TextViewImage(anchor, nick)
             img.set_from_pixbuf(pixbuf)
             img.show()
             self.textview.tv.add_child_at_anchor(img, anchor)
             return
         else:
             # nick not in the db
             id_ = conn.connection.getAnID()
             to = '*****@*****.**'
             iq = nbxmpp.Iq('get', to=to)
             a = iq.addChild(name='query',
                 namespace='http://juick.com/query#users')
             a.addChild(name='user', namespace='http://juick.com/user',
                 attrs={'uname': nick})
             iq.setID(id_)
             conn.connection.SendAndCallForResponse(iq, self._on_response,
                 {'mark': mark, 'special_text': special_text})
             return
     if app.interface.juick_pic_re.match(special_text) and \
         self.plugin.config['SHOW_PREVIEW']:
         # show pics preview
         tag = self.get_iter_and_tag('url', buffer_)
         mark = buffer_.create_mark(None, iter_, True)
         buffer_.insert_with_tags(iter_, special_text, tag)
         uid = special_text.split('/')[-1]
         url = "http://i.juick.com/photos-512/%s" % uid
         app.thread_interface(self.insert_pic_preview, [mark, special_text,
             url])
         return
     self.textview.plugin_modified = False
コード例 #7
0
    def print_real_text(self, real_text, text_tags, graphics, iter_,
                        additional_data):

        if len(real_text.split(' ')) > 1:
            # urlparse dont recognises spaces as URL delimiter
            log.debug('Url with text will not be displayed: %s', real_text)
            return

        urlparts = urlparse(real_text)
        if not self._accept_uri(urlparts, real_text, additional_data):
            return

        # Don't print the URL in the message window (in the calling function)
        self.textview.plugin_modified = True

        buffer_ = self.textview.tv.get_buffer()
        if not iter_:
            iter_ = buffer_.get_end_iter()

        # Show URL, until image is loaded (if ever)
        ttt = buffer_.get_tag_table()
        repl_start = buffer_.create_mark(None, iter_, True)
        buffer_.insert_with_tags(iter_, real_text,
            *[(ttt.lookup(t) if isinstance(t, str) else t) for t in ["url"]])
        repl_end = buffer_.create_mark(None, iter_, True)

        # Handle geo:-URIs
        if real_text.startswith('geo:'):
            if self.plugin.config['GEO_PREVIEW_PROVIDER'] == 'no_preview':
                return
            size = self.plugin.config['PREVIEW_SIZE']
            geo_provider = self.plugin.config['GEO_PREVIEW_PROVIDER']
            key = ''
            iv = ''
            encrypted = False
            ext = '.png'
            color = 'blue'
            zoom = 16
            location = real_text[4:]
            lat, _, lon = location.partition(',')
            if lon == '':
                return

            filename = 'location_' + geo_provider + '_' \
                + location.replace(',', '_').replace('.', '-')
            newfilename = filename + ext
            thumbfilename = filename + '_thumb_' \
                + str(self.plugin.config['PREVIEW_SIZE']) + ext
            filepath = os.path.join(self.directory, newfilename)
            thumbpath = os.path.join(self.thumbpath, thumbfilename)
            filepaths = [filepath, thumbpath]

            # Google
            if geo_provider == 'Google':
                url = 'https://maps.googleapis.com/maps/api/staticmap?' \
                      'center={}&zoom={}&size={}x{}&markers=color:{}' \
                      '|label:.|{}'.format(location, zoom, size, size,
                                           color, location)
                weburl = 'https://www.google.com/maps/place/{}' \
                         .format(location)
                real_text = url
            else:
                # OpenStreetMap / MapQuest
                apikey = 'F7x36jLVv2hiANVAXmhwvUB044XvGASh'

                url = 'https://open.mapquestapi.com/staticmap/v4/' \
                      'getmap?key={}&center={}&zoom={}&size={},{}&type=map' \
                      '&imagetype=png&pois={},{}&scalebar=false' \
                      .format(apikey, location, zoom, size, size, color,
                              location)
                weburl = 'http://www.openstreetmap.org/' \
                         '?mlat={}&mlon={}#map={}/{}/{}&layers=N' \
                         .format(lat, lon, zoom, lat, lon)
                real_text = url
        else:
            weburl = real_text
            filename = os.path.basename(urlparts.path)
            ext = os.path.splitext(filename)[1]
            name = os.path.splitext(filename)[0]
            namehash = hashlib.sha1(real_text.encode('utf-8')).hexdigest()
            newfilename = name + '_' + namehash + ext
            thumbfilename = name + '_' + namehash + '_thumb_' \
                + str(self.plugin.config['PREVIEW_SIZE']) + ext

            filepath = os.path.join(self.directory, newfilename)
            thumbpath = os.path.join(self.thumbpath, thumbfilename)
            filepaths = [filepath, thumbpath]

            key = ''
            iv = ''
            encrypted = False
            if urlparts.fragment:
                fragment = binascii.unhexlify(urlparts.fragment)
                key = fragment[16:]
                iv = fragment[:16]
                if len(key) == 32 and len(iv) == 16:
                    encrypted = True
                if not encrypted:
                    key = fragment[12:]
                    iv = fragment[:12]
                    if len(key) == 32 and len(iv) == 12:
                        encrypted = True

        # file exists but thumbnail got deleted
        if os.path.exists(filepath) and not os.path.exists(thumbpath):
            if urlparts.scheme == 'geo':
                    real_text = weburl
            with open(filepath, 'rb') as f:
                mem = f.read()
            app.thread_interface(
                self._save_thumbnail, [thumbpath, mem],
                self._update_img, [real_text, repl_start,
                                   repl_end, filepath, encrypted])

        # display thumbnail if already downloadeded
        # (but only if file also exists)
        elif os.path.exists(filepath) and os.path.exists(thumbpath):
            if urlparts.scheme == 'geo':
                    real_text = weburl
            app.thread_interface(
                self._load_thumbnail, [thumbpath],
                self._update_img, [real_text, repl_start,
                                   repl_end, filepath, encrypted])

        # or download file, calculate thumbnail and finally display it
        else:
            if encrypted and not decryption_available:
                log.debug('Please install Crytography to decrypt pictures')
            else:
                # First get the http head request
                # which does not fetch data, just headers
                # then check the mime type and filesize
                if urlparts.scheme == 'aesgcm':
                    real_text = 'http://' + real_text[9:]
                verify = self.plugin.config['VERIFY']
                app.thread_interface(
                    get_http_head, [self.textview.account, real_text, verify],
                    self._check_mime_size, [real_text, weburl, repl_start,
                                            repl_end, filepaths, key, iv,
                                            encrypted])