-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdbFunctions.py
More file actions
279 lines (214 loc) · 10.4 KB
/
dbFunctions.py
File metadata and controls
279 lines (214 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
""" dbFunctions.py
COMPSYS302 - Software Design - Python Project
Author: Savi Mohan (smoh944@auckland.ac.nz)
Last Edited: 11/06/2017
This program uses the CherryPy web server (from www.cherrypy.org).
This file contains database functions called by MainFile.py
"""
DB_USER_DATA = "sqliteDatabase.db"
import cherrypy
import hashlib
import urllib
import urllib2
import sqlite3
import json
import time
import os #used to figure out what operating system this is running on
import webbrowser
import socket
import thread
import base64
import markdown
def clearRateRequestTable():
"""Clears the requestNumbers column in the RateRequest table to 0"""
conn = sqlite3.connect(DB_USER_DATA)
# Once we have a Connection, we can create a Cursor object and call its execute() method to perform SQL commands
c = conn.cursor()
c.execute("UPDATE RequestRate SET requestsNumber = 0")
conn.commit()
conn.close()
def checkIfRateLimited(requestor=None):
"""Takes in a username and determines whether that user has exceeded the allowable request rate"""
rateLimited = False
try:
if (requestor == cherrypy.session['username']): #Don't ratelimit the session user
return rateLimited
except:
pass
conn = sqlite3.connect(DB_USER_DATA)
# Once we have a Connection, we can create a Cursor object and call its execute() method to perform SQL commands
c = conn.cursor()
try:
if(not(requestor == None)):
c.execute('SELECT * FROM RequestRate WHERE (requestor=? )', (requestor,))
data = c.fetchone()
if data is None: #Insert requestor into table if they aren't already on it
c.execute('INSERT INTO RequestRate (requestor,requestsNumber) VALUES (?,?)', (requestor,1))
else:
c.execute('''UPDATE RequestRate SET requestsNumber = ? WHERE requestor = ?''',(data[2]+1, requestor))
if(data[2]>8): #if the number of requests for this user exceeds 8, then rate limit them
rateLimited = True
except:
pass
conn.commit()
conn.close()
return rateLimited
def createRequestRateTable():
"""Creates a table to monitor the number of requests from users"""
conn = sqlite3.connect(DB_USER_DATA)
# Once we have a Connection, we can create a Cursor object and call its execute() method to perform SQL commands
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS RequestRate (id INTEGER PRIMARY KEY, requestor TEXT, requestsNumber INTEGER)''')
conn.commit()
conn.close()
def createClientProfilesTable():
"""Creates a table to store user profile details. This table also allows us to support multiple user sessions on the same application"""
conn = sqlite3.connect(DB_USER_DATA)
# Once we have a Connection, we can create a Cursor object and call its execute() method to perform SQL commands
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS ClientProfiles (id INTEGER PRIMARY KEY, profile_username TEXT, fullname TEXT, position TEXT, description TEXT, location TEXT, picture TEXT, encoding TEXT, encryption TEXT, decryptionKey TEXT)''')
conn.commit()
conn.close()
def populateClientProfilesTable():
"""Updates the ClientProfiles table with usernames from the login server's listUsers api"""
serverUsersRequest = urllib2.Request('http://cs302.pythonanywhere.com/listUsers')
serverUsersResponse = urllib2.urlopen(serverUsersRequest,timeout=5)
serverUsersData = serverUsersResponse.read()
serversUsersList = serverUsersData.split(',')
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
for UPI in serversUsersList:
c.execute("INSERT INTO ClientProfiles (profile_username,picture) SELECT ?,'https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Superman-facebook.svg/658px-Superman-facebook.svg.png' WHERE NOT EXISTS (SELECT * FROM ClientProfiles WHERE profile_username = ?)", (UPI,UPI))
conn.commit() # commit actions to the database
conn.close()
def getClientProfile(profile_username=''):
"""Returns the profile data corresponding to an input username"""
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
c.execute('''SELECT * FROM ClientProfiles WHERE profile_username = ?''', (profile_username,))
profileData = c.fetchone()
conn.close()
return profileData
def getUserData(username=''):
"""Returns the user data corresponding to an input username"""
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
c.execute('''SELECT * FROM AllUsers WHERE username = ?''', (username,))
userData = c.fetchone()
conn.close()
return userData
def createMessagesTable():
"""Creates a table to store all messages"""
conn = sqlite3.connect(DB_USER_DATA)
# Once we have a Connection, we can create a Cursor object and call its execute() method to perform SQL commands
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS Messages (id INTEGER PRIMARY KEY, sender TEXT, destination TEXT, message TEXT, stamp REAL, markdown TEXT, isFile TEXT, fileLink TEXT, fileType TEXT, fileName TEXT)''')
conn.commit()
conn.close()
def getMessages(sender, destination):
"""Returns all the messages stored in the database that correspond to the two input usernames"""
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
c.execute('''SELECT * FROM Messages WHERE ((sender=? AND destination=?)OR (sender=? AND destination=?)) order by stamp ''',(sender,destination,destination,sender))
messages = c.fetchall()
conn.commit()
conn.close()
return messages
def getMessagesForOneUser(destination=''):
"""Returns all the messages stored in the database which have a destination that corresponds to the input username """
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
c.execute('''SELECT * FROM Messages WHERE ( destination=?) order by stamp ''',(destination))
messages = c.fetchall()
conn.commit()
conn.close()
return messages
def insertIntoMessagesTable(sender = None, destination = None, message = None, stamp = None, markdown = '0',isFile = 'false', fileLink = None, fileType = None,fileName=None):
"""Inserts a message and its metadata in its own row in the Messages table as long as it doesn't already exist in the table """
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
c.execute('SELECT * FROM Messages WHERE (sender=? AND destination=? AND message=? AND stamp=?)', (sender, destination, message,stamp))
data = c.fetchone()
if data is None:#if input message is not in table, then insert it
c.execute('INSERT INTO Messages (sender,destination,message,stamp,markdown,isFile,fileLink,fileType,fileName) VALUES (?,?,?,?,?,?,?,?,?)', (sender,destination,message,stamp,markdown,isFile,fileLink,fileType,fileName))
conn.commit()
conn.close()
def createAllUsersTable():
"""Creates a table to store all the users details/data"""
conn = sqlite3.connect(DB_USER_DATA)
# Once we have a Connection, we can create a Cursor object and call its execute() method to perform SQL commands
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS AllUsers (id INTEGER PRIMARY KEY, username TEXT, ip TEXT, location TEXT, lastLogin TEXT, port TEXT, status TEXT, publicKey TEXT)''')
conn.commit()
conn.close()
def populateAllUsersTable():
"""Populates the AllUsers table with usernames from the login server's listUsers API"""
serverUsersRequest = urllib2.Request('http://cs302.pythonanywhere.com/listUsers')
serverUsersResponse = urllib2.urlopen(serverUsersRequest,timeout=10)
serverUsersData = serverUsersResponse.read()
serversUsersList = serverUsersData.split(',')
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
c.execute("UPDATE AllUsers SET status = 'Offline'")
for UPI in serversUsersList:
c.execute("INSERT INTO AllUsers (username) SELECT ? WHERE NOT EXISTS (SELECT * FROM AllUsers WHERE username = ?)", (UPI,UPI))
conn.commit() # commit actions to the database
conn.close()
def updateAllUsersTable(onlineUsersData, firstLogin = False):
"""Updates the AllUsers table with new online user data"""
onlineUsersData = json.loads(onlineUsersData)
serverUsersRequest = urllib2.Request('http://cs302.pythonanywhere.com/listUsers')
serverUsersResponse = urllib2.urlopen(serverUsersRequest,timeout=10)
serverUsersData = serverUsersResponse.read()
serversUsersList = serverUsersData.split(',') #get list of users from server
print 'requesting status data from other online users'
for value in onlineUsersData.itervalues():#loop through each user in the online user data
if(firstLogin == False):
try: #Do a getStatus request on each online user
userData = getUserData(value['username'])
ip = userData[2]
port = userData[5]
output_dict = {'profile_username':value['username']}
data = json.dumps(output_dict) #data is a JSON object
request = urllib2.Request('http://'+ ip + ':' + port + '/getStatus' , data, {'Content-Type':'application/json'})
response = urllib2.urlopen(request,timeout=1).read()
responseDict = json.loads(response)
status = str(responseDict['status'])
if(status.lower()=='online')or(status.lower()=='offline')or(status.lower()=='away')or(status.lower()=='idle')or(status.lower()=='do not disturb'):
pass
else:
status = 'Online'
print ('requesting user status for '+value['username'])
except:
status = 'Online' #If a getStatus request on an online user fails or returns an invalid value, set that user's status in the database to 'Online'
else:
status = 'Online'
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
try:#update a row corresponding to a username
c.execute('''UPDATE AllUsers SET ip = ? , location = ?, lastLogin = ?, port = ?, status = ? WHERE username = ?''', (value['ip'], value['location'], value['lastLogin'], value['port'], status, value['username']))
if value['username'] in serversUsersList:
serversUsersList.remove(value['username'])
except:
pass
try:
c.execute('''UPDATE AllUsers SET publicKey = ? WHERE username = ?''',(value['publicKey'], value['username']))
except:
pass
conn.commit() # commit actions to the database
conn.close()
for user in serversUsersList: #Set the status of the remaining users in the database who are logged off to Offline
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
c.execute('''UPDATE AllUsers SET status = 'Offline' WHERE username = ?''',(user,))
conn.commit() # commit actions to the database
conn.close()
def getAllUsersData():
"""Returns every row in the AllUsers table"""
conn = sqlite3.connect(DB_USER_DATA)
c = conn.cursor()
c.execute("SELECT * FROM AllUsers")
usersData = c.fetchall()
conn.commit()
conn.close()
return usersData