Esempio n. 1
0
	def servePage(self, view, url, params):
		if url == "/edit":
			selectedLang = params.get('lang', None)
			if selectedLang and len(selectedLang) == 2:
				Config.setProperty(Config.KEY_LANGUAGE, selectedLang)
				# I18nManager will be triggered here because it listens to the Config
			fsf = params.get('friendsseefriends', None)
			friendsseefriends = fsf is not None and len(fsf) > 0
			Config.setProperty(Config.KEY_ALLOW_FRIENDS_TO_SEE_FRIENDS, friendsseefriends)
			slw = params.get('showlogwindow', None)
			showlogwindow = slw is not None and len(slw) > 0
			Config.setProperty(Config.KEY_SHOW_LOG_WINDOW, showlogwindow)
			# If Config has changed, may need to update profile to include/hide friends info
			DbClient.updateContactList(friendsseefriends)
			# When friends are notified next time, the profile's hash will be calculated and sent
			afw = params.get('allowfriendrequests', None)
			allowfriendrequests = afw is not None and len(afw) > 0
			Config.setProperty(Config.KEY_ALLOW_FRIEND_REQUESTS, allowfriendrequests)
			# Save config to file in case it's changed
			Config.save()
			contents = self.buildPage({'pageTitle' : I18nManager.getText("settings.title"),
				'pageBody' : "<p>Settings changed... should I go back to settings or back to home now?</p>",
				'pageFooter' : "<p>Footer</p>"})
			view.setHtml(contents)
		else:
			pageProps = {"friendsseefriends" : "checked" if Config.getProperty(Config.KEY_ALLOW_FRIENDS_TO_SEE_FRIENDS) else "",
				"allowfriendrequests" : "checked" if Config.getProperty(Config.KEY_ALLOW_FRIEND_REQUESTS) else "",
				"showlogwindow" : "checked" if Config.getProperty(Config.KEY_SHOW_LOG_WINDOW) else "",
				"language_en":"", "language_de":""}
			pageProps["language_" + Config.getProperty(Config.KEY_LANGUAGE)] = "selected"
			#print("body:", self.formtemplate.getHtml(pageProps))
			contents = self.buildPage({'pageTitle' : I18nManager.getText("settings.title"),
				'pageBody' : self.formtemplate.getHtml(pageProps),
				'pageFooter' : "<p>Footer</p>"})
			view.setHtml(contents)
Esempio n. 2
0
 def servePage(self, view, url, params):
     if url == "/edit":
         selectedLang = params.get('lang', None)
         if selectedLang and len(selectedLang) == 2:
             Config.setProperty(Config.KEY_LANGUAGE, selectedLang)
             # I18nManager will be triggered here because it listens to the Config
         fsf = params.get('friendsseefriends', None)
         friendsseefriends = fsf is not None and len(fsf) > 0
         Config.setProperty(Config.KEY_ALLOW_FRIENDS_TO_SEE_FRIENDS,
                            friendsseefriends)
         slw = params.get('showlogwindow', None)
         showlogwindow = slw is not None and len(slw) > 0
         Config.setProperty(Config.KEY_SHOW_LOG_WINDOW, showlogwindow)
         # If Config has changed, may need to update profile to include/hide friends info
         DbI.updateContactList(friendsseefriends)
         # When friends are notified next time, the profile's hash will be calculated and sent
         afw = params.get('allowfriendrequests', None)
         allowfriendrequests = afw is not None and len(afw) > 0
         Config.setProperty(Config.KEY_ALLOW_FRIEND_REQUESTS,
                            allowfriendrequests)
         # Save config to file in case it's changed
         Config.save()
         contents = self.buildPage({
             'pageTitle':
             I18nManager.getText("settings.title"),
             'pageBody':
             "<p>Settings changed... should I go back to settings or back to home now?</p>",
             'pageFooter':
             "<p>Footer</p>"
         })
         view.setHtml(contents)
     else:
         pageProps = {
             "friendsseefriends":
             "checked" if Config.getProperty(
                 Config.KEY_ALLOW_FRIENDS_TO_SEE_FRIENDS) else "",
             "allowfriendrequests":
             "checked" if Config.getProperty(
                 Config.KEY_ALLOW_FRIEND_REQUESTS) else "",
             "showlogwindow":
             "checked"
             if Config.getProperty(Config.KEY_SHOW_LOG_WINDOW) else "",
             "language_en":
             "",
             "language_de":
             ""
         }
         pageProps["language_" +
                   Config.getProperty(Config.KEY_LANGUAGE)] = "selected"
         #print("body:", self.formtemplate.getHtml(pageProps))
         contents = self.buildPage({
             'pageTitle':
             I18nManager.getText("settings.title"),
             'pageBody':
             self.formtemplate.getHtml(pageProps),
             'pageFooter':
             "<p>Footer</p>"
         })
         view.setHtml(contents)
Esempio n. 3
0
 def enableButtons(self, card):
     '''Ask the card what the button texts and enabled status should be'''
     backKey, nextKey = card.getButtonKeys()
     self.backButton.setText(I18nManager.getText("button." + backKey))
     self.nextButton.setText(I18nManager.getText("button." + nextKey))
     backEnabled, nextEnabled = card.getButtonsEnabled()
     self.backButton.setEnabled(backEnabled)
     self.nextButton.setEnabled(nextEnabled)
