PyEmailerAJM 0.1__tar.gz → 1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/PKG-INFO +2 -2
- PyEmailerAJM-1.3/PyEmailerAJM/PyEmailerAJM.py +262 -0
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/PyEmailerAJM.egg-info/PKG-INFO +2 -2
- PyEmailerAJM-1.3/README.md +10 -0
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/setup.py +2 -2
- PyEmailerAJM-0.1/PyEmailerAJM/PyEmailerAJM.py +0 -164
- PyEmailerAJM-0.1/README.md +0 -8
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/LICENSE.txt +0 -0
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/PyEmailerAJM/__init__.py +0 -0
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/PyEmailerAJM.egg-info/SOURCES.txt +0 -0
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/PyEmailerAJM.egg-info/dependency_links.txt +0 -0
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/PyEmailerAJM.egg-info/requires.txt +0 -0
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/PyEmailerAJM.egg-info/top_level.txt +0 -0
- {PyEmailerAJM-0.1 → PyEmailerAJM-1.3}/setup.cfg +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyEmailerAJM
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.3
|
|
4
4
|
Summary: Allows for automating sending Email with the Outlook Desktop client. Future releases will add more client support
|
|
5
5
|
Home-page: https://github.com/amcsparron2793-Water/PyEmailer
|
|
6
6
|
Author: Amcsparron
|
|
7
7
|
Author-email: amcsparron@albanyny.gov
|
|
8
8
|
License: MIT License
|
|
9
|
-
Download-URL: https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/
|
|
9
|
+
Download-URL: https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/1.3.tar.gz
|
|
10
10
|
Keywords: Outlook,Email,Automation
|
|
11
11
|
Platform: UNKNOWN
|
|
12
12
|
License-File: LICENSE.txt
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
#! python3
|
|
2
|
+
"""
|
|
3
|
+
PyEmailerAJM.py
|
|
4
|
+
|
|
5
|
+
install win32 with pip install pywin32
|
|
6
|
+
"""
|
|
7
|
+
from os.path import isfile, abspath, isabs, join
|
|
8
|
+
|
|
9
|
+
# imports
|
|
10
|
+
|
|
11
|
+
# install win32 with pip install pywin32
|
|
12
|
+
import win32com.client as win32
|
|
13
|
+
# This is installed as part of pywin32
|
|
14
|
+
from pythoncom import com_error
|
|
15
|
+
from logging import Logger
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class EmailerNotSetupError(Exception):
|
|
19
|
+
...
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PyEmailer:
|
|
23
|
+
# the email tab_char
|
|
24
|
+
tab_char = ' '
|
|
25
|
+
|
|
26
|
+
def __init__(self, display_window: bool,
|
|
27
|
+
send_emails: bool, logger: Logger = None,
|
|
28
|
+
auto_send: bool = False,
|
|
29
|
+
email_app_name: str = 'outlook.application'):
|
|
30
|
+
|
|
31
|
+
if logger:
|
|
32
|
+
self._logger = logger
|
|
33
|
+
else:
|
|
34
|
+
self._logger = Logger("DUMMY")
|
|
35
|
+
# print("Dummy logger in use!")
|
|
36
|
+
|
|
37
|
+
self.email_app_name = email_app_name
|
|
38
|
+
|
|
39
|
+
self.display_window = display_window
|
|
40
|
+
self.auto_send = auto_send
|
|
41
|
+
self.send_emails = send_emails
|
|
42
|
+
self._setup_was_run = False
|
|
43
|
+
|
|
44
|
+
self._recipient = None
|
|
45
|
+
self._subject = None
|
|
46
|
+
self._text = None
|
|
47
|
+
self.read_folder = None
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
self.email_app = win32.Dispatch(self.email_app_name)
|
|
51
|
+
self._mapi_ns = self.email_app.GetNamespace('MAPI')
|
|
52
|
+
self.email = self.email_app.CreateItem(0)
|
|
53
|
+
except com_error as e:
|
|
54
|
+
self._logger.error(e, exc_info=True)
|
|
55
|
+
raise e
|
|
56
|
+
|
|
57
|
+
def _GetReadFolder(self, email_dir_index: int = 6):
|
|
58
|
+
# 6 = inbox
|
|
59
|
+
self.read_folder = self._mapi_ns.GetDefaultFolder(email_dir_index)
|
|
60
|
+
return self.read_folder
|
|
61
|
+
|
|
62
|
+
def GetMessages(self, folder_index=None):
|
|
63
|
+
if isinstance(folder_index, int):
|
|
64
|
+
self.read_folder = self._GetReadFolder(folder_index)
|
|
65
|
+
elif not folder_index and self.read_folder:
|
|
66
|
+
pass
|
|
67
|
+
elif not folder_index:
|
|
68
|
+
self.read_folder = self._GetReadFolder()
|
|
69
|
+
else:
|
|
70
|
+
try:
|
|
71
|
+
raise TypeError("folder_index must be an integer or self.read_folder must be defined")
|
|
72
|
+
except TypeError as e:
|
|
73
|
+
self._logger.error(e, exc_info=True)
|
|
74
|
+
raise e
|
|
75
|
+
return self.read_folder.Items
|
|
76
|
+
|
|
77
|
+
def GetEmailMessageBody(self, msg):
|
|
78
|
+
"""message = messages.GetLast()"""
|
|
79
|
+
body_content = msg.body
|
|
80
|
+
if body_content:
|
|
81
|
+
return body_content
|
|
82
|
+
else:
|
|
83
|
+
try:
|
|
84
|
+
raise ValueError("This message has no body.")
|
|
85
|
+
except ValueError as e:
|
|
86
|
+
self._logger.error(e, exc_info=True)
|
|
87
|
+
raise e
|
|
88
|
+
|
|
89
|
+
def FindMsgBySubject(self, subject: str, forwarded_message_match: bool = True,
|
|
90
|
+
reply_msg_match: bool = True) -> list:
|
|
91
|
+
"""Matches the message.Subject string to the subject attr string and returns a list of messages.
|
|
92
|
+
If forward_message_match is True than messages are matched without
|
|
93
|
+
regard to if they start with 'FW:' or 'FWD:'"""
|
|
94
|
+
matched_messages = []
|
|
95
|
+
for message in self.GetMessages():
|
|
96
|
+
if forwarded_message_match:
|
|
97
|
+
if (message.Subject == subject or
|
|
98
|
+
(message.Subject.startswith('FW:')
|
|
99
|
+
and message.Subject.split('FW:')[1].strip() == subject) or
|
|
100
|
+
(message.Subject.startswith('FWD:')
|
|
101
|
+
and message.Subject.split('FWD:')[1].strip() == subject)):
|
|
102
|
+
matched_messages.append(message)
|
|
103
|
+
if reply_msg_match:
|
|
104
|
+
if (message.Subject == subject or
|
|
105
|
+
(message.Subject.startswith('RE:')
|
|
106
|
+
and message.Subject.split('RE:')[1].strip() == subject)):
|
|
107
|
+
matched_messages.append(message)
|
|
108
|
+
else:
|
|
109
|
+
if message.Subject == subject:
|
|
110
|
+
matched_messages.append(message)
|
|
111
|
+
|
|
112
|
+
return matched_messages
|
|
113
|
+
|
|
114
|
+
def SaveAllEmailAttachments(self, msg, save_dir_path):
|
|
115
|
+
attachments = msg.Attachments
|
|
116
|
+
for attachment in attachments:
|
|
117
|
+
full_save_path = join(save_dir_path, str(attachment))
|
|
118
|
+
try:
|
|
119
|
+
attachment.SaveAsFile(full_save_path)
|
|
120
|
+
self._logger.debug(f"{full_save_path} saved from email with subject {msg.subject}")
|
|
121
|
+
except Exception as e:
|
|
122
|
+
self._logger.error(e, exc_info=True)
|
|
123
|
+
raise e
|
|
124
|
+
|
|
125
|
+
def SetupEmail(self, recipient: str, subject: str, text: str, attachments: list = None):
|
|
126
|
+
def _validate_attachments():
|
|
127
|
+
if attachments:
|
|
128
|
+
if isinstance(attachments, list):
|
|
129
|
+
for a in attachments:
|
|
130
|
+
if isfile(a):
|
|
131
|
+
if isabs(a):
|
|
132
|
+
self.email.Attachments.Add(a)
|
|
133
|
+
else:
|
|
134
|
+
a = abspath(a)
|
|
135
|
+
if isfile(a):
|
|
136
|
+
self.email.Attachments.Add(a)
|
|
137
|
+
else:
|
|
138
|
+
try:
|
|
139
|
+
raise FileNotFoundError(f"file {a} could not be attached.")
|
|
140
|
+
except FileNotFoundError as e:
|
|
141
|
+
self._logger.error(e, exc_info=True)
|
|
142
|
+
raise e
|
|
143
|
+
else:
|
|
144
|
+
try:
|
|
145
|
+
raise FileNotFoundError(f"file {a} could not be attached.")
|
|
146
|
+
except FileNotFoundError as e:
|
|
147
|
+
self._logger.error(e, exc_info=True)
|
|
148
|
+
raise e
|
|
149
|
+
else:
|
|
150
|
+
try:
|
|
151
|
+
raise TypeError("attachments attribute must be a list")
|
|
152
|
+
except TypeError as e:
|
|
153
|
+
self._logger.error(e, exc_info=True)
|
|
154
|
+
raise e
|
|
155
|
+
else:
|
|
156
|
+
self._logger.debug("no attachments detected")
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
# set the params
|
|
160
|
+
_validate_attachments()
|
|
161
|
+
self.email.To = recipient
|
|
162
|
+
self.email.Subject = subject
|
|
163
|
+
self.email.HtmlBody = text
|
|
164
|
+
|
|
165
|
+
self._recipient = self.email.To
|
|
166
|
+
self._subject = self.email.Subject
|
|
167
|
+
self._text = self.email.HtmlBody
|
|
168
|
+
|
|
169
|
+
# print("New email set up successfully.")
|
|
170
|
+
self._logger.info("New email set up successfully. see debug for details")
|
|
171
|
+
self._logger.debug(f"Email recipient {recipient}, Subject {subject}, Message body {text}")
|
|
172
|
+
self._setup_was_run = True
|
|
173
|
+
return self.email
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
self._logger.error(e, exc_info=True)
|
|
177
|
+
raise e
|
|
178
|
+
|
|
179
|
+
def _display(self):
|
|
180
|
+
# print(f"Displaying the email in {self.email_app_name}, this window might open minimized.")
|
|
181
|
+
self._logger.info(f"Displaying the email in {self.email_app_name}, this window might open minimized.")
|
|
182
|
+
try:
|
|
183
|
+
self.email.Display(True)
|
|
184
|
+
except Exception as e:
|
|
185
|
+
self._logger.error(e, exc_info=True)
|
|
186
|
+
raise e
|
|
187
|
+
|
|
188
|
+
def _send(self):
|
|
189
|
+
try:
|
|
190
|
+
self.email.Send()
|
|
191
|
+
# print(f"Mail sent to {self._recipient}")
|
|
192
|
+
self._logger.info(f"Mail successfully sent to {self._recipient}")
|
|
193
|
+
except Exception as e:
|
|
194
|
+
self._logger.error(e, exc_info=True)
|
|
195
|
+
raise e
|
|
196
|
+
|
|
197
|
+
def _manual_send_loop(self):
|
|
198
|
+
while True:
|
|
199
|
+
yn = input("Send Mail? (y/n/q): ").lower()
|
|
200
|
+
if yn == 'y':
|
|
201
|
+
self._send()
|
|
202
|
+
break
|
|
203
|
+
elif yn == 'n':
|
|
204
|
+
self._logger.info(f"Mail not sent to {self._recipient}")
|
|
205
|
+
print(f"Mail not sent to {self._recipient}")
|
|
206
|
+
break
|
|
207
|
+
elif yn == 'q':
|
|
208
|
+
print("ok quitting!")
|
|
209
|
+
self._logger.warning("Quitting early due to user input.")
|
|
210
|
+
exit(-1)
|
|
211
|
+
else:
|
|
212
|
+
print("Please choose \'y\', \'n\' or \'q\'")
|
|
213
|
+
|
|
214
|
+
def SendOrDisplay(self):
|
|
215
|
+
if self._setup_was_run:
|
|
216
|
+
# print(f"Ready to send/display mail to/for {self._recipient}...")
|
|
217
|
+
self._logger.info(f"Ready to send/display mail to/for {self._recipient}...")
|
|
218
|
+
if self.send_emails and self.display_window:
|
|
219
|
+
send_and_display_warning = ("Sending email while also displaying the email "
|
|
220
|
+
"in the app is not possible. Defaulting to Display only")
|
|
221
|
+
# print(send_and_display_warning)
|
|
222
|
+
self._logger.warning(send_and_display_warning)
|
|
223
|
+
self.send_emails = False
|
|
224
|
+
self.display_window = True
|
|
225
|
+
|
|
226
|
+
if self.send_emails:
|
|
227
|
+
if self.auto_send:
|
|
228
|
+
self._logger.info("Sending emails with auto_send...")
|
|
229
|
+
self._send()
|
|
230
|
+
else:
|
|
231
|
+
self._manual_send_loop()
|
|
232
|
+
|
|
233
|
+
elif self.display_window:
|
|
234
|
+
self._display()
|
|
235
|
+
else:
|
|
236
|
+
both_disabled_warning = ("Both sending and displaying the email are disabled. "
|
|
237
|
+
"No errors were encountered.")
|
|
238
|
+
self._logger.warning(both_disabled_warning)
|
|
239
|
+
# print(both_disabled_warning)
|
|
240
|
+
else:
|
|
241
|
+
try:
|
|
242
|
+
raise EmailerNotSetupError("Setup has not been run, sending or displaying an email cannot occur.")
|
|
243
|
+
except EmailerNotSetupError as e:
|
|
244
|
+
self._logger.error(e, exc_info=True)
|
|
245
|
+
raise e
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
if __name__ == "__main__":
|
|
249
|
+
module_name = __file__.split('\\')[-1].split('.py')[0]
|
|
250
|
+
|
|
251
|
+
"""emailer = PyEmailer(display_window=False, send_emails=True, auto_send=False)
|
|
252
|
+
|
|
253
|
+
r_dict = {
|
|
254
|
+
"subject": f"TEST: Your TEST "
|
|
255
|
+
f"agreement expires in 30 days or less!",
|
|
256
|
+
"text": "testing to see if the attachment works",
|
|
257
|
+
"recipient": 'test',
|
|
258
|
+
"attachments": []
|
|
259
|
+
}
|
|
260
|
+
#   is the tab character for emails
|
|
261
|
+
emailer.SetupEmail(**r_dict) # recipient="test", subject="test subject", text="test_body")
|
|
262
|
+
emailer.SendOrDisplay()"""
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyEmailerAJM
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.3
|
|
4
4
|
Summary: Allows for automating sending Email with the Outlook Desktop client. Future releases will add more client support
|
|
5
5
|
Home-page: https://github.com/amcsparron2793-Water/PyEmailer
|
|
6
6
|
Author: Amcsparron
|
|
7
7
|
Author-email: amcsparron@albanyny.gov
|
|
8
8
|
License: MIT License
|
|
9
|
-
Download-URL: https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/
|
|
9
|
+
Download-URL: https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/1.3.tar.gz
|
|
10
10
|
Keywords: Outlook,Email,Automation
|
|
11
11
|
Platform: UNKNOWN
|
|
12
12
|
License-File: LICENSE.txt
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# <u>PyEmailerAJM</u>
|
|
2
|
+
### <i>Makes automating Outlook emails quick and easy</i>
|
|
3
|
+
|
|
4
|
+
- PyEmailerAJM uses pywin32 to automate the sending/reading of Outlook emails.
|
|
5
|
+
|
|
6
|
+
<b>Import</b>
|
|
7
|
+
|
|
8
|
+
import PyEmailer class using `from PyEmailerAJM.PyEmailerAJM import PyEmailer`
|
|
9
|
+
|
|
10
|
+
see [OutlookPywin32Commands.xlsx](OutlookPywin32Commands.xlsx) for list of commands that can be used with a message object.
|
|
@@ -2,10 +2,10 @@ from setuptools import setup
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='PyEmailerAJM',
|
|
5
|
-
version='
|
|
5
|
+
version='1.3',
|
|
6
6
|
packages=['PyEmailerAJM'],
|
|
7
7
|
url='https://github.com/amcsparron2793-Water/PyEmailer',
|
|
8
|
-
download_url='https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/
|
|
8
|
+
download_url='https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/1.3.tar.gz',
|
|
9
9
|
keywords=["Outlook", "Email", "Automation"],
|
|
10
10
|
install_requires=['pywin32'],
|
|
11
11
|
license='MIT License',
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
#! python3
|
|
2
|
-
"""
|
|
3
|
-
PyEmailerAJM.py
|
|
4
|
-
|
|
5
|
-
install win32 with pip install pywin32
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
# imports
|
|
9
|
-
|
|
10
|
-
# install win32 with pip install pywin32
|
|
11
|
-
import win32com.client as win32
|
|
12
|
-
# This is installed as part of pywin32
|
|
13
|
-
from pythoncom import com_error
|
|
14
|
-
from logging import Logger
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class EmailerNotSetupError(Exception):
|
|
18
|
-
...
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class PyEmailer:
|
|
22
|
-
def __init__(self, display_window: bool,
|
|
23
|
-
send_emails: bool, logger: Logger = None,
|
|
24
|
-
auto_send: bool = False,
|
|
25
|
-
email_app_name: str = 'outlook.application'):
|
|
26
|
-
|
|
27
|
-
if logger:
|
|
28
|
-
self._logger = logger
|
|
29
|
-
else:
|
|
30
|
-
self._logger = Logger("DUMMY")
|
|
31
|
-
# print("Dummy logger in use!")
|
|
32
|
-
|
|
33
|
-
self.email_app_name = email_app_name
|
|
34
|
-
|
|
35
|
-
self.display_window = display_window
|
|
36
|
-
self.auto_send = auto_send
|
|
37
|
-
self.send_emails = send_emails
|
|
38
|
-
self._setup_was_run = False
|
|
39
|
-
|
|
40
|
-
self._recipient = None
|
|
41
|
-
self._subject = None
|
|
42
|
-
self._text = None
|
|
43
|
-
|
|
44
|
-
try:
|
|
45
|
-
self.email_app = win32.Dispatch(self.email_app_name)
|
|
46
|
-
self.email = self.email_app.CreateItem(0)
|
|
47
|
-
except com_error as e:
|
|
48
|
-
self._logger.error(e, exc_info=True)
|
|
49
|
-
raise e
|
|
50
|
-
|
|
51
|
-
def SetupEmail(self, recipient: str, subject: str, text: str):
|
|
52
|
-
try:
|
|
53
|
-
# set the params
|
|
54
|
-
self.email.To = recipient
|
|
55
|
-
self.email.Subject = subject
|
|
56
|
-
self.email.HtmlBody = text
|
|
57
|
-
|
|
58
|
-
self._recipient = self.email.To
|
|
59
|
-
self._subject = self.email.Subject
|
|
60
|
-
self._text = self.email.HtmlBody
|
|
61
|
-
|
|
62
|
-
# print("New email set up successfully.")
|
|
63
|
-
self._logger.info("New email set up successfully. see debug for details")
|
|
64
|
-
self._logger.debug(f"Email recipient {recipient}, Subject {subject}, Message body {text}")
|
|
65
|
-
self._setup_was_run = True
|
|
66
|
-
return self.email
|
|
67
|
-
|
|
68
|
-
except Exception as e:
|
|
69
|
-
self._logger.error(e, exc_info=True)
|
|
70
|
-
raise e
|
|
71
|
-
|
|
72
|
-
def _display(self):
|
|
73
|
-
# print(f"Displaying the email in {self.email_app_name}, this window might open minimized.")
|
|
74
|
-
self._logger.info(f"Displaying the email in {self.email_app_name}, this window might open minimized.")
|
|
75
|
-
try:
|
|
76
|
-
self.email.Display(True)
|
|
77
|
-
except Exception as e:
|
|
78
|
-
self._logger.error(e, exc_info=True)
|
|
79
|
-
raise e
|
|
80
|
-
|
|
81
|
-
def _send(self):
|
|
82
|
-
try:
|
|
83
|
-
self.email.Send()
|
|
84
|
-
# print(f"Mail sent to {self._recipient}")
|
|
85
|
-
self._logger.info(f"Mail successfully sent to {self._recipient}")
|
|
86
|
-
except Exception as e:
|
|
87
|
-
self._logger.error(e, exc_info=True)
|
|
88
|
-
raise e
|
|
89
|
-
|
|
90
|
-
def _manual_send_loop(self):
|
|
91
|
-
while True:
|
|
92
|
-
yn = input("Send Mail? (y/n/q): ").lower()
|
|
93
|
-
if yn == 'y':
|
|
94
|
-
self._send()
|
|
95
|
-
break
|
|
96
|
-
elif yn == 'n':
|
|
97
|
-
self._logger.info(f"Mail not sent to {self._recipient}")
|
|
98
|
-
print(f"Mail not sent to {self._recipient}")
|
|
99
|
-
break
|
|
100
|
-
elif yn == 'q':
|
|
101
|
-
print("ok quitting!")
|
|
102
|
-
self._logger.warning("Quitting early due to user input.")
|
|
103
|
-
exit(-1)
|
|
104
|
-
else:
|
|
105
|
-
print("Please choose \'y\', \'n\' or \'q\'")
|
|
106
|
-
|
|
107
|
-
def SendOrDisplay(self):
|
|
108
|
-
if self._setup_was_run:
|
|
109
|
-
# print(f"Ready to send/display mail to/for {self._recipient}...")
|
|
110
|
-
self._logger.info(f"Ready to send/display mail to/for {self._recipient}...")
|
|
111
|
-
if self.send_emails and self.display_window:
|
|
112
|
-
send_and_display_warning = ("Sending email while also displaying the email "
|
|
113
|
-
"in the app is not possible. Defaulting to Display only")
|
|
114
|
-
# print(send_and_display_warning)
|
|
115
|
-
self._logger.warning(send_and_display_warning)
|
|
116
|
-
self.send_emails = False
|
|
117
|
-
self.display_window = True
|
|
118
|
-
|
|
119
|
-
if self.send_emails:
|
|
120
|
-
if self.auto_send:
|
|
121
|
-
self._logger.info("Sending emails with auto_send...")
|
|
122
|
-
self._send()
|
|
123
|
-
else:
|
|
124
|
-
self._manual_send_loop()
|
|
125
|
-
|
|
126
|
-
elif self.display_window:
|
|
127
|
-
self._display()
|
|
128
|
-
else:
|
|
129
|
-
both_disabled_warning = ("Both sending and displaying the email are disabled. "
|
|
130
|
-
"No errors were encountered.")
|
|
131
|
-
self._logger.warning(both_disabled_warning)
|
|
132
|
-
# print(both_disabled_warning)
|
|
133
|
-
else:
|
|
134
|
-
try:
|
|
135
|
-
raise EmailerNotSetupError("Setup has not been run, sending or displaying an email cannot occur.")
|
|
136
|
-
except EmailerNotSetupError as e:
|
|
137
|
-
self._logger.error(e, exc_info=True)
|
|
138
|
-
raise e
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if __name__ == "__main__":
|
|
142
|
-
module_name = __file__.split('\\')[-1].split('.py')[0]
|
|
143
|
-
|
|
144
|
-
"""emailer = PyEmailer(display_window=False, send_emails=True, auto_send=False)
|
|
145
|
-
|
|
146
|
-
r_dict = {
|
|
147
|
-
"subject": f"TEST: Your TEST "
|
|
148
|
-
f"agreement expires in 30 days or less!",
|
|
149
|
-
"text": f"To whom it may concern,<br>"
|
|
150
|
-
f"  Your TEST "
|
|
151
|
-
f"agreement <b>expires in 30 days or less (your due date is TEST)</b>. "
|
|
152
|
-
f"Please renew the aforementioned by dropping off a hard copy to "
|
|
153
|
-
f"the Albany Water Department at 10 N Enterprise Dr.<br>"
|
|
154
|
-
f"Thank You,<br>"
|
|
155
|
-
f"AWD"
|
|
156
|
-
f"<br>"
|
|
157
|
-
f"<br>"
|
|
158
|
-
f"<br>"
|
|
159
|
-
f"This is an automated email, Please do not respond directly to it.",
|
|
160
|
-
"recipient": ''
|
|
161
|
-
}
|
|
162
|
-
#   is the tab character for emails
|
|
163
|
-
emailer.SetupEmail(**r_dict) # recipient="amcsparron@albanyny.gov", subject="test subject", text="test_body")
|
|
164
|
-
emailer.SendOrDisplay()"""
|
PyEmailerAJM-0.1/README.md
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|