diff --git a/ChatRoom/__pycache__/main.cpython-37.pyc b/ChatRoom/__pycache__/main.cpython-37.pyc new file mode 100644 index 0000000..bc47442 Binary files /dev/null and b/ChatRoom/__pycache__/main.cpython-37.pyc differ diff --git a/ChatRoom/main.py b/ChatRoom/main.py new file mode 100644 index 0000000..8a8179e --- /dev/null +++ b/ChatRoom/main.py @@ -0,0 +1,100 @@ +from fastapi import FastAPI, WebSocket, Request, WebSocketDisconnect +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi.templating import Jinja2Templates +from dataclasses import dataclass +from typing import Dict +import uuid +import json +from fastapi.staticfiles import StaticFiles +from better_profanity import profanity + +templates = Jinja2Templates(directory="templates") + +@dataclass +class ConnectionManager: + def __init__(self) -> None: + self.active_connections: Dict[str, WebSocket] = {} + self.user_warnings: Dict[str, int] = {} + + async def connect(self, websocket: WebSocket): + await websocket.accept() + user_id = str(uuid.uuid4()) + self.active_connections[user_id] = websocket + self.user_warnings[user_id] = 0 + + # Generate a user-friendly name or message + user_message = f"A new user has joined the chat room!" + + # Send a system message to all active connections + await self.send_message_to_all(json.dumps({"isMe": False, "data": user_message, "username": "System"})) + + await self.send_message(websocket, json.dumps({"isMe": True, "data": "Welcome to the chat room!", "username": "System"})) + + async def send_message(self, ws: WebSocket, message: str): + await ws.send_text(message) + + async def send_message_to_all(self, message: str): + for connection in self.active_connections.values(): + await connection.send_text(message) + + def find_connection_id(self, websocket: WebSocket): + return next(id for id, conn in self.active_connections.items() if conn == websocket) + + async def broadcast(self, webSocket: WebSocket, data: str): + decoded_data = json.loads(data) + message = decoded_data['message'] + username = decoded_data['username'] + + # Check message for profanity + if profanity.contains_profanity(message): + user_id = self.find_connection_id(webSocket) + self.user_warnings[user_id] += 1 + warnings = self.user_warnings[user_id] + await self.send_message(webSocket, json.dumps({"isMe": True, "data": f"Warning {warnings}/3: Profanity not allowed.", "username": "System"})) + if warnings >= 3: + await self.disconnect(webSocket) + return + + # Replace profane message with a warning message + message = f"**Content Removed**" + + for connection_id, connection in self.active_connections.items(): + is_me = connection == webSocket + await connection.send_text(json.dumps({"isMe": is_me, "data": message, "username": username})) + + async def disconnect(self, websocket: WebSocket): + user_id = self.find_connection_id(websocket) + del self.active_connections[user_id] + del self.user_warnings[user_id] + + # Notify all active connections about user disconnection + await self.send_message_to_all(json.dumps({"isMe": False, "data": "A user has left the chat room.", "username": "System"})) + + # Notify user about disconnection due to profanity + await self.send_message(websocket, json.dumps({"isMe": True, "data": "You have been removed from the chat room due to profanity.", "username": "System"})) + + await websocket.close() + +app = FastAPI() +app.mount("/static", StaticFiles(directory="static"), name="static") +connection_manager = ConnectionManager() + +@app.get("/", response_class=HTMLResponse) +def get_room(request: Request): + return templates.TemplateResponse("index.html", {"request": request}) + +@app.websocket("/message") +async def websocket_endpoint(websocket: WebSocket): + await connection_manager.connect(websocket) + + try: + while True: + data = await websocket.receive_text() + await connection_manager.broadcast(websocket, data) + except WebSocketDisconnect: + await connection_manager.disconnect(websocket) + return RedirectResponse("/") + +@app.get("/join", response_class=HTMLResponse) +def get_room(request: Request): + return templates.TemplateResponse("room.html", {"request": request}) diff --git a/ChatRoom/static/css/style.css b/ChatRoom/static/css/style.css new file mode 100644 index 0000000..eed306f --- /dev/null +++ b/ChatRoom/static/css/style.css @@ -0,0 +1,41 @@ +/* Custom CSS for styling */ +body { + background-color: #f4f4f4; +} + +.container { + max-width: 500px; + margin: 0 auto; + margin-top: 50px; + background-color: #fff; + padding: 20px; + border-radius: 10px; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); + text-align: center; +} + +#chat { + display: none; +} + +li { + display: block; +} + +.user-message { + background-color: #17A2B8; + color: #fff; + border-radius: 0.5em; + padding: 5px 10px; + margin: 5px 0; + float: left; +} + +.other-message { + background-color: #007BFF; + color: #fff; + border-radius: 0.5em; + padding: 5px 10px; + margin: 5px 0; + float: right; +} diff --git a/ChatRoom/static/css/styles2.css b/ChatRoom/static/css/styles2.css new file mode 100644 index 0000000..cf82759 --- /dev/null +++ b/ChatRoom/static/css/styles2.css @@ -0,0 +1,470 @@ +@import url('https://fonts.googleapis.com/css2?family=Lexend:wght@300;400&display=swap'); + +body { + background-color: rgb(82, 169, 159); + font-family: 'Lexend', sans-serif; + color: #ffffff; +} + +body::before { + content: 'なさけ'; + position: fixed; + transform: rotate(90deg); + font-family: inherit; + font-size: 200px; + opacity: 40%; + font-weight: bolder; + top: 25%; + right: -5%; + z-index: -1; + -webkit-text-stroke-width: 5px; + -webkit-text-fill-color: rgb(82, 169, 159); +} + +a { + text-decoration: none; + color: white; +} + +.navbar { + height: 100%; + width: 10%; + z-index: 1; + position: fixed; + left: 0; + top: 0; + background-color: #e27d60; + overflow: hidden; +} + +.navbar a { + padding: 20px 10px 20px 25px; + text-decoration: none; + color: #ffffff; + display: block; + font-size: 18px; + cursor: pointer; + border-bottom: 2px solid #e8a87c; +} + +.navbar a:hover { + background-color: #e8a87c; +} + +.navbar a.active { + background-color: #e8a87c; +} + +.home, +.auth, +.error { + margin: 3% 30% 0% 13%; +} + +.heading { + font-size: 40px; +} + +.sub-heading { + margin-top: -15px; +} + +::placeholder { + color: rgb(230, 230, 230); +} + +.auth input { + font-family: inherit; + width: 300px; + height: 40px; + display: block; + margin-bottom: 10px; + border: 1px solid #ffffff; + border-radius: 10px; + background-color: inherit; + color: white; + padding-left: 10px; +} + +.auth button { + width: 100px; + height: 35px; + border: 1px solid #956b78; + border-radius: 10px; + background-color: #c38d9e; + color: white; + font-family: inherit; +} + +.auth button:hover { + cursor: pointer; + background-color: #956b78; +} + +.whatsapp button { + margin-top: 25px; + width: 300px; + height: 50px; + border: 1px solid #41b3a3; + border-radius: 10px; + background-color: #139483; + color: white; + font-family: inherit; + font-size: 15px; +} + +.whatsapp button:hover { + cursor: pointer; + background-color: #0e7c6e; +} + +.row { + margin-top: 2.5%; + margin-left: 13%; + display: table; + width: 80%; + table-layout: fixed; + border-spacing: 10px; +} + +.column { + display: table-cell; + text-align: center; + padding: 0px 10px; + -webkit-animation: slide-bottom 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; + animation: slide-bottom 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; +} + +.card-row { + margin-left: 13%; + display: table; + table-layout: fixed; +} + +.card-column { + display: table-cell; +} + +.card { + width: 300px; + height: 200px; + background-color: #378480; + margin-right: 30px; + border-radius: 20px; + -webkit-animation: slide-bottom 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; + animation: slide-bottom 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; +} + +@-webkit-keyframes slide-bottom { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + 100% { + -webkit-transform: translateY(10px); + transform: translateY(10px); + } +} +@keyframes slide-bottom { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + 100% { + -webkit-transform: translateY(10px); + transform: translateY(10px); + } +} + +.card p { + font-size: 25px; + padding: 30px 30px 10px 30px; +} + +.card button { + color: white; + font-size: 14px; + font-family: inherit; + margin-left: 30px; + width: 100px; + height: 40px; + border: 1px solid #956b78; + border-radius: 20px; + background-color: #c38d9e; +} + +.card button:hover { + cursor: pointer; + background-color: #956b78; +} + +.journal-row { + margin-left: 13%; + display: table; + table-layout: fixed; +} + +.journal-column { + display: table-cell; +} + +.journal-column textarea { + height: 400px; + width: 550px; + color: white; + font-family: inherit; + font-size: 14px; + padding: 20px; + background-color: #378480; + border: 1px solid #0e7c6e; + border-radius: 30px; + resize: none; + position: absolute; + box-sizing: border-box; + margin: 0px 30px 10px 80px; +} + +.journal-column button { + margin-top: 430px; + color: white; + font-size: 14px; + font-family: inherit; + margin-left: 30px; + width: 100px; + height: 40px; + border: 1px solid #956b78; + border-radius: 20px; + background-color: #c38d9e; + position: absolute; +} + +.journal-column button:hover { + cursor: pointer; + background-color: #956b78; +} + +.analysis { + margin-top: 40px; +} + +.chatbot input { + margin-bottom: 10px; + font-family: inherit; + width: 700px; + height: 40px; + display: inline-block; + border: 1px solid #ffffff; + border-radius: 10px; + background-color: inherit; + color: white; + padding-left: 10px; +} + +.chatbot button { + color: white; + font-size: 14px; + font-family: inherit; + margin-left: 30px; + width: 100px; + height: 40px; + border: 1px solid #956b78; + border-radius: 20px; + background-color: #c38d9e; + position: absolute; +} + +.chatbot button:hover { + cursor: pointer; + background-color: #956b78; +} + +.chat-area { + height: 400px; + overflow-y: scroll; + padding: 20px; + margin-bottom: 30px; + display: flex; + flex-direction: column-reverse; +} + +.chat-user { + background-color: #139483; + border-radius: 5px; + padding: 20px; + margin: 10px 0; + word-wrap: break-word; + white-space: pre-wrap; +} + +.chat-bot { + background-color: #378480; + border-radius: 5px; + padding: 20px; + margin: 10px 0; + word-wrap: break-word; + white-space: pre-wrap; +} + +.chat-bubble { + background-color: #e6f8f1; + padding: 16px 28px; + -webkit-border-radius: 20px; + -webkit-border-bottom-left-radius: 2px; + -moz-border-radius: 20px; + -moz-border-radius-bottomleft: 2px; + border-radius: 20px; + border-bottom-left-radius: 2px; + display: inline-block; +} + +.typing { + align-items: center; + display: flex; + height: 17px; +} + +.typing .dot { + animation: mercuryTypingAnimation 1.8s infinite ease-in-out; + background-color: #6cad96; + border-radius: 50%; + height: 7px; + margin-right: 4px; + vertical-align: middle; + width: 7px; + display: inline-block; +} + +.typing .dot:nth-child(1) { + animation-delay: 200ms; +} + +.typing .dot:nth-child(2) { + animation-delay: 300ms; +} + +.typing .dot:nth-child(3) { + animation-delay: 400ms; +} + +.typing .dot:last-child { + margin-right: 0; +} + +@keyframes mercuryTypingAnimation { + 0% { + transform: translateY(0px); + background-color: #6cad96; + } + 28% { + transform: translateY(-7px); + background-color: #9ecab9; + } + 44% { + transform: translateY(0px); + background-color: #b5d9cb; + } +} + +::-webkit-scrollbar { + width: 20px; +} + +::-webkit-scrollbar-track { + background-color: transparent; +} + +::-webkit-scrollbar-thumb { + background-color: #d6dee1; + border-radius: 20px; + border: 6px solid transparent; + background-clip: content-box; +} + +::-webkit-scrollbar-thumb:hover { + background-color: #a8bbbf; +} + +#pie-chart { + -webkit-animation: slide-bottom 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; + animation: slide-bottom 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; +} + +.test { + margin-bottom: 30px; +} + +.question { + display: block; + padding: 10px; + font-size: 18px; +} + +.options { + display: block; + padding: 3px; + margin-left: 20px; +} + +.test button { + margin-top: 20px; + margin-left: 20px; + width: 100px; + height: 35px; + border: 1px solid #956b78; + border-radius: 20px; + background-color: #c38d9e; + color: white; + font-family: inherit; +} + +.test button:hover { + cursor: pointer; + background-color: #956b78; +} + +.profile p { + font-size: 18px; + margin-bottom: -10px; +} + +.search select { + font-family: inherit; + background-color: #0e7c6e; + color: white; + padding: 5px; +} + +.search button { + margin-left: 15px; + width: 100px; + height: 35px; + border: 1px solid #956b78; + border-radius: 20px; + background-color: #c38d9e; + color: white; + font-family: inherit; +} + +.search button:hover { + cursor: pointer; + background-color: #956b78; +} + +.search table { + border-collapse: collapse; +} + +.search th, +td { + border: 2px solid #0e7c6e; + text-align: left; + padding: 10px; +} + +.search tr:nth-child(even) { + background-color: #378480; +} + +#search-result { + margin-top: 20px; +} diff --git a/ChatRoom/static/js/script.js b/ChatRoom/static/js/script.js new file mode 100644 index 0000000..51a7a9a --- /dev/null +++ b/ChatRoom/static/js/script.js @@ -0,0 +1,77 @@ +let $ = jQuery; +let socket; + +function initializeWebSocket() { + socket = new WebSocket('ws://localhost:8000/message'); + + socket.onopen = function (event) { + console.log('WebSocket connection established.'); + }; + + socket.onmessage = function (event) { + const data = JSON.parse(event.data); + const msgClass = data.isMe ? 'user-message' : 'other-message'; + const sender = data.isMe ? 'You' : data.username; + const message = data.data; + const messageElement = $('
Discover a world of cinematic wellness with our curated selection of movies designed to uplift your spirits and promote mental well-being. Our "Cinema for Wellness" suggests movies backed by psychologists, specifically chosen to boost your mood and enhance your mental health journey. Dive into a realm of positivity, inspiration, and emotional balance with films that resonate with your wellness goals. Elevate your movie-watching experience with our selection of movies, crafted to nurture your mind and soul.
+Year: {{ movie_info.Year }}
+IMDB Rating: {{ movie_info.imdbRating }}
+Runtime: {{ movie_info.Runtime }}
+Genre: {{ movie_info.Genre }}
+Director: {{ movie_info.Director }}
+Cast: {{ movie_info.Actors }}
+Plot: {{ movie_info.Plot }}
+ + +