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.
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyEmailerAJM
3
- Version: 1.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.1.tar.gz
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.path import isfile, abspath, isabs, join
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) -> list:
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
- if message.Subject == subject:
90
- matched_messages.append(message)
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": 'pbehnke@albanyny.gov',
342
+ "recipient": 'test',
237
343
  "attachments": []
238
344
  }
239
345
  #   is the tab character for emails
240
- emailer.SetupEmail(**r_dict) # recipient="amcsparron@albanyny.gov", subject="test subject", text="test_body")
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.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.1.tar.gz
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.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.1.tar.gz',
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',
@@ -1,8 +0,0 @@
1
- # <u>PyEmailerAJM</u>
2
- ### <i>Makes automating Outlook emails quick and easy</i>
3
-
4
- - PyEmailerAJM uses pywin32 to automate the sending of Outlook emails.
5
-
6
- <b>Import</b>
7
-
8
- import PyEmailer class using `from PyEmailerAJM.PyEmailerAJM import PyEmailer`
File without changes
File without changes