Exemple #1
0
 def __guessUrlFromPath(self, path):
     """
     Private method to guess an URL given a path string.
     
     @param path path string to guess an URL for (string)
     @return guessed URL (QUrl)
     """
     manager = self.__mainWindow.openSearchManager()
     path = Utilities.fromNativeSeparators(path)
     url = manager.convertKeywordSearchToUrl(path)
     if url.isValid():
         return url
     
     try:
         url = QUrl.fromUserInput(path)
     except AttributeError:
         url = QUrl(path)
     
     if url.scheme() == "about" and \
        url.path() == "home":
         url = QUrl("eric:home")
     
     if url.scheme() in ["s", "search"]:
         url = manager.currentEngine().searchUrl(url.path().strip())
     
     if url.scheme() != "" and \
        (url.host() != "" or url.path() != ""):
         return url
     
     urlString = Preferences.getHelp("DefaultScheme") + path.strip()
     url = QUrl.fromEncoded(urlString.encode("utf-8"), QUrl.TolerantMode)
     
     return url
Exemple #2
0
    def __guessUrlFromPath(self, path):
        """
        Private method to guess an URL given a path string.
        
        @param path path string to guess an URL for (string)
        @return guessed URL (QUrl)
        """
        manager = self.__mainWindow.openSearchManager()
        path = Utilities.fromNativeSeparators(path)
        url = manager.convertKeywordSearchToUrl(path)
        if url.isValid():
            return url

        try:
            url = QUrl.fromUserInput(path)
        except AttributeError:
            url = QUrl(path)

        if url.scheme() == "about" and \
           url.path() == "home":
            url = QUrl("eric:home")

        if url.scheme() in ["s", "search"]:
            url = manager.currentEngine().searchUrl(url.path().strip())

        if url.scheme() != "" and \
           (url.host() != "" or url.path() != ""):
            return url

        urlString = Preferences.getHelp("DefaultScheme") + path.strip()
        url = QUrl.fromEncoded(urlString.encode("utf-8"), QUrl.TolerantMode)

        return url
Exemple #3
0
def _has_explicit_scheme(url: QUrl):
    """Check if a url has an explicit scheme given.

    Args:
        url: The URL as QUrl.
    """
    # Note that generic URI syntax actually would allow a second colon
    # after the scheme delimiter. Since we don't know of any URIs
    # using this and want to support e.g. searching for scoped C++
    # symbols, we treat this as not a URI anyways.
    return (url.isValid() and url.scheme() and (url.host() or url.path())
            and " " not in url.path() and not url.path().startswith(":"))
Exemple #4
0
 def _linkClicked(self, url: QUrl) -> None:
     scheme = url.scheme()
     if scheme == 'file':
         # Open the file in an external application.
         utilities.openFile(url.path())
     elif scheme == 'http' or scheme == 'https':
         # Open the web page in the default browser.
         webbrowser.open_new_tab(url.toString())
     elif scheme == 'item':
         # Clear the search and select the item (if present in the tree).
         self._searchEdit.clear()
         self._model.searchText = ''
         index = self._model.findItemById(url.path())
         if index.isValid():
             self._treeView.setCurrentIndex(index)