Esempio n. 4
0
	def enableButtons(self, card):
		'''Ask the card what the button texts and enabled status should be'''
		backKey, nextKey = card.getButtonKeys()
		self.backButton.setText(I18nManager.getText("button." + backKey))
		self.nextButton.setText(I18nManager.getText("button." + nextKey))
		backEnabled, nextEnabled = card.getButtonsEnabled()
		self.backButton.setEnabled(backEnabled)
		self.nextButton.setEnabled(nextEnabled)
Esempio n. 5
0
    def __init__(self, *args):
        self.logPanel = LogWindow()
        GuiWindow.__init__(self, lowerItem=self.logPanel)
        self.clearWebCache()
        self.postmen = None
        self.toolbar = self.makeToolbar([
            ("images/toolbar-home.png", self.onHomeClicked,
             "mainwindow.toolbar.home"),
            ("images/toolbar-people.png", self.onContactsClicked,
             "mainwindow.toolbar.contacts"),
            ("images/toolbar-messages.png", self.onMessagesClicked,
             "mainwindow.toolbar.messages"),
            ("images/toolbar-messages-highlight.png", self.onMessagesClicked,
             "mainwindow.toolbar.messages"),
            ("images/toolbar-calendar.png", self.onCalendarClicked,
             "mainwindow.toolbar.calendar"),
            ("images/toolbar-settings.png", self.onSettingsClicked,
             "mainwindow.toolbar.settings")
        ])
        self.addToolBar(self.toolbar)
        self.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
        # status bar
        self.statusbar = QtWidgets.QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)

        self.setWindowTitle(I18nManager.getText("mainwindow.title"))

        self.setStatusTip("Murmeli")
        self.setPageServer(PageServer())
        self.navigateTo("/")
        # we want to be notified of Config changes
        Config.registerSubscriber(self)
        self.postmen = [
            postmen.IncomingPostman(self),
            postmen.OutgoingPostman(self)
        ]
        self.postmen[1].messageSentSignal.connect(self.logPanel.notifyLogEvent)
        MessageShuffler.getTannoy().updateSignal.connect(
            self.logPanel.notifyLogEvent)
        # Make sure Tor client is started
        if not TorClient.isStarted():
            TorClient.startTor()
        # Create database instance if not already set
        if not DbI.hasDbSet():
            DbI.setDb(MurmeliDb(Config.getSsDatabaseFile()))
        # Make sure the status of the contacts matches our keyring
        missingKeyNames = ContactMaker.checkAllContactsKeys()
        if missingKeyNames:
            warningTexts = [I18nManager.getText("warning.keysnotfoundfor")
                            ] + missingKeyNames
            QtWidgets.QMessageBox.warning(self, "Murmeli",
                                          "\n   ".join(warningTexts))
Esempio n. 6
0
	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)
Esempio n. 7
0
	def servePage(self, view, url, params):
		DbClient.exportAvatars(Config.getWebCacheDir())
		if url == "/send":
			print("send message of type '%(messageType)s' to id '%(sendTo)s'" % params)
		elif url.startswith("/delete/"):
			DbClient.deleteMessageFromInbox(params.get("msgId", ""))
		# Make dictionary to convert ids to names
		contactNames = {c['torid']:c['displayName'] for c in DbClient.getContactList()}
		unknownSender = I18nManager.getText("messages.sender.unknown")
		unknownRecpt = I18nManager.getText("messages.recpt.unknown")
		# Get contact requests, responses and mails from inbox
		conreqs = []
		conresps = []
		mails = []
		for m in DbClient.getInboxMessages():
			m['msgId'] = str(m.get("_id", ""))
			if m['messageType'] == "contactrequest":
				conreqs.append(m)
			elif m['messageType'] == "contactrefer":
				senderId = m.get('fromId', None)
				m['senderName'] = contactNames.get(senderId, unknownSender)
				conreqs.append(m)
			elif m['messageType'] == "contactresponse":
				if not m.get('accepted', False):
					m['messageBody'] = I18nManager.getText("messages.contactrequest.refused")
					m['fromName'] = DbClient.getProfile(m['fromId'], True).get("displayName")
				elif not m.get('messageBody', False):
					m['messageBody'] = I18nManager.getText("messages.contactrequest.accepted")
				conresps.append(m)
			else:
				senderId = m.get('fromId', None)
				if not senderId and m.get('signatureKeyId', None):
					senderId = DbClient.findUserIdFromKeyId(m['signatureKeyId'])
				m['senderName'] = contactNames.get(senderId, unknownSender)
				m['sentTimeStr'] = self.makeLocalTimeString(m['timestamp'])
				# Split m['recipients'] by commas, and look up each id with contactNames
				recpts = m.get('recipients', '')
				if recpts:
					m['recipients'] = ", ".join([contactNames.get(i, unknownRecpt) for i in recpts.split(",")])
				else:
					m['recipients'] = unknownRecpt
				mails.append(m)
		bodytext = self.messagestemplate.getHtml({"contactrequests":conreqs, "contactresponses":conresps,
			"mails":mails, "nummessages":len(conreqs)+len(conresps)+len(mails),
			"webcachedir" : Config.getWebCacheDir()})
		contents = self.buildPage({'pageTitle' : I18nManager.getText("messages.title"),
			'pageBody' : bodytext,
			'pageFooter' : "<p>Footer</p>"})
		view.setHtml(contents)
