From 7b90c29f1fd7f685d883ef6c0be75c46ec495a34 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 16 Aug 2020 23:15:32 +0200 Subject: Extended the File menu to run external Python scripts on demand. --- configure.ac | 1 + plugins/python/Makefile.am | 3 +- plugins/python/scripting/Makefile.am | 8 +++ plugins/python/scripting/__init__.py | 2 + plugins/python/scripting/core.py | 101 +++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 plugins/python/scripting/Makefile.am create mode 100644 plugins/python/scripting/__init__.py create mode 100644 plugins/python/scripting/core.py diff --git a/configure.ac b/configure.ac index 04cb1ef..f467f66 100644 --- a/configure.ac +++ b/configure.ac @@ -467,6 +467,7 @@ AC_CONFIG_FILES([Makefile plugins/python/apkfiles/Makefile plugins/python/checksec/Makefile plugins/python/liveconv/Makefile + plugins/python/scripting/Makefile plugins/readdex/Makefile plugins/readelf/Makefile plugins/readmc/Makefile diff --git a/plugins/python/Makefile.am b/plugins/python/Makefile.am index d094ccc..c96b6c5 100644 --- a/plugins/python/Makefile.am +++ b/plugins/python/Makefile.am @@ -3,4 +3,5 @@ SUBDIRS = \ abackup \ apkfiles \ checksec \ - liveconv + liveconv \ + scripting diff --git a/plugins/python/scripting/Makefile.am b/plugins/python/scripting/Makefile.am new file mode 100644 index 0000000..5d38d6e --- /dev/null +++ b/plugins/python/scripting/Makefile.am @@ -0,0 +1,8 @@ + +scriptingdir = $(pluginsdatadir)/python/scripting + +scripting_DATA = \ + __init__.py \ + core.py + +EXTRA_DIST = $(scripting_DATA) diff --git a/plugins/python/scripting/__init__.py b/plugins/python/scripting/__init__.py new file mode 100644 index 0000000..82accc0 --- /dev/null +++ b/plugins/python/scripting/__init__.py @@ -0,0 +1,2 @@ + +from scripting.core import ScriptingEngine as AutoLoad diff --git a/plugins/python/scripting/core.py b/plugins/python/scripting/core.py new file mode 100644 index 0000000..7aff551 --- /dev/null +++ b/plugins/python/scripting/core.py @@ -0,0 +1,101 @@ + +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)) -- cgit v0.11.2-87-g4458