class TestDownloadTarget: def test_filename(self): target = downloads.FileDownloadTarget("/foo/bar") assert target.filename == "/foo/bar" def test_fileobj(self): fobj = object() target = downloads.FileObjDownloadTarget(fobj) assert target.fileobj is fobj def test_openfile(self): target = downloads.OpenFileDownloadTarget() assert target.cmdline is None def test_openfile_custom_command(self): target = downloads.OpenFileDownloadTarget('echo') assert target.cmdline == 'echo' @pytest.mark.parametrize('obj', [ downloads.FileDownloadTarget('foobar'), downloads.FileObjDownloadTarget(None), downloads.OpenFileDownloadTarget(), ]) def test_class_hierarchy(self, obj): assert isinstance(obj, downloads._DownloadTarget)
def _get_required_scripts(self, script, force=False): required_dls = [(url, self._required_url_to_file_path(url)) for url in script.requires] if not force: required_dls = [(url, path) for (url, path) in required_dls if not os.path.exists(path)] if not required_dls: # All the required files exist already self._add_script_with_requires(script, quiet=True) return download_manager = objreg.get('qtnetwork-download-manager') for url, target_path in required_dls: target = downloads.FileDownloadTarget(target_path, force_overwrite=True) download = download_manager.get(QUrl(url), target=target, auto_remove=True) download.requested_url = url self._in_progress_dls.append(download) if download.successful: self._on_required_download_finished(script, download) else: download.finished.connect( functools.partial(self._on_required_download_finished, script, download))
def handle_download(self, qt_item): """Start a download coming from a QWebEngineProfile.""" suggested_filename = _get_suggested_filename(qt_item.path()) use_pdfjs = pdfjs.should_use_pdfjs(qt_item.mimeType(), qt_item.url()) download = DownloadItem(qt_item) self._init_item(download, auto_remove=use_pdfjs, suggested_filename=suggested_filename) if self._mhtml_target is not None: download.set_target(self._mhtml_target) self._mhtml_target = None return if use_pdfjs: download.set_target(downloads.PDFJSDownloadTarget()) return filename = downloads.immediate_download_path() if filename is not None: # User doesn't want to be asked, so just use the download_dir target = downloads.FileDownloadTarget(filename) download.set_target(target) return # Ask the user for a filename - needs to be blocking! question = downloads.get_filename_question( suggested_filename=suggested_filename, url=qt_item.url(), parent=self) self._init_filename_question(question, download) message.global_bridge.ask(question, blocking=True)
def handle_download(self, qt_item): """Start a download coming from a QWebEngineProfile.""" qt_filename = os.path.basename(qt_item.path()) # FIXME use 5.14 API mime_type = qt_item.mimeType() url = qt_item.url() # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-90355 if version.qtwebengine_versions().webengine >= utils.VersionNumber( 5, 15, 3): needs_workaround = False elif url.scheme().lower() == 'data': if '/' in url.path().split(',')[-1]: # e.g. a slash in base64 wrong_filename = url.path().split('/')[-1] else: wrong_filename = mime_type.split('/')[1] needs_workaround = qt_filename == wrong_filename else: needs_workaround = False if needs_workaround: suggested_filename = urlutils.filename_from_url( url, fallback='qutebrowser-download') else: suggested_filename = _strip_suffix(qt_filename) use_pdfjs = pdfjs.should_use_pdfjs(mime_type, url) download = DownloadItem(qt_item, manager=self) self._init_item(download, auto_remove=use_pdfjs, suggested_filename=suggested_filename) if self._mhtml_target is not None: download.set_target(self._mhtml_target) self._mhtml_target = None return if use_pdfjs: download.set_target(downloads.PDFJSDownloadTarget()) return filename = downloads.immediate_download_path() if filename is not None: # User doesn't want to be asked, so just use the download_dir target = downloads.FileDownloadTarget(filename) download.set_target(target) return if download.cancel_for_origin(): return # Ask the user for a filename - needs to be blocking! question = downloads.get_filename_question( suggested_filename=suggested_filename, url=qt_item.url(), parent=self) self._init_filename_question(question, download) message.global_bridge.ask(question, blocking=True)
def fetch(self, reply, *, target=None, auto_remove=False, suggested_filename=None, prompt_download_directory=None): """Download a QNetworkReply to disk. Args: reply: The QNetworkReply to download. target: Where to save the download as downloads.DownloadTarget. auto_remove: Whether to remove the download even if downloads.remove_finished is set to -1. suggested_filename: The filename to use for the file. prompt_download_directory: Whether to prompt for a location to download the file to. Return: The created DownloadItem. """ if not suggested_filename: try: suggested_filename = target.suggested_filename() except downloads.NoFilenameError: _, suggested_filename = http.parse_content_disposition(reply) log.downloads.debug("fetch: {} -> {}".format(reply.url(), suggested_filename)) download = DownloadItem(reply, manager=self) self._init_item(download, auto_remove, suggested_filename) if download.cancel_for_origin(): return download if target is not None: download.set_target(target) return download # Neither filename nor fileobj were given filename = downloads.immediate_download_path(prompt_download_directory) if filename is not None: # User doesn't want to be asked, so just use the download_dir target = downloads.FileDownloadTarget(filename) download.set_target(target) return download # Ask the user for a filename question = downloads.get_filename_question( suggested_filename=suggested_filename, url=reply.url(), parent=self) self._init_filename_question(question, download) message.global_bridge.ask(question, blocking=False) return download
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 test_sanitized_filenames(raw, expected, config_stub, download_tmpdir, monkeypatch): manager = downloads.AbstractDownloadManager() target = downloads.FileDownloadTarget(str(download_tmpdir)) item = downloads.AbstractDownloadItem() # Don't try to start a timer outside of a QThread manager._update_timer.isActive = lambda: True # Abstract methods item._ensure_can_set_filename = lambda *args: True item._after_set_filename = lambda *args: True manager._init_item(item, True, raw) item.set_target(target) assert item._filename.endswith(expected)
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 handle_download(self, qt_item): """Start a download coming from a QWebEngineProfile.""" if qt_item.url().scheme().lower() == 'data': # WORKAROUND for an unknown QtWebEngine bug (?) which gives us base64 data # as filename. suggested_filename = urlutils.filename_from_url( qt_item.url(), fallback='qutebrowser-download') else: suggested_filename = _get_suggested_filename(qt_item.path()) use_pdfjs = pdfjs.should_use_pdfjs(qt_item.mimeType(), qt_item.url()) download = DownloadItem(qt_item, manager=self) self._init_item(download, auto_remove=use_pdfjs, suggested_filename=suggested_filename) if self._mhtml_target is not None: download.set_target(self._mhtml_target) self._mhtml_target = None return if use_pdfjs: download.set_target(downloads.PDFJSDownloadTarget()) return filename = downloads.immediate_download_path() if filename is not None: # User doesn't want to be asked, so just use the download_dir target = downloads.FileDownloadTarget(filename) download.set_target(target) return # Ask the user for a filename - needs to be blocking! question = downloads.get_filename_question( suggested_filename=suggested_filename, url=qt_item.url(), parent=self) self._init_filename_question(question, download) message.global_bridge.ask(question, blocking=True)
def accept(self, value=None, save=False): done = super().accept(value, save) answer = self.question.answer if answer is not None: self.question.answer = downloads.FileDownloadTarget(answer) return done
def test_filename(self): target = downloads.FileDownloadTarget("/foo/bar") assert target.filename == "/foo/bar"
def accept(self, value=None): text = value if value is not None else self._lineedit.text() self.question.answer = downloads.FileDownloadTarget(text) return True