From 70a86fc06fe93a9658c3eeda970b5c2d89f238f6 Mon Sep 17 00:00:00 2001 From: Lucas Jensen Date: Thu, 12 May 2022 09:12:30 -0700 Subject: [PATCH] Added microservice to download PDFs --- Procfile | 1 - main.py | 35 ++++++++++--- pdf-generator.py | 117 ++++++++++++++++++++++++++++++++++++++++++ recipe.py | 2 +- recipe.txt | 1 + recipes.json | 28 ++++++++++ recipes/recipes.json | 15 ------ runtime.txt | 1 - templates/recipe.html | 3 ++ 9 files changed, 179 insertions(+), 24 deletions(-) delete mode 100644 Procfile create mode 100644 pdf-generator.py create mode 100644 recipe.txt create mode 100644 recipes.json delete mode 100644 recipes/recipes.json delete mode 100644 runtime.txt diff --git a/Procfile b/Procfile deleted file mode 100644 index dc46f1b..0000000 --- a/Procfile +++ /dev/null @@ -1 +0,0 @@ -web: gunicorn main:app \ No newline at end of file diff --git a/main.py b/main.py index d54e8b5..db690e5 100644 --- a/main.py +++ b/main.py @@ -3,8 +3,9 @@ Portfolio Project for CS361 Spring 2022 Written by Lucas Jensen Last updated 5/12 for Assignment 1 """ -from flask import Flask, redirect, render_template, request +from flask import Flask, redirect, render_template, request, send_file from recipe import Recipe, RecipeBook +from time import sleep app = Flask(__name__) book = RecipeBook() @@ -25,17 +26,39 @@ def recipes_page(): @app.route('/recipes/<_id>', methods=['GET', 'POST']) def recipe_page(_id): - recipe = book.find_by_id(_id) + recipe = book.find_by_id(str(_id)) if request.method == 'POST': - scale = request.form.get('scale') - new = recipe.scale(scale) - new_id = book.add_recipe(new) - return redirect(f'/recipes/{new_id}') + if 'scale' in request.form: + scale = request.form.get('scale') + new = recipe.scale(scale) + new_id = book.add_recipe(new) + return redirect(f'/recipes/{new_id}') + + else: + path = write_txt(_id) + sleep(0.5) + return send_file(path, as_attachment=True) return render_template("recipe.html", content=recipe, _id=_id) +def write_txt(_id): + """ + writes to the txt file to have the microservice make a selected pdf + :return: + """ + print(_id) + with open('recipe.txt', 'w') as txt_file: + txt_file.write(_id) + + return f"recipe{_id}.pdf" + + +# app.route('/recipes//download') +# def + + @app.route('/recipes/<_id>/delete') def delete_recipe(_id): book.find_and_delete(_id) diff --git a/pdf-generator.py b/pdf-generator.py new file mode 100644 index 0000000..d92fe52 --- /dev/null +++ b/pdf-generator.py @@ -0,0 +1,117 @@ +""" +Reads a key from a txt file. Searches a json file with the key. +Exports the key values in a pdf form. Writes the PDF file name +to the txt file. +""" + +import json +from fpdf import FPDF +from time import sleep + +TXTFILE = 'recipe.txt' # update to txt file name for read +JSONFILE = 'recipes.json' # update to json file name for read +CATEGORY = 'recipe' # update category to preceed number in PDF file name + + +def create_pdf() -> object: + """ + Create pdf object from FPDF class + :return: PDF object + """ + pdf = FPDF() + pdf.add_page() + pdf.set_font("Arial", size=15) + return pdf + + +def read_txt(file_name) -> object: + """ + Open/reads txt file argument + :param file_name(str) + :return: file content + """ + with open(file_name, 'r') as txt_file: + content = txt_file.read() + return content + + +def load_json(file_name) -> object: + """ + Opens/loads json file argument + :param file_name(str) + :return: file contentquit + """ + with open(file_name, 'r') as json_file: + content = json.load(json_file) + return content + + +def add_pdf_content(txt_content, json_content, pdf) -> None: + """ + Searches json content with key from txt_content. Adds relevant data to pdf object. + :param txt_content: txt file content for json search + :param json_content: json file content to search + :param pdf: pdf object to update + :return: none + """ + for key, value in json_content.items(): + if key == txt_content: + for key, value in value.items(): + if isinstance(value, dict): + pdf.cell(200, 10, txt=key.title() + ":", ln=1, align='C') + for key, value in value.items(): + pdf.cell(200, 10, txt=key + ": " + str(value), ln=1, align='C') + else: + pdf.cell(200, 10, txt=key.title() + ": " + str(value), ln=1, align='C') + + +def generate_pdf(category_name, txt_content, pdf) -> str: + """ + Generate pdf file from pdf object with relevant naming 'category + key from txt file' + :param category_name: category for pdf title + :param txt_content: txt identifier for pdf title + :param pdf: pdf object to generate pdf file + :return: pdf file name + """ + pdf.output(f"{category_name}{txt_content}.pdf") + return f"{category_name}{txt_content}.pdf" + + +def write_txt(file_name, pdf_file) -> None: + """ + Write generated pdf file name to txt file + :param file_name: txt file(str) to write to + :param pdf_file: pdf file name to write(str) + :return: none + """ + with open(file_name, 'w') as txt_file: + txt_file.write(pdf_file) + + +def main(): + initial_content = read_txt(TXTFILE) # initialize variables for while loop comparison + + while True: + updated_content = read_txt(TXTFILE) + # watch for txt change + if updated_content != initial_content: + if updated_content == 'QUIT': # exit program upon cue + break + + pdf = create_pdf() # create pdf object for file generation + + json_content = load_json(JSONFILE) # load json content for data search + + add_pdf_content(updated_content, json_content, pdf) # update pdf object with data + + pdf_file_name = generate_pdf(CATEGORY, updated_content, pdf) # generate pdf file with appropriate name + + write_txt(TXTFILE, pdf_file_name) # write pdf file name to txt file + + initial_content = read_txt(TXTFILE) # update comparison variable + + sleep(.25) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/recipe.py b/recipe.py index cc800df..b1ef51f 100644 --- a/recipe.py +++ b/recipe.py @@ -8,7 +8,7 @@ Last updated 5/12 import json from pprint import pprint -JSON_FILE = "recipes/recipes.json" +JSON_FILE = "recipes.json" class RecipeBook: diff --git a/recipe.txt b/recipe.txt new file mode 100644 index 0000000..78df172 --- /dev/null +++ b/recipe.txt @@ -0,0 +1 @@ +recipe1.pdf \ No newline at end of file diff --git a/recipes.json b/recipes.json new file mode 100644 index 0000000..129889a --- /dev/null +++ b/recipes.json @@ -0,0 +1,28 @@ +{ + "0": { + "quantity": "2", + "name": "Sourdough", + "ingredients": { + "AP Flour": 500, + "WW Flour": 500, + "Rye Flour": 0, + "Water": 0, + "Salt": 0, + "Yeast": 0, + "Starter": 0 + } + }, + "1": { + "quantity": "2", + "name": "Sourdough * 1.0", + "ingredients": { + "AP Flour": 500, + "WW Flour": 500, + "Rye Flour": 0, + "Water": 0, + "Salt": 0, + "Yeast": 0, + "Starter": 0 + } + } +} \ No newline at end of file diff --git a/recipes/recipes.json b/recipes/recipes.json deleted file mode 100644 index a68bee6..0000000 --- a/recipes/recipes.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "0": { - "quantity": "2", - "name": "Sourdough", - "ingredients": { - "AP Flour": 500, - "WW Flour": 500, - "Rye Flour": 0, - "Water": 0, - "Salt": 0, - "Yeast": 0, - "Starter": 0 - } - } -} \ No newline at end of file diff --git a/runtime.txt b/runtime.txt deleted file mode 100644 index 333d904..0000000 --- a/runtime.txt +++ /dev/null @@ -1 +0,0 @@ -python-3.10.0 \ No newline at end of file diff --git a/templates/recipe.html b/templates/recipe.html index 05cf228..ff28159 100644 --- a/templates/recipe.html +++ b/templates/recipe.html @@ -33,6 +33,9 @@ +
+ +
{% endblock %} \ No newline at end of file