예제 #1
0
def extract(relpath: str, *, workdir: str) -> ExtractedMetadata:
    if not relpath.endswith(".metainfo.xml") and not relpath.endswith(".appdata.xml"):
        raise _errors.UnhandledFileError(relpath, "appstream")

    dom = _get_transformed_dom(os.path.join(workdir, relpath))

    common_id = _get_value_from_xml_element(dom, "id")
    summary = _get_value_from_xml_element(dom, "summary")
    description = _get_value_from_xml_element(dom, "description")

    desktop_file_paths = []
    desktop_file_ids = _get_desktop_file_ids_from_nodes(dom.findall("launchable"))
    # if there are no launchables, use the appstream id to take into
    # account the legacy appstream definitions
    if common_id and common_id.endswith(".desktop") and not desktop_file_ids:
        desktop_file_ids.append(common_id)

    for desktop_file_id in desktop_file_ids:
        desktop_file_path = _desktop_file_id_to_path(desktop_file_id, workdir=workdir)
        if desktop_file_path:
            desktop_file_paths.append(desktop_file_path)

    icon = _extract_icon(dom, workdir, desktop_file_paths)

    return ExtractedMetadata(
        common_id=common_id,
        summary=summary,
        description=description,
        icon=icon,
        desktop_file_paths=desktop_file_paths,
    )
예제 #2
0
def extract(path: str) -> ExtractedMetadata:
    if os.path.basename(path) != 'setup.py':
        raise _errors.UnhandledFileError(path, 'setup.py')

    spec = importlib.util.spec_from_file_location('setuppy', path)
    setuppy = importlib.util.module_from_spec(spec)

    params = dict()  # type: Dict[str, str]

    def _fake_setup(*args, **kwargs):
        nonlocal params
        params = kwargs

    with patch('setuptools.setup') as setuptools_mock:
        with patch('distutils.core.setup') as distutils_mock:
            setuptools_mock.side_effect = _fake_setup
            distutils_mock.side_effect = _fake_setup
            # This would really fail during the use of the plugin
            # but let's be cautios and add the proper guards.
            try:
                spec.loader.exec_module(setuppy)
            except SystemExit as e:
                raise _errors.SetupPyFileParseError(path=path)
            except ImportError as e:
                raise _errors.SetupPyImportError(path=path,
                                                 error=str(e)) from e

    version = params.get('version')
    description = params.get('description')

    return ExtractedMetadata(version=version, description=description)
예제 #3
0
def extract(relpath: str, *, workdir: str) -> ExtractedMetadata:
    if not relpath.endswith(".metainfo.xml") and not relpath.endswith(
            ".appdata.xml"):
        raise _errors.UnhandledFileError(relpath, "appstream")

    dom = _get_transformed_dom(os.path.join(workdir, relpath))

    common_id = _get_value_from_xml_element(dom, "id")
    summary = _get_value_from_xml_element(dom, "summary")
    description = _get_value_from_xml_element(dom, "description")

    icon = None
    node = dom.find("icon")
    if node is not None and "type" in node.attrib and node.attrib[
            "type"] == "local":
        # TODO Currently we only support local icons.
        # See bug https://bugs.launchpad.net/snapcraft/+bug/1742348
        # for supporting remote icons.
        # --elopio -20180109
        icon = node.text.strip()

    desktop_file_paths = []
    desktop_file_ids = _get_desktop_file_ids_from_nodes(
        dom.findall("launchable"))
    # if there are no launchables, use the appstream id to take into
    # account the legacy appstream definitions
    if common_id and common_id.endswith(".desktop") and not desktop_file_ids:
        desktop_file_ids.append(common_id)

    for desktop_file_id in desktop_file_ids:
        desktop_file_path = _desktop_file_id_to_path(desktop_file_id,
                                                     workdir=workdir)
        if desktop_file_path:
            desktop_file_paths.append(desktop_file_path)

    return ExtractedMetadata(
        common_id=common_id,
        summary=summary,
        description=description,
        icon=icon,
        desktop_file_paths=desktop_file_paths,
    )