Esempio n. 8
0
	def generateFingerprintsPage(self, userid):
		'''Build the page for checking the fingerprints of the selected user'''
		# First, get the name of the user
		person = DbClient.getProfile(userid, False)
		dispName = person.get('displayName', '')
		fullName = person.get('name', '')
		if not dispName: dispName = fullName
		if dispName != fullName:
			fullName = dispName + " (" + fullName + ")"
		fc = self._makeFingerprintChecker(userid)
		# check it's ok to generate
		status = person.get('status', '')
		if not fc.valid \
		  or status not in ['untrusted', 'trusted']:
			print("Not generating fingerprints page because status is", status)
			return None

		# Get one set of words for us and three sets for them
		printsAlreadyChecked = (person.get('status', '') == "trusted")
		bodytext = self.fingerprintstemplate.getHtml(
			{"mywords":fc.getCodeWords(True, 0, "en"), "theirwords0":fc.getCodeWords(False, 0, "en"),
			 "theirwords1":fc.getCodeWords(False, 1, "en"), "theirwords2":fc.getCodeWords(False, 2, "en"),
			 "fullname":fullName, "shortname":dispName, "userid":userid, "alreadychecked":printsAlreadyChecked})
		return self.buildPage({'pageTitle' : I18nManager.getText("contacts.title"),
			'pageBody' : bodytext,
			'pageFooter' : "<p>Footer</p>"})
Esempio n. 9
0
 def _makeHeadingLabel(self, token):
     '''Convenience method for making a bold label for each panel'''
     label = QtWidgets.QLabel(I18nManager.getText(token))
     boldFont = label.font()
     boldFont.setWeight(QtGui.QFont.Bold)
     boldFont.setPointSize(boldFont.pointSize() + 1)
     label.setFont(boldFont)
     return label
Esempio n. 10
0
	def _makeHeadingLabel(self, token):
		'''Convenience method for making a bold label for each panel'''
		label = QtGui.QLabel(I18nManager.getText(token))
		boldFont = label.font()
		boldFont.setWeight(QtGui.QFont.Bold)
		boldFont.setPointSize(boldFont.pointSize() + 1)
		label.setFont(boldFont)
		return label
Esempio n. 11
0
 def configUpdated(self):
     '''React to a change in settings by changing tooltips and log panel visibility'''
     for a in self.toolbarActions:
         a.setToolTip(I18nManager.getText(a.tooltipkey))
     # Show/hide log window
     if Config.getProperty(Config.KEY_SHOW_LOG_WINDOW):
         self.logPanel.show()
     else:
         self.logPanel.hide()
Esempio n. 12
0
 def finishedServiceCheck(self):
     '''Called when service check has been completed by the other thread'''
     self.updatedServiceCheck()  # make sure all icons are updated
     self.checksDone = True
     self.allOk = self.checkerThread.allGood()
     self.servicesCheckLabel.setText(I18nManager.getText("startupwizard.services." + \
      ("allstarted" if self.allOk else "notallstarted")))
     self.labels["abouttostart"].setVisible(False)
     # emit signal back to controller
     self.redrawNavButtonsSignal.emit()
Esempio n. 13
0
 def servePage(self, view, url, params):
     contents = self.buildPage({
         'pageTitle':
         I18nManager.getText("calendar.title"),
         'pageBody':
         self.calendartemplate.getHtml(),
         'pageFooter':
         "<p>Footer</p>"
     })
     view.setHtml(contents)
Esempio n. 14
0
	def finishedServiceCheck(self):
		'''Called when service check has been completed by the other thread'''
		self.updatedServiceCheck()  # make sure all icons are updated
		self.checksDone = True
		self.allOk = self.checkerThread.allGood()
		self.servicesCheckLabel.setText(I18nManager.getText("startupwizard.services." + \
			("allstarted" if self.allOk else "notallstarted")))
		self.labels["abouttostart"].setVisible(False)
		# emit signal back to controller
		self.panel.emit(QtCore.SIGNAL('redrawNavButtons()'))
Esempio n. 15
0
	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)
Esempio n. 16
0
 def generateAddPage(self):
     '''Build the form page for adding a new user, using the template'''
     bodytext = self.addtemplate.getHtml({"owntorid": DbI.getOwnTorid()})
     return self.buildPage({
         'pageTitle':
         I18nManager.getText("contacts.title"),
         'pageBody':
         bodytext,
         'pageFooter':
         "<p>Footer</p>"
     })
