Spaces:
Running
Running
Update Data_Fetching_and_Rendering.py
Browse files
Data_Fetching_and_Rendering.py
CHANGED
@@ -287,3 +287,67 @@ def fetch_posts_and_stats(comm_client_id, community_token, count=10):
|
|
287 |
})
|
288 |
|
289 |
return combined_posts, org_name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
})
|
288 |
|
289 |
return combined_posts, org_name
|
290 |
+
|
291 |
+
def render_post_cards(posts, org_name):
|
292 |
+
"""Generates HTML to display posts as cards."""
|
293 |
+
safe_org_name = html.escape(org_name) if org_name else "Your Organization"
|
294 |
+
if not posts:
|
295 |
+
return f"<h2 style='text-align: center; color: #555;'>No recent posts found for {safe_org_name}.</h2>"
|
296 |
+
|
297 |
+
cards_html = f"<h2 style='text-align: center; margin-bottom: 20px;'>Recent Posts for {safe_org_name}</h2><div style='display: flex; flex-wrap: wrap; gap: 15px; justify-content: center;'>"
|
298 |
+
for p in posts:
|
299 |
+
# Text is already escaped in fetch_posts_and_stats
|
300 |
+
cards_html += f"""
|
301 |
+
<div style="border: 1px solid #ccc; border-radius: 8px; padding: 15px; margin: 5px; width: 280px;
|
302 |
+
box-shadow: 2px 2px 5px rgba(0,0,0,0.1); background-color: #fff; display: flex;
|
303 |
+
flex-direction: column; justify-content: space-between; min-height: 220px; /* Adjusted min-height */">
|
304 |
+
<div>
|
305 |
+
<div style="font-size: 0.8em; color: #666; margin-bottom: 8px; border-bottom: 1px dashed #eee; padding-bottom: 5px;">{p['when']}</div>
|
306 |
+
<div style="font-size: 0.95em; margin-bottom: 12px; word-wrap: break-word; max-height: 120px; overflow-y: auto; padding-right: 5px;">{p['text']}</div>
|
307 |
+
</div>
|
308 |
+
<div style="font-size: 0.9em; color: #333; border-top: 1px solid #eee; padding-top: 10px; margin-top: auto; line-height: 1.6;">
|
309 |
+
<span title="Impressions">ποΈ {p.get('impressions', 0):,}</span> |
|
310 |
+
<span title="Likes">π {p.get('likes', 0):,}</span> |
|
311 |
+
<span title="Comments">π¬ {p.get('comments', 0):,}</span> |
|
312 |
+
<span title="Shares">π {p.get('shares', 0):,}</span> |
|
313 |
+
<span title="Clicks">π±οΈ {p.get('clicks', 0):,}</span><br>
|
314 |
+
<span title="Engagement Rate" style="font-weight: bold;">π {p.get('engagement', '0.00%')}</span>
|
315 |
+
</div>
|
316 |
+
</div>
|
317 |
+
"""
|
318 |
+
cards_html += "</div>"
|
319 |
+
return cards_html
|
320 |
+
|
321 |
+
def fetch_and_render_dashboard(comm_client_id, community_token):
|
322 |
+
"""Orchestrates fetching post data and rendering the dashboard."""
|
323 |
+
print("--- Rendering Dashboard ---")
|
324 |
+
if not comm_client_id: # Community token not strictly needed for this fetch anymore
|
325 |
+
print("ERROR: comm_client_id missing for dashboard rendering.")
|
326 |
+
return "<p style='color: red; text-align: center; font-weight: bold;'>β Error: Missing LinkedIn Marketing token. Please complete the login process on the 'Login' tab.</p>"
|
327 |
+
try:
|
328 |
+
print("Fetching posts and stats for dashboard...")
|
329 |
+
# Pass only the necessary token
|
330 |
+
posts_data, org_name = fetch_posts_and_stats(comm_client_id, community_token) # community_token kept for signature consistency
|
331 |
+
print(f"Rendering {len(posts_data)} posts for {org_name}.")
|
332 |
+
if not org_name:
|
333 |
+
org_name = "[Organization Name Not Found]" # Handle case where org name wasn't fetched
|
334 |
+
return render_post_cards(posts_data, org_name)
|
335 |
+
except ValueError as ve: # Catch specific errors like missing orgs or token issues
|
336 |
+
print(f"VALUE ERROR during dashboard fetch: {ve}")
|
337 |
+
# Use display_error to format the message for HTML/Markdown
|
338 |
+
error_update = display_error(f"Configuration or API Error: {ve}", ve)
|
339 |
+
return error_update.get('value', "<p style='color: red; text-align: center;'>β A configuration or API error occurred.</p>")
|
340 |
+
except requests.exceptions.RequestException as re:
|
341 |
+
print(f"HTTP ERROR during dashboard fetch: {re}")
|
342 |
+
status_code = re.response.status_code if re.response else "N/A"
|
343 |
+
error_update = display_error(f"API Request Failed (Status: {status_code}). Check permissions/scopes or API status.", re)
|
344 |
+
return error_update.get('value', f"<p style='color: red; text-align: center;'>β API Error: {status_code}. Check console logs.</p>")
|
345 |
+
except Exception as e:
|
346 |
+
print(f"UNEXPECTED ERROR during dashboard fetch: {e}")
|
347 |
+
error_update = display_error("Failed to fetch or render dashboard data.", e)
|
348 |
+
error_html = error_update.get('value', "<p style='color: red; text-align: center;'>β An unexpected error occurred. Check console logs.</p>")
|
349 |
+
# Ensure the error message is HTML-safe
|
350 |
+
if isinstance(error_html, str) and not error_html.strip().startswith("<"):
|
351 |
+
error_html = f"<pre style='color: red; white-space: pre-wrap;'>{html.escape(error_html)}</pre>"
|
352 |
+
return error_html
|
353 |
+
|