Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin object not active by default #433

Merged
merged 8 commits into from
Sep 1, 2023
16 changes: 8 additions & 8 deletions core/cat/mad_hatter/mad_hatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def install_plugin(self, package_plugin):
raise Exception("A plugin should contain a folder, found a file")

# create plugin obj
self.load_plugin(plugin_path, active=False)
self.load_plugin(plugin_path)

# activate it
self.toggle_plugin(plugin_id)
Expand Down Expand Up @@ -95,21 +95,21 @@ def find_plugins(self):

# discover plugins, folder by folder
for folder in all_plugin_folders:
self.load_plugin(folder)

# is the plugin active?
folder_base = os.path.basename(os.path.normpath(folder))
is_active = folder_base in self.active_plugins

self.load_plugin(folder, is_active)
plugin_id = os.path.basename(os.path.normpath(folder))

if plugin_id in self.active_plugins:
self.plugins[plugin_id].activate()

self.sync_hooks_and_tools()

def load_plugin(self, plugin_path, active):
def load_plugin(self, plugin_path):
# Instantiate plugin.
# If the plugin is inactive, only manifest will be loaded
# If active, also settings, tools and hooks
try:
plugin = Plugin(plugin_path, active=active)
plugin = Plugin(plugin_path)
# if plugin is valid, keep a reference
self.plugins[plugin.id] = plugin
except Exception as e:
Expand Down
19 changes: 8 additions & 11 deletions core/cat/mad_hatter/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

class Plugin:

def __init__(self, plugin_path: str, active: bool):
def __init__(self, plugin_path: str):

# does folder exist?
if not os.path.exists(plugin_path) or not os.path.isdir(plugin_path):
Expand All @@ -45,29 +45,26 @@ def __init__(self, plugin_path: str, active: bool):
# but they are created and stored in each plugin instance
self._hooks = []
self._tools = []

self._active = False
Pingdred marked this conversation as resolved.
Show resolved Hide resolved

# all plugins start active, they can be deactivated/reactivated from endpoint
if active:
self.activate()

def activate(self):
# lists of hooks and tools
self._hooks, self._tools = self._load_hooks_and_tools()
self._active = True

def deactivate(self):
self._active = False

# Remove the imported modules
for py_file in self.py_files:
py_filename = py_file.replace("/", ".").replace(".py", "") # this is UGLY I know. I'm sorry
log(f"Remove module {py_filename}", "DEBUG")
sys.modules.pop(py_filename)
py_filename = py_file.replace("/", ".").replace(".py", "")

# If the module is imported it is removed
if py_filename in sys.modules:
log(f"Remove module {py_filename}", "DEBUG")
sys.modules.pop(py_filename)

self._hooks = []
self._tools = []
self._active = False

# get plugin settings JSON schema
def get_settings_schema(self):
Expand Down
44 changes: 10 additions & 34 deletions core/tests/mad_hatter/test_plugin.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import os
import shutil
import pytest
from inspect import isfunction

from cat.mad_hatter.mad_hatter import Plugin
from cat.mad_hatter.decorators import CatHook, CatTool


mock_plugin_path = "tests/mocks/mock_plugin/"

# this fixture will give test functions a ready instantiated plugin
@pytest.fixture
def plugin():

p = Plugin(mock_plugin_path, active=True)
p = Plugin(mock_plugin_path)

yield p

Expand All @@ -25,7 +23,7 @@ def plugin():
def test_create_plugin_wrong_folder():

with pytest.raises(Exception) as e:
Plugin("/non/existent/folder", active=True)
Plugin("/non/existent/folder")

assert f"Cannot create" in str(e.value)

Expand All @@ -36,14 +34,12 @@ def test_create_plugin_empty_folder():
os.mkdir(path)

with pytest.raises(Exception) as e:
Plugin(path, active=True)
Plugin(path)

assert f"Cannot create" in str(e.value)


def test_create_non_active_plugin():

plugin = Plugin(mock_plugin_path, active=False)
def test_create_plugin(plugin):

assert plugin.active == False

Expand All @@ -60,19 +56,12 @@ def test_create_non_active_plugin():
assert plugin.hooks == []
assert plugin.tools == []

def test_activate_plugin(plugin):

# activate it
plugin.activate()

def test_create_active_plugin(plugin):
Pingdred marked this conversation as resolved.
Show resolved Hide resolved

assert plugin.active == True

assert plugin.path == mock_plugin_path
assert plugin.id == "mock_plugin"

# manifest
assert type(plugin.manifest) == dict
assert plugin.manifest["id"] == plugin.id
assert plugin.manifest["name"] == "MockPlugin"
assert "Description not found" in plugin.manifest["description"]

# hooks
assert len(plugin.hooks) == 1
Expand All @@ -93,24 +82,11 @@ def test_create_active_plugin(plugin):
assert isfunction(tool.func)
assert tool.return_direct == True

def test_deactivate_plugin(plugin):

def test_activate_plugin():

# create non-active plugin
plugin = Plugin(mock_plugin_path, active=False)

# activate it
# The plugin is non active by default
plugin.activate()

assert plugin.active == True

# hooks and tools
assert len(plugin.hooks) == 1
assert len(plugin.tools) == 1


def test_deactivate_plugin(plugin):

# deactivate it
plugin.deactivate()

Expand Down
Loading