feat: Created chore command
- feat: Added list subcommand for chore - feat: Added template for chore/list
This commit is contained in:
parent
6d1f3a617a
commit
dd6223f980
26
grocy/chore.py
Normal file
26
grocy/chore.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import logging
|
||||||
|
from grocy.conf import Configuration
|
||||||
|
from grocy.request import Request
|
||||||
|
|
||||||
|
|
||||||
|
class Chore(object):
|
||||||
|
GET_CHORES_URL_TEMPLATE = '{domain}/api/chores'
|
||||||
|
|
||||||
|
def __init__(self, id=None):
|
||||||
|
self.conf = Configuration()
|
||||||
|
self.conf.load()
|
||||||
|
self.id = id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def execution_times(self):
|
||||||
|
logger = logging.getLogger('chore.execution_times')
|
||||||
|
try:
|
||||||
|
if self.id is None:
|
||||||
|
raise Exception('chore id is required')
|
||||||
|
url = self.GET_CHORES_URL_TEMPLATE.format(domain=self.conf.domain)
|
||||||
|
request = Request('get', url)
|
||||||
|
chores = request.send()
|
||||||
|
chore = next((c for c in chores if c['chore_id'] == self.id), None)
|
||||||
|
return chore
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
84
grocy/cli.py
84
grocy/cli.py
@ -9,6 +9,7 @@ from grocy.util import Util
|
|||||||
from grocy.recipe import Recipe
|
from grocy.recipe import Recipe
|
||||||
from grocy.table import Table
|
from grocy.table import Table
|
||||||
from grocy.entity import Entity
|
from grocy.entity import Entity
|
||||||
|
from grocy.chore import Chore
|
||||||
from grocy.stock import Stock
|
from grocy.stock import Stock
|
||||||
from grocy.schema import get_schema
|
from grocy.schema import get_schema
|
||||||
from grocy.shoppinglist import ShoppingList
|
from grocy.shoppinglist import ShoppingList
|
||||||
@ -462,6 +463,7 @@ def remove_ingredient(recipe_id, ingredient_id):
|
|||||||
logger.error(e)
|
logger.error(e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
@main.group()
|
@main.group()
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def shopping(ctx):
|
def shopping(ctx):
|
||||||
@ -677,42 +679,60 @@ def remove_product(shopping_id, template):
|
|||||||
|
|
||||||
|
|
||||||
# TODO: Figure out why this command is not working for new shopping lists
|
# TODO: Figure out why this command is not working for new shopping lists
|
||||||
@shopping.command()
|
#@shopping.command()
|
||||||
@click.argument('shopping_id')
|
#@click.argument('shopping_id')
|
||||||
|
#@click.option('-t', 'template')
|
||||||
|
#@click.option('recipe_id', 'r')
|
||||||
|
#def add_missing_products(shopping_id, recipe_id, template):
|
||||||
|
# logger = logging.getLogger('cli.shopping.add_missing_products')
|
||||||
|
# try:
|
||||||
|
# cfg = Configuration()
|
||||||
|
# cfg.load()
|
||||||
|
# util = Util(cfg=cfg)
|
||||||
|
#
|
||||||
|
# # Validate that shopping list exists
|
||||||
|
# entity = Entity(name='shopping_lists')
|
||||||
|
# found_shopping_list = entity.get(id=shopping_id)
|
||||||
|
# if found_shopping_list is None:
|
||||||
|
# raise Exception('Shopping list does not exist')
|
||||||
|
#
|
||||||
|
# shopping_list = ShoppingList(id=shopping_id)
|
||||||
|
# except Exception as e:
|
||||||
|
# raise e
|
||||||
|
|
||||||
|
@main.group()
|
||||||
|
def chore():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@chore.command()
|
||||||
|
@click.option('--name', '-n', 'name')
|
||||||
@click.option('-t', 'template')
|
@click.option('-t', 'template')
|
||||||
def add_missing_products(shopping_id, template):
|
def list(name, template):
|
||||||
logger = logging.getLogger('cli.shopping.add_missing_products')
|
logger = logging.getLogger('cli.shopping.list')
|
||||||
try:
|
|
||||||
cfg = Configuration()
|
cfg = Configuration()
|
||||||
cfg.load()
|
cfg.load()
|
||||||
util = Util(cfg=cfg)
|
try:
|
||||||
|
entity = Entity(name='chores')
|
||||||
|
if name:
|
||||||
|
chores = entity.find_by_name(name)
|
||||||
|
if len(chores) == 0:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
chores = entity.get()
|
||||||
|
|
||||||
# Validate that shopping list exists
|
data = {'chores': []}
|
||||||
entity = Entity(name='shopping_lists')
|
for chore in chores:
|
||||||
found_shopping_list = entity.get(id=shopping_id)
|
chore_details = Chore(chore['id'])
|
||||||
if found_shopping_list is None:
|
chore.update(chore_details.execution_times)
|
||||||
raise Exception('Shopping list does not exist')
|
data['chores'].append({'fields': chore})
|
||||||
|
|
||||||
shopping_list = ShoppingList(id=shopping_id)
|
if template:
|
||||||
shopping_list.add_missing_products()
|
loaded_template = cfg.templates(template)
|
||||||
|
else:
|
||||||
|
loaded_template = cfg.templates('chore/list')
|
||||||
|
|
||||||
|
click.echo(loaded_template.render(grocy=data))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
#@main.command()
|
|
||||||
#@click.pass_context
|
|
||||||
#def chore(ctx):
|
|
||||||
# cfg = ctx.obj['cfg']
|
|
||||||
#
|
|
||||||
# chore = Chore(**cfg)
|
|
||||||
# chores = chore.get_list()
|
|
||||||
# click.echo(chores)
|
|
||||||
#
|
|
||||||
#@main.command()
|
|
||||||
#@click.pass_context
|
|
||||||
#def task(ctx):
|
|
||||||
# cfg = ctx.obj['cfg']
|
|
||||||
#
|
|
||||||
# task = Task(**cfg)
|
|
||||||
# tasks = task.get_list()
|
|
||||||
# click.echo(tasks)
|
|
||||||
# click.echo(tasks)
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from grocy.request import Request
|
from grocy.request import Request
|
||||||
|
from six.moves.urllib.parse import quote as encode_entity
|
||||||
import re
|
import re
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from grocy.conf import Configuration
|
from grocy.conf import Configuration
|
||||||
@ -7,6 +8,7 @@ import logging
|
|||||||
|
|
||||||
class Entity(object):
|
class Entity(object):
|
||||||
RESOURCE_URL_TEMPLATE = '{domain}/api/objects/{entity}/{objectId}'
|
RESOURCE_URL_TEMPLATE = '{domain}/api/objects/{entity}/{objectId}'
|
||||||
|
FIND_RESOURCE_BY_NAME = '{domain}/api/objects/{entity}/search/{name}'
|
||||||
COLLECTION_URL_TEMPLATE = '{domain}/api/objects/{entity}'
|
COLLECTION_URL_TEMPLATE = '{domain}/api/objects/{entity}'
|
||||||
SCHEMA_URL_TEMPLATE = '{domain}/api/openapi/specification'
|
SCHEMA_URL_TEMPLATE = '{domain}/api/openapi/specification'
|
||||||
SCHEMA_MODEL_MAP = {
|
SCHEMA_MODEL_MAP = {
|
||||||
@ -24,7 +26,6 @@ class Entity(object):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.__dict__.update(**props)
|
self.__dict__.update(**props)
|
||||||
|
|
||||||
|
|
||||||
def get(self, id=None):
|
def get(self, id=None):
|
||||||
logger = logging.getLogger('entity.get')
|
logger = logging.getLogger('entity.get')
|
||||||
if id:
|
if id:
|
||||||
@ -58,6 +59,16 @@ class Entity(object):
|
|||||||
logger.error(e)
|
logger.error(e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
def find_by_name(self, query):
|
||||||
|
logger = logging.getLogger('entity.find_by_name')
|
||||||
|
try:
|
||||||
|
url = self.FIND_RESOURCE_BY_NAME.format(domain=self.conf.domain, entity=self.name, name=encode_entity(query))
|
||||||
|
request = Request('get', url)
|
||||||
|
return request.send()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
raise e
|
||||||
|
|
||||||
def create(self, entity):
|
def create(self, entity):
|
||||||
logger = logging.getLogger('entity.add')
|
logger = logging.getLogger('entity.add')
|
||||||
url = self.COLLECTION_URL_TEMPLATE.format(domain=self.conf.domain, entity=self.name)
|
url = self.COLLECTION_URL_TEMPLATE.format(domain=self.conf.domain, entity=self.name)
|
||||||
|
@ -64,7 +64,7 @@ class ShoppingList(object):
|
|||||||
logger.eror(e)
|
logger.eror(e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def add_missing_products(self):
|
def add_missing_products(self, recipe_id=None):
|
||||||
logger = logging.getLogger('shoppinglist.add_min_stock')
|
logger = logging.getLogger('shoppinglist.add_min_stock')
|
||||||
try:
|
try:
|
||||||
if self.id is None:
|
if self.id is None:
|
||||||
|
7
templates/chore/list.yml
Normal file
7
templates/chore/list.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{{ 'Chore' }} {{ '%15s'|format('') }} {{ 'Next estimated tracking' }} {{ '%15s'|format('') }} {{ 'Last tracked' }}
|
||||||
|
{%- for chore in grocy.chores %}
|
||||||
|
{{ chore.fields.name }} {{ '%15s'|format('') }}{%- if '2999-' in chore.fields.next_estimated_execution_time or 'Never' in chore.fields.next_estimated_execution_time %} {{'%10s'|format('---')}}
|
||||||
|
{%- else %} {{chore.fields.next_estimated_execution_time}} {%endif%} {{'%15s'|format('')}}
|
||||||
|
{%- if not chore.fields.last_tracked_time %} {{'%20s'|format('None')}}
|
||||||
|
{%- else %} {{chore.fields.last_tracked_time}}{%endif%}
|
||||||
|
{%- if loop.nextitem %}{%endif%}{%endfor%}
|
Loading…
Reference in New Issue
Block a user