Start working on plugin manager
This commit is contained in:
		
							parent
							
								
									0ce3c7d940
								
							
						
					
					
						commit
						654703d902
					
				
					 5 changed files with 146 additions and 14 deletions
				
			
		|  | @ -4,18 +4,123 @@ | |||
| 
 | ||||
| # useful libraries | ||||
| import logger, config | ||||
| import os, sys, json | ||||
| 
 | ||||
| # useful functions | ||||
| plugin_name = 'pluginmanager' | ||||
| 
 | ||||
| def installPlugin(): | ||||
| keys_data = {'keys' : {}} | ||||
| 
 | ||||
| # key functions | ||||
| 
 | ||||
| def writeKeys(): | ||||
|     ''' | ||||
|         Serializes and writes the keystore in memory to file | ||||
|     ''' | ||||
| 
 | ||||
|     file = open(keys_file, 'w') | ||||
|     file.write(json.dumps(keys_data, indent=4, sort_keys=True)) | ||||
|     file.close() | ||||
| 
 | ||||
| def readKeys(): | ||||
|     ''' | ||||
|         Loads the keystore into memory | ||||
|     ''' | ||||
| 
 | ||||
|     global keys_data | ||||
|     keys_data = json.loads(open(keys_file).read()) | ||||
|     return keys_data | ||||
| 
 | ||||
| def getKey(plugin): | ||||
|     ''' | ||||
|         Returns the public key for a given plugin | ||||
|     ''' | ||||
| 
 | ||||
|     readKeys() | ||||
|     return (keys_data['keys'][plugin] if plugin in keys_data['keys'] else None) | ||||
| 
 | ||||
| def saveKey(plugin, key): | ||||
|     ''' | ||||
|         Saves the public key for a plugin to keystore | ||||
|     ''' | ||||
| 
 | ||||
|     keys_data['keys'][plugin] = key | ||||
|     writeKeys() | ||||
| 
 | ||||
| def check(): | ||||
|     ''' | ||||
|         Checks to make sure the keystore file still exists | ||||
|     ''' | ||||
| 
 | ||||
|     global keys_file | ||||
|     keys_file = pluginapi.plugins.get_data_folder(plugin_name) + 'keystore.json' | ||||
|     if not os.path.isfile(keys_file): | ||||
|         writeKeys() | ||||
| 
 | ||||
| # command handlers | ||||
| 
 | ||||
| def help(): | ||||
|     logger.info(sys.argv[0] + ' ' + sys.argv[1] + ' <plugin> [public key/block hash]') | ||||
| 
 | ||||
| def commandInstallPlugin(): | ||||
|     logger.warn('This feature is not functional or is still in development.') | ||||
|     if len(sys.argv) >= 3: | ||||
|         check() | ||||
| 
 | ||||
|         pluginname = sys.argv[2] | ||||
|         pkobh = None # public key or block hash | ||||
| 
 | ||||
|         if len(sys.argv) >= 4: | ||||
|             # public key or block hash specified | ||||
|             pkobh = sys.argv[3] | ||||
|         else: | ||||
|             # none specified, check if in config file | ||||
|             pkobh = getKey(pluginname) | ||||
| 
 | ||||
|         if pkobh is None: | ||||
|             logger.error('No key for this plugin found in keystore, please specify.') | ||||
|             help() | ||||
|             return True | ||||
| 
 | ||||
|         valid_hash = pluginapi.get_utils().validateHash(pkobh) | ||||
|         real_block = False | ||||
|         valid_key = pluginapi.get_utils().validatePubKey(pkobh) | ||||
|         real_key = False | ||||
| 
 | ||||
|         if valid_hash: | ||||
|             real_block = pluginapi.get_utils().hasBlock(pkobh) | ||||
|         elif valid_key: | ||||
|             real_key = pluginapi.get_utils().hasKey(pkobh) | ||||
| 
 | ||||
|         blockhash = None | ||||
| 
 | ||||
|         if valid_hash and not real_block: | ||||
|             logger.error('Block hash not found. Perhaps it has not been synced yet?') | ||||
|             logger.debug('Is valid hash, but does not belong to a known block.') | ||||
|             return True | ||||
|         elif valid_hash and real_block: | ||||
|             blockhash = str(pkobh) | ||||
|             logger.debug('Using block ' + blockhash + '...') | ||||
|         elif valid_key and not real_key: | ||||
|             logger.error('Public key not found. Try adding the node by address manually, if possible.') | ||||
|             logger.debug('Is valid key, but the key is not a known one.') | ||||
|         elif valid_key and real_key: | ||||
|             publickey = str(pkobh) | ||||
|             logger.debug('Using public key ' + publickey + '...') | ||||
| 
 | ||||
|             saveKey(pluginname, pkobh) | ||||
|         else: | ||||
|             logger.error('Unknown data \"' + str(pkobh) + '\"; must be public key or block hash.') | ||||
|             return | ||||
|     else: | ||||
|         help() | ||||
| 
 | ||||
|     return True | ||||
| 
 | ||||
| def commandUninstallPlugin(): | ||||
|     logger.info('This feature has not been created yet. Please check back later.') | ||||
|     return | ||||
| 
 | ||||
| def uninstallPlugin(): | ||||
|     logger.info('This feature has not been created yet. Please check back later.') | ||||
|     return | ||||
| 
 | ||||
| def searchPlugin(): | ||||
| def commandSearchPlugin(): | ||||
|     logger.info('This feature has not been created yet. Please check back later.') | ||||
|     return | ||||
| 
 | ||||
