diff --git a/grocy/cli.py b/grocy/cli.py index f941c01..d4fbbcf 100644 --- a/grocy/cli.py +++ b/grocy/cli.py @@ -21,14 +21,6 @@ PROJ_DIR = path.join(path.dirname(path.realpath(__file__))) TEMPLATE_LOADER = Environment(loader=FileSystemLoader('templates'), trim_blocks=True, lstrip_blocks=True) -def __validate_token(cfg): - # Validate token - if hasattr(cfg, 'token') or cfg['token'] is None: - click.echo('No token was found. Please add your token to the config file', err=True) - #logger.error('No token was found. Please add your token') - exit(1) - - @click.group() def main(): cfg = Configuration() @@ -65,15 +57,49 @@ def stock(ctx): logger = logging.getLogger('cli.stock') if ctx.invoked_subcommand is None: try: - entity = Stock() - stocks = entity.get() - table = Table(stocks=stocks) + stock = Stock() + table = Table(stocks=stock.products) click.echo(table.stock) except Exception as e: logger.error(e) raise e +@main.group(invoke_without_command=True) +@click.pass_context +@click.argument('product_id', required=False) +def product(ctx, product_id): + logger = logging.getLogger('cli.product') + try: + if product_id: + stock = Stock() + product = stock.get_product(product_id) + # Need to get quantity_unit + table = Table(entry=product) + click.echo(table.product) + else: + click.echo(ctx.get_help()) + except Exception as e: + logger.error(e) + raise e + +#@product.command('list') +#@click.argument('query', required=False) +#def view(query, product_id): +# logger = logging.getLogger('cli.product.view') + +# try: +# if product_id: +# entity = Entity(name='product') +# product = entity.get(id=product_id) +# table = Table(product=product) +# click.echo(table.product) +# else: +# except Exception as e: +# logger.error(e) +# raise e + + @main.command() def shopping(): logger = logging.getLogger('cli.shopping') @@ -88,34 +114,55 @@ def shopping(): @main.group() -def ingredient(ctx): +def ingredient(): pass @ingredient.command('add') -@click.option('-r', '--recipe_id') -def add(ctx, recipe_id): +@click.argument('query') +@click.argument('recipe_id') +@click.option('--amount', '-a', 'amount', default=1, type=int) +@click.option('--group', '-g', type=str, default='') +@click.option('--variable-amount', '--va', 'variable_amount', default=None, type=float) +@click.option('--in-stock', '--is', 'in_stock', default=False) +@click.option('--disable-fulfillment', '--df', 'disable_fulfillment', default=False) +@click.option('--note', '-n', 'note', multiple=True, default='', type=str) +@click.option('--no-edit', '--ne', 'no_edit', default=False) +def add(query, recipe_id, amount, group, variable_amount, in_stock, disable_fulfillment, note, no_edit): logger = logging.getLogger('cli.ingredient.add') try: loaded_template = TEMPLATE_LOADER.get_template('ingredient_add.yml') + new_ingredient = {} - if recipe_id: - entity = Entity(name='recipes') - recipe = entity.get(id=recipe_id) - new_ingredient = click.edit(loaded_template.render(recipe)) - parsed_new_ingredient = yaml.safe_load(new_ingredient) - else: - new_ingredient = click.edit(loaded_template.render()) - parsed_new_ingredient = yaml.safe_load(new_ingredient) - if parsed_new_ingredient['recipe_id']: - raise Exception('Recipe id is not defined') + entity = Entity(name='recipes') + recipe = entity.get(id=recipe_id) + + if not recipe: + raise click.BadParameter(message='recipe {id} does not exist', param='recipe_id', + param_hint='Use `grocy recipes ls` to get a list of recipes') + + entity = Entity(name='products') + product = entity.findOne(query) + new_ingredient['product_id'] = product['id'] + + new_ingredient['amount'] = amount + new_ingredient['group'] = group + new_ingredient['variable_amount'] = variable_amount + new_ingredient['only_check_single_unit_in_stock'] = "1" if in_stock else "0" + new_ingredient['not_check_stock_fulfillment'] = "1" if disable_fulfillment else "0" + new_ingredient['note'] = note + + if not no_edit: + new_ingredient = click.edit(loaded_template.render(new_ingredient)) + + parsed_new_ingredient = yaml.safe_load(new_ingredient) + entity = Entity(name='recipes_pos') + #entity.create(parsed_new_ingredient) - if new_ingredient: - entity = Entity(name='ingredients', **parsed_new_ingredient) - entity.create() except Exception as e: logger.error(e) + raise e @main.group() @@ -138,6 +185,7 @@ def ls(): logger.error(e) raise e + @recipe.command('edit') @click.argument('recipe_id') def edit(recipe_id): diff --git a/grocy/conf.py b/grocy/conf.py index 8d606fa..3de3150 100644 --- a/grocy/conf.py +++ b/grocy/conf.py @@ -1,12 +1,17 @@ from os import path, chmod, makedirs +from shutil import copy from yaml import safe_load, dump +from jinja2 import Environment, FileSystemLoader from copy import deepcopy class Configuration(object): # TODO: Figure out how to handle windows config CONFIG_DIR = path.expanduser('~/.config/grocy') + USER_TEMPLATE_DIR = path.expanduser('~/.config/grocy/templates') CONFIG_FILE = CONFIG_DIR + '/config.yml' + PROJ_DIR = path.join(path.dirname(path.realpath(__file__))) + PROJ_TEMPLATE_DIR = '{}/templates'.format(PROJ_DIR) API_KEY_HEADER = 'GROCY-API-KEY' DEFAULT_CFG = { 'logger': { @@ -72,6 +77,11 @@ class Configuration(object): fd.write(dump_cfg) chmod(self.CONFIG_DIR, 0o755) + # Create template directory + makedirs(self.USER_TEMPLATE_DIR) + copy(self.PROJ_TEMPLATE_DIR, self.USER_TEMPLATE_DIR) + + @property def exists(self): return path.exists(self.CONFIG_FILE) @@ -83,3 +93,12 @@ class Configuration(object): self.update(data) else: self.create() + + def templates(self, name): + try: + TEMPLATE_LOADER = Environment(loader=FileSystemLoader([self.USER_TEMPLATE_DIR, self.PROJ_TEMPLATE_DIR]), + trim_blocks=True, lstrip_blocks=True) + return TEMPLATE_LOADER.get_template(name) + except Exception as e: + raise e + diff --git a/grocy/entity.py b/grocy/entity.py index 624a50a..3860b07 100644 --- a/grocy/entity.py +++ b/grocy/entity.py @@ -31,7 +31,7 @@ class Entity(object): logger = logging.getLogger('entity.add') url = self.RESOURCE_URL_TEMPLATE - request = Request('post', url) + request = Request('post', url, entity) try: return request.send() except Exception as e: diff --git a/grocy/stock.py b/grocy/stock.py index 779c662..dabf765 100644 --- a/grocy/stock.py +++ b/grocy/stock.py @@ -5,14 +5,13 @@ import logging class Stock(object): GET_STOCK_URL_TEMPLATE = '{api}/stock' + GET_STOCK_PRODUCT_DETAIL_TEMPLATE = '{api}/stock/products/{product_id}' def __init__(self): self.conf = Configuration() self.conf.load() - def get(self): - logger = logging.getLogger('stock.get') - url = self.GET_STOCK_URL_TEMPLATE.format(api=self.conf.api) + def __get_resources(self, url, logger): request = Request('get', url) try: return request.send() @@ -20,3 +19,13 @@ class Stock(object): logger.error(e) raise e + @property + def products(self): + logger = logging.getLogger('stock.products') + url = self.GET_STOCK_URL_TEMPLATE.format(api=self.conf.api) + return self.__get_resources(url, logger) + + def get_product(self, product_id): + logger = logging.getLogger('stock.get_product') + url = self.GET_STOCK_PRODUCT_DETAIL_TEMPLATE.format(api=self.conf.api, product_id=product_id) + return self.__get_resources(url, logger) diff --git a/grocy/table.py b/grocy/table.py index 3019129..1b145b9 100644 --- a/grocy/table.py +++ b/grocy/table.py @@ -2,6 +2,7 @@ from grocy.entity import Entity import re from grocy.conf import Configuration import logging + from tabulate import tabulate @@ -15,6 +16,13 @@ class Table(object): self.conf = Configuration() self.conf.load() + @property + def product(self): + if not self.entry: + raise Exception('Missing product') + loaded_template = self.conf.templates('single_product') + return loaded_template.render(self.entry) + @property def stock(self): logger = logging.getLogger('table.stock') diff --git a/templates/ingredient_add.yml b/templates/ingredient_add similarity index 100% rename from templates/ingredient_add.yml rename to templates/ingredient_add diff --git a/templates/recipe_add.yml b/templates/recipe_add similarity index 100% rename from templates/recipe_add.yml rename to templates/recipe_add diff --git a/templates/recipe_edit.yml b/templates/recipe_edit similarity index 100% rename from templates/recipe_edit.yml rename to templates/recipe_edit diff --git a/templates/single_product b/templates/single_product new file mode 100644 index 0000000..863e7f6 --- /dev/null +++ b/templates/single_product @@ -0,0 +1,13 @@ + +Name: {{product.name}} + +Stock Quantity Unit: {{quantity_unit_stock.name}} + +Last Purchased: {{last_purchased}} + +Last Used: {{last_used}} + +Last Price: {{last_price}} + + +