onionshare_cli 2.3__tar.gz → 2.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/PKG-INFO +5 -4
  2. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/__init__.py +88 -67
  3. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/common.py +240 -10
  4. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/mode_settings.py +9 -3
  5. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/onion.py +28 -34
  6. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/onionshare.py +3 -23
  7. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/css/style.css +7 -0
  8. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/js/chat.js +10 -1
  9. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/js/receive.js +38 -27
  10. onionshare_cli-2.3.2/onionshare_cli/resources/static/js/socket.io.min.js +7 -0
  11. onionshare_cli-2.3.2/onionshare_cli/resources/templates/500.html +21 -0
  12. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/chat.html +4 -3
  13. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/listing.html +24 -23
  14. onionshare_cli-2.3.2/onionshare_cli/resources/templates/receive.html +66 -0
  15. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/send.html +9 -8
  16. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/thankyou.html +3 -3
  17. onionshare_cli-2.3.2/onionshare_cli/resources/torrc_template-obfs4 +16 -0
  18. onionshare_cli-2.3.2/onionshare_cli/resources/version.txt +1 -0
  19. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/settings.py +8 -14
  20. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/web/__init__.py +1 -1
  21. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/web/chat_mode.py +34 -23
  22. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/web/receive_mode.py +216 -70
  23. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/web/send_base_mode.py +36 -19
  24. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/web/share_mode.py +279 -92
  25. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/web/web.py +87 -32
  26. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/web/website_mode.py +5 -7
  27. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/pyproject.toml +5 -4
  28. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/setup.py +5 -4
  29. onionshare_cli-2.3/onionshare_cli/resources/static/js/socket.io.min.js +0 -3
  30. onionshare_cli-2.3/onionshare_cli/resources/templates/receive.html +0 -46
  31. onionshare_cli-2.3/onionshare_cli/resources/torrc_template-obfs4 +0 -27
  32. onionshare_cli-2.3/onionshare_cli/resources/version.txt +0 -1
  33. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/img/ajax.gif +0 -0
  34. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/img/favicon.ico +0 -0
  35. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/img/logo.png +0 -0
  36. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/img/logo_large.png +0 -0
  37. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/img/web_file.png +0 -0
  38. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/img/web_folder.png +0 -0
  39. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/js/jquery-3.5.1.min.js +0 -0
  40. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/static/js/send.js +0 -0
  41. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/401.html +0 -0
  42. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/403.html +0 -0
  43. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/404.html +0 -0
  44. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/405.html +0 -0
  45. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/templates/denied.html +0 -0
  46. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/torrc_template +0 -0
  47. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/torrc_template-meek_lite_amazon +0 -0
  48. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/torrc_template-meek_lite_azure +0 -0
  49. {onionshare_cli-2.3 → onionshare_cli-2.3.2}/onionshare_cli/resources/wordlist.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: onionshare-cli
3
- Version: 2.3
3
+ Version: 2.3.2
4
4
  Summary: OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable web address so others can download files from you, or upload files to you. It does _not_ require setting up a separate server or using a third party file-sharing service.
5
5
  License: GPLv3+
6
6
  Author: Micah Lee
@@ -20,14 +20,15 @@ Classifier: Programming Language :: Python :: 3.9
20
20
  Classifier: Topic :: Communications :: File Sharing
21
21
  Classifier: Topic :: Security :: Cryptography
22
22
  Requires-Dist: click
23
+ Requires-Dist: colorama (>=0.4.4,<0.5.0)
23
24
  Requires-Dist: eventlet
24
- Requires-Dist: flask
25
+ Requires-Dist: flask (>=1.1.4,<2.0.0)
25
26
  Requires-Dist: flask-httpauth
26
- Requires-Dist: flask-socketio
27
+ Requires-Dist: flask-socketio (==5.0.1)
27
28
  Requires-Dist: psutil
28
29
  Requires-Dist: pycryptodome
29
30
  Requires-Dist: pysocks
30
- Requires-Dist: requests
31
+ Requires-Dist: requests[socks] (>=2.25.1,<3.0.0)
31
32
  Requires-Dist: setuptools
32
33
  Requires-Dist: stem
33
34
  Requires-Dist: unidecode