예제 #4
0
def extract(path: str) -> ExtractedMetadata:
    if not path.endswith('.metainfo.xml'):
        raise _errors.UnhandledFileError(path, 'appstream')

    try:
        tree = ElementTree().parse(path)
    except ParseError as e:
        raise _errors.AppstreamFileParseError(path) from e

    summary = None
    node = tree.find('summary')
    if node is not None:
        summary = node.text

    description = None
    node = tree.find('description')
    if node is not None:
        description = node.text

    return ExtractedMetadata(summary=summary, description=description)
예제 #5
0
def extract(path: str) -> ExtractedMetadata:
    if (not path.endswith('.metainfo.xml')
            and not path.endswith('.appdata.xml')):
        raise _errors.UnhandledFileError(path, 'appstream')

    try:
        tree = ElementTree().parse(path)
    except ParseError as e:
        raise _errors.AppstreamFileParseError(path) from e

    summary = None
    node = tree.find('summary')
    if node is not None:
        summary = node.text.strip()

    description = None
    node = tree.find('description')
    if node is not None:
        description = node.text.strip()

    icon = None
    node = tree.find('icon')
    if (node is not None and 'type' in node.attrib
            and node.attrib['type'] == 'local'):
        # TODO Currently we only support local icons.
        # See bug https://bugs.launchpad.net/snapcraft/+bug/1742348
        # for supporting remote icons.
        # --elopio -20180109
        icon = node.text.strip()

    desktop_file_ids = []
    nodes = tree.findall('launchable')
    for node in nodes:
        if ('type' in node.attrib and node.attrib['type'] == 'desktop-id'):
            desktop_file_ids.append(node.text.strip())

    return ExtractedMetadata(summary=summary,
                             description=description,
                             icon=icon,
                             desktop_file_ids=desktop_file_ids)
예제 #6
0
def extract(relpath: str, *, workdir: str) -> ExtractedMetadata:
    if os.path.basename(relpath) != "setup.py":
        raise _errors.UnhandledFileError(relpath, "setup.py")

    spec = importlib.util.spec_from_file_location(
        "setuppy", os.path.join(workdir, relpath)
    )
    setuppy = importlib.util.module_from_spec(spec)

    params = dict()  # type: Dict[str, str]

    def _fake_setup(*args, **kwargs):
        nonlocal params
        params = kwargs

    with patch("setuptools.setup") as setuptools_mock:
        with patch("distutils.core.setup") as distutils_mock:
            setuptools_mock.side_effect = _fake_setup
            distutils_mock.side_effect = _fake_setup

            # Should never happen, but ensure spec.loader is set.
            loader = spec.loader
            if loader is None or not isinstance(loader, Loader):
                raise RuntimeError("Invalid spec loader")

            # This would really fail during the use of the plugin
            # but let's be cautious and add the proper guards.
            try:
                loader.exec_module(setuppy)
            except SystemExit:
                raise _errors.SetupPyFileParseError(path=relpath)
            except ImportError as e:
                raise _errors.SetupPyImportError(path=relpath, error=str(e)) from e

    version = params.get("version")
    description = params.get("description")

    return ExtractedMetadata(version=version, description=description)
예제 #7
0
def extract(path: str) -> ExtractedMetadata:
    if not path.endswith(".metainfo.xml") and not path.endswith(".appdata.xml"):
        raise _errors.UnhandledFileError(path, "appstream")

    try:
        tree = ElementTree().parse(path)
    except ParseError as e:
        raise _errors.AppstreamFileParseError(path) from e

    common_id = _get_value_from_xml_element(tree, "id")
    summary = _get_value_from_xml_element(tree, "summary")
    description = _get_value_from_xml_element(tree, "description")

    icon = None
    node = tree.find("icon")
    if node is not None and "type" in node.attrib and node.attrib["type"] == "local":
        # TODO Currently we only support local icons.
        # See bug https://bugs.launchpad.net/snapcraft/+bug/1742348
        # for supporting remote icons.
        # --elopio -20180109
        icon = node.text.strip()

    desktop_file_paths = []
    nodes = tree.findall("launchable")
    for node in nodes:
        if "type" in node.attrib and node.attrib["type"] == "desktop-id":
            desktop_file_id = node.text.strip()
            desktop_file_path = _desktop_file_id_to_path(desktop_file_id)
            if desktop_file_path:
                desktop_file_paths.append(desktop_file_path)

    return ExtractedMetadata(
        common_id=common_id,
        summary=summary,
        description=description,
        icon=icon,
        desktop_file_paths=desktop_file_paths,
    )