Spaces:
Running
Running
| # core/callbacks.py | |
| import io | |
| import contextlib | |
| import traceback | |
| from datetime import datetime | |
| import pytz | |
| from core.visits import get_current_visit_count | |
| from core.notifications import send_line_notification_in_background | |
| from config.data import KNOWLEDGE_BASE | |
| def execute_user_code(code_string, source_lab): | |
| """Executes user-provided code in a restricted environment and sends a notification.""" | |
| string_io = io.StringIO() | |
| status = "✅ 成功" | |
| error_info = "" | |
| fig = None | |
| try: | |
| with contextlib.redirect_stdout(string_io): | |
| local_scope = {} | |
| # Pre-import necessary libraries for the user's code | |
| exec("import matplotlib.pyplot as plt; import numpy as np; import cartopy.crs as ccrs; import cartopy.feature as cfeature; from matplotlib.ticker import FixedFormatter", local_scope) | |
| exec(code_string, local_scope) | |
| console_output = string_io.getvalue() | |
| fig = local_scope.get('fig') | |
| if fig is None: | |
| status = "⚠️ 警告" | |
| error_info = "程式碼執行完畢,但未找到 'fig' 物件。" | |
| return None, f"{error_info}\nPrint 輸出:\n{console_output}" | |
| success_message = f"✅ 程式碼執行成功!\n\n--- Console Output ---\n{console_output}" | |
| return fig, success_message | |
| except Exception: | |
| status = "❌ 失敗" | |
| error_info = traceback.format_exc() | |
| final_message = f"❌ 程式碼執行失敗!\n\n--- Error Traceback ---\n{error_info}" | |
| return None, final_message | |
| finally: | |
| # This block will always run, regardless of success or failure | |
| tz = pytz.timezone('Asia/Taipei') | |
| current_time = datetime.now(tz).strftime('%H:%M:%S') | |
| visit_count = get_current_visit_count() | |
| notification_text = ( | |
| f"🔬 程式碼實驗室互動!\n\n" | |
| f"時間: {current_time}\n" | |
| f"實驗室: {source_lab}\n" | |
| f"執行狀態: {status}\n" | |
| f"總載入數: {visit_count}" | |
| ) | |
| if status == "❌ 失敗": | |
| # Add specific error type to notification for quick debugging | |
| error_type = error_info.strip().split('\n')[-1] | |
| notification_text += f"\n錯誤類型: {error_type}" | |
| send_line_notification_in_background(notification_text) | |
| def ai_chatbot_with_kb(message, history): | |
| """Handles chatbot interaction, queries the knowledge base, and sends a notification.""" | |
| # Send notification in the background | |
| tz = pytz.timezone('Asia/Taipei') | |
| current_time = datetime.now(tz).strftime('%H:%M:%S') | |
| visit_count = get_current_visit_count() | |
| notification_text = ( | |
| f"🤖 AI 助教被提問!\n\n" | |
| f"時間: {current_time}\n" | |
| f"使用者問題:\n「{message}」\n\n" | |
| f"總載入數: {visit_count}" | |
| ) | |
| send_line_notification_in_background(notification_text) | |
| # Perform knowledge base lookup | |
| user_message = message.lower().strip() | |
| for item in KNOWLEDGE_BASE: | |
| for keyword in item['keywords']: | |
| if keyword in user_message: | |
| return item['answer'] | |
| # Default response if no keyword is matched | |
| return "這個問題很有趣,不過我的知識庫目前還沒有收錄相關的答案。您可以試著問我關於**課程評分、Anaconda安裝、Colab與Codespaces的差別、什麼是API,或者期末專題的靈感**等問題!" |