Esempio n. 17
0
 def getPanel(self):
     # fifth panel, for generating keypair
     self.panel = QtWidgets.QWidget()
     layout = QtWidgets.QVBoxLayout()
     self.labels = {}
     for k in [
             "heading", "introemptykeyring", "introsinglekey",
             "introselectkey", "param.name", "param.email", "param.comment",
             "mighttakeawhile"
     ]:
         self.labels[k] = QtWidgets.QLabel()
     self._makeLabelHeading(self.labels["heading"])
     layout.addWidget(self.labels["heading"])
     layout.addStretch(0.3)
     layout.addWidget(self.labels["introemptykeyring"])
     layout.addWidget(self.labels["introsinglekey"])
     layout.addWidget(self.labels["introselectkey"])
     # list of keypairs already in the keyring
     self.keypairListWidget = QtWidgets.QListWidget()
     layout.addWidget(self.keypairListWidget)
     # parameters for generation of new keypair
     self.keygenbox = QtWidgets.QFrame(self.panel)
     sublayout = QtWidgets.QFormLayout()
     self.keygenParamBoxes = {}
     for param in ['name', 'email', 'comment']:  # (no password)
         editbox = QtWidgets.QLineEdit()
         self.keygenParamBoxes[param] = editbox
         sublayout.addRow(self.labels["param." + param], editbox)
     self.keygenbox.setLayout(sublayout)
     sublayout.setFormAlignment(
         QtCore.Qt.AlignHCenter)  # horizontally centred
     layout.addWidget(self.keygenbox)
     # 'Generate' button
     self.generateButton = QtWidgets.QPushButton(
         I18nManager.getText("button.generate"))
     self.generateButton.clicked.connect(self.generateKeyClicked)
     layout.addWidget(self.generateButton)
     # Progress bar (actually more of an hourglass)
     self.generateProgressbar = QtWidgets.QProgressBar()
     self.generateProgressbar.setVisible(False)
     self.generateProgressbar.setMinimum(0)
     self.generateProgressbar.setMaximum(0)
     progressPanel = QtWidgets.QFrame()
     sublayout = QtWidgets.QHBoxLayout()
     sublayout.addStretch(0.4)
     sublayout.addWidget(self.generateProgressbar)
     sublayout.addStretch(0.4)
     progressPanel.setLayout(sublayout)
     layout.addWidget(progressPanel)
     # Label to say that it might take a minute or two
     layout.addWidget(self.labels["mighttakeawhile"])
     layout.addStretch(1)
     self.panel.setLayout(layout)
     return self.panel
Esempio n. 18
0
    def __init__(self, *args):
        '''Constructor'''
        QtWidgets.QMainWindow.__init__(*(self, ) + args)
        self.setWindowTitle(I18nManager.getText("startupwizard.title"))

        # main pane with the stack and the button panel
        mainpane = QtWidgets.QWidget(self)
        mainlayout = QtWidgets.QVBoxLayout()
        mainpane.setLayout(mainlayout)
        self.setCentralWidget(mainpane)

        self.cardstack = QtWidgets.QStackedWidget(mainpane)

        self.cardPanels = [IntroPanel(), DependenciesPanel(), PathsPanel(), ServicesPanel(), \
         KeygenPanel(), FinishedPanel()]
        for card in self.cardPanels:
            panel = card.getPanel()
            self.cardstack.addWidget(panel)
            card.redrawNavButtonsSignal.connect(self.redrawButtons)

        # button panel at the bottom
        buttonPanel = QtWidgets.QFrame(self.cardstack)
        buttonPanel.setFrameStyle(QtWidgets.QFrame.Box +
                                  QtWidgets.QFrame.Sunken)
        self.backButton = QtWidgets.QPushButton(
            I18nManager.getText("button.exit"))
        self.nextButton = QtWidgets.QPushButton(
            I18nManager.getText("button.next"))
        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(self.backButton)
        layout.addStretch(1)
        layout.addWidget(self.nextButton)
        buttonPanel.setLayout(layout)

        self.backButton.clicked.connect(self.backButtonClicked)
        self.nextButton.clicked.connect(self.nextButtonClicked)

        mainlayout.addWidget(self.cardstack)
        mainlayout.addWidget(buttonPanel)
        self.nextButton.setFocus()
Esempio n. 19
0
	def servePage(self, view, url, params):
		domain, path = self.getDomainAndPath(url)
		# Do I need to intercept this to create a new window?
		if domain == "new":
			cw = ComposeWindow(I18nManager.getText("composemessage.title"))
			cw.setPageServer(self)
			cw.showPage("<html></html>")
			cw.navigateTo(path, params)
			return

		server = self.pageSets.get(domain)
		if not server: server = self.pageSets.get("")
		server.servePage(view, path, params)
Esempio n. 20
0
	def prepare(self):
		'''When going from the intro page to the dependencies page, this needs to be updated'''
		depsFound = {'pyqt':True}  # PyQt must be present, otherwise we wouldn't be here!
		self.allFound = True
		try:
			import pymongo
			depsFound["pymongo"] = True
		except: self.allFound = False
		try:
			from gnupg import GPG
			depsFound["gnupg"] = True
		except: self.allFound = False

		# Update the ticks and crosses
		for l in self.dependencyLabels:
			found = depsFound.get(l.depkey, False)
			l.setPixmap(self.yesPixmap if found else self.noPixmap)
			l.setToolTip(I18nManager.getText("startupwizard.dep.found" if found else "startupwizard.dep.notfound"))

		# if not all dependencies are there, show the message
		self.dependencyCheckLabel.setText(I18nManager.getText("startupwizard.dependencies." +
			("allfound" if self.allFound else "notallfound")))
