Parent/Child assignment & fetching refactor
- TodoObject.get_children accepts an obj_type to filter by - Todo._get_parent accepts an obj_type to filter potential parents - Todo._parse_category now properly assigns parent categories - Reworked get_* methods in Task, Category, and Note to use get_children
This commit is contained in:
parent
e768dae978
commit
ada7812e3b
5 changed files with 47 additions and 50 deletions
|
@ -1,25 +1,21 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .Task import Task
|
|
||||||
from .TodoObject import TodoObject
|
from .TodoObject import TodoObject
|
||||||
|
|
||||||
class Category(TodoObject):
|
class Category(TodoObject):
|
||||||
def __init__(self, name : str, level: int, parent = None):
|
def __init__(self, name : str, level: int, parent = None):
|
||||||
super().__init__(level, name, parent)
|
super().__init__(level, name, parent)
|
||||||
|
|
||||||
def get_subcategories(self) -> list[Category]:
|
def get_notes(self, immediate = True):
|
||||||
categories = []
|
from .Note import Note
|
||||||
for child in self.children:
|
return self.get_children(immediate, Note)
|
||||||
if isinstance(child, Category):
|
|
||||||
categories.append(child)
|
|
||||||
return categories
|
|
||||||
|
|
||||||
def get_tasks(self) -> list[Task]:
|
def get_subcategories(self, immediate = True):
|
||||||
tasks = []
|
return self.get_children(immediate, Category)
|
||||||
for child in self.children:
|
|
||||||
if isinstance(child, Task):
|
def get_tasks(self, immediate = True):
|
||||||
tasks.append(child)
|
from .Task import Task
|
||||||
return tasks
|
return self.get_children(immediate, Task)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "#"*(self.level+1) + f" {self.text}"
|
return "#"*(self.level+1) + f" {self.text}"
|
||||||
|
|
|
@ -7,6 +7,13 @@ class Note(TodoObject):
|
||||||
self.listed = listed
|
self.listed = listed
|
||||||
super().__init__(level, text, parent)
|
super().__init__(level, text, parent)
|
||||||
|
|
||||||
|
def get_subnotes(self, immediate = True):
|
||||||
|
return self.get_children(immediate, Note)
|
||||||
|
|
||||||
|
def get_tasks(self, immediate = True):
|
||||||
|
from .Task import Task
|
||||||
|
return self.get_children(immediate, Task)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.listed:
|
if self.listed:
|
||||||
return f"- {self.text}"
|
return f"- {self.text}"
|
||||||
|
|
17
todo/Task.py
17
todo/Task.py
|
@ -3,7 +3,6 @@ from __future__ import annotations
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from .Note import Note
|
|
||||||
from .TodoObject import TodoObject
|
from .TodoObject import TodoObject
|
||||||
|
|
||||||
class Task(TodoObject):
|
class Task(TodoObject):
|
||||||
|
@ -12,18 +11,12 @@ class Task(TodoObject):
|
||||||
self.complete = complete
|
self.complete = complete
|
||||||
super().__init__(level, name, parent)
|
super().__init__(level, name, parent)
|
||||||
|
|
||||||
def get_subtasks(self) -> list[Task]:
|
def get_subtasks(self, immediate = True):
|
||||||
tasks = []
|
return self.get_children(immediate, Task)
|
||||||
for child in self.children:
|
|
||||||
if isinstance(child, Task):
|
|
||||||
tasks.append(child)
|
|
||||||
return tasks
|
|
||||||
|
|
||||||
def get_notes(self):
|
def get_notes(self, immediate = True):
|
||||||
notes = []
|
from .Note import Note
|
||||||
for child in self.children:
|
return self.get_children(immediate, Note)
|
||||||
if isinstance(child, Note):
|
|
||||||
notes.append(child)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
output = ""
|
output = ""
|
||||||
|
|
38
todo/Todo.py
38
todo/Todo.py
|
@ -4,7 +4,7 @@ import logging
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional
|
from typing import Optional, Type
|
||||||
|
|
||||||
from .TodoObject import TodoObject
|
from .TodoObject import TodoObject
|
||||||
from .Category import Category
|
from .Category import Category
|
||||||
|
@ -57,23 +57,27 @@ class Todo(TodoObject):
|
||||||
else: # catch-all for unlisted notes
|
else: # catch-all for unlisted notes
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def _get_parent(self, level, object: TodoObject):
|
def _get_parent(self, level, obj: TodoObject, obj_type: Type[TodoObject] = None):
|
||||||
"""Gets the parent of an object at level X.
|
"""Gets the parent for an object at level X.
|
||||||
|
If an object with a lower level cannot be found within the obj, it will return the obj.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
level (int): The level to find the parent for.
|
level (int): The level to find the parent for.
|
||||||
object (TodoObject): Object to grab parents from.
|
obj (TodoObject): Object to grab parents from.
|
||||||
|
obj_type (Type[TodoObject]): The type of the object the parent should be. Default is None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
TodoObject: The object found.
|
TodoObject: The object found.
|
||||||
"""
|
"""
|
||||||
if level > 0:
|
if level > 0:
|
||||||
for child in object.children[::-1]:
|
for child in obj.children[::-1]:
|
||||||
if child.level < level:
|
if obj_type is not None and isinstance(child, obj_type) and child.level < level:
|
||||||
return child
|
return child
|
||||||
return object
|
if obj_type is None and child.level < level:
|
||||||
|
return child
|
||||||
|
return obj
|
||||||
else:
|
else:
|
||||||
return object
|
return obj
|
||||||
|
|
||||||
def _parse_note(self, line: str, parent: TodoObject):
|
def _parse_note(self, line: str, parent: TodoObject):
|
||||||
"""Parses a markdown line representing a note.
|
"""Parses a markdown line representing a note.
|
||||||
|
@ -119,7 +123,7 @@ class Todo(TodoObject):
|
||||||
line (str): The line to parse.
|
line (str): The line to parse.
|
||||||
"""
|
"""
|
||||||
level = self._get_level(line)
|
level = self._get_level(line)
|
||||||
parent = self._get_parent(level, self)
|
parent = self._get_parent(level, self, obj_type=Category)
|
||||||
line = line[level+2:]
|
line = line[level+2:]
|
||||||
Category(line, level, parent)
|
Category(line, level, parent)
|
||||||
|
|
||||||
|
@ -134,9 +138,9 @@ class Todo(TodoObject):
|
||||||
elif line[0] == "#":
|
elif line[0] == "#":
|
||||||
self._parse_category(line)
|
self._parse_category(line)
|
||||||
elif re.match(" *- \\[[x ]\\]", line):
|
elif re.match(" *- \\[[x ]\\]", line):
|
||||||
self._parse_task(line, self.children[-1])
|
self._parse_task(line, self.get_children(obj_type=Category)[-1])
|
||||||
else:
|
else:
|
||||||
self._parse_note(line, self.children[-1])
|
self._parse_note(line, self.get_children(obj_type=Category)[-1])
|
||||||
|
|
||||||
def get_md(self, category_spacing: int = 1) -> str:
|
def get_md(self, category_spacing: int = 1) -> str:
|
||||||
"""Gets the markdown text of the current data loaded into the object.
|
"""Gets the markdown text of the current data loaded into the object.
|
||||||
|
@ -168,14 +172,6 @@ class Todo(TodoObject):
|
||||||
Returns:
|
Returns:
|
||||||
Optional[Category]: Returns the category if found.
|
Optional[Category]: Returns the category if found.
|
||||||
"""
|
"""
|
||||||
for i in self.children:
|
for i in self.get_children(obj_type=Category):
|
||||||
if isinstance(i, Category) and i.text == name:
|
if i.text == name:
|
||||||
return i
|
return i
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Generates a markdown of my todos"""
|
|
||||||
todo = Todo()
|
|
||||||
print(todo)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
from __future__ import annotations
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional, Type
|
||||||
|
|
||||||
logger = logging.getLogger("TodoObject")
|
logger = logging.getLogger("TodoObject")
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
@ -16,12 +17,16 @@ class TodoObject:
|
||||||
if parent is not None:
|
if parent is not None:
|
||||||
self.set_parents(parent)
|
self.set_parents(parent)
|
||||||
|
|
||||||
def get_children(self, immediate = False):
|
def get_children(self, immediate = False, obj_type: Type[TodoObject] = None) -> list[TodoObject]:
|
||||||
output = []
|
output = []
|
||||||
for child in self.children:
|
for child in self.children:
|
||||||
if immediate and child.parent is self:
|
if obj_type is not None and isinstance(child, obj_type) and immediate and child.parent is self:
|
||||||
output.append(child)
|
output.append(child)
|
||||||
elif not immediate:
|
elif obj_type is None and immediate and child.parent is self:
|
||||||
|
output.append(child)
|
||||||
|
elif obj_type is not None and isinstance(child, obj_type) and not immediate:
|
||||||
|
output.append(child)
|
||||||
|
elif obj_type is None and not immediate:
|
||||||
output.append(child)
|
output.append(child)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue