fix all syntax issues in SOPS
This commit is contained in:
parent
087dcc3ab2
commit
0abe30791d
@ -7,3 +7,5 @@ Authors=Chrys <chrys@linux-a11y.org>;Storm Dragon <storm_dragon@stormux.org>
|
|||||||
Copyright=Copyright Â2024 Chrys, Storm Dragon
|
Copyright=Copyright Â2024 Chrys, Storm Dragon
|
||||||
Website=https://git.stormux.org/storm/cthulhu
|
Website=https://git.stormux.org/storm/cthulhu
|
||||||
Version=1.0
|
Version=1.0
|
||||||
|
Builtin=true
|
||||||
|
|
||||||
|
@ -1,78 +1,94 @@
|
|||||||
from gi.repository import GObject, Peas, Cthulhu
|
from cthulhu import plugin
|
||||||
|
|
||||||
|
from gi.repository import GObject, Peas
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import importlib.util
|
import importlib.util
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
import threading
|
import _thread
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
class SimplePluginSystem(GObject.Object, Cthulhu.PluginInterface):
|
settings = None
|
||||||
|
keybindings = None
|
||||||
|
speech = None
|
||||||
|
braille = None
|
||||||
|
input_event = None
|
||||||
|
|
||||||
|
def outputMessage( Message):
|
||||||
|
if (settings.enableSpeech):
|
||||||
|
speech.speak(Message)
|
||||||
|
if (settings.enableBraille):
|
||||||
|
braille.displayMessage(Message)
|
||||||
|
|
||||||
|
class SimplePluginSystem(GObject.Object, Peas.Activatable, plugin.Plugin):
|
||||||
__gtype_name__ = 'SimplePluginSystem'
|
__gtype_name__ = 'SimplePluginSystem'
|
||||||
|
object = GObject.Property(type=GObject.Object)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
plugin.Plugin.__init__(self)
|
||||||
self.plugin_list = []
|
self.plugin_list = []
|
||||||
self.loaded = False
|
self.loaded = False
|
||||||
self.my_key_bindings = Cthulhu.keybindings.KeyBindings()
|
self.my_key_bindings = None
|
||||||
self.plugin_repo = os.path.expanduser('~') + "/.local/share/cthulhu/plugins/"
|
self.plugin_repo = os.path.expanduser('~') + "/.local/share/cthulhu/simple-plugins-enabled/"
|
||||||
|
|
||||||
def do_activate(self):
|
def do_activate(self):
|
||||||
"""Required method for Cthulhu plugins"""
|
API = self.object
|
||||||
|
global settings
|
||||||
|
global keybindings
|
||||||
|
global speech
|
||||||
|
global braille
|
||||||
|
global input_event
|
||||||
|
settings = API.app.getDynamicApiManager().getAPI('Settings')
|
||||||
|
keybindings = API.app.getDynamicApiManager().getAPI('Keybindings')
|
||||||
|
speech = API.app.getDynamicApiManager().getAPI('Speech')
|
||||||
|
braille = API.app.getDynamicApiManager().getAPI('Braille')
|
||||||
|
input_event = API.app.getDynamicApiManager().getAPI('InputEvent')
|
||||||
|
"""Required method for plugins"""
|
||||||
|
self.my_key_bindings = keybindings.KeyBindings()
|
||||||
if not self.loaded:
|
if not self.loaded:
|
||||||
self._load_plugins()
|
self.load_plugins()
|
||||||
|
|
||||||
def do_deactivate(self):
|
def do_deactivate(self):
|
||||||
"""Required method for Cthulhu plugins"""
|
"""Required method for plugins"""
|
||||||
# Remove all registered keybindings
|
# Remove all registered keybindings
|
||||||
for plugin in self.plugin_list:
|
for plugin in self.plugin_list:
|
||||||
if plugin.get('inputeventhandler'):
|
if plugin.get('inputeventhandler'):
|
||||||
self.my_key_bindings.remove(plugin['inputeventhandler'])
|
self.my_key_bindings.remove(plugin['inputeventhandler'])
|
||||||
Cthulhu.settings.keyBindingsMap["default"] = Cthulhu.keybindings.KeyBindings()
|
settings.keyBindingsMap["default"] = keybindings.KeyBindings()
|
||||||
self.loaded = False
|
self.loaded = False
|
||||||
self.plugin_list = []
|
self.plugin_list = []
|
||||||
|
|
||||||
def output_message(self, message):
|
def SetupShortcutAndHandle(self, currPluginSetting):
|
||||||
"""Output message through speech and/or braille"""
|
currPluginSetting['inputeventhandler'] = input_event.InputEventHandler(currPluginSetting['function'], currPluginSetting['pluginname'])
|
||||||
if Cthulhu.settings.enableSpeech:
|
# just the modifier
|
||||||
Cthulhu.speech.speak(message)
|
if not currPluginSetting['shiftkey'] and not currPluginSetting['ctrlkey'] and not currPluginSetting['altkey']:
|
||||||
if Cthulhu.settings.enableBraille:
|
self.my_key_bindings.add(keybindings.KeyBinding(currPluginSetting['key'], keybindings.defaultModifierMask, keybindings.CTHULHU_MODIFIER_MASK, currPluginSetting['inputeventhandler']))
|
||||||
Cthulhu.braille.displayMessage(message)
|
# + alt
|
||||||
|
if not currPluginSetting['shiftkey'] and not currPluginSetting['ctrlkey'] and currPluginSetting['altkey']:
|
||||||
|
self.my_key_bindings.add(keybindings.KeyBinding(currPluginSetting['key'], keybindings.defaultModifierMask, keybindings.CTHULHU_ALT_MODIFIER_MASK, currPluginSetting['inputeventhandler']))
|
||||||
|
# + CTRL
|
||||||
|
if not currPluginSetting['shiftkey'] and currPluginSetting['ctrlkey'] and not currPluginSetting['altkey']:
|
||||||
|
self.my_key_bindings.add(keybindings.KeyBinding(currPluginSetting['key'], keybindings.defaultModifierMask, keybindings.CTHULHU_CTRL_MODIFIER_MASK, currPluginSetting['inputeventhandler']))
|
||||||
|
# + alt + CTRL
|
||||||
|
if not currPluginSetting['shiftkey'] and currPluginSetting['ctrlkey'] and currPluginSetting['altkey']:
|
||||||
|
self.my_key_bindings.add(keybindings.KeyBinding(currPluginSetting['key'], keybindings.defaultModifierMask, keybindings.CTHULHU_CTRL_ALT_MODIFIER_MASK, currPluginSetting['inputeventhandler']))
|
||||||
|
# + shift
|
||||||
|
if currPluginSetting['shiftkey'] and not currPluginSetting['ctrlkey'] and not currPluginSetting['altkey']:
|
||||||
|
self.my_key_bindings.add(keybindings.KeyBinding(currPluginSetting['key'], keybindings.defaultModifierMask, keybindings.CTHULHU_SHIFT_MODIFIER_MASK, currPluginSetting['inputeventhandler']))
|
||||||
|
# alt + shift
|
||||||
|
if currPluginSetting['shiftkey'] and not currPluginSetting['ctrlkey'] and currPluginSetting['altkey']:
|
||||||
|
self.my_key_bindings.add(keybindings.KeyBinding(currPluginSetting['key'], keybindings.defaultModifierMask, keybindings.SHIFT_ALT_MODIFIER_MASK, currPluginSetting['inputeventhandler']))
|
||||||
|
print(self.my_key_bindings, currPluginSetting['function'])
|
||||||
|
|
||||||
def setup_shortcut_and_handle(self, settings):
|
settings.keyBindingsMap["default"] = self.my_key_bindings
|
||||||
"""Setup keyboard shortcuts for plugins"""
|
return currPluginSetting
|
||||||
settings['inputeventhandler'] = Cthulhu.input_event.InputEventHandler(
|
|
||||||
settings['function'], settings['pluginname'])
|
|
||||||
|
|
||||||
# Create key binding based on modifier combinations
|
|
||||||
modifiers = Cthulhu.keybindings.defaultModifierMask
|
|
||||||
if settings['shiftkey'] and not settings['ctrlkey'] and not settings['altkey']:
|
|
||||||
mask = Cthulhu.keybindings.CTHULHU_SHIFT_MODIFIER_MASK
|
|
||||||
elif not settings['shiftkey'] and settings['ctrlkey'] and not settings['altkey']:
|
|
||||||
mask = Cthulhu.keybindings.CTHULHU_CTRL_MODIFIER_MASK
|
|
||||||
elif not settings['shiftkey'] and not settings['ctrlkey'] and settings['altkey']:
|
|
||||||
mask = Cthulhu.keybindings.CTHULHU_ALT_MODIFIER_MASK
|
|
||||||
elif not settings['shiftkey'] and settings['ctrlkey'] and settings['altkey']:
|
|
||||||
mask = Cthulhu.keybindings.CTHULHU_CTRL_ALT_MODIFIER_MASK
|
|
||||||
elif settings['shiftkey'] and not settings['ctrlkey'] and settings['altkey']:
|
|
||||||
mask = Cthulhu.keybindings.SHIFT_ALT_MODIFIER_MASK
|
|
||||||
else:
|
|
||||||
mask = Cthulhu.keybindings.CTHULHU_MODIFIER_MASK
|
|
||||||
|
|
||||||
self.my_key_bindings.add(
|
|
||||||
Cthulhu.keybindings.KeyBinding(
|
|
||||||
settings['key'], modifiers, mask, settings['inputeventhandler']
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Cthulhu.settings.keyBindingsMap["default"] = self.my_key_bindings
|
|
||||||
|
|
||||||
def id_generator(self, size=7, chars=string.ascii_letters):
|
def id_generator(self, size=7, chars=string.ascii_letters):
|
||||||
"""Generate random identifier"""
|
|
||||||
return ''.join(random.choice(chars) for _ in range(size))
|
return ''.join(random.choice(chars) for _ in range(size))
|
||||||
|
|
||||||
def init_settings(self):
|
def initSettings(self):
|
||||||
"""Initialize default settings dictionary"""
|
currPluginSetting={
|
||||||
return {
|
|
||||||
'filepath':'',
|
'filepath':'',
|
||||||
'pluginname':'',
|
'pluginname':'',
|
||||||
'functionname':'',
|
'functionname':'',
|
||||||
@ -85,211 +101,172 @@ class SimplePluginSystem(GObject.Object, Cthulhu.PluginInterface):
|
|||||||
'blockcall':False,
|
'blockcall':False,
|
||||||
'error':False,
|
'error':False,
|
||||||
'exec': False,
|
'exec': False,
|
||||||
'executeable': False,
|
|
||||||
'parameters':'',
|
'parameters':'',
|
||||||
'function':None,
|
'function':None,
|
||||||
'inputeventhandler':None,
|
'inputeventhandler':None,
|
||||||
'valid':False,
|
'valid':False,
|
||||||
'supressoutput':False
|
'supressoutput':False
|
||||||
}
|
}
|
||||||
|
return currPluginSetting
|
||||||
|
|
||||||
def get_plugin_settings(self, filepath):
|
def getPluginSettings(self, filepath, currPluginSetting):
|
||||||
"""Parse plugin settings from filename and content"""
|
|
||||||
settings = self.init_settings()
|
|
||||||
try:
|
try:
|
||||||
settings['file'] = filepath
|
currPluginSetting['file'] = filepath
|
||||||
fileName, fileExtension = os.path.splitext(filepath)
|
fileName, fileExtension = os.path.splitext(filepath)
|
||||||
if fileExtension and fileExtension != '':
|
if (fileExtension and (fileExtension != '')): #if there is an extension
|
||||||
settings['loadable'] = (fileExtension.lower() == '.py')
|
currPluginSetting['loadable'] = (fileExtension.lower() == '.py') # only python is loadable
|
||||||
|
filename = os.path.basename(filepath) #filename
|
||||||
filename = os.path.basename(filepath)
|
filename = os.path.splitext(filename)[0] #remove extension if we have one
|
||||||
filename = os.path.splitext(filename)[0]
|
#remove pluginname seperated by __-__
|
||||||
|
filenamehelper = filename.split('__-__')
|
||||||
# Parse filename components
|
filename = filenamehelper[len(filenamehelper) - 1 ]
|
||||||
name_parts = filename.split('__-__')
|
currPluginSetting['permission'] = os.access(filepath, os.X_OK )
|
||||||
if len(name_parts) == 2:
|
currPluginSetting['pluginname'] = 'NoNameAvailable'
|
||||||
settings['pluginname'] = name_parts[0]
|
if len(filenamehelper) == 2:
|
||||||
|
currPluginSetting['pluginname'] = filenamehelper[0]
|
||||||
|
#now get shortcuts seperated by __+__
|
||||||
|
filenamehelper = filename.split('__+__')
|
||||||
|
if len([y for y in filenamehelper if 'parameters_' in y.lower()]) == 1 and\
|
||||||
|
len([y for y in filenamehelper if 'parameters_' in y.lower()][0]) > 11:
|
||||||
|
currPluginSetting['parameters'] = [y for y in filenamehelper if 'parameters_' in y.lower()][0][11:]
|
||||||
|
if len([y for y in filenamehelper if 'key_' in y.lower()]) == 1 and\
|
||||||
|
len([y for y in filenamehelper if 'key_' in y.lower()][0]) > 4 :
|
||||||
|
currPluginSetting['key'] = [y for y in filenamehelper if 'key_' in y.lower()][0][4]
|
||||||
|
if currPluginSetting['key'] == '':
|
||||||
|
settcurrPluginSetting = 'shift' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['ctrlkey'] = 'control' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['altkey'] = 'alt' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['startnotify'] = 'startnotify' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['stopnotify'] = 'stopnotify' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['blockcall'] = 'blockcall' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['error'] = 'error' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['supressoutput'] = 'supressoutput' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['exec'] = 'exec' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting['loadmodule'] = 'loadmodule' in map(str.lower, filenamehelper)
|
||||||
|
currPluginSetting = self.readSettingsFromPlugin(currPluginSetting)
|
||||||
|
if not currPluginSetting['loadmodule']:
|
||||||
|
if not currPluginSetting['permission']: #subprocessing only works with exec permission
|
||||||
|
return self.initSettings()
|
||||||
|
if currPluginSetting['loadmodule'] and not currPluginSetting['loadable']: #sorry.. its not loadable only .py is loadable
|
||||||
|
return self.initSettings()
|
||||||
|
if (len(currPluginSetting['key']) > 1): #no shortcut
|
||||||
|
if not currPluginSetting['exec']: # and no exec -> the plugin make no sense because it isnt hooked anywhere
|
||||||
|
return self.initSettings() #so not load it (sets valid = False)
|
||||||
else:
|
else:
|
||||||
settings['pluginname'] = 'NoNameAvailable'
|
currPluginSetting['key'] = '' #there is a strange key, but exec? ignore the key..
|
||||||
|
currPluginSetting['valid'] = True # we could load everything
|
||||||
|
return currPluginSetting
|
||||||
|
except:
|
||||||
|
return self.initSettings()
|
||||||
|
|
||||||
# Parse settings from filename
|
def readSettingsFromPlugin(self, currPluginSetting):
|
||||||
setting_parts = name_parts[-1].split('__+__')
|
if not os.access(currPluginSetting['file'], os.R_OK ):
|
||||||
|
return currPluginSetting
|
||||||
|
fileName, fileExtension = os.path.splitext(currPluginSetting['file'])
|
||||||
|
if (fileExtension and (fileExtension != '')): #if there is an extension
|
||||||
|
if (fileExtension.lower() != '.py') and \
|
||||||
|
(fileExtension.lower() != '.sh'):
|
||||||
|
return currPluginSetting
|
||||||
|
else:
|
||||||
|
return currPluginSetting
|
||||||
|
|
||||||
# Extract parameters and key
|
with open(currPluginSetting['file'], "r") as pluginFile:
|
||||||
for part in setting_parts:
|
for line in pluginFile:
|
||||||
if part.lower().startswith('parameters_'):
|
currPluginSetting['shiftkey'] = ('sopsproperty:shift' in line.lower().replace(" ", "")) or currPluginSetting['shiftkey']
|
||||||
settings['parameters'] = part[11:]
|
currPluginSetting['ctrlkey'] = ('sopsproperty:control' in line.lower().replace(" ", "")) or currPluginSetting['ctrlkey']
|
||||||
elif part.lower().startswith('key_'):
|
currPluginSetting['altkey'] = ('sopsproperty:alt' in line.lower().replace(" ", "")) or currPluginSetting['altkey']
|
||||||
settings['key'] = part[4:]
|
currPluginSetting['startnotify'] = ('sopsproperty:startnotify' in line.lower().replace(" ", "")) or currPluginSetting['startnotify']
|
||||||
|
currPluginSetting['stopnotify'] = ('sopsproperty:stopnotify' in line.lower().replace(" ", "")) or currPluginSetting['stopnotify']
|
||||||
|
currPluginSetting['blockcall'] = ('sopsproperty:blockcall' in line.lower().replace(" ", "")) or currPluginSetting['blockcall']
|
||||||
|
currPluginSetting['error'] = ('sopsproperty:error' in line.lower().replace(" ", "")) or currPluginSetting['error']
|
||||||
|
currPluginSetting['supressoutput'] = ('sopsproperty:supressoutput' in line.lower().replace(" ", "")) or currPluginSetting['supressoutput']
|
||||||
|
currPluginSetting['exec'] = ('sopsproperty:exec' in line.lower().replace(" ", "")) or currPluginSetting['exec']
|
||||||
|
currPluginSetting['loadmodule'] = ('sopsproperty:loadmodule' in line.lower().replace(" ", "")) or currPluginSetting['loadmodule']
|
||||||
|
return currPluginSetting
|
||||||
|
|
||||||
if not settings['key']:
|
def buildPluginSubprocess(self, currPluginSetting):
|
||||||
settings['key'] = setting_parts[-1].lower()
|
currplugin = "\'\"" + currPluginSetting['file'] + "\" " + currPluginSetting['parameters'] + "\'"
|
||||||
|
pluginname = currPluginSetting['pluginname']
|
||||||
|
if currPluginSetting['blockcall']:
|
||||||
|
pluginname = "blocking " + pluginname
|
||||||
|
fun_body = "global " + currPluginSetting['functionname']+"\n"
|
||||||
|
fun_body += "def " + currPluginSetting['functionname'] + "(script=None, inputEvent=None):\n"
|
||||||
|
if currPluginSetting['startnotify']:
|
||||||
|
fun_body +=" outputMessage('start " + pluginname + "')\n"
|
||||||
|
fun_body +=" p = Popen(" + currplugin + ", stdout=PIPE, stderr=PIPE, shell=True)\n"
|
||||||
|
fun_body +=" stdout, stderr = p.communicate()\n"
|
||||||
|
fun_body +=" message = ''\n"
|
||||||
|
fun_body +=" if not " + str(currPluginSetting['supressoutput']) + " and stdout:\n"
|
||||||
|
fun_body +=" message += str(stdout, \"utf-8\")\n"
|
||||||
|
fun_body +=" if " + str(currPluginSetting['error']) + " and stderr:\n"
|
||||||
|
fun_body +=" message += ' error: ' + str(stderr, \"utf-8\")\n"
|
||||||
|
fun_body +=" outputMessage( message)\n"
|
||||||
|
if currPluginSetting['stopnotify']:
|
||||||
|
fun_body +=" outputMessage('finish " + pluginname + "')\n"
|
||||||
|
fun_body +=" return True\n\n"
|
||||||
|
fun_body += "global " + currPluginSetting['functionname']+"T\n"
|
||||||
|
fun_body +="def " + currPluginSetting['functionname'] + "T(script=None, inputEvent=None):\n"
|
||||||
|
fun_body +=" _thread.start_new_thread("+ currPluginSetting['functionname'] + ",(script, inputEvent))\n\n"
|
||||||
|
return fun_body
|
||||||
|
|
||||||
# Parse boolean flags
|
def buildPluginExec(self, currPluginSetting):
|
||||||
lower_parts = list(map(str.lower, setting_parts))
|
pluginname = currPluginSetting['pluginname']
|
||||||
settings.update({
|
if currPluginSetting['blockcall']:
|
||||||
'shiftkey': 'shift' in lower_parts,
|
pluginname = "blocking " + pluginname
|
||||||
'ctrlkey': 'control' in lower_parts,
|
fun_body = "global " + currPluginSetting['functionname']+"\n"
|
||||||
'altkey': 'alt' in lower_parts,
|
fun_body += "def " + currPluginSetting['functionname'] + "(script=None, inputEvent=None):\n"
|
||||||
'startnotify': 'startnotify' in lower_parts,
|
if currPluginSetting['startnotify']:
|
||||||
'stopnotify': 'stopnotify' in lower_parts,
|
fun_body +=" outputMessage('start " + pluginname + "')\n"
|
||||||
'blockcall': 'blockcall' in lower_parts,
|
fun_body += " try:\n"
|
||||||
'error': 'error' in lower_parts,
|
fun_body += " spec = importlib.util.spec_from_file_location(\"" + currPluginSetting['functionname'] + "\",\""+ currPluginSetting['file']+"\")\n"
|
||||||
'supressoutput': 'supressoutput' in lower_parts,
|
fun_body += " "+currPluginSetting['functionname'] + "Module = importlib.util.module_from_spec(spec)\n"
|
||||||
'exec': 'exec' in lower_parts,
|
fun_body += " spec.loader.exec_module(" + currPluginSetting['functionname'] + "Module)\n"
|
||||||
'loadmodule': 'loadmodule' in lower_parts
|
fun_body += " except:\n"
|
||||||
})
|
fun_body += " pass\n"
|
||||||
|
if currPluginSetting['error']:
|
||||||
|
fun_body += " outputMessage(\"Error while executing " + pluginname + "\")\n"
|
||||||
|
if currPluginSetting['stopnotify']:
|
||||||
|
fun_body +=" outputMessage('finish " + pluginname + "')\n"
|
||||||
|
fun_body += " return True\n\n"
|
||||||
|
fun_body += "global " + currPluginSetting['functionname']+"T\n"
|
||||||
|
fun_body +="def " + currPluginSetting['functionname'] + "T(script=None, inputEvent=None):\n"
|
||||||
|
fun_body +=" _thread.start_new_thread("+ currPluginSetting['functionname'] + ",(script, inputEvent))\n\n"
|
||||||
|
return fun_body
|
||||||
|
|
||||||
settings = self._read_settings_from_plugin(settings)
|
def getFunctionName(self, currPluginSetting):
|
||||||
|
currPluginSetting['functionname'] = ''
|
||||||
|
while currPluginSetting['functionname'] == '' or currPluginSetting['functionname'] + 'T' in globals() or currPluginSetting['functionname'] in globals():
|
||||||
|
currPluginSetting['functionname'] = self.id_generator()
|
||||||
|
return currPluginSetting
|
||||||
|
|
||||||
# Validate settings
|
def load_plugins(self):
|
||||||
if not settings['loadmodule'] and not os.access(filepath, os.X_OK):
|
if not self.loaded:
|
||||||
return self.init_settings()
|
self.plugin_list = glob.glob(self.plugin_repo+'*')
|
||||||
if settings['loadmodule'] and not settings['loadable']:
|
for currplugin in self.plugin_list:
|
||||||
return self.init_settings()
|
currPluginSetting = self.initSettings()
|
||||||
if len(settings['key']) < 1 and not settings['exec']:
|
currPluginSetting = self.getPluginSettings(currplugin, currPluginSetting)
|
||||||
return self.init_settings()
|
|
||||||
|
|
||||||
settings['valid'] = True
|
if not currPluginSetting['valid']:
|
||||||
return settings
|
|
||||||
|
|
||||||
except Exception:
|
|
||||||
return self.init_settings()
|
|
||||||
|
|
||||||
def _read_settings_from_plugin(self, settings):
|
|
||||||
"""Read additional settings from plugin file content"""
|
|
||||||
if not os.access(settings['file'], os.R_OK):
|
|
||||||
return settings
|
|
||||||
|
|
||||||
_, ext = os.path.splitext(settings['file'])
|
|
||||||
if ext and ext.lower() not in ['.py', '.sh']:
|
|
||||||
return settings
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(settings['file'], "r") as plugin_file:
|
|
||||||
for line in plugin_file:
|
|
||||||
line = line.lower().replace(" ", "")
|
|
||||||
if 'sopsproperty:' in line:
|
|
||||||
prop = line.split('sopsproperty:')[1].strip()
|
|
||||||
if prop in settings:
|
|
||||||
settings[prop] = True
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return settings
|
|
||||||
|
|
||||||
def _build_plugin_subprocess(self, settings):
|
|
||||||
"""Build function body for subprocess-based plugins"""
|
|
||||||
curr_plugin = f"'\"{settings['file']}\" {settings['parameters']}'"
|
|
||||||
plugin_name = f"blocking {settings['pluginname']}" if settings['blockcall'] else settings['pluginname']
|
|
||||||
|
|
||||||
func_body = [
|
|
||||||
f"def {settings['functionname']}(script=None, inputEvent=None):"
|
|
||||||
]
|
|
||||||
|
|
||||||
if settings['startnotify']:
|
|
||||||
func_body.append(f" self.output_message('start {plugin_name}')")
|
|
||||||
|
|
||||||
func_body.extend([
|
|
||||||
f" p = Popen({curr_plugin}, stdout=PIPE, stderr=PIPE, shell=True)",
|
|
||||||
" stdout, stderr = p.communicate()",
|
|
||||||
" message = ''",
|
|
||||||
f" if not {settings['supressoutput']} and stdout:",
|
|
||||||
' message += str(stdout, "utf-8")',
|
|
||||||
f" if {settings['error']} and stderr:",
|
|
||||||
' message += \' error: \' + str(stderr, "utf-8")',
|
|
||||||
" self.output_message(message)"
|
|
||||||
])
|
|
||||||
|
|
||||||
if settings['stopnotify']:
|
|
||||||
func_body.append(f" self.output_message('finish {plugin_name}')")
|
|
||||||
|
|
||||||
func_body.append(" return True\n")
|
|
||||||
|
|
||||||
# Add threaded version
|
|
||||||
func_body.extend([
|
|
||||||
f"def {settings['functionname']}T(script=None, inputEvent=None):",
|
|
||||||
f" threading.Thread(target={settings['functionname']}, args=(script, inputEvent)).start()"
|
|
||||||
])
|
|
||||||
|
|
||||||
return "\n".join(func_body)
|
|
||||||
|
|
||||||
def _build_plugin_exec(self, settings):
|
|
||||||
"""Build function body for Python module-based plugins"""
|
|
||||||
plugin_name = f"blocking {settings['pluginname']}" if settings['blockcall'] else settings['pluginname']
|
|
||||||
|
|
||||||
func_body = [
|
|
||||||
f"def {settings['functionname']}(script=None, inputEvent=None):"
|
|
||||||
]
|
|
||||||
|
|
||||||
if settings['startnotify']:
|
|
||||||
func_body.append(f" self.output_message('start {plugin_name}')")
|
|
||||||
|
|
||||||
func_body.extend([
|
|
||||||
" try:",
|
|
||||||
f' spec = importlib.util.spec_from_file_location("{settings["functionname"]}", "{settings["file"]}")',
|
|
||||||
f" {settings['functionname']}Module = importlib.util.module_from_spec(spec)",
|
|
||||||
f" spec.loader.exec_module({settings['functionname']}Module)",
|
|
||||||
" except:",
|
|
||||||
" pass"
|
|
||||||
])
|
|
||||||
|
|
||||||
if settings['error']:
|
|
||||||
func_body.append(f' self.output_message("Error while executing {plugin_name}")')
|
|
||||||
|
|
||||||
if settings['stopnotify']:
|
|
||||||
func_body.append(f" self.output_message('finish {plugin_name}')")
|
|
||||||
|
|
||||||
func_body.append(" return True\n")
|
|
||||||
|
|
||||||
# Add threaded version
|
|
||||||
func_body.extend([
|
|
||||||
f"def {settings['functionname']}T(script=None, inputEvent=None):",
|
|
||||||
f" threading.Thread(target={settings['functionname']}, args=(script, inputEvent)).start()"
|
|
||||||
])
|
|
||||||
|
|
||||||
return "\n".join(func_body)
|
|
||||||
|
|
||||||
def _get_function_name(self, settings):
|
|
||||||
"""Generate unique function name for plugin"""
|
|
||||||
fn = "_" + settings['pluginname'].replace("-", "_")
|
|
||||||
settings['functionname'] = fn
|
|
||||||
while (settings['functionname'] == fn or
|
|
||||||
settings['functionname'] + 'T' in globals() or
|
|
||||||
settings['functionname'] in globals()):
|
|
||||||
settings['functionname'] = self.id_generator() + fn
|
|
||||||
return settings
|
|
||||||
|
|
||||||
def _load_plugins(self):
|
|
||||||
"""Load all plugins from the plugin directory"""
|
|
||||||
plugin_list = glob.glob(self.plugin_repo + '*')
|
|
||||||
for curr_plugin in plugin_list:
|
|
||||||
settings = self.get_plugin_settings(curr_plugin)
|
|
||||||
if not settings['valid']:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
settings = self._get_function_name(settings)
|
currPluginSetting = self.getFunctionName(currPluginSetting)
|
||||||
|
|
||||||
# Build and execute function definition
|
if currPluginSetting['loadmodule']:
|
||||||
if settings['loadmodule']:
|
exec(self.buildPluginExec(currPluginSetting)) # load as python module
|
||||||
exec(self._build_plugin_exec(settings))
|
|
||||||
else:
|
else:
|
||||||
exec(self._build_plugin_subprocess(settings))
|
exec(self.buildPluginSubprocess(currPluginSetting)) # run as subprocess
|
||||||
|
|
||||||
# Set up function reference
|
if currPluginSetting['blockcall']:
|
||||||
if settings['blockcall']:
|
currPluginSetting['function'] = globals()[currPluginSetting['functionname']] # non threaded
|
||||||
settings['function'] = globals()[settings['functionname']]
|
|
||||||
else:
|
else:
|
||||||
settings['function'] = globals()[settings['functionname'] + "T"]
|
currPluginSetting['function'] = globals()[currPluginSetting['functionname']+"T"] # T = Threaded
|
||||||
|
|
||||||
# Execute if needed
|
|
||||||
if settings['exec']:
|
|
||||||
settings['function']()
|
|
||||||
|
|
||||||
# Set up keybinding if needed
|
if currPluginSetting['exec']: # exec on load if we want
|
||||||
if settings['key']:
|
currPluginSetting['function']()
|
||||||
self.setup_shortcut_and_handle(settings)
|
|
||||||
|
|
||||||
self.plugin_list.append(settings)
|
|
||||||
|
|
||||||
|
if not currPluginSetting['key'] == '':
|
||||||
|
currPluginSetting = self.SetupShortcutAndHandle(currPluginSetting)
|
||||||
|
print(currPluginSetting)
|
||||||
|
self.plugin_list.append(currPluginSetting) # store in a list
|
||||||
self.loaded = True
|
self.loaded = True
|
||||||
|
Loading…
Reference in New Issue
Block a user