model-bot / app.py
MHD011's picture
Update app.py
6d856e6 verified
import os
import re
from datetime import datetime
from flask import Flask, request, jsonify
from flask_cors import CORS
import psycopg2
from psycopg2 import pool
from typing import Optional, Dict, List
app = Flask(__name__)
CORS(app)
# إعدادات اتصال قاعدة البيانات
DB_URL = os.getenv('SUPABASE_DB_URL')
connection_pool = psycopg2.pool.SimpleConnectionPool(
minconn=1,
maxconn=5,
dsn=DB_URL
)
class QueryBuilder:
"""فئة مسؤولة عن بناء استعلامات SQL الآمنة"""
@staticmethod
def get_last_office_visit(cam_mac: str) -> str:
"""استعلام عن آخر زيارة للمكتب"""
return f"""
SELECT caption, created_at, image_url
FROM data
WHERE cam_mac = '{cam_mac}'
AND (caption LIKE '%مكتب%' OR caption LIKE '%عمل%')
ORDER BY created_at DESC
LIMIT 1
"""
@staticmethod
def get_last_five_places(cam_mac: str) -> str:
"""استعلام عن آخر 5 أماكن مميزة"""
return f"""
SELECT DISTINCT ON (caption) caption, created_at, latitude, longitude, image_url
FROM data
WHERE cam_mac = '{cam_mac}'
AND caption IS NOT NULL
ORDER BY caption, created_at DESC
LIMIT 5
"""
@staticmethod
def check_garden_visit(cam_mac: str) -> str:
"""استعلام عن زيارة الحديقة"""
return f"""
SELECT caption, created_at, image_url
FROM data
WHERE cam_mac = '{cam_mac}'
AND (caption LIKE '%حديقة%' OR caption LIKE '%حدائق%' OR caption LIKE '%نباتات%')
ORDER BY created_at DESC
LIMIT 1
"""
@staticmethod
def check_classroom_visit(cam_mac: str) -> str:
"""استعلام عن زيارة صف دراسي"""
return f"""
SELECT caption, created_at, image_url
FROM data
WHERE cam_mac = '{cam_mac}'
AND (caption LIKE '%صف%' OR caption LIKE '%قاعة%' OR caption LIKE '%محاضرة%'
OR caption LIKE '%جامعة%' OR caption LIKE '%مدرسة%')
ORDER BY created_at DESC
LIMIT 1
"""
class DatabaseExecutor:
"""فئة مسؤولة عن تنفيذ الاستعلامات وإدارة الاتصالات"""
@staticmethod
def execute_query(sql: str) -> List[Dict]:
"""تنفيذ استعلام SQL وإرجاع النتائج"""
conn = None
try:
conn = connection_pool.getconn()
cursor = conn.cursor()
cursor.execute(sql)
if cursor.description:
columns = [desc[0] for desc in cursor.description]
return [dict(zip(columns, row)) for row in cursor.fetchall()]
return []
finally:
if conn:
connection_pool.putconn(conn)
@app.route('/query', methods=['POST'])
def handle_query():
try:
data = request.get_json()
cam_mac = data.get('cam_mac')
question = data.get('question')
if not cam_mac or not question:
return jsonify({"error": "يجب تقديم cam_mac و question"}), 400
# تنظيف المدخلات
cam_mac = re.sub(r'[^a-fA-F0-9:]', '', cam_mac)
question = question.strip().lower()
# تحديد الاستعلام المناسب
sql = None
if 'مكتب' in question or 'عمل' in question:
sql = QueryBuilder.get_last_office_visit(cam_mac)
elif 'خمس أماكن' in question or 'آخر أماكن' in question:
sql = QueryBuilder.get_last_five_places(cam_mac)
elif 'حديقة' in question or 'حدائق' in question:
sql = QueryBuilder.check_garden_visit(cam_mac)
elif 'صف دراسي' in question or 'محاضرة' in question or 'قاعة' in question:
sql = QueryBuilder.check_classroom_visit(cam_mac)
if not sql:
return jsonify({"error": "نوع السؤال غير معروف"}), 400
# تنفيذ الاستعلام
results = DatabaseExecutor.execute_query(sql)
return jsonify({
"question": question,
"results": results,
"timestamp": datetime.now().isoformat()
})
except psycopg2.Error as e:
return jsonify({"error": "خطأ في قاعدة البيانات", "details": str(e)}), 500
except Exception as e:
return jsonify({"error": "خطأ غير متوقع", "details": str(e)}), 500
@app.route('/health', methods=['GET'])
def health_check():
try:
conn = connection_pool.getconn()
conn.close()
return jsonify({"status": "يعمل بنجاح"})
except Exception as e:
return jsonify({"status": "غير متصل", "error": str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))