mirror of
https://github.com/leon-ai/leon.git
synced 2024-12-25 01:31:47 +03:00
feat(package/calendar): WIP done
This commit is contained in:
parent
b9693df90c
commit
581da8cd98
@ -50,6 +50,10 @@ a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
ul li {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #FFF;
|
||||
background-color: #151718;
|
||||
|
@ -20,6 +20,10 @@
|
||||
"You do not have any list.",
|
||||
"There is no list to show."
|
||||
],
|
||||
"empty_list": [
|
||||
"Your \"%list%\" list is empty.",
|
||||
"There is nothing in your \"%list%\" list."
|
||||
],
|
||||
"list_does_not_exist": [
|
||||
"Sorry I can't because the \"%list%\" does not exist.",
|
||||
"I cannot do that because the \"%list%\" does not exist."
|
||||
@ -28,10 +32,10 @@
|
||||
"You already have a list named \"%list%\"."
|
||||
],
|
||||
"list_renamed": [
|
||||
"I renamed the \"%old_list%\" list to \"%new_list%\" list."
|
||||
"I renamed the \"%old_list%\" list to \"%new_list%\"."
|
||||
],
|
||||
"list_deleted": [
|
||||
"I deleted the \"%list%\" list and all the todos it was contained."
|
||||
"I deleted the \"%list%\" list and all the todos it was containing."
|
||||
],
|
||||
"lists_listed": [
|
||||
"You have %lists_nb% lists. Please let me list them below for you:<br><br><ul>%result%</ul>"
|
||||
@ -40,9 +44,26 @@
|
||||
"<li>\"%list%\", with %todos_nb% elements in it.</li>",
|
||||
"<li>\"%list%\", that contains %todos_nb% items.</li>"
|
||||
],
|
||||
"no_uncompleted_todo": [
|
||||
"You do not have in progress element in your \"%list%\" list.",
|
||||
"You don't have any in progress element in your \"%list%\" list."
|
||||
],
|
||||
"no_completed_todo": [
|
||||
"And you do not have completed element in your \"%list%\" list.",
|
||||
"And you don't have any completed element in your \"%list%\" list."
|
||||
],
|
||||
"uncompleted_todos_listed": [
|
||||
"Here are the in progress elements of your \"%list%\" list:<br><br><ul>%result%</ul><br><br>Stay motivated!"
|
||||
],
|
||||
"completed_todos_listed": [
|
||||
"And here are the completed elements of your \"%list%\" list:<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"list_todo_element": [
|
||||
"<li>%todo%.</li>"
|
||||
],
|
||||
"list_completed_todo_element": [
|
||||
"<li><strike>%todo%</strike>.</li>"
|
||||
],
|
||||
"todos_added": [
|
||||
"Alright, I added the following to your \"%list%\" list:<br><br><ul>%result%</ul>",
|
||||
"Good luck! The following have been added to your \"%list%\" list:<br><br><ul>%result%</ul>"
|
||||
|
@ -20,6 +20,10 @@
|
||||
"Je n'ai trouvé aucune liste.",
|
||||
"Il n'y a pas de liste à montrer."
|
||||
],
|
||||
"empty_list": [
|
||||
"Votre liste \"%list%\" est vide.",
|
||||
"Il n'y a rien dans votre liste \"%list%\"."
|
||||
],
|
||||
"list_does_not_exist": [
|
||||
"Désolé je ne peux pas car la liste \"%list%\" n'éxiste pas.",
|
||||
"Je ne peux pas parce que la liste \"%list%\" n'éxiste pas."
|
||||
@ -28,7 +32,7 @@
|
||||
"Vous avez déjà une liste nommée \"%list%\"."
|
||||
],
|
||||
"list_renamed": [
|
||||
"J'ai renommé la liste \"%old_list%\" en liste \"%new_list%\"."
|
||||
"J'ai renommé la liste \"%old_list%\" en \"%new_list%\"."
|
||||
],
|
||||
"list_deleted": [
|
||||
"J'ai supprimé la liste \"%list%\" et tous les éléments qu'elle contenait."
|
||||
@ -40,9 +44,26 @@
|
||||
"<li>\"%list%\", avec %todos_nb% éléments.</li>",
|
||||
"<li>\"%list%\", contenant %todos_nb% éléments.</li>"
|
||||
],
|
||||
"no_uncompleted_todo": [
|
||||
"Vous n'avez pas d'élément en attente dans votre liste \"%list%\".",
|
||||
"Vous n'avez aucun élément en attente dans votre liste \"%list%\"."
|
||||
],
|
||||
"no_completed_todo": [
|
||||
"Et vous n'avez pas d'élément complété dans votre liste \"%list%\".",
|
||||
"Et vous n'avez aucun élément complété dans votre liste \"%list%\"."
|
||||
],
|
||||
"uncompleted_todos_listed": [
|
||||
"Voici les éléments en attente de votre liste \"%list\" :<br><br><ul>%result%</ul><br><br>Restez motivé !"
|
||||
],
|
||||
"completed_todos_listed": [
|
||||
"Et voici les éléments complétés de votre liste \"%list\" :<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"list_todo_element": [
|
||||
"<li>%todo%.</li>"
|
||||
],
|
||||
"list_completed_todo_element": [
|
||||
"<li><strike>%todo%</strike>.</li>"
|
||||
],
|
||||
"todos_added": [
|
||||
"Entendu, j'ai ajouté ceci à votre liste \"%list%\" :<br><br><ul>%result%</ul>",
|
||||
"Bonne chance ! Ce qui suit vient d'être ajouté à votre liste \"%list%\" :<br><br><ul>%result%</ul>"
|
||||
|
@ -36,16 +36,40 @@
|
||||
},
|
||||
"view_lists": {
|
||||
"expressions": [
|
||||
"Show the lists",
|
||||
"Show my lists",
|
||||
"Show all the lists",
|
||||
"Show all my lists",
|
||||
"What are the lists?",
|
||||
"What are my lists?"
|
||||
]
|
||||
},
|
||||
"view_list": {
|
||||
"expressions": [
|
||||
"What is in my list?",
|
||||
"What is in the list?"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"rename_list": {
|
||||
"expressions": [
|
||||
"Rename the list to list",
|
||||
"Rename my list to list"
|
||||
"Rename the list to",
|
||||
"Rename my list to"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
@ -114,16 +138,6 @@
|
||||
"type": "between",
|
||||
"from": "add",
|
||||
"to": "to"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "add",
|
||||
"to": "and"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "and",
|
||||
"to": "to"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -149,6 +163,70 @@
|
||||
"expressions": [
|
||||
"Complete from the list",
|
||||
"Complete from my list"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "complete",
|
||||
"to": "from"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"uncomplete_todos": {
|
||||
"expressions": [
|
||||
"Unomplete from the list",
|
||||
"Uncomplete from my list"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "uncomplete",
|
||||
"to": "from"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,20 @@
|
||||
import requests
|
||||
import utils
|
||||
from time import time
|
||||
from tinydb import where
|
||||
|
||||
# Package database
|
||||
db = utils.db()['db']
|
||||
|
||||
# Lists of the module table
|
||||
lists = db.table('todo_lists')
|
||||
db_lists = db.table('todo_lists')
|
||||
# Todos of the module table
|
||||
db_todos = db.table('todo_todos')
|
||||
|
||||
# Query
|
||||
List = utils.db()['query']()
|
||||
Query = utils.db()['query']()
|
||||
|
||||
# Time stamp
|
||||
timestamp = int(time())
|
||||
|
||||
def create_list(string, entities):
|
||||
"""Create a to-do list"""
|
||||
@ -31,7 +35,7 @@ def create_list(string, entities):
|
||||
return utils.output('end', 'list_not_provided', utils.translate('list_not_provided'))
|
||||
|
||||
# Verify if list already exists or not
|
||||
if lists.count(List.name == listname) > 0:
|
||||
if db_lists.count(Query.name == listname) > 0:
|
||||
return utils.output('end', 'list_already_exists', utils.translate('list_already_exists', { 'list': listname }))
|
||||
|
||||
dbCreateList(listname)
|
||||
@ -42,7 +46,7 @@ def view_lists(string, entities):
|
||||
"""View to-do lists"""
|
||||
|
||||
# Lists number
|
||||
lists_nb = len(lists)
|
||||
lists_nb = len(db_lists)
|
||||
|
||||
# Verify if a list exists
|
||||
if lists_nb == 0:
|
||||
@ -50,19 +54,76 @@ def view_lists(string, entities):
|
||||
|
||||
result = ''
|
||||
# Fill end-result
|
||||
for listelement in lists:
|
||||
for listelement in db_lists:
|
||||
result += utils.translate('list_list_element', {
|
||||
'list': listelement['name'],
|
||||
'todos_nb': len(listelement['todos'])
|
||||
'todos_nb': db_todos.count(Query.list == listelement['name'])
|
||||
})
|
||||
|
||||
return utils.output('end', 'lists_listed', utils.translate('list_list', {
|
||||
return utils.output('end', 'lists_listed', utils.translate('lists_listed', {
|
||||
'lists_nb': lists_nb,
|
||||
'result': result
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def view_list(string, entities):
|
||||
"""View a to-do list"""
|
||||
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'list':
|
||||
listname = item['sourceText'].lower()
|
||||
|
||||
# Verify if the list exists
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
return utils.output('end', 'list_does_not_exist', utils.translate('list_does_not_exist', { 'list': listname }))
|
||||
|
||||
# Grab todos of the list
|
||||
todos = db_todos.search(Query.list == listname)
|
||||
|
||||
if len(todos) == 0:
|
||||
return utils.output('end', 'empty_list', utils.translate('empty_list', { 'list': listname }))
|
||||
|
||||
uncompleted_todos = db_todos.search((Query.list == listname) & (Query.is_completed == False))
|
||||
completed_todos = db_todos.search((Query.list == listname) & (Query.is_completed == True))
|
||||
|
||||
result_uncompleted_todos = ''
|
||||
result_completed_todos = ''
|
||||
|
||||
if len(uncompleted_todos) == 0:
|
||||
utils.output('inter', 'no_uncompleted_todo', utils.translate('no_uncompleted_todo', { 'list': listname }))
|
||||
else:
|
||||
for todo in uncompleted_todos:
|
||||
result_uncompleted_todos += utils.translate('list_todo_element', {
|
||||
'todo': todo['name']
|
||||
})
|
||||
|
||||
utils.output('inter', 'uncompleted_todos_listed', utils.translate('uncompleted_todos_listed', {
|
||||
'list': listname,
|
||||
'result': result_uncompleted_todos
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
if len(completed_todos) == 0:
|
||||
return utils.output('end', 'no_completed_todo', utils.translate('no_completed_todo', { 'list': listname }))
|
||||
|
||||
for todo in completed_todos:
|
||||
result_completed_todos += utils.translate('list_completed_todo_element', {
|
||||
'todo': todo['name']
|
||||
})
|
||||
|
||||
return utils.output('end', 'completed_todos_listed', utils.translate('completed_todos_listed', {
|
||||
'list': listname,
|
||||
'result': result_completed_todos
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def rename_list(string, entities):
|
||||
"""Rename a to-do list"""
|
||||
|
||||
@ -84,18 +145,23 @@ def rename_list(string, entities):
|
||||
return utils.output('end', 'new_or_old_list_not_provided', utils.translate('new_or_old_list_not_provided'))
|
||||
|
||||
# Verify if the old list exists
|
||||
if lists.count(List.name == old_listname) == 0:
|
||||
if db_lists.count(Query.name == old_listname) == 0:
|
||||
return utils.output('end', 'list_does_not_exist', utils.translate('list_does_not_exist', { 'list': old_listname }))
|
||||
|
||||
# Verify if the new list name already exists
|
||||
if lists.count(List.name == new_listname) > 0:
|
||||
if db_lists.count(Query.name == new_listname) > 0:
|
||||
return utils.output('end', 'list_already_exists', utils.translate('list_already_exists', { 'list': new_listname }))
|
||||
|
||||
# Rename the to-do list
|
||||
lists.update({
|
||||
db_lists.update({
|
||||
'name': new_listname,
|
||||
'updated_at': int(time())
|
||||
}, List.name == old_listname)
|
||||
}, Query.name == old_listname)
|
||||
# Rename the list name of the todos
|
||||
db_todos.update({
|
||||
'list': new_listname,
|
||||
'updated_at': int(time())
|
||||
}, Query.list == old_listname)
|
||||
|
||||
return utils.output('end', 'list_renamed', utils.translate('list_renamed', {
|
||||
'old_list': old_listname,
|
||||
@ -118,11 +184,13 @@ def delete_list(string, entities):
|
||||
return utils.output('end', 'list_not_provided', utils.translate('list_not_provided'))
|
||||
|
||||
# Verify if the list exists
|
||||
if lists.count(List.name == listname) == 0:
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
return utils.output('end', 'list_does_not_exist', utils.translate('list_does_not_exist', { 'list': listname }))
|
||||
|
||||
# Delete the to-do list
|
||||
lists.remove(List.name == listname)
|
||||
db_lists.remove(Query.name == listname)
|
||||
# Delete todos of that to-do list
|
||||
db_todos.remove(Query.list == listname)
|
||||
|
||||
return utils.output('end', 'list_deleted', utils.translate('list_deleted', { 'list': listname }))
|
||||
|
||||
@ -151,29 +219,16 @@ def add_todos(string, entities):
|
||||
if len(todos) == 0:
|
||||
return utils.output('end', 'todos_not_provided', utils.translate('todos_not_provided'))
|
||||
|
||||
# Grab list
|
||||
db_list = lists.get(List.name == listname)
|
||||
existing_todos = []
|
||||
|
||||
# Verify the list exists
|
||||
if db_list == None:
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
# Create the new to-do list
|
||||
dbCreateList(listname)
|
||||
else:
|
||||
existing_todos = lists.get(List.name == listname)['todos']
|
||||
|
||||
result = ''
|
||||
# Transform todo to a dict for DB and fill end-result
|
||||
for i, todo in enumerate(todos):
|
||||
todo = { 'name': todo, 'is_completed': False }
|
||||
todos[i] = todo
|
||||
result += utils.translate('list_todo_element', { 'todo': todo['name'] })
|
||||
|
||||
# Add todos to the to-do list
|
||||
lists.update({
|
||||
'todos': todos + existing_todos,
|
||||
'updated_at': int(time())
|
||||
}, List.name == listname)
|
||||
for todo in todos:
|
||||
# Add to-do to DB
|
||||
dbCreateTodo(listname, todo)
|
||||
result += utils.translate('list_todo_element', { 'todo': todo })
|
||||
|
||||
return utils.output('end', 'todos_added', utils.translate('todos_added', {
|
||||
'list': listname,
|
||||
@ -183,8 +238,6 @@ def add_todos(string, entities):
|
||||
def complete_todos(string, entities):
|
||||
"""Complete todos"""
|
||||
|
||||
"""WIP"""
|
||||
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
@ -207,109 +260,90 @@ def complete_todos(string, entities):
|
||||
if len(todos) == 0:
|
||||
return utils.output('end', 'todos_not_provided', utils.translate('todos_not_provided'))
|
||||
|
||||
# Grab list
|
||||
db_list = lists.get(List.name == listname)
|
||||
existing_todos = []
|
||||
|
||||
# Verify the list exists
|
||||
if db_list == None:
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
# Create the new to-do list
|
||||
dbCreateList(listname)
|
||||
else:
|
||||
existing_todos = lists.get(List.name == listname)['todos']
|
||||
|
||||
result = ''
|
||||
updated_todos = []
|
||||
tmp_todos = []
|
||||
db_todos = lists.get(List.name == listname)['todos']
|
||||
for todo in todos:
|
||||
for db_todo in db_todos.search(Query.list == listname):
|
||||
# Rough matching (e.g. 1kg of rice = rice)
|
||||
if db_todo['name'].find(todo) != -1:
|
||||
db_todos.update({
|
||||
'is_completed': True,
|
||||
'updated_at': timestamp
|
||||
}, (Query.list == listname) & (Query.name == db_todo['name']))
|
||||
|
||||
# Is there todos in the list
|
||||
if len(db_todos) == 0:
|
||||
updated_todos.append({ 'name': todo, 'is_completed': True })
|
||||
|
||||
for todo in todos:
|
||||
result += utils.translate('list_todo_element', { 'todo': todo })
|
||||
else:
|
||||
for todo in todos:
|
||||
for db_todo in db_todos:
|
||||
# Rough matching (e.g. 1kg of rice = rice)
|
||||
if db_todo['name'].find(todo) != -1:
|
||||
updated_todos.append(db_todo['name'])
|
||||
elif todo not in tmp_todos:
|
||||
tmp_todos.append(todo)
|
||||
|
||||
for updated_todo in updated_todos:
|
||||
for tmp_todo in tmp_todos:
|
||||
if updated_todo.find(tmp_todo) != -1:
|
||||
tmp_todos.remove(tmp_todo)
|
||||
elif tmp_todo not in updated_todos:
|
||||
updated_todos.append(tmp_todo)
|
||||
|
||||
# Set DB existing todos
|
||||
for db_todo in db_todos:
|
||||
if db_todo['name'] not in updated_todos:
|
||||
updated_todos.append(db_todo)
|
||||
|
||||
for i, updated_todo in enumerate(updated_todos):
|
||||
if type(updated_todo) == str:
|
||||
updated_todos[i] = { 'name': updated_todo, 'is_completed': True }
|
||||
result += utils.translate('list_todo_element', { 'todo': updated_todo })
|
||||
result += utils.translate('list_todo_element', { 'todo': db_todo['name'] })
|
||||
|
||||
return utils.output('end', 'todos_completed', utils.translate('todos_completed', {
|
||||
'list': listname,
|
||||
'result': result
|
||||
}))
|
||||
# Update todos
|
||||
# lists.update({
|
||||
# 'todos': updated_todos,
|
||||
# 'updated_at': int(time())
|
||||
# }, List.name == listname)
|
||||
|
||||
# # Verify same word in todo. Allow to not give the exact same todo (e.g. 1kg of rice = rice)
|
||||
# if db_todo['name'].find(todo) != -1:
|
||||
|
||||
# result += utils.translate('list_todo_element', { 'todo': db_todo['name'] })
|
||||
|
||||
# Complete todos
|
||||
# lists.update({
|
||||
# 'todos': updated_todos,
|
||||
# 'updated_at': int(time())
|
||||
# }, List.name == listname)
|
||||
|
||||
# return utils.output('end', 'todos_completed', utils.translate('todos_completed', {
|
||||
# 'list': listname,
|
||||
# 'result': result
|
||||
# }))
|
||||
|
||||
# Complete potatoes from my list
|
||||
# TODO: look in all lists first, if several then ask to specify from which list
|
||||
# Complete potatoes from the shopping list
|
||||
|
||||
def uncomplete_todos(string, entities):
|
||||
"""WIP"""
|
||||
"""Complete todos"""
|
||||
|
||||
# Complete potatoes from my list
|
||||
# TODO: look in all lists first, if several then ask to specify from which list
|
||||
# Complete potatoes from the shopping list
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
return utils.output('end', 'todo_uncompleted', utils.translate('todo_uncompleted', {
|
||||
'list': 'fake',
|
||||
'todo': 'todo 1'
|
||||
# Todos
|
||||
todos = []
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'list':
|
||||
listname = item['sourceText'].lower()
|
||||
elif item['entity'] == 'todos':
|
||||
# Split todos into array and trim start/end-whitespaces
|
||||
todos = [chunk.strip() for chunk in item['sourceText'].lower().split(',')]
|
||||
|
||||
# Verify if a list name has been provided
|
||||
if not listname:
|
||||
return utils.output('end', 'list_not_provided', utils.translate('list_not_provided'))
|
||||
|
||||
# Verify todos have been provided
|
||||
if len(todos) == 0:
|
||||
return utils.output('end', 'todos_not_provided', utils.translate('todos_not_provided'))
|
||||
|
||||
# Verify if the list exists
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
return utils.output('end', 'list_does_not_exist', utils.translate('list_does_not_exist', { 'list': listname }))
|
||||
|
||||
result = ''
|
||||
for todo in todos:
|
||||
for db_todo in db_todos.search(Query.list == listname):
|
||||
# Rough matching (e.g. 1kg of rice = rice)
|
||||
if db_todo['name'].find(todo) != -1:
|
||||
db_todos.update({
|
||||
'is_completed': False,
|
||||
'updated_at': timestamp
|
||||
}, (Query.list == listname) & (Query.name == db_todo['name']))
|
||||
|
||||
result += utils.translate('list_todo_element', { 'todo': db_todo['name'] })
|
||||
|
||||
return utils.output('end', 'todo_uncompleted', utils.translate('todos_uncompleted', {
|
||||
'list': listname,
|
||||
'result': result
|
||||
}))
|
||||
|
||||
def view_todos(string, entities):
|
||||
"""WIP"""
|
||||
|
||||
# TODO
|
||||
|
||||
def dbCreateList(listname):
|
||||
"""Create list in DB"""
|
||||
|
||||
timestamp = int(time())
|
||||
|
||||
lists.insert({
|
||||
db_lists.insert({
|
||||
'name': listname,
|
||||
'todos': [],
|
||||
'created_at': timestamp,
|
||||
'updated_at': timestamp
|
||||
})
|
||||
|
||||
def dbCreateTodo(listname, todoname):
|
||||
"""Create to-todo in list DB table"""
|
||||
|
||||
db_todos.insert({
|
||||
'list': listname,
|
||||
'name': todoname,
|
||||
'is_completed': False,
|
||||
'created_at': timestamp,
|
||||
'updated_at': timestamp
|
||||
})
|
Loading…
Reference in New Issue
Block a user