Esempio n. 21
0
 def finish(self):
     '''Called when leaving the paths page'''
     datadir = str(self.dataDirectoryField.text())
     Config.setProperty(Config.KEY_DATA_DIR, datadir)
     # Make sure all the directories exist, create them if not
     try:
         for direc in [Config.getDatabaseDir(), Config.getWebCacheDir(), \
           Config.getKeyringDir(), Config.getTorDir()]:
             if not os.path.exists(direc):
                 os.makedirs(direc)
     except:
         # Couldn't create one of the directories, so show error and stay on this panel
         QtWidgets.QMessageBox.critical(
             self.panel, I18nManager.getText("gui.dialogtitle.error"),
             I18nManager.getText(
                 "startupwizard.paths.failedtocreatedatadir"))
         return False
     # Also store selected paths to exes
     # TODO: Check the exes exist?
     Config.setProperty(Config.KEY_TOR_EXE, str(self.torPathField.text()))
     Config.setProperty(Config.KEY_GPG_EXE, str(self.gpgPathField.text()))
     Config.save()
     return True
Esempio n. 22
0
	def finish(self):
		'''Called when leaving the paths page'''
		datadir = str(self.dataDirectoryField.text())
		Config.setProperty(Config.KEY_DATA_DIR, datadir)
		# Make sure all the directories exist, create them if not
		try:
			for direc in [Config.getDatabaseDir(), Config.getWebCacheDir(), \
			  Config.getKeyringDir(), Config.getTorDir()]:
				if not os.path.exists(direc):
					os.makedirs(direc)
		except:
			# Couldn't create one of the directories, so show error and stay on this panel
			QtGui.QMessageBox.critical(self.panel,
				I18nManager.getText("gui.dialogtitle.error"),
				I18nManager.getText("startupwizard.paths.failedtocreatedatadir"))
			return False
		# Also store selected paths to exes
		# TODO: Check the exes exist?
		Config.setProperty(Config.KEY_MONGO_EXE, str(self.mongoPathField.text()))
		Config.setProperty(Config.KEY_TOR_EXE,   str(self.torPathField.text()))
		Config.setProperty(Config.KEY_GPG_EXE,   str(self.gpgPathField.text()))
		Config.save()
		return True
Esempio n. 23
0
	def __init__(self, *args):
		'''Constructor'''
		QtGui.QMainWindow.__init__(*(self,) + args)
		self.setWindowTitle(I18nManager.getText("startupwizard.title"))

		# main pane with the stack and the button panel
		mainpane = QtGui.QWidget(self)
		mainlayout = QtGui.QVBoxLayout()
		mainpane.setLayout(mainlayout)
		self.setCentralWidget(mainpane)

		self.cardstack = QtGui.QStackedWidget(mainpane)

		self.cardPanels = [IntroPanel(), DependenciesPanel(), PathsPanel(), ServicesPanel(), \
			KeygenPanel(), FinishedPanel()]
		for card in self.cardPanels:
			panel = card.getPanel()
			self.cardstack.addWidget(panel)
			self.connect(panel, QtCore.SIGNAL("redrawNavButtons()"), self.redrawButtons)

		# button panel at the bottom
		buttonPanel = QtGui.QFrame(self.cardstack)
		buttonPanel.setFrameStyle(QtGui.QFrame.Box + QtGui.QFrame.Sunken)
		self.backButton = QtGui.QPushButton(I18nManager.getText("button.exit"))
		self.nextButton = QtGui.QPushButton(I18nManager.getText("button.next"))
		layout = QtGui.QHBoxLayout()
		layout.addWidget(self.backButton)
		layout.addStretch(1)
		layout.addWidget(self.nextButton)
		buttonPanel.setLayout(layout)

		self.connect(self.backButton, QtCore.SIGNAL("clicked()"), self.backButtonClicked)
		self.connect(self.nextButton, QtCore.SIGNAL("clicked()"), self.nextButtonClicked)

		mainlayout.addWidget(self.cardstack)
		mainlayout.addWidget(buttonPanel)
		self.nextButton.setFocus()
Esempio n. 24
0
	def getPanel(self):
		# fifth panel, for generating keypair
		self.panel = QtGui.QWidget()
		layout = QtGui.QVBoxLayout()
		self.labels = {}
		for k in ["heading", "introemptykeyring", "introsinglekey", "introselectkey", "param.name",
		  "param.email", "param.comment", "mighttakeawhile"]:
			self.labels[k] = QtGui.QLabel()
		self._makeLabelHeading(self.labels["heading"])
		layout.addWidget(self.labels["heading"])
		layout.addStretch(0.3)
		layout.addWidget(self.labels["introemptykeyring"])
		layout.addWidget(self.labels["introsinglekey"])
		layout.addWidget(self.labels["introselectkey"])
		# list of keypairs already in the keyring
		self.keypairListWidget = QtGui.QListWidget()
		layout.addWidget(self.keypairListWidget)
		# parameters for generation of new keypair
		self.keygenbox = QtGui.QFrame(self.panel)
		sublayout = QtGui.QFormLayout()
		self.keygenParamBoxes = {}
		for param in ['name', 'email', 'comment']:  # (no password)
			editbox = QtGui.QLineEdit()
			self.keygenParamBoxes[param] = editbox
			sublayout.addRow(self.labels["param." + param], editbox)
		self.keygenbox.setLayout(sublayout)
		sublayout.setFormAlignment(QtCore.Qt.AlignHCenter) # horizontally centred
		layout.addWidget(self.keygenbox)
		# 'Generate' button
		self.generateButton = QtGui.QPushButton(I18nManager.getText("button.generate"))
		self.panel.connect(self.generateButton, QtCore.SIGNAL("clicked()"), self.generateKeyClicked)
		layout.addWidget(self.generateButton)
		# Progress bar (actually more of an hourglass)
		self.generateProgressbar = QtGui.QProgressBar()
		self.generateProgressbar.setVisible(False)
		self.generateProgressbar.setMinimum(0)
		self.generateProgressbar.setMaximum(0)
		progressPanel = QtGui.QFrame()
		sublayout = QtGui.QHBoxLayout()
		sublayout.addStretch(0.4)
		sublayout.addWidget(self.generateProgressbar)
		sublayout.addStretch(0.4)
		progressPanel.setLayout(sublayout)
		layout.addWidget(progressPanel)
		# Label to say that it might take a minute or two
		layout.addWidget(self.labels["mighttakeawhile"])
		layout.addStretch(1)
		self.panel.setLayout(layout)
		return self.panel
