Spaces:
Running
Running
Commit
·
cc21f11
0
Parent(s):
VIZSUM PRO REAL DEPLOY — Claude 3, Emoji Yok, PDF Fix
Browse files- .env.example +1 -0
- .gitignore +11 -0
- .gradio/certificate.pem +31 -0
- README.md +22 -0
- app.py +2 -0
- git +0 -0
- main +0 -0
- ocr_engine.py +46 -0
- pdf_reader.py +15 -0
- requirements.txt +6 -0
- summarizer.py +39 -0
- summarizer_test.py +6 -0
- tests/notepad_test_ocr.py +3 -0
- tests/python_test_key.py +6 -0
- tests/summarizer_test.py +6 -0
- ui.py +54 -0
.env.example
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
OPENROUTER_API_KEY=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
|
.gitignore
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*.png
|
2 |
+
*.jpg
|
3 |
+
*.jpeg
|
4 |
+
*.mp3
|
5 |
+
*.mp4
|
6 |
+
*.pt
|
7 |
+
*.ckpt
|
8 |
+
*.bin
|
9 |
+
__pycache__/
|
10 |
+
*.py[cod]
|
11 |
+
.env
|
.gradio/certificate.pem
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
-----BEGIN CERTIFICATE-----
|
2 |
+
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
|
3 |
+
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
4 |
+
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
|
5 |
+
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
|
6 |
+
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
|
7 |
+
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
|
8 |
+
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
|
9 |
+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
|
10 |
+
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
|
11 |
+
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
|
12 |
+
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
|
13 |
+
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
|
14 |
+
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
|
15 |
+
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
|
16 |
+
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
|
17 |
+
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
|
18 |
+
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
19 |
+
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
|
20 |
+
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
|
21 |
+
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
|
22 |
+
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
|
23 |
+
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
|
24 |
+
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
|
25 |
+
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
|
26 |
+
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
|
27 |
+
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
|
28 |
+
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
|
29 |
+
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
|
30 |
+
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
31 |
+
-----END CERTIFICATE-----
|
README.md
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
title: VizSum Pro
|
3 |
+
emoji: 📄
|
4 |
+
colorFrom: purple
|
5 |
+
colorTo: indigo
|
6 |
+
sdk: gradio
|
7 |
+
sdk_version: 4.19.2
|
8 |
+
app_file: app.py
|
9 |
+
pinned: false
|
10 |
+
---
|
11 |
+
|
12 |
+
|
13 |
+
# VizSum Pro
|
14 |
+
|
15 |
+
AI-powered summarizer that supports images, PDFs, and manual text.
|
16 |
+
|
17 |
+
- 🔍 OCR (Tesseract) for image text extraction
|
18 |
+
- 📄 PDF parser
|
19 |
+
- ✍️ Manual input
|
20 |
+
- 🎯 Mode selector for different summary styles
|
21 |
+
|
22 |
+
Built with ❤️ using Python + Gradio.
|
app.py
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
import ui
|
2 |
+
ui.demo.launch()
|
git
ADDED
File without changes
|
main
ADDED
File without changes
|
ocr_engine.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
import os
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
|
5 |
+
load_dotenv()
|
6 |
+
ocr_api_key = os.getenv("OCR_SPACE_API_KEY")
|
7 |
+
|
8 |
+
def extract_text_from_image(image_path):
|
9 |
+
try:
|
10 |
+
if not isinstance(image_path, str) or not os.path.exists(image_path):
|
11 |
+
return "❌ Geçersiz dosya yolu."
|
12 |
+
|
13 |
+
with open(image_path, 'rb') as image_file:
|
14 |
+
image_data = image_file.read()
|
15 |
+
|
16 |
+
response = requests.post(
|
17 |
+
url='https://api.ocr.space/parse/image',
|
18 |
+
files={'file': ('image.png', image_data)},
|
19 |
+
data={
|
20 |
+
'apikey': ocr_api_key.strip(),
|
21 |
+
'language': 'eng',
|
22 |
+
'isOverlayRequired': False,
|
23 |
+
'OCREngine': 2
|
24 |
+
}
|
25 |
+
)
|
26 |
+
|
27 |
+
# JSON dönüşüm kontrolü
|
28 |
+
try:
|
29 |
+
result = response.json()
|
30 |
+
except Exception:
|
31 |
+
return f"❌ API yanıtı JSON formatında değil:\n{response.text}"
|
32 |
+
|
33 |
+
if not isinstance(result, dict):
|
34 |
+
return f"❌ API çıktısı sözlük değil:\n{result}"
|
35 |
+
|
36 |
+
if result.get("IsErroredOnProcessing"):
|
37 |
+
return f"❌ OCR Hatası: {result.get('ErrorMessage', ['Bilinmeyen hata'])[0]}"
|
38 |
+
|
39 |
+
parsed_results = result.get("ParsedResults")
|
40 |
+
if not parsed_results or not isinstance(parsed_results, list):
|
41 |
+
return "❌ OCR sonucu boş veya biçimsiz."
|
42 |
+
|
43 |
+
return parsed_results[0].get('ParsedText', '').strip()
|
44 |
+
|
45 |
+
except Exception as e:
|
46 |
+
return f"❌ Sistemsel Hata: {str(e)}"
|
pdf_reader.py
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import fitz # PyMuPDF
|
2 |
+
|
3 |
+
def extract_text_from_pdf(pdf_input):
|
4 |
+
try:
|
5 |
+
if isinstance(pdf_input, str):
|
6 |
+
doc = fitz.open(pdf_input)
|
7 |
+
else:
|
8 |
+
doc = fitz.open(stream=pdf_input.read(), filetype="pdf")
|
9 |
+
|
10 |
+
text = "\n".join([page.get_text() for page in doc])
|
11 |
+
doc.close()
|
12 |
+
return text
|
13 |
+
|
14 |
+
except Exception as e:
|
15 |
+
return f"❌ PDF İşleme Hatası: {str(e)}"
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio
|
2 |
+
pytesseract
|
3 |
+
python-dotenv
|
4 |
+
requests
|
5 |
+
PyMuPDF
|
6 |
+
Pillow
|
summarizer.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import requests
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
|
5 |
+
load_dotenv()
|
6 |
+
api_key = os.getenv("OPENROUTER_API_KEY").strip()
|
7 |
+
|
8 |
+
|
9 |
+
def build_prompt(text, mode):
|
10 |
+
if "Sade" in mode:
|
11 |
+
instruction = "Bu metni herkesin anlayabileceği şekilde sadeleştir."
|
12 |
+
elif "Eleştir" in mode:
|
13 |
+
instruction = "Metni eleştir, eksiklerini ve güçlü yönlerini değerlendir."
|
14 |
+
elif "Başlık" in mode:
|
15 |
+
instruction = "Metne uygun birkaç başlık öner."
|
16 |
+
elif "Not" in mode:
|
17 |
+
instruction = "Metinden önemli notlar çıkar."
|
18 |
+
else:
|
19 |
+
instruction = "Kısa ve teknik bir özet ver."
|
20 |
+
|
21 |
+
return f"{instruction}\n\nMetin:\n{text}"
|
22 |
+
|
23 |
+
def summarize_text(text, mode):
|
24 |
+
url = "https://openrouter.ai/api/v1/chat/completions"
|
25 |
+
headers = {
|
26 |
+
"Authorization": f"Bearer {api_key}",
|
27 |
+
"Content-Type": "application/json"
|
28 |
+
}
|
29 |
+
|
30 |
+
data = {
|
31 |
+
"model": "openai/gpt-3.5-turbo",
|
32 |
+
"messages": [
|
33 |
+
{"role": "user", "content": build_prompt(text, mode)}
|
34 |
+
]
|
35 |
+
}
|
36 |
+
|
37 |
+
response = requests.post(url, headers=headers, json=data)
|
38 |
+
response.raise_for_status()
|
39 |
+
return response.json()['choices'][0]['message']['content']
|
summarizer_test.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from summarizer import summarize_text
|
2 |
+
|
3 |
+
text = "Tokenization, metni daha küçük parçalara ayırma işlemidir."
|
4 |
+
mode = "📘 Teknik Özet" # Varsayılan modlardan biri
|
5 |
+
|
6 |
+
print(summarize_text(text, mode))
|
tests/notepad_test_ocr.py
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
from ocr_engine import extract_text_from_image
|
2 |
+
|
3 |
+
print(extract_text_from_image("c:/Users/sinan/Desktop/vizsum-pro/test.png"))
|
tests/python_test_key.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from dotenv import load_dotenv
|
3 |
+
|
4 |
+
load_dotenv()
|
5 |
+
key = os.getenv("OCR_SPACE_API_KEY")
|
6 |
+
print(f"KEY: '{key}'")
|
tests/summarizer_test.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from summarizer import summarize_text
|
2 |
+
|
3 |
+
text = "Tokenization, metni daha küçük parçalara ayırma işlemidir."
|
4 |
+
mode = "📘 Teknik Özet" # Varsayılan modlardan biri
|
5 |
+
|
6 |
+
print(summarize_text(text, mode))
|
ui.py
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from ocr_engine import extract_text_from_image
|
3 |
+
from pdf_reader import extract_text_from_pdf
|
4 |
+
from summarizer import summarize_text
|
5 |
+
|
6 |
+
def process_input(pdf, image, manual_text, mode):
|
7 |
+
if pdf is not None:
|
8 |
+
text = extract_text_from_pdf(pdf)
|
9 |
+
elif image is not None:
|
10 |
+
text = extract_text_from_image(image)
|
11 |
+
elif manual_text.strip() != "":
|
12 |
+
text = manual_text
|
13 |
+
else:
|
14 |
+
return "Lütfen bir giriş türü seçin.", ""
|
15 |
+
|
16 |
+
|
17 |
+
summary = summarize_text(text, mode)
|
18 |
+
return text, summary
|
19 |
+
|
20 |
+
|
21 |
+
with gr.Blocks() as demo:
|
22 |
+
gr.Markdown("## 📚 VizSum Pro+: AI Destekli Özetleyici")
|
23 |
+
|
24 |
+
with gr.Row():
|
25 |
+
pdf_input = gr.File(label="📄 PDF Yükle", file_types=[".pdf"])
|
26 |
+
image_input = gr.Image(type="filepath", label="🖼️ Görsel Yükle")
|
27 |
+
|
28 |
+
manual_input = gr.Textbox(lines=5, label="✍️ Metni Manuel Gir")
|
29 |
+
|
30 |
+
# BURAYA AL
|
31 |
+
mode_selector = gr.Dropdown(
|
32 |
+
choices=["📘 Teknik Özet", "🧒 Sade Anlatım", "🧠 Eleştir ve Değerlendir", "📝 Başlık Çıkar", "📎 Not Formatı"],
|
33 |
+
label="🧩 Özetleme Modu",
|
34 |
+
value="📘 Teknik Özet"
|
35 |
+
)
|
36 |
+
|
37 |
+
with gr.Row():
|
38 |
+
submit_btn = gr.Button("Özetle")
|
39 |
+
|
40 |
+
with gr.Row():
|
41 |
+
text_output = gr.Textbox(label="📜 Metin")
|
42 |
+
summary_output = gr.Textbox(label="🧠 AI Özeti")
|
43 |
+
|
44 |
+
# EN SONDA KALACAK
|
45 |
+
submit_btn.click(
|
46 |
+
fn=process_input,
|
47 |
+
inputs=[pdf_input, image_input, manual_input, mode_selector],
|
48 |
+
outputs=[text_output, summary_output]
|
49 |
+
)
|
50 |
+
|
51 |
+
|
52 |
+
|
53 |
+
if __name__ == "__main__":
|
54 |
+
demo.launch(share=True)
|