AliZain1 commited on
Commit
96984e3
·
verified ·
1 Parent(s): db8bb3d

Upload 9 files

Browse files
Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python runtime as a parent image
2
+ FROM python:3.9-slim
3
+
4
+ # Set the working directory in the container
5
+ WORKDIR /app
6
+
7
+ # Copy the requirements file into the container
8
+ COPY requirements.txt .
9
+
10
+ # Install any needed packages specified in requirements.txt
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ # Copy the rest of the application code
14
+ COPY . .
15
+
16
+ # Make port 5000 available to the world outside this container
17
+ EXPOSE 5000
18
+
19
+ # Define environment variable
20
+ ENV FLASK_APP=app.py
21
+
22
+ # Run the Flask app
23
+ CMD ["flask", "run", "--host=0.0.0.0"]
README.md CHANGED
@@ -1,10 +1 @@
1
- ---
2
- title: Chat
3
- emoji: 🌍
4
- colorFrom: pink
5
- colorTo: blue
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ # Chat-app
 
 
 
 
 
 
 
 
 
__pycache__/app.cpython-312.pyc ADDED
Binary file (1.67 kB). View file
 
app.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, redirect, url_for, session
2
+ from flask_socketio import SocketIO, send, emit
3
+ import os
4
+ import re
5
+ from nltk.tokenize import word_tokenize
6
+ from nltk.corpus import stopwords
7
+ import nltk
8
+
9
+ # Download NLTK data (only required once)
10
+ nltk.download('punkt')
11
+ nltk.download('stopwords')
12
+
13
+ app = Flask(__name__)
14
+ app.secret_key = 'your_secret_key_here' # Required for session management
15
+ socketio = SocketIO(app)
16
+
17
+ # Path to the text file where messages will be stored
18
+ MESSAGE_FILE = 'chat_messages.txt'
19
+
20
+ # Ensure the message file exists
21
+ if not os.path.exists(MESSAGE_FILE):
22
+ with open(MESSAGE_FILE, 'w') as f:
23
+ f.write('')
24
+
25
+ # Predefined users (username: password)
26
+ USERS = {
27
+ 'ali': '1234',
28
+ 'zain': '1234',
29
+ 'fahad': '1234'
30
+ }
31
+
32
+ @app.route('/', methods=['GET'])
33
+ def home():
34
+ # Redirect to login if the user is not logged in
35
+ if 'username' not in session:
36
+ return redirect(url_for('login'))
37
+ return redirect(url_for('chat'))
38
+
39
+ @app.route('/login', methods=['GET', 'POST'])
40
+ def login():
41
+ if request.method == 'POST':
42
+ username = request.form['username']
43
+ password = request.form['password']
44
+
45
+ # Check if the username exists and the password matches
46
+ if username in USERS and USERS[username] == password:
47
+ session['username'] = username # Store username in session
48
+ return redirect(url_for('chat'))
49
+ else:
50
+ return "Invalid username or password. <a href='/login'>Try again</a>"
51
+
52
+ return render_template('login.html')
53
+
54
+ @app.route('/chat', methods=['GET'])
55
+ def chat():
56
+ # Redirect to login if the user is not logged in
57
+ if 'username' not in session:
58
+ return redirect(url_for('login'))
59
+
60
+ # Read all messages from the file
61
+ with open(MESSAGE_FILE, 'r') as f:
62
+ messages = f.readlines()
63
+
64
+ return render_template('chat.html', messages=messages)
65
+
66
+ @app.route('/logout')
67
+ def logout():
68
+ session.pop('username', None) # Remove username from session
69
+ return redirect(url_for('login'))
70
+
71
+ @app.route('/matchmaking')
72
+ def matchmaking():
73
+ # Redirect to login if the user is not logged in
74
+ if 'username' not in session:
75
+ return redirect(url_for('login'))
76
+
77
+ # Perform matchmaking
78
+ matches = check_for_matches() # Use the correct function name
79
+ return render_template('matchmaking.html', matches=matches)
80
+
81
+ # WebSocket event for receiving and broadcasting messages
82
+ @socketio.on('message')
83
+ def handle_message(data):
84
+ username = session.get('username')
85
+ message = data['message']
86
+
87
+ # Save the message to the file
88
+ with open(MESSAGE_FILE, 'a') as f:
89
+ f.write(f'{username}: {message}\n')
90
+
91
+ # Broadcast the message to all connected clients
92
+ emit('message', {'username': username, 'message': message}, broadcast=True)
93
+
94
+ # Check for matches after every new message
95
+ check_for_matches()
96
+
97
+ def check_for_matches():
98
+ # Read all messages from the file
99
+ with open(MESSAGE_FILE, 'r') as f:
100
+ messages = f.readlines()
101
+
102
+ # Initialize lists to store buy and sell requests
103
+ buy_requests = []
104
+ sell_requests = []
105
+
106
+ # Process each message
107
+ for message in messages:
108
+ username, text = message.split(':', 1)
109
+ text = text.strip().lower()
110
+
111
+ # Tokenize the message and remove stopwords
112
+ tokens = word_tokenize(text)
113
+ tokens = [word for word in tokens if word.isalnum() and word not in stopwords.words('english')]
114
+
115
+ # Check if the message contains "buy" or "sell"
116
+ if 'buy' in tokens:
117
+ product = extract_product_name(tokens)
118
+ if product:
119
+ buy_requests.append({'username': username.strip(), 'product': product})
120
+ elif 'sell' in tokens:
121
+ product = extract_product_name(tokens)
122
+ if product:
123
+ sell_requests.append({'username': username.strip(), 'product': product})
124
+
125
+ # Find matches between buy and sell requests
126
+ matches = []
127
+ for buy in buy_requests:
128
+ for sell in sell_requests:
129
+ if buy['product'] == sell['product']:
130
+ matches.append({
131
+ 'buyer': buy['username'],
132
+ 'seller': sell['username'],
133
+ 'product': buy['product']
134
+ })
135
+ # Remove matched messages from the file
136
+ remove_matched_messages(buy['username'], sell['username'], buy['product'])
137
+
138
+ # Broadcast matches to all clients
139
+ if matches:
140
+ for match in matches:
141
+ emit('match_found', {
142
+ 'buyer': match['buyer'],
143
+ 'seller': match['seller'],
144
+ 'product': match['product']
145
+ }, broadcast=True)
146
+
147
+ def extract_product_name(tokens):
148
+ # Extract the product name (assume it's the word after "buy" or "sell")
149
+ for i, word in enumerate(tokens):
150
+ if word in ['buy', 'sell'] and i + 1 < len(tokens):
151
+ return tokens[i + 1]
152
+ return None
153
+
154
+ def remove_matched_messages(buyer, seller, product):
155
+ # Read all messages from the file
156
+ with open(MESSAGE_FILE, 'r') as f:
157
+ messages = f.readlines()
158
+
159
+ # Filter out matched messages
160
+ new_messages = []
161
+ for message in messages:
162
+ username, text = message.split(':', 1)
163
+ text = text.strip().lower()
164
+ if not (username.strip() == buyer and f'buy {product}' in text) and \
165
+ not (username.strip() == seller and f'sell {product}' in text):
166
+ new_messages.append(message)
167
+
168
+ # Write the updated messages back to the file
169
+ with open(MESSAGE_FILE, 'w') as f:
170
+ f.writelines(new_messages)
171
+
172
+ if __name__ == '__main__':
173
+ socketio.run(app, debug=True, host='0.0.0.0')
chat_messages.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ zain: hi
2
+ ali: hi
3
+ ali: hi
4
+ ali: hu
5
+ zain: hello
6
+ ali: have dld
7
+ ali: hi
8
+ ali: hello
9
+ zain: hi
10
+ zain: yes
requirements.txt ADDED
Binary file (134 Bytes). View file
 
