🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
88 lines
3.1 KiB
Python
88 lines
3.1 KiB
Python
"""Hello World example plugin for Dangerous Pi.
|
|
|
|
This plugin demonstrates the plugin framework capabilities including:
|
|
- Lifecycle methods (on_load, on_enable, on_disable, on_unload)
|
|
- Hook registration
|
|
- Header widget display
|
|
"""
|
|
import sys
|
|
|
|
# Import PluginBase from the already-loaded module to ensure class identity matches
|
|
# This is necessary because the plugin manager uses issubclass() check
|
|
# Try both module name variants (depends on how the app is started)
|
|
_plugin_manager_module = (
|
|
sys.modules.get('app.backend.managers.plugin_manager') or
|
|
sys.modules.get('backend.managers.plugin_manager')
|
|
)
|
|
if _plugin_manager_module:
|
|
PluginBase = _plugin_manager_module.PluginBase
|
|
PluginMetadata = _plugin_manager_module.PluginMetadata
|
|
WidgetSeverity = _plugin_manager_module.WidgetSeverity
|
|
else:
|
|
# Fallback for standalone testing
|
|
from pathlib import Path
|
|
app_path = Path(__file__).parent.parent.parent
|
|
if str(app_path) not in sys.path:
|
|
sys.path.insert(0, str(app_path))
|
|
from backend.managers.plugin_manager import PluginBase, PluginMetadata, WidgetSeverity
|
|
|
|
|
|
class HelloWorldPlugin(PluginBase):
|
|
"""Example plugin that demonstrates the plugin framework."""
|
|
|
|
def __init__(self):
|
|
"""Initialize the Hello World plugin."""
|
|
super().__init__()
|
|
self.counter = 0
|
|
|
|
async def on_load(self):
|
|
"""Called when the plugin is loaded."""
|
|
print("Hello World Plugin: Loaded!")
|
|
|
|
async def on_enable(self):
|
|
"""Called when the plugin is enabled."""
|
|
print("Hello World Plugin: Enabled!")
|
|
|
|
# Register a header widget to show plugin is active
|
|
self.register_widget(
|
|
widget_id="status",
|
|
severity=WidgetSeverity.SUCCESS,
|
|
message="Hello World plugin active",
|
|
icon="👋",
|
|
dismissible=True,
|
|
action_label="Settings",
|
|
action_url="/settings"
|
|
)
|
|
|
|
# Register a hook for PM3 commands
|
|
async def pm3_command_hook(command: str):
|
|
"""Hook that logs PM3 commands."""
|
|
self.counter += 1
|
|
print(f"Hello World Plugin: PM3 command #{self.counter}: {command}")
|
|
return {"plugin": "hello_world", "command_count": self.counter}
|
|
|
|
self.register_hook("pm3_command", pm3_command_hook)
|
|
|
|
# Register a hook for update checks
|
|
async def update_check_hook():
|
|
"""Hook that runs on update checks."""
|
|
print("Hello World Plugin: Update check performed")
|
|
return {"plugin": "hello_world", "message": "Hello from plugin!"}
|
|
|
|
self.register_hook("update_check", update_check_hook)
|
|
|
|
async def on_disable(self):
|
|
"""Called when the plugin is disabled."""
|
|
print(f"Hello World Plugin: Disabled! (processed {self.counter} commands)")
|
|
|
|
# Remove the header widget
|
|
self.unregister_widget("status")
|
|
|
|
async def on_unload(self):
|
|
"""Called when the plugin is unloaded."""
|
|
print("Hello World Plugin: Unloaded! Goodbye!")
|
|
|
|
def get_metadata(self) -> PluginMetadata:
|
|
"""Get plugin metadata."""
|
|
return self.metadata
|