Esempio n. 25
0
	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
Esempio n. 26
0
    def prepare(self):
        '''When going from the intro page to the dependencies page, this needs to be updated'''
        depsFound = {
            'pyqt': True
        }  # PyQt must be present, otherwise we wouldn't be here!
        self.allFound = True
        try:
            from gnupg import GPG
            depsFound["gnupg"] = True
        except:
            self.allFound = False

        # Update the ticks and crosses
        for l in self.dependencyLabels:
            found = depsFound.get(l.depkey, False)
            l.setPixmap(self.yesPixmap if found else self.noPixmap)
            l.setToolTip(
                I18nManager.getText("startupwizard.dep.found" if found else
                                    "startupwizard.dep.notfound"))

        # if not all dependencies are there, show the message
        self.dependencyCheckLabel.setText(
            I18nManager.getText("startupwizard.dependencies." + (
                "allfound" if self.allFound else "notallfound")))
Esempio n. 27
0
    def servePage(self, view, url, params):
        domain, path = self.getDomainAndPath(url)
        # Do I need to intercept this to create a new window?
        if domain == "new":
            cw = ComposeWindow(I18nManager.getText("composemessage.title"))
            cw.setPageServer(self)
            cw.showPage("<html></html>")
            cw.navigateTo(path, params)
            # TODO: Remove the closed windows from the list
            self._openWindows.append(cw)
            return

        server = self.pageSets.get(domain)
        if not server: server = self.pageSets.get("")
        server.servePage(view, path, params)
Esempio n. 28
0
    def generateFingerprintsPage(self, userid):
        '''Build the page for checking the fingerprints of the selected user'''
        # First, get the name of the user
        person = DbI.getProfile(userid)
        dispName = person['displayName']
        fullName = person['name']
        if dispName != fullName:
            fullName = dispName + " (" + fullName + ")"
        fc = self._makeFingerprintChecker(userid)
        # check it's ok to generate
        status = person.get('status', '')
        if not fc.valid \
          or status not in ['untrusted', 'trusted']:
            print("Not generating fingerprints page because status is", status)
            return None

        # Get one set of words for us and three sets for them
        printsAlreadyChecked = (person.get('status', '') == "trusted")
        bodytext = self.fingerprintstemplate.getHtml({
            "mywords":
            fc.getCodeWords(True, 0, "en"),
            "theirwords0":
            fc.getCodeWords(False, 0, "en"),
            "theirwords1":
            fc.getCodeWords(False, 1, "en"),
            "theirwords2":
            fc.getCodeWords(False, 2, "en"),
            "fullname":
            fullName,
            "shortname":
            dispName,
            "userid":
            userid,
            "alreadychecked":
            printsAlreadyChecked
        })
        return self.buildPage({
            'pageTitle':
            I18nManager.getText("contacts.title"),
            'pageBody':
            bodytext,
            'pageFooter':
            "<p>Footer</p>"
        })
Esempio n. 29
0
	def prepare(self):
		'''Called before showing the keypair page'''
		self.privateKeys = CryptoClient.getPrivateKeys()
		numKeys = len(self.privateKeys)
		self.labels["introemptykeyring"].setVisible(numKeys == 0)
		self.labels["introsinglekey"].setVisible(numKeys == 1)
		self.labels["introselectkey"].setVisible(numKeys > 1)
		self.generateProgressbar.setVisible(False)
		self.labels["mighttakeawhile"].setVisible(False)
		self.keypairListWidget.clear()
		for k in self.privateKeys:
			name = k['uids']
			if isinstance(name, list):
				name = str(name[0])
			self.keypairListWidget.addItem("%s - %s (%s)" % (k['keyid'], name, k['length']))
		self.keypairListWidget.setVisible(numKeys > 0)
		self.keypairListWidget.setCurrentRow(self.keypairListWidget.count() - 1)
		# Hide generation option if we've got a key already
		self.keygenbox.setVisible(numKeys == 0)
		self.generateButton.setVisible(numKeys == 0)
		# Rewrite button text in case language has changed
		self.generateButton.setText(I18nManager.getText("button.generate"))
