示例#1
0
def incdec_number(url, incdec, count=1, segments=None):
    """Find a number in the url and increment or decrement it.

    Args:
        url: The current url
        incdec: Either 'increment' or 'decrement'
        count: The number to increment or decrement by
        segments: A set of URL segments to search. Valid segments are:
                  'host', 'port', 'path', 'query', 'anchor'.
                  Default: {'path', 'query'}

    Return:
        The new url with the number incremented/decremented.

    Raises IncDecError if the url contains no number.
    """
    if not url.isValid():
        raise InvalidUrlError(url)

    if segments is None:
        segments = {'path', 'query'}
    valid_segments = {'host', 'port', 'path', 'query', 'anchor'}
    if segments - valid_segments:
        extra_elements = segments - valid_segments
        raise IncDecError("Invalid segments: {}".format(
            ', '.join(extra_elements)), url)

    # Make a copy of the QUrl so we don't modify the original
    url = QUrl(url)
    # Order as they appear in a URL
    segment_modifiers = [
        ('host', url.host, url.setHost),
        ('port', lambda: str(url.port()) if url.port() > 0 else '',
         lambda x: url.setPort(int(x))),
        ('path', url.path, url.setPath),
        ('query', url.query, url.setQuery),
        ('anchor', url.fragment, url.setFragment),
    ]
    # We're searching the last number so we walk the url segments backwards
    for segment, getter, setter in reversed(segment_modifiers):
        if segment not in segments:
            continue

        # Get the last number in a string
        match = re.fullmatch(r'(.*\D|^)(0*)(\d+)(.*)', getter())
        if not match:
            continue

        setter(_get_incdec_value(match, incdec, url, count))
        return url

    raise IncDecError("No number found in URL!", url)
示例#2
0
 def transform(self, value):
     if not value:
         return None
     elif value == 'system':
         return SYSTEM_PROXY
     elif value == 'none':
         return QNetworkProxy(QNetworkProxy.NoProxy)
     url = QUrl(value)
     typ = self.PROXY_TYPES[url.scheme()]
     proxy = QNetworkProxy(typ, url.host())
     if url.port() != -1:
         proxy.setPort(url.port())
     if url.userName():
         proxy.setUser(url.userName())
     if url.password():
         proxy.setPassword(url.password())
     return proxy
示例#3
0
 def __init__(self, connections=[], parent=None):
     """
     Constructor
     
     @param connections list of database connections to add
         (list of strings)
     @param parent reference to the parent widget (QWidget)
     """
     super(SqlBrowser, self).__init__(parent)
     self.setObjectName("SqlBrowser")
     
     self.setWindowTitle(self.tr("SQL Browser"))
     self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))
     
     self.setStyle(Preferences.getUI("Style"),
                   Preferences.getUI("StyleSheet"))
     
     from .SqlBrowserWidget import SqlBrowserWidget
     self.__browser = SqlBrowserWidget(self)
     self.setCentralWidget(self.__browser)
     
     self.__browser.statusMessage.connect(self.statusBar().showMessage)
     
     self.__initActions()
     self.__initMenus()
     self.__initToolbars()
     
     self.resize(self.__browser.size())
     
     self.__warnings = []
     
     for connection in connections:
         url = QUrl(connection, QUrl.TolerantMode)
         if not url.isValid():
             self.__warnings.append(
                 self.tr("Invalid URL: {0}").format(connection))
             continue
         
         err = self.__browser.addConnection(url.scheme(), url.path(),
                                            url.userName(), url.password(),
                                            url.host(), url.port(-1))
         if err.type() != QSqlError.NoError:
             self.__warnings.append(
                 self.tr("Unable to open connection: {0}".format(
                     err.text())))
     
     QTimer.singleShot(0, self.__uiStartUp)
示例#4
0
    def matches(self, qurl: QUrl) -> bool:
        """Check if the pattern matches the given QUrl."""
        qtutils.ensure_valid(qurl)

        if self._match_all:
            return True

        if not self._matches_scheme(qurl.scheme()):
            return False
        # FIXME ignore for file:// like Chromium?
        if not self._matches_host(qurl.host()):
            return False
        if not self._matches_port(qurl.scheme(), qurl.port()):
            return False
        if not self._matches_path(qurl.path()):
            return False

        return True