@@ -2,7 +2,7 @@
2
2
  """
3
3
  OnionShare | https://onionshare.org/
4
4
 
5
- Copyright (C) 2014-2020 Micah Lee, et al. <micah@micahflee.com>
5
+ Copyright (C) 2014-2021 Micah Lee, et al. <micah@micahflee.com>
6
6
 
7
7
  This program is free software: you can redistribute it and/or modify
8
8
  it under the terms of the GNU General Public License as published by
@@ -18,13 +18,22 @@ You should have received a copy of the GNU General Public License
18
18
  along with this program. If not, see <http://www.gnu.org/licenses/>.
19
19
  """
20
20
 
21
- import os, sys, time, argparse, threading
21
+ import os
22
+ import sys
23
+ import time
24
+ import argparse
25
+ import threading
22
26
  from datetime import datetime
23
27
  from datetime import timedelta
24
28
 
25
29
  from .common import Common, CannotFindTor
26
30
  from .web import Web
27
- from .onion import *
31
+ from .onion import (
32
+ TorErrorProtocolError,
33
+ TorTooOldEphemeral,
34
+ TorTooOldStealth,
35
+ Onion,
36
+ )
28
37
  from .onionshare import OnionShare
29
38
  from .mode_settings import ModeSettings
30
39
 
@@ -43,57 +52,7 @@ def main(cwd=None):
43
52
  onionshare uses.