Esempio n. 30
0
 def prepare(self):
     '''Called before showing the keypair page'''
     self.privateKeys = CryptoClient.getPrivateKeys()
     numKeys = len(self.privateKeys)
     self.labels["introemptykeyring"].setVisible(numKeys == 0)
     self.labels["introsinglekey"].setVisible(numKeys == 1)
     self.labels["introselectkey"].setVisible(numKeys > 1)
     self.generateProgressbar.setVisible(False)
     self.labels["mighttakeawhile"].setVisible(False)
     self.keypairListWidget.clear()
     for k in self.privateKeys:
         name = k['uids']
         if isinstance(name, list):
             name = str(name[0])
         self.keypairListWidget.addItem("%s - %s (%s)" %
                                        (k['keyid'], name, k['length']))
     self.keypairListWidget.setVisible(numKeys > 0)
     self.keypairListWidget.setCurrentRow(self.keypairListWidget.count() -
                                          1)
     # Hide generation option if we've got a key already
     self.keygenbox.setVisible(numKeys == 0)
     self.generateButton.setVisible(numKeys == 0)
     # Rewrite button text in case language has changed
     self.generateButton.setText(I18nManager.getText("button.generate"))
Esempio n. 31
0
	def servePage(self, view, url, params):
		contents = self.buildPage({'pageTitle' : I18nManager.getText("calendar.title"),
			'pageBody' : self.calendartemplate.getHtml(),
			'pageFooter' : "<p>Footer</p>"})
		view.setHtml(contents)
Esempio n. 32
0
	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>"})
Esempio n. 33
0
    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', 'status-pending.png'
        ])
        # List of contacts, and show details for the selected one (or self if userid=None)
        selectedprofile = DbI.getProfile(userid)
        if not selectedprofile:
            selectedprofile = DbI.getProfile()
        userid = selectedprofile['torid']
        ownPage = userid == DbI.getOwnTorid()

        # Build list of contacts
        userboxes = []
        currTime = datetime.datetime.now()
        for p in DbI.getProfiles():
            box = Bean()
            box.dispName = p['displayName']
            box.torid = p['torid']
            box.tilestyle = "contacttile" + ("selected"
                                             if p['torid'] == userid else "")
            box.status = p['status']
            isonline = Contacts.instance().isOnline(box.torid)
            lastSeen = Contacts.instance().lastSeen(box.torid)
            lastSeenTime = str(lastSeen.timetz())[:5] if lastSeen and (
                currTime - lastSeen).total_seconds() < 18000 else None
            if lastSeenTime:
                box.lastSeen = I18nManager.getText(
                    "contacts.onlinesince"
                    if isonline else "contacts.offlinesince") % lastSeenTime
            elif isonline:
                box.lastSeen = I18nManager.getText("contacts.online")
            else:
                box.lastSeen = None
            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
Esempio n. 34
0
        layout.addWidget(self.youridLabel)
        layout.addStretch(1)
        panel5.setLayout(layout)
        return panel5

    def prepare(self):
        '''Prepare the final panel'''
        text = (I18nManager.getText("startupwizard.finished.yourid") %
                TorClient.getOwnId())
        self.youridLabel.setText(text)
        # TODO: If this is just a label, then it can't be selected and copied- should it be a disabled text field instead?

    def getButtonKeys(self):
        return ("back", "finish")

    def getButtonsEnabled(self):
        return (False, True)


if __name__ == "__main__":
    # Get ready to launch a Qt GUI
    Config.load()
    I18nManager.setLanguage()
    Config.registerSubscriber(I18nManager.instance())
    app = QtWidgets.QApplication([])

    win = StartupWizard()
    win.show()

    app.exec_()
Esempio n. 35
0
 def prepare(self):
     '''Prepare the final panel'''
     text = (I18nManager.getText("startupwizard.finished.yourid") %
             TorClient.getOwnId())
     self.youridLabel.setText(text)
Esempio n. 36
0
	def redrawLabels(self):
		'''Reset the texts for all labels if the language changes'''
		for labelKey in list(self.labels.keys()):
			textKey = "startupwizard." + self.getName() + "." + labelKey
			self.labels[labelKey].setText(I18nManager.getText(textKey))
Esempio n. 37
0
    def servePage(self, view, url, params):
        print("Compose: %s, params %s" % (url, repr(params)))
        if url == "/start":
            self.requirePageResources(['default.css', 'jquery-3.1.1.js'])
            DbI.exportAllAvatars(Config.getWebCacheDir())
            parentHash = params.get("reply", None)
            recpts = params.get("sendto", None)
            # Build list of contacts to whom we can send
            userboxes = []
            for p in DbI.getMessageableProfiles():
                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 DbI.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(",")
            DbI.addToOutbox(msg)
            # Save a copy of the sent message
            sentMessage = {
                "messageType": "normal",
                "fromId": DbI.getOwnTorid(),
                "messageBody": msgBody,
                "timestamp": msg.timestamp,
                "messageRead": True,
                "messageReplied": False,
                "recipients": recpts,
                "parentHash": parentHash
            }
            DbI.addToInbox(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)
Esempio n. 38
0
		layout.addWidget(self.labels["nowstart"])
		self.youridLabel = QtGui.QLabel()
		layout.addWidget(self.youridLabel)
		layout.addStretch(1)
		panel5.setLayout(layout)
		return panel5

	def prepare(self):
		'''Prepare the final panel'''
		text = (I18nManager.getText("startupwizard.finished.yourid") % TorClient.getOwnId())
		self.youridLabel.setText(text)
		# TODO: If this is just a label, then it can't be selected and copied- should it be a disabled text field instead?

	def getButtonKeys(self):
		return ("back", "finish")
	def getButtonsEnabled(self):
		return (False, True)


