feat: Added add/remove ingredients sub commands to recipes
- feat: Added list recipe commands - feat: Added sample add ingredient template for recipe
This commit is contained in:
parent
05089108a9
commit
029ba35945
69
grocy/cli.py
69
grocy/cli.py
@ -9,6 +9,7 @@ from grocy.recipe import Recipe
|
||||
from grocy.table import Table
|
||||
from grocy.entity import Entity
|
||||
from grocy.stock import Stock
|
||||
from grocy.schema import get_schema
|
||||
import yaml
|
||||
from sys import exit
|
||||
from os import path
|
||||
@ -131,7 +132,7 @@ def edit(product_id, name):
|
||||
|
||||
for index, edited_product in enumerate(parsed_edited_products):
|
||||
edited_product['id'] = products[index]['id']
|
||||
Util.verify_integrity(edited_product, schema)
|
||||
util.verify_integrity(edited_product, schema)
|
||||
entity.update(edited_product, id=products[index]['id'])
|
||||
else:
|
||||
raise click.BadParameter('Missing PRODUCT_ID or QUERY')
|
||||
@ -332,6 +333,7 @@ def browse(fullscreen, recipe_id):
|
||||
logger.error(e)
|
||||
|
||||
|
||||
# TODO: revist this command
|
||||
@recipe.command()
|
||||
@click.option('--name', '-n', 'name')
|
||||
@click.argument('recipe_id', required=False)
|
||||
@ -342,11 +344,10 @@ def edit(recipe_id, name, template):
|
||||
cfg = Configuration()
|
||||
util = Util(cfg=cfg)
|
||||
cfg.load()
|
||||
loaded_template = cfg.templates('recipe/edit')
|
||||
if template:
|
||||
loaded_template = cfg.templates(template)
|
||||
else:
|
||||
loaded_template = cfg.templates('recipe/list')
|
||||
loaded_template = cfg.templates('recipe/edit')
|
||||
|
||||
entity = Entity(name='recipes')
|
||||
if recipe_id:
|
||||
@ -368,6 +369,7 @@ def edit(recipe_id, name, template):
|
||||
click.echo('Could not find recipe')
|
||||
return
|
||||
|
||||
# Build hydrated recipe entity object for editing
|
||||
data = {'recipes': []}
|
||||
for recipe_entity in recipe_entities:
|
||||
entry = {'fields': recipe_entity, 'meta': []}
|
||||
@ -386,17 +388,74 @@ def edit(recipe_id, name, template):
|
||||
if edited_recipes is None:
|
||||
return
|
||||
|
||||
schema = []
|
||||
schema.append(Entity(name='products').schema)
|
||||
schema.append(Entity(name='locations').schema)
|
||||
schema.append(Entity(name='quantity_units').schema)
|
||||
schema.append(Entity(name='recipes').schema)
|
||||
|
||||
parsed_edited_recipes = util.load_yaml(edited_recipes)
|
||||
for index, edited_recipe in enumerate(parsed_edited_recipes):
|
||||
schema = entity.schema
|
||||
edited_recipe['id'] = recipe_entities[index]['id']
|
||||
# Util.verify_integrity(edited_recipe, schema)
|
||||
entity.update(edited_recipe, id=recipe[index]['id'])
|
||||
util.verify_integrity(edited_recipe, schema)
|
||||
entity.update(edited_recipe, id=edited_recipe['id'])
|
||||
|
||||
else:
|
||||
raise click.BadParameter('Missing RECIPE_ID or QUERY')
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
raise e
|
||||
@recipe.command()
|
||||
@click.argument('recipe_id', required=True)
|
||||
@click.option('-t', 'template')
|
||||
def add_ingredient(recipe_id, template):
|
||||
logger = logging.getLogger('cli.recipe.add_ingredient')
|
||||
try:
|
||||
cfg = Configuration()
|
||||
util = Util(cfg=cfg)
|
||||
cfg.load()
|
||||
if template:
|
||||
loaded_template = cfg.templates(template)
|
||||
else:
|
||||
loaded_template = cfg.templates('recipe/add-ingredient')
|
||||
|
||||
# Verify that recipe exist
|
||||
try:
|
||||
entity = Entity(name='recipes')
|
||||
entity.get(id=recipe_id)
|
||||
except Exception:
|
||||
raise Exception('Could not find recipe {}'.format(recipe_id))
|
||||
|
||||
# TODO: Meta has to be added to validate against know fields/properties
|
||||
# Add quantity_units to meta
|
||||
ingredient = click.edit(loaded_template.render(), extension='.yml')
|
||||
if ingredient is None:
|
||||
return
|
||||
parsed_new_ingredient = util.load_yaml(ingredient)[0]
|
||||
parsed_new_ingredient['recipe_id'] = recipe_id
|
||||
|
||||
if template == 'debug':
|
||||
click.echo(parsed_new_ingredient)
|
||||
return
|
||||
entity = Entity(name='recipes_pos')
|
||||
entity.create(parsed_new_ingredient)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
||||
|
||||
@recipe.command()
|
||||
@click.argument('recipe_id', required=True)
|
||||
@click.argument('ingredient_id', required=True)
|
||||
def remove_ingredient(recipe_id, ingredient_id):
|
||||
logger = logging.getLogger('cli.recipe.remove_ingredient')
|
||||
try:
|
||||
entity = Entity(name='recipes_pos')
|
||||
entity.delete(ingredient_id)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
||||
#@main.command()
|
||||
#def shopping():
|
||||
|
@ -14,7 +14,8 @@ class Entity(object):
|
||||
'stock': 'StockEntry',
|
||||
'product_groups':'ProductGroup',
|
||||
'locations': 'Location',
|
||||
'quantity_units': 'QuantityUnit'
|
||||
'quantity_units': 'QuantityUnit',
|
||||
'recipes': 'Recipe'
|
||||
}
|
||||
|
||||
def __init__(self, name, **props):
|
||||
@ -65,8 +66,6 @@ class Entity(object):
|
||||
if type(value) == bool:
|
||||
entity[key] = '1' if value else '0'
|
||||
|
||||
print('{}'.format(entity))
|
||||
|
||||
request = Request('post', url, resource=entity)
|
||||
try:
|
||||
return request.send()
|
||||
@ -87,6 +86,19 @@ class Entity(object):
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
||||
def delete(self, id=None):
|
||||
if id is None:
|
||||
raise Exception('id property is required to delete entity')
|
||||
logger = logging.getLogger('entity.delete')
|
||||
url = self.RESOURCE_URL_TEMPLATE.format(domain=self.conf.domain, entity=self.name, objectId=id)
|
||||
|
||||
request = Request('delete', url)
|
||||
try:
|
||||
return request.send()
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
||||
@property
|
||||
def schema(self):
|
||||
logger = logging.getLogger('entity.schema')
|
||||
|
@ -11,7 +11,6 @@ class Recipe(object):
|
||||
GET_RECIPES_FULFILLMENT_URL_TEMPLATE = '{domain}/api/recipes/fulfillment'
|
||||
GET_RECIPE_FULFILLMENT_URL_TEMPLATE = '{domain}/api/recipes/{recipeId}/fulfillment'
|
||||
GET_RECIPES_POS_FULFILLMENT_URL_TEMPLATE = '{domain}/api/recipes/{recipeId}/pos/fulfillment'
|
||||
GET_RECIPE_POS_FULFILLMENT_URL_TEMPLATE = '{domain}/api/recipes/{recipeId}/pos/{recipePosId}/fulfillment'
|
||||
|
||||
def __init__(self, id=None):
|
||||
self.conf = Configuration()
|
||||
@ -104,3 +103,4 @@ class Recipe(object):
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
||||
|
@ -10,7 +10,8 @@ SCHEMA_MODEL_MAP = {
|
||||
'product_groups': 'ProductGroup',
|
||||
'locations': 'Location',
|
||||
'quantity_units': 'QuantityUnit',
|
||||
'recipe_fulfillment': 'RecipeFulfillmentResponse'
|
||||
'recipe_fulfillment': 'RecipeFulfillmentResponse',
|
||||
'recipe_pos_fulfillment': 'RecipePosFulfillmentResponse'
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,15 +16,24 @@ class Util(object):
|
||||
data_list = list(generator)
|
||||
return data_list
|
||||
|
||||
|
||||
def verify_integrity(new_data, schema):
|
||||
def verify_integrity(self, new_data, schema):
|
||||
logger = logging.getLogger('util.verify_integrity')
|
||||
try:
|
||||
# Verify that updated fields exist
|
||||
schema_keys = schema['properties'].keys()
|
||||
if type(schema) != list:
|
||||
schemas = [schema]
|
||||
else:
|
||||
schemas = schema
|
||||
|
||||
keys_not_found = []
|
||||
for current_schema in schemas:
|
||||
schema_keys = current_schema['properties'].keys()
|
||||
for prop in new_data.keys():
|
||||
if prop not in schema_keys:
|
||||
raise Exception('{} is not a valid field'.format(prop))
|
||||
keys_not_found.append(prop)
|
||||
print('{}'.format(keys_not_found))
|
||||
if len(keys_not_found) > 0:
|
||||
raise Exception('{} is not valid property'.format(keys_not_found.join(', ')))
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
raise e
|
||||
|
8
templates/recipe/add-ingredient.yml
Normal file
8
templates/recipe/add-ingredient.yml
Normal file
@ -0,0 +1,8 @@
|
||||
product_id:
|
||||
amount:
|
||||
qu_id:
|
||||
only_check_single_unit_in_stock:
|
||||
not_check_stock_fulfilment:
|
||||
variable_amount:
|
||||
ingredient_group:
|
||||
note:
|
@ -1,7 +1,8 @@
|
||||
{% from 'recipe/macro.yml' import render_recipe_fulfilment %}
|
||||
{% for recipe in grocy.recipes %}
|
||||
id: {{ recipe.fields.id }}
|
||||
name: {{ recipe.fields.name }}
|
||||
servings: {{ recipe.fields.base_servings }}
|
||||
base_servings: {{ recipe.fields.base_servings }}
|
||||
required_fulfilled: {{ render_recipe_fulfilment(recipe.fields.fulfillment, grocy.meta.fa_icons) }}
|
||||
description: |-
|
||||
{{ recipe.fields.description }}
|
||||
|
Loading…
Reference in New Issue
Block a user