42
42
from navigate .config .config import get_navigate_path
43
43
from navigate .view .custom_widgets .popup import PopUp
44
44
from navigate .tools .file_functions import load_yaml_file , save_yaml_file
45
- from navigate .tools .common_functions import combine_funcs , load_module_from_file
45
+ from navigate .tools .common_functions import combine_funcs
46
46
from navigate .tools .decorators import AcquisitionMode
47
- from navigate .model .features import feature_related_functions
48
47
from navigate .controller .sub_controllers .gui import GUIController
49
48
from navigate .view .popups .plugins_popup import PluginsPopup
50
- from navigate .config import set_feature_attributes
49
+
50
+ from navigate .plugins .plugin_manager import PluginFileManager , PluginPackageManager
51
51
52
52
53
53
class PluginsController :
@@ -69,11 +69,6 @@ def __init__(self, view, parent_controller):
69
69
#: object: navigate controller.
70
70
self .parent_controller = parent_controller
71
71
72
- #: str: plugins default path.
73
- self .plugins_path = os .path .join (
74
- Path (__file__ ).resolve ().parent .parent .parent , "plugins"
75
- )
76
-
77
72
#: dict: installed plugins with GUI
78
73
self .plugins_dict = {}
79
74
@@ -87,115 +82,61 @@ def populate_experiment_setting(self):
87
82
88
83
def load_plugins (self ):
89
84
"""Load plugins"""
90
- plugins = os . listdir ( self . plugins_path )
91
- installed_plugins = dict (
92
- [( f , os . path . join ( self . plugins_path , f )) for f in plugins ]
85
+ # load through files
86
+ plugins_path = os . path . join (
87
+ Path ( __file__ ). resolve (). parent . parent . parent , " plugins"
93
88
)
94
- # load plugins from plugins_config
95
89
plugins_config_path = os .path .join (
96
90
get_navigate_path (), "config" , "plugins_config.yml"
97
91
)
98
- plugins_config = load_yaml_file (plugins_config_path )
99
- if plugins_config is None :
100
- plugins_config = {}
101
- save_yaml_file (get_navigate_path (), {}, "plugins_config.yml" )
102
- else :
103
- for plugin_name , plugin_path in plugins_config .items ():
104
- if plugin_path and os .path .exists (plugin_path ):
105
- installed_plugins [plugin_name ] = plugin_path
106
- for _ , plugin_path in installed_plugins .items ():
107
- if not os .path .isdir (plugin_path ):
108
- continue
92
+ plugin_file_manager = PluginFileManager (plugins_path , plugins_config_path )
93
+ self .load_plugins_through_manager (plugin_file_manager )
94
+ self .load_plugins_through_manager (PluginPackageManager )
95
+
96
+ def load_plugins_through_manager (self , plugin_manager ):
97
+ """Load plugins through plugin manager
98
+
99
+ Parameters
100
+ ----------
101
+ plugin_manager : object
102
+ PluginManager object
103
+ """
104
+ plugins = plugin_manager .get_plugins ()
105
+
106
+ for plugin_name , plugin_ref in plugins .items ():
109
107
110
108
# read "plugin_config.yml"
111
- plugin_config = load_yaml_file (
112
- os .path .join (plugin_path , "plugin_config.yml" )
113
- )
109
+ plugin_config = plugin_manager .load_config (plugin_ref )
114
110
if plugin_config is None :
115
111
continue
116
- plugin_name = plugin_config .get ("name" , _ )
117
- plugin_file_name = "_" .join (plugin_name .lower ().split ())
118
- plugin_class_name = "" .join (plugin_name .title ().split ())
119
- if "view" in plugin_config :
120
- # verify if "frame_name" and "file_name" are given and correct
121
- view_file = os .path .join (
122
- plugin_path , "view" , f"{ plugin_file_name } _frame.py"
123
- )
124
- controller_file = os .path .join (
125
- plugin_path ,
126
- "controller" ,
127
- f"{ plugin_file_name } _controller.py" ,
128
- )
129
- if (
130
- os .path .exists (view_file )
131
- and os .path .isfile (view_file )
132
- and os .path .exists (controller_file )
133
- and os .path .isfile (controller_file )
134
- ):
135
- plugin_frame_module = load_module_from_file (
136
- f"{ plugin_class_name } Frame" , view_file
137
- )
138
- if plugin_frame_module is None :
139
- print (
140
- f"Make sure that the plugin frame name "
141
- f"{ plugin_class_name } is correct! "
142
- f"Plugin { plugin_name } needs to be uninstalled from "
143
- f"navigate or reinstalled!"
144
- )
145
- continue
146
- plugin_frame = getattr (
147
- plugin_frame_module , f"{ plugin_class_name } Frame"
148
- )
149
- plugin_controller_module = load_module_from_file (
150
- f"{ plugin_class_name } Controller" , controller_file
151
- )
152
- if plugin_controller_module is None :
153
- print (
154
- f"Make sure that the plugin controller "
155
- f"{ plugin_class_name } is correct! "
156
- f"Plugin { plugin_name } needs to be uninstalled from "
157
- f"navigate or reinstalled!"
158
- )
159
- continue
160
- plugin_controller = getattr (
161
- plugin_controller_module , f"{ plugin_class_name } Controller"
162
- )
112
+ plugin_display_name = plugin_config .get ("name" , plugin_name )
113
+
114
+ plugin_frame = plugin_manager .load_view (plugin_ref , plugin_display_name )
115
+ plugin_controller = plugin_manager .load_controller (
116
+ plugin_ref , plugin_display_name
117
+ )
163
118
164
- if plugin_config ["view" ] == "Popup" :
165
- # menu
166
- self .parent_controller .view .menubar .menu_plugins .add_command (
167
- label = plugin_name ,
168
- command = self .build_popup_window (
169
- plugin_name , plugin_frame , plugin_controller
170
- ),
171
- )
172
- else :
173
- self .build_tab_window (
119
+ if plugin_frame and plugin_controller :
120
+ if plugin_config ["view" ] == "Popup" :
121
+ # menu
122
+ self .parent_controller .view .menubar .menu_plugins .add_command (
123
+ label = plugin_name ,
124
+ command = self .build_popup_window (
174
125
plugin_name , plugin_frame , plugin_controller
175
- )
126
+ ),
127
+ )
128
+ else :
129
+ self .build_tab_window (plugin_name , plugin_frame , plugin_controller )
176
130
# feature
177
- set_feature_attributes ( plugin_path )
131
+ plugin_manager . load_features ( plugin_ref )
178
132
179
133
# acquisition mode
180
134
acquisition_modes = plugin_config .get ("acquisition_modes" , [])
181
- for acquisition_mode_config in acquisition_modes :
182
- acquisition_file = os .path .join (
183
- plugin_path , acquisition_mode_config ["file_name" ]
184
- )
185
- if os .path .exists (acquisition_file ):
186
- module = load_module_from_file (
187
- acquisition_mode_config ["file_name" ][:- 3 ], acquisition_file
188
- )
189
- acquisition_mode = [
190
- m
191
- for m in dir (module )
192
- if isinstance (getattr (module , m ), AcquisitionMode )
193
- ]
194
- if acquisition_mode :
195
- self .parent_controller .add_acquisition_mode (
196
- acquisition_mode_config ["name" ],
197
- getattr (module , acquisition_mode [0 ]),
198
- )
135
+ plugin_manager .load_acquisition_modes (
136
+ plugin_ref ,
137
+ acquisition_modes ,
138
+ self .register_acquisition_mode ,
139
+ )
199
140
200
141
def build_tab_window (self , plugin_name , frame , controller ):
201
142
"""Build tab for a plugin
@@ -220,11 +161,12 @@ def build_tab_window(self, plugin_name, frame, controller):
220
161
"__plugin" + "_" .join (plugin_name .lower ().split ()) + "_controller"
221
162
)
222
163
self .plugins_dict [controller_name ] = plugin_controller
223
- except Exception :
164
+ except Exception as e :
224
165
messagebox .showwarning (
225
166
title = "Warning" ,
226
167
message = (
227
168
f"Plugin { plugin_name } has something went wrong."
169
+ f"Error: { e } "
228
170
f"Please make sure the plugin works correctly or uninstall it!"
229
171
),
230
172
)
@@ -295,6 +237,27 @@ def func_with_wrapper(*args, **kwargs):
295
237
296
238
return func_with_wrapper
297
239
240
+ def register_acquisition_mode (self , acquisition_mode_name , module ):
241
+ """Register acquisition mode
242
+
243
+ Parameters
244
+ ----------
245
+ acquisition_mode_name : str
246
+ The name of an acquisition mode
247
+ module : module
248
+ acquisition mode module
249
+ """
250
+ if not module :
251
+ return
252
+ acquisition_mode = [
253
+ m for m in dir (module ) if isinstance (getattr (module , m ), AcquisitionMode )
254
+ ]
255
+ if acquisition_mode :
256
+ self .parent_controller .add_acquisition_mode (
257
+ acquisition_mode_name ,
258
+ getattr (module , acquisition_mode [0 ]),
259
+ )
260
+
298
261
299
262
class UninstallPluginController (GUIController ):
300
263
"""Uninstall plugin controller"""
0 commit comments