Skip to content

Commit 77a843b

Browse files
committed
Email gateway integration
Sending/receiving from the send tab, reply from inbox and registration/unregistration context menu.
1 parent 04059a6 commit 77a843b

File tree

4 files changed

+347
-15
lines changed

4 files changed

+347
-15
lines changed

src/bitmessageqt/__init__.py

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from regenerateaddresses import *
3535
from newchandialog import *
3636
from specialaddressbehavior import *
37+
from emailgateway import *
3738
from settings import *
3839
from about import *
3940
from help import *
@@ -213,6 +214,10 @@ def init_identities_popup_menu(self, connectSignal=True):
213214
_translate(
214215
"MainWindow", "Special address behavior..."),
215216
self.on_action_SpecialAddressBehaviorDialog)
217+
self.actionEmailGateway = self.ui.addressContextMenuToolbarYourIdentities.addAction(
218+
_translate(
219+
"MainWindow", "Email gateway"),
220+
self.on_action_EmailGatewayDialog)
216221

217222
self.ui.treeWidgetYourIdentities.setContextMenuPolicy(
218223
QtCore.Qt.CustomContextMenu)
@@ -230,6 +235,7 @@ def init_identities_popup_menu(self, connectSignal=True):
230235
self.popMenuYourIdentities.addAction(self.actionDisableYourIdentities)
231236
self.popMenuYourIdentities.addAction(self.actionSetAvatarYourIdentities)
232237
self.popMenuYourIdentities.addAction(self.actionSpecialAddressBehaviorYourIdentities)
238+
self.popMenuYourIdentities.addAction(self.actionEmailGateway)
233239

234240
def init_chan_popup_menu(self, connectSignal=True):
235241
# Popup menu for the Channels tab
@@ -902,6 +908,7 @@ def loadSent(self, tableWidget, account, where="", what=""):
902908

