Ejemplo n.º 1
0
def create_full_filename(basename, filename):
    """Create a full filename based on the given basename and filename.

    Args:
        basename: The basename to use if filename is a directory.
        filename: The path to a folder or file where you want to save.

    Return:
        The full absolute path, or None if filename creation was not possible.
    """
    basename = utils.sanitize_filename(basename)
    # Filename can be a full path so don't use sanitize_filename on it.
    # Remove chars which can't be encoded in the filename encoding.
    # See https://github.com/qutebrowser/qutebrowser/issues/427
    encoding = sys.getfilesystemencoding()
    filename = utils.force_encoding(filename, encoding)
    if os.path.isabs(filename) and (os.path.isdir(filename) or
                                    filename.endswith(os.sep)):
        # We got an absolute directory from the user, so we save it under
        # the default filename in that directory.
        return os.path.join(filename, basename)
    elif os.path.isabs(filename):
        # We got an absolute filename from the user, so we save it under
        # that filename.
        return filename
    return None
Ejemplo n.º 2
0
def create_full_filename(basename, filename):
    """Create a full filename based on the given basename and filename.

    Args:
        basename: The basename to use if filename is a directory.
        filename: The path to a folder or file where you want to save.

    Return:
        The full absolute path, or None if filename creation was not possible.
    """
    basename = utils.sanitize_filename(basename)
    # Filename can be a full path so don't use sanitize_filename on it.
    # Remove chars which can't be encoded in the filename encoding.
    # See https://github.com/qutebrowser/qutebrowser/issues/427
    encoding = sys.getfilesystemencoding()
    filename = utils.force_encoding(filename, encoding)
    if os.path.isabs(filename) and (os.path.isdir(filename)
                                    or filename.endswith(os.sep)):
        # We got an absolute directory from the user, so we save it under
        # the default filename in that directory.
        return os.path.join(filename, basename)
    elif os.path.isabs(filename):
        # We got an absolute filename from the user, so we save it under
        # that filename.
        return filename
    return None
Ejemplo n.º 3
0
def start_download_checked(target, tab):
    """First check if dest is already a file, then start the download.

    Args:
        target: The DownloadTarget where the resulting file should be saved.
        tab: Specify the tab whose page should be loaded.
    """
    if not isinstance(target, downloads.FileDownloadTarget):
        _start_download(target, tab)
        return
    # The default name is 'page title.mhtml'
    title = tab.title()
    default_name = utils.sanitize_filename(title + '.mhtml')

    # Remove characters which cannot be expressed in the file system encoding
    encoding = sys.getfilesystemencoding()
    default_name = utils.force_encoding(default_name, encoding)
    dest = utils.force_encoding(target.filename, encoding)

    dest = os.path.expanduser(dest)

    # See if we already have an absolute path
    path = downloads.create_full_filename(default_name, dest)
    if path is None:
        # We still only have a relative path, prepend download_dir and
        # try again.
        path = downloads.create_full_filename(
            default_name, os.path.join(downloads.download_dir(), dest))
    downloads.last_used_directory = os.path.dirname(path)

    # Avoid downloading files if we can't save the output anyway...
    # Yes, this is prone to race conditions, but we're checking again before
    # saving the file anyway.
    if not os.path.isdir(os.path.dirname(path)):
        folder = os.path.dirname(path)
        message.error("Directory {} does not exist.".format(folder))
        return

    target = downloads.FileDownloadTarget(path)
    if not os.path.isfile(path):
        _start_download(target, tab=tab)
        return

    q = usertypes.Question()
    q.mode = usertypes.PromptMode.yesno
    q.title = "Overwrite existing file?"
    q.text = "<b>{}</b> already exists. Overwrite?".format(
        html.escape(path))
    q.completed.connect(q.deleteLater)
    q.answered_yes.connect(functools.partial(
        _start_download, target, tab=tab))
    message.global_bridge.ask(q, blocking=False)
