Nadasr commited on
Commit
1972b5c
·
verified ·
1 Parent(s): 5083f43

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +165 -0
app.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import pipeline
3
+ import PyPDF2
4
+ import torch
5
+
6
+ # ===== 1) اختر الموديل هنا =====
7
+ # موديل إنجليزي:
8
+ # MODEL_NAME = "csebuetnlp/mT5_multilingual_XLSum"
9
+
10
+ # موديل ملخص متعدد اللغات (يدعم العربية أفضل):
11
+ MODEL_NAME = "csebuetnlp/mT5_multilingual_XLSum"
12
+
13
+ # ===== 2) تجهيز الـ pipeline =====
14
+ device = 0 if torch.cuda.is_available() else -1
15
+
16
+ summarizer = pipeline(
17
+ "summarization",
18
+ model=MODEL_NAME,
19
+ tokenizer=MODEL_NAME,
20
+ device=device,
21
+ )
22
+
23
+ # ===== 3) قراءة الـ PDF =====
24
+ def read_pdf(file_obj):
25
+ """
26
+ يستقبل ملف PDF من Gradio (file_obj)،
27
+ يرجّع النص المستخرج من كل الصفحات.
28
+ """
29
+ if file_obj is None:
30
+ return ""
31
+
32
+ reader = PyPDF2.PdfReader(file_obj)
33
+ text = ""
34
+ for page in reader.pages:
35
+ page_text = page.extract_text()
36
+ if page_text:
37
+ text += page_text + "\n"
38
+
39
+ return text
40
+
41
+
42
+ # ===== 4) تقسيم النص لقطع (عشان حدود الموديل) =====
43
+ def chunk_text(text, max_chars=2000):
44
+ """
45
+ يقسم النص إلى قطع صغيرة بعدد حروف أقصاه max_chars
46
+ عشان لا نتجاوز حدود الموديل.
47
+ """
48
+ paragraphs = text.split("\n")
49
+ chunks = []
50
+ current = ""
51
+
52
+ for p in paragraphs:
53
+ p = p.strip()
54
+ if not p:
55
+ continue
56
+
57
+ # لو نقدر نضيف الفقرة للجزء الحالي بدون ما نتعدى الحد
58
+ if len(current) + len(p) + 1 <= max_chars:
59
+ current += ("\n" + p) if current else p
60
+ else:
61
+ # نخزن الجزء القديم ونبدأ جزء جديد
62
+ if current.strip():
63
+ chunks.append(current.strip())
64
+ current = p
65
+
66
+ if current.strip():
67
+ chunks.append(current.strip())
68
+
69
+ return chunks
70
+
71
+
72
+ # ===== 5) دالة التلخيص الرئيسية =====
73
+ def summarize_pdf(file, max_summary_length=200):
74
+ """
75
+ تستقبل ملف PDF من واجهة Gradio،
76
+ تقرأ النص، تقسمه لقطع، تلخص كل جزء،
77
+ ثم تلخص التلخيصات مرة ثانية (لو كانت كثيرة).
78
+ """
79
+ if file is None:
80
+ return "رجاءً ارفع ملف PDF أولاً."
81
+
82
+ # 1) قراءة النص من الـ PDF
83
+ text = read_pdf(file)
84
+
85
+ if not text or len(text.strip()) < 50:
86
+ return "لم أستطع قراءة نص واضح من الـ PDF. تأكد أن الملف ليس صورة ممسوحة فقط (scan)."
87
+
88
+ # 2) تقسيم النص
89
+ chunks = chunk_text(text, max_chars=2000)
90
+
91
+ # 3) تلخيص كل جزء
92
+ partial_summaries = []
93
+ for idx, ch in enumerate(chunks, start=1):
94
+ # نضمن طول منطقي للتلخيص
95
+ try:
96
+ result = summarizer(
97
+ ch,
98
+ max_length=max_summary_length,
99
+ min_length=int(max_summary_length / 3),
100
+ do_sample=False,
101
+ )
102
+ summary_text = result[0]["summary_text"]
103
+ except Exception as e:
104
+ summary_text = f"[خطأ في تلخيص الجزء {idx}: {e}]"
105
+
106
+ partial_summaries.append(summary_text)
107
+
108
+ combined = "\n\n".join(partial_summaries)
109
+
110
+ # 4) لو الملف طويل جداً (أكثر من جزء واحد)، نلخص التلخيص النهائي
111
+ if len(partial_summaries) > 1:
112
+ try:
113
+ final = summarizer(
114
+ combined,
115
+ max_length=max_summary_length,
116
+ min_length=int(max_summary_length / 3),
117
+ do_sample=False,
118
+ )[0]["summary_text"]
119
+ return final
120
+ except Exception:
121
+ # لو فشل التلخيص الثاني، نرجع دمج التلخيصات الأولية
122
+ return combined
123
+ else:
124
+ return combined
125
+
126
+
127
+ # ===== 6) واجهة Gradio =====
128
+ with gr.Blocks() as demo:
129
+ gr.Markdown(
130
+ """
131
+ # 📄 PDF Summarizer / ملخّص ملفات PDF
132
+
133
+ ارفع ملف PDF وسيقوم النموذج بقراءة النص وتلخيصه بشكل تلقائي.
134
+ يمكن تعديل طول التلخيص باستخدام الشريط أسفل.
135
+ """
136
+ )
137
+
138
+ with gr.Row():
139
+ pdf_input = gr.File(
140
+ label="📎 ارفع ملف PDF",
141
+ file_types=[".pdf"],
142
+ )
143
+ max_len = gr.Slider(
144
+ minimum=50,
145
+ maximum=400,
146
+ step=50,
147
+ value=200,
148
+ label="أقصى طول للتلخيص (تقريبي)",
149
+ )
150
+
151
+ output = gr.Textbox(
152
+ label="ملخص الملف",
153
+ lines=15,
154
+ )
155
+
156
+ summarize_btn = gr.Button("✨ تلخيص PDF")
157
+
158
+ summarize_btn.click(
159
+ fn=summarize_pdf,
160
+ inputs=[pdf_input, max_len],
161
+ outputs=output,
162
+ )
163
+
164
+ # مهم في Hugging Face Spaces:
165
+ demo.launch()