AIEmailAutomationUtility 0.0.19__py3-none-any.whl → 0.0.20__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_Draft.py +3 -3
- AIEmailAutomationUtility/Email_Read.py +13 -11
- AIEmailAutomationUtility/Save_Draft.py +137 -0
- {AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.dist-info}/METADATA +3 -3
- {AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.dist-info}/RECORD +8 -7
- {AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.dist-info}/LICENCE.txt +0 -0
- {AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.dist-info}/WHEEL +0 -0
- {AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.dist-info}/top_level.txt +0 -0
@@ -64,9 +64,9 @@ class Email_Draft:
|
|
64
64
|
email_body = email_details['body']
|
65
65
|
|
66
66
|
# Replace new lines with <br> for proper HTML formatting
|
67
|
-
body_html = body.replace("\n", "<br>")
|
68
|
-
signature_html = signature.replace("\n", "<br>")
|
69
|
-
email_body_html = email_body.replace("\n", "<br>")
|
67
|
+
body_html = body.replace("\n", "<br>").replace("\n\n", "<br>")
|
68
|
+
signature_html = signature.replace("\n", "<br>").replace("\n\n", "<br>")
|
69
|
+
email_body_html = email_body.replace("\n", "<br>").replace("\n\n", "<br>")
|
70
70
|
|
71
71
|
# Create HTML content
|
72
72
|
html_content = (
|
@@ -519,25 +519,27 @@ class Email_Read:
|
|
519
519
|
|
520
520
|
elif model_type == "GeminiAI":
|
521
521
|
prompt = f"""
|
522
|
-
|
522
|
+
Create an HTML product information email draft with the following details:
|
523
523
|
|
524
|
-
Customer: {customer.get('customer_name', '')}
|
525
|
-
Customer Code: {customer.get('customer_code', '')}
|
524
|
+
Customer Name: {customer.get('customer_name', '')}
|
525
|
+
Customer Code: {customer.get('customer_code', '')}
|
526
526
|
|
527
|
-
|
528
|
-
product_table
|
529
|
-
|
527
|
+
Product Information:
|
528
|
+
{product_table}
|
529
|
+
Note: Include price column with a value of "-" if price is not available.
|
530
530
|
|
531
|
-
|
531
|
+
Email Subject Reference: {subject}
|
532
|
+
|
533
|
+
Please format the response as a valid JSON string with these fields:
|
532
534
|
{{
|
533
535
|
"email_body": {{
|
534
|
-
"body": "
|
535
|
-
"
|
536
|
+
"body": "Professional email content that summarizes the product information without being identical to the input data. Do not include signature here.",
|
537
|
+
"table_": "HTML table with SR. No. column and product details",
|
536
538
|
"signature": "{signature}"
|
537
539
|
}}
|
538
540
|
}}
|
539
541
|
|
540
|
-
|
542
|
+
Ensure the JSON is properly formatted with escaped newlines (\\n) and no trailing commas. Return only the valid JSON string without additional explanations or instructions.
|
541
543
|
"""
|
542
544
|
logger.log(f"Quotation draft ::: {prompt}")
|
543
545
|
ai_result = self.create_quotation_draft_GeminiAI(gemini_api_key, email_body, prompt)
|
@@ -695,7 +697,7 @@ class Email_Read:
|
|
695
697
|
logger.log(f"response::: {final_result}")
|
696
698
|
if final_result:
|
697
699
|
try:
|
698
|
-
final_result = final_result.replace(
|
700
|
+
final_result = final_result.replace('```', '').replace('json', '')
|
699
701
|
if final_result.startswith("{{") and final_result.endswith("}}"):
|
700
702
|
final_result = final_result[1:-1]
|
701
703
|
except json.JSONDecodeError:
|
@@ -0,0 +1,137 @@
|
|
1
|
+
import cx_Oracle
|
2
|
+
from DatabaseConnectionUtility import Oracle
|
3
|
+
from DatabaseConnectionUtility import Dremio
|
4
|
+
from DatabaseConnectionUtility import InMemory
|
5
|
+
from DatabaseConnectionUtility import Oracle
|
6
|
+
from DatabaseConnectionUtility import MySql
|
7
|
+
from DatabaseConnectionUtility import MSSQLServer
|
8
|
+
from DatabaseConnectionUtility import SAPHANA
|
9
|
+
from DatabaseConnectionUtility import Postgress
|
10
|
+
import loggerutility as logger
|
11
|
+
import commonutility as common
|
12
|
+
import traceback
|
13
|
+
import imaplib
|
14
|
+
from email.message import Message
|
15
|
+
import datetime
|
16
|
+
import time
|
17
|
+
|
18
|
+
class Save_Draft:
|
19
|
+
|
20
|
+
connection = None
|
21
|
+
|
22
|
+
def get_database_connection(self, dbDetails):
|
23
|
+
if dbDetails['DB_VENDORE'] != None:
|
24
|
+
klass = globals()[dbDetails['DB_VENDORE']]
|
25
|
+
dbObject = klass()
|
26
|
+
connection_obj = dbObject.getConnection(dbDetails)
|
27
|
+
return connection_obj
|
28
|
+
|
29
|
+
def commit(self):
|
30
|
+
if self.connection:
|
31
|
+
try:
|
32
|
+
self.connection.commit()
|
33
|
+
print("Transaction committed successfully.")
|
34
|
+
except cx_Oracle.Error as error:
|
35
|
+
print(f"Error during commit: {error}")
|
36
|
+
else:
|
37
|
+
print("No active connection to commit.")
|
38
|
+
|
39
|
+
def rollback(self):
|
40
|
+
if self.connection:
|
41
|
+
try:
|
42
|
+
self.connection.rollback()
|
43
|
+
print("Transaction rolled back successfully.")
|
44
|
+
except cx_Oracle.Error as error:
|
45
|
+
print(f"Error during rollback: {error}")
|
46
|
+
else:
|
47
|
+
print("No active connection to rollback.")
|
48
|
+
|
49
|
+
def close_connection(self):
|
50
|
+
if self.connection:
|
51
|
+
try:
|
52
|
+
self.connection.close()
|
53
|
+
print("Connection closed successfully.")
|
54
|
+
except cx_Oracle.Error as error:
|
55
|
+
print(f"Error during close: {error}")
|
56
|
+
else:
|
57
|
+
print("No active connection to close.")
|
58
|
+
|
59
|
+
def draft_Email(self, reciever_email_addr, receiver_email_pwd, host_name, sender_email_addr, cc_email_addr, subject, email_body):
|
60
|
+
try:
|
61
|
+
mail_details = ""
|
62
|
+
with imaplib.IMAP4_SSL(host=host_name, port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
|
63
|
+
resp_code, response = imap_ssl.login(reciever_email_addr, receiver_email_pwd)
|
64
|
+
message = Message()
|
65
|
+
message["From"] = reciever_email_addr
|
66
|
+
message["To"] = sender_email_addr
|
67
|
+
message["CC"] = cc_email_addr
|
68
|
+
|
69
|
+
if subject.startswith("Re:"):
|
70
|
+
message["Subject"] = f"{subject} "
|
71
|
+
else:
|
72
|
+
message["Subject"] = f"Re: {subject} "
|
73
|
+
|
74
|
+
mail_details = f'{datetime.datetime.now().strftime("On %a, %b %d, %Y at %I:%M %p")} {sender_email_addr} wrote:'
|
75
|
+
message.set_payload(f"{email_body}\n\n{mail_details}")
|
76
|
+
utf8_message = str(message).encode("utf-8")
|
77
|
+
|
78
|
+
imap_ssl.append("[Gmail]/Drafts", '', imaplib.Time2Internaldate(time.time()), utf8_message)
|
79
|
+
print("Draft Mail saved successfully.")
|
80
|
+
|
81
|
+
return "Success"
|
82
|
+
|
83
|
+
except Exception as error:
|
84
|
+
print(f"Error ::: {error}")
|
85
|
+
return "Fail"
|
86
|
+
|
87
|
+
def check_drafts(self, dbDetails, email_info):
|
88
|
+
|
89
|
+
while True:
|
90
|
+
|
91
|
+
self.connection = self.get_database_connection(dbDetails)
|
92
|
+
|
93
|
+
if self.connection:
|
94
|
+
try:
|
95
|
+
|
96
|
+
cursor = self.connection.cursor()
|
97
|
+
queryy = f"SELECT * FROM DRAFT_EMAIL_INFO WHERE STATUS = 'Pending'"
|
98
|
+
cursor.execute(queryy)
|
99
|
+
pending_records = cursor.fetchall()
|
100
|
+
cursor.close()
|
101
|
+
|
102
|
+
for data in pending_records:
|
103
|
+
# print(f"data ::: {data}")
|
104
|
+
response = self.draft_Email(email_info['email'], email_info['password'], email_info['host'], data[0], data[1], data[2], data[3].read())
|
105
|
+
if response == 'Success':
|
106
|
+
cursor = self.connection.cursor()
|
107
|
+
update_query = """
|
108
|
+
UPDATE DRAFT_EMAIL_INFO SET
|
109
|
+
STATUS = :status
|
110
|
+
WHERE TRIM(TO_EMAIL) = TRIM(:to_email)
|
111
|
+
AND TRIM(SUBJECT) = TRIM(:subject)
|
112
|
+
"""
|
113
|
+
values = {
|
114
|
+
'status': 'Done',
|
115
|
+
'to_email': data[0],
|
116
|
+
'subject': data[2]
|
117
|
+
}
|
118
|
+
cursor.execute(update_query, values)
|
119
|
+
print(f"Successfully updated row.")
|
120
|
+
cursor.close()
|
121
|
+
|
122
|
+
self.commit()
|
123
|
+
|
124
|
+
except Exception as e:
|
125
|
+
print(f"Rollback due to error: {e}")
|
126
|
+
|
127
|
+
finally:
|
128
|
+
print('Closed connection successfully.')
|
129
|
+
self.close_connection()
|
130
|
+
else:
|
131
|
+
print(f'\n In getInvokeIntent exception stacktrace : ', "1")
|
132
|
+
descr = str("Connection fail")
|
133
|
+
print(f'\n Exception ::: {descr}', "0")
|
134
|
+
|
135
|
+
time.sleep(10)
|
136
|
+
|
137
|
+
|
{AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.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.20
|
4
|
+
Summary: Change the Gemini AI prompt to generate quotation draft
|
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
|
+
Change the Gemini AI prompt to generate quotation draft
|
{AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.dist-info}/RECORD
RENAMED
@@ -1,13 +1,14 @@
|
|
1
1
|
AIEmailAutomationUtility/EmailReplyAssistant.py,sha256=oRobM6C1AwiRA3lQ2Sh51m-FaH2PpbUEidbkOG7O9Ww,6339
|
2
2
|
AIEmailAutomationUtility/Email_Classification.py,sha256=anqJ0_Iyr4xRSSJBI3KkavELSoz_EENdbofr07NjTB0,9416
|
3
3
|
AIEmailAutomationUtility/Email_DocumentUploader.py,sha256=P5P36rgDzALZEpO09aJWM0HEA-6vl48HNwz7GO6SbXc,3159
|
4
|
-
AIEmailAutomationUtility/Email_Draft.py,sha256=
|
5
|
-
AIEmailAutomationUtility/Email_Read.py,sha256=
|
4
|
+
AIEmailAutomationUtility/Email_Draft.py,sha256=DcyBeDaE8CReKHnHxLiz-o2tDxuUgwy91c4k0qhQbVw,7749
|
5
|
+
AIEmailAutomationUtility/Email_Read.py,sha256=mVuSwmzPUjO4IRkSIOAPPDcNhKGvwkIwXJfBC8T9QQU,45571
|
6
6
|
AIEmailAutomationUtility/Email_Upload_Document.py,sha256=3bdkxfDlwoeRp-46KPw2Gs1dqBhEIoA1yE5GCudpdV8,1320
|
7
|
+
AIEmailAutomationUtility/Save_Draft.py,sha256=yzLgFN14I_lXE6qL0I3tKNduvcnWdbsY9i2mKdTtio4,5348
|
7
8
|
AIEmailAutomationUtility/Save_Transaction.py,sha256=Gg1w6hhzHmEFjsuzYvkq-3-EsWReetjLHsYSv5YIGgM,3816
|
8
9
|
AIEmailAutomationUtility/__init__.py,sha256=UzDkFSvLwwc0NLnvMiM0jNV5pIWUlM9p2zvpcrh9rkM,344
|
9
|
-
AIEmailAutomationUtility-0.0.
|
10
|
-
AIEmailAutomationUtility-0.0.
|
11
|
-
AIEmailAutomationUtility-0.0.
|
12
|
-
AIEmailAutomationUtility-0.0.
|
13
|
-
AIEmailAutomationUtility-0.0.
|
10
|
+
AIEmailAutomationUtility-0.0.20.dist-info/LICENCE.txt,sha256=2qX9IkEUBx0VJp1Vh9O2dsRwE-IpYId0lXDyn7OVsJ8,1073
|
11
|
+
AIEmailAutomationUtility-0.0.20.dist-info/METADATA,sha256=NbzpD-Fb235OBUjnM5uRYH5zWR3c5IzwqczD4Bj8mxM,611
|
12
|
+
AIEmailAutomationUtility-0.0.20.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
13
|
+
AIEmailAutomationUtility-0.0.20.dist-info/top_level.txt,sha256=3jTWrTUblVkaP7mpwY2UBSnrlfot5Ykpfsehyke-Uzw,25
|
14
|
+
AIEmailAutomationUtility-0.0.20.dist-info/RECORD,,
|
{AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.dist-info}/LICENCE.txt
RENAMED
File without changes
|
{AIEmailAutomationUtility-0.0.19.dist-info → AIEmailAutomationUtility-0.0.20.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|