Ejemplo n.º 4
0
def start_download_checked(target, tab):
    """First check if dest is already a file, then start the download.

    Args:
        target: The DownloadTarget where the resulting file should be saved.
        tab: Specify the tab whose page should be loaded.
    """
    if not isinstance(target, downloads.FileDownloadTarget):
        _start_download(target, tab)
        return
    # The default name is 'page title.mhtml'
    title = tab.title()
    default_name = utils.sanitize_filename(title + '.mhtml')

    # Remove characters which cannot be expressed in the file system encoding
    encoding = sys.getfilesystemencoding()
    default_name = utils.force_encoding(default_name, encoding)
    dest = utils.force_encoding(target.filename, encoding)

    dest = os.path.expanduser(dest)

    # See if we already have an absolute path
    path = downloads.create_full_filename(default_name, dest)
    if path is None:
        # We still only have a relative path, prepend download_dir and
        # try again.
        path = downloads.create_full_filename(
            default_name, os.path.join(downloads.download_dir(), dest))
    downloads.last_used_directory = os.path.dirname(path)

    # Avoid downloading files if we can't save the output anyway...
    # Yes, this is prone to race conditions, but we're checking again before
    # saving the file anyway.
    if not os.path.isdir(os.path.dirname(path)):
        folder = os.path.dirname(path)
        message.error("Directory {} does not exist.".format(folder))
        return

    target = downloads.FileDownloadTarget(path)
    if not os.path.isfile(path):
        _start_download(target, tab=tab)
        return

    q = usertypes.Question()
    q.mode = usertypes.PromptMode.yesno
    q.title = "Overwrite existing file?"
    q.text = "<b>{}</b> already exists. Overwrite?".format(
        html.escape(path))
    q.completed.connect(q.deleteLater)
    q.answered_yes.connect(functools.partial(
        _start_download, target, tab=tab))
    message.global_bridge.ask(q, blocking=False)
Ejemplo n.º 5
0
def suggested_fn_from_title(url_path, title=None):
    """Suggest a filename depending on the URL extension and page title.

    Args:
        url_path: a string with the URL path
        title: the page title string

    Return:
        The download filename based on the title, or None if the extension is
        not found in the whitelist (or if there is no page title).
    """
    ext_whitelist = [".html", ".htm", ".php", ""]
    _, ext = os.path.splitext(url_path)

    suggested_fn = None  # type: typing.Optional[str]
    if ext.lower() in ext_whitelist and title:
        suggested_fn = utils.sanitize_filename(title, shorten=True)
        if not suggested_fn.lower().endswith((".html", ".htm")):
            suggested_fn += ".html"
            suggested_fn = utils.sanitize_filename(suggested_fn, shorten=True)

    return suggested_fn
Ejemplo n.º 6
0
def start_download_checked(dest, web_view):
    """First check if dest is already a file, then start the download.

    Args:
        dest: The filename where the resulting file should be saved.
        web_view: Specify the webview whose page should be loaded.
    """
    # The default name is 'page title.mht'
    title = web_view.title()
    default_name = utils.sanitize_filename(title + '.mht')

    # Remove characters which cannot be expressed in the file system encoding
    encoding = sys.getfilesystemencoding()
    default_name = utils.force_encoding(default_name, encoding)
    dest = utils.force_encoding(dest, encoding)

    dest = os.path.expanduser(dest)

    # See if we already have an absolute path
    path = downloads.create_full_filename(default_name, dest)
    if path is None:
        # We still only have a relative path, prepend download_dir and
        # try again.
        path = downloads.create_full_filename(
            default_name, os.path.join(downloads.download_dir(), dest))
    downloads.last_used_directory = os.path.dirname(path)

    # Avoid downloading files if we can't save the output anyway...
    # Yes, this is prone to race conditions, but we're checking again before
    # saving the file anyway.
    if not os.path.isdir(os.path.dirname(path)):
        folder = os.path.dirname(path)
        message.error(web_view.win_id,
                      "Directory {} does not exist.".format(folder))
        return

    if not os.path.isfile(path):
        _start_download(path, web_view=web_view)
        return

    q = usertypes.Question()
    q.mode = usertypes.PromptMode.yesno
    q.text = "{} exists. Overwrite?".format(path)
    q.completed.connect(q.deleteLater)
    q.answered_yes.connect(
        functools.partial(_start_download, path, web_view=web_view))
    message_bridge = objreg.get('message-bridge',
                                scope='window',
                                window=web_view.win_id)
    message_bridge.ask(q, blocking=False)
