Move common filename-ask-code to a function

This should reduce code/logic-duplication regarding asking for download
filenames.
This commit is contained in:
Daniel Schadt 2015-11-11 23:45:53 +01:00
parent 18da73227b
commit c759bf7a2f
2 changed files with 85 additions and 54 deletions

View File

@ -1185,22 +1185,20 @@ class CommandDispatcher:
dest: The file path to write the download to. dest: The file path to write the download to.
""" """
tab_id = self._current_index() tab_id = self._current_index()
if not config.get('storage', 'prompt-download-directory'):
dest = downloads.download_dir()
if dest is None: if dest is None:
suggested_fn = self._current_title() + ".mht" suggested_fn = self._current_title() + ".mht"
suggested_fn = utils.sanitize_filename(suggested_fn) suggested_fn = utils.sanitize_filename(suggested_fn)
q = usertypes.Question() filename, q = downloads.ask_for_filename(
q.text = "Save page to: " suggested_fn, self._win_id, parent=self,
q.mode = usertypes.PromptMode.text )
q.completed.connect(q.deleteLater) if filename is not None:
q.default = downloads.path_suggestion(suggested_fn) mhtml.start_download_checked(filename, win_id=self._win_id,
q.answered.connect(functools.partial( tab_id=tab_id)
mhtml.start_download_checked, win_id=self._win_id, else:
tab_id=tab_id)) q.answered.connect(functools.partial(
message_bridge = objreg.get("message-bridge", scope="window", mhtml.start_download_checked, win_id=self._win_id,
window=self._win_id) tab_id=tab_id))
message_bridge.ask(q, blocking=False) q.ask()
else: else:
mhtml.start_download_checked(dest, win_id=self._win_id, mhtml.start_download_checked(dest, win_id=self._win_id,
tab_id=tab_id) tab_id=tab_id)

View File

@ -48,6 +48,11 @@ ModelRole = usertypes.enum('ModelRole', ['item'], start=Qt.UserRole,
RetryInfo = collections.namedtuple('RetryInfo', ['request', 'manager']) RetryInfo = collections.namedtuple('RetryInfo', ['request', 'manager'])
DownloadPath = collections.namedtuple('DownloadPath', ['filename',
'question'])
# Remember the last used directory # Remember the last used directory
last_used_directory = None last_used_directory = None
@ -109,6 +114,49 @@ def create_full_filename(basename, filename):
return None return None
def ask_for_filename(suggested_filename, win_id, *, parent=None,
prompt_download_directory=None):
"""Prepare a question for a download-path.
If a filename can be determined directly, it is returned instead.
Returns a (filename, question)-namedtuple, in which one component is
None. filename is a string, question is a usertypes.Question. The
question has a special .ask() method that takes no arguments for
convenience, as this function does not yet ask the question, it
only prepares it.
Args:
suggested_filename: The "default"-name that is pre-entered as path.
win_id: The window where the question will be asked.
parent: The parent of the question (a QObject).
prompt_download_directory: If this is something else than None, it
will overwrite the
storage->prompt-download-directory setting.
"""
if prompt_download_directory is None:
prompt_download_directory = config.get('storage',
'prompt-download-directory')
if not prompt_download_directory:
return DownloadPath(download_dir(), None)
encoding = sys.getfilesystemencoding()
suggested_filename = utils.force_encoding(suggested_filename,
encoding)
q = usertypes.Question(parent)
q.text = "Save file to:"
q.mode = usertypes.PromptMode.text
q.completed.connect(q.deleteLater)
q.default = path_suggestion(suggested_filename)
message_bridge = objreg.get('message-bridge', scope='window',
window=win_id)
q.ask = lambda: message_bridge.ask(q, blocking=False)
return DownloadPath(None, q)
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.
@ -668,15 +716,10 @@ class DownloadManager(QAbstractListModel):
def __repr__(self): def __repr__(self):
return utils.get_repr(self, downloads=len(self.downloads)) return utils.get_repr(self, downloads=len(self.downloads))
def _prepare_question(self): def _postprocess_question(self, q):
"""Prepare a Question object to be asked.""" """Postprocess a Question object that is asked."""
q = usertypes.Question(self)
q.text = "Save file to:"
q.mode = usertypes.PromptMode.text
q.completed.connect(q.deleteLater)
q.destroyed.connect(functools.partial(self.questions.remove, q)) q.destroyed.connect(functools.partial(self.questions.remove, q))
self.questions.append(q) self.questions.append(q)
return q
@pyqtSlot() @pyqtSlot()
def update_gui(self): def update_gui(self):
@ -733,11 +776,11 @@ class DownloadManager(QAbstractListModel):
QNetworkRequest.AlwaysNetwork) QNetworkRequest.AlwaysNetwork)
suggested_fn = urlutils.filename_from_url(request.url()) suggested_fn = urlutils.filename_from_url(request.url())
if prompt_download_directory is None: if fileobj is None:
prompt_download_directory = config.get( filename, q = ask_for_filename(
'storage', 'prompt-download-directory') suggested_fn, self._win_id, parent=self,
if not prompt_download_directory and not fileobj: prompt_download_directory=prompt_download_directory
filename = download_dir() )
if fileobj is not None or filename is not None: if fileobj is not None or filename is not None:
return self.fetch_request(request, return self.fetch_request(request,
@ -745,22 +788,13 @@ class DownloadManager(QAbstractListModel):
filename=filename, filename=filename,
suggested_filename=suggested_fn, suggested_filename=suggested_fn,
**kwargs) **kwargs)
if suggested_fn is None:
suggested_fn = 'qutebrowser-download'
else:
encoding = sys.getfilesystemencoding()
suggested_fn = utils.force_encoding(suggested_fn, encoding)
q = self._prepare_question()
q.default = path_suggestion(suggested_fn)
message_bridge = objreg.get('message-bridge', scope='window',
window=self._win_id)
q.answered.connect( q.answered.connect(
lambda fn: self.fetch_request(request, lambda fn: self.fetch_request(request,
filename=fn, filename=fn,
suggested_filename=suggested_fn, suggested_filename=suggested_fn,
**kwargs)) **kwargs))
message_bridge.ask(q, blocking=False) self._postprocess_question(q)
q.ask()
return None return None
def fetch_request(self, request, *, page=None, **kwargs): def fetch_request(self, request, *, page=None, **kwargs):
@ -834,26 +868,25 @@ class DownloadManager(QAbstractListModel):
if not self._update_timer.isActive(): if not self._update_timer.isActive():
self._update_timer.start() self._update_timer.start()
prompt_download_directory = config.get('storage', if fileobj is not None:
'prompt-download-directory')
if not prompt_download_directory and not fileobj:
filename = download_dir()
if filename is not None:
download.set_filename(filename)
elif fileobj is not None:
download.set_fileobj(fileobj) download.set_fileobj(fileobj)
download.autoclose = False download.autoclose = False
else: return download
q = self._prepare_question()
q.default = path_suggestion(suggested_filename) filename, q = ask_for_filename(
q.answered.connect(download.set_filename) suggested_filename, self._win_id, parent=self,
q.cancelled.connect(download.cancel) prompt_download_directory=prompt_download_directory,
download.cancelled.connect(q.abort) )
download.error.connect(q.abort) if filename is not None:
message_bridge = objreg.get('message-bridge', scope='window', download.set_filename(filename)
window=self._win_id) return download
message_bridge.ask(q, blocking=False)
self._postprocess_question(q)
q.answered.connect(download.set_filename)
q.cancelled.connect(download.cancel)
download.cancelled.connect(q.abort)
download.error.connect(q.abort)
q.ask()
return download return download