Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -9,7 +9,6 @@ from dotenv import load_dotenv
|
|
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,9 +61,9 @@ def clean_text_for_pdf(text):
|
|
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 |
-
|
67 |
-
|
68 |
pdf = FPDF()
|
69 |
pdf.add_page()
|
70 |
pdf.set_font("Arial", 'B', 14)
|
@@ -85,13 +84,13 @@ def save_report_as_pdf(role, supervisor_name, project_id, checklist, suggestions
|
|
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 |
-
|
|
|
|
|
93 |
|
94 |
-
def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id,
|
95 |
try:
|
96 |
sf = Salesforce(
|
97 |
username=os.getenv('SF_USERNAME'),
|
@@ -100,8 +99,9 @@ def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_bu
|
|
100 |
domain=os.getenv('SF_DOMAIN', 'login')
|
101 |
)
|
102 |
|
103 |
-
#
|
104 |
-
|
|
|
105 |
|
106 |
# Create ContentVersion record to upload the PDF to Salesforce
|
107 |
content = sf.ContentVersion.create({
|
@@ -110,24 +110,40 @@ def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_bu
|
|
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
|
118 |
-
|
119 |
-
SELECT Id FROM Supervisor__c
|
|
|
|
|
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}'
|
|
|
125 |
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
project_id_sf = project_query['records'][0]['Id']
|
127 |
|
128 |
-
# Create
|
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,6 +151,7 @@ def upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_bu
|
|
135 |
})
|
136 |
|
137 |
return download_url
|
|
|
138 |
except Exception as e:
|
139 |
print(f"⚠️ Upload error: {e}")
|
140 |
return ""
|
@@ -153,21 +170,58 @@ def get_roles_from_salesforce():
|
|
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 |
-
|
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=
|
169 |
no_repeat_ngram_size=2,
|
170 |
-
do_sample=
|
171 |
top_p=0.9,
|
172 |
temperature=0.7,
|
173 |
pad_token_id=tokenizer.pad_token_id
|
@@ -190,13 +244,13 @@ def generate_outputs(role, supervisor_name, project_id, milestones, reflection):
|
|
190 |
if not suggestions.strip():
|
191 |
suggestions = "- Monitor team coordination\n- Review safety protocols with the team"
|
192 |
|
193 |
-
|
194 |
-
pdf_url = upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id,
|
195 |
|
196 |
if pdf_url:
|
197 |
suggestions += f"\n\n🔗 [Download PDF Report]({pdf_url})"
|
198 |
|
199 |
-
return checklist, suggestions,
|
200 |
|
201 |
def create_interface():
|
202 |
roles = get_roles_from_salesforce()
|
@@ -227,8 +281,8 @@ def create_interface():
|
|
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,
|
231 |
-
return checklist, suggestions,
|
232 |
|
233 |
generate.click(fn=handle_generate,
|
234 |
inputs=[role, supervisor_name, project_id, milestones, reflection],
|
@@ -249,3 +303,5 @@ def create_interface():
|
|
249 |
if __name__ == "__main__":
|
250 |
app = create_interface()
|
251 |
app.launch()
|
|
|
|
|
|
9 |
from fpdf import FPDF
|
10 |
import shutil
|
11 |
import html
|
|
|
12 |
|
13 |
# Load environment variables
|
14 |
load_dotenv()
|
|
|
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 |
+
file_path = f"./reports/{filename}"
|
65 |
+
os.makedirs("reports", exist_ok=True)
|
66 |
+
|
67 |
pdf = FPDF()
|
68 |
pdf.add_page()
|
69 |
pdf.set_font("Arial", 'B', 14)
|
|
|
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 |
+
pdf.output(file_path)
|
|
|
|
|
88 |
|
89 |
+
temp_pdf_path = "/tmp/" + os.path.basename(file_path)
|
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, pdf_path, pdf_name, checklist, suggestions):
|
94 |
try:
|
95 |
sf = Salesforce(
|
96 |
username=os.getenv('SF_USERNAME'),
|
|
|
99 |
domain=os.getenv('SF_DOMAIN', 'login')
|
100 |
)
|
101 |
|
102 |
+
# Read and encode the file as base64
|
103 |
+
with open(pdf_path, "rb") as f:
|
104 |
+
encoded = base64.b64encode(f.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 the ContentDocumentId for the uploaded PDF
|
114 |
content_id = content['id']
|
115 |
download_url = f"https://{sf.sf_instance}/sfc/servlet.shepherd/version/download/{content_id}"
|
116 |
|
117 |
+
# Query Salesforce to find the specific Supervisor_AI_Coaching__c record
|
118 |
+
query = sf.query(f"""
|
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 a new Supervisor_AI_Coaching__c record
|
145 |
sf.Supervisor_AI_Coaching__c.create({
|
146 |
+
'Project_ID__c': project_id_sf, # Use the Salesforce Project ID
|
147 |
'Supervisor_ID__c': supervisor_id,
|
148 |
'Daily_Checklist__c': checklist,
|
149 |
'Suggested_Tips__c': suggestions,
|
|
|
151 |
})
|
152 |
|
153 |
return download_url
|
154 |
+
|
155 |
except Exception as e:
|
156 |
print(f"⚠️ Upload error: {e}")
|
157 |
return ""
|
|
|
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 |
+
prompt = PROMPT_TEMPLATE.format(role=role, project_id=project_id, milestones=milestones, reflection=reflection)
|
|
|
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=150,
|
223 |
no_repeat_ngram_size=2,
|
224 |
+
do_sample=True,
|
225 |
top_p=0.9,
|
226 |
temperature=0.7,
|
227 |
pad_token_id=tokenizer.pad_token_id
|
|
|
244 |
if not suggestions.strip():
|
245 |
suggestions = "- Monitor team coordination\n- Review safety protocols with the team"
|
246 |
|
247 |
+
pdf_path, pdf_name = save_report_as_pdf(role, supervisor_name, project_id, checklist, suggestions)
|
248 |
+
pdf_url = upload_pdf_to_salesforce_and_update_link(supervisor_name, project_id, pdf_path, pdf_name, checklist, suggestions)
|
249 |
|
250 |
if pdf_url:
|
251 |
suggestions += f"\n\n🔗 [Download PDF Report]({pdf_url})"
|
252 |
|
253 |
+
return checklist, suggestions, pdf_path, pdf_name
|
254 |
|
255 |
def create_interface():
|
256 |
roles = get_roles_from_salesforce()
|
|
|
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, pdf_path, pdf_name = generate_outputs(role, supervisor_name, project_id, milestones, reflection)
|
285 |
+
return checklist, suggestions, pdf_path, pdf_name
|
286 |
|
287 |
generate.click(fn=handle_generate,
|
288 |
inputs=[role, supervisor_name, project_id, milestones, reflection],
|
|
|
303 |
if __name__ == "__main__":
|
304 |
app = create_interface()
|
305 |
app.launch()
|
306 |
+
|
307 |
+
|