Allow directories to be entered as destination
The filename will then default to 'page title.mht'
This commit is contained in:
parent
ae8a9b8798
commit
a780325a3a
@ -49,7 +49,7 @@ ModelRole = usertypes.enum('ModelRole', ['item'], start=Qt.UserRole,
|
|||||||
RetryInfo = collections.namedtuple('RetryInfo', ['request', 'manager'])
|
RetryInfo = collections.namedtuple('RetryInfo', ['request', 'manager'])
|
||||||
|
|
||||||
# Remember the last used directory
|
# Remember the last used directory
|
||||||
_last_used_directory = None
|
last_used_directory = None
|
||||||
|
|
||||||
|
|
||||||
# All REFRESH_INTERVAL milliseconds, speeds will be recalculated and downloads
|
# All REFRESH_INTERVAL milliseconds, speeds will be recalculated and downloads
|
||||||
@ -57,13 +57,13 @@ _last_used_directory = None
|
|||||||
REFRESH_INTERVAL = 500
|
REFRESH_INTERVAL = 500
|
||||||
|
|
||||||
|
|
||||||
def _download_dir():
|
def download_dir():
|
||||||
"""Get the download directory to use."""
|
"""Get the download directory to use."""
|
||||||
directory = config.get('storage', 'download-directory')
|
directory = config.get('storage', 'download-directory')
|
||||||
remember_dir = config.get('storage', 'remember-download-directory')
|
remember_dir = config.get('storage', 'remember-download-directory')
|
||||||
|
|
||||||
if remember_dir and _last_used_directory is not None:
|
if remember_dir and last_used_directory is not None:
|
||||||
return _last_used_directory
|
return last_used_directory
|
||||||
elif directory is None:
|
elif directory is None:
|
||||||
return standarddir.download()
|
return standarddir.download()
|
||||||
else:
|
else:
|
||||||
@ -79,15 +79,36 @@ def path_suggestion(filename):
|
|||||||
suggestion = config.get('completion', 'download-path-suggestion')
|
suggestion = config.get('completion', 'download-path-suggestion')
|
||||||
if suggestion == 'path':
|
if suggestion == 'path':
|
||||||
# add trailing '/' if not present
|
# add trailing '/' if not present
|
||||||
return os.path.join(_download_dir(), '')
|
return os.path.join(download_dir(), '')
|
||||||
elif suggestion == 'filename':
|
elif suggestion == 'filename':
|
||||||
return filename
|
return filename
|
||||||
elif suggestion == 'both':
|
elif suggestion == 'both':
|
||||||
return os.path.join(_download_dir(), filename)
|
return os.path.join(download_dir(), filename)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid suggestion value {}!".format(suggestion))
|
raise ValueError("Invalid suggestion value {}!".format(suggestion))
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
if os.path.isabs(filename) and os.path.isdir(filename):
|
||||||
|
# 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
|
||||||
|
|
||||||
|
|
||||||
class DownloadItemStats(QObject):
|
class DownloadItemStats(QObject):
|
||||||
|
|
||||||
"""Statistics (bytes done, total bytes, time, etc.) about a download.
|
"""Statistics (bytes done, total bytes, time, etc.) about a download.
|
||||||
@ -447,7 +468,7 @@ class DownloadItem(QObject):
|
|||||||
filename: The full filename to save the download to.
|
filename: The full filename to save the download to.
|
||||||
None: special value to stop the download.
|
None: special value to stop the download.
|
||||||
"""
|
"""
|
||||||
global _last_used_directory
|
global last_used_directory
|
||||||
if self.fileobj is not None:
|
if self.fileobj is not None:
|
||||||
raise ValueError("fileobj was already set! filename: {}, "
|
raise ValueError("fileobj was already set! filename: {}, "
|
||||||
"existing: {}, fileobj {}".format(
|
"existing: {}, fileobj {}".format(
|
||||||
@ -457,13 +478,16 @@ class DownloadItem(QObject):
|
|||||||
# See https://github.com/The-Compiler/qutebrowser/issues/427
|
# See https://github.com/The-Compiler/qutebrowser/issues/427
|
||||||
encoding = sys.getfilesystemencoding()
|
encoding = sys.getfilesystemencoding()
|
||||||
filename = utils.force_encoding(filename, encoding)
|
filename = utils.force_encoding(filename, encoding)
|
||||||
if not self._create_full_filename(filename):
|
self._filename = create_full_filename(self.basename, filename)
|
||||||
|
if self._filename is None:
|
||||||
# We only got a filename (without directory) or a relative path
|
# We only got a filename (without directory) or a relative path
|
||||||
# from the user, so we append that to the default directory and
|
# from the user, so we append that to the default directory and
|
||||||
# try again.
|
# try again.
|
||||||
self._create_full_filename(os.path.join(_download_dir(), filename))
|
self._filename = create_full_filename(
|
||||||
|
self.basename, os.path.join(download_dir(), filename))
|
||||||
|
|
||||||
_last_used_directory = os.path.dirname(self._filename)
|
self.basename = os.path.basename(self._filename)
|
||||||
|
last_used_directory = os.path.dirname(self._filename)
|
||||||
|
|
||||||
log.downloads.debug("Setting filename to {}".format(filename))
|
log.downloads.debug("Setting filename to {}".format(filename))
|
||||||
if os.path.isfile(self._filename):
|
if os.path.isfile(self._filename):
|
||||||
@ -480,25 +504,6 @@ class DownloadItem(QObject):
|
|||||||
else:
|
else:
|
||||||
self._create_fileobj()
|
self._create_fileobj()
|
||||||
|
|
||||||
def _create_full_filename(self, filename):
|
|
||||||
"""Try to create the full filename.
|
|
||||||
|
|
||||||
Return:
|
|
||||||
True if the full filename was created, False otherwise.
|
|
||||||
"""
|
|
||||||
if os.path.isabs(filename) and os.path.isdir(filename):
|
|
||||||
# We got an absolute directory from the user, so we save it under
|
|
||||||
# the default filename in that directory.
|
|
||||||
self._filename = os.path.join(filename, self.basename)
|
|
||||||
return True
|
|
||||||
elif os.path.isabs(filename):
|
|
||||||
# We got an absolute filename from the user, so we save it under
|
|
||||||
# that filename.
|
|
||||||
self._filename = filename
|
|
||||||
self.basename = os.path.basename(self._filename)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def set_fileobj(self, fileobj):
|
def set_fileobj(self, fileobj):
|
||||||
""""Set the file object to write the download to.
|
""""Set the file object to write the download to.
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import functools
|
|||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import collections
|
import collections
|
||||||
import uuid
|
import uuid
|
||||||
import email.policy
|
import email.policy
|
||||||
@ -32,7 +33,7 @@ import email.mime.multipart
|
|||||||
|
|
||||||
from PyQt5.QtCore import QUrl
|
from PyQt5.QtCore import QUrl
|
||||||
|
|
||||||
from qutebrowser.browser import webelem
|
from qutebrowser.browser import webelem, downloads
|
||||||
from qutebrowser.utils import log, objreg, message, usertypes, utils, urlutils
|
from qutebrowser.utils import log, objreg, message, usertypes, utils, urlutils
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -373,7 +374,7 @@ class _Downloader():
|
|||||||
log.downloads.debug("Oops! Download already gone: %s", item)
|
log.downloads.debug("Oops! Download already gone: %s", item)
|
||||||
return
|
return
|
||||||
item.fileobj.actual_close()
|
item.fileobj.actual_close()
|
||||||
self.writer.add_file(ulrutils.encoded_url(url), b'')
|
self.writer.add_file(urlutils.encoded_url(url), b'')
|
||||||
if self.pending_downloads:
|
if self.pending_downloads:
|
||||||
return
|
return
|
||||||
self.finish_file()
|
self.finish_file()
|
||||||
@ -428,12 +429,11 @@ def _start_download(dest, win_id, tab_id):
|
|||||||
dest: The filename where the resulting file should be saved.
|
dest: The filename where the resulting file should be saved.
|
||||||
win_id, tab_id: Specify the tab whose page should be loaded.
|
win_id, tab_id: Specify the tab whose page should be loaded.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dest = os.path.expanduser(dest)
|
|
||||||
web_view = objreg.get('webview', scope='tab', window=win_id, tab=tab_id)
|
web_view = objreg.get('webview', scope='tab', window=win_id, tab=tab_id)
|
||||||
loader = _Downloader(web_view, dest)
|
loader = _Downloader(web_view, dest)
|
||||||
loader.run()
|
loader.run()
|
||||||
|
|
||||||
|
|
||||||
def start_download_checked(dest, win_id, tab_id):
|
def start_download_checked(dest, win_id, tab_id):
|
||||||
"""First check if dest is already a file, then start the download.
|
"""First check if dest is already a file, then start the download.
|
||||||
|
|
||||||
@ -441,20 +441,37 @@ def start_download_checked(dest, win_id, tab_id):
|
|||||||
dest: The filename where the resulting file should be saved.
|
dest: The filename where the resulting file should be saved.
|
||||||
win_id, tab_id: Specify the tab whose page should be loaded.
|
win_id, tab_id: Specify the tab whose page should be loaded.
|
||||||
"""
|
"""
|
||||||
# start_download will call os.path.expanduser on dest too, so no need to
|
# The default name is 'page title.mht'
|
||||||
# overwrite dest. We just want to make sure that we're checking
|
title = (objreg.get('webview', scope='tab', window=win_id, tab=tab_id)
|
||||||
# the right path here. This also means that the user question will show the
|
.title())
|
||||||
# original path, not the expanded.
|
default_name = title + '.mht'
|
||||||
if not os.path.isfile(os.path.expanduser(dest)):
|
|
||||||
_start_download(dest, win_id=win_id, tab_id=tab_id)
|
# 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)
|
||||||
|
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
_start_download(path, win_id=win_id, tab_id=tab_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
q = usertypes.Question()
|
q = usertypes.Question()
|
||||||
q.mode = usertypes.PromptMode.yesno
|
q.mode = usertypes.PromptMode.yesno
|
||||||
q.text = "{} exists. Overwrite?".format(dest)
|
q.text = "{} exists. Overwrite?".format(path)
|
||||||
q.completed.connect(q.deleteLater)
|
q.completed.connect(q.deleteLater)
|
||||||
q.answered_yes.connect(functools.partial(
|
q.answered_yes.connect(functools.partial(
|
||||||
_start_download, dest, win_id=win_id, tab_id=tab_id))
|
_start_download, path, win_id=win_id, tab_id=tab_id))
|
||||||
message_bridge = objreg.get('message-bridge', scope='window',
|
message_bridge = objreg.get('message-bridge', scope='window',
|
||||||
window=win_id)
|
window=win_id)
|
||||||
message_bridge.ask(q, blocking=False)
|
message_bridge.ask(q, blocking=False)
|
||||||
|
Loading…
Reference in New Issue
Block a user