示例#5
0
def host_tuple(url: QUrl) -> HostTupleType:
    """Get a (scheme, host, port) tuple from a QUrl.

    This is suitable to identify a connection, e.g. for SSL errors.
    """
    ensure_valid(url)
    scheme, host, port = url.scheme(), url.host(), url.port()
    assert scheme
    if not host:
        raise ValueError("Got URL {} without host.".format(
            url.toDisplayString()))
    if port == -1:
        port_mapping = {
            'http': 80,
            'https': 443,
            'ftp': 21,
        }
        try:
            port = port_mapping[scheme]
        except KeyError:
            raise ValueError("Got URL {} with unknown port.".format(
                url.toDisplayString()))
    return scheme, host, port
    def queryProxy(self, query):
        """
        Public method to determine a proxy for a given query.
        
        @param query reference to the query object (QNetworkProxyQuery)
        @return list of proxies in order of preference (list of QNetworkProxy)
        """
        if query.queryType() == QNetworkProxyQuery.UrlRequest and \
           query.protocolTag() in ["http", "https", "ftp"]:
            # use proxy at all ?
            if not Preferences.getUI("UseProxy"):
                return [QNetworkProxy(QNetworkProxy.NoProxy)]

            # test for exceptions
            exceptions = Preferences.getUI("ProxyExceptions")
            if exceptions != self.__exceptions:
                self.__setExceptions(exceptions)
            urlHost = query.url().host()
            for matcher in self.__hostnameMatchers:
                if matcher.match(urlHost):
                    return [QNetworkProxy(QNetworkProxy.NoProxy)]

            # determine proxy
            if Preferences.getUI("UseSystemProxy"):
                proxyList = QNetworkProxyFactory.systemProxyForQuery(query)
                if not Globals.isWindowsPlatform() and \
                   len(proxyList) == 1 and \
                   proxyList[0].type() == QNetworkProxy.NoProxy:
                    # try it the Python way
                    # scan the environment for variables named <scheme>_proxy
                    # scan over whole environment to make this case insensitive
                    for name, value in os.environ.items():
                        name = name.lower()
                        if value and name[-6:] == '_proxy' and \
                           name[:-6] == query.protocolTag().lower():
                            url = QUrl(value)
                            if url.scheme() == "http":
                                proxyType = QNetworkProxy.HttpProxy
                            elif url.scheme() == "https":
                                proxyType = QNetworkProxy.HttpCachingProxy
                            elif url.scheme() == "ftp":
                                proxyType = QNetworkProxy.FtpCachingProxy
                            else:
                                proxyType = QNetworkProxy.HttpProxy
                            proxy = QNetworkProxy(proxyType, url.host(),
                                                  url.port(), url.userName(),
                                                  url.password())
                            proxyList = [proxy]
                            break
                if proxyList:
                    scheme = schemeFromProxyType(proxyList[0].type())
                    if scheme == "":
                        scheme = "Http"
                    if scheme != "NoProxy":
                        proxyList[0].setUser(
                            Preferences.getUI("ProxyUser/{0}".format(scheme)))
                        proxyList[0].setPassword(
                            Preferences.getUI(
                                "ProxyPassword/{0}".format(scheme)))
                    return proxyList
                else:
                    return [QNetworkProxy(QNetworkProxy.NoProxy)]
            else:
                if Preferences.getUI("UseHttpProxyForAll"):
                    protocolKey = "Http"
                else:
                    protocolKey = query.protocolTag().capitalize()
                host = Preferences.getUI("ProxyHost/{0}".format(protocolKey))
                if not host:
                    E5MessageBox.critical(
                        None,
                        QCoreApplication.translate(
                            "E5NetworkProxyFactory",
                            "Proxy Configuration Error"),
                        QCoreApplication.translate(
                            "E5NetworkProxyFactory",
                            """Proxy usage was activated"""
                            """ but no proxy host for protocol"""
                            """ '{0}' configured.""").format(protocolKey))
                    return [QNetworkProxy(QNetworkProxy.DefaultProxy)]
                else:
                    if protocolKey in ["Http", "Https", "Ftp"]:
                        if query.protocolTag() == "ftp":
                            proxyType = QNetworkProxy.FtpCachingProxy
                        elif query.protocolTag() == "https":
                            proxyType = QNetworkProxy.HttpCachingProxy
                        else:
                            proxyType = QNetworkProxy.HttpProxy
                        proxy = QNetworkProxy(
                            proxyType, host,
                            Preferences.getUI("ProxyPort/" + protocolKey),
                            Preferences.getUI("ProxyUser/" + protocolKey),
                            Preferences.getUI("ProxyPassword/" + protocolKey))
                    else:
                        proxy = QNetworkProxy(QNetworkProxy.DefaultProxy)
                    return [proxy, QNetworkProxy(QNetworkProxy.DefaultProxy)]
        else:
            return [QNetworkProxy(QNetworkProxy.NoProxy)]