44
53
  """
45
54
  common = Common()
46
-
47
- # Display OnionShare banner
48
- print(f"OnionShare {common.version} | https://onionshare.org/")
49
- reset = "\033[0m"
50
- purple = "\33[95m"
51
- print(purple)
52
- print(" @@@@@@@@@ ")
53
- print(" @@@@@@@@@@@@@@@@@@@ ")
54
- print(" @@@@@@@@@@@@@@@@@@@@@@@@@ ")
55
- print(" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ")
56
- print(
57
- " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ___ _ "
58
- )
59
- print(
60
- " @@@@@@ @@@@@@@@@@@@@ / _ \\ (_) "
61
- )
62
- print(
63
- " @@@@ @ @@@@@@@@@@@ | | | |_ __ _ ___ _ __ "
64
- )
65
- print(
66
- " @@@@@@@@ @@@@@@@@@@ | | | | '_ \\| |/ _ \\| '_ \\ "
67
- )
68
- print(
69
- " @@@@@@@@@@@@ @@@@@@@@@@ \\ \\_/ / | | | | (_) | | | | "
70
- )
71
- print(
72
- " @@@@@@@@@@@@@@@@ @@@@@@@@@ \\___/|_| |_|_|\\___/|_| |_| "
73
- )
74
- print(
75
- " @@@@@@@@@ @@@@@@@@@@@@@@@@ _____ _ "
76
- )
77
- print(
78
- " @@@@@@@@@@ @@@@@@@@@@@@ / ___| | "
79
- )
80
- print(
81
- " @@@@@@@@@@ @@@@@@@@ \\ `--.| |__ __ _ _ __ ___ "
82
- )
83
- print(
84
- " @@@@@@@@@@@ @ @@@@ `--. \\ '_ \\ / _` | '__/ _ \\"
85
- )
86
- print(
87
- " @@@@@@@@@@@@@ @@@@@@ /\\__/ / | | | (_| | | | __/"
88
- )
89
- print(
90
- " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \\____/|_| |_|\\__,_|_| \\___|"
91
- )
92
- print(" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ")
93
- print(" @@@@@@@@@@@@@@@@@@@@@@@@@ ")
94
- print(" @@@@@@@@@@@@@@@@@@@ ")
95
- print(" @@@@@@@@@ ")
96
- print(reset)
55
+ common.display_banner()
97
56
 
98
57
  # OnionShare CLI in OSX needs to change current working directory (#132)
99
58
  if common.platform == "Darwin":
@@ -143,6 +102,12 @@ def main(cwd=None):
143
102
  help="Filename of persistent session",
144
103
  )
145
104
  # General args
105
+ parser.add_argument(
106
+ "--title",
107
+ metavar="TITLE",
108
+ default=None,
109
+ help="Set a title",
110
+ )
146
111
  parser.add_argument(
147
112
  "--public",
148
113
  action="store_true",
@@ -193,6 +158,24 @@ def main(cwd=None):
193
158
  default=None,
194
159
  help="Receive files: Save files received to this directory",
195
160
  )
161
+ parser.add_argument(
162
+ "--webhook-url",
163
+ metavar="webhook_url",
164
+ default=None,
165
+ help="Receive files: URL to receive webhook notifications",
166
+ )
167
+ parser.add_argument(
168
+ "--disable-text",
169
+ action="store_true",
170
+ dest="disable_text",
171
+ help="Receive files: Disable receiving text messages",
172
+ )
173
+ parser.add_argument(
174
+ "--disable-files",
175
+ action="store_true",
176
+ dest="disable_files",
177
+ help="Receive files: Disable receiving files",
178
+ )
196
179
  # Website args
197
180
  parser.add_argument(
198
181
  "--disable_csp",
@@ -228,6 +211,7 @@ def main(cwd=None):
228
211
  connect_timeout = int(args.connect_timeout)
229
212
  config_filename = args.config
230
213
  persistent_filename = args.persistent
214
+ title = args.title
231
215
  public = bool(args.public)
232
216
  autostart_timer = int(args.autostart_timer)
233
217
  autostop_timer = int(args.autostop_timer)
@@ -235,6 +219,9 @@ def main(cwd=None):
235
219
  client_auth = bool(args.client_auth)
236
220
  autostop_sharing = not bool(args.no_autostop_sharing)
237
221
  data_dir = args.data_dir
222
+ webhook_url = args.webhook_url
223
+ disable_text = args.disable_text
224
+ disable_files = args.disable_files
238
225
  disable_csp = bool(args.disable_csp)
239
226
  verbose = bool(args.verbose)
240
227
 
@@ -267,11 +254,13 @@ def main(cwd=None):
267
254
  if persistent_filename:
268
255
  mode_settings = ModeSettings(common, persistent_filename)
269
256
  mode_settings.set("persistent", "enabled", True)
257
+ mode_settings.set("persistent", "mode", mode)
270
258
  else:
271
259
  mode_settings = ModeSettings(common)
272
260
 
273
261
  if mode_settings.just_created:
274
262
  # This means the mode settings were just created, not loaded from disk
263
+ mode_settings.set("general", "title", title)
275
264
  mode_settings.set("general", "public", public)
276
265
  mode_settings.set("general", "autostart_timer", autostart_timer)
277
266
  mode_settings.set("general", "autostop_timer", autostop_timer)
@@ -282,6 +271,10 @@ def main(cwd=None):
282
271
  if mode == "receive":
283
272
  if data_dir:
284
273
  mode_settings.set("receive", "data_dir", data_dir)
274
+ if webhook_url:
275
+ mode_settings.set("receive", "webhook_url", webhook_url)
276
+ mode_settings.set("receive", "disable_text", disable_text)
277
+ mode_settings.set("receive", "disable_files", disable_files)
285
278
  if mode == "website":
286
279
  mode_settings.set("website", "disable_csp", disable_csp)
287
280
  else:
@@ -292,7 +285,11 @@ def main(cwd=None):
292
285
  if mode == "share" or mode == "website":
293
286
  # Unless you passed in a persistent filename, in which case get the filenames from
294
287
  # the mode settings
295
- if persistent_filename and not mode_settings.just_created:
288
+ if (
289
+ persistent_filename
290
+ and not mode_settings.just_created
291
+ and len(filenames) != 0
292
+ ):
296
293
  filenames = mode_settings.get(mode, "filenames")
297
294
 
298
295
  else:
@@ -316,6 +313,15 @@ def main(cwd=None):
316
313
  if not valid:
317
314
  sys.exit()
318
315
 
316
+ # Save the filenames in persistent file
317
+ if persistent_filename:
318
+ mode_settings.set(mode, "filenames", filenames)
319
+
320
+ # In receive mode, you must allows either text, files, or both
321
+ if mode == "receive" and disable_text and disable_files:
322
+ print("You cannot disable both text and files")
323
+ sys.exit()
324
+
319
325
  # Create the Web object
320
326
  web = Web(common, False, mode_settings, mode)
321
327
 
@@ -339,16 +345,29 @@ def main(cwd=None):
339
345
  except KeyboardInterrupt:
340
346
  print("")
341
347
  sys.exit()
342
- except Exception as e:
348
+ except Exception:
343
349
  sys.exit()
344
350
 
345
351
  # Start the onionshare app
346
352
  try:
347
353
  common.settings.load()
348
- if not mode_settings.get("general", "public"):
349
- web.generate_password(mode_settings.get("onion", "password"))
350
- else:
354
+
355
+ if mode_settings.get("general", "public"):
351
356
  web.password = None
357
+ else:
358
+ web.generate_password(mode_settings.get("onion", "password"))
359
+
360
+ # Receive mode needs to know the tor proxy details for webhooks
361
+ if mode == "receive":
362
+ if local_only:
363
+ web.proxies = None
364
+ else:
365
+ (socks_address, socks_port) = onion.get_tor_socks_port()
366
+ web.proxies = {
367
+ "http": f"socks5h://{socks_address}:{socks_port}",
368
+ "https": f"socks5h://{socks_address}:{socks_port}",
369
+ }
370
+
352
371
  app = OnionShare(common, onion, local_only, autostop_timer)
353
372
  app.choose_port()
354
373
 
@@ -361,7 +380,7 @@ def main(cwd=None):
361
380
  )
362
381
  sys.exit()
363
382
 
364
- app.start_onion_service(mode, mode_settings, False, True)
383
+ app.start_onion_service(mode, mode_settings, False)
365
384
  url = build_url(mode_settings, app, web)
366
385
  schedule = datetime.now() + timedelta(seconds=autostart_timer)
367
386
  if mode == "receive":
@@ -370,7 +389,9 @@ def main(cwd=None):
370
389
  )
371
390
  print("")
372
391
  print(
373
- "Warning: Receive mode lets people upload files to your computer. Some files can potentially take control of your computer if you open them. Only open things from people you trust, or if you know what you are doing."
392
+ "Warning: Receive mode lets people upload files to your computer. Some files can potentially take "
393
+ "control of your computer if you open them. Only open things from people you trust, or if you know "
394
+ "what you are doing."
374
395
  )
375
396
  print("")
376
397
  if mode_settings.get("general", "client_auth"):
@@ -403,7 +424,7 @@ def main(cwd=None):
403
424
  except KeyboardInterrupt:
404
425
  print("")
405
426
  sys.exit()
406
- except (TorTooOld, TorErrorProtocolError) as e:
427
+ except (TorTooOldEphemeral, TorTooOldStealth, TorErrorProtocolError) as e:
407
428
  print("")
408
429
  print(e.args[0])
409
430
  sys.exit()
@@ -421,7 +442,6 @@ def main(cwd=None):
421
442
  print("Compressing files.")
422
443
  try:
423
444
  web.share_mode.set_file_info(filenames)
424
- app.cleanup_filenames += web.share_mode.cleanup_filenames
425
445
  except OSError as e:
426
446
  print(e.strerror)
427
447
  sys.exit(1)
@@ -464,7 +484,9 @@ def main(cwd=None):
464
484
  )
465
485
  print("")
466
486
  print(
467
- "Warning: Receive mode lets people upload files to your computer. Some files can potentially take control of your computer if you open them. Only open things from people you trust, or if you know what you are doing."
487
+ "Warning: Receive mode lets people upload files to your computer. Some files can potentially take "
488
+ "control of your computer if you open them. Only open things from people you trust, or if you know "
489
+ "what you are doing."
468
490
  )
469
491
  print("")
470
492
 
@@ -505,8 +527,7 @@ def main(cwd=None):
505
527
  print("Stopped because auto-stop timer ran out")
506
528
  web.stop(app.port)
507
529
  break
508
- else:
509
- web.receive_mode.can_upload = False
530
+ web.receive_mode.can_upload = False
510
531
  # Allow KeyboardInterrupt exception to be handled with threads
511
532
  # https://stackoverflow.com/questions/3788208/python-threading-ignores-keyboardinterrupt-exception
512
533
  time.sleep(0.2)
@@ -514,7 +535,7 @@ def main(cwd=None):
514
535
  web.stop(app.port)
515
536
  finally:
516
537
  # Shutdown
517
- app.cleanup()
538
+ web.cleanup()
518
539
  onion.cleanup()
519
540
 
520
541
 
@@ -2,7 +2,7 @@
2
2
  """
