eric6/Preferences/ConfigurationPages/EmailPage.py

changeset 6942
2602857055c5
parent 6828
bb6667ea9ae7
child 7229
53054eb5b15a
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2006 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the Email configuration page.
8 """
9
10 from __future__ import unicode_literals
11
12 import smtplib
13 import socket
14 import sys
15
16 from PyQt5.QtCore import pyqtSlot, Qt
17 from PyQt5.QtGui import QCursor
18 from PyQt5.QtWidgets import QApplication
19
20 from E5Gui import E5MessageBox
21 from E5Gui.E5Application import e5App
22
23 from E5Network.E5GoogleMailHelpers import getInstallCommand, RequiredPackages
24
25 from .ConfigurationPageBase import ConfigurationPageBase
26 from .Ui_EmailPage import Ui_EmailPage
27
28 import Preferences
29
30
31 class EmailPage(ConfigurationPageBase, Ui_EmailPage):
32 """
33 Class implementing the Email configuration page.
34 """
35 def __init__(self):
36 """
37 Constructor
38 """
39 super(EmailPage, self).__init__()
40 self.setupUi(self)
41 self.setObjectName("EmailPage")
42
43 self.__helpDialog = None
44
45 pipPackages = [
46 "google-api-python-client",
47 "google-auth-oauthlib",
48 ]
49 self.__pipCommand = "pip install --upgrade {0}".format(
50 " ".join(pipPackages))
51
52 # set initial values
53 self.__checkGoogleMail()
54
55 self.mailServerEdit.setText(Preferences.getUser("MailServer"))
56 self.portSpin.setValue(Preferences.getUser("MailServerPort"))
57 self.emailEdit.setText(Preferences.getUser("Email"))
58 self.signatureEdit.setPlainText(Preferences.getUser("Signature"))
59 self.mailAuthenticationGroup.setChecked(
60 Preferences.getUser("MailServerAuthentication"))
61 self.mailUserEdit.setText(Preferences.getUser("MailServerUser"))
62 self.mailPasswordEdit.setText(
63 Preferences.getUser("MailServerPassword"))
64 encryption = Preferences.getUser("MailServerEncryption")
65 if encryption == "TLS":
66 self.useTlsButton.setChecked(True)
67 elif encryption == "SSL":
68 self.useSslButton.setChecked(True)
69 else:
70 self.noEncryptionButton.setChecked(True)
71
72 def save(self):
73 """
74 Public slot to save the Email configuration.
75 """
76 Preferences.setUser(
77 "UseGoogleMailOAuth2",
78 self.googleMailCheckBox.isChecked())
79 Preferences.setUser(
80 "MailServer",
81 self.mailServerEdit.text())
82 Preferences.setUser(
83 "MailServerPort",
84 self.portSpin.value())
85 Preferences.setUser(
86 "Email",
87 self.emailEdit.text())
88 Preferences.setUser(
89 "Signature",
90 self.signatureEdit.toPlainText())
91 Preferences.setUser(
92 "MailServerAuthentication",
93 self.mailAuthenticationGroup.isChecked())
94 Preferences.setUser(
95 "MailServerUser",
96 self.mailUserEdit.text())
97 Preferences.setUser(
98 "MailServerPassword",
99 self.mailPasswordEdit.text())
100 if self.useTlsButton.isChecked():
101 encryption = "TLS"
102 elif self.useSslButton.isChecked():
103 encryption = "SSL"
104 else:
105 encryption = "No"
106 Preferences.setUser("MailServerEncryption", encryption)
107
108 def __updatePortSpin(self):
109 """
110 Private slot to set the value of the port spin box depending upon
111 the selected encryption method.
112 """
113 if self.useSslButton.isChecked():
114 self.portSpin.setValue(465)
115 elif self.useTlsButton.isChecked():
116 self.portSpin.setValue(587)
117 else:
118 self.portSpin.setValue(25)
119
120 @pyqtSlot(bool)
121 def on_noEncryptionButton_toggled(self, checked):
122 """
123 Private slot handling a change of no encryption button.
124
125 @param checked current state of the button
126 @type bool
127 """
128 self.__updatePortSpin()
129
130 @pyqtSlot(bool)
131 def on_useSslButton_toggled(self, checked):
132 """
133 Private slot handling a change of SSL encryption button.
134
135 @param checked current state of the button
136 @type bool
137 """
138 self.__updatePortSpin()
139
140 @pyqtSlot(bool)
141 def on_useTlsButton_toggled(self, checked):
142 """
143 Private slot handling a change of TLS encryption button.
144
145 @param checked current state of the button
146 @type bool
147 """
148 self.__updatePortSpin()
149
150 def __updateTestButton(self):
151 """
152 Private slot to update the enabled state of the test button.
153 """
154 self.testButton.setEnabled(
155 self.mailAuthenticationGroup.isChecked() and
156 self.mailUserEdit.text() != "" and
157 self.mailPasswordEdit.text() != "" and
158 self.mailServerEdit.text() != ""
159 )
160
161 @pyqtSlot(str)
162 def on_mailServerEdit_textChanged(self, txt):
163 """
164 Private slot to handle a change of the text of the mail server edit.
165
166 @param txt current text of the edit (string)
167 @type str
168 """
169 self.__updateTestButton()
170
171 @pyqtSlot(bool)
172 def on_mailAuthenticationGroup_toggled(self, checked):
173 """
174 Private slot to handle a change of the state of the authentication
175 group.
176
177 @param checked state of the group (boolean)
178 """
179 self.__updateTestButton()
180
181 @pyqtSlot(str)
182 def on_mailUserEdit_textChanged(self, txt):
183 """
184 Private slot to handle a change of the text of the user edit.
185
186 @param txt current text of the edit (string)
187 """
188 self.__updateTestButton()
189
190 @pyqtSlot(str)
191 def on_mailPasswordEdit_textChanged(self, txt):
192 """
193 Private slot to handle a change of the text of the user edit.
194
195 @param txt current text of the edit (string)
196 """
197 self.__updateTestButton()
198
199 @pyqtSlot()
200 def on_testButton_clicked(self):
201 """
202 Private slot to test the mail server login data.
203 """
204 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
205 QApplication.processEvents()
206 try:
207 if self.useSslButton.isChecked():
208 server = smtplib.SMTP_SSL(self.mailServerEdit.text(),
209 self.portSpin.value(),
210 timeout=10)
211 else:
212 server = smtplib.SMTP(self.mailServerEdit.text(),
213 self.portSpin.value(),
214 timeout=10)
215 if self.useTlsButton.isChecked():
216 server.starttls()
217 try:
218 server.login(self.mailUserEdit.text(),
219 self.mailPasswordEdit.text())
220 QApplication.restoreOverrideCursor()
221 E5MessageBox.information(
222 self,
223 self.tr("Login Test"),
224 self.tr("""The login test succeeded."""))
225 except (smtplib.SMTPException, socket.error) as e:
226 QApplication.restoreOverrideCursor()
227 if isinstance(e, smtplib.SMTPResponseException):
228 errorStr = e.smtp_error.decode()
229 elif isinstance(e, socket.timeout):
230 errorStr = str(e)
231 elif isinstance(e, socket.error):
232 try:
233 errorStr = e[1]
234 except TypeError:
235 errorStr = str(e)
236 else:
237 errorStr = str(e)
238 E5MessageBox.critical(
239 self,
240 self.tr("Login Test"),
241 self.tr(
242 """<p>The login test failed.<br>Reason: {0}</p>""")
243 .format(errorStr))
244 server.quit()
245 except (smtplib.SMTPException, socket.error) as e:
246 QApplication.restoreOverrideCursor()
247 if isinstance(e, smtplib.SMTPResponseException):
248 errorStr = e.smtp_error.decode()
249 elif isinstance(e, socket.timeout):
250 errorStr = str(e)
251 elif isinstance(e, socket.error):
252 try:
253 errorStr = e[1]
254 except TypeError:
255 errorStr = str(e)
256 else:
257 errorStr = str(e)
258 E5MessageBox.critical(
259 self,
260 self.tr("Login Test"),
261 self.tr("""<p>The login test failed.<br>Reason: {0}</p>""")
262 .format(errorStr))
263
264 @pyqtSlot()
265 def on_googleHelpButton_clicked(self):
266 """
267 Private slot to show some help text "how to turn on the Gmail API".
268 """
269 if self.__helpDialog is None:
270 try:
271 from E5Network.E5GoogleMail import GoogleMailHelp
272 helpStr = GoogleMailHelp()
273 except ImportError:
274 helpStr = self.tr(
275 "<p>The Google Mail Client API is not installed."
276 " Use <code>{0}</code> to install it.</p>"
277 ).format(getInstallCommand())
278
279 from E5Gui.E5SimpleHelpDialog import E5SimpleHelpDialog
280 self.__helpDialog = E5SimpleHelpDialog(
281 title=self.tr("Gmail API Help"),
282 helpStr=helpStr, parent=self)
283
284 self.__helpDialog.show()
285
286 @pyqtSlot()
287 def on_googleInstallButton_clicked(self):
288 """
289 Private slot to install the required packages for use of Google Mail.
290 """
291 pip = e5App().getObject("Pip")
292 pip.installPackages(RequiredPackages, interpreter=sys.executable)
293 self.__checkGoogleMail()
294
295 @pyqtSlot()
296 def on_googleCheckAgainButton_clicked(self):
297 """
298 Private slot to check again the availability of Google Mail.
299 """
300 self.__checkGoogleMail()
301
302 def __checkGoogleMail(self):
303 """
304 Private method to check the Google Mail availability and set the
305 widgets accordingly.
306 """
307 self.googleMailInfoLabel.hide()
308 self.googleInstallButton.show()
309 self.googleCheckAgainButton.show()
310 self.googleHelpButton.setEnabled(True)
311 self.googleMailCheckBox.setEnabled(True)
312
313 try:
314 import E5Network.E5GoogleMail # __IGNORE_WARNING__
315 from E5Network.E5GoogleMailHelpers import \
316 isClientSecretFileAvailable
317
318 self.googleInstallButton.hide()
319 if not isClientSecretFileAvailable():
320 # secrets file is not installed
321 self.googleMailCheckBox.setChecked(False)
322 self.googleMailCheckBox.setEnabled(False)
323 self.googleMailInfoLabel.setText(self.tr(
324 "<p>The client secrets file is not present."
325 " Has the Gmail API been enabled?</p>"))
326 self.googleMailInfoLabel.show()
327 Preferences.setUser("UseGoogleMailOAuth2", False)
328 else:
329 self.googleMailCheckBox.setChecked(
330 Preferences.getUser("UseGoogleMailOAuth2"))
331 self.googleMailInfoLabel.hide()
332 self.googleCheckAgainButton.hide()
333 except ImportError:
334 # missing libraries, disable Google Mail
335 self.googleMailCheckBox.setChecked(False)
336 self.googleMailCheckBox.setEnabled(False)
337 self.googleMailInfoLabel.setText(self.tr(
338 "<p>The Google Mail Client API is not installed."
339 " Use <code>{0}</code> to install it.</p>"
340 ).format(getInstallCommand()))
341 self.googleMailInfoLabel.show()
342 self.googleHelpButton.setEnabled(False)
343 Preferences.setUser("UseGoogleMailOAuth2", False)
344
345
346 def create(dlg):
347 """
348 Module function to create the configuration page.
349
350 @param dlg reference to the configuration dialog
351 @return reference to the instantiated page (ConfigurationPageBase)
352 """
353 page = EmailPage()
354 return page

eric ide

mercurial