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
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)
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
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)
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)
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
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
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)
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
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)
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))