Sum / app.py
harshdhane's picture
Update app.py
87772f4 verified
Raw
History Blame Contribute Delete
7 kB
import os
import io
from flask import Flask, render_template, request, jsonify, send_file
from werkzeug.utils import secure_filename
import PyPDF2
from io import BytesIO
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
import nltk
from nltk.tokenize import sent_tokenize, word_tokenize
from nltk.corpus import stopwords
from collections import defaultdict
import heapq
import tempfile
import json
# ==============================
# FIXED NLTK DOWNLOAD SECTION
# ==============================
def download_nltk_resources():
resources = ['punkt', 'punkt_tab', 'stopwords']
for resource in resources:
try:
nltk.data.find(f'tokenizers/{resource}')
except LookupError:
try:
nltk.data.find(f'corpora/{resource}')
except LookupError:
nltk.download(resource)
download_nltk_resources()
# ==============================
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max file size
app.config['UPLOAD_FOLDER'] = tempfile.gettempdir()
app.config['SECRET_KEY'] = 'your-secret-key-here'
ALLOWED_EXTENSIONS = {'pdf'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def extract_text_from_pdf(pdf_file):
"""Extract text from uploaded PDF file"""
pdf_reader = PyPDF2.PdfReader(pdf_file)
text = ""
for page in pdf_reader.pages:
page_text = page.extract_text()
if page_text:
text += page_text + "\n"
return text
def summarize_text(text, num_sentences=5):
"""Summarize text using frequency-based scoring"""
sentences = sent_tokenize(text)
if len(sentences) <= num_sentences:
return text
stop_words = set(stopwords.words('english'))
words = word_tokenize(text.lower())
words = [word for word in words if word.isalnum() and word not in stop_words]
word_freq = defaultdict(int)
for word in words:
word_freq[word] += 1
sentence_scores = defaultdict(int)
for i, sentence in enumerate(sentences):
sentence_words = word_tokenize(sentence.lower())
for word in sentence_words:
if word in word_freq:
sentence_scores[i] += word_freq[word]
top_sentences = heapq.nlargest(num_sentences, sentence_scores, key=sentence_scores.get)
top_sentences.sort()
summary = [sentences[i] for i in top_sentences]
return ' '.join(summary)
def analyze_pdf_statistics(text):
"""Analyze PDF and return statistics"""
sentences = sent_tokenize(text)
words = word_tokenize(text)
characters = len(text)
return {
'page_count': text.count('\f') + 1,
'sentence_count': len(sentences),
'word_count': len(words),
'character_count': characters,
'avg_sentence_length': round(len(words) / len(sentences), 2) if sentences else 0,
'avg_word_length': round(sum(len(word) for word in words) / len(words), 2) if words else 0
}
def create_summary_pdf(summary, filename="summary.pdf"):
"""Create a downloadable PDF from summary"""
buffer = BytesIO()
pdf = canvas.Canvas(buffer, pagesize=letter)
pdf.setTitle("PDF Summary")
pdf.setFont("Helvetica-Bold", 16)
pdf.drawString(72, 750, "PDF Document Summary")
pdf.line(72, 745, 540, 745)
pdf.setFont("Helvetica", 12)
y_position = 720
max_width = 500
words = summary.split()
line = []
for word in words:
line.append(word)
test_line = ' '.join(line)
if pdf.stringWidth(test_line, "Helvetica", 12) > max_width:
line.pop()
pdf.drawString(72, y_position, ' '.join(line))
y_position -= 20
line = [word]
if y_position < 50:
pdf.showPage()
pdf.setFont("Helvetica", 12)
y_position = 750
if line:
pdf.drawString(72, y_position, ' '.join(line))
pdf.save()
buffer.seek(0)
return buffer
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload_pdf():
if 'pdf_file' not in request.files:
return jsonify({'error': 'No file uploaded'}), 400
file = request.files['pdf_file']
if file.filename == '':
return jsonify({'error': 'No file selected'}), 400
if not allowed_file(file.filename):
return jsonify({'error': 'Only PDF files are allowed'}), 400
try:
text = extract_text_from_pdf(file)
if not text.strip():
return jsonify({'error': 'Could not extract text from PDF. The PDF might be scanned or image-based.'}), 400
summary_ratio = float(request.form.get('summary_ratio', 0.3))
total_sentences = len(sent_tokenize(text))
num_sentences = max(3, int(total_sentences * summary_ratio))
summary = summarize_text(text, num_sentences)
stats = analyze_pdf_statistics(text)
original_words = len(word_tokenize(text))
summary_words = len(word_tokenize(summary))
compression_ratio = (
((original_words - summary_words) / original_words) * 100
if original_words > 0 else 0
)
return jsonify({
'success': True,
'summary': summary,
'statistics': stats,
'compression_ratio': round(compression_ratio, 2),
'summary_length': summary_words,
'filename': secure_filename(file.filename)
})
except Exception as e:
return jsonify({'error': f'Error processing PDF: {str(e)}'}), 500
@app.route('/download', methods=['POST'])
def download_summary():
data = request.json
summary = data.get('summary', '')
filename = data.get('filename', 'summary.pdf')
if not summary:
return jsonify({'error': 'No summary to download'}), 400
try:
pdf_buffer = create_summary_pdf(summary, filename)
return send_file(
pdf_buffer,
as_attachment=True,
download_name=filename.replace('.pdf', '_summary.pdf'),
mimetype='application/pdf'
)
except Exception as e:
return jsonify({'error': f'Error creating PDF: {str(e)}'}), 500
@app.route('/export', methods=['POST'])
def export_summary():
data = request.json
summary = data.get('summary', '')
if not summary:
return jsonify({'error': 'No summary to export'}), 400
return send_file(
BytesIO(summary.encode()),
as_attachment=True,
download_name='summary.txt',
mimetype='text/plain'
)
if __name__ == '__main__':
os.makedirs('uploads', exist_ok=True)
os.makedirs('templates', exist_ok=True)
os.makedirs('static', exist_ok=True)
print("Starting PDF Summarizer Server...")
print("Open your browser and navigate to: http://localhost:5000")
app.run(debug=True, host='0.0.0.0', port = 7860)