diff --git a/src/__init__.py b/src/__init__.py index f9aa7843..c094e1fb 100755 --- a/src/__init__.py +++ b/src/__init__.py @@ -66,6 +66,8 @@ import onionrvalues # noqa import onionrexceptions # noqa import onionrsetup as setup # noqa +setup.setup_default_plugins() + min_ver = onionrvalues.MIN_PY_VERSION # Ensure we have at least the minimum python version @@ -95,7 +97,6 @@ if config.get('advanced.security_auditing', True): pass -setup.setup_default_plugins() def onionr_main(): diff --git a/src/apiservers/private/__init__.py b/src/apiservers/private/__init__.py index bef974dc..852d02ae 100644 --- a/src/apiservers/private/__init__.py +++ b/src/apiservers/private/__init__.py @@ -53,19 +53,7 @@ class PrivateAPI: self.startTime = epoch.get_epoch() app = flask.Flask(__name__) - bind_port = int(config.get('client.client.port', 59496)) - self.bindPort = bind_port - self.clientToken = config.get('client.webpassword') - - if config.get('general.bind_address'): - with open(private_API_host_file, 'w') as bindFile: - bindFile.write(config.get('general.bind_address')) - self.host = config.get('general.bind_address') - else: - self.host = httpapi.apiutils.setbindip.set_bind_IP( - private_API_host_file) - logger.info(f'Running API on {self.host}:{self.bindPort}', terminal=True) self.httpServer = '' self.queueResponse = {} @@ -75,11 +63,24 @@ class PrivateAPI: def start(self): """Start client gevent API web server with flask client app.""" + fd_handler = httpapi.fdsafehandler.FDSafeHandler + self.clientToken = config.get('client.webpassword') + if config.get('general.bind_address'): + with open(private_API_host_file, 'w') as bindFile: + bindFile.write(config.get('general.bind_address')) + self.host = config.get('general.bind_address') + else: + self.host = httpapi.apiutils.setbindip.set_bind_IP( + private_API_host_file) + bind_port = int(config.get('client.client.port', 59496)) + self.bindPort = bind_port + self.httpServer = WSGIServer((self.host, self.bindPort), self.app, log=None, handler_class=fd_handler) + logger.info(f'Running API on {self.host}:{self.bindPort}', terminal=True) self.httpServer.serve_forever() def setPublicAPIInstance(self, inst): diff --git a/src/apiservers/private/register_private_blueprints.py b/src/apiservers/private/register_private_blueprints.py index 8d68032e..41e93b1b 100644 --- a/src/apiservers/private/register_private_blueprints.py +++ b/src/apiservers/private/register_private_blueprints.py @@ -10,6 +10,7 @@ from httpapi import miscclientapi, apiutils from httpapi import themeapi from httpapi import fileoffsetreader from httpapi.sse.private import private_sse_blueprint +from httpapi import addblock """ This program is free software: you can redistribute it and/or modify @@ -40,5 +41,6 @@ def register_private_blueprints(private_api, app): app.register_blueprint(themeapi.theme_blueprint) app.register_blueprint(private_sse_blueprint) app.register_blueprint(fileoffsetreader.offset_reader_api) + app.register_blueprint(addblock.blockapi_blueprint) return app diff --git a/src/httpapi/__init__.py b/src/httpapi/__init__.py index c6f0ee16..8f488317 100755 --- a/src/httpapi/__init__.py +++ b/src/httpapi/__init__.py @@ -25,7 +25,7 @@ along with this program. If not, see . def load_plugin_blueprints(flaskapp, blueprint: str = 'flask_blueprint'): """Iterate enabled plugins and load any http endpoints they have""" config.reload() - disabled = config.get('plugins.disabled') + disabled = config.get('plugins.disabled', []) for plugin in onionrplugins.get_enabled_plugins(): if plugin in disabled: continue diff --git a/src/httpapi/addblock/__init__.py b/src/httpapi/addblock/__init__.py index bb19020f..9ec507de 100644 --- a/src/httpapi/addblock/__init__.py +++ b/src/httpapi/addblock/__init__.py @@ -27,18 +27,17 @@ 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 . """ -blockapi = Blueprint('blockapi', __name__) +blockapi_blueprint = Blueprint('blockapi', __name__) stream_to_use = secrets.randbits(1) # Add a block that we generated (or received from a transport like LAN/sneakernet) -@blockapi.route('/addvdfblock', methods=['POST']) +@blockapi_blueprint.route('/addvdfblock', methods=['POST']) def block_serialized(): req_data = request.data block_id = req_data[:BLOCK_ID_SIZE] block_data = req_data[BLOCK_ID_SIZE:] blockqueues.gossip_block_queues[stream_to_use].put( Block(block_id, block_data, auto_verify=False)) - logger.info("Added block" + block_id, terminal=True) - return "ok" \ No newline at end of file + return "ok" diff --git a/src/onionrplugins/__init__.py b/src/onionrplugins/__init__.py index 2bc0e9b6..d63e0a42 100755 --- a/src/onionrplugins/__init__.py +++ b/src/onionrplugins/__init__.py @@ -86,7 +86,7 @@ def enable(name, start_event = True): return False else: logger.error('Failed to enable plugin \"%s\", disabling plugin.' % name, terminal=True) - logger.debug('Plugins folder not found: %s' % get_plugins_folder(str(name).lower())) + logger.debug('Plugins folder not found: %s' % get_plugins_folder(str(name).lower()), terminal=True) disable(name) return False diff --git a/src/onionrplugins/onionrevents.py b/src/onionrplugins/onionrevents.py index 828e6481..16f1f487 100755 --- a/src/onionrplugins/onionrevents.py +++ b/src/onionrplugins/onionrevents.py @@ -35,7 +35,7 @@ def __event_caller(event_name, data = {}): Instead, call onionrevents.event """ - disabled = config.get('plugins.disabled') + disabled = config.get('plugins.disabled', []) for plugin in plugins.get_enabled_plugins(): if plugin in disabled: continue try: diff --git a/src/onionrsetup/defaultpluginsetup.py b/src/onionrsetup/defaultpluginsetup.py index c88a762b..51b0e5e8 100644 --- a/src/onionrsetup/defaultpluginsetup.py +++ b/src/onionrsetup/defaultpluginsetup.py @@ -26,20 +26,22 @@ from utils.readstatic import get_static_dir def setup_default_plugins(): # Copy default plugins into plugins folder - if not os.path.exists(plugins.get_plugins_folder()): - if os.path.exists(get_static_dir() + '/default-plugins/'): - names = [f for f in os.listdir(get_static_dir() + '/default-plugins/')] - try: - shutil.copytree( - get_static_dir() + '/default-plugins/', - plugins.get_plugins_folder()) - except FileExistsError: - pass + if os.path.exists(get_static_dir() + '/default-plugins/'): + names = [f for f in os.listdir(get_static_dir() + '/default-plugins/')] + shutil.copytree( + get_static_dir() + '/default-plugins/', + plugins.get_plugins_folder(), dirs_exist_ok=True) + + + # Enable plugins + for name in names: + if not name in plugins.get_enabled_plugins(): + plugins.enable(name) + else: + logger.error( + "Plugin source directory does not exist!" + + "Onionr needs plugins to be useful", terminal=True) - # Enable plugins - for name in names: - if not name in plugins.get_enabled_plugins(): - plugins.enable(name) for name in plugins.get_enabled_plugins(): if not os.path.exists(plugins.get_plugin_data_folder(name)): diff --git a/src/utils/createdirs.py b/src/utils/createdirs.py index ab536fa1..8462faa5 100644 --- a/src/utils/createdirs.py +++ b/src/utils/createdirs.py @@ -5,6 +5,8 @@ Create required Onionr directories import os import stat +from onionrplugins import get_plugins_folder + from . import identifyhome import filepaths import onionrexceptions @@ -30,7 +32,8 @@ def create_dirs(): order of the hardcoded list below, then trigger creation of DBs""" gen_dirs = [home, filepaths.block_data_location, - filepaths.contacts_location, filepaths.export_location] + filepaths.contacts_location, + filepaths.export_location] for path in gen_dirs: if not os.path.exists(path): os.makedirs(path) diff --git a/static-data/default-plugins/example/.env b/static-data/default-plugins/example/.env new file mode 100644 index 00000000..27a4c0d2 --- /dev/null +++ b/static-data/default-plugins/example/.env @@ -0,0 +1 @@ +PYTHONPATH=./venv/bin/python310:../../src/:./ \ No newline at end of file diff --git a/static-data/default-plugins/example/info.json b/static-data/default-plugins/example/info.json new file mode 100644 index 00000000..306a0686 --- /dev/null +++ b/static-data/default-plugins/example/info.json @@ -0,0 +1,4 @@ +{ "name": "example", + "version": "0.0.0", + "author": "onionr" + } \ No newline at end of file diff --git a/static-data/default-plugins/example/main.py b/static-data/default-plugins/example/main.py new file mode 100644 index 00000000..98df8439 --- /dev/null +++ b/static-data/default-plugins/example/main.py @@ -0,0 +1,57 @@ +"""Onionr - Private P2P Communication. + +Default example plugin for devs or to test blocks +""" +import sys +import os +import locale +import traceback +from typing import Set, TYPE_CHECKING +from threading import Thread, local +import blockdb + +import logger + +import onionrblocks + +locale.setlocale(locale.LC_ALL, '') +sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) +# import after path insert +from onionrutils.localcommand import local_command + +""" +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 . +""" + + +plugin_name = 'example' +PLUGIN_VERSION = '0.0.0' + + + + +def on_blocktest_cmd(api, data=None): + bl = onionrblocks.create_anonvdf_block(b"test", b"txt", 3600) + logger.info( + local_command( + '/addvdfblock', + post_data=bl.id + bl.raw, + silent=False, post=True), + terminal=True) + + + +def on_init(api, data=None): + logger.info( + f"Example Plugin v{PLUGIN_VERSION} enabled", terminal=True) diff --git a/static-data/default-plugins/tor/bootstrap.txt b/static-data/default-plugins/tor/bootstrap.txt index e69de29b..d908f82c 100644 --- a/static-data/default-plugins/tor/bootstrap.txt +++ b/static-data/default-plugins/tor/bootstrap.txt @@ -0,0 +1 @@ +aai7opy5q6innjpb2zgviexvbenhpne7lggnh4lumudojwga2m4wbaqd \ No newline at end of file