3
3
  OnionShare | https://onionshare.org/
4
4
 
5
- Copyright (C) 2014-2020 Micah Lee, et al. <micah@micahflee.com>
5
+ Copyright (C) 2014-2021 Micah Lee, et al. <micah@micahflee.com>
6
6
 
7
7
  This program is free software: you can redistribute it and/or modify
8
8
  it under the terms of the GNU General Public License as published by
@@ -19,18 +19,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
19
19
  """
20
20
  import base64
21
21
  import hashlib
22
- import inspect
23
22
  import os
24
23
  import platform
25
24
  import random
26
25
  import socket
27
26
  import sys
28
- import tempfile
29
27
  import threading
30
28
  import time
31
29
  import shutil
32
30
  from pkg_resources import resource_filename
33
31
 
32
+ import colorama
33
+ from colorama import Fore, Back, Style
34
+
34
35
  from .settings import Settings
35
36
 
36
37
 
@@ -48,6 +49,8 @@ class Common:
48
49
  def __init__(self, verbose=False):
49
50
  self.verbose = verbose
50
51
 
52
+ colorama.init(autoreset=True)
53
+
51
54
  # The platform OnionShare is running on
52
55
  self.platform = platform.system()
53
56
  if self.platform.endswith("BSD") or self.platform == "DragonFly":
@@ -57,6 +60,224 @@ class Common:
57
60
  with open(self.get_resource_path("version.txt")) as f:
58
61
  self.version = f.read().strip()
59
62
 
63
+ def display_banner(self):
64
+ """
65
+ Raw ASCII art example:
66
+ ╭───────────────────────────────────────────╮
67
+ │ * ▄▄█████▄▄ * │
68
+ │ ▄████▀▀▀████▄ * │
69
+ │ ▀▀█▀ ▀██▄ │
70
+ │ * ▄█▄ ▀██▄ │
71
+ │ ▄█████▄ ███ -+- │
72
+ │ ███ ▀█████▀ │
73
+ │ ▀██▄ ▀█▀ │
74
+ │ * ▀██▄ ▄█▄▄ * │
75
+ │ * ▀████▄▄▄████▀ │
76
+ │ ▀▀█████▀▀ │
77
+ │ -+- * │
78
+ │ ▄▀▄ ▄▀▀ █ │
79
+ │ █ █ ▀ ▀▄ █ │
80
+ │ █ █ █▀▄ █ ▄▀▄ █▀▄ ▀▄ █▀▄ ▄▀▄ █▄▀ ▄█▄ │
81
+ │ ▀▄▀ █ █ █ ▀▄▀ █ █ ▄▄▀ █ █ ▀▄█ █ ▀▄▄ │
82
+ │ │
83
+ │ v2.3.1 │
84
+ │ │
85
+ │ https://onionshare.org/ │
86
+ ╰───────────────────────────────────────────╯
87
+ """
88
+
89
+ if self.platform == "Windows":
90
+ pass
91
+ else:
92
+ pass
93
+
94
+ print(
95
+ Back.MAGENTA + Fore.WHITE + "╭───────────────────────────────────────────╮"
96
+ )
97
+ print(
98
+ Back.MAGENTA
99
+ + Fore.WHITE
100
+ + "│"
101
+ + Fore.LIGHTMAGENTA_EX
102
+ + " * "
103
+ + Fore.WHITE
104
+ + "▄▄█████▄▄"
105
+ + Fore.LIGHTMAGENTA_EX
106
+ + " * "
107
+ + Fore.WHITE
108
+ + "│"
109
+ )
110
+ print(
111
+ Back.MAGENTA
112
+ + Fore.WHITE
113
+ + "│"
114
+ + Fore.WHITE
115
+ + " ▄████▀▀▀████▄"
116
+ + Fore.LIGHTMAGENTA_EX
117
+ + " * "
118
+ + Fore.WHITE
119
+ + "│"
120
+ )
121
+ print(
122
+ Back.MAGENTA
123
+ + Fore.WHITE
124
+ + "│"
125
+ + Fore.WHITE
126
+ + " ▀▀█▀ ▀██▄ "
127
+ + Fore.WHITE
128
+ + "│"
129
+ )
130
+ print(
131
+ Back.MAGENTA
132
+ + Fore.WHITE
133
+ + "│"
134
+ + Fore.LIGHTMAGENTA_EX
135
+ + " * "
136
+ + Fore.WHITE
137
+ + "▄█▄ ▀██▄ "
138
+ + Fore.WHITE
139
+ + "│"
140
+ )
141
+ print(
142
+ Back.MAGENTA
143
+ + Fore.WHITE
144
+ + "│"
145
+ + Fore.WHITE
146
+ + " ▄█████▄ ███"
147
+ + Fore.LIGHTMAGENTA_EX
148
+ + " -+- "
149
+ + Fore.WHITE
150
+ + "│"
151
+ )
152
+ print(
153
+ Back.MAGENTA
154
+ + Fore.WHITE
155
+ + "│"
156
+ + Fore.WHITE
157
+ + " ███ ▀█████▀ "
158
+ + Fore.WHITE
159
+ + "│"
160
+ )
161
+ print(
162
+ Back.MAGENTA
163
+ + Fore.WHITE
164
+ + "│"
165
+ + Fore.WHITE
166
+ + " ▀██▄ ▀█▀ "
167
+ + Fore.WHITE
168
+ + "│"
169
+ )
170
+ print(
171
+ Back.MAGENTA
172
+ + Fore.WHITE
173
+ + "│"
174
+ + Fore.LIGHTMAGENTA_EX
175
+ + " * "
176
+ + Fore.WHITE
177
+ + "▀██▄ ▄█▄▄"
178
+ + Fore.LIGHTMAGENTA_EX
179
+ + " * "
180
+ + Fore.WHITE
181
+ + "│"
182
+ )
183
+ print(
184
+ Back.MAGENTA
185
+ + Fore.WHITE
186
+ + "│"
187
+ + Fore.LIGHTMAGENTA_EX
188
+ + " * "
189
+ + Fore.WHITE
190
+ + "▀████▄▄▄████▀ "
191
+ + Fore.WHITE
192
+ + "│"
193
+ )
194
+ print(
195
+ Back.MAGENTA
196
+ + Fore.WHITE
197
+ + "│"
198
+ + Fore.WHITE
199
+ + " ▀▀█████▀▀ "
200
+ + Fore.WHITE
201
+ + "│"
202
+ )
203
+ print(
204
+ Back.MAGENTA
205
+ + Fore.WHITE
206
+ + "│"
207
+ + Fore.LIGHTMAGENTA_EX
208
+ + " -+- * "
209
+ + Fore.WHITE
210
+ + "│"
211
+ )
212
+ print(
213
+ Back.MAGENTA
214
+ + Fore.WHITE
215
+ + "│"
216
+ + Fore.WHITE
217
+ + " ▄▀▄ ▄▀▀ █ "
218
+ + Fore.WHITE
219
+ + "│"
220
+ )
221
+ print(
222
+ Back.MAGENTA
223
+ + Fore.WHITE
224
+ + "│"
225
+ + Fore.WHITE
226
+ + " █ █ ▀ ▀▄ █ "
227
+ + Fore.WHITE
228
+ + "│"
229
+ )
230
+ print(
231
+ Back.MAGENTA
232
+ + Fore.WHITE
233
+ + "│"
234
+ + Fore.WHITE
235
+ + " █ █ █▀▄ █ ▄▀▄ █▀▄ ▀▄ █▀▄ ▄▀▄ █▄▀ ▄█▄ "
236
+ + Fore.WHITE
237
+ + "│"
238
+ )
239
+ print(
240
+ Back.MAGENTA
241
+ + Fore.WHITE
242
+ + "│"
243
+ + Fore.WHITE
244
+ + " ▀▄▀ █ █ █ ▀▄▀ █ █ ▄▄▀ █ █ ▀▄█ █ ▀▄▄ "
245
+ + Fore.WHITE
246
+ + "│"
247
+ )
248
+ print(
249
+ Back.MAGENTA + Fore.WHITE + "│ │"
250
+ )
251
+ left_spaces = (43 - len(self.version) - 1) // 2
252
+ right_spaces = left_spaces
253
+ if left_spaces + len(self.version) + 1 + right_spaces < 43:
254
+ right_spaces += 1
255
+ print(
256
+ Back.MAGENTA
257
+ + Fore.WHITE
258
+ + "│"
259
+ + Fore.WHITE
260
+ + f"{' '*left_spaces}v{self.version}{' '*right_spaces}"
261
+ + Fore.WHITE
262
+ + "│"
263
+ )
264
+ print(
265
+ Back.MAGENTA + Fore.WHITE + "│ │"
266
+ )
267
+ print(
268
+ Back.MAGENTA
269
+ + Fore.WHITE
270
+ + "│"
271
+ + Fore.WHITE
272
+ + " https://onionshare.org/ "
273
+ + Fore.WHITE
274
+ + "│"
275
+ )
276
+ print(
277
+ Back.MAGENTA + Fore.WHITE + "╰───────────────────────────────────────────╯"
278
+ )
279
+ print()
280
+
60
281
  def load_settings(self, config=None):
61
282
  """
