def on_imagesTree_currentItemChanged(self, current, previous): """ Private slot to show a preview of the selected image. @param current current image entry (QTreeWidgetItem) @param previous old current entry (QTreeWidgetItem) """ if current is None: return imageUrl = QUrl(current.text(1)) if not imageUrl.host(): imageUrl.setHost(QUrl(self.siteAddressLabel.text()).host()) imageUrl.setScheme(QUrl(self.siteAddressLabel.text()).scheme()) import Helpviewer.HelpWindow cache = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().cache() if cache: cacheData = cache.data(imageUrl) else: cacheData = None pixmap = QPixmap() invalidPixmap = False scene = QGraphicsScene(self.imagePreview) if not cacheData: invalidPixmap = True else: pixmap.loadFromData(cacheData.readAll()) if pixmap.isNull(): invalidPixmap = True if invalidPixmap: scene.addText(self.tr("Preview not available.")) else: scene.addPixmap(pixmap) self.imagePreview.setScene(scene)
def encode_uri(ds_uri, schema_name, project_name=None): u = QUrl() urlQuery = QUrlQuery() u.setScheme("postgresql") u.setHost(ds_uri.host()) if ds_uri.port() != '': u.setPort(int(ds_uri.port())) if ds_uri.username() != '': u.setUserName(ds_uri.username()) if ds_uri.password() != '': u.setPassword(ds_uri.password()) if ds_uri.service() != '': urlQuery.addQueryItem("service", ds_uri.service()) if ds_uri.authConfigId() != '': urlQuery.addQueryItem("authcfg", ds_uri.authConfigId()) if ds_uri.sslMode() != QgsDataSourceUri.SslPrefer: urlQuery.addQueryItem("sslmode", QgsDataSourceUri.encodeSslMode(ds_uri.sslMode())) urlQuery.addQueryItem("dbname", ds_uri.database()) urlQuery.addQueryItem("schema", schema_name) if project_name: urlQuery.addQueryItem("project", project_name) u.setQuery(urlQuery) return str(u.toEncoded(), 'utf-8')
def keyPressEvent(self, evt): """ Protected method to handle key presses. @param evt reference to the key press event (QKeyEvent) """ if evt.key() == Qt.Key_Escape and self.__browser is not None: self.setText( str(self.__browser.url().toEncoded(), encoding="utf-8")) self.selectAll() return currentText = self.text().strip() if evt.key() in [Qt.Key_Enter, Qt.Key_Return] and \ not currentText.lower().startswith("http://"): append = "" if evt.modifiers() == Qt.KeyboardModifiers(Qt.ControlModifier): append = ".com" elif evt.modifiers() == Qt.KeyboardModifiers(Qt.ControlModifier | Qt.ShiftModifier): append = ".org" elif evt.modifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier): append = ".net" if append != "": url = QUrl("http://www." + currentText) host = url.host() if not host.lower().endswith(append): host += append url.setHost(host) self.setText(url.toString()) E5LineEdit.keyPressEvent(self, evt)
def open_help(self): url = QUrl() url.setScheme(DefaultConfig.Help.url_scheme) url.setHost(DefaultConfig.Help.host) url.setPath(DefaultConfig.Help.url_path_pattern) # % str(Version.babel)) QDesktopServices.openUrl(url)
def keyPressEvent(self, evt): """ Protected method to handle key presses. @param evt reference to the key press event (QKeyEvent) """ if evt.key() == Qt.Key_Escape and self.__browser is not None: self.setText( str(self.__browser.url().toEncoded(), encoding="utf-8")) self.selectAll() return currentText = self.text().strip() if evt.key() in [Qt.Key_Enter, Qt.Key_Return] and \ not currentText.lower().startswith("http://"): append = "" if evt.modifiers() == Qt.KeyboardModifiers(Qt.ControlModifier): append = ".com" elif evt.modifiers() == Qt.KeyboardModifiers( Qt.ControlModifier | Qt.ShiftModifier): append = ".org" elif evt.modifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier): append = ".net" if append != "": url = QUrl("http://www." + currentText) host = url.host() if not host.lower().endswith(append): host += append url.setHost(host) self.setText(url.toString()) E5LineEdit.keyPressEvent(self, evt)
def open_help(self): url = QUrl() url.setScheme(DefaultConfig.Help.url_scheme) url.setHost(DefaultConfig.Help.host) url.setPath( DefaultConfig.Help.url_path_pattern) # % str(Version.babel)) QDesktopServices.openUrl(url)
def intercept(info: interceptor.Request) -> None: if not info.request_url.scheme().startswith('http'): return new_url = QUrl(clear_url(info.request_url.url())) if new_host := redirects.get(new_url.host()): new_url.setHost(new_host)
def data_for_url(url): """Get the data to show for the given URL. Args: url: The QUrl to show. Return: A (mimetype, data) tuple. """ norm_url = url.adjusted(QUrl.NormalizePathSegments | QUrl.StripTrailingSlash) if norm_url != url: raise Redirect(norm_url) path = url.path() host = url.host() query = urlutils.query_string(url) # A url like "qute:foo" is split as "scheme:path", not "scheme:host". log.misc.debug("url: {}, path: {}, host {}".format(url.toDisplayString(), path, host)) if not path or not host: new_url = QUrl() new_url.setScheme('qute') # When path is absent, e.g. qute://help (with no trailing slash) if host: new_url.setHost(host) # When host is absent, e.g. qute:help else: new_url.setHost(path) new_url.setPath('/') if query: new_url.setQuery(query) if new_url.host(): # path was a valid host raise Redirect(new_url) try: handler = _HANDLERS[host] except KeyError: raise NoHandlerFound(url) try: mimetype, data = handler(url) except OSError as e: # FIXME:qtwebengine how to handle this? raise QuteSchemeOSError(e) except QuteSchemeError as e: raise assert mimetype is not None, url if mimetype == 'text/html' and isinstance(data, str): # We let handlers return HTML as text data = data.encode('utf-8', errors='xmlcharrefreplace') return mimetype, data
def data_for_url(url): """Get the data to show for the given URL. Args: url: The QUrl to show. Return: A (mimetype, data) tuple. """ norm_url = url.adjusted(QUrl.NormalizePathSegments | QUrl.StripTrailingSlash) if norm_url != url: raise Redirect(norm_url) path = url.path() host = url.host() query = urlutils.query_string(url) # A url like "qute:foo" is split as "scheme:path", not "scheme:host". log.misc.debug("url: {}, path: {}, host {}".format( url.toDisplayString(), path, host)) if not path or not host: new_url = QUrl() new_url.setScheme('qute') # When path is absent, e.g. qute://help (with no trailing slash) if host: new_url.setHost(host) # When host is absent, e.g. qute:help else: new_url.setHost(path) new_url.setPath('/') if query: new_url.setQuery(query) if new_url.host(): # path was a valid host raise Redirect(new_url) try: handler = _HANDLERS[host] except KeyError: raise NoHandlerFound(url) try: mimetype, data = handler(url) except OSError as e: # FIXME:qtwebengine how to handle this? raise QuteSchemeOSError(e) except QuteSchemeError as e: raise assert mimetype is not None, url if mimetype == 'text/html' and isinstance(data, str): # We let handlers return HTML as text data = data.encode('utf-8', errors='xmlcharrefreplace') return mimetype, data
def __saveImage(self): """ Private slot to save the selected image to disk. """ act = self.sender() index = act.data() itm = self.imagesTree.topLevelItem(index) if itm is None: return imageUrl = QUrl(itm.text(1)) if not imageUrl.host(): imageUrl.setHost(QUrl(self.siteAddressLabel.text()).host()) imageUrl.setScheme(QUrl(self.siteAddressLabel.text()).scheme()) import Helpviewer.HelpWindow cache = Helpviewer.HelpWindow.HelpWindow.networkAccessManager().cache() if cache: cacheData = cache.data(imageUrl) else: cacheData = None if not cacheData: E5MessageBox.critical( self, self.tr("Save Image"), self.tr("""This image is not available.""")) return downloadDirectory = Helpviewer.HelpWindow.HelpWindow\ .downloadManager().downloadDirectory() fn = os.path.join(downloadDirectory, os.path.basename(itm.text(1))) filename = E5FileDialog.getSaveFileName( self, self.tr("Save Image"), fn, self.tr("All Files (*)"), E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) if not filename: return f = QFile(filename) if not f.open(QFile.WriteOnly): E5MessageBox.critical( self, self.tr("Save Image"), self.tr( """<p>Cannot write to file <b>{0}</b>.</p>""") .format(filename)) return f.write(cacheData.readAll()) f.close()
def data_for_url(url: QUrl): """Get the data to show for the given URL. Args: url: The QUrl to show. Return: A (mimetype, data) tuple. """ norm_url = url.adjusted(QUrl.NormalizePathSegments | QUrl.StripTrailingSlash) if norm_url != url: raise Redirect(norm_url) path = url.path() host = url.host() query = urlutils.query_string(url) # A url like "luminos:foo" is split as "scheme:path", not "scheme:host". if not path or not host: new_url = QUrl() new_url.setScheme("luminos") # When path is absent, e.g. luminos://help (with no trailing slash) if host: new_url.setHost(host) # When host is absent, e.g. luminos:help else: new_url.setHost(path) new_url.setPath("/") if query: new_url.setQuery(query) if new_url.host(): # path was a valid host raise Redirect(new_url) try: handler = _HANDLERS[host] except KeyError: raise NotFoundError("No handler found for {}".format( url.toDisplayString())) try: mimetype, data = handler(url) except OSError as e: raise SchemeOSError(e) assert mimetype is not None, url if mimetype == "text/html" and isinstance(data, str): # We let handlers return HTML as text data = data.encode("utf-8", errors="xmlcharrefreplace") return mimetype, data
def addHistoryEntry(self, url): """ Public method to add a history entry. @param url URL to be added (string) """ cleanurl = QUrl(url) if cleanurl.scheme() not in ["eric", "about"]: if cleanurl.password(): # don't save the password in the history cleanurl.setPassword("") if cleanurl.host(): cleanurl.setHost(cleanurl.host().lower()) itm = HistoryEntry(cleanurl.toString(), QDateTime.currentDateTime()) self._addHistoryEntry(itm)
def _init_host(self, parsed: urllib.parse.ParseResult) -> None: """Parse the host from the given URL. Deviation from Chromium: - http://:1234/ is not a valid URL because it has no host. - We don't allow patterns for dot/space hosts which QUrl considers invalid. """ if parsed.hostname is None or not parsed.hostname.strip(): if self._scheme not in self._SCHEMES_WITHOUT_HOST: raise ParseError("Pattern without host") assert self.host is None return if parsed.netloc.startswith('['): # Using QUrl parsing to minimize ipv6 addresses url = QUrl() url.setHost(parsed.hostname) if not url.isValid(): raise ParseError(url.errorString()) self.host = url.host() return if parsed.hostname == '*': self._match_subdomains = True hostname = None elif parsed.hostname.startswith('*.'): if len(parsed.hostname) == 2: # We don't allow just '*.' as a host. raise ParseError("Pattern without host") self._match_subdomains = True hostname = parsed.hostname[2:] elif set(parsed.hostname) in {frozenset('.'), frozenset('. ')}: raise ParseError("Invalid host") else: hostname = parsed.hostname if hostname is None: self.host = None elif '*' in hostname: # Only * or *.foo is allowed as host. raise ParseError("Invalid host wildcard") else: self.host = hostname.rstrip('.')
def resource_url(path, qutescheme=False): """Load images from a relative path (to qutebrowser). Arguments: path: The relative path to the image qutescheme: If the logo needs to be served via a qute:// scheme. This is the case when we want to show an error page from there. """ if qutescheme: url = QUrl() url.setScheme('qute') url.setHost('resource') url.setPath('/' + path) qtutils.ensure_valid(url) return url.toString(QUrl.FullyEncoded) else: full_path = utils.resource_filename(path) return QUrl.fromLocalFile(full_path).toString(QUrl.FullyEncoded)
def _init_host(self, parsed: urllib.parse.ParseResult) -> None: """Parse the host from the given URL. Deviation from Chromium: - http://:1234/ is not a valid URL because it has no host. """ # https://github.com/python/typeshed/commit/f0ccb325aa787ca0a539ef9914276b2c3148327a if (parsed.hostname is None or # type: ignore not parsed.hostname.strip()): if self._scheme not in self._SCHEMES_WITHOUT_HOST: raise ParseError("Pattern without host") assert self._host is None return if parsed.netloc.startswith('['): # Using QUrl parsing to minimize ipv6 addresses url = QUrl() url.setHost(parsed.hostname) if not url.isValid(): raise ParseError(url.errorString()) self._host = url.host() return # FIXME what about multiple dots? host_parts = parsed.hostname.rstrip('.').split('.') if host_parts[0] == '*': host_parts = host_parts[1:] self._match_subdomains = True if not host_parts: self._host = None return self._host = '.'.join(host_parts) if self._host.endswith('.*'): # Special case to have a nicer error raise ParseError("TLD wildcards are not implemented yet") if '*' in self._host: # Only * or *.foo is allowed as host. raise ParseError("Invalid host wildcard")
def data_for_url(url): """Get the data to show for the given URL. Args: url: The QUrl to show. Return: A (mimetype, data) tuple. """ path = url.path() host = url.host() # A url like "qute:foo" is split as "scheme:path", not "scheme:host". log.misc.debug("url: {}, path: {}, host {}".format( url.toDisplayString(), path, host)) if path and not host: new_url = QUrl() new_url.setScheme('qute') new_url.setHost(path) new_url.setPath('/') if new_url.host(): # path was a valid host raise Redirect(new_url) try: handler = _HANDLERS[host] except KeyError: raise NoHandlerFound(url) try: mimetype, data = handler(url) except OSError as e: # FIXME:qtwebengine how to handle this? raise QuteSchemeOSError(e) except QuteSchemeError as e: raise assert mimetype is not None, url if mimetype == 'text/html' and isinstance(data, str): # We let handlers return HTML as text data = data.encode('utf-8', errors='xmlcharrefreplace') return mimetype, data
def url(self, player_id): if self.state == GameState.CLOSED: return None url = QUrl() url.setHost("lobby.faforever.com") query = QUrlQuery() query.addQueryItem("map", self.mapname) query.addQueryItem("mod", self.featured_mod) if self.state == GameState.OPEN: url.setScheme("fafgame") url.setPath("/" + str(player_id)) query.addQueryItem("uid", str(self.uid)) else: url.setScheme("faflive") url.setPath("/" + str(self.uid) + "/" + str(player_id) + ".SCFAreplay") url.setQuery(query) return url
def _init_host(self, parsed): """Parse the host from the given URL. Deviation from Chromium: - http://:1234/ is not a valid URL because it has no host. """ if parsed.hostname is None or not parsed.hostname.strip(): if self._scheme not in self._SCHEMES_WITHOUT_HOST: raise ParseError("Pattern without host") assert self._host is None return if parsed.netloc.startswith('['): # Using QUrl parsing to minimize ipv6 addresses url = QUrl() url.setHost(parsed.hostname) if not url.isValid(): raise ParseError(url.errorString()) self._host = url.host() return # FIXME what about multiple dots? host_parts = parsed.hostname.rstrip('.').split('.') if host_parts[0] == '*': host_parts = host_parts[1:] self._match_subdomains = True if not host_parts: self._host = None return self._host = '.'.join(host_parts) if self._host.endswith('.*'): # Special case to have a nicer error raise ParseError("TLD wildcards are not implemented yet") if '*' in self._host: # Only * or *.foo is allowed as host. raise ParseError("Invalid host wildcard")
class AuthWidget(QWebEngineView): def __init__(self, parent, config=None, credential_file=None, cookie_persistence=False, log_level=logging.INFO): super(AuthWidget, self).__init__(parent) self.parent = parent self.config = None self.config_file = DEFAULT_CONFIG_FILE self.credential = DEFAULT_CREDENTIAL self.credential_file = None self.cookie_file = None self.cookie_jar = None self.auth_url = None self.authn_session = None self.authn_session_page = None self.authn_cookie_name = None self.authn_expires = time.time() self._success_callback = None self._failure_callback = None self._session = requests.session() self.token = None self.default_profile = QWebEngineProfile("deriva-auth", self) self.private_profile = QWebEngineProfile(self) logging.getLogger().setLevel(log_level) info = "%s v%s [Python: %s (PyQt: %s), %s]" % ( self.__class__.__name__, get_installed_version(VERSION), platform.python_version(), PYQT_VERSION_STR, platform.platform(aliased=True)) logging.info("Initializing authorization provider: %s" % info) self.cookie_persistence = cookie_persistence self._timer = QTimer(self) self._timer.timeout.connect(self._onTimerFired) self.configure(config, credential_file) def configure(self, config, credential_file): self.config = config if config else read_config(self.config_file, create_default=True, default=DEFAULT_CONFIG) self.credential_file = credential_file host = self.config.get("host") if not host: self.set_current_html(ERROR_HTML % "Could not locate hostname parameter in configuration.") return self.auth_url = QUrl() self.auth_url.setScheme(config.get("protocol", "https")) self.auth_url.setHost(host) if config.get("port") is not None: self.auth_url.setPort(config["port"]) self.authn_cookie_name = self.config.get("cookie_name", "webauthn") self.cookie_file = DEFAULT_SESSION_CONFIG.get("cookie_jar") self.cookie_jar = load_cookies_from_file(self.cookie_file) retries = Retry(connect=DEFAULT_SESSION_CONFIG['retry_connect'], read=DEFAULT_SESSION_CONFIG['retry_read'], backoff_factor=DEFAULT_SESSION_CONFIG['retry_backoff_factor'], status_forcelist=DEFAULT_SESSION_CONFIG['retry_status_forcelist']) self._session.mount(self.auth_url.toString() + '/', HTTPAdapter(max_retries=retries)) def set_current_html(self, html): page = QWebEnginePage(self.parent) page.setHtml(html) self.setPage(page) self.update() qApp.processEvents() def authenticated(self): if self.authn_session is None: return False now = time.time() if now >= self.authn_expires: return False return True def login(self): if not (self.auth_url and (self.auth_url.host() and self.auth_url.scheme())): logging.error("Missing or invalid hostname parameter in configuration.") return logging.info("Authenticating with host: %s" % self.auth_url.toString()) qApp.setOverrideCursor(Qt.WaitCursor) self._cleanup() self.authn_session_page = QWebEnginePage(self.private_profile, self.parent) \ if not self.cookie_persistence else QWebEnginePage(self.default_profile, self.parent) self.authn_session_page.profile().setPersistentCookiesPolicy( QWebEngineProfile.ForcePersistentCookies if self.cookie_persistence else QWebEngineProfile.NoPersistentCookies) if self.cookie_persistence: logging.debug("QTWebEngine persistent storage located at: %s" % self.authn_session_page.profile().persistentStoragePath()) self.authn_session_page.profile().cookieStore().cookieAdded.connect(self._onCookieAdded) self.authn_session_page.profile().cookieStore().cookieRemoved.connect(self._onCookieRemoved) self.authn_session_page.loadProgress.connect(self._onLoadProgress) self.authn_session_page.loadFinished.connect(self._onLoadFinished) self.authn_session_page.setUrl(QUrl(self.auth_url.toString() + "/authn/preauth")) self.setPage(self.authn_session_page) def logout(self, delete_cookies=False): if not (self.auth_url and (self.auth_url.host() and self.auth_url.scheme())): return if self.authenticated(): try: logging.info("Logging out of host: %s" % self.auth_url.toString()) if delete_cookies and self.cookie_persistence: self.authn_session_page.profile().cookieStore().deleteAllCookies() self._session.delete(self.auth_url.toString() + "/authn/session") if self.credential_file: creds = read_credential(self.credential_file, create_default=True) host = self.auth_url.host() if creds.get(host): del creds[host] write_credential(self.credential_file, creds) except Exception as e: logging.warning("Logout error: %s" % format_exception(e)) self._cleanup() def setSuccessCallback(self, callback=None): self._success_callback = callback def setFailureCallback(self, callback=None): self._failure_callback = callback def setStatus(self, message): if self.window().statusBar is not None: self.window().statusBar().showMessage(message) def _execSuccessCallback(self): if self._success_callback: self._success_callback(host=self.auth_url.host(), credential=self.credential) def _execFailureCallback(self, message): if self._failure_callback: self._failure_callback(host=self.auth_url.host(), message=message) def _onTimerFired(self): if not self.authenticated(): self.authn_session = None return resp = self._session.put(self.auth_url.toString() + "/authn/session") seconds_remaining = self.authn_session['seconds_remaining'] self.authn_expires = time.time() + seconds_remaining + 1 if resp.ok: logging.trace("webauthn session:\n%s\n", resp.json()) logging.info("Session refreshed for: %s" % self.auth_url.host()) else: logging.warning( "Unable to refresh session for: %s. Server responded: %s" % (self.auth_url.host(), str.format("%s %s: %s" % (resp.status_code, resp.reason, resp.content.decode())))) def _onSessionContent(self, content): try: qApp.restoreOverrideCursor() self.set_current_html(SUCCESS_HTML) try: self.authn_session = json.loads(content) except json.JSONDecodeError: raise RuntimeError("Unable to parse response from server: %s" % content) seconds_remaining = self.authn_session['seconds_remaining'] if not self._timer.isActive(): interval = seconds_remaining // 2 logging.info("Authentication successful for [%s]: credential refresh in %d seconds." % (self.auth_url.toString(), interval)) self._timer.start(interval * 1000) self.authn_expires = time.time() + seconds_remaining + 1 logging.trace("webauthn session:\n%s\n", json.dumps(self.authn_session, indent=2)) QTimer.singleShot(100, self._execSuccessCallback) except (ValueError, Exception) as e: error = format_exception(e) logging.error(error) self.set_current_html(ERROR_HTML % content) self._execFailureCallback(error) def _onPreAuthContent(self, content): try: if not content: logging.debug("no preauth content") return preauth = json.loads(content) logging.trace("webauthn preauth:\n%s\n", json.dumps(preauth, indent=2)) qApp.setOverrideCursor(Qt.WaitCursor) self.authn_session_page.setUrl(QUrl(preauth["redirect_url"])) except (ValueError, Exception) as e: logging.error(format_exception(e)) self.set_current_html(ERROR_HTML % content) def _onLoadFinished(self, result): qApp.restoreOverrideCursor() qApp.processEvents() if not result: self.setPage(self.authn_session_page) logging.debug("Page load error: %s" % self.authn_session_page.url().toDisplayString()) return self.set_current_html(DEFAULT_HTML % self.auth_url.host()) path = self.authn_session_page.url().path() if path == "/authn/preauth": self.authn_session_page.toPlainText(self._onPreAuthContent) elif path == "/authn/session": self.authn_session_page.toPlainText(self._onSessionContent) else: if self.page() != self.authn_session_page: self.page().deleteLater() self.setPage(self.authn_session_page) def _onLoadProgress(self, progress): self.setStatus("Loading page: %s [%d%%]" % (self.page().url().host(), progress)) def _onCookieAdded(self, cookie): cookie_str = str(cookie.toRawForm(QNetworkCookie.NameAndValueOnly), encoding='utf-8') cookie_name = str(cookie.name(), encoding='utf-8') cookie_val = str(cookie.value(), encoding='utf-8') if (cookie_name == self.authn_cookie_name) and (cookie.domain() == self.config.get("host")): logging.trace("%s cookie added:\n\n%s\n\n" % (self.authn_cookie_name, cookie_str)) self.credential["cookie"] = "%s=%s" % (self.authn_cookie_name, cookie_val) host = self.auth_url.host() cred_entry = dict() cred_entry[host] = self.credential if self.credential_file: creds = read_credential(self.credential_file, create_default=True) creds.update(cred_entry) write_credential(self.credential_file, creds) self.token = cookie_val self._session.cookies.set(self.authn_cookie_name, cookie_val, domain=host, path='/') if self.cookie_jar is not None: self.cookie_jar.set_cookie( create_cookie(self.authn_cookie_name, cookie_val, domain=host, path='/', expires=0, discard=False, secure=True)) for path in self.config.get("cookie_jars", DEFAULT_CONFIG["cookie_jars"]): path_dir = os.path.dirname(path) if os.path.isdir(path_dir): logging.debug("Saving cookie jar to: %s" % path) self.cookie_jar.save(path, ignore_discard=True, ignore_expires=True) else: logging.debug("Cookie jar save path [%s] does not exist." % path_dir) def _onCookieRemoved(self, cookie): cookie_str = str(cookie.toRawForm(QNetworkCookie.NameAndValueOnly), encoding='utf-8') cookie_name = str(cookie.name(), encoding='utf-8') if cookie_name == self.authn_cookie_name and cookie.domain() == self.url().host(): logging.trace("%s cookie removed:\n\n%s\n\n" % (self.authn_cookie_name, cookie_str)) if self.cookie_jar: self.cookie_jar.clear(cookie_name, path=cookie.path(), domain=cookie.domain()) def _cleanup(self): self._timer.stop() self.token = None self.authn_session = None self.authn_expires = time.time() if self.authn_session_page: self.authn_session_page.loadProgress.disconnect(self._onLoadProgress) self.authn_session_page.loadFinished.disconnect(self._onLoadFinished) self.authn_session_page.profile().cookieStore().cookieAdded.disconnect(self._onCookieAdded) self.authn_session_page.profile().cookieStore().cookieRemoved.disconnect(self._onCookieRemoved) self.authn_session_page.deleteLater() self.authn_session_page = None