eric7/Preferences/ConfigurationPages/EmailPage.py

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

eric ide

mercurial