Email gateway integration

Sending/receiving from the send tab, reply from inbox and
registration/unregistration context menu.
This commit is contained in:
mailchuck 2015-10-03 17:24:21 +02:00 committed by Peter Surda
parent b4fa5d4abf
commit 2bc9c7ff4c
4 changed files with 347 additions and 15 deletions

View File

@ -34,6 +34,7 @@ from newsubscriptiondialog import *
from regenerateaddresses import *
from newchandialog import *
from specialaddressbehavior import *
from emailgateway import *
from settings import *
from about import *
from help import *
@ -213,6 +214,10 @@ class MyForm(QtGui.QMainWindow):
_translate(
"MainWindow", "Special address behavior..."),
self.on_action_SpecialAddressBehaviorDialog)
self.actionEmailGateway = self.ui.addressContextMenuToolbarYourIdentities.addAction(
_translate(
"MainWindow", "Email gateway"),
self.on_action_EmailGatewayDialog)
self.ui.treeWidgetYourIdentities.setContextMenuPolicy(
QtCore.Qt.CustomContextMenu)
@ -230,6 +235,7 @@ class MyForm(QtGui.QMainWindow):
self.popMenuYourIdentities.addAction(self.actionDisableYourIdentities)
self.popMenuYourIdentities.addAction(self.actionSetAvatarYourIdentities)
self.popMenuYourIdentities.addAction(self.actionSpecialAddressBehaviorYourIdentities)
self.popMenuYourIdentities.addAction(self.actionEmailGateway)
def init_chan_popup_menu(self, connectSignal=True):
# Popup menu for the Channels tab
@ -902,6 +908,7 @@ class MyForm(QtGui.QMainWindow):
subjectItem = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8'))
subjectItem.setToolTip(unicode(acct.subject, 'utf-8'))
subjectItem.setData(Qt.UserRole, str(subject))
subjectItem.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
tableWidget.setItem(0, 2, subjectItem)
@ -1038,6 +1045,7 @@ class MyForm(QtGui.QMainWindow):
# subject
subject_item = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8'))
subject_item.setToolTip(unicode(acct.subject, 'utf-8'))
subject_item.setData(Qt.UserRole, str(subject))
subject_item.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
if not read:
@ -1969,6 +1977,8 @@ more work your computer must do to send the message. A Time-To-Live of four or f
"MainWindow", "The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending.").arg(len(message) - (2 ** 18 - 500)))
return
acct = accountClass(fromAddress)
if sendMessageToPeople: # To send a message to specific people (rather than broadcast)
toAddressesList = [s.strip()
for s in toAddresses.replace(',', ';').split(';')]
@ -1976,6 +1986,12 @@ more work your computer must do to send the message. A Time-To-Live of four or f
toAddressesList)) # remove duplicate addresses. If the user has one address with a BM- and the same address without the BM-, this will not catch it. They'll send the message to the person twice.
for toAddress in toAddressesList:
if toAddress != '':
if toAddress.find("@") >= 0 and isinstance(acct, GatewayAccount):
acct.createMessage(toAddress, fromAddress, subject, message)
subject = acct.subject
toAddress = acct.toAddress
print "Subject: %s" % (subject)
print "address: %s" % (toAddress)
status, addressVersionNumber, streamNumber, ripe = decodeAddress(
toAddress)
if status != 'success':
@ -2197,6 +2213,8 @@ more work your computer must do to send the message. A Time-To-Live of four or f
self.ui.tableWidgetInbox.setItem(0, 1, newItem)
newItem = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8)'))
newItem.setToolTip(unicode(acct.subject, 'utf-8)'))
newItem.setData(Qt.UserRole, str(subject))
#newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) # No longer hold the message in the table; we'll use a SQL query to display it as needed.
self.ui.tableWidgetInbox.setItem(0, 2, newItem)
# newItem = QtGui.QTableWidgetItem('Doing work necessary to send
@ -2242,6 +2260,8 @@ more work your computer must do to send the message. A Time-To-Live of four or f
self.ui.tableWidgetInbox.setItem(0, 1, newItem)
newItem = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8)'))
newItem.setToolTip(unicode(acct.subject, 'utf-8)'))
newItem.setData(Qt.UserRole, str(subject))
#newItem.setData(Qt.UserRole, unicode(message, 'utf-8)')) # No longer hold the message in the table; we'll use a SQL query to display it as needed.
newItem.setFont(font)
self.ui.tableWidgetInbox.setItem(0, 2, newItem)
@ -2631,6 +2651,30 @@ more work your computer must do to send the message. A Time-To-Live of four or f
shared.writeKeysFile()
self.rerenderInboxToLabels()
def on_action_EmailGatewayDialog(self):
self.dialog = EmailGatewayDialog(self)
# For Modal dialogs
if self.dialog.exec_():
addressAtCurrentRow = self.getCurrentAccount()
acct = accountClass(addressAtCurrentRow)
if isinstance(acct, GatewayAccount) and self.dialog.ui.radioButtonUnregister.isChecked():
print "unregister"
acct.unregister()
shared.config.remove_option(addressAtCurrentRow, 'gateway')
shared.writeKeysFile()
elif (not isinstance(acct, GatewayAccount)) and self.dialog.ui.radioButtonRegister.isChecked():
print "register"
email = str(self.dialog.ui.lineEditEmail.text().toUtf8())
acct = MailchuckAccount(addressAtCurrentRow)
acct.register(email)
shared.config.set(addressAtCurrentRow, 'label', email)
shared.config.set(addressAtCurrentRow, 'gateway', 'mailchuck')
shared.writeKeysFile()
else:
print "well nothing"
# shared.writeKeysFile()
# self.rerenderInboxToLabels()
def click_NewAddressDialog(self):
addresses = []
configSections = shared.config.sections()
@ -2638,11 +2682,11 @@ more work your computer must do to send the message. A Time-To-Live of four or f
if addressInKeysFile == 'bitmessagesettings':
continue
addresses.append(addressInKeysFile)
self.dialog = Ui_NewAddressWizard(addresses)
self.dialog.exec_()
# self.dialog = Ui_NewAddressWizard(addresses)
# self.dialog.exec_()
# print "Name: " + self.dialog.field("name").toString()
# print "Email: " + self.dialog.field("email").toString()
return
# return
self.dialog = NewAddressDialog(self)
# For Modal dialogs
if self.dialog.exec_():
@ -2789,6 +2833,7 @@ more work your computer must do to send the message. A Time-To-Live of four or f
currentInboxRow = tableWidget.currentRow()
toAddressAtCurrentInboxRow = str(tableWidget.item(
currentInboxRow, 0).data(Qt.UserRole).toPyObject())
acct = accountClass(toAddressAtCurrentInboxRow)
fromAddressAtCurrentInboxRow = str(tableWidget.item(
currentInboxRow, 1).data(Qt.UserRole).toPyObject())
msgid = str(tableWidget.item(
@ -2798,6 +2843,7 @@ more work your computer must do to send the message. A Time-To-Live of four or f
if queryreturn != []:
for row in queryreturn:
messageAtCurrentInboxRow, = row
acct.parseMessage(toAddressAtCurrentInboxRow, fromAddressAtCurrentInboxRow, str(tableWidget.item(currentInboxRow, 2).data(Qt.UserRole).toPyObject()), messageAtCurrentInboxRow)
if toAddressAtCurrentInboxRow == self.str_broadcast_subscribers:
#TODO what does this if?..
a = a
@ -2810,7 +2856,7 @@ more work your computer must do to send the message. A Time-To-Live of four or f
else:
self.setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(toAddressAtCurrentInboxRow)
self.ui.lineEditTo.setText(str(fromAddressAtCurrentInboxRow))
self.ui.lineEditTo.setText(str(acct.fromLabel))
# If the previous message was to a chan then we should send our reply to the chan rather than to the particular person who sent the message.
if shared.config.has_section(toAddressAtCurrentInboxRow):
@ -2827,12 +2873,10 @@ more work your computer must do to send the message. A Time-To-Live of four or f
quotedText = self.quoted_text(unicode(messageAtCurrentInboxRow, 'utf-8'))
self.ui.textEditMessage.setText(quotedText)
if tableWidget.item(currentInboxRow, 2).text()[0:3] in ['Re:', 'RE:']:
self.ui.lineEditSubject.setText(
tableWidget.item(currentInboxRow, 2).text())
if acct.subject[0:3] in ['Re:', 'RE:']:
self.ui.lineEditSubject.setText(acct.subject)
else:
self.ui.lineEditSubject.setText(
'Re: ' + tableWidget.item(currentInboxRow, 2).text())
self.ui.lineEditSubject.setText('Re: ' + acct.subject)
self.ui.tabWidgetSend.setCurrentIndex(0)
self.ui.tabWidget.setCurrentIndex(1)
@ -3774,6 +3818,23 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog):
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
class EmailGatewayDialog(QtGui.QDialog):
def __init__(self, parent):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_EmailGatewayDialog()
self.ui.setupUi(self)
self.parent = parent
addressAtCurrentRow = parent.getCurrentAccount()
acct = accountClass(addressAtCurrentRow)
# if isinstance(acct, GatewayAccount):
label = shared.config.get(addressAtCurrentRow, 'label')
if label.find("@mailchuck.com") > -1:
self.ui.lineEditEmail.setText(label)
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
class AddAddressDialog(QtGui.QDialog):
def __init__(self, parent):
@ -4001,11 +4062,11 @@ def run():
if shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
myapp.showConnectDialog() # ask the user if we may connect
try:
if shared.config.get('bitmessagesettings', 'mailchuck') < 1:
myapp.showMigrationWizard(shared.config.get('bitmessagesettings', 'mailchuck'))
except:
myapp.showMigrationWizard(0)
# try:
# if shared.config.get('bitmessagesettings', 'mailchuck') < 1:
# myapp.showMigrationWizard(shared.config.get('bitmessagesettings', 'mailchuck'))
# except:
# myapp.showMigrationWizard(0)
# only show after wizards and connect dialogs have completed
if not shared.config.getboolean('bitmessagesettings', 'startintray'):

View File

@ -5,6 +5,9 @@ import re
import sys
import inspect
from helper_sql import *
from addresses import decodeAddress
from pyelliptic.openssl import OpenSSL
import time
def accountClass(address):
if not shared.config.has_section(address):
@ -58,6 +61,31 @@ class GatewayAccount(BMAccount):
def __init__(self, address):
super(BMAccount, self).__init__(address)
def send(self):
status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.toAddress)
ackdata = OpenSSL.rand(32)
t = ()
sqlExecute(
'''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
'',
self.toAddress,
ripe,
self.fromAddress,
self.subject,
self.message,
ackdata,
int(time.time()), # sentTime (this will never change)
int(time.time()), # lastActionTime
0, # sleepTill time. This will get set when the POW gets done.
'msgqueued',
0, # retryNumber
'sent', # folder
2, # encodingtype
shared.config.getint('bitmessagesettings', 'ttl')
)
shared.workerQueue.put(('sendmessage', self.toAddress))
def parseMessage(self, toAddress, fromAddress, subject, message):
super(BMAccount, self).parseMessage(toAddress, fromAddress, subject, message)
@ -72,6 +100,26 @@ class MailchuckAccount(GatewayAccount):
def __init__(self, address):
super(GatewayAccount, self).__init__(address)
def createMessage(self, toAddress, fromAddress, subject, message):
self.subject = toAddress + " " + subject
self.toAddress = self.relayAddress
self.fromAddress = fromAddress
self.message = message
def register(self, email):
self.toAddress = self.registrationAddress
self.subject = email
self.message = ""
self.fromAddress = self.address
self.send()
def unregister(self):
self.toAddress = self.unregistrationAddress
self.subject = ""
self.message = ""
self.fromAddress = self.address
self.send()
def parseMessage(self, toAddress, fromAddress, subject, message):
super(GatewayAccount, self).parseMessage(toAddress, fromAddress, subject, message)
if fromAddress == self.relayAddress:
@ -84,6 +132,7 @@ class MailchuckAccount(GatewayAccount):
self.subject += matches.group(3)
if not matches.group(2) is None:
self.fromLabel = matches.group(2)
self.fromAddress = matches.group(2)
if toAddress == self.relayAddress:
matches = self.regExpOutgoing.search(subject)
if not matches is None:
@ -91,3 +140,4 @@ class MailchuckAccount(GatewayAccount):
self.subject = matches.group(2)
if not matches.group(1) is None:
self.toLabel = matches.group(1)
self.toAddress = matches.group(1)

View File

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'emailgateway.ui'
#
# Created: Fri Apr 26 17:43:31 2013
# by: PyQt4 UI code generator 4.9.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_EmailGatewayDialog(object):
def setupUi(self, EmailGatewayDialog):
EmailGatewayDialog.setObjectName(_fromUtf8("EmailGatewayDialog"))
EmailGatewayDialog.resize(386, 172)
self.gridLayout = QtGui.QGridLayout(EmailGatewayDialog)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.radioButtonRegister = QtGui.QRadioButton(EmailGatewayDialog)
self.radioButtonRegister.setChecked(True)
self.radioButtonRegister.setObjectName(_fromUtf8("radioButtonRegister"))
self.gridLayout.addWidget(self.radioButtonRegister, 1, 0, 1, 1)
self.radioButtonUnregister = QtGui.QRadioButton(EmailGatewayDialog)
self.radioButtonUnregister.setObjectName(_fromUtf8("radioButtonUnregister"))
self.gridLayout.addWidget(self.radioButtonUnregister, 4, 0, 1, 1)
self.label = QtGui.QLabel(EmailGatewayDialog)
self.label.setWordWrap(True)
self.label.setObjectName(_fromUtf8("label"))
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.label_2 = QtGui.QLabel(EmailGatewayDialog)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.lineEditEmail = QtGui.QLineEdit(EmailGatewayDialog)
self.lineEditEmail.setEnabled(True)
self.lineEditEmail.setObjectName(_fromUtf8("lineEditEmail"))
self.gridLayout.addWidget(self.lineEditEmail, 3, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(EmailGatewayDialog)
self.buttonBox.setMinimumSize(QtCore.QSize(368, 0))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1)
self.retranslateUi(EmailGatewayDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), EmailGatewayDialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), EmailGatewayDialog.reject)
QtCore.QObject.connect(self.radioButtonRegister, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.lineEditEmail.setEnabled)
QtCore.QObject.connect(self.radioButtonUnregister, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.lineEditEmail.setDisabled)
QtCore.QMetaObject.connectSlotsByName(EmailGatewayDialog)
EmailGatewayDialog.setTabOrder(self.radioButtonRegister, self.lineEditEmail)
EmailGatewayDialog.setTabOrder(self.lineEditEmail, self.radioButtonUnregister)
EmailGatewayDialog.setTabOrder(self.radioButtonUnregister, self.buttonBox)
def retranslateUi(self, EmailGatewayDialog):
EmailGatewayDialog.setWindowTitle(QtGui.QApplication.translate("EmailGatewayDialog", "Email gateway", None, QtGui.QApplication.UnicodeUTF8))
self.radioButtonRegister.setText(QtGui.QApplication.translate("EmailGatewayDialog", "Register on email gateway", None, QtGui.QApplication.UnicodeUTF8))
self.radioButtonUnregister.setText(QtGui.QApplication.translate("EmailGatewayDialog", "Unregister from email gateway", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("EmailGatewayDialog", "Email gateway allows you to communicate with email users. Currently, only the Mailchuck email gateway (@mailchuck.com) is available.", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("EmailGatewayDialog", "Desired email address (including @mailchuck.com):", None, QtGui.QApplication.UnicodeUTF8))

View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EmailGatewayDialog</class>
<widget class="QDialog" name="EmailGatewayDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>386</width>
<height>172</height>
</rect>
</property>
<property name="windowTitle">
<string>Email gateway</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Desired email address (including @mailchuck.com)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="radioButtonRegister">
<property name="text">
<string>Register on email gateway</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="minimumSize">
<size>
<width>368</width>
<height>0</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLineEdit" name="lineEditEmailAddress">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>@mailchuck.com</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Email gateway alows you to communicate with email users. Currently, only the Mailchuck email gateway (@mailchuck.com) is available.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QRadioButton" name="radioButtonUnregister">
<property name="text">
<string>Unregister from email gateway</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>radioButtonRegister</tabstop>
<tabstop>lineEditEmailAddress</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>EmailGatewayDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>227</x>
<y>152</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>171</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>EmailGatewayDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>295</x>
<y>158</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>171</y>
</hint>
</hints>
</connection>
<connection>
<sender>radioButtonRegister</sender>
<signal>clicked(bool)</signal>
<receiver>lineEditEmailAddress</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>95</x>
<y>40</y>
</hint>
<hint type="destinationlabel">
<x>94</x>
<y>123</y>
</hint>
</hints>
</connection>
<connection>
<sender>radioButtonUnregister</sender>
<signal>clicked(bool)</signal>
<receiver>lineEditEmailAddress</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>139</x>
<y>19</y>
</hint>
<hint type="destinationlabel">
<x>187</x>
<y>123</y>
</hint>
</hints>
</connection>
</connections>
</ui>