| 1 |  |  | # Copyright 2014 Diamond Light Source Ltd. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | # Licensed under the Apache License, Version 2.0 (the "License"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | # you may not use this file except in compliance with the License. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | # You may obtain a copy of the License at | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | #     http://www.apache.org/licenses/LICENSE-2.0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | # Unless required by applicable law or agreed to in writing, software | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | # distributed under the License is distributed on an "AS IS" BASIS, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | # See the License for the specific language governing permissions and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | # limitations under the License. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | .. module:: savu_plugin_generator | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |    :platform: Unix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |    :synopsis: A command line tool for creating Savu plugins | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | .. moduleauthor:: Jessica Verschoyle <[email protected]> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | import os | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | import string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | import argparse | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  | import warnings | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | with warnings.catch_warnings(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     warnings.simplefilter("ignore") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |     import scripts.config_generator.savu_config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     from savu.plugins import utils as pu | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     from scripts.config_generator import config_utils as utils | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  | def __option_parser(doc=True): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |     """ Option parser for command line arguments. Use -d for file deletion | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     and -q for quick template. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     parser = argparse.ArgumentParser(prog='savu_plugin_generator') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     parser.add_argument('plugin_name', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |                         help='Plugin name to create file', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |                         type=str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |     delete_str = 'Delete the plugin file and its tools ' \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |                  'and documentation files.' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     parser.add_argument('-q', '--quick', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |                         action='store_true', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |                         default='False', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |                         help='Create a short template version') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     parser.add_argument('-d', '--delete', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |                         action='store_true', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |                         default='False', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |                         help=delete_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     return parser if doc is True else parser.parse_args() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  | def get_plugin_class(plugin_name): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     """Return the class for the given plugin""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     with warnings.catch_warnings(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         warnings.simplefilter("ignore") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         failed_plugins = utils.populate_plugins() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |     if (failed_plugins is not None) and ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         plugin_name in failed_plugins.keys() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |     ): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |         print( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |             f"IMPORT ERROR: {plugin_name} is unavailable due to the " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |             f"following error:\n\t {failed_plugins[plugin_name]}" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         # At the moment a new file is then created in the general folder. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |         # A yes or no confirmation should be provided before that is created | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |         plugin_class = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |     elif plugin_name not in pu.plugins.keys(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |         print(f"The plugin named {plugin_name} is not in the list " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |               f"of registered plugins.\n") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |         plugin_class = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |         plugin_class = pu.plugins[plugin_name]() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |     return plugin_class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  | def append_file(f, additional_file): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |     """ Append the additional_file on to main file f """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |     with open(additional_file) as input: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         f.write(input.read()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  | def create_plugin_template(file_path, module, quick_arg, savu_base_path): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |     Find the file path for the selected plugin. Generate template files | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     for those which are not present already. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |     :param file_path: File path to the new file | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     :param module: The module name of the new plugin | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |     :param quick_arg: bool True if the user wants a quick template | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |     :param savu_base_path: The base directory | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |     plugin_folder = savu_base_path + file_path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |     title = module.split(".") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |     capital_title = convert_title(title[-1]).replace(" ", "") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |     file_str = plugin_folder + ".py" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |     generator_dir = savu_base_path + "scripts/plugin_generator/" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |     copyright_template = generator_dir + "template_elements/copyright.py" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     detailed_template = ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |         generator_dir | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |         + "template_elements/process_and_setup_detailed_notes.py" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |     quick_template = generator_dir + "template_elements/process_and_setup.py" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |     if os.path.isfile(file_str): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |         print('\nA plugin file exists at', file_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |         with open(file_str, 'w+') as new_py_file: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |             append_file(new_py_file, copyright_template) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |             new_py_file.write(get_module_info(title[-1]).strip()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |             new_py_file.write('\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |             new_py_file.write('from savu.plugins.utils ' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |                                             'import register_plugin\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |             new_py_file.write('from savu.plugins.plugin import Plugin\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             new_py_file.write('# Import any additional libraries or base ' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |                               'plugins here.\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |             new_py_file.write('\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |             new_py_file.write('# This decorator is required for the ' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |                               'configurator to recognise the plugin\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |             new_py_file.write('@register_plugin') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |             new_py_file.write('\nclass ' + capital_title + '(Plugin):\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |             new_py_file.write('# Each class must inherit from the ' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |                               'Plugin class and a driver\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |             new_py_file.write('\n    def __init__(self):') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |             new_py_file.write('\n        super(' + capital_title) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |             new_py_file.write(', self).__init__("' + capital_title + '")\n\n') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |             if quick_arg is True: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |                 # Concise template for previous users | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |                 append_file(new_py_file, quick_template) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |             else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |                 # Detailed template for new users | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |                 append_file(new_py_file, detailed_template) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         print('A plugin file has been created at:\n', file_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  | def create_tools_template(file_path, module, savu_base_path): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |     """Locate a tools file if it exists, otherwise create a new file. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |     Include a brief guide for the parameter yaml layout and citation layout | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |     plugin_folder = savu_base_path + file_path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |     title = module.split(".") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |     capital_title = convert_title(title[-1]).replace(" ", "") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |     file_str = plugin_folder + "_tools.py" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |     generator_dir = savu_base_path + "scripts/plugin_generator/" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |     param_definition_template = ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |         generator_dir + "template_elements/parameter_definition.py" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |     if os.path.isfile(file_str): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |         print("\nA tools file exists at " + file_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |         with open(file_str, "w+") as new_tools_file: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |             new_tools_file.write(get_tools_info(capital_title)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |             append_file(new_tools_file, param_definition_template) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |         print("A tools file has been created at:\n", file_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  | def get_tools_info(title): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |     tools_info =\ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  | '''from savu.plugins.plugin_tools import PluginTools | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  | class ''' + title + '''Tools(PluginTools): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |     """(Change this) A short description of the plugin""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |      | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  | ''' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |     return tools_info | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  | def create_documentation_template( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |     file_path, module, savu_base_path, plugin_guide_path): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |     # Locate documentation file | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |     plugin_path = file_path.replace("savu/", "") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |     doc_folder = ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |         savu_base_path + "doc/source/" + plugin_guide_path + plugin_path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |     title = module.split(".") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |     file_str = doc_folder + "_doc.rst" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |     doc_image_folder = ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |         savu_base_path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |         + "doc/source/files_and_images/" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |         + plugin_guide_path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |         + plugin_path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |         + ".png" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |     if os.path.isfile(file_str): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |         print("\nA documentation file exists at " + file_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |         # Create the file directory for the documentation if it doesn't exist | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |         pu.create_dir(file_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |         # Create the file for the documentation images | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |         pu.create_dir(doc_image_folder) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |         doc_image_folder_inline = doc_image_folder.split("files_and_images/")[ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |             1 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |         ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |         with open(file_str, "w+") as new_rst_file: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |             new_rst_file.write(":orphan:\n\n") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |             new_rst_file.write( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |                 convert_title(title[-1]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |                 + " Documentation" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |                 + "\n##########################################" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |                 "#######################\n" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |             ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |             new_rst_file.write( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |                 "\n(Change this) Include your plugin " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |                 "documentation here. Use a restructured " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |                 "text format.\n" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |             ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |             new_rst_file.write("\n..") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |             new_rst_file.write( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |                 "\n    This is a comment. Include an image " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |                 'or file by using the following text \n    "' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |                 ".. figure:: ../files_and_images/" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |                 + doc_image_folder_inline | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |                 + '"\n' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |             ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |         print("A documentation file has been created at:\n", file_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  | def get_module_info(title): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |     module_info =\ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |     ''' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  | .. module:: ''' + title + \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  | ''' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |    :platform: Unix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |    :synopsis: (Change this) A template to create a simple plugin that takes  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |     one dataset as input and returns a similar dataset as output. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  | .. moduleauthor:: (Change this) Developer Name <[email protected]> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |     ''' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |     return module_info | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  | def convert_title(original_title): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |     # Capwords is used so that the first letter following a number is | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |     # not capitalised. This would affect plugin names including '3d' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |     return string.capwords(original_title.replace("_", " ")) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 250 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 251 |  |  | def valid_name(plugin_name): | 
            
                                                                        
                            
            
                                    
            
            
                | 252 |  |  |     """Return false if the plugin name is not valid. | 
            
                                                                        
                            
            
                                    
            
            
                | 253 |  |  |     Plugin names must begin with a lowercase letter. | 
            
                                                                        
                            
            
                                    
            
            
                | 254 |  |  |     """ | 
            
                                                                        
                            
            
                                    
            
            
                | 255 |  |  |     letters = [l for l in plugin_name] | 
            
                                                                        
                            
            
                                    
            
            
                | 256 |  |  |     if isinstance(letters[0], str) and letters[0].islower(): | 
            
                                                                        
                            
            
                                    
            
            
                | 257 |  |  |         return True | 
            
                                                                        
                            
            
                                    
            
            
                | 258 |  |  |     return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  | def remove_plugin_files(file_path, savu_base_path, plugin_guide_path): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |     """Delete plugin file, tools file and documentation file""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |     plugin_folder = savu_base_path + file_path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |     file_str = plugin_folder + ".py" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |     plugin_error_str = "No plugin file exists for this plugin." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |     remove_file(file_str, plugin_error_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |     # Delete tools file | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |     file_str = plugin_folder + "_tools.py" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |     tools_error_str = "No tools file was located for this plugin." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |     remove_file(file_str, tools_error_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |     # Delete documentation file | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |     doc_file_path = file_path.replace("savu/", "") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  |     doc_folder = ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  |         savu_base_path + "doc/source/" + plugin_guide_path + doc_file_path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |     doc_file_str = doc_folder + "_doc.rst" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |     doc_error_str = \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |         "No documentation file was located for this plugin." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |     remove_file(doc_file_str, doc_error_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  | def check_decision(check): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |     if check.lower() == "y": | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |         return True | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |         return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 |  |  | def remove_file(file_str, error_str): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |     """Remove the file at the provided file path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |     :param file_str: The file path to the file to remove | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  |     :param error_str: The error message to display | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  |     if os.path.isfile(file_str): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |         os.remove(file_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  |         print("The file at:\n", file_str, "was removed.") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |         print(error_str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  | def check_plugin_exists(plugin_name): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  |     """Check if a plugin class is already registered inside Savu | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |     :param plugin_name: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  |     :return: True if found, module name for plugin | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |     if not valid_name(plugin_name): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |         raise ValueError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  |             "Please write the plugin name in the format plugin_name with " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |             "a lowercase letter as the first character and underscores in " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |             "the place of spaces. For example, to create a plugin named " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |             "Median Filter, type median_filter." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |         ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |     print("\nChecking if this plugin already exists..") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |     plugin_title = convert_title(plugin_name).replace(" ", "") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |     plugin = get_plugin_class(plugin_title) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |     if plugin is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |         plugin_module_name = plugin_name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  |         module = "savu.plugins." + plugin_module_name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 |  |  |         return False, module | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 |  |  |     print("This plugin does exist inside Savu.\n") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 |  |  |     return True, plugin.__module__ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  | def main(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 |  |  |     args = __option_parser(doc=False) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  |     print("\n*******************************************************") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  |     print(" Please only use this command when you are working on") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  |     print(" your own Savu directory. New plugin files cannot be ") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 |  |  |     print(" saved to the Diamond Light Source Savu directory") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 |  |  |     print("*******************************************************") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |     print(" Three files will be created: ") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 |  |  |     print(" * A plugin file \n * A plugin tools file \n" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  |           " * A file where you can describe how to use your " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 |  |  |           "plugin") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |     print("*******************************************************") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  |     plugin_exists, module = check_plugin_exists(args.plugin_name) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  |     savu_base_path = \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  |         os.path.dirname(os.path.realpath(__file__)).split("scripts")[0] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 |  |  |     file_path = module.replace(".", "/") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |     plugin_guide_path = "plugin_guides/" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |     if args.delete is True: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 |  |  |         question_str = "Are you sure you want to delete all files for " \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |                        "this plugin? [y/n]" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  |         if check_decision(check=input(question_str)) is True: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |             remove_plugin_files(file_path, savu_base_path, plugin_guide_path) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |             print("Plugin files were not removed.") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |         question_str_1 = f"Do you want the files to be saved inside " \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  |                        f"{savu_base_path}?" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |         question_str = f"Do you want to view the paths to the current " \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |                        f"plugin files?" if plugin_exists \ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  |                        else question_str_1 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |         if check_decision(check=input(question_str)) is True: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |             create_plugin_template( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |                 file_path, module, args.quick, savu_base_path) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |             create_tools_template(file_path, module, savu_base_path) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |             create_documentation_template( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |                 file_path, module, savu_base_path, plugin_guide_path) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |             print(f"\nIf you want to remove all files created, use " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |                   f"\n      savu_plugin_generator -r {args.plugin_name}\n") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |             print("Exiting plugin generator.") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  | if __name__ == '__main__': | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 374 |  |  |     main() | 
            
                                                        
            
                                    
            
            
                | 375 |  |  |  |