def requestOfflineMessages(self,username,hashedPassword): """Calls the retrieveMessages API of all logged in users to get any messages this client may have received while they were offline""" try: if(dbFunctions.checkIfRateLimited(username)): #check for rate limiting return '11: Blacklisted or Rate Limited' onlineUsersRequest = urllib2.Request('http://cs302.pythonanywhere.com/getList?username='******'&password='******'&enc=0&json=1') onlineUsersResponse = urllib2.urlopen(onlineUsersRequest,timeout=5) onlineUsersData = onlineUsersResponse.read() onlineUsersData = json.loads(onlineUsersData) output_dict = {'requestor':username} data = json.dumps(output_dict) #data is a JSON object for value in onlineUsersData.itervalues():#loop through all online users try: userToRequest = value['username'] if (not(userToRequest == username)): destinationUserData = dbFunctions.getUserData(userToRequest) ip = destinationUserData[2] port = destinationUserData[5] #call retrieveMessages API on all online users request = urllib2.Request('http://'+ ip + ':' + port + '/retrieveMessages', data, {'Content-Type':'application/json'}) response = urllib2.urlopen(request,timeout=1) print('offline messages request response: '+response.read()) except: pass except: print('Error trying to retrieve Offline Messages')
def openMessagingPage(self,destination=None): """Opens the messaging.html page and inserts into it the messages between the logged in user and the destination user """ try: client = cherrypy.session['username'] destinationUserData = dbFunctions.getUserData(destination) #get user data for destination user messages = dbFunctions.getMessages(client,destination)#retrieve all stored messages between these 2 users messages.reverse()#reverse this list so that the newest messages will appear at the top of the page if (not(destinationUserData[4]==None)): lastLogin = (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(float(destinationUserData[4]))))#convert epoch time to readable format else: lastLogin = '' destinationUserDetails = destination+' '+'Last Login:'******' '+destinationUserData[6] userConversation = '' for message in messages: if (str(message[5])=='1'): userMessage = markdown.markdown(message[3])#if markdown flag is 1, then carry out this function else: userMessage = message[3] if((client==message[1])and(destination==message[2])):#message sent by client userConversation += ('<li class="i"> <div class="head"> <span class="time">'+(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(float(message[4]))))+'</span> <span class="name">You</span> </div> <div class="message">'+userMessage+'</div> </li>') elif((client==message[2])and(destination==message[1])):#message sent from destination userConversation += ('<li class="friend"> <div class="head"> <span class="name">'+destination+'</span> <span class="time">'+(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(float(message[4]))))+'</span> </div> <div class="message">'+userMessage+'</div> </li>') Page = open('messaging.html').read().format(receiverUsername = destination, senderUsername = client,userDetails = destinationUserDetails,userMessages=userConversation) return Page except: pass raise cherrypy.HTTPRedirect('/login') #redirect back to login page
def sendFile(self, sender=None, destination=None, outFile=None,stamp = None,encryption=0, hashing = 0, hashedFile = None, decryptionKey=None): """Allows the client to send another user a file and its metadata""" try: if(dbFunctions.checkIfRateLimited(sender)): #Check for rate limiting return '11: Blacklisted or Rate Limited' destinationUserData = dbFunctions.getUserData(destination) ip = destinationUserData[2] port = destinationUserData[5] if (stamp == None)or(stamp== ''):#if no stamp value is provided, generate one stamp = float(time.time()) fileName = outFile.filename content_type = outFile.content_type.value print (fileName + ' is preparing to be sent') encoded = base64.b64encode(outFile.file.read())#encode file to base64 output_dict = {'sender':sender,'destination':destination,'file':encoded, 'stamp':stamp, 'filename':fileName,'content_type':content_type, 'encryption':encryption, 'hashing':hashing, 'hash': hashedFile}#, 'decryptionKey':decryptionKey} data = json.dumps(output_dict) #data is a JSON object sendResponse = ' ' fileSentOffline = False try: request = urllib2.Request('http://'+ ip + ':' + port + '/receiveFile' , data, {'Content-Type':'application/json'}) response = urllib2.urlopen(request,timeout=5) sendResponse = response.read() print ('file send response: '+sendResponse) except: #if the user is offline, send the file to other online users thread.start_new_thread(OfflineMessaging.sendOfflineFile, (data, cherrypy.session['username'], cherrypy.session['hashedPassword'])) fileSentOffline = True #Depending on the content_type of the file, an html line of code will be stored in the database so that file can be viewed in an embedded form in the messages page if 'image/' in output_dict['content_type']: fileMessage = '<img src="receivedFiles/'+fileName+'" alt= Picture 380x320 height="320" width="380">'#embedded image elif 'video/' in output_dict['content_type']: fileMessage = '<video width="380" height="320" controls><source src="'+'receivedFiles/'+fileName+'">Your browser does not support the video tag.</video>'#embedded video elif 'audio/' in output_dict['content_type']: fileMessage = '<audio controls> <source src="'+'receivedFiles/'+fileName+'">Your browser does not support the audio element.</audio>'#embedded audio else: fileMessage = '<a href="receivedFiles/'+fileName+'" download>'+fileName +'</a>'#embedded download link if (str(sendResponse[0]) == '0')or(str(sendResponse[1]) == '0')or(fileSentOffline == True): #save the file in the receivedFiles folder saveFile = open('public/receivedFiles/'+fileName,'wb') saveFile.write((output_dict['file']).decode('base64')) saveFile.close dbFunctions.insertIntoMessagesTable(output_dict['sender'], output_dict['destination'], fileMessage, output_dict['stamp'], '0','true', fileName, content_type) else: print 'file send confirmation not received' except: print 'file send error' if(sender==None)or(destination==None): raise cherrypy.HTTPRedirect('/login') raise cherrypy.HTTPRedirect('/openMessagingPage?destination='+destination)
def getStatus(self): """This API allows another client to request information about the current status of the user operating this client. The valid values to be returned are {Online, Idle, Away, Do Not Disturb, Offline}.""" try: input = cherrypy.request.json if(not('profile_username' in input)): return '1: Missing Compulsory Field' userStatus = dbFunctions.getUserData(input['profile_username'])#get user status from database outputDict = {'status':userStatus[6]} return json.dumps(outputDict) except: return '3: Client Currently Unavailable'
def sendMessage(self, sender=None, destination=None, message='Default Message',markDown='0',stamp=None,encryption=0, hashing = 0, hashedMessage = None, decryptionKey=None): """This function allows the logged in client to send a message and its metadata to another user""" try: if(dbFunctions.checkIfRateLimited(sender)): #Check for rate limiting return '11: Blacklisted or Rate Limited' if ((message == None)or(message == '')): #if the message field is empty redirect back to the messaging page raise cherrypy.HTTPRedirect('/openMessagingPage?destination='+destination) destinationUserData = dbFunctions.getUserData(destination) ip = destinationUserData[2] port = destinationUserData[5] if (stamp == None)or(stamp== ''):#generate stamp if it doesn't already exist stamp = float(time.time()) output_dict = {'sender':sender,'destination':destination,'message':message, 'stamp':stamp, 'markdown':int(markDown), 'encryption':encryption, 'hashing':hashing, 'hash': hashedMessage, 'decryptionKey':decryptionKey} data = json.dumps(output_dict) #data is a JSON object try: request = urllib2.Request('http://'+ ip + ':' + port + '/receiveMessage', data, {'Content-Type':'application/json'}) response = urllib2.urlopen(request,timeout=5) print response.read() except: #send message offline if the destination user is offline message = 'Msg Sent Offline: ' + message output_dict = {'sender':sender,'destination':destination,'message':message, 'stamp':stamp, 'markdown':int(markDown), 'encryption':encryption, 'hashing':hashing, 'hash': hashedMessage, 'decryptionKey':decryptionKey} data = json.dumps(output_dict) #data is a JSON object #call sendOfflineMessage function on its own thread, so that the rest of the program doesn't have to wait on it. thread.start_new_thread(OfflineMessaging.sendOfflineMessage, (data, cherrypy.session['username'], cherrypy.session['hashedPassword'])) if (str(markDown)=='1'): message = markdown.markdown(output_dict['message']) #save message in database dbFunctions.insertIntoMessagesTable(output_dict['sender'], output_dict['destination'], message, output_dict['stamp'], int(markDown),'false', None,None) except: print 'send message error' if(sender==None)or(destination==None): raise cherrypy.HTTPRedirect('/login') #redirect back to messaging page raise cherrypy.HTTPRedirect('/openMessagingPage?destination='+destination)
def viewProfilePage(self,username=None): """Opens the viewProfile.html page and inserts into it the profile data that corresponds to the input username """ try: client = cherrypy.session['username'] except: raise cherrypy.HTTPRedirect('/login')#if no client is logged in then redirect back to the login page try: if username == None: username = client if (client == username): #The current logged in user requesting to see their own profile page, so no need to do an external getProfile request clientData = dbFunctions.getClientProfile(client) Page = open('viewProfile.html').read().format(profileHeading = 'MY',UPI = client,fullname=clientData[2],position=clientData[3],description=clientData[4],location=clientData[5],image=clientData[6]) return Page else: userData = dbFunctions.getUserData(username) #get user data of the profile to display ip = userData[2] port = userData[5] output_dict = {'sender':client,'profile_username':username} data = json.dumps(output_dict) #data is a JSON object request = urllib2.Request('http://'+ ip + ':' + port + '/getProfile' , data, {'Content-Type':'application/json'}) #Do a getProfile request to the user response = urllib2.urlopen(request,timeout=5).read() responseDict = (json.loads(response)) Page = open('viewProfile.html').read().format(profileHeading = 'USER',UPI = username,fullname=responseDict['fullname'],position=responseDict['position'],description=responseDict['description'],location=responseDict['location'],image=responseDict['picture']) return Page except: Page = open('viewProfile.html').read().format(profileHeading = 'No data available for USER',UPI = username,fullname='',position='',description='',location='',image='') return Page