def handleInitiate(torId, displayName): '''We have requested contact with another id, so we can set up this new contact's name with a status of "requested"''' # TODO: If row already exists then get status (and name/displayname) and error with it # Add new row in db with id, name and "requested" if torId and torId != DbClient.getOwnTorId(): DbClient.updateContact(torId, {'displayName':displayName, 'name':displayName, 'status':'requested'})
def servePage(self, view, url, params): print("Special function:", url) if url == "/selectprofilepic": # Get home directory for file dialog homedir = os.path.expanduser("~/") fname = QtGui.QFileDialog.getOpenFileName(view, I18nManager.getText("gui.dialogtitle.openimage"), homedir, I18nManager.getText("gui.fileselection.filetypes.jpg")) if fname: view.page().mainFrame().evaluateJavaScript("updateProfilePic('" + fname + "');") elif url == "/friendstorm": if not DbClient.hasFriends(): view.page().mainFrame().evaluateJavaScript("window.alert('No friends :(');") return # Launch a storm self.bs = Brainstorm(I18nManager.getText("contacts.storm.title")) self.bs.show() storm = Storm() # Build up Nodes and Edges using our contact list and if possible our friends' contact lists myTorId = DbClient.getOwnTorId() friends = {} friendsOfFriends = {} for c in DbClient.getContactList(): #print("Contact:", c['torid'], "'", c['displayName'], "'") nodeid = storm.getUnusedNodeId() torid = c['torid'] friends[torid] = nodeid storm.addNode(Node(None, nodeid, c['displayName'])) friendsOfFriends[torid] = c.get('contactlist', "") for torid in friends: if torid != myTorId: storm.addEdge(friends[torid], friends[myTorId]) for torid in friendsOfFriends: if torid != myTorId: ffList = friendsOfFriends[torid] if ffList: for ff in ffList.split(","): if ff and len(ff) > 16: ffTorid = ff[:16] ffName = ff[16:] if ffTorid != myTorId: if not friends.get(ffTorid, None): # Friend's friend is not in the list yet - add it nodeid = storm.getUnusedNodeId() friends[ffTorid] = nodeid storm.addNode(Node(None, nodeid, ffName)) # Add edge from torid to ffTorid storm.addEdge(friends[torid], friends[ffTorid]) self.bs.setStorm(storm)
def generateListPage(self, doEdit=False, userid=None, extraParams=None): self.requirePageResources(['avatar-none.jpg', 'status-self.png', 'status-requested.png', 'status-untrusted.png', 'status-trusted.png']) # List of contacts, and show details for the selected one (or self if userid=None) selectedprofile = DbClient.getProfile(userid) if selectedprofile is None: selectedprofile = DbClient.getProfile() userid = selectedprofile['torid'] ownPage = userid == DbClient.getOwnTorId() # Build list of contacts userboxes = [] for p in DbClient.getContactList(): box = Bean() box.dispName = p['displayName'] box.torid = p['torid'] box.tilestyle = "contacttile" + ("selected" if p['torid'] == userid else "") box.status = p['status'] box.isonline = Contacts.isOnline(box.torid) userboxes.append(box) # expand templates using current details lefttext = self.listtemplate.getHtml({'webcachedir' : Config.getWebCacheDir(), 'contacts' : userboxes}) pageProps = {"webcachedir" : Config.getWebCacheDir(), 'person':selectedprofile} # Add extra parameters if necessary if extraParams: pageProps.update(extraParams) # See which contacts we have in common with this person (sharedContactIds, possIdsForThem, possIdsForMe, nameMap) = ContactMaker.getSharedAndPossibleContacts(userid) sharedContacts = self._makeIdAndNameBeanList(sharedContactIds, nameMap) pageProps.update({"sharedcontacts" : sharedContacts}) possibleContacts = self._makeIdAndNameBeanList(possIdsForThem, nameMap) pageProps.update({"possiblecontactsforthem" : possibleContacts}) possibleContacts = self._makeIdAndNameBeanList(possIdsForMe, nameMap) pageProps.update({"possiblecontactsforme" : possibleContacts}) # Which template to use depends on whether we're just showing or also editing if doEdit: # Use two different details templates, one for self and one for others detailstemplate = self.editowndetailstemplate if ownPage else self.editdetailstemplate righttext = detailstemplate.getHtml(pageProps) else: detailstemplate = self.detailstemplate # just show righttext = detailstemplate.getHtml(pageProps) contents = self.buildTwoColumnPage({'pageTitle' : I18nManager.getText("contacts.title"), 'leftColumn' : lefttext, 'rightColumn' : righttext, 'pageFooter' : "<p>Footer</p>"}) return contents
def _createSubpayload(self): '''Use the stored fields to pack the payload contents together''' if self.senderKey is None: self.senderKey = self.getOwnPublicKey() # Get own torid and name if not self.senderId: self.senderId = DbClient.getOwnTorId() if not self.senderName: self.senderName = DbClient.getProfile(None).get('name', self.senderId) if not self.introMessage: self.introMessage = "" nameAsBytes = self.senderName.encode('utf-8') messageAsBytes = self.introMessage.encode('utf-8') print("Packing contact request with senderId", self.senderId) return self.packBytesTogether([ self.senderId, self.encodeNumberToBytes(len(nameAsBytes), 4), nameAsBytes, self.encodeNumberToBytes(len(messageAsBytes), 4), messageAsBytes, self.senderKey])
def getSharedAndPossibleContacts(torid): '''Check which contacts we share with the given torid and which ones we could recommend to each other''' nameMap = {} ourContactIds = set() trustedContactIds = set() theirContactIds = set() # Get our id so we can exclude it from the sets myTorId = DbClient.getOwnTorId() if torid == myTorId: return (None, None, None, None) # Find the contacts of the specified person selectedProfile = DbClient.getProfile(torid, False) selectedContacts = selectedProfile.get('contactlist', None) if selectedProfile else None if selectedContacts: for s in selectedContacts.split(","): if s and len(s) >= 16: foundid = s[0:16] if foundid != myTorId: foundName = s[16:] theirContactIds.add(foundid) nameMap[foundid] = foundName foundTheirContacts = len(theirContactIds) > 0 # Now get information about our contacts for c in DbClient.getMessageableContacts(): foundid = c['torid'] ourContactIds.add(foundid) if c['status'] == 'trusted' and foundid != torid: trustedContactIds.add(foundid) nameMap[foundid] = c.get('displayName', c.get('name', None)) # Should we check the contact information too? if not foundTheirContacts: foundContacts = c.get('contactlist', None) if foundContacts: for s in foundContacts.split(","): if s[0:16] == torid: theirContactIds.add(foundid) # Now we have three sets of torids: our contacts, our trusted contacts, and their contacts. sharedContactIds = ourContactIds.intersection(theirContactIds) # might be empty suggestionsForThem = trustedContactIds.difference(theirContactIds) possibleForMe = theirContactIds.difference(ourContactIds) # Some or all of these sets may be empty, but we still return the map so we can look up names return (sharedContactIds, suggestionsForThem, possibleForMe, nameMap)
def servePage(self, view, url, params): print("Compose: %s, params %s" % (url, ",".join(params))) if url == "/start": self.requirePageResources(['default.css']) parentHash = params.get("reply", None) recpts = params.get("sendto", None) # Build list of contacts to whom we can send userboxes = [] for p in DbClient.getMessageableContacts(): box = Bean() box.dispName = p['displayName'] box.torid = p['torid'] userboxes.append(box) pageParams = {"contactlist":userboxes, "parenthash" : parentHash if parentHash else "", "webcachedir":Config.getWebCacheDir(), "recipientids":recpts} contents = self.buildPage({'pageTitle' : I18nManager.getText("composemessage.title"), 'pageBody' : self.composetemplate.getHtml(pageParams), 'pageFooter' : "<p>Footer</p>"}) view.setHtml(contents) # If we've got no friends, then warn, can't send to anyone if not DbClient.hasFriends(): view.page().mainFrame().evaluateJavaScript("window.alert('No friends :(');") elif url == "/send": print("Submit new message with params:", params) msgBody = params['messagebody'] # TODO: check body isn't empty, throw an exception? parentHash = params.get("parenthash", None) recpts = params['sendto'] # Make a corresponding message object and pass it on msg = message.RegularMessage(sendTo=recpts, messageBody=msgBody, replyToHash=parentHash) msg.recipients = recpts.split(",") DbClient.addMessageToOutbox(msg) # Save a copy of the sent message sentMessage = {"messageType":"normal", "fromId":DbClient.getOwnTorId(), "messageBody":msgBody, "timestamp":msg.timestamp, "messageRead":True, "messageReplied":False, "recipients":recpts, "parentHash":parentHash} DbClient.addMessageToInbox(sentMessage) # Close window after successful send contents = self.buildPage({'pageTitle' : I18nManager.getText("messages.title"), 'pageBody' : self.closingtemplate.getHtml(), 'pageFooter' : "<p>Footer</p>"}) view.setHtml(contents)
def getOwnTorId(): if not MessageShuffler.ownTorId: MessageShuffler.ownTorId = DbClient.getOwnTorId() return MessageShuffler.ownTorId
def _createUnencryptedPayload(self): if self.senderId is None: self.senderId = DbClient.getOwnTorId() return self.packBytesTogether([ self.encodeNumberToBytes(self.messageType, 1), self.senderId, self._createSubpayload()])
def handleDeleteContact(torId): '''For whatever reason, we don't trust this contact any more, so status is set to "deleted"''' if torId and torId != DbClient.getOwnTorId(): DbClient.updateContact(torId, {"status" : "deleted"})
def handleReceiveDeny(torId): '''We have requested contact with another id, but this has been denied. So we need to update their status accordingly''' if torId and torId != DbClient.getOwnTorId(): DbClient.updateContact(torId, {"status" : "deleted"})
def generateAddPage(self): '''Build the form page for adding a new user, using the template''' bodytext = self.addtemplate.getHtml({"owntorid" : DbClient.getOwnTorId()}) return self.buildPage({'pageTitle' : I18nManager.getText("contacts.title"), 'pageBody' : bodytext, 'pageFooter' : "<p>Footer</p>"})