def qute_pdfjs(url: QUrl) -> _HandlerRet:
    """Handler for qute://pdfjs.

    Return the pdf.js viewer or redirect to original URL if the file does not
    exist.
    """
    if url.path() == '/file':
        filename = QUrlQuery(url).queryItemValue('filename')
        if not filename:
            raise UrlInvalidError("Missing filename")
        if '/' in filename or os.sep in filename:
            raise RequestDeniedError("Path separator in filename.")

        path = _pdf_path(filename)
        with open(path, 'rb') as f:
            data = f.read()

        mimetype = utils.guess_mimetype(filename, fallback=True)
        return mimetype, data

    if url.path() == '/web/viewer.html':
        query = QUrlQuery(url)
        filename = query.queryItemValue("filename")
        if not filename:
            raise UrlInvalidError("Missing filename")

        path = _pdf_path(filename)
        if not os.path.isfile(path):
            source = query.queryItemValue('source')
            if not source:  # This may happen with old URLs stored in history
                raise UrlInvalidError("Missing source")
            raise Redirect(QUrl(source))

        data = pdfjs.generate_pdfjs_page(filename, url)
        return 'text/html', data

    try:
        data = pdfjs.get_pdfjs_res(url.path())
    except pdfjs.PDFJSNotFound as e:
        # Logging as the error might get lost otherwise since we're not showing
        # the error page if a single asset is missing. This way we don't lose
        # information, as the failed pdfjs requests are still in the log.
        log.misc.warning(
            "pdfjs resource requested but not found: {}".format(e.path))
        raise NotFoundError("Can't find pdfjs resource '{}'".format(e.path))
    else:
        mimetype = utils.guess_mimetype(url.fileName(), fallback=True)
        return mimetype, data
Exemple #6
0
def qute_settings(url: QUrl) -> _HandlerRet:
    """Handler for qute://settings. View/change qute configuration."""
    global csrf_token

    if url.path() == '/set':
        if url.password() != csrf_token:
            message.error("Invalid CSRF token for qute://settings!")
            raise RequestDeniedError("Invalid CSRF token!")
        return _qute_settings_set(url)

    # Requests to qute://settings/set should only be allowed from
    # qute://settings. As an additional security precaution, we generate a CSRF
    # token to use here.
    if secrets:
        csrf_token = secrets.token_urlsafe()
    else:
        # On Python < 3.6, from secrets.py
        token = base64.urlsafe_b64encode(os.urandom(32))
        csrf_token = token.rstrip(b'=').decode('ascii')

    src = jinja.render('settings.html',
                       title='settings',
                       configdata=configdata,
                       confget=config.instance.get_str,
                       csrf_token=csrf_token)
    return 'text/html', src
 def __init__(self, qml):
   app = QGuiApplication(sys.argv)
   
   model = QmlModel()
   model.register()
   
   qmlUrl=QUrl(qml)
   assert qmlUrl.isValid()
   print(qmlUrl.path())
   #assert qmlUrl.isLocalFile()
   
   """
   Create an engine a reference to the window?
   
   window = QuickWindowFactory().create(qmlUrl=qmlUrl)
   window.show() # visible
   """
   engine = QQmlApplicationEngine()
   '''
   Need this if no stdio, i.e. Android, OSX, iOS.
   OW, qWarnings to stdio.
   engine.warnings.connect(self.errors)
   '''
   engine.load(qmlUrl)
   engine.quit.connect(app.quit)
   
   app.exec_()   # !!! C exec => Python exec_
   print("Application returned")
Exemple #8
0
 def acceptNavigationRequest(self, url: QUrl, _type, isMainFrame):
     """При запросе урла со схемой file возбуждает событие и запрещает загрузку этого урла"""
     if url.scheme() == 'file':
         QCoreApplication.sendEvent(self.parent(), MyEvent(url.path()))
         return False
     return super(WebEnginePage,
                  self).acceptNavigationRequest(url, _type, isMainFrame)
Exemple #9
0
    def load_group(self, file: QUrl):
        group_loader = GroupLoader.auto(file=file.path(),
                                        professor=self.professor,
                                        session=self.loading_session)

        group = group_loader.get_group()
        self._apply_group(group.name, group_loader.get_students_list())
Exemple #10
0
def filename_from_url(url: QUrl, fallback: str = None) -> Optional[str]:
    """Get a suitable filename from a URL.

    Args:
        url: The URL to parse, as a QUrl.
        fallback: Value to use if no name can be determined.

    Return:
        The suggested filename as a string, or None.
    """
    if not url.isValid():
        return fallback

    if url.scheme().lower() == 'data':
        mimetype, _encoding = mimetypes.guess_type(url.toString())
        if not mimetype:
            return fallback

        ext = utils.mimetype_extension(mimetype) or ''
        return 'download' + ext

    pathname = posixpath.basename(url.path())
    if pathname:
        return pathname
    elif url.host():
        return url.host() + '.html'
    else:
        return fallback
