Files
Medios-Macina/plugins
2026-05-24 12:32:57 -07:00
..
2026-05-23 14:20:12 -07:00
2026-05-23 13:49:47 -07:00
2026-05-24 12:32:57 -07:00
2026-05-21 16:19:17 -07:00
2026-05-24 12:32:57 -07:00
2026-05-23 13:49:47 -07:00
2026-05-24 12:32:57 -07:00
2026-05-21 16:19:17 -07:00
2026-05-23 13:49:47 -07:00
2026-04-26 16:49:23 -07:00
2026-05-23 13:49:47 -07:00

Plugins

This folder is the primary home for bundled plugins and also the default search path for drop-in plugins.

User-facing docs and CLI flows treat these integrations as plugins. Some Python types and some stored config keys still use older Provider naming internally, but that is a legacy implementation detail rather than the preferred public term.

Preferred layout:

  • Put each plugin in its own folder under plugins/<name>/ with an __init__.py.
  • Keep plugin-specific assets beside the code in that same folder.
  • Single-file .py plugins are still supported, but package folders are the recommended plug-and-play format.

That means a plugin can ship as a drag-and-drop folder with extras such as:

  • cookies.txt
  • templates or fixture files
  • helper modules
  • small static assets

Built-in bundled plugins use the same layout as external plugins. Additional drop-in plugin search paths are:

  • plugins/ in the repo root
  • plugins/ in the current working directory
  • Any directory listed in MM_PLUGIN_PATH
  • Any directory listed in MEDEIA_PLUGIN_PATH

Plugin rules:

  • A plugin can be a single .py file or a package directory with __init__.py.
  • Current plugin classes inherit from PluginCore.base.Provider.
  • Give the plugin a stable name using PLUGIN_NAME or the class name.

Example skeleton:

from PluginCore.base import Provider, SearchResult


class MyPlugin(Provider):
    PLUGIN_NAME = "myplugin"
    URL_DOMAINS = ("example.com",)

    def search(self, query, limit=50, filters=None, **kwargs):
        text = str(query or "").strip()
        if not text:
            return []
        return [
            SearchResult(
                table="myplugin",
                title=f"Result for {text}",
                path=f"https://example.com/{text}",
            )
        ]

Bundled walkthrough:

  • Plugins can expose named config instances. The current stored config may still use legacy key paths such as provider.<plugin>.<instance>, and cmdlets target instances with -instance <name>.
  • Use .config plugins in the CLI to browse configured plugin instances.
  • The repo now includes a real FTP example plugin in plugins/ftp/__init__.py.
  • The walkthrough is in docs/ftp_plugin_tutorial.md and shows search-file -plugin ftp -instance <name>, folder drill-in via @N, file download routing, @N | add-file -instance ..., and add-file -plugin ftp -instance <name> uploads.
  • The repo also includes an SCP example plugin in plugins/scp/__init__.py.
  • The walkthrough is in docs/scp_plugin_tutorial.md and shows search-file -plugin scp -instance <name>, SSH-backed directory drill-in, file download routing, @N | add-file -instance ..., and add-file -plugin scp -instance <name> uploads.
  • The repo also includes a built-in HydrusNetwork plugin in plugins/hydrusnetwork/__init__.py. Its Hydrus client API now lives in the plugin-owned package plugins/hydrusnetwork/api/__init__.py, its configured-backend adapter lives in plugins/hydrusnetwork/store_proxy.py, and its heavy internal operations live in plugins/hydrusnetwork/store_backend.py. This plugins/<name>/api/ package shape is the intended pattern for plugin-owned API helpers going forward. The plugin resolves configured Hydrus instances directly from plugin config instead of routing back through PluginCore.backend_registry; the proxy exists only so generic backend callers can still target configured Hydrus instances.