Add in PluginAPI (#7)
* Modify soft resetting Made it more like hard resetting (output-wise). * Refactor timedHmac.py * Update onionrplugins.py Remove test code * Create onionrpluginapi.py * Update onionrevents.py * Update onionrpluginapi.py * Update onionrevents.py * Update onionr.py * Add onionr object to events * Update onionr.pymaster
parent
034410a6e8
commit
2126138428
6
Makefile
6
Makefile
|
@ -23,11 +23,11 @@ test:
|
||||||
@mv onionr/data-backup onionr/data | true > /dev/null 2>&1
|
@mv onionr/data-backup onionr/data | true > /dev/null 2>&1
|
||||||
|
|
||||||
soft-reset:
|
soft-reset:
|
||||||
rm -f onionr/data/blocks/*.dat | true > /dev/null 2>&1
|
@echo "Soft-resetting Onionr..."
|
||||||
rm -f onionr/data/*.db | true > /dev/null 2>&1
|
rm -f onionr/data/blocks/*.dat onionr/data/*.db | true > /dev/null 2>&1
|
||||||
|
@./RUN-LINUX.sh version | grep -v "Failed" --color=always
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
@echo "Hard-resetting Onionr..."
|
@echo "Hard-resetting Onionr..."
|
||||||
rm -rf onionr/data/ | true > /dev/null 2>&1
|
rm -rf onionr/data/ | true > /dev/null 2>&1
|
||||||
@./RUN-LINUX.sh version | grep -v "Failed" --color=always
|
@./RUN-LINUX.sh version | grep -v "Failed" --color=always
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,6 @@ ONIONR_VERSION = '0.0.0' # for debugging and stuff
|
||||||
API_VERSION = '1' # increments of 1; only change when something fundemental about how the API works changes. This way other nodes knows how to communicate without learning too much information about you.
|
API_VERSION = '1' # increments of 1; only change when something fundemental about how the API works changes. This way other nodes knows how to communicate without learning too much information about you.
|
||||||
|
|
||||||
class Onionr:
|
class Onionr:
|
||||||
cmds = {}
|
|
||||||
cmdhelp = {}
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
'''
|
'''
|
||||||
Main Onionr class. This is for the CLI program, and does not handle much of the logic.
|
Main Onionr class. This is for the CLI program, and does not handle much of the logic.
|
||||||
|
@ -210,10 +207,16 @@ class Onionr:
|
||||||
return self.cmdhelp
|
return self.cmdhelp
|
||||||
|
|
||||||
def addCommand(self, command, function):
|
def addCommand(self, command, function):
|
||||||
cmds[str(command).lower()] = function
|
self.cmds[str(command).lower()] = function
|
||||||
|
|
||||||
def addHelp(self, command, description):
|
def addHelp(self, command, description):
|
||||||
cmdhelp[str(command).lower()] = str(description)
|
self.cmdhelp[str(command).lower()] = str(description)
|
||||||
|
|
||||||
|
def delCommand(self, command):
|
||||||
|
return self.cmds.pop(str(command).lower(), None)
|
||||||
|
|
||||||
|
def delHelp(self, command):
|
||||||
|
return self.cmdhelp.pop(str(command).lower(), None)
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
'''
|
'''
|
||||||
|
@ -243,6 +246,8 @@ class Onionr:
|
||||||
|
|
||||||
command = commands.get(argument, self.notFound)
|
command = commands.get(argument, self.notFound)
|
||||||
command()
|
command()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
'''
|
'''
|
||||||
THIS SECTION DEFINES THE COMMANDS
|
THIS SECTION DEFINES THE COMMANDS
|
||||||
|
@ -257,6 +262,8 @@ class Onionr:
|
||||||
logger.info(ONIONR_TAGLINE)
|
logger.info(ONIONR_TAGLINE)
|
||||||
if verbosity >= 2:
|
if verbosity >= 2:
|
||||||
logger.info('Running on ' + platform.platform() + ' ' + platform.release())
|
logger.info('Running on ' + platform.platform() + ' ' + platform.release())
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def sendEncrypt(self):
|
def sendEncrypt(self):
|
||||||
'''
|
'''
|
||||||
|
@ -362,7 +369,7 @@ class Onionr:
|
||||||
if len(sys.argv) >= 3:
|
if len(sys.argv) >= 3:
|
||||||
plugin_name = sys.argv[2]
|
plugin_name = sys.argv[2]
|
||||||
logger.info('Enabling plugin \"' + plugin_name + '\"...')
|
logger.info('Enabling plugin \"' + plugin_name + '\"...')
|
||||||
plugins.enable(plugin_name)
|
plugins.enable(plugin_name, self)
|
||||||
else:
|
else:
|
||||||
logger.info(sys.argv[0] + ' ' + sys.argv[1] + ' <plugin>')
|
logger.info(sys.argv[0] + ' ' + sys.argv[1] + ' <plugin>')
|
||||||
|
|
||||||
|
@ -376,7 +383,7 @@ class Onionr:
|
||||||
if len(sys.argv) >= 3:
|
if len(sys.argv) >= 3:
|
||||||
plugin_name = sys.argv[2]
|
plugin_name = sys.argv[2]
|
||||||
logger.info('Disabling plugin \"' + plugin_name + '\"...')
|
logger.info('Disabling plugin \"' + plugin_name + '\"...')
|
||||||
plugins.disable(plugin_name)
|
plugins.disable(plugin_name, self)
|
||||||
else:
|
else:
|
||||||
logger.info(sys.argv[0] + ' ' + sys.argv[1] + ' <plugin>')
|
logger.info(sys.argv[0] + ' ' + sys.argv[1] + ' <plugin>')
|
||||||
|
|
||||||
|
@ -390,11 +397,11 @@ class Onionr:
|
||||||
if len(sys.argv) >= 3:
|
if len(sys.argv) >= 3:
|
||||||
plugin_name = sys.argv[2]
|
plugin_name = sys.argv[2]
|
||||||
logger.info('Reloading plugin \"' + plugin_name + '\"...')
|
logger.info('Reloading plugin \"' + plugin_name + '\"...')
|
||||||
plugins.stop(plugin_name)
|
plugins.stop(plugin_name, self)
|
||||||
plugins.start(plugin_name)
|
plugins.start(plugin_name, self)
|
||||||
else:
|
else:
|
||||||
logger.info('Reloading all plugins...')
|
logger.info('Reloading all plugins...')
|
||||||
plugins.reload()
|
plugins.reload(self)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,10 @@
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import config, logger, onionrplugins as plugins
|
import config, logger, onionrplugins as plugins, onionrpluginapi as pluginapi
|
||||||
|
|
||||||
|
def get_pluginapi(onionr):
|
||||||
|
return pluginapi.PluginAPI(onionr)
|
||||||
|
|
||||||
def event(event_name, data = None, onionr = None):
|
def event(event_name, data = None, onionr = None):
|
||||||
'''
|
'''
|
||||||
|
@ -27,11 +30,11 @@ def event(event_name, data = None, onionr = None):
|
||||||
|
|
||||||
for plugin in plugins.get_enabled_plugins():
|
for plugin in plugins.get_enabled_plugins():
|
||||||
try:
|
try:
|
||||||
call(plugins.get_plugin(plugin), event_name, data, onionr)
|
call(plugins.get_plugin(plugin), event_name, data, self.get_pluginapi(onionr))
|
||||||
except:
|
except:
|
||||||
logger.warn('Event \"' + event_name + '\" failed for plugin \"' + plugin + '\".')
|
logger.warn('Event \"' + event_name + '\" failed for plugin \"' + plugin + '\".')
|
||||||
|
|
||||||
def call(plugin, event_name, data = None, onionr = None):
|
def call(plugin, event_name, data = None, pluginapi = None):
|
||||||
'''
|
'''
|
||||||
Calls an event on a plugin if one is defined
|
Calls an event on a plugin if one is defined
|
||||||
'''
|
'''
|
||||||
|
@ -43,7 +46,7 @@ def call(plugin, event_name, data = None, onionr = None):
|
||||||
# TODO: Use multithreading perhaps?
|
# TODO: Use multithreading perhaps?
|
||||||
if hasattr(plugin, attribute):
|
if hasattr(plugin, attribute):
|
||||||
logger.debug('Calling event ' + str(event_name))
|
logger.debug('Calling event ' + str(event_name))
|
||||||
getattr(plugin, attribute)(onionr, data)
|
getattr(plugin, attribute)(pluginapi, data)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
'''
|
||||||
|
Onionr - P2P Microblogging Platform & Social network
|
||||||
|
|
||||||
|
This file deals with the object that is passed with each event
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import onionrplugins as plugins, logger
|
||||||
|
|
||||||
|
class PluginAPI:
|
||||||
|
def __init__(self, onionr):
|
||||||
|
self.onionr = onionr
|
||||||
|
|
||||||
|
self.daemon = DaemonAPI(self)
|
||||||
|
self.plugin = PluginAPI(self)
|
||||||
|
self.command = CommandAPI(self)
|
||||||
|
|
||||||
|
def get_onionr(self):
|
||||||
|
return self.onionr
|
||||||
|
|
||||||
|
def get_core(self):
|
||||||
|
return self.get_onionr().onionrCore
|
||||||
|
|
||||||
|
def get_utils(self):
|
||||||
|
return self.get_onionr().onionrUtils
|
||||||
|
|
||||||
|
def get_daemonapi(self):
|
||||||
|
return self.daemon
|
||||||
|
|
||||||
|
def get_pluginapi(self):
|
||||||
|
return self.plugin
|
||||||
|
|
||||||
|
def get_commandapi(self):
|
||||||
|
return self.command
|
||||||
|
|
||||||
|
def is_development_mode(self):
|
||||||
|
return self.get_onionr()._developmentMode
|
||||||
|
|
||||||
|
class DaemonAPI:
|
||||||
|
def __init__(self, pluginapi):
|
||||||
|
self.pluginapi = pluginapi
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.pluginapi.get_onionr().daemon()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.pluginapi.get_onionr().killDaemon()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def queue(self, command, data = ''):
|
||||||
|
self.pluginapi.get_core().daemonQueueAdd(command, data)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def local_command(self, command):
|
||||||
|
self.pluginapi.get_utils().localCommand(self, command)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def queue_pop(self):
|
||||||
|
return self.get_core().daemonQueue()
|
||||||
|
|
||||||
|
class PluginAPI:
|
||||||
|
def __init__(self, pluginapi):
|
||||||
|
self.pluginapi = pluginapi
|
||||||
|
|
||||||
|
def start(self, name):
|
||||||
|
plugins.start(name)
|
||||||
|
|
||||||
|
def stop(self, name):
|
||||||
|
plugins.stop(name)
|
||||||
|
|
||||||
|
def reload(self, name):
|
||||||
|
plugins.reload(name)
|
||||||
|
|
||||||
|
def enable(self, name):
|
||||||
|
plugins.enable(name)
|
||||||
|
|
||||||
|
def disable(self, name):
|
||||||
|
plugins.disable(name)
|
||||||
|
|
||||||
|
def is_enabled(self, name):
|
||||||
|
return plugins.is_enabled(name)
|
||||||
|
|
||||||
|
def get_enabled_plugins(self):
|
||||||
|
return plugins.get_enabled_plugins()
|
||||||
|
|
||||||
|
class CommandAPI:
|
||||||
|
def __init__(self, pluginapi):
|
||||||
|
self.pluginapi = pluginapi
|
||||||
|
|
||||||
|
def register(self, names, call = None):
|
||||||
|
if isinstance(names, str):
|
||||||
|
names = [names]
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
self.pluginapi.get_onionr().addCommand(name, call)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def unregister(self, names):
|
||||||
|
if isinstance(names, str):
|
||||||
|
names = [names]
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
self.pluginapi.get_onionr().delCommand(name)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def register_help(self, names, description):
|
||||||
|
if isinstance(names, str):
|
||||||
|
names = [names]
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
self.pluginapi.get_onionr().addHelp(name, description)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def unregister_help(self, names):
|
||||||
|
if isinstance(names, str):
|
||||||
|
names = [names]
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
self.pluginapi.get_onionr().delHelp(name)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def call(self, name):
|
||||||
|
self.pluginapi.get_onionr().execute(name)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def get_commands(self):
|
||||||
|
return self.pluginapi.get_onionr().getCommands()
|
|
@ -24,7 +24,7 @@ import onionrevents as events
|
||||||
_pluginsfolder = 'data/plugins/'
|
_pluginsfolder = 'data/plugins/'
|
||||||
_instances = dict()
|
_instances = dict()
|
||||||
|
|
||||||
def reload(stop_event = True):
|
def reload(onionr = None, stop_event = True):
|
||||||
'''
|
'''
|
||||||
Reloads all the plugins
|
Reloads all the plugins
|
||||||
'''
|
'''
|
||||||
|
@ -41,10 +41,10 @@ def reload(stop_event = True):
|
||||||
|
|
||||||
if stop_event is True:
|
if stop_event is True:
|
||||||
for plugin in enabled_plugins:
|
for plugin in enabled_plugins:
|
||||||
stop(plugin)
|
stop(plugin, onionr)
|
||||||
|
|
||||||
for plugin in enabled_plugins:
|
for plugin in enabled_plugins:
|
||||||
start(plugin)
|
start(plugin, onionr)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
|
@ -53,7 +53,7 @@ def reload(stop_event = True):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def enable(name, start_event = True):
|
def enable(name, onionr = None, start_event = True):
|
||||||
'''
|
'''
|
||||||
Enables a plugin
|
Enables a plugin
|
||||||
'''
|
'''
|
||||||
|
@ -67,7 +67,7 @@ def enable(name, start_event = True):
|
||||||
config_plugins['enabled'] = enabled_plugins
|
config_plugins['enabled'] = enabled_plugins
|
||||||
config.set('plugins', config_plugins, True)
|
config.set('plugins', config_plugins, True)
|
||||||
|
|
||||||
events.call(get_plugin(name), 'enable')
|
events.call(get_plugin(name), 'enable', onionr)
|
||||||
|
|
||||||
if start_event is True:
|
if start_event is True:
|
||||||
start(name)
|
start(name)
|
||||||
|
@ -80,7 +80,7 @@ def enable(name, start_event = True):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def disable(name, stop_event = True):
|
def disable(name, onionr = None, stop_event = True):
|
||||||
'''
|
'''
|
||||||
Disables a plugin
|
Disables a plugin
|
||||||
'''
|
'''
|
||||||
|
@ -95,12 +95,12 @@ def disable(name, stop_event = True):
|
||||||
config.set('plugins', config_plugins, True)
|
config.set('plugins', config_plugins, True)
|
||||||
|
|
||||||
if exists(name):
|
if exists(name):
|
||||||
events.call(get_plugin(name), 'disable')
|
events.call(get_plugin(name), 'disable', onionr)
|
||||||
|
|
||||||
if stop_event is True:
|
if stop_event is True:
|
||||||
stop(name)
|
stop(name)
|
||||||
|
|
||||||
def start(name):
|
def start(name, onionr = None):
|
||||||
'''
|
'''
|
||||||
Starts the plugin
|
Starts the plugin
|
||||||
'''
|
'''
|
||||||
|
@ -114,7 +114,7 @@ def start(name):
|
||||||
if plugin is None:
|
if plugin is None:
|
||||||
raise Exception('Failed to import module.')
|
raise Exception('Failed to import module.')
|
||||||
else:
|
else:
|
||||||
events.call(plugin, 'start')
|
events.call(plugin, 'start', onionr)
|
||||||
|
|
||||||
return plugin
|
return plugin
|
||||||
except:
|
except:
|
||||||
|
@ -124,7 +124,7 @@ def start(name):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def stop(name):
|
def stop(name, onionr = None):
|
||||||
'''
|
'''
|
||||||
Stops the plugin
|
Stops the plugin
|
||||||
'''
|
'''
|
||||||
|
@ -138,7 +138,7 @@ def stop(name):
|
||||||
if plugin is None:
|
if plugin is None:
|
||||||
raise Exception('Failed to import module.')
|
raise Exception('Failed to import module.')
|
||||||
else:
|
else:
|
||||||
events.call(plugin, 'stop')
|
events.call(plugin, 'stop', onionr)
|
||||||
|
|
||||||
return plugin
|
return plugin
|
||||||
except:
|
except:
|
||||||
|
@ -225,10 +225,5 @@ def check():
|
||||||
if not os.path.exists(os.path.dirname(get_plugins_folder())):
|
if not os.path.exists(os.path.dirname(get_plugins_folder())):
|
||||||
logger.debug('Generating plugin data folder...')
|
logger.debug('Generating plugin data folder...')
|
||||||
os.makedirs(os.path.dirname(get_plugins_folder()))
|
os.makedirs(os.path.dirname(get_plugins_folder()))
|
||||||
|
|
||||||
#if not exists('test'):
|
|
||||||
#os.makedirs(get_plugins_folder('test'))
|
|
||||||
#with open(get_plugins_folder('test') + '/main.py', 'a') as main:
|
|
||||||
#main.write("print('Running')\n\ndef on_test(onionr = None, data = None):\n print('received test event!')\n return True\n\ndef on_start(onionr = None, data = None):\n print('start event called')\n\ndef on_stop(onionr = None, data = None):\n print('stop event called')\n\ndef on_enable(onionr = None, data = None):\n print('enable event called')\n\ndef on_disable(onionr = None, data = None):\n print('disable event called')\n")
|
|
||||||
#enable('test')
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import hmac, base64, time, math
|
import hmac, base64, time, math
|
||||||
|
|
||||||
class TimedHMAC:
|
class TimedHMAC:
|
||||||
def __init__(self, base64Key, data, hashAlgo):
|
def __init__(self, base64Key, data, hashAlgo):
|
||||||
'''
|
'''
|
||||||
|
@ -23,6 +25,7 @@ class TimedHMAC:
|
||||||
|
|
||||||
Maximum of 10 seconds grace period
|
Maximum of 10 seconds grace period
|
||||||
'''
|
'''
|
||||||
|
|
||||||
self.data = data
|
self.data = data
|
||||||
self.expire = math.floor(time.time())
|
self.expire = math.floor(time.time())
|
||||||
self.hashAlgo = hashAlgo
|
self.hashAlgo = hashAlgo
|
||||||
|
@ -34,11 +37,14 @@ class TimedHMAC:
|
||||||
return
|
return
|
||||||
|
|
||||||
def check(self, data):
|
def check(self, data):
|
||||||
# Check a hash (and verify time is sane)
|
'''
|
||||||
|
Check a hash (and verify time is sane)
|
||||||
|
'''
|
||||||
|
|
||||||
testHash = hmac.HMAC(base64.b64decode(base64Key).decode(), digestmod=self.hashAlgo)
|
testHash = hmac.HMAC(base64.b64decode(base64Key).decode(), digestmod=self.hashAlgo)
|
||||||
testHash.update(data + math.floor(time.time()))
|
testHash.update(data + math.floor(time.time()))
|
||||||
testHash = testHash.hexdigest()
|
testHash = testHash.hexdigest()
|
||||||
if hmac.compare_digest(testHash, self.HMACResult):
|
if hmac.compare_digest(testHash, self.HMACResult):
|
||||||
return true
|
return true
|
||||||
else:
|
|
||||||
return false
|
return false
|
Loading…
Reference in New Issue