Exemple #11
0
def test_client():
    q=QUrl("entry: abc")
    print(q.toString().split(":")[1].strip("/ "))
    print(q.scheme())
    print(q.host())
    print(q.path())
    print(q.fragment())
Exemple #12
0
def test_failed_dl_update(config_stub, basedir, download_stub,
                          data_tmpdir, tmpdir, win_registry):
    """One blocklist fails to download.

    Ensure hosts from this list are not blocked.
    """
    dl_fail_blocklist = QUrl(create_blocklist(tmpdir,
                                              blocked_hosts=CLEAN_HOSTS,
                                              name='download_will_fail',
                                              line_format='one_per_line'))
    hosts_to_block = generic_blocklists(tmpdir) + [dl_fail_blocklist]
    config_stub.data = {
        'content': {
            'host-block-lists': hosts_to_block,
            'host-blocking-enabled': True,
            'host-blocking-whitelist': None,
        }
    }
    host_blocker = adblock.HostBlocker()
    host_blocker.adblock_update(0)
    while host_blocker._in_progress:
        current_download = host_blocker._in_progress[0]
        # if current download is the file we want to fail, make it fail
        if current_download.name == dl_fail_blocklist.path():
            current_download.successful = False
        current_download.finished.emit()
    host_blocker.read_hosts()
    assert_urls(host_blocker, whitelisted=[])
    def __init__(self, qml):
        app = QGuiApplication(sys.argv)

        model = QmlModel()
        model.register()

        qmlUrl = QUrl(qml)
        assert qmlUrl.isValid()
        print(qmlUrl.path())
        # assert qmlUrl.isLocalFile()

        """
    Create an engine a reference to the window?
    
    window = QuickWindowFactory().create(qmlUrl=qmlUrl)
    window.show() # visible
    """
        engine = QQmlApplicationEngine()
        """
    Need this if no stdio, i.e. Android, OSX, iOS.
    OW, qWarnings to stdio.
    engine.warnings.connect(self.errors)
    """
        engine.load(qmlUrl)
        engine.quit.connect(app.quit)

        app.exec_()  # !!! C exec => Python exec_
        print("Application returned")
Exemple #14
0
def _the_compiler_redir(url: QUrl) -> bool:
    p = url.path().strip('/')
    res = re.search(r"\w+$", p)
    if p.startswith('view/') and res:
        url.setPath(urljoin("/view/raw/", res.group()))
        return True
    return False
Exemple #15
0
def test_failed_dl_update(config_stub, basedir, download_stub, data_tmpdir,
                          tmpdir, win_registry):
    """One blocklist fails to download.

    Ensure hosts from this list are not blocked.
    """
    dl_fail_blocklist = QUrl(
        create_blocklist(tmpdir,
                         blocked_hosts=CLEAN_HOSTS,
                         name='download_will_fail',
                         line_format='one_per_line'))
    hosts_to_block = generic_blocklists(tmpdir) + [dl_fail_blocklist]
    config_stub.data = {
        'content': {
            'host-block-lists': hosts_to_block,
            'host-blocking-enabled': True,
            'host-blocking-whitelist': None,
        }
    }
    host_blocker = adblock.HostBlocker()
    host_blocker.adblock_update(0)
    while host_blocker._in_progress:
        current_download = host_blocker._in_progress[0]
        # if current download is the file we want to fail, make it fail
        if current_download.name == dl_fail_blocklist.path():
            current_download.successful = False
        current_download.finished.emit()
    host_blocker.read_hosts()
    assert_urls(host_blocker, whitelisted=[])
    def acceptNavigationRequest(self, url: QtCore.QUrl,
                                type: 'QWebEnginePage.NavigationType',
                                isMainFrame: bool):
        """
        Overrides the default method
        Returns True if navigation is OK, returns False otherwise
        """
        text = url.path()

        if text.startswith('/action'):
            id = int(text[7:])
            if self.callback is None:
                raise Exception(
                    'callback not set - please set this.callback = your_function'
                )

            try:
                data = self.action_data[id]
            except:
                raise Exception(
                    'data with id = {} is not available. Did you accidentally clear actions since creating the link?'
                    .format(id))
            self.callback(data)
            return False

        return True
