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:
riley 2021-09-25 23:25:30 -04:00
parent e768dae978
commit ada7812e3b
5 changed files with 47 additions and 50 deletions

View file

@ -1,25 +1,21 @@
from __future__ import annotations
from .Task import Task
from .TodoObject import TodoObject
class Category(TodoObject):
def __init__(self, name : str, level: int, parent = None):
super().__init__(level, name, parent)
def get_subcategories(self) -> list[Category]:
categories = []
for child in self.children:
if isinstance(child, Category):
categories.append(child)
return categories
def get_notes(self, immediate = True):
from .Note import Note
return self.get_children(immediate, Note)
def get_tasks(self) -> list[Task]:
tasks = []
for child in self.children:
if isinstance(child, Task):
tasks.append(child)
return tasks
def get_subcategories(self, immediate = True):
return self.get_children(immediate, Category)
def get_tasks(self, immediate = True):
from .Task import Task
return self.get_children(immediate, Task)
def __str__(self):
return "#"*(self.level+1) + f" {self.text}"

View file

@ -7,6 +7,13 @@ class Note(TodoObject):
self.listed = listed
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):
if self.listed:
return f"- {self.text}"

View file

@ -3,7 +3,6 @@ from __future__ import annotations
from typing import Union
from datetime import datetime
from .Note import Note
from .TodoObject import TodoObject
class Task(TodoObject):
@ -12,18 +11,12 @@ class Task(TodoObject):
self.complete = complete
super().__init__(level, name, parent)
def get_subtasks(self) -> list[Task]:
tasks = []
for child in self.children:
if isinstance(child, Task):
tasks.append(child)
return tasks
def get_subtasks(self, immediate = True):
return self.get_children(immediate, Task)
def get_notes(self):
notes = []
for child in self.children:
if isinstance(child, Note):
notes.append(child)
def get_notes(self, immediate = True):
from .Note import Note
return self.get_children(immediate, Note)
def __str__(self):
output = ""

View file

@ -4,7 +4,7 @@ import logging
from pathlib import Path
from datetime import datetime
from typing import Optional
from typing import Optional, Type
from .TodoObject import TodoObject
from .Category import Category
@ -57,23 +57,27 @@ class Todo(TodoObject):
else: # catch-all for unlisted notes
return 0
def _get_parent(self, level, object: TodoObject):
"""Gets the parent of an object at level X.
def _get_parent(self, level, obj: TodoObject, obj_type: Type[TodoObject] = None):
"""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:
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:
TodoObject: The object found.
"""
if level > 0:
for child in object.children[::-1]:
if child.level < level:
for child in obj.children[::-1]:
if obj_type is not None and isinstance(child, obj_type) and child.level < level:
return child
return object
if obj_type is None and child.level < level:
return child
return obj
else:
return object
return obj
def _parse_note(self, line: str, parent: TodoObject):
"""Parses a markdown line representing a note.
@ -119,7 +123,7 @@ class Todo(TodoObject):
line (str): The line to parse.
"""
level = self._get_level(line)
parent = self._get_parent(level, self)
parent = self._get_parent(level, self, obj_type=Category)
line = line[level+2:]
Category(line, level, parent)
@ -134,9 +138,9 @@ class Todo(TodoObject):
elif line[0] == "#":
self._parse_category(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:
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:
"""Gets the markdown text of the current data loaded into the object.
@ -168,14 +172,6 @@ class Todo(TodoObject):
Returns:
Optional[Category]: Returns the category if found.
"""
for i in self.children:
if isinstance(i, Category) and i.text == name:
for i in self.get_children(obj_type=Category):
if i.text == name:
return i
def main():
"""Generates a markdown of my todos"""
todo = Todo()
print(todo)
if __name__ == "__main__":
main()

View file

@ -1,6 +1,7 @@
from __future__ import annotations
import logging
from typing import Optional
from typing import Optional, Type
logger = logging.getLogger("TodoObject")
logger.setLevel(logging.INFO)
@ -16,12 +17,16 @@ class TodoObject:
if parent is not None:
self.set_parents(parent)
def get_children(self, immediate = False):
def get_children(self, immediate = False, obj_type: Type[TodoObject] = None) -> list[TodoObject]:
output = []
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)
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)
return output