示例#1
0
def find_api_page(obj, version=None, openinbrowser=True, timeout=None):
    """
    Determines the URL of the API page for the specified object, and
    optionally open that page in a web browser.

    .. note::
        You must be connected to the internet for this to function even if
        ``openinbrowser`` is `False`, unless you provide a local version of
        the documentation to ``version`` (e.g., ``file:///path/to/docs``).

    Parameters
    ----------
    obj
        The object to open the docs for or its fully-qualified name
        (as a str).
    version : str
        The doc version - either a version number like '0.1', 'dev' for
        the development/latest docs, or a URL to point to a specific
        location that should be the *base* of the documentation. Defaults to
        latest if you are on aren't on a release, otherwise, the version you
        are on.
    openinbrowser : bool
        If `True`, the `webbrowser` package will be used to open the doc
        page in a new web browser window.
    timeout : number, optional
        The number of seconds to wait before timing-out the query to
        the astropy documentation.  If not given, the default python
        stdlib timeout will be used.

    Returns
    -------
    url : str
        The loaded URL

    Raises
    ------
    ValueError
        If the documentation can't be found

    """
    import webbrowser
    import urllib.request
    from zlib import decompress

    if (not isinstance(obj, str) and hasattr(obj, '__module__')
            and hasattr(obj, '__name__')):
        obj = obj.__module__ + '.' + obj.__name__
    elif inspect.ismodule(obj):
        obj = obj.__name__

    if version is None:
        from astropy import version

        if version.release:
            version = 'v' + version.version
        else:
            version = 'dev'

    if '://' in version:
        if version.endswith('index.html'):
            baseurl = version[:-10]
        elif version.endswith('/'):
            baseurl = version
        else:
            baseurl = version + '/'
    elif version == 'dev' or version == 'latest':
        baseurl = 'http://devdocs.astropy.org/'
    else:
        baseurl = f'http://docs.astropy.org/en/{version}/'

    if timeout is None:
        uf = urllib.request.urlopen(baseurl + 'objects.inv')
    else:
        uf = urllib.request.urlopen(baseurl + 'objects.inv', timeout=timeout)

    try:
        oiread = uf.read()

        # need to first read/remove the first four lines, which have info before
        # the compressed section with the actual object inventory
        idx = -1
        headerlines = []
        for _ in range(4):
            oldidx = idx
            idx = oiread.index(b'\n', oldidx + 1)
            headerlines.append(oiread[(oldidx + 1):idx].decode('utf-8'))

        # intersphinx version line, project name, and project version
        ivers, proj, vers, compr = headerlines
        if 'The remainder of this file is compressed using zlib' not in compr:
            raise ValueError('The file downloaded from {} does not seem to be'
                             'the usual Sphinx objects.inv format.  Maybe it '
                             'has changed?'.format(baseurl + 'objects.inv'))

        compressed = oiread[(idx + 1):]
    finally:
        uf.close()

    decompressed = decompress(compressed).decode('utf-8')

    resurl = None

    for l in decompressed.strip().splitlines():
        ls = l.split()
        name = ls[0]
        loc = ls[3]
        if loc.endswith('$'):
            loc = loc[:-1] + name

        if name == obj:
            resurl = baseurl + loc
            break

    if resurl is None:
        raise ValueError(f'Could not find the docs for the object {obj}')
    elif openinbrowser:
        webbrowser.open(resurl)

    return resurl
示例#2
0
文件: misc.py 项目: Cadair/astropy
def find_api_page(obj, version=None, openinbrowser=True, timeout=None):
    """
    Determines the URL of the API page for the specified object, and
    optionally open that page in a web browser.

    .. note::
        You must be connected to the internet for this to function even if
        ``openinbrowser`` is `False`, unless you provide a local version of
        the documentation to ``version`` (e.g., ``file:///path/to/docs``).

    Parameters
    ----------
    obj
        The object to open the docs for or its fully-qualified name
        (as a str).
    version : str
        The doc version - either a version number like '0.1', 'dev' for
        the development/latest docs, or a URL to point to a specific
        location that should be the *base* of the documentation. Defaults to
        latest if you are on aren't on a release, otherwise, the version you
        are on.
    openinbrowser : bool
        If `True`, the `webbrowser` package will be used to open the doc
        page in a new web browser window.
    timeout : number, optional
        The number of seconds to wait before timing-out the query to
        the astropy documentation.  If not given, the default python
        stdlib timeout will be used.

    Returns
    -------
    url : str
        The loaded URL

    Raises
    ------
    ValueError
        If the documentation can't be found

    """
    import webbrowser
    import urllib.request
    from zlib import decompress

    if (not isinstance(obj, str) and
            hasattr(obj, '__module__') and
            hasattr(obj, '__name__')):
        obj = obj.__module__ + '.' + obj.__name__
    elif inspect.ismodule(obj):
        obj = obj.__name__

    if version is None:
        from astropy import version

        if version.release:
            version = 'v' + version.version
        else:
            version = 'dev'

    if '://' in version:
        if version.endswith('index.html'):
            baseurl = version[:-10]
        elif version.endswith('/'):
            baseurl = version
        else:
            baseurl = version + '/'
    elif version == 'dev' or version == 'latest':
        baseurl = 'http://devdocs.astropy.org/'
    else:
        baseurl = 'http://docs.astropy.org/en/{vers}/'.format(vers=version)

    if timeout is None:
        uf = urllib.request.urlopen(baseurl + 'objects.inv')
    else:
        uf = urllib.request.urlopen(baseurl + 'objects.inv', timeout=timeout)

    try:
        oiread = uf.read()

        # need to first read/remove the first four lines, which have info before
        # the compressed section with the actual object inventory
        idx = -1
        headerlines = []
        for _ in range(4):
            oldidx = idx
            idx = oiread.index(b'\n', oldidx + 1)
            headerlines.append(oiread[(oldidx+1):idx].decode('utf-8'))

        # intersphinx version line, project name, and project version
        ivers, proj, vers, compr = headerlines
        if 'The remainder of this file is compressed using zlib' not in compr:
            raise ValueError('The file downloaded from {0} does not seem to be'
                             'the usual Sphinx objects.inv format.  Maybe it '
                             'has changed?'.format(baseurl + 'objects.inv'))

        compressed = oiread[(idx+1):]
    finally:
        uf.close()

    decompressed = decompress(compressed).decode('utf-8')

    resurl = None

    for l in decompressed.strip().splitlines():
        ls = l.split()
        name = ls[0]
        loc = ls[3]
        if loc.endswith('$'):
            loc = loc[:-1] + name

        if name == obj:
            resurl = baseurl + loc
            break

    if resurl is None:
        raise ValueError('Could not find the docs for the object {obj}'.format(obj=obj))
    elif openinbrowser:
        webbrowser.open(resurl)

    return resurl