62
283
  Loading settings, optionally from a custom config json file.
@@ -70,10 +291,11 @@ class Common:
70
291
  """
71
292
  if self.verbose:
72
293
  timestamp = time.strftime("%b %d %Y %X")
73
-
74
- final_msg = f"[{timestamp}] {module}.{func}"
294
+ final_msg = f"{Fore.LIGHTBLACK_EX + Style.DIM}[{timestamp}]{Style.RESET_ALL} {Fore.WHITE + Style.DIM}{module}.{func}{Style.RESET_ALL}"
75
295
  if msg:
76
- final_msg = f"{final_msg}: {msg}"
296
+ final_msg = (
297
+ f"{final_msg}{Fore.WHITE + Style.DIM}: {msg}{Style.RESET_ALL}"
298
+ )
77
299
  print(final_msg)
78
300
 
79
301
  def get_resource_path(self, filename):
@@ -129,16 +351,24 @@ class Common:
129
351
  try:
130
352
  appdata = os.environ["APPDATA"]
131
353
  onionshare_data_dir = f"{appdata}\\OnionShare"
132
- except:
354
+ except Exception:
133
355
  # If for some reason we don't have the 'APPDATA' environment variable
134
356
  # (like running tests in Linux while pretending to be in Windows)
135
- onionshare_data_dir = os.path.expanduser("~/.config/onionshare")
357
+ try:
358
+ xdg_config_home = os.environ["XDG_CONFIG_HOME"]
359
+ onionshare_data_dir = f"{xdg_config_home}/onionshare"
360
+ except Exception:
361
+ onionshare_data_dir = os.path.expanduser("~/.config/onionshare")
136
362
  elif self.platform == "Darwin":
137
363
  onionshare_data_dir = os.path.expanduser(
138
364
  "~/Library/Application Support/OnionShare"
139
365
  )
140
366
  else:
141
- onionshare_data_dir = os.path.expanduser("~/.config/onionshare")
367
+ try:
368
+ xdg_config_home = os.environ["XDG_CONFIG_HOME"]
369
+ onionshare_data_dir = f"{xdg_config_home}/onionshare"
370
+ except Exception:
371
+ onionshare_data_dir = os.path.expanduser("~/.config/onionshare")
142
372
 
143
373
  # Modify the data dir if running tests
144
374
  if getattr(sys, "onionshare_test_mode", False):
@@ -256,7 +486,7 @@ class Common:
256
486
  try:
257
487
  tmpsock.bind(("127.0.0.1", random.randint(min_port, max_port)))
258
488
  break
259
- except OSError as e:
489
+ except OSError:
260
490
  pass
261
491
  _, port = tmpsock.getsockname()
262
492
  return port
@@ -2,7 +2,7 @@
2
2
  """
