summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicah Lee <micah@micahflee.com>2021-04-29 16:58:33 -0700
committerMicah Lee <micah@micahflee.com>2021-04-29 16:58:33 -0700
commit343e1be3d08e0725815e1a2d6bf7c4717c8c26b5 (patch)
treeebd1f298e31535d79e306682dd318cdb5de4a54d
parent0de27f9775cf5231e0d7bdf5a2b388e5d1b7ee52 (diff)
parent34554414e9ff6d98988e4ab27a6d79300e8e1197 (diff)
downloadonionshare-343e1be3d08e0725815e1a2d6bf7c4717c8c26b5.tar.gz
onionshare-343e1be3d08e0725815e1a2d6bf7c4717c8c26b5.zip
Merge branch 'develop' into 1305_receive_messages
-rw-r--r--cli/onionshare_cli/__init__.py60
-rw-r--r--cli/onionshare_cli/common.py263
-rw-r--r--cli/onionshare_cli/mode_settings.py1
-rw-r--r--cli/onionshare_cli/resources/templates/chat.html4
-rw-r--r--cli/onionshare_cli/resources/templates/listing.html6
-rw-r--r--cli/onionshare_cli/resources/templates/receive.html4
-rw-r--r--cli/onionshare_cli/resources/templates/send.html17
-rw-r--r--cli/onionshare_cli/resources/templates/thankyou.html6
-rw-r--r--cli/onionshare_cli/web/chat_mode.py8
-rw-r--r--cli/onionshare_cli/web/receive_mode.py3
-rw-r--r--cli/onionshare_cli/web/share_mode.py1
-rw-r--r--cli/onionshare_cli/web/web.py2
-rw-r--r--cli/onionshare_cli/web/website_mode.py1
-rw-r--r--desktop/src/onionshare/__init__.py4
-rw-r--r--desktop/src/onionshare/resources/locale/en.json1
-rw-r--r--desktop/src/onionshare/tab/mode/chat_mode/__init__.py5
-rw-r--r--desktop/src/onionshare/tab/mode/mode_settings_widget.py38
-rw-r--r--desktop/src/onionshare/tab/mode/receive_mode/__init__.py5
-rw-r--r--desktop/src/onionshare/tab/mode/share_mode/__init__.py5
-rw-r--r--desktop/src/onionshare/tab/mode/website_mode/__init__.py5
-rw-r--r--desktop/src/onionshare/tab_widget.py12
21 files changed, 367 insertions, 84 deletions
diff --git a/cli/onionshare_cli/__init__.py b/cli/onionshare_cli/__init__.py
index 0a7a1d3c..cea445a9 100644
--- a/cli/onionshare_cli/__init__.py
+++ b/cli/onionshare_cli/__init__.py
@@ -43,57 +43,7 @@ def main(cwd=None):
onionshare uses.
"""
common = Common()
-
- # Display OnionShare banner
- print(f"OnionShare {common.version} | https://onionshare.org/")
- reset = "\033[0m"
- purple = "\33[95m"
- print(purple)
- print(" @@@@@@@@@ ")
- print(" @@@@@@@@@@@@@@@@@@@ ")
- print(" @@@@@@@@@@@@@@@@@@@@@@@@@ ")
- print(" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ")
- print(
- " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ___ _ "
- )
- print(
- " @@@@@@ @@@@@@@@@@@@@ / _ \\ (_) "
- )
- print(
- " @@@@ @ @@@@@@@@@@@ | | | |_ __ _ ___ _ __ "
- )
- print(
- " @@@@@@@@ @@@@@@@@@@ | | | | '_ \\| |/ _ \\| '_ \\ "
- )
- print(
- " @@@@@@@@@@@@ @@@@@@@@@@ \\ \\_/ / | | | | (_) | | | | "
- )
- print(
- " @@@@@@@@@@@@@@@@ @@@@@@@@@ \\___/|_| |_|_|\\___/|_| |_| "
- )
- print(
- " @@@@@@@@@ @@@@@@@@@@@@@@@@ _____ _ "
- )
- print(
- " @@@@@@@@@@ @@@@@@@@@@@@ / ___| | "
- )
- print(
- " @@@@@@@@@@ @@@@@@@@ \\ `--.| |__ __ _ _ __ ___ "
- )
- print(
- " @@@@@@@@@@@ @ @@@@ `--. \\ '_ \\ / _` | '__/ _ \\"
- )
- print(
- " @@@@@@@@@@@@@ @@@@@@ /\\__/ / | | | (_| | | | __/"
- )
- print(
- " @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \\____/|_| |_|\\__,_|_| \\___|"
- )
- print(" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ")
- print(" @@@@@@@@@@@@@@@@@@@@@@@@@ ")
- print(" @@@@@@@@@@@@@@@@@@@ ")
- print(" @@@@@@@@@ ")
- print(reset)
+ common.display_banner()
# OnionShare CLI in OSX needs to change current working directory (#132)
if common.platform == "Darwin":
@@ -144,6 +94,12 @@ def main(cwd=None):
)
# General args
parser.add_argument(
+ "--title",
+ metavar="TITLE",
+ default=None,
+ help="Set a title",
+ )
+ parser.add_argument(
"--public",
action="store_true",
dest="public",
@@ -246,6 +202,7 @@ def main(cwd=None):
connect_timeout = int(args.connect_timeout)
config_filename = args.config
persistent_filename = args.persistent
+ title = args.title
public = bool(args.public)
autostart_timer = int(args.autostart_timer)
autostop_timer = int(args.autostop_timer)
@@ -294,6 +251,7 @@ def main(cwd=None):
if mode_settings.just_created:
# This means the mode settings were just created, not loaded from disk
+ mode_settings.set("general", "title", title)
mode_settings.set("general", "public", public)
mode_settings.set("general", "autostart_timer", autostart_timer)
mode_settings.set("general", "autostop_timer", autostop_timer)
diff --git a/cli/onionshare_cli/common.py b/cli/onionshare_cli/common.py
index e812aa98..0b0d084f 100644
--- a/cli/onionshare_cli/common.py
+++ b/cli/onionshare_cli/common.py
@@ -44,8 +44,13 @@ class Common:
"""
C_RESET = "\033[0m"
+ C_BG_PURPLE = "\033[45m"
+ C_BOLD = "\033[01m"
+ C_WHITE = "\033[97m"
C_LIGHTGRAY = "\033[37m"
C_DARKGRAY = "\033[90m"
+ C_LIGHTPURPLE = "\033[95m"
+ C_DARKPURPLE = "\033[35m"
def __init__(self, verbose=False):
self.verbose = verbose
@@ -59,6 +64,248 @@ class Common:
with open(self.get_resource_path("version.txt")) as f:
self.version = f.read().strip()
+ def display_banner(self):
+ """
+ Raw ASCII art example:
+ ╭───────────────────────────────────────────╮
+ │ * ▄▄█████▄▄ * │
+ │ ▄████▀▀▀████▄ * │
+ │ ▀▀█▀ ▀██▄ │
+ │ * ▄█▄ ▀██▄ │
+ │ ▄█████▄ ███ -+- │
+ │ ███ ▀█████▀ │
+ │ ▀██▄ ▀█▀ │
+ │ * ▀██▄ ▄█▄▄ * │
+ │ * ▀████▄▄▄████▀ │
+ │ ▀▀█████▀▀ │
+ │ -+- * │
+ │ ▄▀▄ ▄▀▀ █ │
+ │ █ █ ▀ ▀▄ █ │
+ │ █ █ █▀▄ █ ▄▀▄ █▀▄ ▀▄ █▀▄ ▄▀▄ █▄▀ ▄█▄ │
+ │ ▀▄▀ █ █ █ ▀▄▀ █ █ ▄▄▀ █ █ ▀▄█ █ ▀▄▄ │
+ │ │
+ │ v2.3.1 │
+ │ │
+ │ https://onionshare.org/ │
+ ╰───────────────────────────────────────────╯
+ """
+
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "╭───────────────────────────────────────────╮"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_LIGHTPURPLE
+ + " * "
+ + self.C_WHITE
+ + "▄▄█████▄▄"
+ + self.C_LIGHTPURPLE
+ + " * "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " ▄████▀▀▀████▄"
+ + self.C_LIGHTPURPLE
+ + " * "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " ▀▀█▀ ▀██▄ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_LIGHTPURPLE
+ + " * "
+ + self.C_WHITE
+ + "▄█▄ ▀██▄ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " ▄█████▄ ███"
+ + self.C_LIGHTPURPLE
+ + " -+- "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " ███ ▀█████▀ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " ▀██▄ ▀█▀ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_LIGHTPURPLE
+ + " * "
+ + self.C_WHITE
+ + "▀██▄ ▄█▄▄"
+ + self.C_LIGHTPURPLE
+ + " * "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_LIGHTPURPLE
+ + " * "
+ + self.C_WHITE
+ + "▀████▄▄▄████▀ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " ▀▀█████▀▀ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_LIGHTPURPLE
+ + " -+- * "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " ▄▀▄ ▄▀▀ █ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " █ █ ▀ ▀▄ █ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " █ █ █▀▄ █ ▄▀▄ █▀▄ ▀▄ █▀▄ ▄▀▄ █▄▀ ▄█▄ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_WHITE
+ + " ▀▄▀ █ █ █ ▀▄▀ █ █ ▄▄▀ █ █ ▀▄█ █ ▀▄▄ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│ │"
+ + self.C_RESET
+ )
+ left_spaces = (43 - len(self.version) - 1) // 2
+ right_spaces = left_spaces
+ if left_spaces + len(self.version) + right_spaces < 43:
+ right_spaces += 1
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_LIGHTGRAY
+ + f"{' '*left_spaces}v{self.version}{' '*right_spaces}"
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│ │"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_LIGHTGRAY
+ + " https://onionshare.org/ "
+ + self.C_LIGHTGRAY
+ + "│"
+ + self.C_RESET
+ )
+ print(
+ self.C_BG_PURPLE
+ + self.C_LIGHTGRAY
+ + "╰───────────────────────────────────────────╯"
+ + self.C_RESET
+ )
+ print()
+
def load_settings(self, config=None):
"""
Loading settings, optionally from a custom config json file.
@@ -130,16 +377,24 @@ class Common:
try:
appdata = os.environ["APPDATA"]
onionshare_data_dir = f"{appdata}\\OnionShare"
- except:
+ except Exception:
# If for some reason we don't have the 'APPDATA' environment variable
# (like running tests in Linux while pretending to be in Windows)
- onionshare_data_dir = os.path.expanduser("~/.config/onionshare")
+ try:
+ xdg_config_home = os.environ["XDG_CONFIG_HOME"]
+ onionshare_data_dir = f"{xdg_config_home}/onionshare"
+ except:
+ onionshare_data_dir = os.path.expanduser("~/.config/onionshare")
elif self.platform == "Darwin":
onionshare_data_dir = os.path.expanduser(
"~/Library/Application Support/OnionShare"
)
else:
- onionshare_data_dir = os.path.expanduser("~/.config/onionshare")
+ try:
+ xdg_config_home = os.environ["XDG_CONFIG_HOME"]
+ onionshare_data_dir = f"{xdg_config_home}/onionshare"
+ except:
+ onionshare_data_dir = os.path.expanduser("~/.config/onionshare")
# Modify the data dir if running tests
if getattr(sys, "onionshare_test_mode", False):
@@ -257,7 +512,7 @@ class Common:
try:
tmpsock.bind(("127.0.0.1", random.randint(min_port, max_port)))
break
- except OSError as e:
+ except OSError:
pass
_, port = tmpsock.getsockname()
return port
diff --git a/cli/onionshare_cli/mode_settings.py b/cli/onionshare_cli/mode_settings.py
index 7b545623..25d4e837 100644
--- a/cli/onionshare_cli/mode_settings.py
+++ b/cli/onionshare_cli/mode_settings.py
@@ -42,6 +42,7 @@ class ModeSettings:
},
"persistent": {"mode": None, "enabled": False},
"general": {
+ "title": None,
"public": False,
"autostart_timer": False,
"autostop_timer": False,
diff --git a/cli/onionshare_cli/resources/templates/chat.html b/cli/onionshare_cli/resources/templates/chat.html
index b4443c09..7156d58c 100644
--- a/cli/onionshare_cli/resources/templates/chat.html
+++ b/cli/onionshare_cli/resources/templates/chat.html
@@ -2,7 +2,7 @@
<html>
<head>
- <title>OnionShare</title>
+ <title>{% if title %}{{ title }}{% else %}OnionShare Chat{% endif %}</title>
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head>
@@ -11,7 +11,7 @@
<header class="clearfix">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
- <h1>OnionShare</h1>
+ <h1>{% if title %}{{ title }}{% else %}OnionShare Chat{% endif %}</h1>
</header>
<noscript>
<p>
diff --git a/cli/onionshare_cli/resources/templates/listing.html b/cli/onionshare_cli/resources/templates/listing.html
index 8458bb87..8e0dedf7 100644
--- a/cli/onionshare_cli/resources/templates/listing.html
+++ b/cli/onionshare_cli/resources/templates/listing.html
@@ -2,7 +2,7 @@
<html>
<head>
- <title>OnionShare</title>
+ <title>{% if title %}{{ title }}{% else %}OnionShare{% endif %}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon" />
@@ -14,7 +14,7 @@
<header class="d-flex">
<div class="logo-container">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
- <h1>OnionShare</h1>
+ <h1>{% if title %}{{ title }}{% else %}OnionShare{% endif %}</h1>
</div>
</header>
@@ -57,4 +57,4 @@
</div>
</body>
-</html>
+</html> \ No newline at end of file
diff --git a/cli/onionshare_cli/resources/templates/receive.html b/cli/onionshare_cli/resources/templates/receive.html
index 507ebea6..c28813ea 100644
--- a/cli/onionshare_cli/resources/templates/receive.html
+++ b/cli/onionshare_cli/resources/templates/receive.html
@@ -2,7 +2,7 @@
<html>
<head>
- <title>OnionShare</title>
+ <title>{% if title %}{{ title }}{% else %}OnionShare Dropbox{% endif %}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
@@ -13,7 +13,7 @@
<header class="clearfix">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
- <h1>OnionShare</h1>
+ <h1>{% if title %}{{ title }}{% else %}OnionShare Dropbox{% endif %}</h1>
</header>
<div class="upload-wrapper">
diff --git a/cli/onionshare_cli/resources/templates/send.html b/cli/onionshare_cli/resources/templates/send.html
index dd30bfdd..bd9bd631 100644
--- a/cli/onionshare_cli/resources/templates/send.html
+++ b/cli/onionshare_cli/resources/templates/send.html
@@ -2,9 +2,9 @@
<html>
<head>
- <title>OnionShare</title>
+ <title>{% if title %}{{ title }}{% else %}OnionShare{% endif %}</title>
<meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
<meta name="onionshare-filename" content="{{ filename }}">
@@ -16,7 +16,7 @@
<header class="d-flex">
<div class="logo-container">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
- <h1>OnionShare</h1>
+ <h1>{% if title %}{{ title }}{% else %}OnionShare{% endif %}</h1>
</div>
<div class="information d-flex">
<div>Total size: <strong>{{ filesize_human }}</strong> {% if is_zipped %} (compressed){% endif %}</div>
@@ -25,10 +25,11 @@
</header>
{% if breadcrumbs %}
- <ul class="breadcrumbs">
- {% for breadcrumb in breadcrumbs %}<li><a href="{{ breadcrumb[1] }}">{{ breadcrumb[0] }}</a> <span class="sep">&#8227;</span></li>{% endfor %}<li>{{ breadcrumbs_leaf }}</li>
- </ul>
- {% endif %}
+ <ul class="breadcrumbs">
+ {% for breadcrumb in breadcrumbs %}<li><a href="{{ breadcrumb[1] }}">{{ breadcrumb[0] }}</a> <span
+ class="sep">&#8227;</span></li>{% endfor %}<li>{{ breadcrumbs_leaf }}</li>
+ </ul>
+ {% endif %}
<div class="file-list" id="file-list">
<div class="d-flex">
@@ -66,4 +67,4 @@
<script async src="{{ static_url_path }}/js/send.js" charset="utf-8"></script>
</body>
-</html>
+</html> \ No newline at end of file
diff --git a/cli/onionshare_cli/resources/templates/thankyou.html b/cli/onionshare_cli/resources/templates/thankyou.html
index aa0bc553..8e92386d 100644
--- a/cli/onionshare_cli/resources/templates/thankyou.html
+++ b/cli/onionshare_cli/resources/templates/thankyou.html
@@ -4,7 +4,7 @@
<head>
<title>OnionShare is closed</title>
<meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head>
@@ -12,7 +12,7 @@
<body>
<header class="clearfix">
<img class="logo" src="{{ static_url_path }}/img/logo.png" title="OnionShare">
- <h1>OnionShare</h1>
+ <h1>{% if title %}{{ title }}{% else %}OnionShare{% endif %}</h1>
</header>
<div class="info-wrapper">
@@ -24,4 +24,4 @@
</div>
</body>
-</html>
+</html> \ No newline at end of file
diff --git a/cli/onionshare_cli/web/chat_mode.py b/cli/onionshare_cli/web/chat_mode.py
index 2daf9654..8b2a5673 100644
--- a/cli/onionshare_cli/web/chat_mode.py
+++ b/cli/onionshare_cli/web/chat_mode.py
@@ -18,12 +18,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
-from flask import (
- request,
- render_template,
- make_response,
- jsonify,
- session)
+from flask import request, render_template, make_response, jsonify, session
from flask_socketio import emit, join_room, leave_room
@@ -72,6 +67,7 @@ class ChatModeWeb:
"chat.html",
static_url_path=self.web.static_url_path,
username=session.get("name"),
+ title=self.web.settings.get("general", "title"),
)
)
return self.web.add_security_headers(r)
diff --git a/cli/onionshare_cli/web/receive_mode.py b/cli/onionshare_cli/web/receive_mode.py
index 7d2f0d7d..c3729a0f 100644
--- a/cli/onionshare_cli/web/receive_mode.py
+++ b/cli/onionshare_cli/web/receive_mode.py
@@ -79,6 +79,7 @@ class ReceiveModeWeb:
static_url_path=self.web.static_url_path,
disable_text=self.web.settings.get("receive", "disable_text"),
disable_files=self.web.settings.get("receive", "disable_files"),
+ title=self.web.settings.get("general", "title"),
)
)
return self.web.add_security_headers(r)
@@ -234,6 +235,7 @@ class ReceiveModeWeb:
"new_body": render_template(
"thankyou.html",
static_url_path=self.web.static_url_path,
+ title=self.web.settings.get("general", "title"),
)
}
)
@@ -242,6 +244,7 @@ class ReceiveModeWeb:
r = make_response(
render_template("thankyou.html"),
static_url_path=self.web.static_url_path,
+ title=self.web.settings.get("general", "title"),
)
return self.web.add_security_headers(r)
diff --git a/cli/onionshare_cli/web/share_mode.py b/cli/onionshare_cli/web/share_mode.py
index ad5825a2..b0b096ca 100644
--- a/cli/onionshare_cli/web/share_mode.py
+++ b/cli/onionshare_cli/web/share_mode.py
@@ -390,6 +390,7 @@ class ShareModeWeb(SendBaseModeWeb):
is_zipped=self.is_zipped,
static_url_path=self.web.static_url_path,
download_individual_files=self.download_individual_files,
+ title=self.web.settings.get("general", "title"),
)
)
diff --git a/cli/onionshare_cli/web/web.py b/cli/onionshare_cli/web/web.py
index ab47195c..7c2e4256 100644
--- a/cli/onionshare_cli/web/web.py
+++ b/cli/onionshare_cli/web/web.py
@@ -310,7 +310,7 @@ class Web:
if not self.settings.get("website", "disable_csp") or self.mode != "website":
r.headers.set(
"Content-Security-Policy",
- "default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:;",
+ "default-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; img-src 'self' data:;",
)
return r
diff --git a/cli/onionshare_cli/web/website_mode.py b/cli/onionshare_cli/web/website_mode.py
index 5718c9a9..6badd399 100644
--- a/cli/onionshare_cli/web/website_mode.py
+++ b/cli/onionshare_cli/web/website_mode.py
@@ -60,6 +60,7 @@ class WebsiteModeWeb(SendBaseModeWeb):
breadcrumbs=breadcrumbs,
breadcrumbs_leaf=breadcrumbs_leaf,
static_url_path=self.web.static_url_path,
+ title=self.web.settings.get("general", "title"),
)
)
diff --git a/desktop/src/onionshare/__init__.py b/desktop/src/onionshare/__init__.py
index 744f6979..1c69ffa5 100644
--- a/desktop/src/onionshare/__init__.py
+++ b/desktop/src/onionshare/__init__.py
@@ -75,14 +75,12 @@ def main():
The main() function implements all of the logic that the GUI version of onionshare uses.
"""
common = Common()
+ common.display_banner()
# Required for macOS Big Sur: https://stackoverflow.com/a/64878899
if common.platform == "Darwin":
os.environ["QT_MAC_WANTS_LAYER"] = "1"
- # Display OnionShare banner
- print(f"OnionShare {common.version} | https://onionshare.org/")
-
# Start the Qt app
global qtapp
qtapp = Application(common)
diff --git a/desktop/src/onionshare/resources/locale/en.json b/desktop/src/onionshare/resources/locale/en.json
index 55e39d73..cbd898dc 100644
--- a/desktop/src/onionshare/resources/locale/en.json
+++ b/desktop/src/onionshare/resources/locale/en.json
@@ -165,6 +165,7 @@
"gui_quit_warning_cancel": "Cancel",
"mode_settings_advanced_toggle_show": "Show advanced settings",
"mode_settings_advanced_toggle_hide": "Hide advanced settings",
+ "mode_settings_title_label": "Custom title",
"mode_settings_persistent_checkbox": "Save this tab, and automatically open it when I open OnionShare",
"mode_settings_public_checkbox": "Don't use a password",
"mode_settings_autostart_timer_checkbox": "Start onion service at scheduled time",
diff --git a/desktop/src/onionshare/tab/mode/chat_mode/__init__.py b/desktop/src/onionshare/tab/mode/chat_mode/__init__.py
index 2312a64e..44a6d240 100644
--- a/desktop/src/onionshare/tab/mode/chat_mode/__init__.py
+++ b/desktop/src/onionshare/tab/mode/chat_mode/__init__.py
@@ -68,6 +68,11 @@ class ChatMode(Mode):
self.image = QtWidgets.QWidget()
self.image.setLayout(image_layout)
+ # Set title placeholder
+ self.mode_settings_widget.title_lineedit.setPlaceholderText(
+ strings._("gui_tab_name_chat")
+ )
+
# Server status
self.server_status.set_mode("chat")
self.server_status.server_started_finished.connect(self.update_primary_action)
diff --git a/desktop/src/onionshare/tab/mode/mode_settings_widget.py b/desktop/src/onionshare/tab/mode/mode_settings_widget.py
index a3a315c9..ef59f37e 100644
--- a/desktop/src/onionshare/tab/mode/mode_settings_widget.py
+++ b/desktop/src/onionshare/tab/mode/mode_settings_widget.py
@@ -57,6 +57,16 @@ class ModeSettingsWidget(QtWidgets.QWidget):
else:
self.public_checkbox.setCheckState(QtCore.Qt.Unchecked)
+ # Title
+ title_label = QtWidgets.QLabel(strings._("mode_settings_title_label"))
+ self.title_lineedit = QtWidgets.QLineEdit()
+ self.title_lineedit.editingFinished.connect(self.title_editing_finished)
+ if self.settings.get("general", "title"):
+ self.title_lineedit.setText(self.settings.get("general", "title"))
+ title_layout = QtWidgets.QHBoxLayout()
+ title_layout.addWidget(title_label)
+ title_layout.addWidget(self.title_lineedit)
+
# Whether or not to use an auto-start timer
self.autostart_timer_checkbox = QtWidgets.QCheckBox()
self.autostart_timer_checkbox.clicked.connect(
@@ -152,6 +162,7 @@ class ModeSettingsWidget(QtWidgets.QWidget):
# Advanced group itself
advanced_layout = QtWidgets.QVBoxLayout()
advanced_layout.setContentsMargins(0, 0, 0, 0)
+ advanced_layout.addLayout(title_layout)
advanced_layout.addLayout(autostart_timer_layout)
advanced_layout.addLayout(autostop_timer_layout)
advanced_layout.addWidget(self.legacy_checkbox)
@@ -203,6 +214,33 @@ class ModeSettingsWidget(QtWidgets.QWidget):
self.legacy_checkbox.hide()
self.client_auth_checkbox.hide()
+ def title_editing_finished(self):
+ if self.title_lineedit.text().strip() == "":
+ self.title_lineedit.setText("")
+ self.settings.set("general", "title", None)
+ if self.tab.mode == self.common.gui.MODE_SHARE:
+ self.tab.change_title.emit(
+ self.tab.tab_id, strings._("gui_tab_name_share")
+ )
+ elif self.tab.mode == self.common.gui.MODE_RECEIVE:
+ self.tab.change_title.emit(
+ self.tab.tab_id, strings._("gui_tab_name_receive")
+ )
+ elif self.tab.mode == self.common.gui.MODE_WEBSITE:
+ self.tab.change_title.emit(
+ self.tab.tab_id, strings._("gui_tab_name_website")
+ )
+ elif self.tab.mode == self.common.gui.MODE_CHAT:
+ self.tab.change_title.emit(
+ self.tab.tab_id, strings._("gui_tab_name_chat")
+ )
+ elif self.tab_mode == None:
+ pass
+ else:
+ title = self.title_lineedit.text()
+ self.settings.set("general", "title", title)
+ self.tab.change_title.emit(self.tab.tab_id, title)
+
def persistent_checkbox_clicked(self):
self.settings.set("persistent", "enabled", self.persistent_checkbox.isChecked())
self.settings.set("persistent", "mode", self.tab.mode)
diff --git a/desktop/src/onionshare/tab/mode/receive_mode/__init__.py b/desktop/src/onionshare/tab/mode/receive_mode/__init__.py
index 64e7aebf..6056b1db 100644
--- a/desktop/src/onionshare/tab/mode/receive_mode/__init__.py
+++ b/desktop/src/onionshare/tab/mode/receive_mode/__init__.py
@@ -128,6 +128,11 @@ class ReceiveMode(Mode):
self.hide_webhook_url()
self.mode_settings_widget.mode_specific_layout.addLayout(webhook_url_layout)
+ # Set title placeholder
+ self.mode_settings_widget.title_lineedit.setPlaceholderText(
+ strings._("gui_tab_name_receive")
+ )
+
# Server status
self.server_status.set_mode("receive")
self.server_status.server_started_finished.connect(self.update_primary_action)
diff --git a/desktop/src/onionshare/tab/mode/share_mode/__init__.py b/desktop/src/onionshare/tab/mode/share_mode/__init__.py
index 74a4e2c2..05038e20 100644
--- a/desktop/src/onionshare/tab/mode/share_mode/__init__.py
+++ b/desktop/src/onionshare/tab/mode/share_mode/__init__.py
@@ -77,6 +77,11 @@ class ShareMode(Mode):
for filename in self.filenames:
self.file_selection.file_list.add_file(filename)
+ # Set title placeholder
+ self.mode_settings_widget.title_lineedit.setPlaceholderText(
+ strings._("gui_tab_name_share")
+ )
+
# Server status
self.server_status.set_mode("share", self.file_selection)
self.server_status.server_started.connect(self.file_selection.server_started)
diff --git a/desktop/src/onionshare/tab/mode/website_mode/__init__.py b/desktop/src/onionshare/tab/mode/website_mode/__init__.py
index 6aa83de0..f7cfa758 100644
--- a/desktop/src/onionshare/tab/mode/website_mode/__init__.py
+++ b/desktop/src/onionshare/tab/mode/website_mode/__init__.py
@@ -77,6 +77,11 @@ class WebsiteMode(Mode):
for filename in self.filenames:
self.file_selection.file_list.add_file(filename)
+ # Set title placeholder
+ self.mode_settings_widget.title_lineedit.setPlaceholderText(
+ strings._("gui_tab_name_website")
+ )
+
# Server status
self.server_status.set_mode("website", self.file_selection)
self.server_status.server_started.connect(self.file_selection.server_started)
diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py
index b9a70011..a955ea53 100644
--- a/desktop/src/onionshare/tab_widget.py
+++ b/desktop/src/onionshare/tab_widget.py
@@ -176,6 +176,11 @@ class TabWidget(QtWidgets.QTabWidget):
)
tab.init(mode_settings)
+
+ # Make sure the title is set
+ if tab.get_mode():
+ tab.get_mode().mode_settings_widget.title_editing_finished()
+
# If it's persistent, set the persistent image in the tab
self.change_persistent(tab.tab_id, tab.settings.get("persistent", "enabled"))
@@ -183,8 +188,13 @@ class TabWidget(QtWidgets.QTabWidget):
self.bring_to_front.emit()
def change_title(self, tab_id, title):
+ shortened_title = title
+ if len(shortened_title) > 11:
+ shortened_title = shortened_title[:10] + "..."
+
index = self.indexOf(self.tabs[tab_id])
- self.setTabText(index, title)
+ self.setTabText(index, shortened_title)
+ self.setTabToolTip(index, title)
def change_icon(self, tab_id, icon_path):
index = self.indexOf(self.tabs[tab_id])