示例#7
0
class CoverArtImage:

    # Indicate if types are provided by the source, ie. CAA or certain file
    # formats may have types associated with cover art, but some other sources
    # don't provide such information
    support_types = False
    # `is_front` has to be explicitly set, it is used to handle CAA is_front
    # indicator
    is_front = None
    sourceprefix = "URL"

    def __init__(self, url=None, types=None, comment='', data=None):
        if types is None:
            self.types = []
        else:
            self.types = types
        if url is not None:
            self.parse_url(url)
        else:
            self.url = None
        self.comment = comment
        self.datahash = None
        # thumbnail is used to link to another CoverArtImage, ie. for PDFs
        self.thumbnail = None
        self.can_be_saved_to_tags = True
        self.can_be_saved_to_disk = True
        self.can_be_saved_to_metadata = True
        if data is not None:
            self.set_data(data)

    def parse_url(self, url):
        self.url = QUrl(url)
        self.host = string_(self.url.host())
        self.port = self.url.port(80)
        self.path = string_(self.url.path(QUrl.FullyEncoded))
        if self.url.hasQuery():
            self.path += '?' + string_(self.url.query(QUrl.FullyEncoded))

    @property
    def source(self):
        if self.url is not None:
            return "%s: %s" % (self.sourceprefix, self.url.toString())
        else:
            return "%s" % self.sourceprefix

    def is_front_image(self):
        """Indicates if image is considered as a 'front' image.
        It depends on few things:
            - if `is_front` was set, it is used over anything else
            - if `types` was set, search for 'front' in it
            - if `support_types` is False, default to True for any image
            - if `support_types` is True, default to False for any image
        """
        if not self.can_be_saved_to_metadata:
            # ignore thumbnails
            return False
        if self.is_front is not None:
            return self.is_front
        if 'front' in self.types:
            return True
        return (self.support_types is False)

    def imageinfo_as_string(self):
        if self.datahash is None:
            return ""
        return "w=%d h=%d mime=%s ext=%s datalen=%d file=%s" % (self.width,
                                                                self.height,
                                                                self.mimetype,
                                                                self.extension,
                                                                self.datalength,
                                                                self.tempfile_filename)

    def __repr__(self):
        p = []
        if self.url is not None:
            p.append("url=%r" % self.url.toString())
        if self.types:
            p.append("types=%r" % self.types)
        if self.is_front is not None:
            p.append("is_front=%r" % self.is_front)
        if self.comment:
            p.append("comment=%r" % self.comment)
        return "%s(%s)" % (self.__class__.__name__, ", ".join(p))

    def __str__(self):
        p = ['Image']
        if self.url is not None:
            p.append("from %s" % self.url.toString())
        if self.types:
            p.append("of type %s" % ','.join(self.types))
        if self.comment:
            p.append("and comment '%s'" % self.comment)
        return ' '.join(p)

    def __eq__(self, other):
        if self and other:
            if self.types and other.types:
                return (self.datahash, self.types) == (other.datahash, other.types)
            else:
                return self.datahash == other.datahash
        elif not self and not other:
            return True
        else:
            return False

    def __hash__(self):
        if self.datahash is None:
            return 0
        return hash(self.datahash.hash())

    def set_data(self, data):
        """Store image data in a file, if data already exists in such file
           it will be re-used and no file write occurs
        """
        if self.datahash:
            self.datahash.delete_file()
            self.datahash = None

        try:
            (self.width, self.height, self.mimetype, self.extension,
             self.datalength) = imageinfo.identify(data)
        except imageinfo.IdentificationError as e:
            raise CoverArtImageIdentificationError(e)

        try:
            self.datahash = DataHash(data, suffix=self.extension)
        except (OSError, IOError) as e:
            raise CoverArtImageIOError(e)

    @property
    def maintype(self):
        """Returns one type only, even for images having more than one type set.
        This is mostly used when saving cover art to tags because most formats
        don't support multiple types for one image.
        Images coming from CAA can have multiple types (ie. 'front, booklet').
        """
        if self.is_front_image() or not self.types or 'front' in self.types:
            return 'front'
        # TODO: do something better than randomly using the first in the list
        return self.types[0]

    def _make_image_filename(self, filename, dirname, metadata):
        filename = ScriptParser().eval(filename, metadata)
        if config.setting["ascii_filenames"]:
            if isinstance(filename, str):
                filename = unaccent(filename)
            filename = replace_non_ascii(filename)
        if not filename:
            filename = "cover"
        if not os.path.isabs(filename):
            filename = os.path.join(dirname, filename)
        # replace incompatible characters
        if config.setting["windows_compatibility"] or sys.platform == "win32":
            filename = replace_win32_incompat(filename)
        # remove null characters
        if isinstance(filename, bytes):
            filename = filename.replace(b"\x00", "")
        return encode_filename(filename)

    def save(self, dirname, metadata, counters):
        """Saves this image.

        :dirname: The name of the directory that contains the audio file
        :metadata: A metadata object
        :counters: A dictionary mapping filenames to the amount of how many
                    images with that filename were already saved in `dirname`.
        """
        if not self.can_be_saved_to_disk:
            return
        if (config.setting["caa_image_type_as_filename"] and
            not self.is_front_image()):
            filename = self.maintype
            log.debug("Make cover filename from types: %r -> %r",
                      self.types, filename)
        else:
            filename = config.setting["cover_image_filename"]
            log.debug("Using default cover image filename %r", filename)
        filename = self._make_image_filename(filename, dirname, metadata)

        overwrite = config.setting["save_images_overwrite"]
        ext = encode_filename(self.extension)
        image_filename = self._next_filename(filename, counters)
        while os.path.exists(image_filename + ext) and not overwrite:
            if not self._is_write_needed(image_filename + ext):
                break
            image_filename = self._next_filename(filename, counters)
        else:
            new_filename = image_filename + ext
            # Even if overwrite is enabled we don't need to write the same
            # image multiple times
            if not self._is_write_needed(new_filename):
                return
            log.debug("Saving cover image to %r", new_filename)
            try:
                new_dirname = os.path.dirname(new_filename)
                if not os.path.isdir(new_dirname):
                    os.makedirs(new_dirname)
                shutil.copyfile(self.tempfile_filename, new_filename)
            except (OSError, IOError) as e:
                raise CoverArtImageIOError(e)

    def _next_filename(self, filename, counters):
        if counters[filename]:
            new_filename = b"%b (%d)" % (filename, counters[filename])
        else:
            new_filename = filename
        counters[filename] += 1
        return new_filename

    def _is_write_needed(self, filename):
        if (os.path.exists(filename)
                and os.path.getsize(filename) == self.datalength):
            log.debug("Identical file size, not saving %r", filename)
            return False
        return True

    @property
    def data(self):
        """Reads the data from the temporary file created for this image.
        May raise CoverArtImageIOError
        """
        try:
            return self.datahash.data
        except (OSError, IOError) as e:
            raise CoverArtImageIOError(e)

    @property
    def tempfile_filename(self):
        return self.datahash.filename

    def types_as_string(self, translate=True, separator=', '):
        if self.types:
            types = self.types
        elif self.is_front_image():
            types = ['front']
        else:
            types = ['-']
        if translate:
            types = [translate_caa_type(type) for type in types]
        return separator.join(types)
