File size: 6,987 Bytes
a878591
 
 
 
f9e510b
a878591
 
 
 
bf4244e
a878591
f9e510b
 
 
 
 
bf4244e
672b965
f9e510b
 
f11c153
 
 
 
 
 
 
 
 
a878591
f11c153
 
 
 
 
 
a878591
 
 
 
 
 
 
bf4244e
f11c153
a878591
 
 
 
 
 
 
 
 
 
f11c153
a878591
f11c153
a878591
f9e510b
f11c153
 
 
 
 
 
 
 
 
 
 
f9e510b
a878591
f11c153
 
 
 
 
 
 
 
 
a878591
 
f11c153
 
 
 
 
 
 
 
 
 
 
a878591
 
f11c153
 
 
 
 
 
 
f9e510b
 
a878591
f11c153
a878591
f11c153
 
a878591
63f1f20
6bcb91c
 
 
 
7c3e45f
 
 
6bcb91c
 
 
 
 
 
63f1f20
bf4244e
63f1f20
f11c153
6bcb91c
 
 
 
 
 
a24ce43
6bcb91c
a878591
3504a29
 
 
 
 
 
 
a878591
672b965
63f1f20
672b965
63f1f20
a878591
6bcb91c
 
 
 
 
 
 
 
a878591
6bcb91c
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import os
import gradio as gr
import pdfplumber
from openai import OpenAI
from langdetect import detect

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

SUMMARY_STYLES = ["Child-Friendly", "Academic", "Tweet"]
LANGUAGES = ["English", "Turkish", "French", "German", "Spanish", "Arabic"]

LANGUAGE_CODES = {
    "English": "en",
    "Turkish": "tr",
    "French": "fr",
    "German": "de",
    "Spanish": "es",
    "Arabic": "ar"  
}

QUIZ_TITLES = {
    "English": "### 📘 Quiz Questions:",
    "Turkish": "### 📘 Test Soruları:",
    "French": "### 📘 Questions à Choix Multiples :",
    "German": "### 📘 Quizfragen:",
    "Spanish": "### 📘 Preguntas del cuestionario:",
    "Arabic": "### 📘 أسئلة الاختيار من متعدد:"
}

PROMPT_TEMPLATES = {
    "English": "Please summarize the following text in a {style} style and keep it within approximately {char_limit} characters.\nThen provide 5 relevant keywords.\n\nTEXT:\n{text}",
    "Turkish": "Lütfen aşağıdaki metni {style} tarzında ve yaklaşık {char_limit} karakter olacak şekilde özetle.\nArdından 5 anahtar kelime ver.\n\nMETİN:\n{text}",
    "French": "Veuillez résumer le texte suivant dans un style {style}, en environ {char_limit} caractères.\nFournissez ensuite 5 mots-clés pertinents.\n\nTEXTE :\n{text}",
    "German": "Fassen Sie den folgenden Text im {style}-Stil mit etwa {char_limit} Zeichen zusammen.\nGeben Sie anschließend 5 relevante Schlüsselwörter an.\n\nTEXT:\n{text}",
    "Spanish": "Resume el siguiente texto en un estilo {style} y con un límite de aproximadamente {char_limit} caracteres.\nLuego proporciona 5 palabras clave relevantes.\n\nTEXTO:\n{text}",
    "Arabic": "الرجاء تلخيص النص التالي بأسلوب {style}، على ألا يتجاوز {char_limit} حرفًا.\nثم قدم 5 كلمات مفتاحية مهمة.\n\nالنص:\n{text}"
}

QUIZ_PROMPTS = {
    "English": "Based on the text below, generate 2 multiple choice questions (each with 4 options A-D):\n\n{text}",
    "Turkish": "Aşağıdaki metne dayanarak, 4 seçenekli (A, B, C, D) 2 adet çoktan seçmeli soru oluştur:\n\n{text}",
    "French": "Sur la base du texte ci-dessous, générez 2 questions à choix multiples (4 options A à D) :\n\n{text}",
    "German": "Erstelle basierend auf dem folgenden Text 2 Multiple-Choice-Fragen (mit jeweils 4 Optionen A–D):\n\n{text}",
    "Spanish": "Con base en el siguiente texto, genera 2 preguntas de opción múltiple (cada una con 4 opciones A–D):\n\n{text}",
    "Arabic": "قم بإنشاء سؤالين اختيار من متعدد استنادًا إلى النص أدناه، مع أربعة خيارات لكل سؤال (أ، ب، ج، د):\n\n{text}"
}

