115 lines
3.1 KiB
Python
115 lines
3.1 KiB
Python
"""Flask app to generate memes."""
|
|
|
|
import random
|
|
import os
|
|
import requests
|
|
from flask import Flask, render_template, abort, request
|
|
|
|
from QuoteEngine import Ingestor
|
|
from MemeEngine import MemeEngine
|
|
|
|
# Create the Flask application object. "__name__" tells Flask,
|
|
# where to find templates and static files.
|
|
app = Flask(__name__)
|
|
|
|
# Create a global MemeEngine instance that will write generated memes
|
|
# into "./static" so that the images can be served by the web server.
|
|
meme = MemeEngine("./static")
|
|
|
|
|
|
def setup():
|
|
"""Load all resources."""
|
|
quote_files = [
|
|
"./_data/DogQuotes/DogQuotesTXT.txt",
|
|
"./_data/DogQuotes/DogQuotesDOCX.docx",
|
|
"./_data/DogQuotes/DogQuotesPDF.pdf",
|
|
"./_data/DogQuotes/DogQuotesCSV.csv",
|
|
]
|
|
|
|
quotes = []
|
|
for file in quote_files:
|
|
if Ingestor.parse(file) is not None:
|
|
quotes.append(Ingestor.parse(file))
|
|
|
|
images_path = "./_data/photos/dog/"
|
|
|
|
imgs = []
|
|
for root, _, files in os.walk(images_path):
|
|
imgs = [os.path.join(root, name) for name in files]
|
|
|
|
return quotes, imgs
|
|
|
|
|
|
# Call setup() once at import time to preload quotes and images.
|
|
# These will be reused on every request.
|
|
quotes, imgs = setup()
|
|
|
|
|
|
@app.route("/")
|
|
def meme_rand():
|
|
"""Generate a random meme.
|
|
|
|
Steps:
|
|
- Pick a random image from imgs
|
|
- Pick a random "quote list" from quotes
|
|
- Pick a random quote from that list
|
|
- Generate a meme image with that quote and image
|
|
- Render a template to show the meme
|
|
"""
|
|
img = random.choice(imgs)
|
|
quote_list = random.choice(quotes)
|
|
quote = random.choice(quote_list)
|
|
path = meme.make_meme(img, quote.body, quote.author)
|
|
return render_template("meme.html", path=path)
|
|
|
|
|
|
@app.route("/create", methods=["GET"])
|
|
def meme_form():
|
|
"""User input for meme information.
|
|
|
|
This route renders a form where the user can input:
|
|
- image_url: URL of the source image
|
|
- body: quote text
|
|
- author: quote author
|
|
"""
|
|
return render_template("meme_form.html")
|
|
|
|
|
|
@app.route("/create", methods=["POST"])
|
|
def meme_post():
|
|
"""Create a user defined meme.
|
|
|
|
This route:
|
|
- Reads form data sent via POST from the meme_form page
|
|
- Downloads the image from the provided URL
|
|
- Saves it to a temporary file
|
|
- Passes that file to MemeEngine to generate a meme
|
|
- Deletes the temporary file
|
|
- Renders the final meme
|
|
"""
|
|
|
|
image_url = request.form.get("image_url", "").strip()
|
|
body = request.form.get("body", "").strip()
|
|
author = request.form.get("author", "").strip()
|
|
image = requests.get(image_url, timeout=5)
|
|
|
|
try:
|
|
tmp_file = f"tmp/{random.randint(0, 10000)}.jpg"
|
|
with open(tmp_file, "wb") as file:
|
|
file.write(image.content)
|
|
except OSError as e:
|
|
print("Failed to generate meme:", e)
|
|
path = None
|
|
if os.path.exists(tmp_file):
|
|
os.remove(tmp_file)
|
|
else:
|
|
path = meme.make_meme(tmp_file, body, author)
|
|
if os.path.exists(tmp_file):
|
|
os.remove(tmp_file)
|
|
finally:
|
|
return render_template("meme.html", path=path)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app.run()
|