Ejemplo n.º 7
0
def start_download_checked(dest, web_view):
    """First check if dest is already a file, then start the download.

    Args:
        dest: The filename where the resulting file should be saved.
        web_view: Specify the webview whose page should be loaded.
    """
    # The default name is 'page title.mht'
    title = web_view.title()
    default_name = utils.sanitize_filename(title + '.mht')

    # Remove characters which cannot be expressed in the file system encoding
    encoding = sys.getfilesystemencoding()
    default_name = utils.force_encoding(default_name, encoding)
    dest = utils.force_encoding(dest, encoding)

    dest = os.path.expanduser(dest)

    # See if we already have an absolute path
    path = downloads.create_full_filename(default_name, dest)
    if path is None:
        # We still only have a relative path, prepend download_dir and
        # try again.
        path = downloads.create_full_filename(
            default_name, os.path.join(downloads.download_dir(), dest))
    downloads.last_used_directory = os.path.dirname(path)

    # Avoid downloading files if we can't save the output anyway...
    # Yes, this is prone to race conditions, but we're checking again before
    # saving the file anyway.
    if not os.path.isdir(os.path.dirname(path)):
        folder = os.path.dirname(path)
        message.error(web_view.win_id,
                      "Directory {} does not exist.".format(folder))
        return

    if not os.path.isfile(path):
        _start_download(path, web_view=web_view)
        return

    q = usertypes.Question()
    q.mode = usertypes.PromptMode.yesno
    q.text = "{} exists. Overwrite?".format(path)
    q.completed.connect(q.deleteLater)
    q.answered_yes.connect(functools.partial(
        _start_download, path, web_view=web_view))
    message_bridge = objreg.get('message-bridge', scope='window',
                                window=web_view.win_id)
    message_bridge.ask(q, blocking=False)
Ejemplo n.º 8
0
def get_filename_question(*, suggested_filename, url, parent=None):
    """Get a Question object for a download-path.

    Args:
        suggested_filename: The "default"-name that is pre-entered as path.
        url: The URL the download originated from.
        parent: The parent of the question (a QObject).
    """
    suggested_filename = utils.sanitize_filename(suggested_filename)

    q = usertypes.Question(parent)
    q.title = "Save file to:"
    q.text = "Please enter a location for <b>{}</b>".format(
        html.escape(url.toDisplayString()))
    q.url = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
    q.mode = usertypes.PromptMode.download
    q.completed.connect(q.deleteLater)
    q.default = _path_suggestion(suggested_filename)
    return q
Ejemplo n.º 9
0
def get_filename_question(*, suggested_filename, url, parent=None):
    """Get a Question object for a download-path.

    Args:
        suggested_filename: The "default"-name that is pre-entered as path.
        url: The URL the download originated from.
        parent: The parent of the question (a QObject).
    """
    suggested_filename = utils.sanitize_filename(suggested_filename)

    q = usertypes.Question(parent)
    q.title = "Save file to:"
    q.text = "Please enter a location for <b>{}</b>".format(
        html.escape(url.toDisplayString()))
    q.url = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
    q.mode = usertypes.PromptMode.download
    q.completed.connect(q.deleteLater)
    q.default = _path_suggestion(suggested_filename)
    return q
Ejemplo n.º 10
0
def suggested_fn_from_title(url_path, title=None):
    """Suggest a filename depending on the URL extension and page title.

    Args:
        url_path: a string with the URL path
        title: the page title string

    Return:
        The download filename based on the title, or None if the extension is
        not found in the whitelist (or if there is no page title).
    """
    ext_whitelist = [".html", ".htm", ".php", ""]
    _, ext = os.path.splitext(url_path)
    if ext.lower() in ext_whitelist and title:
        suggested_fn = utils.sanitize_filename(title)
        if not suggested_fn.lower().endswith((".html", ".htm")):
            suggested_fn += ".html"
    else:
        suggested_fn = None
    return suggested_fn
