Olivier-Truong
commited on
Commit
•
a22ef44
1
Parent(s):
35e937b
Upload 5 files
Browse files- README-French.MD +59 -0
- README.md +56 -13
- cloud-computing.png +0 -0
- fast-messaging.png +0 -0
- main.py +267 -0
README-French.MD
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Application de Messagerie Flask-SocketIO
|
2 |
+
|
3 |
+
Une application de messagerie simple construite en utilisant Flask et SocketIO.
|
4 |
+
|
5 |
+
## Description
|
6 |
+
|
7 |
+
Cette application permet aux utilisateurs de communiquer via des messages en temps réel au sein de différentes salles de discussion. Les utilisateurs peuvent se connecter, rejoindre des salles de chat, envoyer des messages et même partager des images.
|
8 |
+
|
9 |
+
## Capture d'Écran
|
10 |
+
|
11 |
+
![Interface de l'Application](fast-messaging.png)
|
12 |
+
|
13 |
+
## Table des matières
|
14 |
+
|
15 |
+
- [Installation](#installation)
|
16 |
+
- [Utilisation](#utilisation)
|
17 |
+
- [Fonctionnalités](#fonctionnalités)
|
18 |
+
- [Contributions](#contributions)
|
19 |
+
- [Licence](#licence)
|
20 |
+
|
21 |
+
## Installation
|
22 |
+
|
23 |
+
1. Clonez le dépôt :
|
24 |
+
|
25 |
+
```bash
|
26 |
+
git clone <repository_url>
|
27 |
+
cd <repository_directory>
|
28 |
+
|
29 |
+
|
30 |
+
2. Installez les packages requis en utilisant pip :
|
31 |
+
|
32 |
+
```bash
|
33 |
+
pip install -r requirements.txt
|
34 |
+
```
|
35 |
+
|
36 |
+
## Utilisation
|
37 |
+
|
38 |
+
1. Lancez l'application :
|
39 |
+
```bash
|
40 |
+
python3 main.py
|
41 |
+
```
|
42 |
+
|
43 |
+
2. Accédez à l'application dans votre navigateur web à http://localhost:80.
|
44 |
+
|
45 |
+
## Fonctionnalités
|
46 |
+
- Authentification Utilisateur : Les utilisateurs peuvent se connecter avec leur nom d'utilisateur et leur mot de passe.
|
47 |
+
- Messagerie en Temps Réel : Les utilisateurs peuvent envoyer et recevoir des messages en temps réel au sein des salles de chat.
|
48 |
+
- Partage d'Images : Les utilisateurs peuvent partager des images au sein du chat.
|
49 |
+
- Salles Multiples : Les utilisateurs peuvent rejoindre différentes salles de chat et passer de l'une à l'autre.
|
50 |
+
- Historique des Messages : Les messages précédents sont restaurés lors de la connexion à une salle de chat.
|
51 |
+
- Données Persistantes : Les informations utilisateur et les messages sont stockés dans une base de données SQLite.
|
52 |
+
|
53 |
+
## Contributions
|
54 |
+
|
55 |
+
Les contributions sont les bienvenues !
|
56 |
+
|
57 |
+
## Licence
|
58 |
+
|
59 |
+
Ce projet est sous licence MIT.
|
README.md
CHANGED
@@ -1,13 +1,56 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Flask-SocketIO Messaging Application
|
2 |
+
<!-- # Flask-SocketIO-Messaging-Application -->
|
3 |
+
|
4 |
+
A simple messaging application built using Flask and SocketIO.
|
5 |
+
|
6 |
+
## Description
|
7 |
+
|
8 |
+
This application allows users to communicate through real-time messages within different chat rooms. Users can log in, join chat rooms, send messages, and even share images.
|
9 |
+
|
10 |
+
## Screenshot
|
11 |
+
|
12 |
+
![Application Interface](fast-messaging.png)
|
13 |
+
|
14 |
+
## Table of Contents
|
15 |
+
|
16 |
+
- [Installation](#installation)
|
17 |
+
- [Usage](#usage)
|
18 |
+
- [Features](#features)
|
19 |
+
- [Contributions](#contributions)
|
20 |
+
- [License](#license)
|
21 |
+
|
22 |
+
## Installation
|
23 |
+
|
24 |
+
1. Clone the repository:
|
25 |
+
|
26 |
+
```bash
|
27 |
+
git clone <repository_url>
|
28 |
+
cd <repository_directory>
|
29 |
+
|
30 |
+
2. Install the required packages using pip:
|
31 |
+
```bash
|
32 |
+
pip install -r requirements.txt
|
33 |
+
```
|
34 |
+
|
35 |
+
# Usage
|
36 |
+
1. Launch the application:
|
37 |
+
```bash
|
38 |
+
python3 main.py
|
39 |
+
```
|
40 |
+
|
41 |
+
2. Access the application in your web browser at `http://localhost:80`.
|
42 |
+
|
43 |
+
## Features
|
44 |
+
- User Authentication: Users can log in using their username and password.
|
45 |
+
- Real-time Messaging: Users can send and receive real-time messages within chat rooms.
|
46 |
+
- Image Sharing: Users can share images within the chat.
|
47 |
+
- Multiple Rooms: Users can join different chat rooms and switch between them.
|
48 |
+
- Message History: Previous messages are restored when joining a chat room.
|
49 |
+
- Persistent Data: User information and messages are stored in an SQLite database.
|
50 |
+
- Contributions
|
51 |
+
- Contributions are welcome!
|
52 |
+
|
53 |
+
## License
|
54 |
+
This project is under the MIT license.
|
55 |
+
|
56 |
+
<p align="center"><img src="https://ipipip-gh.0xsql.repl.co/webchat-io/views.png" alt="Visitors"></a></p>
|
cloud-computing.png
ADDED
fast-messaging.png
ADDED
main.py
ADDED
@@ -0,0 +1,267 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import *
|
2 |
+
from flask_socketio import SocketIO, emit, join_room
|
3 |
+
import json, hashlib, sqlite3, time
|
4 |
+
|
5 |
+
|
6 |
+
def check_user(username, passwd, k, update=False, data={}):
|
7 |
+
_ = False
|
8 |
+
while not (_):
|
9 |
+
try:
|
10 |
+
con = sqlite3.connect("database.db")
|
11 |
+
cur = con.cursor()
|
12 |
+
cur.execute("SELECT * FROM userinfo")
|
13 |
+
if cur.arraysize < 2:
|
14 |
+
cur.executemany(
|
15 |
+
"INSERT INTO userinfo(username, passwd, infos, messages) VALUES(?, ?, ?, ?)",
|
16 |
+
[("database", "azertyuiop",
|
17 |
+
json.dumps({"creation_date": time.ctime()}), "")])
|
18 |
+
cur.execute("SELECT * FROM userinfo")
|
19 |
+
size = cur.arraysize
|
20 |
+
while size > 0:
|
21 |
+
db = cur.fetchmany(512)
|
22 |
+
for info in db:
|
23 |
+
size -= 1
|
24 |
+
if info[0] == username:
|
25 |
+
if passwd == "noPasswdButCookies":
|
26 |
+
if (json.loads(info[2])['cookies']
|
27 |
+
== k) and not (update):
|
28 |
+
cur.close()
|
29 |
+
con.close()
|
30 |
+
return (info[2], info[3])
|
31 |
+
if update:
|
32 |
+
d = json.loads(info[3])
|
33 |
+
for key in data:
|
34 |
+
if d.get(key) == None:
|
35 |
+
d[key] = data[key]
|
36 |
+
else:
|
37 |
+
d[key] = d[key] + data[key]
|
38 |
+
requete_mise_a_jour = "UPDATE userinfo SET username = ?, passwd = ?, infos = ?, messages = ? WHERE messages = ?"
|
39 |
+
cur.execute(requete_mise_a_jour,
|
40 |
+
(info[0], info[1], info[2],
|
41 |
+
json.dumps(d), info[3]))
|
42 |
+
con.commit()
|
43 |
+
cur.close()
|
44 |
+
con.close()
|
45 |
+
return ""
|
46 |
+
if info[1] == passwd:
|
47 |
+
cur.close()
|
48 |
+
con.close()
|
49 |
+
return (info[2], info[3])
|
50 |
+
else:
|
51 |
+
cur.close()
|
52 |
+
con.close()
|
53 |
+
return "bad password"
|
54 |
+
cur.executemany(
|
55 |
+
"INSERT INTO userinfo(username, passwd, infos, messages) VALUES(?, ?, ?, ?)",
|
56 |
+
[(username, passwd,
|
57 |
+
json.dumps({
|
58 |
+
"creation_date": time.ctime(),
|
59 |
+
"cookies": k
|
60 |
+
}), json.dumps({
|
61 |
+
"general;": [],
|
62 |
+
"generale;": []
|
63 |
+
}))])
|
64 |
+
con.commit()
|
65 |
+
cur.close()
|
66 |
+
con.close()
|
67 |
+
return (json.dumps({
|
68 |
+
"creation_date": time.ctime(),
|
69 |
+
"cookies": k
|
70 |
+
}), json.dumps({
|
71 |
+
"general;": [],
|
72 |
+
"generale;": []
|
73 |
+
}))
|
74 |
+
except Exception as e:
|
75 |
+
print(e)
|
76 |
+
|
77 |
+
|
78 |
+
def initDB():
|
79 |
+
con = sqlite3.connect("database.db")
|
80 |
+
cur = con.cursor()
|
81 |
+
cur.execute(
|
82 |
+
"CREATE TABLE IF NOT EXISTS userinfo(username, passwd, infos, messages)"
|
83 |
+
)
|
84 |
+
cur.executemany(
|
85 |
+
"INSERT INTO userinfo(username, passwd, infos, messages) VALUES(?, ?, ?, ?)",
|
86 |
+
[("database", "azertyuiop", json.dumps({"creation_date": time.ctime()
|
87 |
+
}), "")])
|
88 |
+
con.commit()
|
89 |
+
cur.close()
|
90 |
+
con.close()
|
91 |
+
|
92 |
+
|
93 |
+
initDB()
|
94 |
+
|
95 |
+
app = Flask(__name__)
|
96 |
+
app.config['SECRET_KEY'] = 'fhdvidushdujxjddfkidfjojcvndhfxnvkdnvid'
|
97 |
+
app.config['tab'] = {'usid': {123456789: {'tmp-img': ""}}}
|
98 |
+
socketio = SocketIO(app)
|
99 |
+
|
100 |
+
|
101 |
+
@app.route('/', methods=['GET', 'POST'])
|
102 |
+
def index():
|
103 |
+
if request.method == 'GET':
|
104 |
+
cookie_value = request.cookies.get('uid')
|
105 |
+
if cookie_value:
|
106 |
+
return redirect("/chat")
|
107 |
+
return send_file("html_css_js/login.html")
|
108 |
+
else:
|
109 |
+
username = request.form.get('username')
|
110 |
+
passwd = request.form.get('password')
|
111 |
+
if (username != None) and (passwd != None):
|
112 |
+
k = hashlib.sha1(passwd.encode() +
|
113 |
+
str(time.time()).encode()).hexdigest()
|
114 |
+
h = hashlib.sha256(passwd.encode()).hexdigest()
|
115 |
+
r = cku = check_user(username, h, k)
|
116 |
+
if len(cku) == 2:
|
117 |
+
resp = make_response(redirect("/chat"))
|
118 |
+
resp.set_cookie('username', username)
|
119 |
+
resp.set_cookie('uid', k)
|
120 |
+
return resp
|
121 |
+
else:
|
122 |
+
return r
|
123 |
+
|
124 |
+
|
125 |
+
@app.route('/chat')
|
126 |
+
def chat():
|
127 |
+
uid = request.cookies.get('uid')
|
128 |
+
username = request.cookies.get('username')
|
129 |
+
if (username != None) and (uid != None):
|
130 |
+
cku = check_user(username, "noPasswdButCookies", uid)
|
131 |
+
if len(cku) == 2:
|
132 |
+
rooms = ""
|
133 |
+
oldMessage = ""
|
134 |
+
rooms_messages = json.loads(cku[1])
|
135 |
+
for room in rooms_messages:
|
136 |
+
rooms += f"<div class='menu-item' onclick='sendnew(\"{room}\");'>{room}</div>\n\r"
|
137 |
+
else:
|
138 |
+
return redirect('/')
|
139 |
+
return open("templates/heremeknown.html", "rb").read().replace(
|
140 |
+
b"{{ rooms }}", rooms.encode()).replace(
|
141 |
+
b"{{ username }}", username.encode()).replace(
|
142 |
+
b"{{ oldMessage }}", oldMessage.encode()).replace(
|
143 |
+
b"{{ roomID }}", b"Message a envoyer dans general;...")
|
144 |
+
else:
|
145 |
+
return redirect('/')
|
146 |
+
|
147 |
+
|
148 |
+
@app.route('/upload-img')
|
149 |
+
def upload_img():
|
150 |
+
return send_file("cloud-computing.png")
|
151 |
+
|
152 |
+
|
153 |
+
@socketio.on('message')
|
154 |
+
def handle_message(message):
|
155 |
+
r = message
|
156 |
+
username = ""
|
157 |
+
cookie = ""
|
158 |
+
roomID = ""
|
159 |
+
msg = ""
|
160 |
+
try:
|
161 |
+
if (len(json.loads(message['data'])['message']) > 0):
|
162 |
+
app.config['tab']['usid'][json.loads(message['data'])['usid']] = {
|
163 |
+
'tmp-img': ""
|
164 |
+
}
|
165 |
+
join_room(json.loads(message['data'])['roomID'])
|
166 |
+
k = json.loads(message['data'])
|
167 |
+
if k['message'].startswith('\n'):
|
168 |
+
k['message'] = k['message'][1:]
|
169 |
+
username = k["usid"]
|
170 |
+
cookie = k["cookies"].split("; ")[1].replace("uid=", "")
|
171 |
+
if cookie.find("username") != -1:
|
172 |
+
cookie = k["cookies"].split("; ")[0].replace("uid=", "")
|
173 |
+
roomID = k["roomID"]
|
174 |
+
print(username, roomID)
|
175 |
+
msg = k['message']
|
176 |
+
|
177 |
+
if msg == "Connected!":
|
178 |
+
cku = check_user(username, "noPasswdButCookies", cookie)
|
179 |
+
messages = json.loads(cku[1]).get(roomID)
|
180 |
+
for Msg in messages:
|
181 |
+
usid = Msg.split(": \n")[0]
|
182 |
+
emit(
|
183 |
+
'message', {
|
184 |
+
'data':
|
185 |
+
json.dumps(
|
186 |
+
{
|
187 |
+
'message': Msg.replace(usid + ": \n", ""),
|
188 |
+
"usid": usid,
|
189 |
+
"stat": 'restoreHistory'
|
190 |
+
})
|
191 |
+
})
|
192 |
+
r = {'data': json.dumps(k)}
|
193 |
+
k["cookies"] = ""
|
194 |
+
check_user(username,
|
195 |
+
"noPasswdButCookies",
|
196 |
+
cookie,
|
197 |
+
update=True,
|
198 |
+
data={roomID: [msg]})
|
199 |
+
except Exception as e:
|
200 |
+
a = 1
|
201 |
+
try:
|
202 |
+
if r['data'].find('donotsend: true') == -1:
|
203 |
+
emit('message', r, room=json.loads(message['data'])['roomID'])
|
204 |
+
except Exception as e:
|
205 |
+
a = 1
|
206 |
+
|
207 |
+
|
208 |
+
@socketio.on('image')
|
209 |
+
def recv_images(
|
210 |
+
image
|
211 |
+
): # {'data': "{'usid': 1234, 'buf': 'b64MCQU', 'endded': 'bool', 'type': 'png'}"}
|
212 |
+
if app.config['tab']['usid'][json.loads(
|
213 |
+
image['data']).get('usid')] != None:
|
214 |
+
if json.loads(image['data'])['endded'] != 'true':
|
215 |
+
app.config['tab']['usid'][json.loads(
|
216 |
+
image['data'])['usid']]['tmp-img'] += json.loads(
|
217 |
+
image['data'])['buf']
|
218 |
+
else:
|
219 |
+
data = json.dumps({
|
220 |
+
'usid':
|
221 |
+
json.loads(image['data'])['usid'],
|
222 |
+
'ext':
|
223 |
+
json.loads(image['data'])['type'],
|
224 |
+
'file':
|
225 |
+
app.config['tab']['usid'][json.loads(
|
226 |
+
image['data'])['usid']]['tmp-img']
|
227 |
+
})
|
228 |
+
app.config['tab']['usid'][json.loads(
|
229 |
+
image['data'])['usid']]['tmp-img'] = ''
|
230 |
+
data = json.loads(data)
|
231 |
+
data["cookies"] = ""
|
232 |
+
data = json.dumps(data)
|
233 |
+
emit('message', {'data': data},
|
234 |
+
room=json.loads(image['data'])['roomID'])
|
235 |
+
|
236 |
+
|
237 |
+
@socketio.on('save')
|
238 |
+
def handle_message(message):
|
239 |
+
r = message
|
240 |
+
username = ""
|
241 |
+
cookie = ""
|
242 |
+
roomID = ""
|
243 |
+
msg = ""
|
244 |
+
try:
|
245 |
+
if (len(json.loads(message['data'])['message']) > 0):
|
246 |
+
k = json.loads(message['data'])
|
247 |
+
if k['message'].startswith('\n'):
|
248 |
+
k['message'] = k['message'][1:]
|
249 |
+
username = k["usid"]
|
250 |
+
cookie = k["cookies"].split("; ")[1].replace("uid=", "")
|
251 |
+
if cookie.find("username") != -1:
|
252 |
+
cookie = k["cookies"].split("; ")[0].replace("uid=", "")
|
253 |
+
roomID = k["roomID"]
|
254 |
+
msg = k['message']
|
255 |
+
r = {'data': json.dumps(k)}
|
256 |
+
k["cookies"] = ""
|
257 |
+
check_user(username,
|
258 |
+
"noPasswdButCookies",
|
259 |
+
cookie,
|
260 |
+
update=True,
|
261 |
+
data={roomID: [msg]})
|
262 |
+
except Exception as e:
|
263 |
+
a = 1
|
264 |
+
|
265 |
+
|
266 |
+
if __name__ == '__main__':
|
267 |
+
socketio.run(app, host="0.0.0.0", port=80)
|