File size: 4,605 Bytes
12deac4
d883482
1c7f366
4481124
 
d883482
686e415
89ced22
1aa9765
4481124
 
1c7f366
69715cb
4481124
1aa9765
69715cb
 
 
12deac4
 
69715cb
 
 
 
f6450b6
 
 
 
d883482
1c7f366
 
 
 
1aa9765
12deac4
 
1aa9765
d883482
 
 
 
1c7f366
69715cb
 
6b06b7c
69715cb
 
 
d883482
1c7f366
 
 
 
 
 
 
 
 
 
 
 
 
69715cb
1c7f366
 
69715cb
1c7f366
 
 
 
69715cb
f6450b6
69715cb
1c7f366
 
3c2ec1f
0d5f076
d883482
1c7f366
69715cb
 
1c7f366
 
69715cb
 
1c7f366
69715cb
 
0d5f076
f6450b6
 
 
 
 
 
 
 
69715cb
1c7f366
f6450b6
69715cb
1c7f366
 
69715cb
1c7f366
 
d883482
f6450b6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, HttpUrl, Field
from typing import List, Dict, Optional, Tuple, Any
import requests
from helpers.text_blocks import extract_text_from_url
from helpers.output_clipper import clip_by_ranges
from parser.assembler import parse_law_from_texts
from supabase_utils import save_law_to_supabase  # استدعاء الدالة لحفظ القانون

app = FastAPI(
    title="Text Extractor API",
    description="API لاستخراج النصوص من صفحات الويب مع إمكانية التحكم في النطاقات",
    version="2.1.0"
)

# -----------------------------
# نماذج البيانات
# -----------------------------
class URLRequest(BaseModel):
    url: HttpUrl
    return_parsed: bool = Field(
        default=False,
        description="إذا True → إرجاع المستند القانوني المحلل، إذا False → إرجاع النصوص الخام"
    )
    save_to_supabase: bool = Field(
        default=False,
        description="إذا True → حفظ المستند القانوني في قاعدة البيانات"
    )
    timeout: int = Field(default=10, ge=1, le=60)
    ranges: Optional[List[List[int]]] = Field(
        default=None,
        description="نطاقات الاستخراج في شكل [[start, end], [start, end]] - اختياري"
    )

class TextResponse(BaseModel):
    text: str

class CountResponse(BaseModel):
    total_texts: int
    url: str

class LegalDocumentResponse(BaseModel):
    raw_texts: Optional[List[TextResponse]] = None
    parsed_document: Optional[Dict[str, Any]] = None

# -----------------------------
# التحقق من صحة النطاقات
# -----------------------------
def validate_ranges(ranges: List[List[int]]) -> List[Tuple[int, int]]:
    validated_ranges = []
    for i, range_pair in enumerate(ranges):
        if len(range_pair) != 2:
            raise HTTPException(
                status_code=400,
                detail=f"النطاق رقم {i+1} غير صحيح. كل نطاق يجب أن يحتوي على عنصرين: [start, end]"
            )
        start, end = range_pair
        if not isinstance(start, int) or not isinstance(end, int):
            raise HTTPException(
                status_code=400,
                detail=f"النطاق رقم {i+1} غير صحيح. القيم يجب أن تكون أرقام صحيحة"
            )
        if start < 0 or end <= start:
            raise HTTPException(
                status_code=400,
                detail=f"النطاق رقم {i+1} غير صحيح. النهاية يجب أن تكون أكبر من البداية والبداية >= 0"
            )
        validated_ranges.append((start, end))
    return validated_ranges

# -----------------------------
# نقطة النهاية لاستخراج النصوص / القانون مع حفظ قاعدة البيانات
# -----------------------------
@app.post("/extract", response_model=LegalDocumentResponse)
async def extract_text_endpoint(request: URLRequest):
    try:
        # 1) استخراج جميع النصوص (قائمة قواميس)
        all_texts = extract_text_from_url(str(request.url), request.timeout)
        
        # 2) تطبيق النطاقات إذا وجدت
        if request.ranges:
            validated_ranges = validate_ranges(request.ranges)
            filtered_texts = clip_by_ranges(all_texts, validated_ranges)
        else:
            filtered_texts = all_texts
        
        # 3) إذا طلب تحليل القانون
        if request.return_parsed:
            parsed_document = parse_law_from_texts(filtered_texts)

            # 4) حفظ القانون في Supabase إذا كان save_to_supabase = True
            if request.save_to_supabase:
                save_law_to_supabase(parsed_document["law"])
                parsed_document["saved_to_db"] = True  # تحديث المفتاح داخل الاستجابة
            else:
                parsed_document["saved_to_db"] = False

            return LegalDocumentResponse(parsed_document=parsed_document)
        
        # 5) خلاف ذلك: إرجاع النصوص الخام
        return LegalDocumentResponse(raw_texts=filtered_texts)
        
    except requests.RequestException as e:
        raise HTTPException(status_code=400, detail=f"خطأ في جلب الصفحة: {str(e)}")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"خطأ في معالجة المحتوى: {str(e)}")