recipes_api.getRecipes view updated for new
standards!
This commit is contained in:
parent
c7c8383baf
commit
df5b575e10
Binary file not shown.
@ -1839,3 +1839,6 @@
|
||||
2025-04-21 14:45:18.122865 --- ERROR --- DatabaseError(message='new row for relation "logins" violates check constraint "logins_email_check"DETAIL: Failing row contains (32, ScannerDeviceB, 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08, test, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, f, {}, device).',
|
||||
payload=('ScannerDeviceB', '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', 'test', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', False, '{}', 'device'),
|
||||
sql='INSERT INTO logins(username, password, email, favorites, unseen_pantry_items, unseen_groups, unseen_shopping_lists, unseen_recipes, seen_pantry_items, seen_groups, seen_shopping_lists, seen_recipes, sites, site_roles, system_admin, flags, row_type) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;')
|
||||
2025-04-26 18:29:30.532818 --- ERROR --- DatabaseError(message=''module' object is not callable. Did you mean: 'config.config(...)'?',
|
||||
payload=(10, 0),
|
||||
sql='SELECT *, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM main_recipe_items g WHERE rp_id = main_recipes.id) AS rp_items FROM main_recipes LIMIT %s OFFSET %s;')
|
||||
Binary file not shown.
Binary file not shown.
@ -23,3 +23,44 @@ def getModalSKUs(site, payload, convert=True):
|
||||
if rows and count:
|
||||
return rows, count
|
||||
return [], 0
|
||||
|
||||
def getRecipes(site:str, payload:tuple, convert=True):
|
||||
recordset = []
|
||||
count = 0
|
||||
with open("scripts/recipes/sql/getRecipes.sql", "r+") as file:
|
||||
sql = file.read().replace("%%site_name%%", site)
|
||||
with open(f"scripts/recipes/sql/getRecipesCount.sql", "r+") as file:
|
||||
sqlcount = file.read().replace("%%site_name%%", site)
|
||||
try:
|
||||
database_config = config.config()
|
||||
with psycopg2.connect(**database_config) as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(sql, payload)
|
||||
rows = cur.fetchall()
|
||||
if rows and convert:
|
||||
recordset = [postsqldb.tupleDictionaryFactory(cur.description, row) for row in rows]
|
||||
if rows and not convert:
|
||||
recordset = rows
|
||||
cur.execute(sqlcount)
|
||||
count = cur.fetchone()[0]
|
||||
except (Exception, psycopg2.DatabaseError) as error:
|
||||
raise postsqldb.DatabaseError(error, payload, sql)
|
||||
return recordset, count
|
||||
|
||||
def postRecipeUpdate(site, payload, convert=True):
|
||||
database_config = config.config()
|
||||
updated = ()
|
||||
with psycopg2.connect(**database_config) as conn:
|
||||
with conn.cursor() as cur:
|
||||
set_clause, values = postsqldb.updateStringFactory(payload['update'])
|
||||
with open("scripts/recipes/sql/postRecipeUpdate.sql") as file:
|
||||
sql = file.read().replace("%%site_name%%", site).replace("%%set_clause%%", set_clause)
|
||||
values.append(payload['id'])
|
||||
cur.execute(sql, values)
|
||||
|
||||
rows = cur.fetchone()
|
||||
if rows and convert:
|
||||
updated = postsqldb.tupleDictionaryFactory(cur.description, rows)
|
||||
elif rows and not convert:
|
||||
updated = rows
|
||||
return updated
|
||||
@ -5,13 +5,22 @@ from main import unfoldCostLayers
|
||||
from user_api import login_required
|
||||
import os
|
||||
import postsqldb, webpush
|
||||
from flasgger import swag_from
|
||||
from scripts.recipes import database_recipes
|
||||
from flask_restx import Api, fields
|
||||
|
||||
recipes_api = Blueprint('recipes_api', __name__)
|
||||
model_api = Api(recipes_api)
|
||||
|
||||
@recipes_api.route("/recipes")
|
||||
@login_required
|
||||
def recipes():
|
||||
"""This is the main endpoint to reach the webpage for a list of all recipes
|
||||
---
|
||||
responses:
|
||||
200:
|
||||
description: returns recipes/index.html with sites, current_site.
|
||||
"""
|
||||
sites = [site[1] for site in main.get_sites(session['user']['sites'])]
|
||||
return render_template("recipes/index.html",
|
||||
current_site=session['selected_site'],
|
||||
@ -19,7 +28,24 @@ def recipes():
|
||||
|
||||
@recipes_api.route("/recipe/<mode>/<id>")
|
||||
@login_required
|
||||
def recipe(mode, id):
|
||||
def recipe(id, mode='view'):
|
||||
"""This is the main endpoint to reach the webpage for a recipe's view or edit mode.
|
||||
---
|
||||
parameters:
|
||||
- name: mode
|
||||
in: path
|
||||
type: string
|
||||
required: true
|
||||
default: view
|
||||
- name: id
|
||||
in: path
|
||||
type: integer
|
||||
required: true
|
||||
default: all
|
||||
responses:
|
||||
200:
|
||||
description: Respondes with either the Edit or View webpage for the recipe.
|
||||
"""
|
||||
database_config = config()
|
||||
with psycopg2.connect(**database_config) as conn:
|
||||
units = postsqldb.UnitsTable.getAll(conn)
|
||||
@ -32,16 +58,22 @@ def recipe(mode, id):
|
||||
|
||||
@recipes_api.route('/recipes/getRecipes', methods=["GET"])
|
||||
def getRecipes():
|
||||
""" Get a subquery of recipes from the database by passing a page, limit
|
||||
---
|
||||
responses:
|
||||
200:
|
||||
description: limit of rows passed returned to requester
|
||||
"""
|
||||
recipes = []
|
||||
count=0
|
||||
if request.method == "GET":
|
||||
page = int(request.args.get('page', 1))
|
||||
limit = int(request.args.get('limit', 1))
|
||||
offset = (page-1)*limit
|
||||
database_config = config()
|
||||
site_name = session['selected_site']
|
||||
with psycopg2.connect(**database_config) as conn:
|
||||
recipes, count = postsqldb.RecipesTable.getRecipes(conn, site_name, (limit, offset), convert=True)
|
||||
return jsonify({'recipes': recipes, 'end': math.ceil(count/limit), 'error': False, 'message': 'bleh'})
|
||||
recipes, count = database_recipes.getRecipes(site_name, (limit, offset))
|
||||
return jsonify({'recipes': recipes, 'end': math.ceil(count/limit), 'error': False, 'message': 'fetch was successful!'})
|
||||
return jsonify({'recipes': recipes, 'end': math.ceil(count/limit), 'error': True, 'message': f'method is not allowed: {request.method}'})
|
||||
|
||||
@recipes_api.route('/recipe/getRecipe', methods=["GET"])
|
||||
def getRecipe():
|
||||
@ -75,6 +107,12 @@ def addRecipe():
|
||||
|
||||
@recipes_api.route('/recipe/getItems', methods=["GET"])
|
||||
def getItems():
|
||||
""" Pass along a page, limit, and search strings to get a pagination of items from the system
|
||||
---
|
||||
responses:
|
||||
200:
|
||||
description: Items were returned successfully!
|
||||
"""
|
||||
recordset = []
|
||||
count = {'count': 0}
|
||||
if request.method == "GET":
|
||||
@ -83,22 +121,35 @@ def getItems():
|
||||
search_string = request.args.get('search_string', 10)
|
||||
site_name = session['selected_site']
|
||||
offset = (page - 1) * limit
|
||||
recordset, count = database_recipes.getModalSKUs(site_name, (limit, offset))
|
||||
recordset, count = database_recipes.getModalSKUs(site_name, (search_string, limit, offset))
|
||||
print(recordset)
|
||||
return jsonify({"items":recordset, "end":math.ceil(count/limit), "error":False, "message":"items fetched succesfully!"})
|
||||
return jsonify({"items":recordset, "end":math.ceil(count/limit), "error":True, "message":"There was an error with this GET statement"})
|
||||
|
||||
|
||||
update_model = model_api.model('model', {
|
||||
'id': fields.Integer(min=1),
|
||||
'update': fields.Raw(required=True, description="all the data to be updated!")
|
||||
})
|
||||
|
||||
@recipes_api.route('/recipe/postUpdate', methods=["POST"])
|
||||
@model_api.expect(update_model)
|
||||
def postUpdate():
|
||||
""" This is an endpoint for updating an RecipeTuple in the sites recipes table
|
||||
---
|
||||
responses:
|
||||
200:
|
||||
description: The time was updated successfully!
|
||||
|
||||
Returns:
|
||||
dict: returns a dictionary containing the updated recipe object, error status, and a message to post for notifications
|
||||
"""
|
||||
recipe = {}
|
||||
if request.method == "POST":
|
||||
recipe_id = int(request.get_json()['recipe_id'])
|
||||
update = request.get_json()['update']
|
||||
database_config = config()
|
||||
site_name = session['selected_site']
|
||||
with psycopg2.connect(**database_config) as conn:
|
||||
recipe = postsqldb.RecipesTable.updateRecipe(conn, site_name, {'id': recipe_id, 'update': update}, convert=True)
|
||||
recipe = database_recipes.postRecipeUpdate(site_name, {'id': recipe_id, 'update': update})
|
||||
return jsonify({'recipe': recipe, 'error': False, 'message': 'Update of Recipe successful!'})
|
||||
return jsonify({'recipe': recipe, 'error': True, 'message': 'Update of Recipe unsuccessful!'})
|
||||
|
||||
|
||||
3
scripts/recipes/sql/getRecipes.sql
Normal file
3
scripts/recipes/sql/getRecipes.sql
Normal file
@ -0,0 +1,3 @@
|
||||
SELECT *,
|
||||
(SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM %%site_name%%_recipe_items g WHERE rp_id = %%site_name%%_recipes.id) AS rp_items
|
||||
FROM %%site_name%%_recipes LIMIT %s OFFSET %s;
|
||||
1
scripts/recipes/sql/getRecipesCount.sql
Normal file
1
scripts/recipes/sql/getRecipesCount.sql
Normal file
@ -0,0 +1 @@
|
||||
SELECT COUNT(*) FROM %%site_name%%_recipes;
|
||||
@ -1,2 +1,3 @@
|
||||
SELECT item.id, item.barcode, item.item_name FROM %%site_name%%_items item
|
||||
WHERE item.search_string LIKE '%%' || %s || '%%'
|
||||
LIMIT %s OFFSET %s;
|
||||
1
scripts/recipes/sql/postRecipeUpdate.sql
Normal file
1
scripts/recipes/sql/postRecipeUpdate.sql
Normal file
@ -0,0 +1 @@
|
||||
UPDATE %%site_name%%_recipes SET %%set_clause%% WHERE id=%s RETURNING *;
|
||||
15
webserver.py
15
webserver.py
@ -9,8 +9,11 @@ import database
|
||||
import postsqldb
|
||||
from webpush import trigger_push_notifications_for_subscriptions
|
||||
from scripts.recipes import recipes_api
|
||||
from flasgger import Swagger
|
||||
|
||||
|
||||
app = Flask(__name__, instance_relative_config=True)
|
||||
swagger = Swagger(app)
|
||||
UPLOAD_FOLDER = 'static/pictures'
|
||||
FILES_FOLDER = 'static/files'
|
||||
app.config.from_pyfile('application.cfg.py')
|
||||
@ -66,6 +69,18 @@ def inject_user():
|
||||
@app.route("/transactions/<id>")
|
||||
@login_required
|
||||
def transactions(id):
|
||||
"""This is the main endpoint to reach the webpage for an items transaction history
|
||||
---
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
type: integer
|
||||
required: true
|
||||
default: all
|
||||
responses:
|
||||
200:
|
||||
description: Returns the transactions.html webpage for the item with passed ID
|
||||
"""
|
||||
sites = [site[1] for site in main.get_sites(session['user']['sites'])]
|
||||
return render_template("items/transactions.html", id=id, current_site=session['selected_site'], sites=sites)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user