3
3
  OnionShare | https://onionshare.org/
4
4
 
5
- Copyright (C) 2014-2020 Micah Lee, et al. <micah@micahflee.com>
5
+ Copyright (C) 2014-2021 Micah Lee, et al. <micah@micahflee.com>
6
6
 
7
7
  This program is free software: you can redistribute it and/or modify
8
8
  it under the terms of the GNU General Public License as published by
@@ -42,6 +42,7 @@ class ModeSettings:
42
42
  },
43
43
  "persistent": {"mode": None, "enabled": False},
44
44
  "general": {
45
+ "title": None,
45
46
  "public": False,
46
47
  "autostart_timer": False,
47
48
  "autostop_timer": False,
@@ -50,7 +51,12 @@ class ModeSettings:
50
51
  "service_id": None,
51
52
  },
52
53
  "share": {"autostop_sharing": True, "filenames": []},
53
- "receive": {"data_dir": self.build_default_receive_data_dir()},
54
+ "receive": {
55
+ "data_dir": self.build_default_receive_data_dir(),
56
+ "webhook_url": None,
57
+ "disable_text": False,
58
+ "disable_files": False,
59
+ },
54
60
  "website": {"disable_csp": False, "filenames": []},
55
61
  "chat": {"room": "default"},
56
62
  }
@@ -123,7 +129,7 @@ class ModeSettings:
123
129
  self.fill_in_defaults()
124
130
  self.common.log("ModeSettings", "load", f"loaded {self.filename}")
125
131
  return
126
- except:
132
+ except Exception:
127
133
  pass
128
134
 
129
135
  # If loading settings didn't work, create the settings file