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 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()
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()
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
elems = closest_section.elems.copy()
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,
)