Exemple #17
0
    def open_in_browser(self, url: QtCore.QUrl) -> None:
        """Open links in browser
        :param url: Url of file
        """
        if url.path()[-3:] != ".md":

            self.back()
            QtGui.QDesktopServices.openUrl(url)
Exemple #18
0
 def checkdownloadFileExists(self, downloadPath):
     if (not downloadPath or not downloadPath): return False
     filePath = QUrl(downloadPath)
     fileInfo = QFileInfo(filePath.path())
     fileName = fileInfo.fileName()
     if QFile.exists(fileName):
         QFile.remove(fileName)
         return True
 def onbuttonInsertPiture(self):
     url = self.lineEditInserPiture.text()
     if url != "":
         url = QUrl(url)
         self.textEditActualresults.moveCursor(QTextCursor.End)
         self.textEditActualresults.insertPlainText(
             """\n<img src="{}"/>""".format(url.path()))
         self.textEditActualresults.moveCursor(QTextCursor.End)
         self.lineEditInserPiture.clear()
Exemple #20
0
def qute_resource(url: QUrl) -> _HandlerRet:
    """Handler for qute://resource."""
    path = url.path().lstrip('/')
    mimetype = utils.guess_mimetype(path, fallback=True)
    try:
        data = resources.read_file_binary(path)
    except FileNotFoundError as e:
        raise NotFoundError(str(e))
    return mimetype, data
Exemple #21
0
def data_for_url(url: QUrl) -> Tuple[str, bytes]:
    """Get the data to show for the given URL.

    Args:
        url: The QUrl to show.

    Return:
        A (mimetype, data) tuple.
    """
    norm_url = url.adjusted(
        QUrl.NormalizePathSegments |  # type: ignore[arg-type]
        QUrl.StripTrailingSlash)
    if norm_url != url:
        raise Redirect(norm_url)

    path = url.path()
    host = url.host()
    query = url.query()
    # A url like "qute:foo" is split as "scheme:path", not "scheme:host".
    log.misc.debug("url: {}, path: {}, host {}".format(
        url.toDisplayString(), path, host))
    if not path or not host:
        new_url = QUrl()
        new_url.setScheme('qute')
        # When path is absent, e.g. qute://help (with no trailing slash)
        if host:
            new_url.setHost(host)
        # When host is absent, e.g. qute:help
        else:
            new_url.setHost(path)

        new_url.setPath('/')
        if query:
            new_url.setQuery(query)
        if new_url.host():  # path was a valid host
            raise Redirect(new_url)

    try:
        handler = _HANDLERS[host]
    except KeyError:
        raise NotFoundError("No handler found for {}".format(
            url.toDisplayString()))

    try:
        mimetype, data = handler(url)
    except OSError as e:
        raise SchemeOSError(e)

    assert mimetype is not None, url
    if mimetype == 'text/html' and isinstance(data, str):
        # We let handlers return HTML as text
        data = data.encode('utf-8', errors='xmlcharrefreplace')
    assert isinstance(data, bytes)

    return mimetype, data
Exemple #22
0
def paths_to_items_list(parent, paths):
    items = []
    for path in paths:
        url = QUrl(path) if type(path) == QUrl else path
        path = url.path()
        item = QTreeWidgetItem(parent, [ path ])
        item.setData(0, SubtleTreeWidget.ITEM_ROLE, url)
        item.setText(0, os.path.basename(path))
        item.setToolTip(0, path)
        items.append( item )
    return items
Exemple #23
0
def paths_to_items_list(parent, paths):
    items = []
    for path in paths:
        url = QUrl(path) if type(path) == QUrl else path
        path = url.path()
        item = QTreeWidgetItem(parent, [path])
        item.setData(0, SubtleTreeWidget.ITEM_ROLE, url)
        item.setText(0, os.path.basename(path))
        item.setToolTip(0, path)
        items.append(item)
    return items
