2020-08-27 19:13:08 -04:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
OnionShare | https://onionshare.org/
|
|
|
|
|
2021-02-22 16:35:14 -05:00
|
|
|
Copyright (C) 2014-2021 Micah Lee, et al. <micah@micahflee.com>
|
2020-08-27 19:13:08 -04:00
|
|
|
|
|
|
|
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 <http://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
|
|
|
2021-04-12 17:55:16 -04:00
|
|
|
from flask import request, render_template, make_response, jsonify, session
|
2021-11-14 10:28:21 -05:00
|
|
|
from flask_socketio import emit
|
2020-03-08 05:21:43 -04:00
|
|
|
|
|
|
|
|
|
|
|
class ChatModeWeb:
|
|
|
|
"""
|
|
|
|
All of the web logic for chat mode
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, common, web):
|
|
|
|
self.common = common
|
|
|
|
self.common.log("ChatModeWeb", "__init__")
|
|
|
|
|
|
|
|
self.web = web
|
|
|
|
|
2021-11-14 10:28:21 -05:00
|
|
|
# This tracks users in the server
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
self.connected_users = []
|
2020-03-08 05:21:43 -04:00
|
|
|
|
|
|
|
# This tracks the history id
|
|
|
|
self.cur_history_id = 0
|
|
|
|
|
2021-05-31 08:05:31 -04:00
|
|
|
# Whether or not we can send REQUEST_INDIVIDUAL_FILE_STARTED
|
|
|
|
# and maybe other events when requests come in to this mode
|
|
|
|
# Chat mode has no concept of individual file requests that
|
|
|
|
# turn into history widgets in the GUI, so set it to False
|
|
|
|
self.supports_file_requests = False
|
|
|
|
|
2020-03-08 05:21:43 -04:00
|
|
|
self.define_routes()
|
|
|
|
|
|
|
|
def define_routes(self):
|
|
|
|
"""
|
|
|
|
The web app routes for chatting
|
|
|
|
"""
|
|
|
|
|
2021-05-31 08:05:31 -04:00
|
|
|
@self.web.app.route("/", methods=["GET"], provide_automatic_options=False)
|
2020-03-08 05:21:43 -04:00
|
|
|
def index():
|
|
|
|
history_id = self.cur_history_id
|
|
|
|
self.cur_history_id += 1
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
session["name"] = (
|
|
|
|
session.get("name")
|
|
|
|
if session.get("name")
|
|
|
|
else self.common.build_username()
|
|
|
|
)
|
2020-03-08 05:21:43 -04:00
|
|
|
self.web.add_request(
|
2020-11-10 09:31:11 -05:00
|
|
|
request.path,
|
|
|
|
{"id": history_id, "status_code": 200},
|
2020-03-08 05:21:43 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
self.web.add_request(self.web.REQUEST_LOAD, request.path)
|
2021-05-13 04:11:29 -04:00
|
|
|
return render_template(
|
2021-05-31 08:05:31 -04:00
|
|
|
"chat.html",
|
|
|
|
static_url_path=self.web.static_url_path,
|
|
|
|
username=session.get("name"),
|
|
|
|
title=self.web.settings.get("general", "title"),
|
2020-03-08 05:21:43 -04:00
|
|
|
)
|
|
|
|
|
2021-05-31 08:05:31 -04:00
|
|
|
@self.web.app.route("/update-session-username", methods=["POST"], provide_automatic_options=False)
|
2020-05-11 03:21:46 -04:00
|
|
|
def update_session_username():
|
|
|
|
history_id = self.cur_history_id
|
|
|
|
data = request.get_json()
|
2020-11-10 09:31:11 -05:00
|
|
|
if (
|
|
|
|
data.get("username", "")
|
|
|
|
and data.get("username", "") not in self.connected_users
|
2021-05-31 08:05:31 -04:00
|
|
|
and len(data.get("username", "")) < 128
|
2020-11-10 09:31:11 -05:00
|
|
|
):
|
2020-08-21 08:16:21 -04:00
|
|
|
session["name"] = data.get("username", session.get("name"))
|
2021-05-31 08:05:31 -04:00
|
|
|
self.web.add_request(
|
|
|
|
request.path,
|
|
|
|
{"id": history_id, "status_code": 200},
|
|
|
|
)
|
|
|
|
|
|
|
|
self.web.add_request(self.web.REQUEST_LOAD, request.path)
|
|
|
|
r = make_response(
|
|
|
|
jsonify(
|
|
|
|
username=session.get("name"),
|
|
|
|
success=True,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.web.add_request(
|
|
|
|
request.path,
|
|
|
|
{"id": history_id, "status_code": 403},
|
|
|
|
)
|
|
|
|
|
|
|
|
r = make_response(
|
|
|
|
jsonify(
|
|
|
|
username=session.get("name"),
|
|
|
|
success=False,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return r
|
2020-05-11 03:21:46 -04:00
|
|
|
|
2021-11-14 10:28:21 -05:00
|
|
|
@self.web.socketio.on("connect", namespace="/chat")
|
|
|
|
def server_connect():
|
2020-03-08 05:21:43 -04:00
|
|
|
"""Sent by clients when they enter a room.
|
|
|
|
A status message is broadcast to all people in the room."""
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
self.connected_users.append(session.get("name"))
|
2020-03-08 05:21:43 -04:00
|
|
|
emit(
|
|
|
|
"status",
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
{
|
2020-08-19 19:40:00 -04:00
|
|
|
"username": session.get("name"),
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
"msg": "{} has joined.".format(session.get("name")),
|
|
|
|
"connected_users": self.connected_users,
|
|
|
|
"user": session.get("name"),
|
|
|
|
},
|
2021-11-14 10:28:21 -05:00
|
|
|
broadcast=True,
|
2020-03-08 05:21:43 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
@self.web.socketio.on("text", namespace="/chat")
|
|
|
|
def text(message):
|
|
|
|
"""Sent by a client when the user entered a new message.
|
2021-11-14 10:28:21 -05:00
|
|
|
The message is sent to all people in the server."""
|
2020-03-08 05:21:43 -04:00
|
|
|
emit(
|
2021-11-14 10:36:47 -05:00
|
|
|
"chat_message",
|
2020-08-19 19:40:00 -04:00
|
|
|
{"username": session.get("name"), "msg": message["msg"]},
|
2021-11-14 10:28:21 -05:00
|
|
|
broadcast=True,
|
2020-03-08 05:21:43 -04:00
|
|
|
)
|
2020-03-12 05:24:48 -04:00
|
|
|
|
|
|
|
@self.web.socketio.on("update_username", namespace="/chat")
|
|
|
|
def update_username(message):
|
|
|
|
"""Sent by a client when the user updates their username.
|
2021-11-14 10:28:21 -05:00
|
|
|
The message is sent to all people in the server."""
|
2020-03-12 05:24:48 -04:00
|
|
|
current_name = session.get("name")
|
2020-11-10 09:31:11 -05:00
|
|
|
if message.get("username", ""):
|
2020-08-21 08:16:21 -04:00
|
|
|
session["name"] = message["username"]
|
|
|
|
self.connected_users[
|
|
|
|
self.connected_users.index(current_name)
|
|
|
|
] = session.get("name")
|
2020-03-12 05:24:48 -04:00
|
|
|
emit(
|
|
|
|
"status",
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
{
|
|
|
|
"msg": "{} has updated their username to: {}".format(
|
|
|
|
current_name, session.get("name")
|
|
|
|
),
|
|
|
|
"connected_users": self.connected_users,
|
|
|
|
"old_name": current_name,
|
|
|
|
"new_name": session.get("name"),
|
2020-03-12 05:24:48 -04:00
|
|
|
},
|
2021-11-14 10:28:21 -05:00
|
|
|
broadcast=True,
|
2020-03-12 05:24:48 -04:00
|
|
|
)
|
|
|
|
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
@self.web.socketio.on("disconnect", namespace="/chat")
|
|
|
|
def disconnect():
|
2021-11-14 10:28:21 -05:00
|
|
|
"""Sent by clients when they disconnect.
|
|
|
|
A status message is broadcast to all people in the server."""
|
|
|
|
if session.get("name") in self.connected_users:
|
|
|
|
self.connected_users.remove(session.get("name"))
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
emit(
|
|
|
|
"status",
|
|
|
|
{
|
|
|
|
"msg": "{} has left the room.".format(session.get("name")),
|
|
|
|
"connected_users": self.connected_users,
|
|
|
|
},
|
2021-11-14 10:28:21 -05:00
|
|
|
broadcast=True,
|
Refactors logic for chat user list and scroll
- Refactors server side code to use instance variable instead of
background thread to generate a list of connected users
- Send this user list anytime any change is made to the list. It can
be: join, update username, disconnect
- In js, render the entire user list everytime it is received.
- Scroll to the bottom of the chat, everytime the current user
sends a message
- Else, if already at the bottom of the chat, scroll to the bottom
after appending incoming status or chat message. But if the user
is scrolled up in the chat window, then do not scroll to the bottom
- When refreshed or close tab is clicked, default browser warning is
shown.
- On receiving disconnect, the browser removes user from room.
- If refreshed, it is shown as if the user left and joined again.
2020-05-03 18:17:13 -04:00
|
|
|
)
|