diff --git a/gajim/common/app.py b/gajim/common/app.py index 9ec68329be6f06ad5937f381081a02c3e68a845f..e41d5c5565a5a26009e7d602a31eae4dc7607739 100644 --- a/gajim/common/app.py +++ b/gajim/common/app.py @@ -140,7 +140,6 @@ 'AV': False, 'GEOCLUE': False, 'UPNP': False, - 'PYCURL': False, 'GSOUND': False, 'GSPELL': False, 'IDLE': False, @@ -239,13 +238,6 @@ def detect_dependencies(): except ValueError: pass - # PYCURL - try: - import pycurl # pylint: disable=unused-import - _dependencies['PYCURL'] = True - except ImportError: - pass - # IDLE try: from gajim.common import idle diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py index 451680b99603443886d469a08f10ad4af6d98482..c2aa9fba5bc90bfdd98241b95d038240d5585432 100644 --- a/gajim/common/helpers.py +++ b/gajim/common/helpers.py @@ -38,7 +38,6 @@ import hashlib import shlex import socket -import time import logging import json import copy @@ -52,7 +51,6 @@ from string import Template import urllib from urllib.parse import unquote -from io import StringIO from encodings.punycode import punycode_encode from functools import wraps from packaging.version import Version as V @@ -84,9 +82,6 @@ from gajim.common.const import SHOW_LIST from gajim.common.structs import URI -if app.is_installed('PYCURL'): - import pycurl - log = logging.getLogger('gajim.c.helpers') @@ -871,137 +866,6 @@ def get_proxy(proxy_name): username=username, password=password) -def get_proxy_info(account): - p = app.config.get_per('accounts', account, 'proxy') - if not p: - p = app.config.get('global_proxy') - if p and p in app.config.get_per('proxies'): - proxy = {} - proxyptr = app.config.get_per('proxies', p) - if not proxyptr: - return proxy - for key in proxyptr.keys(): - proxy[key] = proxyptr[key] - return proxy - -def _get_img_direct(attrs): - """ - Download an image. This function should be launched in a separated thread. - """ - mem = b'' - alt = '' - max_size = 2*1024*1024 - if 'max_size' in attrs: - max_size = attrs['max_size'] - # Wait maximum 10s for connection - socket.setdefaulttimeout(10) - try: - req = urllib.request.Request(attrs['src']) - req.add_header('User-Agent', 'Gajim ' + app.version) - f = urllib.request.urlopen(req) - except Exception as ex: - log.debug('Error loading image %s ', attrs['src'] + str(ex)) - alt = attrs.get('alt', 'Broken image') - else: - # Wait 2s between each byte - try: - f.fp._sock.fp._sock.settimeout(2) - except Exception: - pass - - # On a slow internet connection with ~1000kbps - # you need ~10 seconds for 1 MB - deadline = time.time() + (10 * (max_size / 1048576)) - while True: - if time.time() > deadline: - log.debug('Timeout loading image %s ', attrs['src']) - mem = '' - alt = attrs.get('alt', '') - if alt: - alt += '\n' - alt += _('Timeout loading image') - break - try: - temp = f.read(100) - except socket.timeout as ex: - log.debug('Timeout loading image %s ', attrs['src'] + str(ex)) - alt = attrs.get('alt', '') - if alt: - alt += '\n' - alt += _('Timeout loading image') - break - if temp: - mem += temp - else: - break - if len(mem) > max_size: - alt = attrs.get('alt', '') - if alt: - alt += '\n' - alt += _('Image is too big') - break - f.close() - return (mem, alt) - -def _get_img_proxy(attrs, proxy): - """ - Download an image through a proxy. This function should be launched in a - separated thread. - """ - if not app.is_installed('PYCURL'): - return '', _('PyCURL is not installed') - alt, max_size = '', 2*1024*1024 - if 'max_size' in attrs: - max_size = attrs['max_size'] - try: - b = StringIO() - c = pycurl.Curl() - c.setopt(pycurl.URL, attrs['src'].encode('utf-8')) - c.setopt(pycurl.FOLLOWLOCATION, 1) - # Wait maximum 10s for connection - c.setopt(pycurl.CONNECTTIMEOUT, 10) - - # On a slow internet connection with ~1000kbps - # you need ~10 seconds for 1 MB - c.setopt(pycurl.TIMEOUT, 10 * (max_size / 1048576)) - c.setopt(pycurl.MAXFILESIZE, max_size) - c.setopt(pycurl.WRITEFUNCTION, b.write) - c.setopt(pycurl.USERAGENT, 'Gajim ' + app.version) - # set proxy - c.setopt(pycurl.PROXY, proxy['host'].encode('utf-8')) - c.setopt(pycurl.PROXYPORT, proxy['port']) - if proxy['useauth']: - c.setopt(pycurl.PROXYUSERPWD, proxy['user'].encode('utf-8')\ - + ':' + proxy['pass'].encode('utf-8')) - c.setopt(pycurl.PROXYAUTH, pycurl.HTTPAUTH_ANY) - if proxy['type'] == 'http': - c.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_HTTP) - elif proxy['type'] == 'socks5': - c.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5) - c.close() - t = b.getvalue() - return (t, attrs.get('alt', '')) - except pycurl.error as ex: - alt = attrs.get('alt', '') - if alt: - alt += '\n' - if ex.errno == pycurl.E_FILESIZE_EXCEEDED: - alt += _('Image is too big') - elif ex.errno == pycurl.E_OPERATION_TIMEOUTED: - alt += _('Timeout loading image') - else: - alt += _('Error loading image') - except Exception as ex: - log.debug('Error loading image %s ', attrs['src'] + str(ex)) - alt = attrs.get('alt', 'Broken image') - return ('', alt) - -def download_image(account, attrs): - proxy = get_proxy_info(account) - if proxy and proxy['type'] in ('http', 'socks5'): - return _get_img_proxy(attrs, proxy) - return _get_img_direct(attrs) - def version_condition(current_version, required_version): if V(current_version) < V(required_version): return False diff --git a/gajim/gtk/htmltextview.py b/gajim/gtk/htmltextview.py index 37c41176f227875c5eec8475c441def92817b5d2..f6e18053f5d294a6161775a39800e9030c582556 100644 --- a/gajim/gtk/htmltextview.py +++ b/gajim/gtk/htmltextview.py @@ -33,7 +33,6 @@ import re import logging -import urllib import xml.sax import xml.sax.handler from io import StringIO @@ -42,16 +41,12 @@ from gi.repository import Pango from gi.repository import Gtk from gi.repository import Gdk -from gi.repository import GdkPixbuf from gi.repository import GLib from gajim.common import app -from gajim.common import helpers -from gajim.common.i18n import _ from gajim.common.const import StyleAttr from gajim.common.helpers import open_uri from gajim.common.helpers import parse_uri -from gajim.gtk.util import load_icon from gajim.gtk.util import get_cursor from gajim.gui_menu_builder import get_conv_context_menu @@ -510,123 +505,6 @@ def _create_url(self, href, title, type_, id_): tag.title = title return tag - def _update_img(self, output, attrs, img_mark, tags): - '''Callback function called after the function helpers.download_image. - ''' - mem, alt = output - self._process_img(attrs, (mem, alt, img_mark, tags)) - - 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 _begin_span(self, style, tag=None, id_=None): if style is None: self.styles.append(tag) @@ -730,8 +608,7 @@ def startElement(self, name, attrs): tag.is_anchor = True elif name in LIST_ELEMS: style += ';margin-left: 2em' - elif name == 'img': - tag = self._process_img(attrs) + if name in _element_styles: style += _element_styles[name] # so that explicit styles override implicit ones, diff --git a/mypy.ini b/mypy.ini index a5b726f6257ceec0c276ff8ea185a3dc55642043..bfa75b4a242f2fd851c06fc2e58da61c5acbf65f 100644 --- a/mypy.ini +++ b/mypy.ini @@ -40,9 +40,6 @@ ignore_missing_imports = True [mypy-PIL.*] ignore_missing_imports = True -[mypy-pycurl.*] -ignore_missing_imports = True - [mypy-netifaces.*] ignore_missing_imports = True diff --git a/pylintrc b/pylintrc index 274dcf926be6dea847c2bd431a7a2e331dc1a22d..3cd5791e453ae496e7d3152747f78c5355113dbc 100644 --- a/pylintrc +++ b/pylintrc @@ -3,7 +3,7 @@ # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code -extension-pkg-whitelist=pycurl +extension-pkg-whitelist= # Add files or directories to the blacklist. They should be base names, not # paths.