def qute_javascript(url: QUrl) -> _HandlerRet:
    """Handler for qute://javascript.

    Return content of file given as query parameter.
    """
    path = url.path()
    if path:
        path = "javascript" + os.sep.join(path.split('/'))
        return 'text/html', utils.read_file(path, binary=False)
    else:
        raise UrlInvalidError("No file specified")
Exemple #25
0
def qute_configdiff(url: QUrl) -> _HandlerRet:
    """Handler for qute://configdiff."""
    if url.path() == '/old':
        try:
            return 'text/html', configdiff.get_diff()
        except OSError as e:
            error = (b'Failed to read old config: ' +
                     str(e.strerror).encode('utf-8'))
            return 'text/plain', error
    else:
        data = config.instance.dump_userconfig().encode('utf-8')
        return 'text/plain', data
Exemple #26
0
 def _map_to_signal(self, url: QUrl):
     """
     This slot delegates clicked link signal to show the same html as
     before (eg. link to a point in the term has been clicked)
     or to delegates the filename given in the link as emitted
     signal_link_clicked(filename) signal.
     """
     if url.fileName() == "" and url.path() == "/":
         logging.debug(str(url))
         self.ui.contentWebView.setHtml(self._html, url)
     else:
         self.signal_link_clicked.emit(url.toLocalFile().split("/")[-1])
Exemple #27
0
def data_for_url(url: QUrl):
    """Get the data to show for the given URL.

    Args:
        url: The QUrl to show.

    Return:
        A (mimetype, data) tuple.
    """
    norm_url = url.adjusted(QUrl.NormalizePathSegments
                            | QUrl.StripTrailingSlash)
    if norm_url != url:
        raise Redirect(norm_url)

    path = url.path()
    host = url.host()
    query = urlutils.query_string(url)
    # A url like "luminos:foo" is split as "scheme:path", not "scheme:host".

    if not path or not host:
        new_url = QUrl()
        new_url.setScheme("luminos")
        # When path is absent, e.g. luminos://help (with no trailing slash)
        if host:
            new_url.setHost(host)
        # When host is absent, e.g. luminos:help
        else:
            new_url.setHost(path)

        new_url.setPath("/")
        if query:
            new_url.setQuery(query)
        if new_url.host():  # path was a valid host
            raise Redirect(new_url)

    try:
        handler = _HANDLERS[host]
    except KeyError:
        raise NotFoundError("No handler found for {}".format(
            url.toDisplayString()))

    try:
        mimetype, data = handler(url)
    except OSError as e:
        raise SchemeOSError(e)

    assert mimetype is not None, url
    if mimetype == "text/html" and isinstance(data, str):
        # We let handlers return HTML as text
        data = data.encode("utf-8", errors="xmlcharrefreplace")

    return mimetype, data
def qute_warning(url: QUrl) -> _HandlerRet:
    """Handler for qute://warning."""
    path = url.path()
    if path == '/webkit':
        src = jinja.render('warning-webkit.html',
                           title='QtWebKit backend warning')
    elif path == '/sessions':
        src = jinja.render('warning-sessions.html',
                           title='Qt 5.15 sessions warning',
                           datadir=standarddir.data(),
                           sep=os.sep)
    else:
        raise NotFoundError("Invalid warning page {}".format(path))
    return 'text/html', src
Exemple #29
0
    def __init__(self, connections=None, 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")

        if connections is None:
            connections = []

        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)
Exemple #30
0
 def loadResource(self, resource_type: int,
                  name: QtCore.QUrl) -> Union[QtGui.QImage, None]:
     logger.debug("loadResource: %r, %r", resource_type, name)
     if resource_type == QtGui.QTextDocument.ImageResource:
         name = name.path()
         if name.startswith("/file/download/"):
             name = name[len("/file/download/"):]
         if name in self.resourceMapCache:
             if self.resourceMapCache[name] is not None:
                 return QtGui.QImage(
                     self.resourceMapCache[name]["filename"])
         else:
             RemoteFile(name, self.onFileAvaiable)
             self.resourceMapCache[name] = None
     return None
