from gi.repository import Gtk from pychrysalide import PluginModule from pychrysalide import core from pychrysalide.gui import core as gcore from pychrysalide.gtkext import EasyGtk class ScriptingEngine(PluginModule): """Extend the GUI to run external Python scripts.""" _name = 'ScriptingEngine' _desc = 'Run external Python scripts on demand' _version = '0.1' _url = 'https://www.chrysalide.re/' _actions = ( ) def __init__(self): """Initialize the plugin for Chrysalide.""" super(ScriptingEngine, self).__init__() # Insert the new menu item into 'File' submenu bar = gcore.find_editor_item_by_key('menubar') builder = gcore.get_editor_builder() file_menu = builder.get_object('file').get_submenu() sep_item = builder.get_object('file_sep_1') save_item = builder.get_object('file_save_project') index = EasyGtk.find_contained_child_index(file_menu, save_item) if index == -1: raise RuntimeError('file menu not found') prev = EasyGtk.get_nth_contained_child(file_menu, index - 1) if sep_item == prev: sep = Gtk.SeparatorMenuItem() sep.show() file_menu.insert(sep, index) item = Gtk.MenuItem(label='Run Python script...') item.connect("activate", self._on_file_run_script_activate) item.show() file_menu.insert(item, index) def _on_file_run_script_activate(self, widget): """Look for a new script to run.""" dialog = Gtk.FileChooserDialog(title='Please choose a Python script to execute', transient_for=gcore.get_editor_window(), action=Gtk.FileChooserAction.OPEN) dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK) ffilter = Gtk.FileFilter() ffilter.set_name('Python files') ffilter.add_mime_type('text/x-python') dialog.add_filter(ffilter) response = dialog.run() if response == Gtk.ResponseType.OK: filename = dialog.get_filename() else: filename = None dialog.destroy() if filename: self._run_script_file(filename) def _run_script_file(self, filename): """Run a given script file.""" core.log_message(core.LogMessageType.INFO, 'Execute the script file \'%s\'' % filename) try: with open(filename, 'r') as fd: content = fd.read() code = compile(content, '', 'exec') eval(code) except Exception as e: core.log_message(core.LogMessageType.EXT_ERROR, 'Error while running the script: %s' % str(e))