903909
subjectItem = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8'))
904910
subjectItem.setToolTip(unicode(acct.subject, 'utf-8'))
911+
subjectItem.setData(Qt.UserRole, str(subject))
905912
subjectItem.setFlags(
906913
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
907914
tableWidget.setItem(0, 2, subjectItem)
@@ -1038,6 +1045,7 @@ def loadMessagelist(self, tableWidget, account, folder="inbox", where="", what="
10381045
# subject
10391046
subject_item = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8'))
10401047
subject_item.setToolTip(unicode(acct.subject, 'utf-8'))
1048+
subject_item.setData(Qt.UserRole, str(subject))
10411049
subject_item.setFlags(
10421050
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
10431051
if not read:
@@ -1966,6 +1974,8 @@ def click_pushButtonSend(self):
19661974
QMessageBox.about(self, _translate("MainWindow", "Message too long"), _translate(
19671975
"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)))
19681976
return
1977+
1978+
acct = accountClass(fromAddress)
19691979

19701980
if sendMessageToPeople: # To send a message to specific people (rather than broadcast)
19711981
toAddressesList = [s.strip()
@@ -1974,6 +1984,12 @@ def click_pushButtonSend(self):
19741984
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.
19751985
for toAddress in toAddressesList:
19761986
if toAddress != '':
1987+
if toAddress.find("@") >= 0 and isinstance(acct, GatewayAccount):
1988+
acct.createMessage(toAddress, fromAddress, subject, message)
1989+
subject = acct.subject
1990+
toAddress = acct.toAddress
1991+
print "Subject: %s" % (subject)
1992+
print "address: %s" % (toAddress)
19771993
status, addressVersionNumber, streamNumber, ripe = decodeAddress(
19781994
toAddress)
19791995
if status != 'success':
@@ -2195,6 +2211,8 @@ def displayNewSentMessage(self, toAddress, toLabel, fromAddress, subject, messag
21952211
self.ui.tableWidgetInbox.setItem(0, 1, newItem)
21962212
newItem = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8)'))
21972213
newItem.setToolTip(unicode(acct.subject, 'utf-8)'))
2214+
newItem.setData(Qt.UserRole, str(subject))
2215+
21982216
#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.
21992217
self.ui.tableWidgetInbox.setItem(0, 2, newItem)
22002218
# newItem = QtGui.QTableWidgetItem('Doing work necessary to send
@@ -2240,6 +2258,8 @@ def displayNewInboxMessage(self, inventoryHash, toAddress, fromAddress, subject,
22402258
self.ui.tableWidgetInbox.setItem(0, 1, newItem)
22412259
newItem = QtGui.QTableWidgetItem(unicode(acct.subject, 'utf-8)'))
22422260
newItem.setToolTip(unicode(acct.subject, 'utf-8)'))
2261+
newItem.setData(Qt.UserRole, str(subject))
2262+
22432263
#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.
22442264
newItem.setFont(font)
22452265
self.ui.tableWidgetInbox.setItem(0, 2, newItem)
@@ -2629,18 +2649,42 @@ def on_action_SpecialAddressBehaviorDialog(self):
26292649
shared.writeKeysFile()
26302650
self.rerenderInboxToLabels()
26312651

2652+
def on_action_EmailGatewayDialog(self):
2653+
self.dialog = EmailGatewayDialog(self)
2654+
# For Modal dialogs
2655+
if self.dialog.exec_():
2656+
addressAtCurrentRow = self.getCurrentAccount()
2657+
acct = accountClass(addressAtCurrentRow)
2658+
if isinstance(acct, GatewayAccount) and self.dialog.ui.radioButtonUnregister.isChecked():
2659+
print "unregister"
2660+
acct.unregister()
2661+
shared.config.remove_option(addressAtCurrentRow, 'gateway')
2662+
shared.writeKeysFile()
2663+
elif (not isinstance(acct, GatewayAccount)) and self.dialog.ui.radioButtonRegister.isChecked():
2664+
print "register"
2665+
email = str(self.dialog.ui.lineEditEmail.text().toUtf8())
2666+
acct = MailchuckAccount(addressAtCurrentRow)
2667+
acct.register(email)
2668+
shared.config.set(addressAtCurrentRow, 'label', email)
2669+
shared.config.set(addressAtCurrentRow, 'gateway', 'mailchuck')
2670+
shared.writeKeysFile()
2671+
else:
2672+
print "well nothing"
2673+
# shared.writeKeysFile()
2674+
# self.rerenderInboxToLabels()
2675+
26322676
def click_NewAddressDialog(self):
26332677
addresses = []
26342678
configSections = shared.config.sections()
26352679
for addressInKeysFile in configSections:
26362680
if addressInKeysFile == 'bitmessagesettings':
26372681
continue
26382682
addresses.append(addressInKeysFile)
2639-
self.dialog = Ui_NewAddressWizard(addresses)
2640-
self.dialog.exec_()
2683+
# self.dialog = Ui_NewAddressWizard(addresses)
2684+
# self.dialog.exec_()
26412685
# print "Name: " + self.dialog.field("name").toString()
26422686
# print "Email: " + self.dialog.field("email").toString()
2643-
return
2687+
# return
26442688
self.dialog = NewAddressDialog(self)
26452689
# For Modal dialogs
26462690
if self.dialog.exec_():
@@ -2787,6 +2831,7 @@ def on_action_InboxReply(self):
27872831
currentInboxRow = tableWidget.currentRow()
27882832
toAddressAtCurrentInboxRow = str(tableWidget.item(
27892833
currentInboxRow, 0).data(Qt.UserRole).toPyObject())
2834+
acct = accountClass(toAddressAtCurrentInboxRow)
27902835
fromAddressAtCurrentInboxRow = str(tableWidget.item(
27912836
currentInboxRow, 1).data(Qt.UserRole).toPyObject())
27922837
msgid = str(tableWidget.item(
@@ -2796,6 +2841,7 @@ def on_action_InboxReply(self):
27962841
if queryreturn != []:
27972842
for row in queryreturn:
27982843
messageAtCurrentInboxRow, = row
2844+
acct.parseMessage(toAddressAtCurrentInboxRow, fromAddressAtCurrentInboxRow, str(tableWidget.item(currentInboxRow, 2).data(Qt.UserRole).toPyObject()), messageAtCurrentInboxRow)
27992845
if toAddressAtCurrentInboxRow == self.str_broadcast_subscribers:
28002846
#TODO what does this if?..
28012847
a = a
@@ -2808,7 +2854,7 @@ def on_action_InboxReply(self):
28082854
else:
28092855
self.setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(toAddressAtCurrentInboxRow)
28102856

2811-
self.ui.lineEditTo.setText(str(fromAddressAtCurrentInboxRow))
2857+
self.ui.lineEditTo.setText(str(acct.fromLabel))
28122858

28132859
# 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.
28142860
if shared.config.has_section(toAddressAtCurrentInboxRow):
@@ -2825,12 +2871,10 @@ def on_action_InboxReply(self):
28252871

28262872
quotedText = self.quoted_text(unicode(messageAtCurrentInboxRow, 'utf-8'))
28272873
self.ui.textEditMessage.setText(quotedText)
2828-
if tableWidget.item(currentInboxRow, 2).text()[0:3] in ['Re:', 'RE:']:
2829-
self.ui.lineEditSubject.setText(
2830-
tableWidget.item(currentInboxRow, 2).text())
2874+
if acct.subject[0:3] in ['Re:', 'RE:']:
2875+
self.ui.lineEditSubject.setText(acct.subject)
28312876
else:
2832-
self.ui.lineEditSubject.setText(
2833-
'Re: ' + tableWidget.item(currentInboxRow, 2).text())
2877+
self.ui.lineEditSubject.setText('Re: ' + acct.subject)
28342878
self.ui.tabWidgetSend.setCurrentIndex(0)
28352879
self.ui.tabWidget.setCurrentIndex(1)
28362880

@@ -3772,6 +3816,23 @@ def __init__(self, parent):
37723816

37733817
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
37743818

3819+
class EmailGatewayDialog(QtGui.QDialog):
3820+
3821+
def __init__(self, parent):
3822+
QtGui.QWidget.__init__(self, parent)
3823+
self.ui = Ui_EmailGatewayDialog()
3824+
self.ui.setupUi(self)
3825+
self.parent = parent
3826+
addressAtCurrentRow = parent.getCurrentAccount()
3827+
acct = accountClass(addressAtCurrentRow)
3828+
# if isinstance(acct, GatewayAccount):
3829+
label = shared.config.get(addressAtCurrentRow, 'label')
3830+
if label.find("@mailchuck.com") > -1:
3831+
self.ui.lineEditEmail.setText(label)
3832+
3833+
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
3834+
3835+
37753836
class AddAddressDialog(QtGui.QDialog):
37763837

37773838
def __init__(self, parent):
@@ -3999,11 +4060,11 @@ def run():
39994060
if shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
40004061
myapp.showConnectDialog() # ask the user if we may connect
40014062

4002-
try:
4003-
if shared.config.get('bitmessagesettings', 'mailchuck') < 1:
4004-
myapp.showMigrationWizard(shared.config.get('bitmessagesettings', 'mailchuck'))
4005-
except:
4006-
myapp.showMigrationWizard(0)
4063+
# try:
4064+
# if shared.config.get('bitmessagesettings', 'mailchuck') < 1:
4065+
# myapp.showMigrationWizard(shared.config.get('bitmessagesettings', 'mailchuck'))
4066+
# except:
4067+
# myapp.showMigrationWizard(0)
40074068

40084069
# only show after wizards and connect dialogs have completed
40094070
if not shared.config.getboolean('bitmessagesettings', 'startintray'):

src/bitmessageqt/account.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import sys
66
import inspect
77
from helper_sql import *
8+
from addresses import decodeAddress
9+
from pyelliptic.openssl import OpenSSL
10+
import time
811

912
def accountClass(address):
1013
if not shared.config.has_section(address):
@@ -57,6 +60,31 @@ class GatewayAccount(BMAccount):
5760
gatewayName = None
5861
def __init__(self, address):
5962
super(BMAccount, self).__init__(address)
63+
64+
def send(self):
65+
status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.toAddress)
66+
ackdata = OpenSSL.rand(32)
67+
t = ()
68+
sqlExecute(
69+
'''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
70+
'',
71+
self.toAddress,
72+
ripe,
73+
self.fromAddress,
74+
self.subject,
75+
self.message,
76+
ackdata,
77+
int(time.time()), # sentTime (this will never change)
78+
int(time.time()), # lastActionTime
79+
0, # sleepTill time. This will get set when the POW gets done.
80+
'msgqueued',
81+
0, # retryNumber
82+
'sent', # folder
83+
2, # encodingtype
84+
shared.config.getint('bitmessagesettings', 'ttl')
85+
)
86+
87+
shared.workerQueue.put(('sendmessage', self.toAddress))
6088

6189
def parseMessage(self, toAddress, fromAddress, subject, message):
6290
super(BMAccount, self).parseMessage(toAddress, fromAddress, subject, message)
@@ -71,6 +99,26 @@ class MailchuckAccount(GatewayAccount):
7199
regExpOutgoing = re.compile("(\S+) (.*)")
72100
def __init__(self, address):
73101
super(GatewayAccount, self).__init__(address)
102+
103+
def createMessage(self, toAddress, fromAddress, subject, message):
104+
self.subject = toAddress + " " + subject
105+
self.toAddress = self.relayAddress
106+
self.fromAddress = fromAddress
107+
self.message = message
108+
109+
def register(self, email):
110+
self.toAddress = self.registrationAddress
111+
self.subject = email
112+
self.message = ""
113+
self.fromAddress = self.address
114+
self.send()
115+
116+
def unregister(self):
117+
self.toAddress = self.unregistrationAddress
118+
self.subject = ""
119+
self.message = ""
120+
self.fromAddress = self.address
121+
self.send()
74122

75123
def parseMessage(self, toAddress, fromAddress, subject, message):
76124
super(GatewayAccount, self).parseMessage(toAddress, fromAddress, subject, message)
@@ -84,10 +132,12 @@ def parseMessage(self, toAddress, fromAddress, subject, message):
84132
self.subject += matches.group(3)
85133
if not matches.group(2) is None:
86134
self.fromLabel = matches.group(2)
135+
self.fromAddress = matches.group(2)
87136
if toAddress == self.relayAddress:
88137
matches = self.regExpOutgoing.search(subject)
89138
if not matches is None:
90139
if not matches.group(2) is None:
91140
self.subject = matches.group(2)
92141
if not matches.group(1) is None:
93-
self.toLabel = matches.group(1)
142+
self.toLabel = matches.group(1)
143+
self.toAddress = matches.group(1)

src/bitmessageqt/emailgateway.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Form implementation generated from reading ui file 'emailgateway.ui'
4+
#
5+
# Created: Fri Apr 26 17:43:31 2013
6+
# by: PyQt4 UI code generator 4.9.4
7+
#
8+
# WARNING! All changes made in this file will be lost!
9+
10+
from PyQt4 import QtCore, QtGui
11+
12+
try:
13+
_fromUtf8 = QtCore.QString.fromUtf8
14+
except AttributeError:
15+
_fromUtf8 = lambda s: s
16+
17+
class Ui_EmailGatewayDialog(object):
18+
def setupUi(self, EmailGatewayDialog):
19+
EmailGatewayDialog.setObjectName(_fromUtf8("EmailGatewayDialog"))
20+
EmailGatewayDialog.resize(386, 172)
21+
self.gridLayout = QtGui.QGridLayout(EmailGatewayDialog)
22+
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
23+
self.radioButtonRegister = QtGui.QRadioButton(EmailGatewayDialog)
24+
self.radioButtonRegister.setChecked(True)
25+
self.radioButtonRegister.setObjectName(_fromUtf8("radioButtonRegister"))
26+
self.gridLayout.addWidget(self.radioButtonRegister, 1, 0, 1, 1)
27+
self.radioButtonUnregister = QtGui.QRadioButton(EmailGatewayDialog)
28+
self.radioButtonUnregister.setObjectName(_fromUtf8("radioButtonUnregister"))
29+
self.gridLayout.addWidget(self.radioButtonUnregister, 4, 0, 1, 1)
30+
self.label = QtGui.QLabel(EmailGatewayDialog)
31+
self.label.setWordWrap(True)
32+
self.label.setObjectName(_fromUtf8("label"))
33+
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
34+
self.label_2 = QtGui.QLabel(EmailGatewayDialog)
35+
self.label_2.setObjectName(_fromUtf8("label_2"))
36+
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
37+
self.lineEditEmail = QtGui.QLineEdit(EmailGatewayDialog)
38+
self.lineEditEmail.setEnabled(True)
39+
self.lineEditEmail.setObjectName(_fromUtf8("lineEditEmail"))
40+
self.gridLayout.addWidget(self.lineEditEmail, 3, 0, 1, 1)
41+
self.buttonBox = QtGui.QDialogButtonBox(EmailGatewayDialog)
42+
self.buttonBox.setMinimumSize(QtCore.QSize(368, 0))
43+
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
44+
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
45+
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
46+
self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1)
47+
48+
self.retranslateUi(EmailGatewayDialog)
49+
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), EmailGatewayDialog.accept)
50+
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), EmailGatewayDialog.reject)
51+
QtCore.QObject.connect(self.radioButtonRegister, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.lineEditEmail.setEnabled)
52+
QtCore.QObject.connect(self.radioButtonUnregister, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.lineEditEmail.setDisabled)
53+
QtCore.QMetaObject.connectSlotsByName(EmailGatewayDialog)
54+
EmailGatewayDialog.setTabOrder(self.radioButtonRegister, self.lineEditEmail)
55+
EmailGatewayDialog.setTabOrder(self.lineEditEmail, self.radioButtonUnregister)
56+
EmailGatewayDialog.setTabOrder(self.radioButtonUnregister, self.buttonBox)
57+
58+
def retranslateUi(self, EmailGatewayDialog):
59+
EmailGatewayDialog.setWindowTitle(QtGui.QApplication.translate("EmailGatewayDialog", "Email gateway", None, QtGui.QApplication.UnicodeUTF8))
60+
self.radioButtonRegister.setText(QtGui.QApplication.translate("EmailGatewayDialog", "Register on email gateway", None, QtGui.QApplication.UnicodeUTF8))
61+
self.radioButtonUnregister.setText(QtGui.QApplication.translate("EmailGatewayDialog", "Unregister from email gateway", None, QtGui.QApplication.UnicodeUTF8))
62+
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))
63+
self.label_2.setText(QtGui.QApplication.translate("EmailGatewayDialog", "Desired email address (including @mailchuck.com):", None, QtGui.QApplication.UnicodeUTF8))
64+

0 commit comments

Comments
 (0)