示例#8
0
class CoverArtImage:

    # Indicate if types are provided by the source, ie. CAA or certain file
    # formats may have types associated with cover art, but some other sources
    # don't provide such information
    support_types = False
    # Indicates that the source supports multiple types per image.
    support_multi_types = False
    # `is_front` has to be explicitly set, it is used to handle CAA is_front
    # indicator
    is_front = None
    sourceprefix = "URL"

    def __init__(self,
                 url=None,
                 types=None,
                 comment='',
                 data=None,
                 support_types=None,
                 support_multi_types=None):
        if types is None:
            self.types = []
        else:
            self.types = types
        if url is not None:
            self.parse_url(url)
        else:
            self.url = None
        self.comment = comment
        self.datahash = None
        # thumbnail is used to link to another CoverArtImage, ie. for PDFs
        self.thumbnail = None
        self.can_be_saved_to_tags = True
        self.can_be_saved_to_disk = True
        self.can_be_saved_to_metadata = True
        if support_types is not None:
            self.support_types = support_types
        if support_multi_types is not None:
            self.support_multi_types = support_multi_types
        if data is not None:
            self.set_data(data)

    def parse_url(self, url):
        self.url = QUrl(url)
        self.host = self.url.host()
        self.port = self.url.port(443 if self.url.scheme() == 'https' else 80)
        self.path = self.url.path(QUrl.FullyEncoded)
        if self.url.hasQuery():
            self.path += '?' + self.url.query(QUrl.FullyEncoded)

    @property
    def source(self):
        if self.url is not None:
            return "%s: %s" % (self.sourceprefix, self.url.toString())
        else:
            return "%s" % self.sourceprefix

    def is_front_image(self):
        """Indicates if image is considered as a 'front' image.
        It depends on few things:
            - if `is_front` was set, it is used over anything else
            - if `types` was set, search for 'front' in it
            - if `support_types` is False, default to True for any image
            - if `support_types` is True, default to False for any image
        """
        if not self.can_be_saved_to_metadata:
            # ignore thumbnails
            return False
        if self.is_front is not None:
            return self.is_front
        if 'front' in self.types:
            return True
        return (self.support_types is False)

    def imageinfo_as_string(self):
        if self.datahash is None:
            return ""
        return "w=%d h=%d mime=%s ext=%s datalen=%d file=%s" % (
            self.width, self.height, self.mimetype, self.extension,
            self.datalength, self.tempfile_filename)

    def __repr__(self):
        p = []
        if self.url is not None:
            p.append("url=%r" % self.url.toString())
        if self.types:
            p.append("types=%r" % self.types)
        p.append('support_types=%r' % self.support_types)
        p.append('support_multi_types=%r' % self.support_types)
        if self.is_front is not None:
            p.append("is_front=%r" % self.is_front)
        if self.comment:
            p.append("comment=%r" % self.comment)
        return "%s(%s)" % (self.__class__.__name__, ", ".join(p))

    def __str__(self):
        p = ['Image']
        if self.url is not None:
            p.append("from %s" % self.url.toString())
        if self.types:
            p.append("of type %s" % ','.join(self.types))
        if self.comment:
            p.append("and comment '%s'" % self.comment)
        return ' '.join(p)

    def __eq__(self, other):
        if self and other:
            if self.support_types and other.support_types:
                if self.support_multi_types and other.support_multi_types:
                    return (self.datahash, self.types) == (other.datahash,
                                                           other.types)
                else:
                    return (self.datahash, self.maintype) == (other.datahash,
                                                              other.maintype)
            else:
                return self.datahash == other.datahash
        elif not self and not other:
            return True
        else:
            return False

    def __hash__(self):
        if self.datahash is None:
            return 0
        return hash(self.datahash.hash())

    def set_data(self, data):
        """Store image data in a file, if data already exists in such file
           it will be re-used and no file write occurs
        """
        if self.datahash:
            self.datahash.delete_file()
            self.datahash = None

        try:
            (self.width, self.height, self.mimetype, self.extension,
             self.datalength) = imageinfo.identify(data)
        except imageinfo.IdentificationError as e:
            raise CoverArtImageIdentificationError(e)

        try:
            self.datahash = DataHash(data, suffix=self.extension)
        except (OSError, IOError) as e:
            raise CoverArtImageIOError(e)

    @property
    def maintype(self):
        """Returns one type only, even for images having more than one type set.
        This is mostly used when saving cover art to tags because most formats
        don't support multiple types for one image.
        Images coming from CAA can have multiple types (ie. 'front, booklet').
        """
        if self.is_front_image() or not self.types or 'front' in self.types:
            return 'front'
        # TODO: do something better than randomly using the first in the list
        return self.types[0]

    def _make_image_filename(self, filename, dirname, _metadata):
        metadata = Metadata()
        metadata.copy(_metadata)
        metadata["coverart_maintype"] = self.maintype
        metadata["coverart_comment"] = self.comment
        if self.is_front:
            metadata.add_unique("coverart_types", "front")
        for cover_type in self.types:
            metadata.add_unique("coverart_types", cover_type)
        filename = script_to_filename(filename, metadata)
        if not filename:
            filename = "cover"
        if not os.path.isabs(filename):
            filename = os.path.join(dirname, filename)
        return encode_filename(filename)

    def save(self, dirname, metadata, counters):
        """Saves this image.

        :dirname: The name of the directory that contains the audio file
        :metadata: A metadata object
        :counters: A dictionary mapping filenames to the amount of how many
                    images with that filename were already saved in `dirname`.
        """
        if not self.can_be_saved_to_disk:
            return
        if (config.setting["caa_image_type_as_filename"]
                and not self.is_front_image()):
            filename = self.maintype
            log.debug("Make cover filename from types: %r -> %r", self.types,
                      filename)
        else:
            filename = config.setting["cover_image_filename"]
            log.debug("Using default cover image filename %r", filename)
        filename = self._make_image_filename(filename, dirname, metadata)

        overwrite = config.setting["save_images_overwrite"]
        ext = encode_filename(self.extension)
        image_filename = self._next_filename(filename, counters)
        while os.path.exists(image_filename + ext) and not overwrite:
            if not self._is_write_needed(image_filename + ext):
                break
            image_filename = self._next_filename(filename, counters)
        else:
            new_filename = image_filename + ext
            # Even if overwrite is enabled we don't need to write the same
            # image multiple times
            if not self._is_write_needed(new_filename):
                return
            log.debug("Saving cover image to %r", new_filename)
            try:
                new_dirname = os.path.dirname(new_filename)
                if not os.path.isdir(new_dirname):
                    os.makedirs(new_dirname)
                shutil.copyfile(self.tempfile_filename, new_filename)
            except (OSError, IOError) as e:
                raise CoverArtImageIOError(e)

    def _next_filename(self, filename, counters):
        if counters[filename]:
            new_filename = "%s (%d)" % (decode_filename(filename),
                                        counters[filename])
        else:
            new_filename = filename
        counters[filename] += 1
        return encode_filename(new_filename)

    def _is_write_needed(self, filename):
        if (os.path.exists(filename)
                and os.path.getsize(filename) == self.datalength):
            log.debug("Identical file size, not saving %r", filename)
            return False
        return True

    @property
    def data(self):
        """Reads the data from the temporary file created for this image.
        May raise CoverArtImageIOError
        """
        try:
            return self.datahash.data
        except (OSError, IOError) as e:
            raise CoverArtImageIOError(e)

    @property
    def tempfile_filename(self):
        return self.datahash.filename

    def normalized_types(self):
        if self.types:
            types = sorted(set(self.types))
        elif self.is_front_image():
            types = ['front']
        else:
            types = ['-']
        return types

    def types_as_string(self, translate=True, separator=', '):
        types = self.normalized_types()
        if translate:
            types = [translate_caa_type(type) for type in types]
        return separator.join(types)
