summaryrefslogtreecommitdiff
path: root/onionshare/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'onionshare/__init__.py')
-rw-r--r--onionshare/__init__.py182
1 files changed, 122 insertions, 60 deletions
diff --git a/onionshare/__init__.py b/onionshare/__init__.py
index 032b4acc..2f44c846 100644
--- a/onionshare/__init__.py
+++ b/onionshare/__init__.py
@@ -2,7 +2,7 @@
"""
OnionShare | https://onionshare.org/
-Copyright (C) 2018 Micah Lee <micah@micahflee.com>
+Copyright (C) 2014-2018 Micah Lee <micah@micahflee.com>
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
@@ -20,21 +20,32 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import os, sys, time, argparse, threading
-from . import strings, common, web
+from . import strings
+from .common import Common
+from .web import Web
from .onion import *
from .onionshare import OnionShare
-from .settings import Settings
def main(cwd=None):
"""
The main() function implements all of the logic that the command-line version of
onionshare uses.
"""
+ common = Common()
+
+ # Load the default settings and strings early, for the sake of being able to parse options.
+ # These won't be in the user's chosen locale necessarily, but we need to parse them
+ # early in order to even display the option to pass alternate settings (which might
+ # contain a preferred locale).
+ # If an alternate --config is passed, we'll reload strings later.
+ common.load_settings()
strings.load_strings(common)
- print(strings._('version_string').format(common.get_version()))
+
+ # Display OnionShare banner
+ print(strings._('version_string').format(common.version))
# OnionShare CLI in OSX needs to change current working directory (#132)
- if common.get_platform() == 'Darwin':
+ if common.platform == 'Darwin':
if cwd:
os.chdir(cwd)
@@ -44,9 +55,10 @@ def main(cwd=None):
parser.add_argument('--stay-open', action='store_true', dest='stay_open', help=strings._("help_stay_open"))
parser.add_argument('--shutdown-timeout', metavar='<int>', dest='shutdown_timeout', default=0, help=strings._("help_shutdown_timeout"))
parser.add_argument('--stealth', action='store_true', dest='stealth', help=strings._("help_stealth"))
- parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug"))
+ parser.add_argument('--receive', action='store_true', dest='receive', help=strings._("help_receive"))
parser.add_argument('--config', metavar='config', default=False, help=strings._('help_config'))
- parser.add_argument('filename', metavar='filename', nargs='+', help=strings._('help_filename'))
+ parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug"))
+ parser.add_argument('filename', metavar='filename', nargs='*', help=strings._('help_filename'))
args = parser.parse_args()
filenames = args.filename
@@ -58,65 +70,86 @@ def main(cwd=None):
stay_open = bool(args.stay_open)
shutdown_timeout = int(args.shutdown_timeout)
stealth = bool(args.stealth)
+ receive = bool(args.receive)
config = args.config
- # Debug mode?
- if debug:
- common.set_debug(debug)
- web.debug_mode()
-
- # Validation
- valid = True
- for filename in filenames:
- if not os.path.isfile(filename) and not os.path.isdir(filename):
- print(strings._("not_a_file").format(filename))
- valid = False
- if not os.access(filename, os.R_OK):
- print(strings._("not_a_readable_file").format(filename))
- valid = False
- if not valid:
+ if receive:
+ mode = 'receive'
+ else:
+ mode = 'share'
+
+ # Make sure filenames given if not using receiver mode
+ if mode == 'share' and len(filenames) == 0:
+ parser.print_help()
sys.exit()
+ # Validate filenames
+ if mode == 'share':
+ valid = True
+ for filename in filenames:
+ if not os.path.isfile(filename) and not os.path.isdir(filename):
+ print(strings._("not_a_file").format(filename))
+ valid = False
+ if not os.access(filename, os.R_OK):
+ print(strings._("not_a_readable_file").format(filename))
+ valid = False
+ if not valid:
+ sys.exit()
+
+ # Re-load settings, if a custom config was passed in
+ if config:
+ common.load_settings(config)
+ # Re-load the strings, in case the provided config has changed locale
+ strings.load_strings(common)
- settings = Settings(config)
+ # Debug mode?
+ common.debug = debug
+
+ # Create the Web object
+ web = Web(common, False, mode)
# Start the Onion object
- onion = Onion()
+ onion = Onion(common)
try:
- onion.connect(settings=False, config=config)
- except (TorTooOld, TorErrorInvalidSetting, TorErrorAutomatic, TorErrorSocketPort, TorErrorSocketFile, TorErrorMissingPassword, TorErrorUnreadableCookieFile, TorErrorAuthError, TorErrorProtocolError, BundledTorNotSupported, BundledTorTimeout) as e:
- sys.exit(e.args[0])
+ onion.connect(custom_settings=False, config=config)
except KeyboardInterrupt:
print("")
sys.exit()
+ except Exception as e:
+ sys.exit(e.args[0])
# Start the onionshare app
try:
- app = OnionShare(onion, local_only, stay_open, shutdown_timeout)
+ app = OnionShare(common, onion, local_only, shutdown_timeout)
app.set_stealth(stealth)
+ app.choose_port()
app.start_onion_service()
except KeyboardInterrupt:
print("")
sys.exit()
+ except (TorTooOld, TorErrorProtocolError) as e:
+ print("")
+ print(e.args[0])
+ sys.exit()
- # Prepare files to share
- print(strings._("preparing_files"))
- try:
- web.set_file_info(filenames)
- app.cleanup_filenames.append(web.zip_filename)
- except OSError as e:
- print(e.strerror)
- sys.exit(1)
-
- # Warn about sending large files over Tor
- if web.zip_filesize >= 157286400: # 150mb
- print('')
- print(strings._("large_filesize"))
- print('')
+ if mode == 'share':
+ # Prepare files to share
+ print(strings._("preparing_files"))
+ try:
+ web.share_mode.set_file_info(filenames)
+ app.cleanup_filenames += web.share_mode.cleanup_filenames
+ except OSError as e:
+ print(e.strerror)
+ sys.exit(1)
+
+ # Warn about sending large files over Tor
+ if web.share_mode.download_filesize >= 157286400: # 150mb
+ print('')
+ print(strings._("large_filesize"))
+ print('')
# Start OnionShare http service in new thread
- settings.load()
- t = threading.Thread(target=web.start, args=(app.port, app.stay_open, settings.get('slug')))
+ t = threading.Thread(target=web.start, args=(app.port, stay_open, common.settings.get('public_mode'), common.settings.get('slug')))
t.daemon = True
t.start()
@@ -129,18 +162,39 @@ def main(cwd=None):
app.shutdown_timer.start()
# Save the web slug if we are using a persistent private key
- if settings.get('save_private_key'):
- if not settings.get('slug'):
- settings.set('slug', web.slug)
- settings.save()
-
- if(stealth):
- print(strings._("give_this_url_stealth"))
- print('http://{0:s}/{1:s}'.format(app.onion_host, web.slug))
- print(app.auth_string)
+ if common.settings.get('save_private_key'):
+ if not common.settings.get('slug'):
+ common.settings.set('slug', web.slug)
+ common.settings.save()
+
+ # Build the URL
+ if common.settings.get('public_mode'):
+ url = 'http://{0:s}'.format(app.onion_host)
+ else:
+ url = 'http://{0:s}/{1:s}'.format(app.onion_host, web.slug)
+
+ print('')
+ if mode == 'receive':
+ print(strings._('receive_mode_data_dir').format(common.settings.get('data_dir')))
+ print('')
+ print(strings._('receive_mode_warning'))
+ print('')
+
+ if stealth:
+ print(strings._("give_this_url_receive_stealth"))
+ print(url)
+ print(app.auth_string)
+ else:
+ print(strings._("give_this_url_receive"))
+ print(url)
else:
- print(strings._("give_this_url"))
- print('http://{0:s}/{1:s}'.format(app.onion_host, web.slug))
+ if stealth:
+ print(strings._("give_this_url_stealth"))
+ print(url)
+ print(app.auth_string)
+ else:
+ print(strings._("give_this_url"))
+ print(url)
print('')
print(strings._("ctrlc_to_stop"))
@@ -149,11 +203,19 @@ def main(cwd=None):
if app.shutdown_timeout > 0:
# if the shutdown timer was set and has run out, stop the server
if not app.shutdown_timer.is_alive():
- # If there were no attempts to download the share, or all downloads are done, we can stop
- if web.download_count == 0 or web.done:
- print(strings._("close_on_timeout"))
- web.stop(app.port)
- break
+ if mode == 'share':
+ # If there were no attempts to download the share, or all downloads are done, we can stop
+ if web.share_mode.download_count == 0 or web.done:
+ print(strings._("close_on_timeout"))
+ web.stop(app.port)
+ break
+ if mode == 'receive':
+ if web.receive_mode.upload_count == 0 or not web.receive_mode.uploads_in_progress:
+ print(strings._("close_on_timeout"))
+ web.stop(app.port)
+ break
+ else:
+ web.receive_mode.can_upload = False
# Allow KeyboardInterrupt exception to be handled with threads
# https://stackoverflow.com/questions/3788208/python-threading-ignores-keyboardinterrupt-exception
time.sleep(0.2)