2015-07-12 20:36:46 +02:00
|
|
|
import argparse
|
|
|
|
import sys
|
|
|
|
import os
|
2015-04-18 03:02:08 +02:00
|
|
|
import ConfigParser
|
|
|
|
|
2015-07-12 20:36:46 +02:00
|
|
|
|
2015-04-18 03:02:08 +02:00
|
|
|
class Config(object):
|
2015-07-12 20:36:46 +02:00
|
|
|
|
2015-07-17 00:28:43 +02:00
|
|
|
def __init__(self, argv):
|
Version 0.3.4, Rev656, CryptMessage plugin for AES and ECIES encryption, Added pyelliptic lib for OpenSSSL based encryption methods, Test CryptMessage plugin, Force reload content.json before signing and after write, Escaped Sql IN queries support, Test Sql parameter escaping, ui_websocket Test fixture, Plugin testing support, Always return websocket errors as dict, Wait for file on weboscket fileGet command if its already in bad_files queue, PushState and ReplaceState url manipulation support in wrapper API, Per auth-address localstorage, Longer timeout for udp tracker query
2015-12-10 21:36:20 +01:00
|
|
|
self.version = "0.3.4"
|
2015-12-28 00:19:58 +01:00
|
|
|
self.rev = 668
|
2015-07-17 00:28:43 +02:00
|
|
|
self.argv = argv
|
|
|
|
self.action = None
|
|
|
|
self.createParser()
|
|
|
|
self.createArguments()
|
|
|
|
|
|
|
|
def createParser(self):
|
|
|
|
# Create parser
|
|
|
|
self.parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
|
|
self.parser.register('type', 'bool', self.strToBool)
|
|
|
|
self.subparsers = self.parser.add_subparsers(title="Action to perform", dest="action")
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return str(self.arguments).replace("Namespace", "Config") # Using argparse str output
|
|
|
|
|
|
|
|
# Convert string to bool
|
|
|
|
def strToBool(self, v):
|
|
|
|
return v.lower() in ("yes", "true", "t", "1")
|
|
|
|
|
|
|
|
# Create command line arguments
|
|
|
|
def createArguments(self):
|
2015-09-10 23:25:09 +02:00
|
|
|
trackers = [
|
2015-11-17 12:48:03 +01:00
|
|
|
"udp://tracker.coppersurfer.tk:6969",
|
2015-09-10 23:25:09 +02:00
|
|
|
"udp://tracker.leechers-paradise.org:6969",
|
|
|
|
"udp://9.rarbg.com:2710",
|
|
|
|
"http://tracker.aletorrenty.pl:2710/announce",
|
2015-11-17 12:48:03 +01:00
|
|
|
"http://tracker.skyts.net:6969/announce",
|
2015-09-10 23:25:09 +02:00
|
|
|
"http://torrent.gresille.org/announce"
|
|
|
|
]
|
2015-07-12 20:36:46 +02:00
|
|
|
# Platform specific
|
|
|
|
if sys.platform.startswith("win"):
|
|
|
|
coffeescript = "type %s | tools\\coffee\\coffee.cmd"
|
|
|
|
else:
|
|
|
|
coffeescript = None
|
|
|
|
|
2015-07-17 00:28:43 +02:00
|
|
|
use_openssl = True
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
# Main
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("main", help='Start UiServer and FileServer (default)')
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
# SiteCreate
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("siteCreate", help='Create a new site')
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
# SiteSign
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("siteSign", help='Update and sign content.json: address [privatekey]')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('address', help='Site to sign')
|
|
|
|
action.add_argument('privatekey', help='Private key (default: ask on execute)', nargs='?')
|
|
|
|
action.add_argument('--inner_path', help='File you want to sign (default: content.json)',
|
|
|
|
default="content.json", metavar="inner_path")
|
|
|
|
action.add_argument('--publish', help='Publish site after the signing', action='store_true')
|
|
|
|
|
|
|
|
# SitePublish
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("sitePublish", help='Publish site to other peers: address')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('address', help='Site to publish')
|
|
|
|
action.add_argument('peer_ip', help='Peer ip to publish (default: random peers ip from tracker)',
|
|
|
|
default=None, nargs='?')
|
|
|
|
action.add_argument('peer_port', help='Peer port to publish (default: random peer port from tracker)',
|
|
|
|
default=15441, nargs='?')
|
|
|
|
action.add_argument('--inner_path', help='Content.json you want to publish (default: content.json)',
|
|
|
|
default="content.json", metavar="inner_path")
|
|
|
|
|
|
|
|
# SiteVerify
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("siteVerify", help='Verify site files using sha512: address')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('address', help='Site to verify')
|
|
|
|
|
|
|
|
# dbRebuild
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("dbRebuild", help='Rebuild site database cache')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('address', help='Site to rebuild')
|
|
|
|
|
|
|
|
# dbQuery
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("dbQuery", help='Query site sql cache')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('address', help='Site to query')
|
|
|
|
action.add_argument('query', help='Sql query')
|
|
|
|
|
|
|
|
# PeerPing
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("peerPing", help='Send Ping command to peer')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('peer_ip', help='Peer ip')
|
|
|
|
action.add_argument('peer_port', help='Peer port', nargs='?')
|
|
|
|
|
|
|
|
# PeerGetFile
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("peerGetFile", help='Request and print a file content from peer')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('peer_ip', help='Peer ip')
|
|
|
|
action.add_argument('peer_port', help='Peer port')
|
|
|
|
action.add_argument('site', help='Site address')
|
|
|
|
action.add_argument('filename', help='File name to request')
|
2015-07-25 13:38:58 +02:00
|
|
|
action.add_argument('--benchmark', help='Request file 10x then displays the total time', action='store_true')
|
2015-07-12 20:36:46 +02:00
|
|
|
|
2015-07-25 13:38:58 +02:00
|
|
|
# PeerCmd
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("peerCmd", help='Request and print a file content from peer')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('peer_ip', help='Peer ip')
|
|
|
|
action.add_argument('peer_port', help='Peer port')
|
|
|
|
action.add_argument('cmd', help='Command to execute')
|
|
|
|
action.add_argument('parameters', help='Parameters to command', nargs='?')
|
|
|
|
|
|
|
|
# CryptSign
|
2015-07-17 00:28:43 +02:00
|
|
|
action = self.subparsers.add_parser("cryptSign", help='Sign message using Bitcoin private key')
|
2015-07-12 20:36:46 +02:00
|
|
|
action.add_argument('message', help='Message to sign')
|
|
|
|
action.add_argument('privatekey', help='Private key')
|
|
|
|
|
|
|
|
# Config parameters
|
2015-07-17 00:28:43 +02:00
|
|
|
self.parser.add_argument('--debug', help='Debug mode', action='store_true')
|
|
|
|
self.parser.add_argument('--debug_socket', help='Debug socket connections', action='store_true')
|
|
|
|
|
2015-09-02 19:15:55 +02:00
|
|
|
self.parser.add_argument('--batch', help="Batch mode (No interactive input for commands)", action='store_true')
|
|
|
|
|
2015-07-17 00:28:43 +02:00
|
|
|
self.parser.add_argument('--config_file', help='Path of config file', default="zeronet.conf", metavar="path")
|
|
|
|
self.parser.add_argument('--data_dir', help='Path of data directory', default="data", metavar="path")
|
|
|
|
self.parser.add_argument('--log_dir', help='Path of logging directory', default="log", metavar="path")
|
|
|
|
|
|
|
|
self.parser.add_argument('--ui_ip', help='Web interface bind address', default="127.0.0.1", metavar='ip')
|
|
|
|
self.parser.add_argument('--ui_port', help='Web interface bind port', default=43110, type=int, metavar='port')
|
|
|
|
self.parser.add_argument('--ui_restrict', help='Restrict web access', default=False, metavar='ip', nargs='*')
|
|
|
|
self.parser.add_argument('--open_browser', help='Open homepage in web browser automatically',
|
|
|
|
nargs='?', const="default_browser", metavar='browser_name')
|
|
|
|
self.parser.add_argument('--homepage', help='Web interface Homepage', default='1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr',
|
|
|
|
metavar='address')
|
|
|
|
self.parser.add_argument('--size_limit', help='Default site size limit in MB', default=10, metavar='size')
|
|
|
|
|
|
|
|
self.parser.add_argument('--fileserver_ip', help='FileServer bind address', default="*", metavar='ip')
|
|
|
|
self.parser.add_argument('--fileserver_port', help='FileServer bind port', default=15441, type=int, metavar='port')
|
|
|
|
self.parser.add_argument('--disable_udp', help='Disable UDP connections', action='store_true')
|
|
|
|
self.parser.add_argument('--proxy', help='Socks proxy address', metavar='ip:port')
|
2015-09-10 23:25:09 +02:00
|
|
|
self.parser.add_argument('--ip_external', help='Set reported external ip (tested on start if None)', metavar='ip')
|
|
|
|
self.parser.add_argument('--trackers', help='Bootstraping torrent trackers', default=trackers, metavar='protocol://address', nargs='*')
|
2015-09-12 17:13:34 +02:00
|
|
|
self.parser.add_argument('--trackers_file', help='Load torrent trackers dynamically from a file', default=False, metavar='path')
|
2015-07-17 00:28:43 +02:00
|
|
|
self.parser.add_argument('--use_openssl', help='Use OpenSSL liblary for speedup',
|
|
|
|
type='bool', choices=[True, False], default=use_openssl)
|
|
|
|
self.parser.add_argument('--disable_encryption', help='Disable connection encryption', action='store_true')
|
|
|
|
self.parser.add_argument('--disable_sslcompression', help='Disable SSL compression to save memory',
|
|
|
|
type='bool', choices=[True, False], default=True)
|
2015-07-25 13:38:58 +02:00
|
|
|
self.parser.add_argument('--use_tempfiles', help='Use temporary files when downloading (experimental)',
|
|
|
|
type='bool', choices=[True, False], default=False)
|
|
|
|
self.parser.add_argument('--stream_downloads', help='Stream download directly to files (experimental)',
|
|
|
|
type='bool', choices=[True, False], default=False)
|
2015-08-06 00:51:25 +02:00
|
|
|
self.parser.add_argument("--msgpack_purepython", help='Use less memory, but a bit more CPU power',
|
2015-09-02 19:15:55 +02:00
|
|
|
type='bool', choices=[True, False], default=True)
|
2015-07-17 00:28:43 +02:00
|
|
|
|
|
|
|
self.parser.add_argument('--coffeescript_compiler', help='Coffeescript compiler for developing', default=coffeescript,
|
|
|
|
metavar='executable_path')
|
|
|
|
|
|
|
|
self.parser.add_argument('--version', action='version', version='ZeroNet %s r%s' % (self.version, self.rev))
|
|
|
|
|
|
|
|
return self.parser
|
2015-07-12 20:36:46 +02:00
|
|
|
|
2015-09-12 17:13:34 +02:00
|
|
|
def loadTrackersFile(self):
|
|
|
|
self.trackers = []
|
|
|
|
for tracker in open(self.trackers_file):
|
|
|
|
if "://" in tracker:
|
|
|
|
self.trackers.append(tracker.strip())
|
|
|
|
|
|
|
|
# Find arguments specified for current action
|
2015-07-12 20:36:46 +02:00
|
|
|
def getActionArguments(self):
|
|
|
|
back = {}
|
|
|
|
arguments = self.parser._subparsers._group_actions[0].choices[self.action]._actions[1:] # First is --version
|
|
|
|
for argument in arguments:
|
|
|
|
back[argument.dest] = getattr(self, argument.dest)
|
|
|
|
return back
|
|
|
|
|
2015-07-17 00:28:43 +02:00
|
|
|
# Try to find action from argv
|
2015-07-12 20:36:46 +02:00
|
|
|
def getAction(self, argv):
|
|
|
|
actions = [action.choices.keys() for action in self.parser._actions if action.dest == "action"][0] # Valid actions
|
|
|
|
found_action = False
|
2015-07-17 00:28:43 +02:00
|
|
|
for action in actions: # See if any in argv
|
2015-07-12 20:36:46 +02:00
|
|
|
if action in argv:
|
|
|
|
found_action = action
|
|
|
|
break
|
|
|
|
return found_action
|
|
|
|
|
2015-07-17 00:28:43 +02:00
|
|
|
# Move plugin parameters to end of argument list
|
|
|
|
def moveUnknownToEnd(self, argv, default_action):
|
|
|
|
valid_actions = sum([action.option_strings for action in self.parser._actions], [])
|
|
|
|
valid_parameters = []
|
|
|
|
plugin_parameters = []
|
|
|
|
plugin = False
|
|
|
|
for arg in argv:
|
|
|
|
if arg.startswith("--"):
|
|
|
|
if arg not in valid_actions:
|
|
|
|
plugin = True
|
|
|
|
else:
|
|
|
|
plugin = False
|
|
|
|
elif arg == default_action:
|
|
|
|
plugin = False
|
|
|
|
|
|
|
|
if plugin:
|
|
|
|
plugin_parameters.append(arg)
|
|
|
|
else:
|
|
|
|
valid_parameters.append(arg)
|
|
|
|
return valid_parameters + plugin_parameters
|
|
|
|
|
|
|
|
# Parse arguments from config file and command line
|
|
|
|
def parse(self, silent=False, parse_config=True):
|
|
|
|
if silent: # Don't display messages or quit on unknown parameter
|
|
|
|
original_print_message = self.parser._print_message
|
|
|
|
original_exit = self.parser.exit
|
|
|
|
|
2015-09-27 02:08:53 +02:00
|
|
|
def silencer(parser, function_name):
|
2015-07-17 00:28:43 +02:00
|
|
|
parser.exited = True
|
|
|
|
return None
|
|
|
|
self.parser.exited = False
|
2015-09-27 02:08:53 +02:00
|
|
|
self.parser._print_message = lambda *args, **kwargs: silencer(self.parser, "_print_message")
|
|
|
|
self.parser.exit = lambda *args, **kwargs: silencer(self.parser, "exit")
|
2015-07-17 00:28:43 +02:00
|
|
|
|
|
|
|
argv = self.argv[:] # Copy command line arguments
|
|
|
|
if parse_config:
|
|
|
|
argv = self.parseConfig(argv) # Add arguments from config file
|
|
|
|
self.parseCommandline(argv, silent) # Parse argv
|
|
|
|
self.setAttributes()
|
|
|
|
|
|
|
|
if silent: # Restore original functions
|
|
|
|
if self.parser.exited and self.action == "main": # Argument parsing halted, don't start ZeroNet with main action
|
|
|
|
self.action = None
|
|
|
|
self.parser._print_message = original_print_message
|
|
|
|
self.parser.exit = original_exit
|
|
|
|
|
2015-07-12 20:36:46 +02:00
|
|
|
# Parse command line arguments
|
2015-07-17 00:28:43 +02:00
|
|
|
def parseCommandline(self, argv, silent=False):
|
2015-07-12 20:36:46 +02:00
|
|
|
# Find out if action is specificed on start
|
|
|
|
action = self.getAction(argv)
|
2015-07-17 00:28:43 +02:00
|
|
|
if not action:
|
2015-07-12 20:36:46 +02:00
|
|
|
argv.append("main")
|
2015-07-17 00:28:43 +02:00
|
|
|
action = "main"
|
|
|
|
argv = self.moveUnknownToEnd(argv, action)
|
|
|
|
if silent:
|
|
|
|
res = self.parser.parse_known_args(argv[1:])
|
|
|
|
if res:
|
|
|
|
self.arguments = res[0]
|
|
|
|
else:
|
|
|
|
self.arguments = {}
|
|
|
|
else:
|
|
|
|
self.arguments = self.parser.parse_args(argv[1:])
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
# Parse config file
|
|
|
|
def parseConfig(self, argv):
|
|
|
|
# Find config file path from parameters
|
|
|
|
config_file = "zeronet.conf"
|
|
|
|
if "--config_file" in argv:
|
|
|
|
config_file = argv[argv.index("--config_file") + 1]
|
|
|
|
# Load config file
|
|
|
|
if os.path.isfile(config_file):
|
|
|
|
config = ConfigParser.ConfigParser(allow_no_value=True)
|
|
|
|
config.read(config_file)
|
|
|
|
for section in config.sections():
|
|
|
|
for key, val in config.items(section):
|
|
|
|
if section != "global": # If not global prefix key with section
|
|
|
|
key = section + "_" + key
|
|
|
|
if val:
|
2015-09-12 17:13:34 +02:00
|
|
|
for line in val.strip().split("\n"): # Allow multi-line values
|
2015-09-10 23:25:09 +02:00
|
|
|
argv.insert(1, line)
|
2015-07-12 20:36:46 +02:00
|
|
|
argv.insert(1, "--%s" % key)
|
|
|
|
return argv
|
|
|
|
|
|
|
|
# Expose arguments as class attributes
|
|
|
|
def setAttributes(self):
|
|
|
|
# Set attributes from arguments
|
2015-07-17 00:28:43 +02:00
|
|
|
if self.arguments:
|
|
|
|
args = vars(self.arguments)
|
|
|
|
for key, val in args.items():
|
|
|
|
setattr(self, key, val)
|
|
|
|
|
|
|
|
def loadPlugins(self):
|
|
|
|
from Plugin import PluginManager
|
|
|
|
|
|
|
|
@PluginManager.acceptPlugins
|
|
|
|
class ConfigPlugin(object):
|
|
|
|
def __init__(self, config):
|
|
|
|
self.parser = config.parser
|
|
|
|
self.createArguments()
|
|
|
|
|
|
|
|
def createArguments(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
ConfigPlugin(self)
|
2015-04-18 03:02:08 +02:00
|
|
|
|
|
|
|
|
2015-07-17 00:28:43 +02:00
|
|
|
config = Config(sys.argv)
|