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 _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])
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)
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)
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
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
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={}¢er={}&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])