|
@@ -0,0 +1,145 @@
|
|
1
|
+import argparse
|
|
2
|
+import sys
|
|
3
|
+
|
|
4
|
+from lodel import logger
|
|
5
|
+from lodel.exceptions import *
|
|
6
|
+
|
|
7
|
+##@brief Stores registered scripts
|
|
8
|
+__registered_scripts = dict()
|
|
9
|
+
|
|
10
|
+##@brief LodelScript metaclass that allows to "catch" child class
|
|
11
|
+#declaration
|
|
12
|
+#
|
|
13
|
+#Automatic script registration on child class declaration
|
|
14
|
+class MetaLodelScript(type):
|
|
15
|
+
|
|
16
|
+ def __init__(self, name, bases, attrs):
|
|
17
|
+ #Here we can store all child classes of LodelScript
|
|
18
|
+ super().__init__(name, bases, attrs)
|
|
19
|
+ if len(bases) == 1 and bases[0] == object:
|
|
20
|
+ print("Dropped : ", name, bases)
|
|
21
|
+ return
|
|
22
|
+
|
|
23
|
+ self.__register_script(name)
|
|
24
|
+ #_action initialization
|
|
25
|
+ if self._action is None:
|
|
26
|
+ logger.warning("%s._action is None. Trying to use class name as \
|
|
27
|
+action identifier" % name)
|
|
28
|
+ self._action = name
|
|
29
|
+ self._action = self._action.lower()
|
|
30
|
+ if self._description is None:
|
|
31
|
+ self._description = self._default_description()
|
|
32
|
+ self._parser = argparse.ArgumentParser(
|
|
33
|
+ prog = self._prog_name,
|
|
34
|
+ description = self._description)
|
|
35
|
+ self.argparser_config(self._parser)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+ ##@brief Handles script registration
|
|
39
|
+ #@note Script list is maitained in
|
|
40
|
+ #lodel.plugin.admin_script.__registered_scripts
|
|
41
|
+ def __register_script(self, name):
|
|
42
|
+ if self._action is None:
|
|
43
|
+ logger.warning("%s._action is None. Trying to use class name as \
|
|
44
|
+action identifier" % name)
|
|
45
|
+ self._action = name
|
|
46
|
+ self._action = self._action.lower()
|
|
47
|
+ script_registration(self._action, self)
|
|
48
|
+
|
|
49
|
+class LodelScript(object, metaclass=MetaLodelScript):
|
|
50
|
+
|
|
51
|
+ ##@brief A string to identify the action
|
|
52
|
+ _action = None
|
|
53
|
+ ##@brief Script descripiton (argparse argument)
|
|
54
|
+ _description = None
|
|
55
|
+ ##@brief argparse.ArgumentParser instance
|
|
56
|
+ _parser = None
|
|
57
|
+
|
|
58
|
+ ##@brief No instanciation
|
|
59
|
+ def __init__(self):
|
|
60
|
+ raise NotImplementedError("Static class")
|
|
61
|
+
|
|
62
|
+ ##@brief Virtual method. Designed to initialize arguement parser.
|
|
63
|
+ #@param argparser ArgumentParser : Child class argument parser instance
|
|
64
|
+ #@return MUST return the argument parser (NOT SURE ABOUT THAT !! Maybe it \
|
|
65
|
+ #works by reference)
|
|
66
|
+ @classmethod
|
|
67
|
+ def argparser_config(cls, parser):
|
|
68
|
+ raise LodelScriptError("LodelScript.argparser_config() is a pure \
|
|
69
|
+virtual method! MUST be implemented by ALL child classes")
|
|
70
|
+
|
|
71
|
+ ##@brief Virtual method. Run the script
|
|
72
|
+ #@return None or an integer that will be the script return code
|
|
73
|
+ @classmethod
|
|
74
|
+ def run(cls, args):
|
|
75
|
+ raise LodelScriptError("LodelScript.run() is a pure virtual method. \
|
|
76
|
+MUST be implemented by ALL child classes")
|
|
77
|
+
|
|
78
|
+ ##@brief Called by main_run() to execute a script.
|
|
79
|
+ #
|
|
80
|
+ #Handles argument parsing and then call LodelScript.run()
|
|
81
|
+ @classmethod
|
|
82
|
+ def _run(cls):
|
|
83
|
+ args = cls._parser.parse_args()
|
|
84
|
+ return cls.run(args)
|
|
85
|
+
|
|
86
|
+ ##@brief Append action name to the prog name
|
|
87
|
+ #@note See argparse.ArgumentParser() prog argument
|
|
88
|
+ @classmethod
|
|
89
|
+ def _prog_name(cls):
|
|
90
|
+ return '%s %s' % (sys.argv[0], self._action)
|
|
91
|
+
|
|
92
|
+ ##@brief Return the default description for an action
|
|
93
|
+ @classmethod
|
|
94
|
+ def _default_description(cls):
|
|
95
|
+ return "Lodel2 script : %s" % cls._action
|
|
96
|
+
|
|
97
|
+ @classmethod
|
|
98
|
+ def help_exit(cls,msg = None, return_code = 1, exit_after = True):
|
|
99
|
+ if not (msg is None):
|
|
100
|
+ print(msg, file=sys.stderr)
|
|
101
|
+ cls._parser.print_help()
|
|
102
|
+ if exit_after:
|
|
103
|
+ exit(1)
|
|
104
|
+
|
|
105
|
+def script_registration(action_name, cls):
|
|
106
|
+ __registered_scripts[action_name] = cls
|
|
107
|
+ logger.info("New script registered : %s" % action_name)
|
|
108
|
+
|
|
109
|
+##@brief Return a list containing all available actions
|
|
110
|
+def _available_actions():
|
|
111
|
+ return [ act for act in __registered_scripts ]
|
|
112
|
+
|
|
113
|
+##@brief Returns default runner argument parser
|
|
114
|
+def _default_parser():
|
|
115
|
+
|
|
116
|
+ action_list = _available_actions()
|
|
117
|
+ if len(action_list) > 0:
|
|
118
|
+ action_list = ', '.join(sorted(action_list))
|
|
119
|
+ else:
|
|
120
|
+ action_list = 'NO SCRIPT FOUND !'
|
|
121
|
+
|
|
122
|
+ parser = argparse.ArgumentParser(description = "Lodel2 script runner")
|
|
123
|
+ parser.add_argument('action', metavar="ACTION", type=str,
|
|
124
|
+ help="One of the following actions : %s" % action_list)
|
|
125
|
+ parser.add_argument('option', metavar="OPTIONS", type=str, nargs='*',
|
|
126
|
+ help="Action options. Use %s ACTION -h to have help on a specific \
|
|
127
|
+action" % sys.argv[0])
|
|
128
|
+ return parser
|
|
129
|
+
|
|
130
|
+def main_run():
|
|
131
|
+ default_parser = _default_parser()
|
|
132
|
+ if len(sys.argv) == 1:
|
|
133
|
+ default_parser.print_help()
|
|
134
|
+ exit(1)
|
|
135
|
+ #preparing sys.argv (deleting action)
|
|
136
|
+ action = sys.argv[1].lower()
|
|
137
|
+ del(sys.argv[1])
|
|
138
|
+ if action not in __registered_scripts:
|
|
139
|
+ print("Unknow action '%s'\n" % action, file=sys.stderr)
|
|
140
|
+ default_parser.print_help()
|
|
141
|
+ exit(1)
|
|
142
|
+ script = __registered_scripts[action]
|
|
143
|
+ ret = script._run()
|
|
144
|
+ ret = 0 if ret is None else ret
|
|
145
|
+ exit(ret)
|