def extract_text_from_pdf(file):
    try:
        with pdfplumber.open(file.name) as pdf:
            text = ""
            for page in pdf.pages:
                page_text = page.extract_text()
                if page_text:
                    text += page_text + "\n"
        return text.strip() if text.strip() else None, None
    except Exception as e:
        return None, str(e)

def translate_text(text, target_lang):
    prompt = f"Translate the following text into {target_lang}:\n\n{text}"
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.3,
        max_tokens=1000
    )
    return response.choices[0].message.content

def replace_arabic_choices(quiz_text):
    return quiz_text.replace("A)", "أ.").replace("B)", "ب.").replace("C)", "ج.").replace("D)", "د.")

def generate_summary_and_keywords(text, summary_lang, style, char_limit):
    template = PROMPT_TEMPLATES[summary_lang]
    prompt = template.format(style=style, char_limit=char_limit, text=text[:2000])
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7,
        max_tokens=700
    )
    return response.choices[0].message.content

def generate_quiz(summary_text, summary_lang):
    prompt = QUIZ_PROMPTS[summary_lang].format(text=summary_text)
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7,
        max_tokens=500
    )
    result = response.choices[0].message.content
    return replace_arabic_choices(result) if summary_lang == "Arabic" else result

def process(text_input, pdf_file, summary_lang, style, char_limit, make_quiz):
    if not char_limit.isdigit():
        return "⚠️ Please enter a numeric character limit."

    text, error = extract_text_from_pdf(pdf_file) if pdf_file else (text_input.strip(), None)
    if error or not text:
        return f"⚠️ Error: {error or 'No valid text provided.'}"

    detected = detect(text)
    if detected != LANGUAGE_CODES[summary_lang]:
        text = translate_text(text, summary_lang)

    summary = generate_summary_and_keywords(text, summary_lang, style, char_limit)
    if make_quiz:
        quiz = generate_quiz(summary, summary_lang)
        return summary + "\n\n" + QUIZ_TITLES[summary_lang] + "\n" + quiz
    return summary

with gr.Blocks(css="""
.big-file-upload .file-wrap, 
.big-file-upload .wrap, 
.big-file-upload .upload-box, 
.big-file-upload .dropbox {
    min-height: 258px !important;
    max-height: 258px !important;
    height: 258px !important;
}
.big-textbox textarea {
    min-height: 210px !important;
    max-height: 210px !important;
    height: 210px !important;
}
""") as demo:
    gr.Markdown("## 🌍 Multilingual Summarizer + Quiz Generator")

    with gr.Accordion("📘 View README / Usage Guide", open=False):
        gr.Markdown("""
This application allows you to upload a PDF or paste text, select your preferred summary language, and receive:
- ✂️ A clear summary  
- 🏷️ An auto-generated title  
- 🔑 5 relevant keywords  
- 🌐 If the content language and summary language differ, the app will auto-translate before summarizing  
Powered by OpenAI GPT-3.5 and Gradio.
""")

    with gr.Row():
        summary_lang = gr.Dropdown(LANGUAGES, value="English", label="Summary Language")
        summary_style = gr.Dropdown(SUMMARY_STYLES, value="Academic", label="Summary Style")
        char_limit = gr.Textbox(label="Character Limit", value="300")

    make_quiz = gr.Checkbox(label="Generate Quiz Questions", value=True)

    with gr.Row():
        with gr.Column(scale=2):
            text_input = gr.Textbox(lines=15, label="Text Input", elem_classes="big-textbox")
        with gr.Column(scale=2):
            pdf_file = gr.File(label="Or Upload PDF", elem_classes="big-file-upload")

    output = gr.Textbox(label="Output", lines=8)

    run_btn = gr.Button("Summarize")

    run_btn.click(
        inputs=[summary_lang, summary_style, char_limit, text_input, pdf_file, make_quiz],
        outputs=output
    )

demo.launch()