示例#9
0
    def queryProxy(self, query):
        """
        Public method to determine a proxy for a given query.
        
        @param query reference to the query object (QNetworkProxyQuery)
        @return list of proxies in order of preference (list of QNetworkProxy)
        """
        if query.queryType() == QNetworkProxyQuery.UrlRequest and query.protocolTag() in ["http", "https", "ftp"]:
            # use proxy at all ?
            if not Preferences.getUI("UseProxy"):
                return [QNetworkProxy(QNetworkProxy.NoProxy)]

            # test for exceptions
            exceptions = Preferences.getUI("ProxyExceptions")
            if exceptions != self.__exceptions:
                self.__setExceptions(exceptions)
            urlHost = query.url().host()
            for matcher in self.__hostnameMatchers:
                if matcher.match(urlHost):
                    return [QNetworkProxy(QNetworkProxy.NoProxy)]

            # determine proxy
            if Preferences.getUI("UseSystemProxy"):
                proxyList = QNetworkProxyFactory.systemProxyForQuery(query)
                if (
                    not Globals.isWindowsPlatform()
                    and len(proxyList) == 1
                    and proxyList[0].type() == QNetworkProxy.NoProxy
                ):
                    # try it the Python way
                    # scan the environment for variables named <scheme>_proxy
                    # scan over whole environment to make this case insensitive
                    for name, value in os.environ.items():
                        name = name.lower()
                        if value and name[-6:] == "_proxy" and name[:-6] == query.protocolTag().lower():
                            url = QUrl(value)
                            if url.scheme() == "http":
                                proxyType = QNetworkProxy.HttpProxy
                            elif url.scheme() == "https":
                                proxyType = QNetworkProxy.HttpCachingProxy
                            elif url.scheme() == "ftp":
                                proxyType = QNetworkProxy.FtpCachingProxy
                            else:
                                proxyType = QNetworkProxy.HttpProxy
                            proxy = QNetworkProxy(proxyType, url.host(), url.port(), url.userName(), url.password())
                            proxyList = [proxy]
                            break
                if proxyList:
                    scheme = schemeFromProxyType(proxyList[0].type())
                    if scheme == "":
                        scheme = "Http"
                    if scheme != "NoProxy":
                        proxyList[0].setUser(Preferences.getUI("ProxyUser/{0}".format(scheme)))
                        proxyList[0].setPassword(Preferences.getUI("ProxyPassword/{0}".format(scheme)))
                    return proxyList
                else:
                    return [QNetworkProxy(QNetworkProxy.NoProxy)]
            else:
                if Preferences.getUI("UseHttpProxyForAll"):
                    protocolKey = "Http"
                else:
                    protocolKey = query.protocolTag().capitalize()
                host = Preferences.getUI("ProxyHost/{0}".format(protocolKey))
                if not host:
                    E5MessageBox.critical(
                        None,
                        QCoreApplication.translate("E5NetworkProxyFactory", "Proxy Configuration Error"),
                        QCoreApplication.translate(
                            "E5NetworkProxyFactory",
                            """Proxy usage was activated"""
                            """ but no proxy host for protocol"""
                            """ '{0}' configured.""",
                        ).format(protocolKey),
                    )
                    return [QNetworkProxy(QNetworkProxy.DefaultProxy)]
                else:
                    if protocolKey in ["Http", "Https", "Ftp"]:
                        if query.protocolTag() == "ftp":
                            proxyType = QNetworkProxy.FtpCachingProxy
                        elif query.protocolTag() == "https":
                            proxyType = QNetworkProxy.HttpCachingProxy
                        else:
                            proxyType = QNetworkProxy.HttpProxy
                        proxy = QNetworkProxy(
                            proxyType,
                            host,
                            Preferences.getUI("ProxyPort/" + protocolKey),
                            Preferences.getUI("ProxyUser/" + protocolKey),
                            Preferences.getUI("ProxyPassword/" + protocolKey),
                        )
                    else:
                        proxy = QNetworkProxy(QNetworkProxy.DefaultProxy)
                    return [proxy, QNetworkProxy(QNetworkProxy.DefaultProxy)]
        else:
            return [QNetworkProxy(QNetworkProxy.NoProxy)]