def test_resource_url():
    """Test resource_url() which can be used from templates."""
    data = jinja.render('test2.html')
    print(data)
    url = QUrl(data)
    assert url.isValid()
    assert url.scheme() == 'file'

    path = url.path()

    if os.name == "nt":
        path = path.lstrip('/')
        path = path.replace('/', os.sep)

    with open(path, 'r', encoding='utf-8') as f:
        assert f.read().splitlines()[0] == "Hello World!"
Exemple #32
0
def test_resource_url():
    """Test resource_url() which can be used from templates."""
    data = jinja.render('resource_url.html')
    print(data)
    url = QUrl(data)
    assert url.isValid()
    assert url.scheme() == 'file'

    path = url.path()

    if os.name == "nt":
        path = path.lstrip('/')
        path = path.replace('/', os.sep)

    with open(path, 'r', encoding='utf-8') as f:
        assert f.read().splitlines()[0] == "Hello World!"
def qute_help(url: QUrl) -> _HandlerRet:
    """Handler for qute://help."""
    urlpath = url.path()
    if not urlpath or urlpath == '/':
        urlpath = 'index.html'
    else:
        urlpath = urlpath.lstrip('/')
    if not docutils.docs_up_to_date(urlpath):
        message.error("Your documentation is outdated! Please re-run "
                      "scripts/asciidoc2html.py.")

    path = 'html/doc/{}'.format(urlpath)
    if not urlpath.endswith('.html'):
        try:
            bdata = utils.read_file(path, binary=True)
        except OSError as e:
            raise SchemeOSError(e)
        mimetype = utils.guess_mimetype(urlpath)
        return mimetype, bdata

    try:
        data = utils.read_file(path)
    except OSError:
        asciidoc = _asciidoc_fallback_path(path)

        if asciidoc is None:
            raise

        preamble = textwrap.dedent("""
            There was an error loading the documentation!

            This most likely means the documentation was not generated
            properly. If you are running qutebrowser from the git repository,
            please (re)run scripts/asciidoc2html.py and reload this page.

            If you're running a released version this is a bug, please use
            :report to report it.

            Falling back to the plaintext version.

            ---------------------------------------------------------------


        """)
        return 'text/plain', (preamble + asciidoc).encode('utf-8')
    else:
        return 'text/html', data
Exemple #34
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)
Exemple #35
0
def test_resource_url():
    """Test resource_url() which can be used from templates."""
    template = jinja.env.get_template("test2.html")
    data = template.render()  # pylint: disable=no-member
    print(data)
    url = QUrl(data)
    assert url.isValid()
    assert url.scheme() == "file"

    path = url.path()

    if os.name == "nt":
        path = path.lstrip("/")
        path = path.replace("/", os.sep)

    with open(path, "r", encoding="utf-8") as f:
        assert f.read().splitlines()[0] == "Hello World!"
    def __stripUrl(self, url):
        """
        Private method to strip off all unneeded parts of a URL.
        
        @param url URL to be stripped (QUrl)
        @return stripped URL (QUrl)
        """
        cleanUrl = QUrl(url)
        cleanUrl.setQuery("")
        cleanUrl.setUserInfo("")

        authority = cleanUrl.authority()
        if authority.startswith("@"):
            authority = authority[1:]
        cleanUrl = QUrl("{0}://{1}{2}".format(cleanUrl.scheme(), authority,
                                              cleanUrl.path()))
        cleanUrl.setFragment("")
        return cleanUrl
Exemple #37
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
Exemple #38
0
def filename_from_url(url: QUrl) -> Optional[str]:
    """Get a suitable filename from a URL.

    Args:
        url: The URL to parse, as a QUrl.

    Return:
        The suggested filename as a string, or None.
    """
    if not url.isValid():
        return None
    pathname = posixpath.basename(url.path())
    if pathname:
        return pathname
    elif url.host():
        return url.host() + '.html'
    else:
        return None
