AIEmailAutomationUtility 0.0.8__py3-none-any.whl → 0.0.10__py3-none-any.whl
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.
- AIEmailAutomationUtility/EmailReplyAssistant.py +12 -13
- AIEmailAutomationUtility/Email_Classification.py +1 -4
- AIEmailAutomationUtility/Email_DocumentUploader.py +25 -41
- AIEmailAutomationUtility/Email_Draft.py +2 -6
- AIEmailAutomationUtility/Email_Read.py +282 -24
- {AIEmailAutomationUtility-0.0.8.dist-info → AIEmailAutomationUtility-0.0.10.dist-info}/METADATA +3 -3
- AIEmailAutomationUtility-0.0.10.dist-info/RECORD +14 -0
- AIEmailAutomationUtility-0.0.8.dist-info/RECORD +0 -14
- {AIEmailAutomationUtility-0.0.8.dist-info → AIEmailAutomationUtility-0.0.10.dist-info}/LICENCE.txt +0 -0
- {AIEmailAutomationUtility-0.0.8.dist-info → AIEmailAutomationUtility-0.0.10.dist-info}/WHEEL +0 -0
- {AIEmailAutomationUtility-0.0.8.dist-info → AIEmailAutomationUtility-0.0.10.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@ from openai import OpenAI, AssistantEventHandler
|
|
4
4
|
from flask import Flask,request
|
5
5
|
import json
|
6
6
|
import loggerutility as logger
|
7
|
+
import ast, re
|
7
8
|
|
8
9
|
class EmailReplyAssistant:
|
9
10
|
def __init__(self):
|
@@ -18,23 +19,23 @@ class EmailReplyAssistant:
|
|
18
19
|
|
19
20
|
def on_text_created(self, text):
|
20
21
|
if isinstance(text, str):
|
21
|
-
|
22
|
+
logger.log(f"\nAssistant: {text}", end="", flush=True)
|
22
23
|
|
23
24
|
def on_text_delta(self, delta, snapshot):
|
24
25
|
self.delta_values.append(delta.value)
|
25
26
|
|
26
27
|
def on_tool_call_created(self, tool_call):
|
27
|
-
|
28
|
+
logger.log(f"\nAssistant: {tool_call.type}\n", flush=True)
|
28
29
|
|
29
30
|
def on_tool_call_delta(self, delta, snapshot):
|
30
31
|
if delta.type == 'code_interpreter':
|
31
32
|
if delta.code_interpreter.input:
|
32
|
-
|
33
|
+
logger.log(delta.code_interpreter.input, end="", flush=True)
|
33
34
|
if delta.code_interpreter.outputs:
|
34
|
-
|
35
|
+
logger.log(f"\n\nOutput >", flush=True)
|
35
36
|
for output in delta.code_interpreter.outputs:
|
36
37
|
if output.type == "logs":
|
37
|
-
|
38
|
+
logger.log(output.logs, flush=True)
|
38
39
|
|
39
40
|
openAI_response = ""
|
40
41
|
client = OpenAI(api_key=openAI_key)
|
@@ -65,15 +66,13 @@ class EmailReplyAssistant:
|
|
65
66
|
except Exception as error:
|
66
67
|
responseStr = "<br/><br/>" + str(error)
|
67
68
|
trace = traceback.format_exc()
|
68
|
-
|
69
|
+
logger.log(f"Exception in process_Email: {responseStr} \n {trace} \n DataType ::: {type(responseStr)}")
|
70
|
+
m = re.search(r"({.*})", str(error))
|
71
|
+
data = ast.literal_eval(m.group(1)).get('error') if m else {}
|
72
|
+
return {"status": "Failed", "message": data.get('message')}
|
69
73
|
|
70
|
-
def email_reply_assitant(self):
|
74
|
+
def email_reply_assitant(self, data):
|
71
75
|
try:
|
72
|
-
# while True:
|
73
|
-
data = request.get_data('jsonData', None)
|
74
|
-
data = json.loads(data[9:])
|
75
|
-
logger.log(f"jsondata:: {data}")
|
76
|
-
|
77
76
|
openAI_key = data.get("openAI_key")
|
78
77
|
assistant_ID = data.get("assistant_ID")
|
79
78
|
email_content = data.get("email_content")
|
@@ -89,7 +88,7 @@ class EmailReplyAssistant:
|
|
89
88
|
subject=subject
|
90
89
|
)
|
91
90
|
|
92
|
-
logger.log(f"Reply_Email_Ai_Assistant response: {email_response}")
|
91
|
+
# logger.log(f"Reply_Email_Ai_Assistant response: {email_response}")
|
93
92
|
return email_response
|
94
93
|
|
95
94
|
except Exception as e:
|
@@ -142,11 +142,8 @@ class Email_Classification:
|
|
142
142
|
logger.log(f"Error with LocalAI detection/generation: {str(e)}")
|
143
143
|
return {"success": "Failed", "message": f"Error with LocalAI detection/generation: {str(e)}"}
|
144
144
|
|
145
|
-
def detect_category(self):
|
145
|
+
def detect_category(self, data):
|
146
146
|
try:
|
147
|
-
data = request.get_data('jsonData', None)
|
148
|
-
data = json.loads(data[9:])
|
149
|
-
logger.log(f"jsondata:: {data}")
|
150
147
|
model_type = data.get('model_type', 'OpenAI')
|
151
148
|
|
152
149
|
required_fields = ['email_body', 'categories']
|
@@ -5,7 +5,6 @@ import requests
|
|
5
5
|
import loggerutility as logger
|
6
6
|
from flask import Flask,request
|
7
7
|
|
8
|
-
|
9
8
|
class Email_DocumentUploader:
|
10
9
|
def upload_document(self, upload_config, file_data):
|
11
10
|
# try:
|
@@ -55,47 +54,32 @@ class Email_DocumentUploader:
|
|
55
54
|
return str(response.status_code), document_id
|
56
55
|
else:
|
57
56
|
return str(response.status_code), f"Upload failed: {response.text}"
|
58
|
-
|
59
|
-
# except Exception as e:
|
60
|
-
# logger.log(f"Error uploading document: {str(e)}")
|
61
|
-
# raise
|
62
|
-
# finally:
|
63
|
-
# # Cleanup
|
64
|
-
# if os.path.exists(temp_dir):
|
65
|
-
# shutil.rmtree(temp_dir)
|
66
|
-
|
67
|
-
def email_document_upload(self):
|
68
|
-
try:
|
69
|
-
if 'file' not in request.files:
|
70
|
-
return "file not found"
|
71
|
-
|
72
|
-
file = request.files['file']
|
73
|
-
if file.filename == '':
|
74
|
-
return "No selected file"
|
75
57
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
'file_type': request.form.get('FILE_TYPE', ''),
|
81
|
-
'app_id': request.form.get('APP_ID', ''),
|
82
|
-
'method': request.form.get('Method_Type', 'POST'),
|
83
|
-
'url': request.form.get('RestAPI_Url')
|
84
|
-
}
|
58
|
+
def email_document_upload(self, file, parameters_details):
|
59
|
+
logger.log(f"file ::: {file}")
|
60
|
+
if not file:
|
61
|
+
return "file not found"
|
85
62
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
63
|
+
upload_config = {
|
64
|
+
'token_id': parameters_details.get('TOKEN_ID'),
|
65
|
+
'document_type': parameters_details.get('DOCUMENT_TYPE', ''),
|
66
|
+
'obj_name': parameters_details.get('OBJ_NAME', ''),
|
67
|
+
'file_type': parameters_details.get('FILE_TYPE', ''),
|
68
|
+
'app_id': parameters_details.get('APP_ID', ''),
|
69
|
+
'method': parameters_details.get('Method_Type', 'POST'),
|
70
|
+
'url': parameters_details.get('RestAPI_Url')
|
71
|
+
}
|
94
72
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
73
|
+
# Validate required fields
|
74
|
+
if not upload_config['token_id'] or not upload_config['url']:
|
75
|
+
return "Missing required fields: TOKEN_ID or RestAPI_Url"
|
76
|
+
|
77
|
+
file_data = {
|
78
|
+
'filename': os.path.basename(file.name),
|
79
|
+
'content': file.read()
|
80
|
+
}
|
99
81
|
|
100
|
-
|
101
|
-
|
82
|
+
response_status, restAPI_Result = self.upload_document(upload_config, file_data)
|
83
|
+
|
84
|
+
logger.log(f"Upload_Document response result: {restAPI_Result}")
|
85
|
+
return response_status, restAPI_Result
|
@@ -12,7 +12,6 @@ class Email_Draft:
|
|
12
12
|
try:
|
13
13
|
with imaplib.IMAP4_SSL(host=email_config['host'], port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
|
14
14
|
imap_ssl.login(email_config['email'], email_config['password'])
|
15
|
-
logger.log(f"login successfully")
|
16
15
|
|
17
16
|
message = Message()
|
18
17
|
message["From"] = email_config['email']
|
@@ -28,7 +27,7 @@ class Email_Draft:
|
|
28
27
|
message.set_payload(f"{response_content}\n\n{mail_details}\n\n{email_details['body']}")
|
29
28
|
|
30
29
|
utf8_message = str(message).encode("utf-8")
|
31
|
-
logger.log(f"utf8_message:: {utf8_message}")
|
30
|
+
# logger.log(f"utf8_message:: {utf8_message}")
|
32
31
|
imap_ssl.append("[Gmail]/Drafts", '', imaplib.Time2Internaldate(time.time()), utf8_message)
|
33
32
|
|
34
33
|
return True, utf8_message.decode("utf-8")
|
@@ -57,11 +56,8 @@ class Email_Draft:
|
|
57
56
|
logger.log(f"Error creating draft: {str(e)}")
|
58
57
|
return "Failed", None
|
59
58
|
|
60
|
-
def draft_mail(self):
|
59
|
+
def draft_mail(self, data):
|
61
60
|
try:
|
62
|
-
data = request.get_data('jsonData', None)
|
63
|
-
data = json.loads(data[9:])
|
64
|
-
logger.log(f"jsondata:: {data}")
|
65
61
|
|
66
62
|
if "reciever_email_addr" in data and data["reciever_email_addr"] != None:
|
67
63
|
reciever_email_addr = data["reciever_email_addr"]
|
@@ -4,14 +4,21 @@ import os
|
|
4
4
|
import json
|
5
5
|
import time
|
6
6
|
import loggerutility as logger
|
7
|
-
from flask import
|
7
|
+
from flask import request
|
8
|
+
import traceback
|
9
|
+
from fpdf import FPDF
|
10
|
+
|
8
11
|
from .Save_Transaction import Save_Transaction
|
9
12
|
from .Email_Upload_Document import Email_Upload_Document
|
13
|
+
from .Email_Classification import Email_Classification
|
14
|
+
from .EmailReplyAssistant import EmailReplyAssistant
|
15
|
+
from .Email_Draft import Email_Draft
|
16
|
+
from .Email_DocumentUploader import Email_DocumentUploader
|
10
17
|
|
11
18
|
class Email_Read:
|
12
19
|
def read_email(self, email_config):
|
13
20
|
try:
|
14
|
-
logger.log("inside
|
21
|
+
logger.log("inside read_email")
|
15
22
|
mail = imaplib.IMAP4_SSL(email_config['host'], email_config['port'])
|
16
23
|
mail.login(email_config['email'], email_config['password'])
|
17
24
|
logger.log("login successfully")
|
@@ -26,7 +33,7 @@ class Email_Read:
|
|
26
33
|
|
27
34
|
if not email_ids:
|
28
35
|
logger.log("Email not found, going to check new mail")
|
29
|
-
|
36
|
+
logger.log("Email not found,\ngoing to check new mail \n")
|
30
37
|
else:
|
31
38
|
|
32
39
|
for email_id in email_ids:
|
@@ -64,23 +71,6 @@ class Email_Read:
|
|
64
71
|
call_save_transaction = Save_Transaction()
|
65
72
|
save_transaction_response = call_save_transaction.email_save_transaction(email_data)
|
66
73
|
logger.log(f"save_transaction_response:: {save_transaction_response}")
|
67
|
-
|
68
|
-
if save_transaction_response['status'] == "Success":
|
69
|
-
if msg.is_multipart():
|
70
|
-
for part in msg.walk():
|
71
|
-
content_disposition = str(part.get("Content-Disposition"))
|
72
|
-
|
73
|
-
if "attachment" in content_disposition:
|
74
|
-
attachment_path = self.save_attachment(part, "attachments")
|
75
|
-
if attachment_path:
|
76
|
-
logger.log(f"Attachment saved at: {attachment_path}")
|
77
|
-
attachments.append(attachment_path)
|
78
|
-
for file_path in attachments:
|
79
|
-
logger.log(f"file_path:: {file_path}")
|
80
|
-
email_upload_doc = Email_Upload_Document()
|
81
|
-
email_file_upload = email_upload_doc.upload_files(file_path)
|
82
|
-
logger.log(f"file uploaded :: {email_file_upload}")
|
83
|
-
logger.log(f"emails:: {emails}")
|
84
74
|
time.sleep(10)
|
85
75
|
|
86
76
|
except Exception as e:
|
@@ -92,6 +82,181 @@ class Email_Read:
|
|
92
82
|
except Exception as close_error:
|
93
83
|
logger.log(f"Error during mail close/logout: {str(close_error)}")
|
94
84
|
|
85
|
+
def read_email_automation(self, email_config):
|
86
|
+
# try:
|
87
|
+
logger.log(f"inside read_email_automation")
|
88
|
+
# logger.log(f"email_config ::: {email_config}")
|
89
|
+
LABEL = "Unprocessed_Email"
|
90
|
+
file_JsonArray = []
|
91
|
+
templateName = "ai_email_automation.json"
|
92
|
+
fileName = ""
|
93
|
+
|
94
|
+
Model_Name = email_config.get('model_type', 'OpenAI')
|
95
|
+
reciever_email_addr = email_config.get('email', '')
|
96
|
+
receiver_email_pwd = email_config.get('password', '')
|
97
|
+
host = email_config.get('host', '')
|
98
|
+
port = email_config.get('port', '')
|
99
|
+
|
100
|
+
mail = imaplib.IMAP4_SSL(host, port)
|
101
|
+
mail.login(reciever_email_addr, receiver_email_pwd)
|
102
|
+
logger.log("login successfully")
|
103
|
+
mail.select('inbox')
|
104
|
+
|
105
|
+
file_JsonArray, categories = self.read_JSON_File(templateName)
|
106
|
+
|
107
|
+
while True:
|
108
|
+
status, email_ids = mail.search(None, 'UNSEEN')
|
109
|
+
emails = []
|
110
|
+
|
111
|
+
if status == 'OK':
|
112
|
+
email_ids = email_ids[0].split()
|
113
|
+
|
114
|
+
if not email_ids:
|
115
|
+
logger.log("Email not found, going to check new mail")
|
116
|
+
logger.log("Email not found,\ngoing to check new mail \n")
|
117
|
+
else:
|
118
|
+
|
119
|
+
for email_id in email_ids:
|
120
|
+
email_body = ""
|
121
|
+
attachments = []
|
122
|
+
status, data = mail.fetch(email_id, '(RFC822)')
|
123
|
+
|
124
|
+
if status == 'OK':
|
125
|
+
raw_email = data[0][1]
|
126
|
+
msg = email.message_from_bytes(raw_email)
|
127
|
+
|
128
|
+
subject = msg['Subject']
|
129
|
+
sender_email_addr = msg['From']
|
130
|
+
cc_email_addr = msg['CC']
|
131
|
+
subject = msg['Subject']
|
132
|
+
|
133
|
+
if msg.is_multipart():
|
134
|
+
for part in msg.walk():
|
135
|
+
content_type = part.get_content_type()
|
136
|
+
if content_type == "text/plain":
|
137
|
+
email_body += part.get_payload(decode=True).decode('utf-8', errors='replace')
|
138
|
+
fileName = self.download_attachment(msg)
|
139
|
+
else:
|
140
|
+
email_body = msg.get_payload(decode=True).decode('utf-8', errors='replace')
|
141
|
+
|
142
|
+
openai_Process_Input = email_body
|
143
|
+
logger.log("\nEmail Subject:::", subject)
|
144
|
+
logger.log("\nEmail body:::", openai_Process_Input )
|
145
|
+
|
146
|
+
openai_api_key = email_config.get('openai_api_key', '')
|
147
|
+
geminiAI_APIKey = email_config.get('gemini_api_key', '')
|
148
|
+
signature = email_config.get('signature', '')
|
149
|
+
localAIURL = email_config.get('local_ai_url', '')
|
150
|
+
|
151
|
+
if len(str(openai_Process_Input)) > 0 :
|
152
|
+
email_cat_data = {
|
153
|
+
"model_type" : Model_Name,
|
154
|
+
"openai_api_key" : openai_api_key,
|
155
|
+
"categories" : categories,
|
156
|
+
"email_body" : email_body,
|
157
|
+
"gemini_api_key" : geminiAI_APIKey,
|
158
|
+
"signature" : signature,
|
159
|
+
"local_ai_url" : localAIURL,
|
160
|
+
}
|
161
|
+
# logger.log(f"\nemail_cat_data ::: {email_cat_data}")
|
162
|
+
email_classification = Email_Classification()
|
163
|
+
emailCategory = email_classification.detect_category(email_cat_data)
|
164
|
+
emailCategory = emailCategory['message']
|
165
|
+
logger.log(f"\nDetected Email category ::: {emailCategory}")
|
166
|
+
|
167
|
+
if emailCategory == 'Others':
|
168
|
+
logger.log(f"Marking email as UNREAD. ")
|
169
|
+
mail.store(email_id, '-FLAGS', '\\Seen')
|
170
|
+
|
171
|
+
mail.create(LABEL)
|
172
|
+
mail.copy(email_id, LABEL)
|
173
|
+
mail.store(email_id, '+FLAGS', '\\Deleted') # Mark for deletion
|
174
|
+
mail.expunge()
|
175
|
+
logger.log(f"Mail removed from inbox and added to '{LABEL}' label.")
|
176
|
+
|
177
|
+
elif emailCategory == "Product Enquiry":
|
178
|
+
|
179
|
+
if Model_Name == "OpenAI":
|
180
|
+
responseMethod, parameters = self.get_JsonArray_values(emailCategory, file_JsonArray)
|
181
|
+
if responseMethod == "Reply_Email_Ai_Assistant" :
|
182
|
+
|
183
|
+
emailreplyassistant = EmailReplyAssistant()
|
184
|
+
openai_Response = emailreplyassistant.Reply_Email_Ai_Assistant(openai_api_key, parameters["Assistant_Id"], openai_Process_Input, subject)
|
185
|
+
|
186
|
+
logger.log(f"Process openai_Response ::: {openai_Response['message']}\n")
|
187
|
+
email_details = {"sender":sender_email_addr, "cc":cc_email_addr, "subject":subject, "body": email_body}
|
188
|
+
|
189
|
+
email_draft = Email_Draft()
|
190
|
+
status, response = email_draft.draft_email(email_config, email_details, openai_Response['message'])
|
191
|
+
logger.log(f"status ::: {status}")
|
192
|
+
else :
|
193
|
+
message = f"Invalid response method received '{responseMethod}' for category : '{emailCategory}'"
|
194
|
+
raise ValueError(message)
|
195
|
+
elif Model_Name == "LocalAI":
|
196
|
+
logger.log("localAI")
|
197
|
+
Detect_Email_category = False
|
198
|
+
LocalAI_Response = emailCategory
|
199
|
+
logger.log(f"Process LocalAI_Response ::: {LocalAI_Response}\n")
|
200
|
+
email_details = {"sender":sender_email_addr, "cc":cc_email_addr, "subject":subject, "body": email_body}
|
201
|
+
|
202
|
+
email_draft = Email_Draft()
|
203
|
+
status, response = email_draft.draft_email(email_config, email_details, LocalAI_Response)
|
204
|
+
logger.log(f"status ::: {status}")
|
205
|
+
elif Model_Name == "GeminiAI":
|
206
|
+
logger.log("GeminiAI")
|
207
|
+
Detect_Email_category = False
|
208
|
+
GeminiAI_Response = emailCategory
|
209
|
+
logger.log(f"Process GeminiAI_Response ::: {GeminiAI_Response}\n")
|
210
|
+
email_details = {"sender":sender_email_addr, "cc":cc_email_addr, "subject":subject, "body": email_body}
|
211
|
+
|
212
|
+
email_draft = Email_Draft()
|
213
|
+
status, response = email_draft.draft_email(email_config, email_details, GeminiAI_Response)
|
214
|
+
logger.log(f"status ::: {status}")
|
215
|
+
else:
|
216
|
+
raise ValueError(f"Invalid Model Name provided : '{Model_Name}'")
|
217
|
+
|
218
|
+
elif emailCategory == "Purchase Order":
|
219
|
+
responseMethod, parameters = self.get_JsonArray_values(emailCategory, file_JsonArray)
|
220
|
+
logger.log(f"responseMethod ::: {responseMethod}")
|
221
|
+
logger.log(f"parameters ::: {parameters}")
|
222
|
+
if responseMethod == "Upload_Document" :
|
223
|
+
|
224
|
+
if len(fileName) != 0 :
|
225
|
+
|
226
|
+
email_upload_document = Email_DocumentUploader()
|
227
|
+
with open(f"temp/{fileName}", "rb") as file:
|
228
|
+
response_status, restAPI_Result = email_upload_document.email_document_upload(file, parameters)
|
229
|
+
logger.log(f"email_upload_document_response ::: {restAPI_Result}")
|
230
|
+
else:
|
231
|
+
|
232
|
+
new_fileName = self.create_file_from_emailBody(email_body, sender_email_addr, parameters)
|
233
|
+
with open(f"temp/{new_fileName}", "rb") as file:
|
234
|
+
response_status, restAPI_Result = email_upload_document.email_document_upload(file, parameters)
|
235
|
+
logger.log(f"email_upload_document_response ::: {restAPI_Result}")
|
236
|
+
|
237
|
+
if response_status == "200" :
|
238
|
+
logger.log(f"Attachment uploaded sucessfully against Document id: '{restAPI_Result}'.")
|
239
|
+
else:
|
240
|
+
logger.log(restAPI_Result)
|
241
|
+
|
242
|
+
else :
|
243
|
+
message = f"Invalid response method received '{responseMethod}' for category : '{emailCategory}'"
|
244
|
+
raise ValueError(message)
|
245
|
+
else:
|
246
|
+
message = f"Detected Email category not found : '{emailCategory}'"
|
247
|
+
raise ValueError(message)
|
248
|
+
time.sleep(10)
|
249
|
+
|
250
|
+
# except Exception as e:
|
251
|
+
# return {"status": "Failed", "message": f"Error reading emails: {str(e)}"}
|
252
|
+
# finally:
|
253
|
+
# try:
|
254
|
+
# mail.close()
|
255
|
+
# mail.logout()
|
256
|
+
# except Exception as close_error:
|
257
|
+
# logger.log(f"Error during mail close/logout: {str(close_error)}")
|
258
|
+
# return {"status": "Failed", "message": f"Error reading emails: {str(close_error)}"}
|
259
|
+
|
95
260
|
def save_attachment(self, part, download_dir):
|
96
261
|
try:
|
97
262
|
filename = part.get_filename()
|
@@ -109,11 +274,8 @@ class Email_Read:
|
|
109
274
|
except Exception as e:
|
110
275
|
return {"success": "Failed", "message": f"Error saving attachment: {str(e)}"}
|
111
276
|
|
112
|
-
def Read_Email(self):
|
277
|
+
def Read_Email(self, data):
|
113
278
|
try:
|
114
|
-
data = request.get_data('jsonData', None)
|
115
|
-
data = json.loads(data[9:])
|
116
|
-
logger.log(f"jsondata:: {data}")
|
117
279
|
|
118
280
|
reciever_email_addr = data.get("reciever_email_addr")
|
119
281
|
receiver_email_pwd = data.get("receiver_email_pwd")
|
@@ -141,5 +303,101 @@ class Email_Read:
|
|
141
303
|
except Exception as e:
|
142
304
|
logger.log(f"Error in Read_Email: {str(e)}")
|
143
305
|
|
306
|
+
def download_attachment(self, msg):
|
307
|
+
filepath = ""
|
308
|
+
filename = ""
|
309
|
+
ATTACHMENT_SAVE_PATH = "temp"
|
310
|
+
|
311
|
+
for part in msg.walk():
|
312
|
+
if part.get_content_maintype() == 'multipart':
|
313
|
+
continue
|
314
|
+
if part.get('Content-Disposition') is None:
|
315
|
+
continue
|
316
|
+
filename = part.get_filename()
|
317
|
+
if filename:
|
318
|
+
if not os.path.exists(ATTACHMENT_SAVE_PATH):
|
319
|
+
os.mkdir(ATTACHMENT_SAVE_PATH)
|
320
|
+
filepath = os.path.join(ATTACHMENT_SAVE_PATH, filename)
|
321
|
+
else:
|
322
|
+
filepath = os.path.join(ATTACHMENT_SAVE_PATH, filename)
|
323
|
+
with open(filepath, 'wb') as f:
|
324
|
+
f.write(part.get_payload(decode=True))
|
325
|
+
logger.log(f"\nAttachment saved: '{filepath}'")
|
326
|
+
else:
|
327
|
+
logger.log("\nNo Attachment found.")
|
328
|
+
return filename
|
329
|
+
|
330
|
+
def read_JSON_File(self, json_fileName):
|
331
|
+
category_list = []
|
332
|
+
categories = ""
|
333
|
+
try:
|
334
|
+
if os.path.exists(json_fileName):
|
335
|
+
with open(json_fileName, "r") as fileObj:
|
336
|
+
file_JsonArray = json.load(fileObj)
|
337
|
+
|
338
|
+
for eachJson in file_JsonArray :
|
339
|
+
for key, value in eachJson.items():
|
340
|
+
if key == "Category" and value:
|
341
|
+
category_list.append(value)
|
342
|
+
# categories = ", ".join(category_list)
|
343
|
+
|
344
|
+
return file_JsonArray, category_list
|
345
|
+
|
346
|
+
else:
|
347
|
+
message = f"{json_fileName} file not found."
|
348
|
+
raise Exception(message)
|
349
|
+
except Exception as e:
|
350
|
+
msg = f"'{json_fileName}' file is empty. Please provide JSON parameters in the filename."
|
351
|
+
trace = traceback.format_exc()
|
352
|
+
logger.log(f"Exception in writeJsonFile: {msg} \n {trace} \n DataType ::: {type(msg)}")
|
353
|
+
raise Exception(msg)
|
354
|
+
|
355
|
+
def get_JsonArray_values(self, category, jsonArray):
|
356
|
+
responseMethod = ""
|
357
|
+
parameters = ""
|
358
|
+
|
359
|
+
for eachJson in jsonArray :
|
360
|
+
for key, value in eachJson.items():
|
361
|
+
if value == category:
|
362
|
+
responseMethod = eachJson["Response_Method"]
|
363
|
+
parameters = eachJson["Parameters"]
|
364
|
+
|
365
|
+
return responseMethod, parameters
|
366
|
+
|
367
|
+
def create_file_from_emailBody(self, text, sender_email_addr, parameters):
|
368
|
+
|
369
|
+
dir = "temp/"
|
370
|
+
if not os.path.exists(dir):
|
371
|
+
os.mkdir(dir)
|
372
|
+
fileName = sender_email_addr[sender_email_addr.find("<")+1:sender_email_addr.find("@")].strip().replace(".","_")
|
373
|
+
logger.log(f"{fileName = }")
|
374
|
+
|
375
|
+
if parameters["FILE_TYPE"] == "pdf":
|
376
|
+
fileName = fileName + ".pdf"
|
377
|
+
filePath = dir + fileName
|
378
|
+
|
379
|
+
pdf = FPDF()
|
380
|
+
pdf.add_page()
|
381
|
+
pdf.set_font("Arial", size=12)
|
382
|
+
pdf.multi_cell(0, 10, text)
|
383
|
+
pdf.output(filePath)
|
384
|
+
logger.log(f"New PDF file created from email body and stored in '{filePath}'")
|
385
|
+
|
386
|
+
elif parameters["FILE_TYPE"] == "txt":
|
387
|
+
fileName = fileName + ".txt"
|
388
|
+
filePath = dir + fileName
|
389
|
+
|
390
|
+
with open(filePath, "w") as file:
|
391
|
+
file.write(text)
|
392
|
+
logger.log(f"New TXT file created from email body and stored in '{filePath}'")
|
393
|
+
else:
|
394
|
+
message = f"Invalid File Type received. "
|
395
|
+
self.send_response(200)
|
396
|
+
self.send_header('Content-type', 'text/html')
|
397
|
+
self.end_headers()
|
398
|
+
self.wfile.write(message.encode('utf-8'))
|
399
|
+
|
400
|
+
return fileName
|
401
|
+
|
144
402
|
|
145
403
|
|
{AIEmailAutomationUtility-0.0.8.dist-info → AIEmailAutomationUtility-0.0.10.dist-info}/METADATA
RENAMED
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: AIEmailAutomationUtility
|
3
|
-
Version: 0.0.
|
4
|
-
Summary:
|
3
|
+
Version: 0.0.10
|
4
|
+
Summary: Create 2 different methods in read_email for different client
|
5
5
|
Author: Proteus Technology PVT. LTD.
|
6
6
|
Author-email: <apps@baseinformation.com>
|
7
7
|
Keywords: python,first package
|
@@ -13,4 +13,4 @@ Classifier: Operating System :: MacOS :: MacOS X
|
|
13
13
|
Classifier: Operating System :: Microsoft :: Windows
|
14
14
|
License-File: LICENCE.txt
|
15
15
|
|
16
|
-
|
16
|
+
Create 2 different methods in read_email for different client
|
@@ -0,0 +1,14 @@
|
|
1
|
+
AIEmailAutomationUtility/EmailReplyAssistant.py,sha256=NQlBPugGdEvNwGFOoaiJNb4JDQB_DYvCy_hWLgAVLns,3938
|
2
|
+
AIEmailAutomationUtility/Email_Classification.py,sha256=eL52Td50zo7V0QTIqjN4Khhg-5HKvf2RUITIcKz5yZ0,9343
|
3
|
+
AIEmailAutomationUtility/Email_DocumentUploader.py,sha256=ImTmMz_JeU6Xynt9kyu7lFv7vqrxzqAtBF-A7014fYc,3055
|
4
|
+
AIEmailAutomationUtility/Email_Draft.py,sha256=BfseewnnlwNl1moodq3kZiUPXDUE9a_nQjuFQsUp3fY,5244
|
5
|
+
AIEmailAutomationUtility/Email_Read.py,sha256=bmRS_jt_v0BxsOWQZcH12VKhcWUbc9dNuw3qkvbGCN4,20516
|
6
|
+
AIEmailAutomationUtility/Email_Upload_Document.py,sha256=3bdkxfDlwoeRp-46KPw2Gs1dqBhEIoA1yE5GCudpdV8,1320
|
7
|
+
AIEmailAutomationUtility/Save_Draft.py,sha256=yzLgFN14I_lXE6qL0I3tKNduvcnWdbsY9i2mKdTtio4,5348
|
8
|
+
AIEmailAutomationUtility/Save_Transaction.py,sha256=Gg1w6hhzHmEFjsuzYvkq-3-EsWReetjLHsYSv5YIGgM,3816
|
9
|
+
AIEmailAutomationUtility/__init__.py,sha256=bB7N-qQD85RdMaXHg_ZU5oPtHtx9zgeG6-ue4rhcfYI,379
|
10
|
+
AIEmailAutomationUtility-0.0.10.dist-info/LICENCE.txt,sha256=2qX9IkEUBx0VJp1Vh9O2dsRwE-IpYId0lXDyn7OVsJ8,1073
|
11
|
+
AIEmailAutomationUtility-0.0.10.dist-info/METADATA,sha256=iG4GkrRFAa5-1rXSU-nXQmnMbSqkIso7QKXPF7j4S78,623
|
12
|
+
AIEmailAutomationUtility-0.0.10.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
13
|
+
AIEmailAutomationUtility-0.0.10.dist-info/top_level.txt,sha256=3jTWrTUblVkaP7mpwY2UBSnrlfot5Ykpfsehyke-Uzw,25
|
14
|
+
AIEmailAutomationUtility-0.0.10.dist-info/RECORD,,
|
@@ -1,14 +0,0 @@
|
|
1
|
-
AIEmailAutomationUtility/EmailReplyAssistant.py,sha256=9X4osN7JDG_2sdyq0Sww5VapxPc_u7Nc9bEbODeE6YU,3852
|
2
|
-
AIEmailAutomationUtility/Email_Classification.py,sha256=NhJwKFGVjLd4BsIFPAWs9qKAUYTxRTYyWd-BvjONXF0,9476
|
3
|
-
AIEmailAutomationUtility/Email_DocumentUploader.py,sha256=0AWcwAx7x4WiZwFBxHwdFpUfE9wjvLGcaxT_95bqRcY,3496
|
4
|
-
AIEmailAutomationUtility/Email_Draft.py,sha256=WUdaSLk4xTwMs1wSOUXE2xiDUehsZQ2wGqvWtXbjeo0,5427
|
5
|
-
AIEmailAutomationUtility/Email_Read.py,sha256=ScuF5zFimkiIUX91-WhgNL18RbhHrcWe7fbbRwDGB7w,6717
|
6
|
-
AIEmailAutomationUtility/Email_Upload_Document.py,sha256=3bdkxfDlwoeRp-46KPw2Gs1dqBhEIoA1yE5GCudpdV8,1320
|
7
|
-
AIEmailAutomationUtility/Save_Draft.py,sha256=yzLgFN14I_lXE6qL0I3tKNduvcnWdbsY9i2mKdTtio4,5348
|
8
|
-
AIEmailAutomationUtility/Save_Transaction.py,sha256=Gg1w6hhzHmEFjsuzYvkq-3-EsWReetjLHsYSv5YIGgM,3816
|
9
|
-
AIEmailAutomationUtility/__init__.py,sha256=bB7N-qQD85RdMaXHg_ZU5oPtHtx9zgeG6-ue4rhcfYI,379
|
10
|
-
AIEmailAutomationUtility-0.0.8.dist-info/LICENCE.txt,sha256=2qX9IkEUBx0VJp1Vh9O2dsRwE-IpYId0lXDyn7OVsJ8,1073
|
11
|
-
AIEmailAutomationUtility-0.0.8.dist-info/METADATA,sha256=UgDXx1muiZQtvoTCwjhKMYgYY2FK_GagTkxhh8gftbs,624
|
12
|
-
AIEmailAutomationUtility-0.0.8.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
13
|
-
AIEmailAutomationUtility-0.0.8.dist-info/top_level.txt,sha256=3jTWrTUblVkaP7mpwY2UBSnrlfot5Ykpfsehyke-Uzw,25
|
14
|
-
AIEmailAutomationUtility-0.0.8.dist-info/RECORD,,
|
{AIEmailAutomationUtility-0.0.8.dist-info → AIEmailAutomationUtility-0.0.10.dist-info}/LICENCE.txt
RENAMED
File without changes
|
{AIEmailAutomationUtility-0.0.8.dist-info → AIEmailAutomationUtility-0.0.10.dist-info}/WHEEL
RENAMED
File without changes
|
{AIEmailAutomationUtility-0.0.8.dist-info → AIEmailAutomationUtility-0.0.10.dist-info}/top_level.txt
RENAMED
File without changes
|