feat: Added configurable user templates
This commit is contained in:
parent
0a1ecddf3d
commit
1f7a061600
98
grocy/cli.py
98
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')
|
||||
|
||||
if new_ingredient:
|
||||
entity = Entity(name='ingredients', **parsed_new_ingredient)
|
||||
entity.create()
|
||||
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)
|
||||
|
||||
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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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')
|
||||
|
13
templates/single_product
Normal file
13
templates/single_product
Normal file
@ -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}}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user