Ejemplo n.º 11
0
    def get_mhtml(self, tab, target):
        """Download the given tab as mhtml to the given DownloadTarget."""
        assert tab.backend == usertypes.Backend.QtWebKit
        from qutebrowser.browser.webkit import mhtml

        if target is not None:
            mhtml.start_download_checked(target, tab=tab)
            return

        suggested_fn = utils.sanitize_filename(tab.title() + ".mhtml")

        filename = downloads.immediate_download_path()
        if filename is not None:
            target = downloads.FileDownloadTarget(filename)
            mhtml.start_download_checked(target, tab=tab)
        else:
            question = downloads.get_filename_question(
                suggested_filename=suggested_fn, url=tab.url(), parent=tab)
            question.answered.connect(
                functools.partial(mhtml.start_download_checked, tab=tab))
            message.global_bridge.ask(question, blocking=False)
Ejemplo n.º 12
0
    def get_tmpfile(self, suggested_name):
        """Return a temporary file in the temporary downloads directory.

        The files are kept as long as qutebrowser is running and automatically
        cleaned up at program exit.

        Args:
            suggested_name: str of the "suggested"/original filename. Used as a
                            suffix, so any file extenions are preserved.

        Return:
            A tempfile.NamedTemporaryFile that should be used to save the file.
        """
        tmpdir = self.get_tmpdir()
        suggested_name = utils.sanitize_filename(suggested_name)
        # Make sure that the filename is not too long
        suggested_name = utils.elide_filename(suggested_name, 50)
        fobj = tempfile.NamedTemporaryFile(dir=tmpdir.name, delete=False,
                                           suffix='_' + suggested_name)
        self.files.append(fobj)
        return fobj
Ejemplo n.º 13
0
    def get_mhtml(self, tab, target):
        """Download the given tab as mhtml to the given DownloadTarget."""
        assert tab.backend == usertypes.Backend.QtWebKit
        from qutebrowser.browser.webkit import mhtml

        if target is not None:
            mhtml.start_download_checked(target, tab=tab)
            return

        suggested_fn = utils.sanitize_filename(tab.title() + ".mhtml")

        filename = downloads.immediate_download_path()
        if filename is not None:
            target = downloads.FileDownloadTarget(filename)
            mhtml.start_download_checked(target, tab=tab)
        else:
            question = downloads.get_filename_question(
                suggested_filename=suggested_fn, url=tab.url(), parent=tab)
            question.answered.connect(functools.partial(
                mhtml.start_download_checked, tab=tab))
            message.global_bridge.ask(question, blocking=False)
Ejemplo n.º 14
0
    def get_tmpfile(self, suggested_name):
        """Return a temporary file in the temporary downloads directory.

        The files are kept as long as qutebrowser is running and automatically
        cleaned up at program exit.

        Args:
            suggested_name: str of the "suggested"/original filename. Used as a
                            suffix, so any file extenions are preserved.

        Return:
            A tempfile.NamedTemporaryFile that should be used to save the file.
        """
        tmpdir = self.get_tmpdir()
        suggested_name = utils.sanitize_filename(suggested_name)
        # Make sure that the filename is not too long
        suggested_name = utils.elide_filename(suggested_name, 50)
        fobj = tempfile.NamedTemporaryFile(dir=tmpdir.name, delete=False,
                                           suffix='_' + suggested_name)
        self.files.append(fobj)
        return fobj
Ejemplo n.º 15
0
 def _required_url_to_file_path(self, url):
     requires_dir = os.path.join(_scripts_dir(), 'requires')
     if not os.path.exists(requires_dir):
         os.mkdir(requires_dir)
     return os.path.join(requires_dir, utils.sanitize_filename(url))
Ejemplo n.º 16
0
 def _required_url_to_file_path(self, url):
     requires_dir = os.path.join(_scripts_dir(), 'requires')
     if not os.path.exists(requires_dir):
         os.mkdir(requires_dir)
     return os.path.join(requires_dir, utils.sanitize_filename(url))