|  | @ -24,11 +129,12 @@ def searchPlugin(): | |||
| def on_init(api, data = None): | ||||
|     global pluginapi | ||||
|     pluginapi = api | ||||
|     check() | ||||
| 
 | ||||
|     # register some commands | ||||
|     api.commands.register(['install-plugin', 'installplugin', 'plugin-install', 'install', 'plugininstall'], installPlugin) | ||||
|     api.commands.register(['remove-plugin', 'removeplugin', 'plugin-remove', 'uninstall-plugin', 'uninstallplugin', 'plugin-uninstall', 'uninstall', 'remove', 'pluginremove'], uninstallPlugin) | ||||
|     api.commands.register(['search', 'filter-plugins', 'search-plugins', 'searchplugins', 'search-plugin', 'searchplugin', 'findplugin', 'find-plugin', 'filterplugin', 'plugin-search', 'pluginsearch'], searchPlugin) | ||||
|     api.commands.register(['install-plugin', 'installplugin', 'plugin-install', 'install', 'plugininstall'], commandInstallPlugin) | ||||
|     api.commands.register(['remove-plugin', 'removeplugin', 'plugin-remove', 'uninstall-plugin', 'uninstallplugin', 'plugin-uninstall', 'uninstall', 'remove', 'pluginremove'], commandUninstallPlugin) | ||||
|     api.commands.register(['search', 'filter-plugins', 'search-plugins', 'searchplugins', 'search-plugin', 'searchplugin', 'findplugin', 'find-plugin', 'filterplugin', 'plugin-search', 'pluginsearch'], commandSearchPlugin) | ||||
| 
 | ||||
|     # add help menus once the features are actually implemented | ||||
| 
 | ||||
|  |  | |||
|  | @ -102,16 +102,20 @@ class Onionr: | |||
| 
 | ||||
|                 # Copy default plugins into plugins folder | ||||
| 
 | ||||
|             if not os.path.exists('data/plugins/'): | ||||
|             if not os.path.exists(plugins.get_plugins_folder()): | ||||
|                 if os.path.exists('default-plugins/'): | ||||
|                     names = [f for f in os.listdir("default-plugins/") if not os.path.isfile(f)] | ||||
|                     shutil.copytree('default-plugins/', 'data/plugins/') | ||||
|                     shutil.copytree('default-plugins/', plugins.get_plugins_folder()) | ||||
| 
 | ||||
|                     # Enable plugins | ||||
|                     for name in names: | ||||
|                         if not name in plugins.get_enabled_plugins(): | ||||
|                             plugins.enable(name, self) | ||||
| 
 | ||||
|         for name in plugins.get_enabled_plugins(): | ||||
|             if not os.path.exists(plugins.get_plugin_data_folder(name)): | ||||
|                 os.mkdir(plugins.get_plugin_data_folder(name)) | ||||
| 
 | ||||
|         if not os.path.exists(self.onionrCore.peerDB): | ||||
|             self.onionrCore.createPeerDB() | ||||
|             pass | ||||
|  |  | |||
|  | @ -75,6 +75,15 @@ class PluginAPI: | |||
|     def get_enabled_plugins(self): | ||||
|         return plugins.get_enabled() | ||||
| 
 | ||||
|     def get_folder(self, name = None, absolute = True): | ||||
|         return plugins.get_plugins_folder(name = name, absolute = absolute) | ||||
| 
 | ||||
|     def get_data_folder(self, name, absolute = True): | ||||
|         return plugins.get_plugin_data_folder(name, absolute = absolute) | ||||
| 
 | ||||
|     def daemon_event(self, event, plugin = None): | ||||
|         return # later make local command like /client/?action=makeEvent&event=eventname&module=modulename | ||||
| 
 | ||||
| class CommandAPI: | ||||
|     def __init__(self, pluginapi): | ||||
|         self.pluginapi = pluginapi | ||||
|  |  | |||
|  | @ -204,12 +204,19 @@ def get_plugins_folder(name = None, absolute = True): | |||
|         path = _pluginsfolder | ||||
|     else: | ||||
|         # only allow alphanumeric characters | ||||
|         path = _pluginsfolder + re.sub('[^0-9a-zA-Z]+', '', str(name).lower()) + '/' | ||||
|         path = _pluginsfolder + re.sub('[^0-9a-zA-Z]+', '', str(name).lower()) | ||||
| 
 | ||||
|     if absolute is True: | ||||
|         path = os.path.abspath(path) | ||||
| 
 | ||||
|     return path | ||||
|     return path + '/' | ||||
| 
 | ||||
| def get_plugin_data_folder(name, absolute = True): | ||||
|     ''' | ||||
|         Returns the location of a plugin's data folder | ||||
|     ''' | ||||
| 
 | ||||
|     return get_plugins_folder(name, absolute) + 'data/' | ||||
| 
 | ||||
| def check(): | ||||
|     ''' | ||||
|  |  | |||
|  | @ -228,6 +228,12 @@ class OnionrUtils: | |||
|                 conn.close() | ||||
|                 return False | ||||
| 
 | ||||
|     def hasKey(self, key): | ||||
|         ''' | ||||
|             Check for key in list of public keys | ||||
|         ''' | ||||
|         return key in self._core.listPeers() | ||||
| 
 | ||||
|     def validateHash(self, data, length=64): | ||||
|         ''' | ||||
|             Validate if a string is a valid hex formatted hash | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue