from flask import Flask, request, render_template, current_app, send_file import json import zipfile import fitz # PyMuPDF import io from weasyprint import HTML, CSS from bs4 import BeautifulSoup import requests def read_css_file(): with current_app.open_resource('templates/passage.css') as f: content = f.read().decode('utf-8') return content app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def index(): reference = '' version = '' verse_html = '' error = 'No error.' if request.method == 'POST': reference = request.form.get('scripture_reference') version = request.form.get('version') # Map version to ESV Bible ID bible_id = { 'NRSV': 'nrsv', 'NIV': 'niv', 'NLT': 'nlt' }.get(version) filenameref = reference.replace(' ', '_').replace(':', '_') if bible_id and reference: webfriendlyref=reference.replace(' ','%20').replace(':','%3A') url = f'https://www.biblegateway.com/passage/?search={webfriendlyref}&version={bible_id}' print(url) try: response = requests.get(url) #response.raise_for_status() verse = response.text except request.RequestException as e: error = f"Error fetching from Bible Gateway: {str(e)}" else: error = "Please provide both a reference and a version." soup = BeautifulSoup(verse, 'html.parser') verse_html = '' verse_text = '' for sp in soup.find_all('div',class_='footnotes'): sp.decompose() for sp in soup.find_all('sup',class_='footnote'): sp.decompose() for sp in soup.find_all('sup',class_='crossreference'): sp.decompose() for sp in soup.find_all('a',class_='full-chap-link'): sp.decompose() for sp in soup.find_all('div',class_='crossrefs'): sp.decompose() for sp in soup.find_all('h2'): sp.decompose() for sp in soup.find_all('div',class_='passage-content'): verse_html = verse_html + sp.prettify() verse_text = verse_text + sp.get_text() #verse_html = "".format(read_css_file()) + verse_html + '' verse_html = ""+ verse_html + '' print(verse_html) pdf_data=HTML(string=verse_html).write_pdf( stylesheets=[CSS(string=read_css_file())] ) doc = fitz.open(stream=pdf_data, filetype="pdf") memory_file = io.BytesIO() # Create the zip file in the buffer with zipfile.ZipFile(memory_file, 'w', zipfile.ZIP_DEFLATED) as zf: for page_index in range(len(doc)): page = doc.load_page(page_index) pix = page.get_pixmap(dpi=240) # Convert the rendered image into PNG bytes png_bytes = pix.tobytes("png") # You can now send png_bytes to a response or store it in a DB print(f"Page {page_index} is {len(png_bytes)} bytes.") zf.writestr("{}/{}-slide-number-{:02d}.png".format(filenameref, filenameref, page_index), png_bytes) doc.close() # Crucial step: rewind the buffer position to the beginning so the file can be read for download memory_file.seek(0) # Send the in-memory file using Flask's send_file return send_file( memory_file, mimetype='application/zip', as_attachment=True, download_name='{}.zip'.format(filenameref) # Use download_name for modern Flask versions ) print(f"Reference: {reference}, Version: {version}, Text: {verse_text}, Error: {error}") return render_template('index.html', reference=reference, version=version, verse_html=verse_html, error=error) if __name__ == '__main__': app.run()