Exemple #39
0
 def __stripUrl(self, url):
     """
     Private method to strip off all unneeded parts of a URL.
     
     @param url URL to be stripped (QUrl)
     @return stripped URL (QUrl)
     """
     cleanUrl = QUrl(url)
     if qVersion() >= "5.0.0":
         cleanUrl.setQuery("")
     else:
         cleanUrl.setQueryItems([])
     cleanUrl.setUserInfo("")
     
     authority = cleanUrl.authority()
     if authority.startswith("@"):
         authority = authority[1:]
     cleanUrl = QUrl("{0}://{1}{2}".format(
         cleanUrl.scheme(), authority, cleanUrl.path()))
     cleanUrl.setFragment("")
     return cleanUrl
Exemple #40
0
def test_failed_dl_update(config_stub, basedir, download_stub, data_tmpdir, tmpdir, win_registry, caplog):
    """One blocklist fails to download.

    Ensure hosts from this list are not blocked.
    """
    dl_fail_blocklist = QUrl(
        create_blocklist(tmpdir, blocked_hosts=CLEAN_HOSTS, name="download_will_fail", line_format="one_per_line")
    )
    hosts_to_block = generic_blocklists(tmpdir) + [dl_fail_blocklist]
    config_stub.data = {
        "content": {"host-block-lists": hosts_to_block, "host-blocking-enabled": True, "host-blocking-whitelist": None}
    }
    host_blocker = adblock.HostBlocker()
    host_blocker.adblock_update()
    while host_blocker._in_progress:
        current_download = host_blocker._in_progress[0]
        # if current download is the file we want to fail, make it fail
        if current_download.name == dl_fail_blocklist.path():
            current_download.successful = False
        with caplog.at_level(logging.ERROR):
            current_download.finished.emit()
    host_blocker.read_hosts()
    assert_urls(host_blocker, whitelisted=[])
