diff options
Diffstat (limited to 'cli/onionshare_cli/web/chat_mode.py')
-rw-r--r-- | cli/onionshare_cli/web/chat_mode.py | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/cli/onionshare_cli/web/chat_mode.py b/cli/onionshare_cli/web/chat_mode.py new file mode 100644 index 00000000..15e236d3 --- /dev/null +++ b/cli/onionshare_cli/web/chat_mode.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2020 Micah Lee, et al. <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 +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/>. +""" + +from flask import ( + Request, + request, + render_template, + make_response, + jsonify, + redirect, + session, +) +from werkzeug.utils import secure_filename +from flask_socketio import emit, join_room, leave_room + + +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 + + # This tracks users in the room + self.connected_users = [] + + # This tracks the history id + self.cur_history_id = 0 + + self.define_routes() + + def define_routes(self): + """ + The web app routes for chatting + """ + + @self.web.app.route("/") + def index(): + history_id = self.cur_history_id + self.cur_history_id += 1 + session["name"] = ( + session.get("name") + if session.get("name") + else self.common.build_username() + ) + session["room"] = self.web.settings.default_settings["chat"]["room"] + 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( + render_template( + "chat.html", + static_url_path=self.web.static_url_path, + username=session.get("name"), + ) + ) + return self.web.add_security_headers(r) + + @self.web.app.route("/update-session-username", methods=["POST"]) + def update_session_username(): + history_id = self.cur_history_id + data = request.get_json() + if data.get("username", "") not in self.connected_users: + session["name"] = data.get("username", session.get("name")) + 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,)) + return self.web.add_security_headers(r) + + @self.web.socketio.on("joined", namespace="/chat") + def joined(message): + """Sent by clients when they enter a room. + A status message is broadcast to all people in the room.""" + self.connected_users.append(session.get("name")) + join_room(session.get("room")) + emit( + "status", + { + "username": session.get("name"), + "msg": "{} has joined.".format(session.get("name")), + "connected_users": self.connected_users, + "user": session.get("name"), + }, + room=session.get("room"), + ) + + @self.web.socketio.on("text", namespace="/chat") + def text(message): + """Sent by a client when the user entered a new message. + The message is sent to all people in the room.""" + emit( + "message", + {"username": session.get("name"), "msg": message["msg"]}, + room=session.get("room"), + ) + + @self.web.socketio.on("update_username", namespace="/chat") + def update_username(message): + """Sent by a client when the user updates their username. + The message is sent to all people in the room.""" + current_name = session.get("name") + if message["username"] not in self.connected_users: + session["name"] = message["username"] + self.connected_users[ + self.connected_users.index(current_name) + ] = session.get("name") + emit( + "status", + { + "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"), + }, + room=session.get("room"), + ) + + @self.web.socketio.on("disconnect", namespace="/chat") + def disconnect(): + """Sent by clients when they disconnect from a room. + A status message is broadcast to all people in the room.""" + self.connected_users.remove(session.get("name")) + leave_room(session.get("room")) + emit( + "status", + { + "msg": "{} has left the room.".format(session.get("name")), + "connected_users": self.connected_users, + }, + room=session.get("room"), + ) |