Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -9,6 +9,7 @@ from dotenv import load_dotenv
|
|
9 |
from fpdf import FPDF
|
10 |
import shutil
|
11 |
import html
|
|
|
12 |
|
13 |
# Load environment variables
|
14 |
load_dotenv()
|
@@ -61,9 +62,9 @@ def clean_text_for_pdf(text):
|
|
61 |
def save_report_as_pdf(role, supervisor_name, project_id, checklist, suggestions):
|
62 |
now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
63 |
filename = f"report_{supervisor_name}_{project_id}_{now}.pdf"
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
pdf = FPDF()
|
68 |
pdf.add_page()
|
69 |
pdf.set_font("Arial", 'B', 14)
|
@@ -84,13 +85,13 @@ def save_report_as_pdf(role, supervisor_name, project_id, checklist, suggestions
|
|
84 |
pdf.set_font("Arial", size=12)
|
85 |
for line in suggestions.split("\n"):
|
86 |
pdf.multi_cell(0, 10, clean_text_for_pdf(line))
|
87 |
-
|
|
|
|
|
88 |
|
89 |
-
|
90 |
-
shutil.copy(file_path, temp_pdf_path)
|
91 |
-
return temp_pdf_path,filename
|
92 |
|
93 |
-
def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id,
|
94 |
try:
|
95 |
sf = Salesforce(
|
96 |
username=os.getenv('SF_USERNAME'),
|
@@ -99,9 +100,8 @@ def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_pa
|
|
99 |
domain=os.getenv('SF_DOMAIN', 'login')
|
100 |
)
|
101 |
|
102 |
-
#
|
103 |
-
|
104 |
-
encoded = base64.b64encode(f.read()).decode()
|
105 |
|
106 |
# Create ContentVersion record to upload the PDF to Salesforce
|
107 |
content = sf.ContentVersion.create({
|
@@ -110,40 +110,24 @@ def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_pa
|
|
110 |
'VersionData': encoded
|
111 |
})
|
112 |
|
113 |
-
# Get
|
114 |
content_id = content['id']
|
115 |
download_url = f"https://{sf.sf_instance}/sfc/servlet.shepherd/version/download/{content_id}"
|
116 |
|
117 |
-
# Query
|
118 |
-
|
119 |
-
SELECT Id FROM Supervisor__c
|
120 |
-
WHERE Name = '{supervisor_name}'
|
121 |
-
LIMIT 1
|
122 |
""")
|
|
|
123 |
|
124 |
-
# Ensure that the Supervisor is found
|
125 |
-
if query['totalSize'] == 0:
|
126 |
-
print("⚠️ Supervisor not found!")
|
127 |
-
return ""
|
128 |
-
|
129 |
-
supervisor_id = query['records'][0]['Id']
|
130 |
-
|
131 |
-
# Query to get the Project ID in Salesforce
|
132 |
project_query = sf.query(f"""
|
133 |
-
SELECT Id FROM Project__c WHERE Name = '{project_id}'
|
134 |
-
LIMIT 1
|
135 |
""")
|
136 |
-
|
137 |
-
# Ensure that the Project ID is found
|
138 |
-
if project_query['totalSize'] == 0:
|
139 |
-
print(f"⚠️ Project '{project_id}' not found in Salesforce!")
|
140 |
-
return ""
|
141 |
-
|
142 |
project_id_sf = project_query['records'][0]['Id']
|
143 |
|
144 |
-
# Create
|
145 |
sf.Supervisor_AI_Coaching__c.create({
|
146 |
-
'Project_ID__c': project_id_sf,
|
147 |
'Supervisor_ID__c': supervisor_id,
|
148 |
'Daily_Checklist__c': checklist,
|
149 |
'Suggested_Tips__c': suggestions,
|
@@ -151,7 +135,6 @@ def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_pa
|
|
151 |
})
|
152 |
|
153 |
return download_url
|
154 |
-
|
155 |
except Exception as e:
|
156 |
print(f"⚠️ Upload error: {e}")
|
157 |
return ""
|
@@ -170,58 +153,21 @@ def get_roles_from_salesforce():
|
|
170 |
print(f"⚠️ Error fetching roles: {e}")
|
171 |
return []
|
172 |
|
173 |
-
def get_supervisor_name_by_role(role):
|
174 |
-
try:
|
175 |
-
sf = Salesforce(
|
176 |
-
username=os.getenv('SF_USERNAME'),
|
177 |
-
password=os.getenv('SF_PASSWORD'),
|
178 |
-
security_token=os.getenv('SF_SECURITY_TOKEN'),
|
179 |
-
domain=os.getenv('SF_DOMAIN', 'login')
|
180 |
-
)
|
181 |
-
result = sf.query(f"SELECT Name FROM Supervisor__c WHERE Role__c = '{role}'")
|
182 |
-
return [record['Name'] for record in result['records']]
|
183 |
-
except Exception as e:
|
184 |
-
print(f"⚠️ Error fetching names: {e}")
|
185 |
-
return []
|
186 |
-
|
187 |
-
def get_projects_for_supervisor(supervisor_name):
|
188 |
-
try:
|
189 |
-
sf = Salesforce(
|
190 |
-
username=os.getenv('SF_USERNAME'),
|
191 |
-
password=os.getenv('SF_PASSWORD'),
|
192 |
-
security_token=os.getenv('SF_SECURITY_TOKEN'),
|
193 |
-
domain=os.getenv('SF_DOMAIN', 'login')
|
194 |
-
)
|
195 |
-
result = sf.query(f"SELECT Id FROM Supervisor__c WHERE Name = '{supervisor_name}' LIMIT 1")
|
196 |
-
if result['totalSize'] == 0:
|
197 |
-
return ""
|
198 |
-
supervisor_id = result['records'][0]['Id']
|
199 |
-
project_result = sf.query(f"SELECT Name FROM Project__c WHERE Supervisor_ID__c = '{supervisor_id}' LIMIT 1")
|
200 |
-
return project_result['records'][0]['Name'] if project_result['totalSize'] > 0 else ""
|
201 |
-
except Exception as e:
|
202 |
-
print(f"⚠️ Error fetching project: {e}")
|
203 |
-
return ""
|
204 |
-
|
205 |
-
def generate_salesforce_dashboard_url(supervisor_name, project_id):
|
206 |
-
return f"https://aicoachforsitesupervisors-dev-ed--c.develop.vf.force.com/apex/DashboardPage?supervisorName={supervisor_name}&projectId={project_id}"
|
207 |
-
|
208 |
-
def open_dashboard(role, supervisor_name, project_id):
|
209 |
-
url = generate_salesforce_dashboard_url(supervisor_name, project_id)
|
210 |
-
return f'<a href="{url}" target="_blank">Open Salesforce Dashboard</a>'
|
211 |
-
|
212 |
def generate_outputs(role, supervisor_name, project_id, milestones, reflection):
|
213 |
if not all([role, supervisor_name, project_id, milestones, reflection]):
|
214 |
return "❗ Please fill all fields.", "", None, ""
|
215 |
|
216 |
-
|
|
|
217 |
inputs = tokenizer(prompt, return_tensors="pt", padding=True, truncation=True, max_length=512)
|
|
|
218 |
try:
|
219 |
with torch.no_grad():
|
220 |
outputs = model.generate(
|
221 |
inputs['input_ids'],
|
222 |
-
max_new_tokens=
|
223 |
no_repeat_ngram_size=2,
|
224 |
-
do_sample=
|
225 |
top_p=0.9,
|
226 |
temperature=0.7,
|
227 |
pad_token_id=tokenizer.pad_token_id
|
@@ -244,13 +190,13 @@ def generate_outputs(role, supervisor_name, project_id, milestones, reflection):
|
|
244 |
if not suggestions.strip():
|
245 |
suggestions = "- Monitor team coordination\n- Review safety protocols with the team"
|
246 |
|
247 |
-
|
248 |
-
pdf_url = upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id,
|
249 |
|
250 |
if pdf_url:
|
251 |
suggestions += f"\n\n🔗 [Download PDF Report]({pdf_url})"
|
252 |
|
253 |
-
return checklist, suggestions,
|
254 |
|
255 |
def create_interface():
|
256 |
roles = get_roles_from_salesforce()
|
@@ -281,8 +227,8 @@ def create_interface():
|
|
281 |
supervisor_name.change(fn=get_projects_for_supervisor, inputs=supervisor_name, outputs=project_id)
|
282 |
|
283 |
def handle_generate(role, supervisor_name, project_id, milestones, reflection):
|
284 |
-
checklist, suggestions,
|
285 |
-
return checklist, suggestions,
|
286 |
|
287 |
generate.click(fn=handle_generate,
|
288 |
inputs=[role, supervisor_name, project_id, milestones, reflection],
|
|
|
9 |
from fpdf import FPDF
|
10 |
import shutil
|
11 |
import html
|
12 |
+
from io import BytesIO
|
13 |
|
14 |
# Load environment variables
|
15 |
load_dotenv()
|
|
|
62 |
def save_report_as_pdf(role, supervisor_name, project_id, checklist, suggestions):
|
63 |
now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
64 |
filename = f"report_{supervisor_name}_{project_id}_{now}.pdf"
|
65 |
+
|
66 |
+
# In-memory PDF creation
|
67 |
+
pdf_buffer = BytesIO()
|
68 |
pdf = FPDF()
|
69 |
pdf.add_page()
|
70 |
pdf.set_font("Arial", 'B', 14)
|
|
|
85 |
pdf.set_font("Arial", size=12)
|
86 |
for line in suggestions.split("\n"):
|
87 |
pdf.multi_cell(0, 10, clean_text_for_pdf(line))
|
88 |
+
|
89 |
+
pdf.output(pdf_buffer)
|
90 |
+
pdf_buffer.seek(0)
|
91 |
|
92 |
+
return pdf_buffer, filename
|
|
|
|
|
93 |
|
94 |
+
def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_buffer, pdf_name, checklist, suggestions):
|
95 |
try:
|
96 |
sf = Salesforce(
|
97 |
username=os.getenv('SF_USERNAME'),
|
|
|
100 |
domain=os.getenv('SF_DOMAIN', 'login')
|
101 |
)
|
102 |
|
103 |
+
# Encode PDF to base64
|
104 |
+
encoded = base64.b64encode(pdf_buffer.read()).decode()
|
|
|
105 |
|
106 |
# Create ContentVersion record to upload the PDF to Salesforce
|
107 |
content = sf.ContentVersion.create({
|
|
|
110 |
'VersionData': encoded
|
111 |
})
|
112 |
|
113 |
+
# Get ContentDocumentId
|
114 |
content_id = content['id']
|
115 |
download_url = f"https://{sf.sf_instance}/sfc/servlet.shepherd/version/download/{content_id}"
|
116 |
|
117 |
+
# Query for supervisor and project
|
118 |
+
supervisor_query = sf.query(f"""
|
119 |
+
SELECT Id FROM Supervisor__c WHERE Name = '{supervisor_name}' LIMIT 1
|
|
|
|
|
120 |
""")
|
121 |
+
supervisor_id = supervisor_query['records'][0]['Id']
|
122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
project_query = sf.query(f"""
|
124 |
+
SELECT Id FROM Project__c WHERE Name = '{project_id}' LIMIT 1
|
|
|
125 |
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
project_id_sf = project_query['records'][0]['Id']
|
127 |
|
128 |
+
# Create record in Supervisor_AI_Coaching__c object
|
129 |
sf.Supervisor_AI_Coaching__c.create({
|
130 |
+
'Project_ID__c': project_id_sf,
|
131 |
'Supervisor_ID__c': supervisor_id,
|
132 |
'Daily_Checklist__c': checklist,
|
133 |
'Suggested_Tips__c': suggestions,
|
|
|
135 |
})
|
136 |
|
137 |
return download_url
|
|
|
138 |
except Exception as e:
|
139 |
print(f"⚠️ Upload error: {e}")
|
140 |
return ""
|
|
|
153 |
print(f"⚠️ Error fetching roles: {e}")
|
154 |
return []
|
155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
def generate_outputs(role, supervisor_name, project_id, milestones, reflection):
|
157 |
if not all([role, supervisor_name, project_id, milestones, reflection]):
|
158 |
return "❗ Please fill all fields.", "", None, ""
|
159 |
|
160 |
+
# Shortened input for faster processing
|
161 |
+
prompt = PROMPT_TEMPLATE.format(role=role, project_id=project_id, milestones=milestones[:256], reflection=reflection[:256])
|
162 |
inputs = tokenizer(prompt, return_tensors="pt", padding=True, truncation=True, max_length=512)
|
163 |
+
|
164 |
try:
|
165 |
with torch.no_grad():
|
166 |
outputs = model.generate(
|
167 |
inputs['input_ids'],
|
168 |
+
max_new_tokens=100,
|
169 |
no_repeat_ngram_size=2,
|
170 |
+
do_sample=False,
|
171 |
top_p=0.9,
|
172 |
temperature=0.7,
|
173 |
pad_token_id=tokenizer.pad_token_id
|
|
|
190 |
if not suggestions.strip():
|
191 |
suggestions = "- Monitor team coordination\n- Review safety protocols with the team"
|
192 |
|
193 |
+
pdf_buffer, pdf_name = save_report_as_pdf(role, supervisor_name, project_id, checklist, suggestions)
|
194 |
+
pdf_url = upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_buffer, pdf_name, checklist, suggestions)
|
195 |
|
196 |
if pdf_url:
|
197 |
suggestions += f"\n\n🔗 [Download PDF Report]({pdf_url})"
|
198 |
|
199 |
+
return checklist, suggestions, pdf_buffer, pdf_name
|
200 |
|
201 |
def create_interface():
|
202 |
roles = get_roles_from_salesforce()
|
|
|
227 |
supervisor_name.change(fn=get_projects_for_supervisor, inputs=supervisor_name, outputs=project_id)
|
228 |
|
229 |
def handle_generate(role, supervisor_name, project_id, milestones, reflection):
|
230 |
+
checklist, suggestions, pdf_buffer, pdf_name = generate_outputs(role, supervisor_name, project_id, milestones, reflection)
|
231 |
+
return checklist, suggestions, pdf_buffer, pdf_name
|
232 |
|
233 |
generate.click(fn=handle_generate,
|
234 |
inputs=[role, supervisor_name, project_id, milestones, reflection],
|