From ec2b860bf0b73a6784fe322b026960734f6991f0 Mon Sep 17 00:00:00 2001 From: David Pape Date: Wed, 11 Dec 2024 09:22:53 +0100 Subject: [PATCH 01/40] First iteration of plugin list on main page --- docs/source/_templates/plugins.html | 35 +++++++++++++++++ docs/source/conf.py | 1 + docs/source/index.md | 11 +++++- docs/source/plugins.json | 61 +++++++++++++++++++++++++++++ poetry.lock | 59 +++++++++++++++++++++++++++- pyproject.toml | 1 + 6 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 docs/source/_templates/plugins.html create mode 100644 docs/source/plugins.json diff --git a/docs/source/_templates/plugins.html b/docs/source/_templates/plugins.html new file mode 100644 index 00000000..a27cb6b5 --- /dev/null +++ b/docs/source/_templates/plugins.html @@ -0,0 +1,35 @@ +{# +SPDX-FileCopyrightText: 2024 Helmholtz-Zentrum Dresden-Rossendorf +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileContributor: David Pape +#} + diff --git a/docs/source/conf.py b/docs/source/conf.py index 2009097c..5775bd01 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -60,6 +60,7 @@ 'autoapi.extension', 'sphinxcontrib.mermaid', 'sphinx_togglebutton', + 'sphinxcontrib.datatemplates', ] language = 'en' diff --git a/docs/source/index.md b/docs/source/index.md index 5c290d81..99922fc8 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -33,6 +33,15 @@ automatic submission to publication repositories. ![](_static/img/workflow-overview.svg) +## Plugins + +Hermes is built to be extensible for your needs. +This is a list of available plugins: + +```{datatemplate:json} ../source/plugins.json +:template: plugins.html +``` + ## Documentation ![](_static/img/header.png) From ffcd4eada995854da045ad33cbbc04fe27321ea0 Mon Sep 17 00:00:00 2001 From: David Pape Date: Mon, 16 Dec 2024 16:32:10 +0100 Subject: [PATCH 26/40] =?UTF-8?q?market=20place=20=E2=86=92=20marketplace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hermes/commands/marketplace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hermes/commands/marketplace.py b/src/hermes/commands/marketplace.py index ff1dfe63..778365ec 100644 --- a/src/hermes/commands/marketplace.py +++ b/src/hermes/commands/marketplace.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileContributor: David Pape -"""Basic CLI to list plugins from the Hermes market place.""" +"""Basic CLI to list plugins from the Hermes marketplace.""" from html.parser import HTMLParser from typing import List, Optional From 9d019b9eabef14a1de01e8de660fc21933984b89 Mon Sep 17 00:00:00 2001 From: David Pape Date: Wed, 18 Dec 2024 12:49:19 +0100 Subject: [PATCH 27/40] Remove rawource from docutils nodes --- docs/source/_ext/plugin_markup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/_ext/plugin_markup.py b/docs/source/_ext/plugin_markup.py index 029d9425..74df5020 100644 --- a/docs/source/_ext/plugin_markup.py +++ b/docs/source/_ext/plugin_markup.py @@ -95,7 +95,7 @@ def run(self) -> list[nodes.Node]: by_alias=True, exclude_none=True ) tag = f'' - tags.append(nodes.raw(rawsource=markup, text=tag, format="html")) + tags.append(nodes.raw(text=tag, format="html")) return tags From a9291b60895a5416bd6cfd4d66c0ef424d4e197a Mon Sep 17 00:00:00 2001 From: David Pape Date: Wed, 18 Dec 2024 15:00:25 +0100 Subject: [PATCH 28/40] Keywords based on harvested files --- .../add-plugin-to-marketplace.yml | 7 +++++++ docs/source/_ext/plugin_markup.py | 19 +++++++++++++++++++ docs/source/plugins-schema.json | 9 +++++++++ docs/source/plugins.json | 3 +++ 4 files changed, 38 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/add-plugin-to-marketplace.yml b/.github/ISSUE_TEMPLATE/add-plugin-to-marketplace.yml index 1ed263ed..11437b35 100644 --- a/.github/ISSUE_TEMPLATE/add-plugin-to-marketplace.yml +++ b/.github/ISSUE_TEMPLATE/add-plugin-to-marketplace.yml @@ -48,6 +48,13 @@ body: multiple: true options: ["harvest", "process", "curate", "deposit", "postprocess"] + - id: "harvested-files" + type: "input" + attributes: + label: "Harvested files" + description: "The types of files your plugin harvests (if it is a harvest plugin)" + placeholder: "foobar, foobar.yml, foobar.json" + - id: "repository-url" type: "input" attributes: diff --git a/docs/source/_ext/plugin_markup.py b/docs/source/_ext/plugin_markup.py index 74df5020..51978f5b 100644 --- a/docs/source/_ext/plugin_markup.py +++ b/docs/source/_ext/plugin_markup.py @@ -3,6 +3,7 @@ # SPDX-FileContributor: David Pape import json +import re from pathlib import Path from typing import Any, Dict @@ -30,6 +31,19 @@ def log_message(text: str, text2: str = None) -> None: logger.info(message) +def keywordify(text: str) -> str: + """Make keyword-friendly text. + + The result will only contain lowercase a through z and hyphens, e.g.: + + * CITATION.cff → citation-cff + * codemeta.json → codemeta-json + * LICENSE → license + """ + text = text.casefold() + return re.sub(r"[^a-z]", "-", text) + + def plugin_to_schema_org(plugin: Dict[str, Any]) -> SchemaOrgSoftwarePublication: """Convert plugin metadata from the used JSON format to Schema.org. @@ -43,6 +57,11 @@ def plugin_to_schema_org(plugin: Dict[str, Any]) -> SchemaOrgSoftwarePublication """ keywords = [f"hermes-step-{step}" for step in plugin.get("steps", [])] + if "harvest" in plugin.get("steps", []) and ( + harvested_files := plugin.get("harvested_files", []) + ): + keywords += [f"hermes-harvest-{keywordify(file)}" for file in harvested_files] + return SchemaOrgSoftwarePublication( name=plugin.get("name"), url=plugin.get("repository_url"), diff --git a/docs/source/plugins-schema.json b/docs/source/plugins-schema.json index 7c6d2fff..a1eaec58 100644 --- a/docs/source/plugins-schema.json +++ b/docs/source/plugins-schema.json @@ -6,6 +6,7 @@ "minItems": 1, "items": { "type": "object", + "additionalProperties": false, "properties": { "name": { "type": "string", @@ -34,6 +35,14 @@ ] } }, + "harvested_files": { + "type": "array", + "description": "Names of files harvested by a harvest plugin", + "items": { + "type": "string", + "uniqueItems": true + } + }, "repository_url": { "type": "string", "description": "Link to the repository where users can find and inspect the source code of the plugin", diff --git a/docs/source/plugins.json b/docs/source/plugins.json index 94d484d3..16cec4ad 100644 --- a/docs/source/plugins.json +++ b/docs/source/plugins.json @@ -4,6 +4,7 @@ "description": "Harvest plugin for CITATION.cff files.", "author": "Hermes team", "steps": ["harvest"], + "harvested_files": ["CITATION.cff"], "builtin": true }, { @@ -11,6 +12,7 @@ "description": "Harvest plugin for codemeta.json files.", "author": "Hermes team", "steps": ["harvest"], + "harvested_files": ["codemeta.json"], "builtin": true }, { @@ -25,6 +27,7 @@ "description": "Harvest plugin for .toml files.", "author": "Hermes team", "steps": ["harvest"], + "harvested_files": ["pyproject.toml"], "repository_url": "https://github.com/softwarepub/hermes-plugin-python", "pypi_url": "https://pypi.org/project/hermes-plugin-python/" }, From c4de01c43400db7ce597b8f139817987b1ad5648 Mon Sep 17 00:00:00 2001 From: David Pape Date: Wed, 18 Dec 2024 15:17:37 +0100 Subject: [PATCH 29/40] Code readability --- docs/source/_ext/plugin_markup.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/source/_ext/plugin_markup.py b/docs/source/_ext/plugin_markup.py index 51978f5b..ec7d2c5e 100644 --- a/docs/source/_ext/plugin_markup.py +++ b/docs/source/_ext/plugin_markup.py @@ -55,11 +55,10 @@ def plugin_to_schema_org(plugin: Dict[str, Any]) -> SchemaOrgSoftwarePublication name of the workflow step. If the plugin is marked as a Hermes ``builtin``, this is expressed using ``schema:isPartOf``. """ - keywords = [f"hermes-step-{step}" for step in plugin.get("steps", [])] - - if "harvest" in plugin.get("steps", []) and ( - harvested_files := plugin.get("harvested_files", []) - ): + steps = plugin.get("steps", []) + keywords = [f"hermes-step-{step}" for step in steps] + if "harvest" in steps: + harvested_files = plugin.get("harvested_files", []) keywords += [f"hermes-harvest-{keywordify(file)}" for file in harvested_files] return SchemaOrgSoftwarePublication( From d5d89e2195b97269a025dfb05e562100293fc4a6 Mon Sep 17 00:00:00 2001 From: David Pape Date: Thu, 19 Dec 2024 13:42:58 +0100 Subject: [PATCH 30/40] Method `model_dump_jsonld` --- docs/source/_ext/plugin_markup.py | 4 +--- src/hermes/commands/marketplace.py | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/source/_ext/plugin_markup.py b/docs/source/_ext/plugin_markup.py index ec7d2c5e..2df8f255 100644 --- a/docs/source/_ext/plugin_markup.py +++ b/docs/source/_ext/plugin_markup.py @@ -109,9 +109,7 @@ def run(self) -> list[nodes.Node]: log_message("converting plugins to markup") tags = [] for plugin in plugin_data: - markup = plugin_to_schema_org(plugin).model_dump_json( - by_alias=True, exclude_none=True - ) + markup = plugin_to_schema_org(plugin).model_dump_jsonld() tag = f'' tags.append(nodes.raw(text=tag, format="html")) diff --git a/src/hermes/commands/marketplace.py b/src/hermes/commands/marketplace.py index 778365ec..ab31012e 100644 --- a/src/hermes/commands/marketplace.py +++ b/src/hermes/commands/marketplace.py @@ -29,6 +29,9 @@ class SchemaOrgModel(BaseModel): type_: str = Field(alias="@type") id_: Optional[str] = Field(alias="@id", default=None) + def model_dump_jsonld(self): + return self.model_dump_json(by_alias=True, exclude_none=True) + class SchemaOrgOrganization(SchemaOrgModel): """Validation and serialization of ``schema:Organization``. From d953c3fc34aa48b09bb774a7e1e969d7039eb71f Mon Sep 17 00:00:00 2001 From: David Pape Date: Thu, 19 Dec 2024 14:25:01 +0100 Subject: [PATCH 31/40] Don't introduce pathlib --- docs/source/conf.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index e47ed647..bd97c694 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -22,9 +22,8 @@ # import os import sys -from pathlib import Path sys.path.insert(0, os.path.abspath('../../src')) -sys.path.append(str(Path('_ext').resolve())) +sys.path.append(os.path.abspath('_ext')) # -- Project information ----------------------------------------------------- From f1f490945acadb18478036e50d5e7d69524cdbde Mon Sep 17 00:00:00 2001 From: David Pape Date: Thu, 19 Dec 2024 14:35:36 +0100 Subject: [PATCH 32/40] =?UTF-8?q?Argument=20`text2`=20=E2=86=92=20`detail`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/source/_ext/plugin_markup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/_ext/plugin_markup.py b/docs/source/_ext/plugin_markup.py index 2df8f255..13c87452 100644 --- a/docs/source/_ext/plugin_markup.py +++ b/docs/source/_ext/plugin_markup.py @@ -24,10 +24,10 @@ logger = logging.getLogger(__name__) -def log_message(text: str, text2: str = None) -> None: +def log_message(text: str, detail: str = None) -> None: message = colorize("bold", "[Plugin Markup]") + " " + text - if text2 is not None: - message += " " + colorize("darkgreen", text2) + if detail is not None: + message += " " + colorize("darkgreen", detail) logger.info(message) @@ -94,12 +94,12 @@ def run(self) -> list[nodes.Node]: directory = filename.parent plugins_file = directory / self.arguments[0] - log_message("reading plugins file", text2=str(plugins_file)) + log_message("reading plugins file", detail=str(plugins_file)) with open(plugins_file) as file: plugin_data = json.load(file) plugins_schema_file = directory / self.arguments[1] - log_message("reading plugins schema file", text2=str(plugins_schema_file)) + log_message("reading plugins schema file", detail=str(plugins_schema_file)) with open(plugins_schema_file) as file: plugin_schema = json.load(file) From 679ec34d32b86dbddab033ef2dbea5846da08af4 Mon Sep 17 00:00:00 2001 From: David Pape Date: Thu, 19 Dec 2024 14:45:14 +0100 Subject: [PATCH 33/40] Display URL constant for marketplace --- src/hermes/commands/marketplace.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hermes/commands/marketplace.py b/src/hermes/commands/marketplace.py index ab31012e..5f3d9080 100644 --- a/src/hermes/commands/marketplace.py +++ b/src/hermes/commands/marketplace.py @@ -14,6 +14,7 @@ from hermes.utils import hermes_doi, hermes_user_agent MARKETPLACE_URL = "https://hermes.software-metadata.pub" +MARKETPLACE_URL_DISPLAY = f"{MARKETPLACE_URL}#plugins" class SchemaOrgModel(BaseModel): @@ -96,7 +97,7 @@ def main(): print( "A detailed list of available plugins can be found on the " - f"Hermes website at {MARKETPLACE_URL}#plugins" + f"Hermes website at {MARKETPLACE_URL_DISPLAY}" ) if parser.plugins: From 27bfe157ffbdb91c014d99874dbbc86ce55b3090 Mon Sep 17 00:00:00 2001 From: David Pape Date: Thu, 19 Dec 2024 14:57:54 +0100 Subject: [PATCH 34/40] Update docstring --- docs/source/_ext/plugin_markup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/_ext/plugin_markup.py b/docs/source/_ext/plugin_markup.py index 13c87452..6cb73f4c 100644 --- a/docs/source/_ext/plugin_markup.py +++ b/docs/source/_ext/plugin_markup.py @@ -52,8 +52,10 @@ def plugin_to_schema_org(plugin: Dict[str, Any]) -> SchemaOrgSoftwarePublication is expressed as a ``schema:Organization`` using the given author field as the ``name``. The steps targeted by the plugin are expressed using the ``keyword`` field by transforming them to the keywords ``hermes-step-`` where ```` is the - name of the workflow step. If the plugin is marked as a Hermes ``builtin``, this is - expressed using ``schema:isPartOf``. + name of the workflow step. The ``harvested_files`` are also transformed into + keywords by making the text "keyword-friendly" and prepending ``hermes-harvest-``. + If the plugin is marked as a Hermes ``builtin``, this is expressed using + ``schema:isPartOf``. """ steps = plugin.get("steps", []) keywords = [f"hermes-step-{step}" for step in steps] From bd047f30d695a4e8c482f409d14a4f672ce06257 Mon Sep 17 00:00:00 2001 From: David Pape Date: Thu, 19 Dec 2024 15:10:28 +0100 Subject: [PATCH 35/40] =?UTF-8?q?`SchemaOrgSoftware{Publication=20?= =?UTF-8?q?=E2=86=92=20Application}`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parapraxis :-) --- docs/source/_ext/plugin_markup.py | 6 +++--- src/hermes/commands/marketplace.py | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/source/_ext/plugin_markup.py b/docs/source/_ext/plugin_markup.py index 6cb73f4c..d8c1d635 100644 --- a/docs/source/_ext/plugin_markup.py +++ b/docs/source/_ext/plugin_markup.py @@ -16,7 +16,7 @@ from hermes.commands.marketplace import ( SchemaOrgOrganization, - SchemaOrgSoftwarePublication, + SchemaOrgSoftwareApplication, schema_org_hermes, ) @@ -44,7 +44,7 @@ def keywordify(text: str) -> str: return re.sub(r"[^a-z]", "-", text) -def plugin_to_schema_org(plugin: Dict[str, Any]) -> SchemaOrgSoftwarePublication: +def plugin_to_schema_org(plugin: Dict[str, Any]) -> SchemaOrgSoftwareApplication: """Convert plugin metadata from the used JSON format to Schema.org. The ``plugin`` is transformed into a ``schema:SoftwareApplication``. For most @@ -63,7 +63,7 @@ def plugin_to_schema_org(plugin: Dict[str, Any]) -> SchemaOrgSoftwarePublication harvested_files = plugin.get("harvested_files", []) keywords += [f"hermes-harvest-{keywordify(file)}" for file in harvested_files] - return SchemaOrgSoftwarePublication( + return SchemaOrgSoftwareApplication( name=plugin.get("name"), url=plugin.get("repository_url"), install_url=plugin.get("pypi_url"), diff --git a/src/hermes/commands/marketplace.py b/src/hermes/commands/marketplace.py index 5f3d9080..52648bb1 100644 --- a/src/hermes/commands/marketplace.py +++ b/src/hermes/commands/marketplace.py @@ -46,8 +46,8 @@ class SchemaOrgOrganization(SchemaOrgModel): name: str -class SchemaOrgSoftwarePublication(SchemaOrgModel): - """Validation and serialization of ``schema:SoftwarePublication``. +class SchemaOrgSoftwareApplication(SchemaOrgModel): + """Validation and serialization of ``schema:SoftwareApplication``. This model does not incorporate all possible fields and is meant to be used merely for the purposes of the Hermes marketplace. @@ -60,11 +60,11 @@ class SchemaOrgSoftwarePublication(SchemaOrgModel): install_url: Optional[str] = None abstract: Optional[str] = None author: Optional[SchemaOrgOrganization] = None - is_part_of: Optional["SchemaOrgSoftwarePublication"] = None + is_part_of: Optional["SchemaOrgSoftwareApplication"] = None keywords: List["str"] = None -schema_org_hermes = SchemaOrgSoftwarePublication(id_=hermes_doi, name="hermes") +schema_org_hermes = SchemaOrgSoftwareApplication(id_=hermes_doi, name="hermes") class PluginMarketPlaceParser(HTMLParser): @@ -73,7 +73,7 @@ class PluginMarketPlaceParser(HTMLParser): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.is_json_ld: bool = False - self.plugins: List[SchemaOrgSoftwarePublication] = [] + self.plugins: List[SchemaOrgSoftwareApplication] = [] def handle_starttag(self, tag, attrs): if tag == "script" and ("type", "application/ld+json") in attrs: @@ -84,7 +84,7 @@ def handle_endtag(self, tag): def handle_data(self, data): if self.is_json_ld: - plugin = SchemaOrgSoftwarePublication.model_validate_json(data) + plugin = SchemaOrgSoftwareApplication.model_validate_json(data) self.plugins.append(plugin) From 2b1b0820297abb99038404e33ce38b1f3ebd570f Mon Sep 17 00:00:00 2001 From: David Pape Date: Thu, 19 Dec 2024 15:56:13 +0100 Subject: [PATCH 36/40] Fix `code-block` directiry --- docs/source/_ext/plugin_markup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/_ext/plugin_markup.py b/docs/source/_ext/plugin_markup.py index d8c1d635..94619ffe 100644 --- a/docs/source/_ext/plugin_markup.py +++ b/docs/source/_ext/plugin_markup.py @@ -80,7 +80,7 @@ class PluginMarkupDirective(SphinxDirective): The plugins file and its jsonschema are passed to the directive as parameters, i.e., in Markdown: - .. code:: markdown + .. code-block:: markdown ```{plugin-markup} path/to/plugins.json path/to/plugins-schema.json ``` From 133f6e5dbad7484b407bab76a6ef893841a95692 Mon Sep 17 00:00:00 2001 From: David Pape Date: Tue, 14 Jan 2025 09:38:50 +0100 Subject: [PATCH 37/40] Use `/marketplace` URL --- src/hermes/commands/marketplace.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hermes/commands/marketplace.py b/src/hermes/commands/marketplace.py index 52648bb1..00d36295 100644 --- a/src/hermes/commands/marketplace.py +++ b/src/hermes/commands/marketplace.py @@ -13,8 +13,7 @@ from hermes.utils import hermes_doi, hermes_user_agent -MARKETPLACE_URL = "https://hermes.software-metadata.pub" -MARKETPLACE_URL_DISPLAY = f"{MARKETPLACE_URL}#plugins" +MARKETPLACE_URL = "https://hermes.software-metadata.pub/marketplace" class SchemaOrgModel(BaseModel): @@ -96,8 +95,8 @@ def main(): parser.feed(response.text) print( - "A detailed list of available plugins can be found on the " - f"Hermes website at {MARKETPLACE_URL_DISPLAY}" + "A detailed list of available plugins can be found on the Hermes website at", + MARKETPLACE_URL, ) if parser.plugins: From c93739a0e0f85603f165b72fd147fd80c106b7d4 Mon Sep 17 00:00:00 2001 From: Stephan Druskat Date: Tue, 14 Jan 2025 11:10:15 +0100 Subject: [PATCH 38/40] Improve output of hermes-marketplace command - Prints a table with the plugins sorted by hermes step - Plugins that target >1 step are listed under each step --- src/hermes/commands/marketplace.py | 40 +++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/hermes/commands/marketplace.py b/src/hermes/commands/marketplace.py index 00d36295..02ba0cc7 100644 --- a/src/hermes/commands/marketplace.py +++ b/src/hermes/commands/marketplace.py @@ -1,9 +1,9 @@ -# SPDX-FileCopyrightText: 2024 Helmholtz-Zentrum Dresden-Rossendorf +# SPDX-FileCopyrightText: 2024 Helmholtz-Zentrum Dresden-Rossendorf, German Aerospace Center (DLR) # SPDX-License-Identifier: Apache-2.0 # SPDX-FileContributor: David Pape +# SPDX-FileContributor: Stephan Druskat """Basic CLI to list plugins from the Hermes marketplace.""" - from html.parser import HTMLParser from typing import List, Optional @@ -87,6 +87,16 @@ def handle_data(self, data): self.plugins.append(plugin) +def _sort_plugins_by_step(plugins: list[SchemaOrgSoftwareApplication]) -> dict[str, list[SchemaOrgSoftwareApplication]]: + sorted_plugins = {k:[] for k in ["harvest", "process", "curate", "deposit", "postprocess"]} + for p in plugins: + for kw in p.keywords: + if kw.startswith("hermes-step-"): + sorted_plugins[kw.removeprefix("hermes-step-")].append(p) + return sorted_plugins + + + def main(): response = requests.get(MARKETPLACE_URL, headers={"User-Agent": hermes_user_agent}) response.raise_for_status() @@ -95,20 +105,26 @@ def main(): parser.feed(response.text) print( - "A detailed list of available plugins can be found on the Hermes website at", - MARKETPLACE_URL, + "A detailed list of available plugins can be found on the HERMES website at", + MARKETPLACE_URL + "." ) + def _plugin_loc(_plugin: SchemaOrgSoftwareApplication) -> str: + return "builtin" if _plugin.is_part_of == schema_org_hermes else (_plugin.url or "") + if parser.plugins: print() - alignment = max(map(lambda plugin: len(plugin.name), parser.plugins)) + 1 - for plugin in parser.plugins: - where = ( - "builtin" - if plugin.is_part_of == schema_org_hermes - else (plugin.url or "") - ) - print(f"{plugin.name:>{alignment}} {where}") + max_name_len = max(map(lambda plugin: len(plugin.name), parser.plugins)) + max_loc_len = max(map(lambda plugin: len(_plugin_loc(plugin)), parser.plugins)) + row_sep = "-" * (17 + max_name_len + max_loc_len) + print("HERMES step " + "Plugin name" + (" " * (max_name_len -8)) + "Plugin location") + print(row_sep) + name_alignment = max(map(lambda plugin: len(plugin.name), parser.plugins))# + 1 + plugins_sorted = _sort_plugins_by_step(parser.plugins) + for step in plugins_sorted.keys(): + for plugin in plugins_sorted[step]: + print(f"{step:>11} {plugin.name:{name_alignment}} {_plugin_loc(plugin)}") + print(row_sep) print() From b0c9a89aa6568bbecfbc0a78f10108e1421e7bfe Mon Sep 17 00:00:00 2001 From: Stephan Druskat Date: Tue, 14 Jan 2025 11:15:47 +0100 Subject: [PATCH 39/40] Satisfy linter --- src/hermes/commands/marketplace.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hermes/commands/marketplace.py b/src/hermes/commands/marketplace.py index 02ba0cc7..283e9263 100644 --- a/src/hermes/commands/marketplace.py +++ b/src/hermes/commands/marketplace.py @@ -88,7 +88,7 @@ def handle_data(self, data): def _sort_plugins_by_step(plugins: list[SchemaOrgSoftwareApplication]) -> dict[str, list[SchemaOrgSoftwareApplication]]: - sorted_plugins = {k:[] for k in ["harvest", "process", "curate", "deposit", "postprocess"]} + sorted_plugins = {k: [] for k in ["harvest", "process", "curate", "deposit", "postprocess"]} for p in plugins: for kw in p.keywords: if kw.startswith("hermes-step-"): @@ -96,7 +96,6 @@ def _sort_plugins_by_step(plugins: list[SchemaOrgSoftwareApplication]) -> dict[s return sorted_plugins - def main(): response = requests.get(MARKETPLACE_URL, headers={"User-Agent": hermes_user_agent}) response.raise_for_status() @@ -117,9 +116,9 @@ def _plugin_loc(_plugin: SchemaOrgSoftwareApplication) -> str: max_name_len = max(map(lambda plugin: len(plugin.name), parser.plugins)) max_loc_len = max(map(lambda plugin: len(_plugin_loc(plugin)), parser.plugins)) row_sep = "-" * (17 + max_name_len + max_loc_len) - print("HERMES step " + "Plugin name" + (" " * (max_name_len -8)) + "Plugin location") + print("HERMES step " + "Plugin name" + (" " * (max_name_len - 8)) + "Plugin location") print(row_sep) - name_alignment = max(map(lambda plugin: len(plugin.name), parser.plugins))# + 1 + name_alignment = max(map(lambda plugin: len(plugin.name), parser.plugins)) plugins_sorted = _sort_plugins_by_step(parser.plugins) for step in plugins_sorted.keys(): for plugin in plugins_sorted[step]: From 1fd0dc771cd02ab376ea341b4fcff1b382dc2073 Mon Sep 17 00:00:00 2001 From: David Pape Date: Tue, 14 Jan 2025 11:31:48 +0100 Subject: [PATCH 40/40] Remove duplicated variable --- src/hermes/commands/marketplace.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hermes/commands/marketplace.py b/src/hermes/commands/marketplace.py index 283e9263..842955dc 100644 --- a/src/hermes/commands/marketplace.py +++ b/src/hermes/commands/marketplace.py @@ -118,11 +118,10 @@ def _plugin_loc(_plugin: SchemaOrgSoftwareApplication) -> str: row_sep = "-" * (17 + max_name_len + max_loc_len) print("HERMES step " + "Plugin name" + (" " * (max_name_len - 8)) + "Plugin location") print(row_sep) - name_alignment = max(map(lambda plugin: len(plugin.name), parser.plugins)) plugins_sorted = _sort_plugins_by_step(parser.plugins) for step in plugins_sorted.keys(): for plugin in plugins_sorted[step]: - print(f"{step:>11} {plugin.name:{name_alignment}} {_plugin_loc(plugin)}") + print(f"{step:>11} {plugin.name:{max_name_len}} {_plugin_loc(plugin)}") print(row_sep) print()