PyEmailerAJM 1.1__tar.gz → 1.5__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-1.1 → PyEmailerAJM-1.5}/PKG-INFO +2 -2
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/PyEmailerAJM/PyEmailerAJM.py +112 -6
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/PyEmailerAJM.egg-info/PKG-INFO +2 -2
- PyEmailerAJM-1.5/README.md +15 -0
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/setup.py +2 -2
- PyEmailerAJM-1.1/README.md +0 -8
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/LICENSE.txt +0 -0
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/PyEmailerAJM/__init__.py +0 -0
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/PyEmailerAJM.egg-info/SOURCES.txt +0 -0
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/PyEmailerAJM.egg-info/dependency_links.txt +0 -0
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/PyEmailerAJM.egg-info/requires.txt +0 -0
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/PyEmailerAJM.egg-info/top_level.txt +0 -0
- {PyEmailerAJM-1.1 → PyEmailerAJM-1.5}/setup.cfg +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyEmailerAJM
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5
|
|
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/1.
|
|
9
|
+
Download-URL: https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/1.5.tar.gz
|
|
10
10
|
Keywords: Outlook,Email,Automation
|
|
11
11
|
Platform: UNKNOWN
|
|
12
12
|
License-File: LICENSE.txt
|
|
@@ -4,7 +4,8 @@ PyEmailerAJM.py
|
|
|
4
4
|
|
|
5
5
|
install win32 with pip install pywin32
|
|
6
6
|
"""
|
|
7
|
-
from os
|
|
7
|
+
from os import environ
|
|
8
|
+
from os.path import isfile, abspath, isabs, join, isdir
|
|
8
9
|
|
|
9
10
|
# imports
|
|
10
11
|
|
|
@@ -19,9 +20,21 @@ class EmailerNotSetupError(Exception):
|
|
|
19
20
|
...
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
class DisplayManualQuit(Exception):
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
|
|
22
27
|
class PyEmailer:
|
|
28
|
+
# the email tab_char
|
|
29
|
+
tab_char = ' '
|
|
30
|
+
signature_dir_path = join((environ['USERPROFILE']),
|
|
31
|
+
'AppData\\Roaming\\Microsoft\\Signatures\\')
|
|
32
|
+
|
|
33
|
+
DisplayEmailSendTrackingWarning = "THIS TYPE OF SEND CANNOT BE DETECTED FOR SEND SUCCESS AUTOMATICALLY."
|
|
34
|
+
|
|
23
35
|
def __init__(self, display_window: bool,
|
|
24
36
|
send_emails: bool, logger: Logger = None,
|
|
37
|
+
email_sig_filename: str = None,
|
|
25
38
|
auto_send: bool = False,
|
|
26
39
|
email_app_name: str = 'outlook.application'):
|
|
27
40
|
|
|
@@ -51,6 +64,69 @@ class PyEmailer:
|
|
|
51
64
|
self._logger.error(e, exc_info=True)
|
|
52
65
|
raise e
|
|
53
66
|
|
|
67
|
+
self._email_signature = None
|
|
68
|
+
self._send_success = False
|
|
69
|
+
self.email_sig_filename = email_sig_filename
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def email_signature(self):
|
|
73
|
+
return self._email_signature
|
|
74
|
+
|
|
75
|
+
@email_signature.getter
|
|
76
|
+
def email_signature(self):
|
|
77
|
+
signature_full_path = join(self.signature_dir_path, self.email_sig_filename)
|
|
78
|
+
if isdir(self.signature_dir_path):
|
|
79
|
+
pass
|
|
80
|
+
else:
|
|
81
|
+
try:
|
|
82
|
+
raise NotADirectoryError(f"{self.signature_dir_path} does not exist.")
|
|
83
|
+
except NotADirectoryError as e:
|
|
84
|
+
self._logger.warning(e)
|
|
85
|
+
self._email_signature = None
|
|
86
|
+
|
|
87
|
+
if isfile(signature_full_path):
|
|
88
|
+
with open(signature_full_path, 'r', encoding='utf-16') as f:
|
|
89
|
+
self._email_signature = f.read().strip()
|
|
90
|
+
else:
|
|
91
|
+
try:
|
|
92
|
+
raise FileNotFoundError(f"{signature_full_path} does not exist.")
|
|
93
|
+
except FileNotFoundError as e:
|
|
94
|
+
self._logger.warning(e)
|
|
95
|
+
self._email_signature = None
|
|
96
|
+
|
|
97
|
+
return self._email_signature
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def send_success(self):
|
|
101
|
+
return self._send_success
|
|
102
|
+
|
|
103
|
+
@send_success.setter
|
|
104
|
+
def send_success(self, value):
|
|
105
|
+
self._send_success = value
|
|
106
|
+
|
|
107
|
+
def _display_tracking_warning_confirm(self):
|
|
108
|
+
while True:
|
|
109
|
+
q = input(f"{self.DisplayEmailSendTrackingWarning}. Do you understand? (y/n): ").lower().strip()
|
|
110
|
+
if q == 'y':
|
|
111
|
+
self._logger.warning(self.DisplayEmailSendTrackingWarning)
|
|
112
|
+
return True
|
|
113
|
+
elif q == 'n':
|
|
114
|
+
return False
|
|
115
|
+
else:
|
|
116
|
+
print("Please respond with 'y' or 'n'.")
|
|
117
|
+
|
|
118
|
+
def display_tracker_check(self) -> bool:
|
|
119
|
+
if self.display_window:
|
|
120
|
+
c = self._display_tracking_warning_confirm()
|
|
121
|
+
if c:
|
|
122
|
+
return c
|
|
123
|
+
else:
|
|
124
|
+
try:
|
|
125
|
+
raise DisplayManualQuit("User cancelled operation due to DisplayTrackingWarning.")
|
|
126
|
+
except DisplayManualQuit as e:
|
|
127
|
+
self._logger.error(e, exc_info=True)
|
|
128
|
+
raise e
|
|
129
|
+
|
|
54
130
|
def _GetReadFolder(self, email_dir_index: int = 6):
|
|
55
131
|
# 6 = inbox
|
|
56
132
|
self.read_folder = self._mapi_ns.GetDefaultFolder(email_dir_index)
|
|
@@ -83,11 +159,39 @@ class PyEmailer:
|
|
|
83
159
|
self._logger.error(e, exc_info=True)
|
|
84
160
|
raise e
|
|
85
161
|
|
|
86
|
-
def FindMsgBySubject(self, subject: str
|
|
162
|
+
def FindMsgBySubject(self, subject: str, forwarded_message_match: bool = True,
|
|
163
|
+
reply_msg_match: bool = True) -> list:
|
|
164
|
+
"""Matches the message.Subject string to the subject attr string and returns a list of messages.
|
|
165
|
+
If forward_message_match is True than messages are matched without
|
|
166
|
+
regard to if they start with 'FW:' or 'FWD:'
|
|
167
|
+
|
|
168
|
+
If reply_msg_match is True than messages are matched without
|
|
169
|
+
regard to if they start with 'RE:'
|
|
170
|
+
"""
|
|
87
171
|
matched_messages = []
|
|
172
|
+
subject = subject.lower().strip()
|
|
173
|
+
fw_str = 'FW:'.lower()
|
|
174
|
+
fwd_str = 'FWD:'.lower()
|
|
175
|
+
re_str = 'RE:'.lower()
|
|
176
|
+
|
|
88
177
|
for message in self.GetMessages():
|
|
89
|
-
|
|
90
|
-
|
|
178
|
+
message.Subject = message.Subject.lower()
|
|
179
|
+
if forwarded_message_match:
|
|
180
|
+
if (message.Subject == subject or
|
|
181
|
+
(message.Subject.startswith(fw_str)
|
|
182
|
+
and message.Subject.split(fw_str)[1].strip() == subject) or
|
|
183
|
+
(message.Subject.startswith(fwd_str)
|
|
184
|
+
and message.Subject.split(fwd_str)[1].strip() == subject)):
|
|
185
|
+
matched_messages.append(message)
|
|
186
|
+
if reply_msg_match:
|
|
187
|
+
if (message.Subject == subject or
|
|
188
|
+
(message.Subject.startswith(re_str)
|
|
189
|
+
and message.Subject.split(re_str)[1].strip() == subject)):
|
|
190
|
+
matched_messages.append(message)
|
|
191
|
+
else:
|
|
192
|
+
if message.Subject == subject:
|
|
193
|
+
matched_messages.append(message)
|
|
194
|
+
|
|
91
195
|
return matched_messages
|
|
92
196
|
|
|
93
197
|
def SaveAllEmailAttachments(self, msg, save_dir_path):
|
|
@@ -166,8 +270,10 @@ class PyEmailer:
|
|
|
166
270
|
|
|
167
271
|
def _send(self):
|
|
168
272
|
try:
|
|
273
|
+
self.send_success = False
|
|
169
274
|
self.email.Send()
|
|
170
275
|
# print(f"Mail sent to {self._recipient}")
|
|
276
|
+
self.send_success = True
|
|
171
277
|
self._logger.info(f"Mail successfully sent to {self._recipient}")
|
|
172
278
|
except Exception as e:
|
|
173
279
|
self._logger.error(e, exc_info=True)
|
|
@@ -233,9 +339,9 @@ if __name__ == "__main__":
|
|
|
233
339
|
"subject": f"TEST: Your TEST "
|
|
234
340
|
f"agreement expires in 30 days or less!",
|
|
235
341
|
"text": "testing to see if the attachment works",
|
|
236
|
-
"recipient": '
|
|
342
|
+
"recipient": 'test',
|
|
237
343
|
"attachments": []
|
|
238
344
|
}
|
|
239
345
|
#   is the tab character for emails
|
|
240
|
-
emailer.SetupEmail(**r_dict) # recipient="
|
|
346
|
+
emailer.SetupEmail(**r_dict) # recipient="test", subject="test subject", text="test_body")
|
|
241
347
|
emailer.SendOrDisplay()"""
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyEmailerAJM
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5
|
|
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/1.
|
|
9
|
+
Download-URL: https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/1.5.tar.gz
|
|
10
10
|
Keywords: Outlook,Email,Automation
|
|
11
11
|
Platform: UNKNOWN
|
|
12
12
|
License-File: LICENSE.txt
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
**Import**
|
|
7
|
+
|
|
8
|
+
- import PyEmailer class using `from PyEmailerAJM.PyEmailerAJM import PyEmailer`
|
|
9
|
+
|
|
10
|
+
**Notes**
|
|
11
|
+
|
|
12
|
+
- see [OutlookPywin32Commands.xlsx](OutlookPywin32Commands.xlsx) for list of commands that can be used with a message object.
|
|
13
|
+
|
|
14
|
+
- Email signature **text** can now be added as of v1.4
|
|
15
|
+
- Assuming the signature *.txt file is found in `%APPDATA%/Microsoft/Signatures/`
|
|
@@ -2,10 +2,10 @@ from setuptools import setup
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='PyEmailerAJM',
|
|
5
|
-
version='1.
|
|
5
|
+
version='1.5',
|
|
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/1.
|
|
8
|
+
download_url='https://github.com/amcsparron2793-Water/PyEmailer/archive/refs/tags/1.5.tar.gz',
|
|
9
9
|
keywords=["Outlook", "Email", "Automation"],
|
|
10
10
|
install_requires=['pywin32'],
|
|
11
11
|
license='MIT License',
|
PyEmailerAJM-1.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
|