AIEmailAutomationUtility 0.0.23__py3-none-any.whl → 0.0.24__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/Email_Read.py +15 -15
- AIEmailAutomationUtility/Process_Category.py +20 -20
- {AIEmailAutomationUtility-0.0.23.dist-info → AIEmailAutomationUtility-0.0.24.dist-info}/METADATA +1 -1
- {AIEmailAutomationUtility-0.0.23.dist-info → AIEmailAutomationUtility-0.0.24.dist-info}/RECORD +7 -7
- {AIEmailAutomationUtility-0.0.23.dist-info → AIEmailAutomationUtility-0.0.24.dist-info}/LICENCE.txt +0 -0
- {AIEmailAutomationUtility-0.0.23.dist-info → AIEmailAutomationUtility-0.0.24.dist-info}/WHEEL +0 -0
- {AIEmailAutomationUtility-0.0.23.dist-info → AIEmailAutomationUtility-0.0.24.dist-info}/top_level.txt +0 -0
@@ -149,9 +149,9 @@ class Email_Read:
|
|
149
149
|
|
150
150
|
|
151
151
|
# Extract UID
|
152
|
-
|
152
|
+
logger.log(f" the data -----{data[0][0]}")
|
153
153
|
raw_uid = data[0][0].decode() if isinstance(data[0][0], bytes) else data[0][0]
|
154
|
-
|
154
|
+
logger.log(f"the raw uid is ------- {raw_uid}")
|
155
155
|
uid_match = re.search(r'UID (\d+)', raw_uid)
|
156
156
|
uid = uid_match.group(1) if uid_match else "N/A"
|
157
157
|
|
@@ -399,57 +399,57 @@ class Email_Read:
|
|
399
399
|
extracted_info['to'] = msg.get('To')
|
400
400
|
extracted_info['from'] = msg.get('From')
|
401
401
|
extracted_info['cc'] = msg.get('Cc')
|
402
|
-
|
402
|
+
logger.log(f"To: {extracted_info['to']}, From: {extracted_info['from']}, CC: {extracted_info['cc']}")
|
403
403
|
|
404
404
|
# Extracting subject and decoding it if necessary
|
405
405
|
subject = decode_header(msg.get('Subject', ''))[0][0]
|
406
406
|
if decode_header(msg.get('Subject', ''))[0][1]:
|
407
407
|
subject = subject.decode()
|
408
408
|
extracted_info['subject'] = subject
|
409
|
-
|
409
|
+
logger.log(f"Subject: {extracted_info['subject']}")
|
410
410
|
|
411
411
|
# Extracting the body content (text or HTML)
|
412
412
|
text_body = None
|
413
413
|
html_body = None
|
414
414
|
if msg.is_multipart():
|
415
|
-
|
415
|
+
logger.log("Multipart email detected.")
|
416
416
|
for part in msg.walk():
|
417
417
|
content_type = part.get_content_type()
|
418
418
|
content_disposition = str(part.get("Content-Disposition"))
|
419
|
-
|
419
|
+
logger.log(f"Part content type: {content_type}, Content-Disposition: {content_disposition}")
|
420
420
|
|
421
421
|
if content_type == "text/plain" and "attachment" not in content_disposition:
|
422
422
|
text_body = part.get_payload(decode=True).decode()
|
423
|
-
|
423
|
+
logger.log("Text body extracted.")
|
424
424
|
elif content_type == "text/html" and "attachment" not in content_disposition:
|
425
425
|
html_body = part.get_payload(decode=True).decode()
|
426
|
-
|
426
|
+
logger.log("HTML body extracted.")
|
427
427
|
else:
|
428
428
|
if msg.get_content_type() == "text/plain":
|
429
429
|
text_body = msg.get_payload(decode=True).decode()
|
430
|
-
|
430
|
+
logger.log("Text body extracted (non-multipart) .")
|
431
431
|
elif msg.get_content_type() == "text/html":
|
432
432
|
html_body = msg.get_payload(decode=True).decode()
|
433
|
-
|
433
|
+
logger.log("HTML body extracted (non-multipart).")
|
434
434
|
|
435
435
|
extracted_info['email_body'] = text_body if text_body else html_body if html_body else None
|
436
436
|
extracted_info['is_html'] = bool(html_body)
|
437
437
|
|
438
438
|
# Extracting the date and converting it to ISO format
|
439
439
|
date_tuple = email.utils.parsedate_tz(msg.get('Date'))
|
440
|
-
|
440
|
+
logger.log(f"date tuple is {date_tuple}")
|
441
441
|
if date_tuple:
|
442
442
|
local_date = datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
|
443
443
|
extracted_info['date'] = local_date.isoformat()
|
444
|
-
|
444
|
+
logger.log(f"Date: {extracted_info['date']}")
|
445
445
|
else:
|
446
446
|
extracted_info['date'] = None
|
447
|
-
|
447
|
+
logger.log("No date found.")
|
448
448
|
|
449
449
|
# Extracting the unique ID (Message-ID)
|
450
450
|
extracted_info['unique_id'] = msg.get('Message-ID')
|
451
|
-
|
452
|
-
|
451
|
+
logger.log(f"Unique ID: {extracted_info['unique_id']}")
|
452
|
+
logger.log(f"-------------------------------The extracted info is --------------------------{extracted_info}")
|
453
453
|
|
454
454
|
return extracted_info,msg
|
455
455
|
|
@@ -42,25 +42,25 @@ class Process_Category:
|
|
42
42
|
import_file = dataValues.get('import_file')
|
43
43
|
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
logger.log(f"the json datavalues of mailare ------------------------ {mail}")
|
46
|
+
logger.log(f"the json datavalues of email_id are ------------------------ {email_id}")
|
47
|
+
logger.log(f"the category is ------------------------ {category}")
|
48
48
|
|
49
49
|
if category == "Product Enquiry":
|
50
50
|
if Model_Name == "OpenAI":
|
51
51
|
action_taken = "Reply email drafted using Open_AI Model"
|
52
52
|
responseMethod, parameters = self.get_JsonArray_values(category, file_JsonArray)
|
53
|
-
|
53
|
+
logger.log(f"the repsonse method{responseMethod}")
|
54
54
|
if responseMethod == "Reply_Email_Ai_Assistant":
|
55
55
|
emailreplyassistant = EmailReplyAssistant()
|
56
56
|
openai_Response = emailreplyassistant.Reply_Email_Ai_Assistant(openai_api_key, parameters["Assistant_Id"], openai_Process_Input, subject)
|
57
57
|
logger.log(f"Process openai_Response ::: {openai_Response['message']}\n")
|
58
58
|
email_details = {"sender": sender_email_addr, "cc": cc_email_addr, "subject": subject, "body": email_body}
|
59
|
-
|
59
|
+
logger.log(f"response generated")
|
60
60
|
email_draft = Email_Draft()
|
61
61
|
status, response = email_draft.draft_email(email_config, email_details, openai_Response['message'])
|
62
62
|
logger.log(f"status ::: {status}")
|
63
|
-
|
63
|
+
logger.log(f"Email draft called")
|
64
64
|
csv_data_status = status
|
65
65
|
csv_data_response = response
|
66
66
|
else:
|
@@ -144,13 +144,13 @@ class Process_Category:
|
|
144
144
|
# Step 4: Identify customer from email using AI
|
145
145
|
customer_data = self.identify_customer(email_body, subject, Model_Name, openai_api_key, geminiAI_APIKey, localAIURL, parameters["Customer_Assistant_Id"])
|
146
146
|
logger.log(f"Identified customer: {customer_data}")
|
147
|
-
|
147
|
+
logger.log(f'this is the customer data we are getting',customer_data)
|
148
148
|
# Extract customer code once
|
149
149
|
customer_code = customer_data.get("customer_code", "")
|
150
150
|
|
151
151
|
# Step 5: Identify product from email using AI
|
152
152
|
products = self.identify_products(email_body, subject, Model_Name, openai_api_key, geminiAI_APIKey, localAIURL, parameters["Product_Assistant_Id"])
|
153
|
-
|
153
|
+
logger.log(f'this is the products data we are getting',products)
|
154
154
|
|
155
155
|
db_connection = sqlite3.connect('/home/base/git/ai-email-automation/AI_Email/database/fetchprice.db')
|
156
156
|
for product in products:
|
@@ -181,13 +181,13 @@ class Process_Category:
|
|
181
181
|
|
182
182
|
try:
|
183
183
|
raw_price = float(price_cleaned)
|
184
|
-
|
184
|
+
logger.log(f"[0] Base price for item '{item_no}' is {raw_price}")
|
185
185
|
except (TypeError, ValueError):
|
186
|
-
|
186
|
+
logger.log(f"[0] Invalid raw price for item '{item_no}': {price_result[0]}")
|
187
187
|
product["rate"] = None
|
188
188
|
continue
|
189
189
|
else:
|
190
|
-
|
190
|
+
logger.log(f"[0] No base price found for item '{item_no}'. Skipping...")
|
191
191
|
product["rate"] = None
|
192
192
|
continue
|
193
193
|
|
@@ -205,7 +205,7 @@ class Process_Category:
|
|
205
205
|
if result:
|
206
206
|
rate = result[0]
|
207
207
|
found_rate = True
|
208
|
-
|
208
|
+
logger.log(f"[1] Special Rate for item '{item_no}' and customer '{customer_code}' is {rate}")
|
209
209
|
|
210
210
|
# Condition 2: Customer + Manufacturer discount
|
211
211
|
if not found_rate:
|
@@ -222,7 +222,7 @@ class Process_Category:
|
|
222
222
|
rate = raw_price * (1 - discount_percent / 100)
|
223
223
|
rate = round(rate, 2)
|
224
224
|
found_rate = True
|
225
|
-
|
225
|
+
logger.log(f"[2] Discounted rate for '{make}' ({discount_percent}%) on price {raw_price}: {rate}")
|
226
226
|
|
227
227
|
# Condition 3: Past Sales most used make
|
228
228
|
if not found_rate:
|
@@ -244,11 +244,11 @@ class Process_Category:
|
|
244
244
|
rate = raw_price * (1 - past_discount / 100)
|
245
245
|
rate = round(rate, 2)
|
246
246
|
found_rate = True
|
247
|
-
|
247
|
+
logger.log(f"[3] Fallback: Most used make '{most_common_make}' for customer '{customer_code}' got {past_discount}% discount. Rate: {rate}")
|
248
248
|
else:
|
249
|
-
|
249
|
+
logger.log(f"[3] Fallback: Invalid price for item '{item_no}'")
|
250
250
|
else:
|
251
|
-
|
251
|
+
logger.log(f"[3] No past sales data for item '{item_no}' and customer '{customer_code}'")
|
252
252
|
|
253
253
|
# Condition 4: Manufacturer General Discount
|
254
254
|
if not found_rate:
|
@@ -265,9 +265,9 @@ class Process_Category:
|
|
265
265
|
rate = raw_price * (1 - general_discount_percent / 100)
|
266
266
|
rate = round(rate, 2)
|
267
267
|
found_rate = True
|
268
|
-
|
268
|
+
logger.log(f"[4] General Discount for '{make}' ({general_discount_percent}%) on price {raw_price}: {rate}")
|
269
269
|
else:
|
270
|
-
|
270
|
+
logger.log(f"[4] No applicable discount found for item '{item_no}'")
|
271
271
|
|
272
272
|
product["rate"] = rate
|
273
273
|
cursor.close()
|
@@ -312,7 +312,7 @@ class Process_Category:
|
|
312
312
|
csv_data_response = f""
|
313
313
|
|
314
314
|
logger.log(f"Marking email as UNREAD. ")
|
315
|
-
|
315
|
+
logger.log(f"email_id: {email_id}, type: {type(email_id)}")
|
316
316
|
mail.store(email_id, '-FLAGS', '\\Seen')
|
317
317
|
mail.create(LABEL)
|
318
318
|
mail.copy(email_id, LABEL)
|
@@ -321,7 +321,7 @@ class Process_Category:
|
|
321
321
|
logger.log(f"Mail removed from inbox and added to '{LABEL}' label.")
|
322
322
|
|
323
323
|
filename = f"{uid}"
|
324
|
-
|
324
|
+
logger.log(f"the file name is ---------------- {filename}")
|
325
325
|
self.store_email_details_to_csv(
|
326
326
|
email_id=uid,
|
327
327
|
to_email=parseaddr(to_email_addr)[1],
|
{AIEmailAutomationUtility-0.0.23.dist-info → AIEmailAutomationUtility-0.0.24.dist-info}/RECORD
RENAMED
@@ -2,14 +2,14 @@ AIEmailAutomationUtility/EmailReplyAssistant.py,sha256=oRobM6C1AwiRA3lQ2Sh51m-Fa
|
|
2
2
|
AIEmailAutomationUtility/Email_Classification.py,sha256=QvNNj8PSsfWoByBeHcaXH9mRET2TQuYGKJZGg385dzs,9412
|
3
3
|
AIEmailAutomationUtility/Email_DocumentUploader.py,sha256=P5P36rgDzALZEpO09aJWM0HEA-6vl48HNwz7GO6SbXc,3159
|
4
4
|
AIEmailAutomationUtility/Email_Draft.py,sha256=DcyBeDaE8CReKHnHxLiz-o2tDxuUgwy91c4k0qhQbVw,7749
|
5
|
-
AIEmailAutomationUtility/Email_Read.py,sha256=
|
5
|
+
AIEmailAutomationUtility/Email_Read.py,sha256=UJDHdsr5RN_GG5OsOvUKbKziaw0a-kR3TT0iUv0oRmI,27795
|
6
6
|
AIEmailAutomationUtility/Email_Upload_Document.py,sha256=3bdkxfDlwoeRp-46KPw2Gs1dqBhEIoA1yE5GCudpdV8,1320
|
7
|
-
AIEmailAutomationUtility/Process_Category.py,sha256=
|
7
|
+
AIEmailAutomationUtility/Process_Category.py,sha256=z_OwAAz28G2oIFEW9Kye6tAWa4OFYOaijPbCD8azVYk,39308
|
8
8
|
AIEmailAutomationUtility/Save_Draft.py,sha256=yzLgFN14I_lXE6qL0I3tKNduvcnWdbsY9i2mKdTtio4,5348
|
9
9
|
AIEmailAutomationUtility/Save_Transaction.py,sha256=Gg1w6hhzHmEFjsuzYvkq-3-EsWReetjLHsYSv5YIGgM,3816
|
10
10
|
AIEmailAutomationUtility/__init__.py,sha256=Jad3IdPRsVMeLqEEh-FbCrc1lE2tzJO2DTG5Hgmxh5g,391
|
11
|
-
AIEmailAutomationUtility-0.0.
|
12
|
-
AIEmailAutomationUtility-0.0.
|
13
|
-
AIEmailAutomationUtility-0.0.
|
14
|
-
AIEmailAutomationUtility-0.0.
|
15
|
-
AIEmailAutomationUtility-0.0.
|
11
|
+
AIEmailAutomationUtility-0.0.24.dist-info/LICENCE.txt,sha256=2qX9IkEUBx0VJp1Vh9O2dsRwE-IpYId0lXDyn7OVsJ8,1073
|
12
|
+
AIEmailAutomationUtility-0.0.24.dist-info/METADATA,sha256=TFVVAleDPTxYmpwEOIhT-pEAhoUYhFRxVDNKYC3bMWs,551
|
13
|
+
AIEmailAutomationUtility-0.0.24.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
14
|
+
AIEmailAutomationUtility-0.0.24.dist-info/top_level.txt,sha256=3jTWrTUblVkaP7mpwY2UBSnrlfot5Ykpfsehyke-Uzw,25
|
15
|
+
AIEmailAutomationUtility-0.0.24.dist-info/RECORD,,
|
{AIEmailAutomationUtility-0.0.23.dist-info → AIEmailAutomationUtility-0.0.24.dist-info}/LICENCE.txt
RENAMED
File without changes
|
{AIEmailAutomationUtility-0.0.23.dist-info → AIEmailAutomationUtility-0.0.24.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|