Warning

This document is for an old release of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.

Source code for galaxy.tool_util.toolbox.views.static

import logging
import re
from typing import Optional

from .definitions import (
    ExcludeTool,
    ExcludeToolRegex,
    ExcludeTypes,
    ExpandedRootContent,
    Label,
    Section,
    SectionAlias,
    StaticToolBoxView,
    Tool,
    Workflow,
)
from .interface import (
    ToolBoxRegistry,
    ToolPanelView,
    ToolPanelViewModel,
    ToolPanelViewModelType,
)
from ..panel import (
    panel_item_types,
    ToolPanelElements,
    ToolSection,
    ToolSectionLabel,
)

log = logging.getLogger(__name__)


[docs]def build_filter(excludes_): excludes = excludes_ or [] def filter_function(panel_key, panel_value): for exclude in excludes: if panel_key.startswith("tool_"): if isinstance(exclude, ExcludeTool): if panel_value.id == exclude.tool_id: return False if panel_value.old_id == exclude.tool_id: return False if isinstance(exclude, ExcludeToolRegex): if re.match(exclude.tool_id_regex, panel_value.id): return False if re.match(exclude.tool_id_regex, panel_value.old_id): return False if isinstance(exclude, ExcludeTypes): if panel_key.startswith("label_") and "label" in exclude.types: return False if panel_key.startswith("tool_") and "tool" in exclude.types: return False if panel_key.startswith("workflow_") and "workflow" in exclude.types: return False return True return filter_function
[docs]class StaticToolPanelView(ToolPanelView): _definition: StaticToolBoxView
[docs] def __init__(self, definition: StaticToolBoxView): self._definition = definition
[docs] def apply_view(self, base_tool_panel: ToolPanelElements, toolbox_registry: ToolBoxRegistry) -> ToolPanelElements: def apply_filter(definition, elems): excludes = self._all_excludes(definition) if excludes: elems.apply_filter(build_filter(excludes)) def definition_with_items_to_panel(definition, allow_sections: bool = True, items=None): new_panel = ToolPanelElements() if items is None: items = definition.items_expanded for element in items: if element.content_type == "section": assert allow_sections section_def: Section = element section: ToolSection assert section_def.id is not None or section_def.name is not None if element.items: panel = definition_with_items_to_panel(section_def, allow_sections=False) section = ToolSection() if section_def.name is not None: name = section_def.name else: assert section_def.id is not None name = section_def.id section.name = name if section_def.id is not None: section.id = section_def.id else: # TODO: there has to be tool shed code to do this in a consistent way... where is it? section.id = name.replace(" ", "-").lower() section.elems = panel else: closest_section = base_tool_panel.closest_section(section_def.id, section_def.name) if closest_section is None: log.warning( f"Failed to find matching section for (id, name) = ({section_def.id}, {section_def.name})" ) continue section = closest_section.copy(merge_tools=True) if section_def.id is not None: section.id = section_def.id if section_def.name is not None: section.name = section_def.name apply_filter(section_def, section.elems) new_panel.append_section(section.id, section) elif element.content_type == "section_alias": assert allow_sections closest_section = base_tool_panel.closest_section(element.section, element.section) if closest_section is None: log.warning( f"Failed to find matching section for (id, name) = ({element.section}, {element.section})" ) continue section = closest_section.copy(merge_tools=True) apply_filter(element, section.elems) new_panel.append_section(section.id, section) elif element.content_type == "label": as_dict = { "id": element.id or element.text.lower().replace(" ", "-"), "text": element.text, "type": "label", } label = ToolSectionLabel(as_dict) key = f"label_{label.id}" new_panel[key] = label elif element.content_type == "tool": tool_id = element.id if not toolbox_registry.has_tool(tool_id): log.warning( f"Failed to find tool_id {tool_id} from parent toolbox, cannot load into panel view" ) continue tool = toolbox_registry.get_tool(tool_id) toolbox_registry.add_tool_to_tool_panel_view(tool, new_panel) elif element.content_type == "workflow": workflow_def: Workflow = element workflow = toolbox_registry.get_workflow(element.id) panel_id = f"workflow_{workflow_def.id}" new_panel[panel_id] = workflow elif element.content_type == "items_from": closest_section = base_tool_panel.closest_section(element.items_from, element.items_from) if closest_section is None: log.warning(f"Failed to find matching section for (id, name) = ({element.items_from}, None)") continue section = closest_section.copy(merge_tools=True) elems = section.elems apply_filter(element, elems) for key, item in elems.items(): new_panel[key] = item else: raise AssertionError("Unknown static toolbox configuration element encountered.") excludes = self._all_excludes(definition) if excludes: new_panel.apply_filter(build_filter(excludes)) return new_panel root_defintion = self._definition root_items = root_defintion.items_expanded if root_items is None: root_items = [] # No items found, use base tool panel and apply filters to that... for _, panel_type, panel_value in base_tool_panel.panel_items_iter(): item: Optional[ExpandedRootContent] = None if panel_type == panel_item_types.TOOL: item = Tool( id=panel_value.id, ) elif panel_type == panel_item_types.SECTION: item = SectionAlias( section=panel_value.id, ) elif panel_type == panel_item_types.LABEL: item = Label( id=panel_value.id, text=panel_value.text, ) elif panel_type == panel_item_types.WORKFLOW: item = Workflow( id=panel_value.id, ) if item is None: raise Exception("Unknown panel item type encountered.") root_items.append(item) return definition_with_items_to_panel(root_defintion, items=root_items)
def _all_excludes(self, has_excludes): excludes = has_excludes.excludes or [] if has_excludes != self._definition and self._definition.excludes: excludes.extend(self._definition.excludes) return excludes
[docs] def to_model(self) -> ToolPanelViewModel: model_id = self._definition.id name = self._definition.name description = self._definition.description view_type = ToolPanelViewModelType[self._definition.view_type.value] model_class = self.__class__.__name__ return ToolPanelViewModel( id=model_id, name=name, description=description, model_class=model_class, view_type=view_type, searchable=True, )