diff --git a/onionr.sh b/onionr.sh index 286a0f7f..9360e48b 100755 --- a/onionr.sh +++ b/onionr.sh @@ -1,4 +1,4 @@ #!/bin/sh cd "$(dirname "$0")" cd onionr/ -./onionr.py "$@" +./__init__.py "$@" diff --git a/onionr/__init__.py b/onionr/__init__.py index c5f5bfaa..cc5be05f 100755 --- a/onionr/__init__.py +++ b/onionr/__init__.py @@ -36,7 +36,7 @@ except ImportError: # Onionr imports from etc import onionrvalues # For different Onionr related constants such as versions -from onionr import setup +import setup # Ensure we have at least the minimum python version if sys.version_info[0] == 2 or sys.version_info[1] < onionrvalues.MIN_PY_VERSION: @@ -47,16 +47,19 @@ if sys.version_info[0] == 2 or sys.version_info[1] < onionrvalues.MIN_PY_VERSION from utils import detectoptimization if detectoptimization.detect_optimization(): sys.stderr.write('Error, Onionr cannot be run with an optimized Python interpreter\n') - sys.exit(1) + sys.exit(2) # Create Onionr data directories, must be done before most imports from utils import createdirs createdirs.create_dirs() +from onionrcommands import parser + setup.setup_config() setup.setup_default_plugins() def onionr_main(): + parser.register() return if __name__ == "__main__": diff --git a/onionr/etc/onionrvalues.py b/onionr/etc/onionrvalues.py index cd647954..02f12551 100755 --- a/onionr/etc/onionrvalues.py +++ b/onionr/etc/onionrvalues.py @@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' +import platform DENIABLE_PEER_ADDRESS = "OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA====" PASSWORD_LENGTH = 25 ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net' @@ -24,6 +25,13 @@ ONIONR_VERSION = '0.0.0' # for debugging and stuff ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION) API_VERSION = '0' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you. MIN_PY_VERSION = 6 + +platform = platform.system() +if platform == 'Windows': + SCRIPT_NAME = 'run-windows.bat' +else: + SCRIPT_NAME = 'onionr.sh' + class OnionrValues: def __init__(self): self.passwordLength = 20 diff --git a/onionr/onionr.py b/onionr/onionr.py deleted file mode 100755 index 216c0b1d..00000000 --- a/onionr/onionr.py +++ /dev/null @@ -1,384 +0,0 @@ -#!/usr/bin/env python3 -''' - Onionr - Private P2P Communication - - This file initializes Onionr when ran to be a daemon or with commands - - Run with 'help' for usage. -''' -''' - 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 . -''' -import sys -from etc import onionrvalues -if sys.version_info[0] == 2 or sys.version_info[1] < MIN_PY_VERSION: - sys.stderr.write('Error, Onionr requires Python 3.%s+\n' % (MIN_PY_VERSION,)) - sys.exit(1) - -from utils import detectoptimization -if detectoptimization.detect_optimization(): - sys.stderr.write('Error, Onionr cannot be run with an optimized Python interpreter\n') - sys.exit(1) -from utils import createdirs -createdirs.create_dirs() -import os, base64, random, shutil, time, platform, signal -from threading import Thread -import config, logger, onionrplugins as plugins, onionrevents as events -import netcontroller -from onionrblockapi import Block -import onionrexceptions, communicator, setupconfig -import onionrcommands as commands # Many command definitions are here -from utils import identifyhome, hastor -from coredb import keydb -import filepaths - -try: - from urllib3.contrib.socks import SOCKSProxyManager -except ImportError: - raise ImportError("You need the PySocks module (for use with socks5 proxy to use Tor)") - -class Onionr: - def __init__(self): - ''' - Main Onionr class. This is for the CLI program, and does not handle much of the logic. - In general, external programs and plugins should not use this class. - ''' - self.API_VERSION = onionrvalues.API_VERSION - self.userRunDir = os.getcwd() # Directory user runs the program from - self.killed = False - self.config = config - - if sys.argv[0] == os.path.basename(__file__): - try: - os.chdir(sys.path[0]) - except FileNotFoundError: - pass - - # set data dir - self.dataDir = identifyhome.identify_home() - if not self.dataDir.endswith('/'): - self.dataDir += '/' - - # Load global configuration data - data_exists = Onionr.setupConfig(self) - - # Copy default plugins into plugins folder - if not os.path.exists(plugins.get_plugins_folder()): - if os.path.exists('static-data/default-plugins/'): - names = [f for f in os.listdir("static-data/default-plugins/")] - shutil.copytree('static-data/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)): - try: - os.mkdir(plugins.get_plugin_data_folder(name)) - except Exception as e: - #logger.warn('Error enabling plugin: ' + str(e), terminal=True) - plugins.disable(name, onionr = self, stop_event = False) - - self.communicatorInst = None - #self.deleteRunFiles() - - self.clientAPIInst = '' # Client http api instance - self.publicAPIInst = '' # Public http api instance - - signal.signal(signal.SIGTERM, self.exitSigterm) - - # Handle commands - - self.debug = False # Whole application debugging - - # Get configuration - if type(config.get('client.webpassword')) is type(None): - config.set('client.webpassword', base64.b16encode(os.urandom(32)).decode('utf-8'), savefile=True) - if type(config.get('client.client.port')) is type(None): - randomPort = netcontroller.get_open_port() - config.set('client.client.port', randomPort, savefile=True) - if type(config.get('client.public.port')) is type(None): - randomPort = netcontroller.get_open_port() - config.set('client.public.port', randomPort, savefile=True) - if type(config.get('client.api_version')) is type(None): - config.set('client.api_version', onionrvalues.API_VERSION, savefile=True) - - self.cmds = commands.get_commands(self) - self.cmdhelp = commands.cmd_help - - # initialize plugins - events.event('init', onionr = self, threaded = False) - - command = '' - try: - command = sys.argv[1].lower() - except IndexError: - command = '' - finally: - self.execute(command) - - os.chdir(self.userRunDir) - return - - def exitSigterm(self, signum, frame): - self.killed = True - - def cmdHeader(self): - if len(sys.argv) >= 3: - self.header(logger.colors.fg.pink + sys.argv[2].replace('Onionr', logger.colors.bold + 'Onionr' + logger.colors.reset + logger.colors.fg.pink)) - else: - self.header(None) - - def cmdHeader(self): - if len(sys.argv) >= 3: - self.header(logger.colors.fg.pink + sys.argv[2].replace('Onionr', logger.colors.bold + 'Onionr' + logger.colors.reset + logger.colors.fg.pink)) - else: - self.header(None) - - def doExport(self, bHash): - exportDir = self.dataDir + 'block-export/' - if not os.path.exists(exportDir): - if os.path.exists(self.dataDir): - os.mkdir(exportDir) - else: - logger.error('Onionr Not initialized') - data = onionrstorage.getData(bHash) - with open('%s/%s.dat' % (exportDir, bHash), 'wb') as exportFile: - exportFile.write(data) - - def deleteRunFiles(self): - try: - os.remove(filepaths.public_API_host_file) - except FileNotFoundError: - pass - try: - os.remove(filepaths.private_API_host_file) - except FileNotFoundError: - pass - - ''' - Handle command line commands - ''' - - def showDetails(self): - commands.onionrstatistics.show_details(self) - - def openHome(self): - commands.openwebinterface.open_home(self) - - def addID(self): - commands.pubkeymanager.add_ID(self) - - def changeID(self): - commands.pubkeymanager.change_ID(self) - - def getCommands(self): - return self.cmds - - def friendCmd(self): - '''List, add, or remove friend(s) - Changes their peer DB entry. - ''' - commands.pubkeymanager.friend_command(self) - - def banBlock(self): - commands.banblocks.ban_block(self) - - def listConn(self): - commands.onionrstatistics.show_peers(self) - - def listPeers(self): - logger.info('Peer transport address list:', terminal=True) - for i in keydb.listkeys.list_adders(): - logger.info(i, terminal=True) - - def getWebPassword(self): - return config.get('client.webpassword') - - def printWebPassword(self): - logger.info(self.getWebPassword(), terminal=True) - - def getHelp(self): - return self.cmdhelp - - def addCommand(self, command, function): - self.cmds[str(command).lower()] = function - - def addHelp(self, command, 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): - ''' - Displays something from the configuration file, or sets it - ''' - - if len(sys.argv) >= 4: - config.reload() - config.set(sys.argv[2], sys.argv[3], True) - logger.info('Configuration file updated.', terminal=True) - elif len(sys.argv) >= 3: - config.reload() - logger.info(logger.colors.bold + sys.argv[2] + ': ' + logger.colors.reset + str(config.get(sys.argv[2], logger.colors.fg.red + 'Not set.')), terminal=True) - else: - logger.info(logger.colors.bold + 'Get a value: ' + logger.colors.reset + sys.argv[0] + ' ' + sys.argv[1] + ' ', terminal=True) - logger.info(logger.colors.bold + 'Set a value: ' + logger.colors.reset + sys.argv[0] + ' ' + sys.argv[1] + ' ', terminal=True) - - def execute(self, argument): - ''' - Executes a command - ''' - - argument = argument[argument.startswith('--') and len('--'):] # remove -- if it starts with it - - # define commands - commands = self.getCommands() - - command = commands.get(argument, self.notFound) - command() - - def version(self, verbosity = 5, function = logger.info): - ''' - Displays the Onionr version - ''' - - function('Onionr v%s (%s) (API v%s)' % (onionrvalues.ONIONR_VERSION, platform.machine(), onionrvalues.API_VERSION), terminal=True) - if verbosity >= 1: - function(onionrvalues.ONIONR_TAGLINE, terminal=True) - if verbosity >= 2: - function('Running on %s %s' % (platform.platform(), platform.release()), terminal=True) - function('Onionr data dir: %s' % self.dataDir) - - def listKeys(self): - ''' - Displays a list of keys (used to be called peers) (?) - ''' - logger.info('%sPublic keys in database: \n%s%s' % (logger.colors.fg.lightgreen, logger.colors.fg.green, '\n'.join(keydb.listkeys.list_peers()())), terminal=True) - - def addPeer(self): - ''' - Adds a peer (?) - ''' - commands.keyadders.add_peer(self) - - def addAddress(self): - ''' - Adds a Onionr node address - ''' - commands.keyadders.add_address(self) - - def enablePlugin(self): - ''' - Enables and starts the given plugin - ''' - commands.plugincommands.enable_plugin(self) - - def disablePlugin(self): - ''' - Disables and stops the given plugin - ''' - commands.plugincommands.disable_plugin(self) - - def reloadPlugin(self): - ''' - Reloads (stops and starts) all plugins, or the given plugin - ''' - commands.plugincommands.reload_plugin(self) - - def createPlugin(self): - ''' - Creates the directory structure for a plugin name - ''' - commands.plugincommands.create_plugin(self) - - def notFound(self): - ''' - Displays a "command not found" message - ''' - - logger.error('Invalid command.', timestamp = False, terminal=True) - - def showHelpSuggestion(self): - ''' - Displays a message suggesting help - ''' - logger.info('Do ' + logger.colors.bold + sys.argv[0] + ' --help' + logger.colors.reset + logger.colors.fg.green + ' for Onionr help.', terminal=True) - - def start(self, input = False, override = False): - ''' - Starts the Onionr daemon - ''' - if config.get('general.dev_mode', False): - override = True - commands.daemonlaunch.start(self, input, override) - - def setClientAPIInst(self, inst): - self.clientAPIInst = inst - - def getClientApi(self): - while self.clientAPIInst == '': - time.sleep(0.5) - return self.clientAPIInst - - def daemon(self): - ''' - Starts the Onionr communication daemon - ''' - commands.daemonlaunch.daemon(self) - - def killDaemon(self): - ''' - Shutdown the Onionr daemon - ''' - commands.daemonlaunch.kill_daemon(self) - - def showStats(self): - ''' - Displays statistics and exits - ''' - commands.onionrstatistics.show_stats(self) - - def showHelp(self, command = None): - ''' - Show help for Onionr - ''' - commands.show_help(self, command) - - def getFile(self): - ''' - Get a file from onionr blocks - ''' - commands.filecommands.getFile(self) - - def addWebpage(self): - ''' - Add a webpage to the onionr network - ''' - self.addFile(singleBlock=True, blockType='html') - - def addFile(self, singleBlock=False, blockType='bin'): - ''' - Adds a file to the onionr network - ''' - commands.filecommands.add_file(self, singleBlock, blockType) - -if __name__ == "__main__": - Onionr() diff --git a/onionr/onionrcommands/__init__.py b/onionr/onionrcommands/__init__.py index 19029b81..7ec7c971 100755 --- a/onionr/onionrcommands/__init__.py +++ b/onionr/onionrcommands/__init__.py @@ -17,13 +17,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' - +''' import webbrowser, sys import logger from . import pubkeymanager, onionrstatistics, daemonlaunch, filecommands, plugincommands, keyadders from . import banblocks, exportblocks, openwebinterface, resettor, dopex from onionrutils import importnewblocks - +''' def show_help(o_inst, command): helpmenu = o_inst.getHelp() diff --git a/onionr/onionrcommands/parser/__init__.py b/onionr/onionrcommands/parser/__init__.py new file mode 100644 index 00000000..029cc3f3 --- /dev/null +++ b/onionr/onionrcommands/parser/__init__.py @@ -0,0 +1,27 @@ +''' + Onionr - Private P2P Communication + + This module loads in the Onionr arguments and their help messages +''' +''' + 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 . +''' +import argparse, sys +from etc import onionrvalues +def register(): + + parser = argparse.ArgumentParser(prog=onionrvalues.SCRIPT_NAME) + parser.add_argument("command", help="Onionr command to execute") + args = parser.parse_args() + print(args.start) \ No newline at end of file diff --git a/onionr/onionrcommands/parser/arguments.py b/onionr/onionrcommands/parser/arguments.py new file mode 100644 index 00000000..e69de29b