templates/chat.html ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Chat Room</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
8
+ <style>
9
+ body {
10
+ font-family: Arial, sans-serif;
11
+ background-color: #f5f5f5;
12
+ margin: 0;
13
+ padding: 0;
14
+ display: flex;
15
+ flex-direction: column;
16
+ height: 100vh;
17
+ }
18
+ #chat {
19
+ flex: 1;
20
+ overflow-y: scroll;
21
+ padding: 10px;
22
+ background-color: #fff;
23
+ border-bottom: 1px solid #ddd;
24
+ }
25
+ .message {
26
+ margin-bottom: 10px;
27
+ padding: 10px;
28
+ border-radius: 10px;
29
+ background-color: #e1f5fe;
30
+ max-width: 70%;
31
+ word-wrap: break-word;
32
+ }
33
+ .message.user {
34
+ background-color: #d1c4e9;
35
+ margin-left: auto;
36
+ }
37
+ .message.deleted {
38
+ background-color: #ffebee;
39
+ color: #757575;
40
+ font-style: italic;
41
+ }
42
+ .user-info {
43
+ font-weight: bold;
44
+ color: #333;
45
+ }
46
+ .timestamp {
47
+ font-size: 0.8em;
48
+ color: #757575;
49
+ margin-top: 5px;
50
+ }
51
+ #input-area {
52
+ display: flex;
53
+ padding: 10px;
54
+ background-color: #fff;
55
+ border-top: 1px solid #ddd;
56
+ }
57
+ #message {
58
+ flex: 1;
59
+ padding: 10px;
60
+ border: 1px solid #ddd;
61
+ border-radius: 5px;
62
+ margin-right: 10px;
63
+ }
64
+ #send-button {
65
+ padding: 10px 20px;
66
+ background-color: #007bff;
67
+ color: #fff;
68
+ border: none;
69
+ border-radius: 5px;
70
+ cursor: pointer;
71
+ }
72
+ </style>
73
+ </head>
74
+ <body>
75
+ <h1>Chat Room</h1>
76
+ <p>Logged in as: <strong>{{ session.username }}</strong> | <a href="{{ url_for('logout') }}">Logout</a> | <a href="{{ url_for('matchmaking') }}">Matchmaking</a></p>
77
+ <div id="chat">
78
+ {% for message in messages %}
79
+ <div class="message {% if message.split(':')[0].strip() == session.username %}user{% endif %}">
80
+ <div class="user-info">{{ message.split(':')[0] }}</div>
81
+ <div class="text">{{ message.split(':')[1] }}</div>
82
+ <div class="timestamp">6:32 am</div>
83
+ </div>
84
+ {% endfor %}
85
+ <!-- <div class="message deleted">
86
+ <div class="text">This message was deleted.</div>
87
+ <div class="timestamp">6:32 am</div>
88
+ </div> -->
89
+ </div>
90
+ <div id="input-area">
91
+ <input type="text" id="message" placeholder="Type a message..." required>
92
+ <button id="send-button">Send</button>
93
+ </div>
94
+
95
+ <script>
96
+ // Connect to the WebSocket server
97
+ const socket = io();
98
+
99
+ // Handle incoming messages
100
+ socket.on('message', function(data) {
101
+ const chat = document.getElementById('chat');
102
+ const messageElement = document.createElement('div');
103
+ messageElement.className = `message ${data.username === '{{ session.username }}' ? 'user' : ''}`;
104
+ messageElement.innerHTML = `
105
+ <div class="user-info">${data.username}</div>
106
+ <div class="text">${data.message}</div>
107
+ <div class="timestamp">${new Date().toLocaleTimeString()}</div>
108
+ `;
109
+ chat.appendChild(messageElement);
110
+ chat.scrollTop = chat.scrollHeight; // Auto-scroll to the bottom
111
+ });
112
+
113
+ // Handle match notifications
114
+ socket.on('match_found', function(data) {
115
+ const chat = document.getElementById('chat');
116
+ const matchElement = document.createElement('div');
117
+ matchElement.className = 'match-notification';
118
+ matchElement.innerHTML = `Match found: <strong>${data.buyer}</strong> wants to buy <strong>${data.product}</strong>, and <strong>${data.seller}</strong> wants to sell <strong>${data.product}</strong>.`;
119
+ chat.appendChild(matchElement);
120
+ chat.scrollTop = chat.scrollHeight; // Auto-scroll to the bottom
121
+ });
122
+
123
+ // Function to send a message
124
+ function sendMessage() {
125
+ const messageInput = document.getElementById('message');
126
+ const message = messageInput.value.trim();
127
+ if (message) {
128
+ socket.send({ message: message }); // Send message to the server
129
+ messageInput.value = ''; // Clear the input field
130
+ }
131
+ }
132
+
133
+ // Send message when the send button is clicked
134
+ document.getElementById('send-button').addEventListener('click', function(e) {
135
+ e.preventDefault();
136
+ sendMessage();
137
+ });
138
+
139
+ // Send message when the Enter key is pressed
140
+ document.getElementById('message').addEventListener('keypress', function(e) {
141
+ if (e.key === 'Enter') {
142
+ e.preventDefault();
143
+ sendMessage();
144
+ }
145
+ });
146
+ </script>
147
+ </body>
148
+ </html>
templates/login.html ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Login</title>
7
+ </head>
8
+ <body>
9
+ <h1>Login</h1>
10
+ <form method="POST">
11
+ <label for="username">Username:</label>
12
+ <input type="text" id="username" name="username" required>
13
+ <br>
14
+ <label for="password">Password:</label>
15
+ <input type="password" id="password" name="password" required>
16
+ <br>
17
+ <button type="submit">Login</button>
18
+ </form>
19
+ </body>
20
+ </html>
templates/matchmaking.html ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Matchmaking</title>
7
+ </head>
8
+ <body>
9
+ <h1>Matchmaking Results</h1>
10
+ <a href="{{ url_for('chat') }}">Back to Chat</a>
11
+ <div id="matches">
12
+ {% if matches %}
13
+ {% for match in matches %}
14
+ <p>
15
+ <strong>{{ match.buyer }}</strong> wants to buy <strong>{{ match.product }}</strong>.
16
+ <strong>{{ match.seller }}</strong> wants to sell <strong>{{ match.product }}</strong>.
17
+ Contact them for matchmaking!
18
+ </p>
19
+ {% endfor %}
20
+ {% else %}
21
+ <p>No matches found.</p>
22
+ {% endif %}
23
+ </div>
24
+ </body>
25
+ </html>