File: C:/Users/fred/anaconda3/Lib/site-packages/anaconda_navigator/widgets/web/links.py
# -*- coding: utf8 -*-
"""Helper components for web links."""
from __future__ import annotations
__all__ = ['open_link', 'NavigatorLink']
import collections.abc
import typing
import urllib.parse
from qtpy import QtCore
from qtpy import QtGui
from anaconda_navigator.utils import telemetry
if typing.TYPE_CHECKING:
import typing_extensions
def open_link(url: str | QtCore.QUrl, *, origin: str | None = None) -> None:
"""Open a :code:`url` in an external web browser."""
qt_url: QtCore.QUrl
if isinstance(url, QtCore.QUrl):
url, qt_url = url.toString(), url
else:
qt_url = QtCore.QUrl(url)
if url.startswith('navigator://'):
raise ValueError('Navigator links must be processed separately')
QtGui.QDesktopServices.openUrl(qt_url)
details: dict[str, typing.Any] = {'url': url}
if origin is not None:
details['origin'] = origin
telemetry.ANALYTICS.instance.event('redirect', details)
class NavigatorLink(typing.NamedTuple):
"""Details on a :code:`navigator://` link."""
path: collections.abc.Sequence[str]
query: collections.abc.Mapping[str, str]
@classmethod
def parse(cls, url: str) -> typing_extensions.Self:
"""Parse a :code:`navigator://` link."""
parts: list[str] = url.split('://', 1)
if len(parts) > 1:
if parts[0] != 'navigator':
raise ValueError('url is not a `navigator://` link')
parts = parts[1:]
parts = parts[0].split('?', 1)
query: dict[str, str] = {}
if len(parts) >= 2:
query.update(urllib.parse.parse_qsl(parts[1], keep_blank_values=True))
return cls(
path=tuple(map(urllib.parse.unquote, parts[0].split('/'))),
query=query,
)