New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic todo template #456
Conversation
orchestra/models/core/models.py
Outdated
@@ -592,6 +592,9 @@ class TodoListTemplate (TodoListTemplateMixin, BaseModel): | |||
if it is generated by the system. | |||
todos (str) | |||
A JSON blob that describe the todos in the todo list template. | |||
conditional_property_function (str) | |||
A JSON blob containing the path to and name of a python method | |||
that will return the preconditions to prune the created todos |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: period at end of sentence
orchestra/todos/api.py
Outdated
todo.save() | ||
for template_todo_item in template_todo.get('items', []): | ||
_add_template_todo(template_todo_item, todolist_template, todo, task) | ||
def _to_exclude(props, conditions=[]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can do this:
def _to_exclude(props, conditions=None):
for condition in conditions or []:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alternatively, you already pass in []
below, so just make conditions
required ;)
orchestra/todos/api.py
Outdated
get_cond_props = locate(path) | ||
cond_props = get_cond_props(task.project) | ||
except Exception: | ||
logger.exception('Invalid condition function path.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
condition->contional
@@ -592,6 +592,9 @@ class TodoListTemplate (TodoListTemplateMixin, BaseModel): | |||
if it is generated by the system. | |||
todos (str) | |||
A JSON blob that describe the todos in the todo list template. | |||
conditional_property_function (str) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
explain the structure---is it a list of conditions that get ORed together, with properties in each dictionary getting ANDed, or the other way?
orchestra/todos/api.py
Outdated
todo.save() | ||
for template_todo_item in template_todo.get('items', []): | ||
_add_template_todo(template_todo_item, todolist_template, todo, task) | ||
def _to_exclude(props, conditions=[]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docstring to rehash this question above:
explain the structure---is it a list of conditions that get ORed together, with properties in each dictionary getting ANDed, or the other way?
orchestra/todos/api.py
Outdated
current_value = props.get(prop) | ||
compared_to_value = predicate['value'] | ||
if predicate['operator'] == '=': | ||
return current_value == compared_to_value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since these return immediately, they only ever check the first property of the first condition. you probably want to keep a boolean around that you keep flipping depending on properties/conditions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way to implement string operators -> https://stackoverflow.com/questions/44554614/eval-string-cmp-operator
This might be useful if we intend to extend the available operators in future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few things
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A small suggestion regarding the string operators and a comment on skip propagation.
orchestra/todos/api.py
Outdated
current_value = props.get(prop) | ||
compared_to_value = predicate['value'] | ||
if predicate['operator'] == '=': | ||
return current_value == compared_to_value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way to implement string operators -> https://stackoverflow.com/questions/44554614/eval-string-cmp-operator
This might be useful if we intend to extend the available operators in future.
description=template_todo['description'], | ||
template=todolist_template, | ||
parent_todo=parent_todo, | ||
skipped_datetime=skipped_datetime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To propogate skipping from parents to descendents.
skipped_datetime = timezone.now() if parent_todo.skipped_datetime or to_skip else None
We may even want to skip evaluation of to_skip
if parent_todo.skipped_datetime is not Null. That may save considerable computation time.
orchestra/todos/api.py
Outdated
def _to_exclude(props, conditions): | ||
""" | ||
The conditions is it a list of conditions that get ORed together, | ||
with properties in each dictionary getting ANDed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with predicates in each dictionary
orchestra/todos/api.py
Outdated
for condition in conditions: | ||
all_props_true = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we fine with a zero-item list of properties evaluating to true? could do all_props_true = True and len(all_props_true) > 0
orchestra/todos/api.py
Outdated
""" | ||
any_condition_true = False | ||
|
||
for condition in conditions: | ||
all_props_true = True | ||
all_props_true = len(condition) > 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
len(conditions) :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for detecting {} (a condition). if len(conditions) == 0, this line wouldn't get executed.
orchestra/todos/api.py
Outdated
template=todolist_template | ||
) | ||
root_todo.save() | ||
with transaction.atomic(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could wrap the entire function in @transaction.atomic
and then you don't have to indent everything :)
value (number, bool, sring, or None): | ||
The value to compare with of the predicate. | ||
""" | ||
operator = jsl.StringField(required=True, pattern='[!=><]=|[><]') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[!=><]=|[><]
looks like a serious Kirby battle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[!=><]=|[><]
Add an option to specify todos to remove or skip from a todo list template based on computed conditional properties.