if __name__ == "__main__":
	# Get ready to launch a Qt GUI
	Config.load()
	I18nManager.setLanguage()
	Config.registerSubscriber(I18nManager.instance())
	app = QtGui.QApplication([])

	win = StartupWizard()
	win.show()

	app.exec_()
Esempio n. 39
0
 def redrawLabels(self):
     '''Reset the texts for all labels if the language changes'''
     for labelKey in list(self.labels.keys()):
         textKey = "startupwizard." + self.getName() + "." + labelKey
         self.labels[labelKey].setText(I18nManager.getText(textKey))
Esempio n. 40
0
	def prepare(self):
		'''Prepare the final panel'''
		text = (I18nManager.getText("startupwizard.finished.yourid") % TorClient.getOwnId())
		self.youridLabel.setText(text)
Esempio n. 41
0
    def servePage(self, view, url, params):
        print("Special function:", url)
        if url == "/selectprofilepic":
            # Get home directory for file dialog
            homedir = os.path.expanduser("~/")
            fname = 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 DbI.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 = DbI.getOwnTorid()
            friends = {}
            friendsOfFriends = {}
            for c in DbI.getMessageableProfiles():
                # print("Contact: id:'%s' name:'%s'" % (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', "")
            # Also add ourselves
            c = DbI.getProfile()
            nodeid = storm.getUnusedNodeId()
            friends[c['torid']] = nodeid
            storm.addNode(Node(None, nodeid, c['displayName']))
            # Add edges
            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)
Esempio n. 42
0
    def servePage(self, view, url, params):
        self.requirePageResources(
            ['button-compose.png', 'default.css', 'jquery-3.1.1.js'])
        DbI.exportAllAvatars(Config.getWebCacheDir())

        messageList = None
        if url == "/send":
            print("send message of type '%(messageType)s' to id '%(sendTo)s'" %
                  params)
            if params['messageType'] == "contactresponse":
                torId = params['sendTo']
                if params.get("accept", "0") == "1":
                    ContactMaker.handleAccept(torId)
                    # Make sure this new contact has an empty avatar
                    DbI.exportAllAvatars(Config.getWebCacheDir())
                    outmsg = message.ContactResponseMessage(
                        message=params['messageBody'])
                else:
                    ContactMaker.handleDeny(torId)
                    outmsg = message.ContactDenyMessage()
                # Construct a ContactResponse message object for sending
                outmsg.recipients = [params['sendTo']]
                DbI.addToOutbox(outmsg)
        elif url.startswith("/delete/"):
            DbI.deleteFromInbox(params.get("msgId", ""))
        elif url in ["/search", "/search/"]:
            messageList = DbI.searchInboxMessages(params.get("searchTerm"))

        # Make dictionary to convert ids to names
        contactNames = {
            c['torid']: c['displayName']
            for c in DbI.getProfiles()
        }
        unknownSender = I18nManager.getText("messages.sender.unknown")
        unknownRecpt = I18nManager.getText("messages.recpt.unknown")
        # Get contact requests, responses and mails from inbox
        conreqs = []
        conresps = []
        mailTree = MessageTree()
        if messageList is None:
            messageList = DbI.getInboxMessages()
        # TODO: Paging options?
        for m in messageList:
            if not m:
                continue
            m['msgId'] = str(m.get("_id", ""))
            if m['messageType'] == "contactrequest":
                conreqs.append(m)
            elif m['messageType'] == "contactrefer":
                senderId = m.get('fromId', None)
                m['senderName'] = contactNames.get(senderId, unknownSender)
                conreqs.append(m)
            elif m['messageType'] == "contactresponse":
                if not m.get('accepted', False):
                    m['messageBody'] = I18nManager.getText(
                        "messages.contactrequest.refused")
                    m['fromName'] = DbI.getProfile(m['fromId'])["displayName"]
                elif not m.get('messageBody', False):
                    m['messageBody'] = I18nManager.getText(
                        "messages.contactrequest.accepted")
                conresps.append(m)
            else:
                senderId = m.get('fromId', None)
                if not senderId and m.get('signatureKeyId', None):
                    senderId = DbI.findUserIdFromKeyId(m['signatureKeyId'])
                m['senderName'] = contactNames.get(senderId, unknownSender)
                m['sentTimeStr'] = self.makeLocalTimeString(m['timestamp'])
                # Split m['recipients'] by commas, and look up each id with contactNames
                recpts = m.get('recipients', '')
                if recpts:
                    replyAll = recpts.split(",")
                    m['recipients'] = ", ".join(
                        [contactNames.get(i, unknownRecpt) for i in replyAll])
                    replyAll.append(senderId)
                    m['replyAll'] = ",".join(replyAll)
                else:
                    m['recipients'] = unknownRecpt
                    m['replyAll'] = ""
                mailTree.addMsg(m)
        mails = mailTree.build()
        bodytext = self.messagestemplate.getHtml({
            "contactrequests":
            conreqs,
            "contactresponses":
            conresps,
            "mails":
            mails,
            "nummessages":
            len(conreqs) + len(conresps) + len(mails),
            "webcachedir":
            Config.getWebCacheDir()
        })
        contents = self.buildPage({
            'pageTitle':
            I18nManager.getText("messages.title"),
            'pageBody':
            bodytext,
            'pageFooter':
            "<p>Footer</p>"
        })
        view.setHtml(contents)