Spaces:
Running
Running
import gradio as gr | |
import google.generativeai as genai | |
import markdown | |
from docx import Document | |
from bs4 import BeautifulSoup | |
import shutil | |
import os | |
import PyPDF2 | |
import tempfile | |
from datetime import datetime | |
# API anahtarı yapılandırması | |
def setup_api_key(): | |
google_api_key = os.getenv("GOOGLE_API_KEY") | |
if not google_api_key: | |
raise ValueError("GOOGLE_API_KEY çevre değişkeni ayarlanmamış.") | |
genai.configure(api_key=google_api_key) | |
# Dosya yükleme fonksiyonu | |
def upload_file(file_path): | |
try: | |
text_file = genai.upload_file(path=file_path) | |
return text_file | |
except Exception as e: | |
raise Exception(f"Dosya yükleme hatası: {str(e)}") | |
# Markdown formatına dönüştürme | |
def to_markdown(text): | |
text = text.replace('•', ' *') | |
return markdown.markdown(text) | |
# AI modelini oluşturma | |
def build_model(text_file): | |
generation_config = { | |
"temperature": 0.2, | |
"top_p": 0.95, | |
"top_k": 64, | |
"max_output_tokens": 8192, | |
"response_mime_type": "text/plain", | |
} | |
model = genai.GenerativeModel( | |
model_name="gemini-1.5-flash", | |
generation_config=generation_config, | |
system_instruction="""PDF belgesinden yüklenen bilgilere dayanarak soruları cevapla. | |
Belge içinde ilgili bilgi yoksa 'Bu konuda belgede bilgi bulamadım.' diye yanıtla. | |
Cevaplarında mümkün olduğunca belgedeki bilgileri referans ver ve doğru bilgi sağla.""", | |
) | |
chat_session = model.start_chat(history=[]) | |
# Belgeyi özetleyerek başla | |
response = chat_session.send_message(["Bu belgeyi kısaca özetle", text_file]) | |
return chat_session, response.text | |
# Sohbet fonksiyonu | |
def chat(chat_session, prompt): | |
try: | |
response = chat_session.send_message(prompt) | |
return response.text | |
except Exception as e: | |
return f"Yanıt alınamadı: {str(e)}" | |
# Rapor oluşturma | |
def generate_report(chat_session, questions, summary): | |
report_text = "# PDF Belge Analiz Raporu\n\n" | |
report_text += f"*Oluşturulma tarihi: {datetime.now().strftime('%d.%m.%Y %H:%M')}*\n\n" | |
report_text += f"## Belge Özeti\n\n{summary}\n\n" | |
report_text += f"## Soru ve Cevaplar\n\n" | |
for i, question in enumerate(questions, 1): | |
if not question.strip(): | |
continue | |
report_text += f"### Soru {i}: {question}\n\n" | |
answer = chat(chat_session, question) | |
report_text += f"{answer}\n\n" | |
return report_text | |
# Markdown'ı HTML'e dönüştürme | |
def convert_markdown_to_html(report_text): | |
html_text = markdown.markdown(report_text, extensions=['tables']) | |
return f""" | |
<div style="font-family: Arial, sans-serif; line-height: 1.6; max-width: 800px; margin: 0 auto; padding: 20px;"> | |
{html_text} | |
</div> | |
""" | |
# HTML'i Word belgesine ekleme | |
def add_html_to_word(html_text, doc): | |
soup = BeautifulSoup(html_text, 'html.parser') | |
for element in soup.find_all(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'ul', 'ol', 'li']): | |
if element.name.startswith('h') and element.name[1:].isdigit(): | |
level = int(element.name[1]) | |
doc.add_heading(element.get_text(), level=level) | |
elif element.name == 'p': | |
if element.get_text().strip(): | |
doc.add_paragraph(element.get_text()) | |
elif element.name == 'ul': | |
for li in element.find_all('li', recursive=False): | |
doc.add_paragraph(li.get_text(), style='List Bullet') | |
elif element.name == 'ol': | |
for li in element.find_all('li', recursive=False): | |
doc.add_paragraph(li.get_text(), style='List Number') | |
# PDF'den metin çıkarma | |
def extract_text_from_pdf(pdf_path): | |
text = "" | |
try: | |
with open(pdf_path, 'rb') as file: | |
pdf_reader = PyPDF2.PdfReader(file) | |
for page_num in range(len(pdf_reader.pages)): | |
text += pdf_reader.pages[page_num].extract_text() + "\n" | |
return text | |
except Exception as e: | |
raise Exception(f"PDF okuma hatası: {str(e)}") | |
# Ana işlem fonksiyonu | |
def process_pdf(pdf_file, user_questions, progress=gr.Progress()): | |
if not pdf_file: | |
return "Lütfen bir PDF dosyası yükleyin.", None | |
progress(0, desc="PDF yükleniyor...") | |
# Geçici dosya ve klasör yönetimi | |
temp_dir = tempfile.mkdtemp() | |
file_name = os.path.basename(pdf_file) | |
pdf_path = os.path.join(temp_dir, file_name) | |
try: | |
# PDF dosyasını geçici konuma kopyala | |
shutil.copyfile(pdf_file, pdf_path) | |
progress(20, desc="PDF'den metin çıkarılıyor...") | |
text = extract_text_from_pdf(pdf_path) | |
# Çıkarılan metni bir dosyaya yaz | |
text_file_path = os.path.join(temp_dir, "extracted_text.txt") | |
with open(text_file_path, "w", encoding="utf-8") as f: | |
f.write(text) | |
progress(40, desc="Metin dosyası yükleniyor...") | |
text_file = upload_file(text_file_path) | |
progress(60, desc="AI modeli hazırlanıyor...") | |
chat_session, summary = build_model(text_file) | |
progress(70, desc="Sorular işleniyor...") | |
# Soruları ayırma | |
questions = [q.strip() for q in user_questions.split('\n') if q.strip()] | |
progress(80, desc="Rapor oluşturuluyor...") | |
report_text = generate_report(chat_session, questions, summary) | |
progress(90, desc="Sonuçlar formatlanıyor...") | |
html_output = convert_markdown_to_html(report_text) | |
# Word belgesi oluştur | |
doc = Document() | |
add_html_to_word(html_output, doc) | |
doc_name = f"PDF_Rapor_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx" | |
doc_path = os.path.join(temp_dir, doc_name) | |
doc.save(doc_path) | |
progress(100, desc="Tamamlandı!") | |
return html_output, doc_path | |
except Exception as e: | |
error_message = f"<div style='color: red; font-weight: bold;'>Hata oluştu: {str(e)}</div>" | |
return error_message, None | |
finally: | |
# Geçici dosyaları silme işlemi (opsiyonel) | |
pass | |
# Varsayılan sorular | |
default_questions = """Belgenin ana konusu nedir? | |
Belgenin yazarları kimlerdir? | |
Belgedeki önemli bulgular nelerdir? | |
Kaç sayfa ve bölüm vardır? | |
Hangi tarihte yayınlanmıştır?""" | |
# Gradio arayüzü | |
with gr.Blocks(theme=gr.themes.Soft()) as iface: | |
gr.Markdown(""" | |
# 📄 PDF Soru-Cevap Asistanı | |
Bu uygulama, yüklediğiniz PDF belgesi üzerinde sorular sormanıza ve detaylı bir rapor almanıza olanak tanır. | |
""") | |
with gr.Row(): | |
with gr.Column(scale=1): | |
pdf_input = gr.File( | |
label="PDF Dosyası Yükleyin", | |
file_types=[".pdf"], | |
type="filepath" | |
) | |
questions_input = gr.TextArea( | |
label="Sorularınız", | |
placeholder="Her satıra bir soru yazın...", | |
value=default_questions, | |
lines=10 | |
) | |
submit_btn = gr.Button("📝 Rapor Oluştur", variant="primary") | |
with gr.Column(scale=2): | |
with gr.Tabs(): | |
with gr.Tab("HTML Görünüm"): | |
html_output = gr.HTML(label="Rapor Sonucu") | |
with gr.Tab("İndirilebilir Dosya"): | |
file_output = gr.File(label="DOCX Rapor") | |
with gr.Accordion("Nasıl Kullanılır?", open=False): | |
gr.Markdown(""" | |
### Kullanım Adımları: | |
1. PDF dosyanızı yükleyin | |
2. Belge hakkında cevaplarını almak istediğiniz soruları yazın | |
3. "Rapor Oluştur" düğmesine basın | |
4. Oluşturulan raporu HTML olarak görüntüleyin veya DOCX dosyası olarak indirin | |
### İpuçları: | |
- Her satıra bir soru yazın | |
- Belgenin içeriğiyle ilgili net sorular sorun | |
- Büyük PDF'ler için işlem süresi uzayabilir | |
""") | |
submit_btn.click( | |
fn=process_pdf, | |
inputs=[pdf_input, questions_input], | |
outputs=[html_output, file_output], | |
show_progress=True | |
) | |
# API anahtarını ayarla ve uygulamayı başlat | |
if __name__ == "__main__": | |
try: | |
setup_api_key() | |
iface.launch(share=True) | |
except ValueError as e: | |
print(f"Hata: {str(e)}") | |
print("Lütfen GOOGLE_API_KEY çevre değişkenini ayarlayın.") |