Exemple #41
0
class HttpWindow(QDialog):
    def __init__(self, parent=None):
        super(HttpWindow, self).__init__(parent)

        self.url = QUrl()
        self.qnam = QNetworkAccessManager()
        self.reply = None
        self.outFile = None
        self.httpGetId = 0
        self.httpRequestAborted = False

        self.urlLineEdit = QLineEdit('https://www.qt.io')

        urlLabel = QLabel("&URL:")
        urlLabel.setBuddy(self.urlLineEdit)
        self.statusLabel = QLabel(
                "Please enter the URL of a file you want to download.")
        self.statusLabel.setWordWrap(True)

        self.downloadButton = QPushButton("Download")
        self.downloadButton.setDefault(True)
        self.quitButton = QPushButton("Quit")
        self.quitButton.setAutoDefault(False)

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.downloadButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole)

        self.progressDialog = QProgressDialog(self)

        self.urlLineEdit.textChanged.connect(self.enableDownloadButton)
        self.qnam.authenticationRequired.connect(
                self.slotAuthenticationRequired)
        self.qnam.sslErrors.connect(self.sslErrors)
        self.progressDialog.canceled.connect(self.cancelDownload)
        self.downloadButton.clicked.connect(self.downloadFile)
        self.quitButton.clicked.connect(self.close)

        topLayout = QHBoxLayout()
        topLayout.addWidget(urlLabel)
        topLayout.addWidget(self.urlLineEdit)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(topLayout)
        mainLayout.addWidget(self.statusLabel)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("HTTP")
        self.urlLineEdit.setFocus()

    def startRequest(self, url):
        self.reply = self.qnam.get(QNetworkRequest(url))
        self.reply.finished.connect(self.httpFinished)
        self.reply.readyRead.connect(self.httpReadyRead)
        self.reply.downloadProgress.connect(self.updateDataReadProgress)

    def downloadFile(self):
        self.url = QUrl(self.urlLineEdit.text())
        fileInfo = QFileInfo(self.url.path())
        fileName = fileInfo.fileName()

        if not fileName:
            fileName = 'index.html'

        if QFile.exists(fileName):
            ret = QMessageBox.question(self, "HTTP",
                    "There already exists a file called %s in the current "
                    "directory. Overwrite?" % fileName,
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

            if ret == QMessageBox.No:
                return

            QFile.remove(fileName)

        self.outFile = QFile(fileName)
        if not self.outFile.open(QIODevice.WriteOnly):
            QMessageBox.information(self, "HTTP",
                    "Unable to save the file %s: %s." % (fileName, self.outFile.errorString()))
            self.outFile = None
            return

        self.progressDialog.setWindowTitle("HTTP")
        self.progressDialog.setLabelText("Downloading %s." % fileName)
        self.downloadButton.setEnabled(False)

        self.httpRequestAborted = False
        self.startRequest(self.url)

    def cancelDownload(self):
        self.statusLabel.setText("Download canceled.")
        self.httpRequestAborted = True
        if self.reply is not None:
            self.reply.abort()
        self.downloadButton.setEnabled(True)

    def httpFinished(self):
        if self.httpRequestAborted:
            if self.outFile is not None:
                self.outFile.close()
                self.outFile.remove()
                self.outFile = None

            self.reply.deleteLater()
            self.reply = None
            self.progressDialog.hide()
            return

        self.progressDialog.hide()
        self.outFile.flush()
        self.outFile.close()

        redirectionTarget = self.reply.attribute(QNetworkRequest.RedirectionTargetAttribute)

        if self.reply.error():
            self.outFile.remove()
            QMessageBox.information(self, "HTTP",
                    "Download failed: %s." % self.reply.errorString())
            self.downloadButton.setEnabled(True)
        elif redirectionTarget is not None:
            newUrl = self.url.resolved(redirectionTarget)

            ret = QMessageBox.question(self, "HTTP",
                    "Redirect to %s?" % newUrl.toString(),
                    QMessageBox.Yes | QMessageBox.No)

            if ret == QMessageBox.Yes:
                self.url = newUrl
                self.reply.deleteLater()
                self.reply = None
                self.outFile.open(QIODevice.WriteOnly)
                self.outFile.resize(0)
                self.startRequest(self.url)
                return
        else:
            fileName = QFileInfo(QUrl(self.urlLineEdit.text()).path()).fileName()
            self.statusLabel.setText("Downloaded %s to %s." % (fileName, QDir.currentPath()))

            self.downloadButton.setEnabled(True)

        self.reply.deleteLater()
        self.reply = None
        self.outFile = None

    def httpReadyRead(self):
        if self.outFile is not None:
            self.outFile.write(self.reply.readAll())

    def updateDataReadProgress(self, bytesRead, totalBytes):
        if self.httpRequestAborted:
            return

        self.progressDialog.setMaximum(totalBytes)
        self.progressDialog.setValue(bytesRead)

    def enableDownloadButton(self):
        self.downloadButton.setEnabled(self.urlLineEdit.text() != '')

    def slotAuthenticationRequired(self, authenticator):
        import os
        from PyQt5 import uic

        ui = os.path.join(os.path.dirname(__file__), 'authenticationdialog.ui')
        dlg = uic.loadUi(ui)
        dlg.adjustSize()
        dlg.siteDescription.setText("%s at %s" % (authenticator.realm(), self.url.host()))

        dlg.userEdit.setText(self.url.userName())
        dlg.passwordEdit.setText(self.url.password())

        if dlg.exec_() == QDialog.Accepted:
            authenticator.setUser(dlg.userEdit.text())
            authenticator.setPassword(dlg.passwordEdit.text())

    def sslErrors(self, reply, errors):
        errorString = ", ".join([str(error.errorString()) for error in errors])

        ret = QMessageBox.warning(self, "HTTP Example",
                "One or more SSL errors has occurred: %s" % errorString,
                QMessageBox.Ignore | QMessageBox.Abort)

        if ret == QMessageBox.Ignore:
            self.reply.ignoreSslErrors()
Exemple #42
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)