diff --git a/__pycache__/zrb_init.cpython-310.pyc b/__pycache__/zrb_init.cpython-310.pyc deleted file mode 100644 index 7b69636..0000000 Binary files a/__pycache__/zrb_init.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__init__.py b/_daily/noto/__init__.py deleted file mode 100644 index 81c789f..0000000 --- a/_daily/noto/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from _daily.noto import lint, list, log, sync, todo, wiki - -assert lint -assert log -assert list -assert sync -assert todo -assert wiki diff --git a/_daily/noto/__pycache__/__init__.cpython-310.pyc b/_daily/noto/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 7822ba1..0000000 Binary files a/_daily/noto/__pycache__/__init__.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__pycache__/_config.cpython-310.pyc b/_daily/noto/__pycache__/_config.cpython-310.pyc deleted file mode 100644 index 744ee09..0000000 Binary files a/_daily/noto/__pycache__/_config.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__pycache__/_env.cpython-310.pyc b/_daily/noto/__pycache__/_env.cpython-310.pyc deleted file mode 100644 index c969222..0000000 Binary files a/_daily/noto/__pycache__/_env.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__pycache__/_group.cpython-310.pyc b/_daily/noto/__pycache__/_group.cpython-310.pyc deleted file mode 100644 index 26f7bba..0000000 Binary files a/_daily/noto/__pycache__/_group.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__pycache__/_helper.cpython-310.pyc b/_daily/noto/__pycache__/_helper.cpython-310.pyc deleted file mode 100644 index 82496bc..0000000 Binary files a/_daily/noto/__pycache__/_helper.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__pycache__/lint.cpython-310.pyc b/_daily/noto/__pycache__/lint.cpython-310.pyc deleted file mode 100644 index df28011..0000000 Binary files a/_daily/noto/__pycache__/lint.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__pycache__/list.cpython-310.pyc b/_daily/noto/__pycache__/list.cpython-310.pyc deleted file mode 100644 index 75e316f..0000000 Binary files a/_daily/noto/__pycache__/list.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__pycache__/sync.cpython-310.pyc b/_daily/noto/__pycache__/sync.cpython-310.pyc deleted file mode 100644 index a20820d..0000000 Binary files a/_daily/noto/__pycache__/sync.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/__pycache__/wiki.cpython-310.pyc b/_daily/noto/__pycache__/wiki.cpython-310.pyc deleted file mode 100644 index 86b28e5..0000000 Binary files a/_daily/noto/__pycache__/wiki.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/_config.py b/_daily/noto/_config.py deleted file mode 100644 index 34da018..0000000 --- a/_daily/noto/_config.py +++ /dev/null @@ -1,12 +0,0 @@ -import os -from datetime import datetime - -CURRENT_DIR = os.path.dirname(__file__) -PROJECT_DIR = os.path.dirname(os.path.dirname(CURRENT_DIR)) -SRC_DIR = os.path.join(PROJECT_DIR, "src") -TODO_FILE_NAME = os.path.join(SRC_DIR, "todo.txt") - -CURRENT_TIME = datetime.now() -CURRENT_YEAR = CURRENT_TIME.year -CURRENT_MONTH = CURRENT_TIME.strftime("%m") -CURRENT_DAY = CURRENT_TIME.strftime("%d") diff --git a/_daily/noto/_env.py b/_daily/noto/_env.py deleted file mode 100644 index 6ee1686..0000000 --- a/_daily/noto/_env.py +++ /dev/null @@ -1,5 +0,0 @@ -from zrb import Env - -from _daily.noto._config import PROJECT_DIR - -PROJECT_DIR_ENV = Env(name="PROJECT_DIR", default=PROJECT_DIR, os_name="") diff --git a/_daily/noto/_group.py b/_daily/noto/_group.py deleted file mode 100644 index f0fc52f..0000000 --- a/_daily/noto/_group.py +++ /dev/null @@ -1,4 +0,0 @@ -from zrb import Group - -NOTO_GROUP = Group(name="noto", description="Noto management") -NOTO_WIKI_GROUP = Group(name="wiki", description="Noto wiki") diff --git a/_daily/noto/_helper.py b/_daily/noto/_helper.py deleted file mode 100644 index 401e893..0000000 --- a/_daily/noto/_helper.py +++ /dev/null @@ -1,49 +0,0 @@ -import os -import shutil -import subprocess - -from zrb import Task -from zrb.helper.accessories.color import colored - - -def sync_noto(task: Task) -> int: - current_dir = os.path.dirname(__file__) - try: - return run_cmd_path(task, os.path.join(current_dir, "sync.sh")) - except Exception: - task.print_err(colored("Cannot sync", color="light_red")) - return 0 - - -def run_cmd_path(task: Task, command_path: str) -> int: - with open(command_path, "r") as file: - command = file.read() - return run_cmd(task, command) - - -def run_cmd(task: Task, command: str) -> int: - # Start the process - process = subprocess.Popen( - command, - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - text=True, - env=task.get_env_map(), - ) - # Iterate over the output lines as they become available - while True: - output = process.stdout.readline() - if output == "" and process.poll() is not None: - break - if output: - task.print_out_dark(output.strip()) - rc = process.poll() - if rc != 0: - raise Exception(f"Non zero exit code: {rc}") - return rc - - -def get_screen_width() -> int: - terminal_size = shutil.get_terminal_size() - return terminal_size.columns diff --git a/_daily/noto/lint.py b/_daily/noto/lint.py deleted file mode 100644 index b316307..0000000 --- a/_daily/noto/lint.py +++ /dev/null @@ -1,20 +0,0 @@ -import os -from typing import Any - -from zrb import Task, python_task, runner - -from _daily.noto._config import CURRENT_DIR -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._group import NOTO_GROUP -from _daily.noto._helper import run_cmd_path - - -@python_task( - name="lint", group=NOTO_GROUP, description="Lint code", envs=[PROJECT_DIR_ENV] -) -def lint(*args: Any, **kwargs: Any): - task: Task = kwargs.get("_task") - run_cmd_path(task, os.path.join(CURRENT_DIR, "lint.sh")) - - -runner.register(lint) diff --git a/_daily/noto/lint.sh b/_daily/noto/lint.sh deleted file mode 100644 index 260fd3e..0000000 --- a/_daily/noto/lint.sh +++ /dev/null @@ -1,4 +0,0 @@ -set -e -cd "${PROJECT_DIR}" -isort . -black . \ No newline at end of file diff --git a/_daily/noto/list.py b/_daily/noto/list.py deleted file mode 100644 index b4d207d..0000000 --- a/_daily/noto/list.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Any - -from zrb import Task, python_task, runner -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._group import NOTO_GROUP -from _daily.noto._helper import sync_noto -from _daily.noto.log._helper import get_pretty_log_lines -from _daily.noto.todo._helper import get_items, get_pretty_item_lines - - -@python_task( - name="list", - group=NOTO_GROUP, - description="List todo", - envs=[PROJECT_DIR_ENV], - retry=0, -) -def list(*args: Any, **kwargs: Any): - task: Task = kwargs.get("_task") - sync_noto(task) - items = get_items(completed=False) - show_lines(task, *get_pretty_log_lines(), "", *get_pretty_item_lines(items)) - - -runner.register(list) diff --git a/_daily/noto/log/__init__.py b/_daily/noto/log/__init__.py deleted file mode 100644 index 310482d..0000000 --- a/_daily/noto/log/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from _daily.noto.log import add, list_log - -assert add -assert list_log diff --git a/_daily/noto/log/__pycache__/__init__.cpython-310.pyc b/_daily/noto/log/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index e0bffdb..0000000 Binary files a/_daily/noto/log/__pycache__/__init__.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/log/__pycache__/_group.cpython-310.pyc b/_daily/noto/log/__pycache__/_group.cpython-310.pyc deleted file mode 100644 index e092ef9..0000000 Binary files a/_daily/noto/log/__pycache__/_group.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/log/__pycache__/_helper.cpython-310.pyc b/_daily/noto/log/__pycache__/_helper.cpython-310.pyc deleted file mode 100644 index 3e2cca9..0000000 Binary files a/_daily/noto/log/__pycache__/_helper.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/log/__pycache__/add.cpython-310.pyc b/_daily/noto/log/__pycache__/add.cpython-310.pyc deleted file mode 100644 index f04b2d6..0000000 Binary files a/_daily/noto/log/__pycache__/add.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/log/__pycache__/list_log.cpython-310.pyc b/_daily/noto/log/__pycache__/list_log.cpython-310.pyc deleted file mode 100644 index e3cc631..0000000 Binary files a/_daily/noto/log/__pycache__/list_log.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/log/_group.py b/_daily/noto/log/_group.py deleted file mode 100644 index 4ff43f8..0000000 --- a/_daily/noto/log/_group.py +++ /dev/null @@ -1,3 +0,0 @@ -from zrb import Group - -LOG_GROUP = Group(name="log", description="log") diff --git a/_daily/noto/log/_helper.py b/_daily/noto/log/_helper.py deleted file mode 100644 index 7a89e88..0000000 --- a/_daily/noto/log/_helper.py +++ /dev/null @@ -1,70 +0,0 @@ -import os -import re -from datetime import datetime -from pathlib import Path -from typing import List, Optional - -from zrb.helper.accessories.color import colored - -from _daily.noto._config import CURRENT_TIME, SRC_DIR - -_STATUS_COLOR_MAP = { - "START": "cyan", - "COMPLETE": "green", - "STOP": "yellow", -} - - -def get_log_file_name(current_time: datetime = CURRENT_TIME) -> str: - year = current_time.year - month = current_time.strftime("%m") - date = current_time.strftime("%d") - return os.path.join( - SRC_DIR, "logs", f"{year}", f"{year}-{month}", f"{year}-{month}-{date}.md" - ) - - -def append_log(text: str, current_time: datetime = CURRENT_TIME) -> str: - file_name = get_log_file_name(current_time=current_time) - dir_path = Path(os.path.dirname(file_name)) - dir_path.mkdir(parents=True, exist_ok=True) - time_str: str = current_time.strftime("%H:%M") - log_lines = _get_log_lines(file_name) - log_lines.append(f"- {time_str}: {text}\n") - with open(file_name, "w") as file: - file.write("\n".join(log_lines)) - file.write("\n") - - -def _get_log_lines(file_name: Optional[str] = None) -> List[str]: - if file_name is None: - file_name = get_log_file_name() - log_str = get_log(file_name) - return log_str.split("\n") - - -def get_pretty_log_lines(file_name: Optional[str] = None) -> List[str]: - if file_name is None: - file_name = get_log_file_name() - log_str = get_log(file_name) - for keyword, color in _STATUS_COLOR_MAP.items(): - log_str = re.sub( - re.compile("([\n]*- \\d{2}:\\d{2}): __" + keyword + "__"), - lambda match: match.group(1) + ": " + colored(keyword, color=color), - log_str, - ) - log_str = re.sub( - r"__(.*?)__", lambda match: colored(match.group(1), color="yellow"), log_str - ) - return log_str.split("\n") - - -def get_log(file_name: Optional[str] = None) -> str: - if file_name is None: - file_name = get_log_file_name() - dir_path = Path(os.path.dirname(file_name)) - dir_path.mkdir(parents=True, exist_ok=True) - if not os.path.isfile(file_name): - return "" - with open(file_name, "r") as file: - return file.read().strip() diff --git a/_daily/noto/log/add.py b/_daily/noto/log/add.py deleted file mode 100644 index 1ef31d0..0000000 --- a/_daily/noto/log/add.py +++ /dev/null @@ -1,33 +0,0 @@ -from zrb import StrInput, Task, python_task, runner -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.log._group import LOG_GROUP -from _daily.noto.log._helper import append_log, get_pretty_log_lines - - -@python_task( - name="add", - group=LOG_GROUP, - inputs=[ - StrInput( - name="text", - shortcut="t", - prompt="Text", - default="", - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def add(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - text = kwargs.get("text") - append_log(text) - sync_noto(task) - show_lines(task, *get_pretty_log_lines()) - - -runner.register(add) diff --git a/_daily/noto/log/list_log.py b/_daily/noto/log/list_log.py deleted file mode 100644 index ff849ef..0000000 --- a/_daily/noto/log/list_log.py +++ /dev/null @@ -1,35 +0,0 @@ -from datetime import datetime - -from zrb import StrInput, Task, python_task, runner -from zrb.helper.task import show_lines - -from _daily.noto._config import CURRENT_TIME -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.log._group import LOG_GROUP -from _daily.noto.log._helper import get_log_file_name, get_pretty_log_lines - - -@python_task( - name="list", - group=LOG_GROUP, - inputs=[ - StrInput( - name="date", - prompt="Date (Y-m-d)", - default=CURRENT_TIME.strftime("%Y-%m-%d"), - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def list_log(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - date_str = kwargs.get("date") - current_time = datetime.strptime(date_str, "%Y-%m-%d") - file_name = get_log_file_name(current_time) - show_lines(task, *get_pretty_log_lines(file_name)) - - -runner.register(list_log) diff --git a/_daily/noto/sync.py b/_daily/noto/sync.py deleted file mode 100644 index f8a2885..0000000 --- a/_daily/noto/sync.py +++ /dev/null @@ -1,23 +0,0 @@ -import os -from typing import Any - -from zrb import Task, python_task, runner - -from _daily.noto._config import CURRENT_DIR -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._group import NOTO_GROUP -from _daily.noto._helper import run_cmd_path - - -@python_task( - name="sync", - group=NOTO_GROUP, - description="sync code", - envs=[PROJECT_DIR_ENV], -) -def sync(*args: Any, **kwargs: Any): - task: Task = kwargs.get("_task") - run_cmd_path(task, os.path.join(CURRENT_DIR, "sync.sh")) - - -runner.register(sync) diff --git a/_daily/noto/sync.sh b/_daily/noto/sync.sh deleted file mode 100644 index ce01779..0000000 --- a/_daily/noto/sync.sh +++ /dev/null @@ -1,38 +0,0 @@ -set -e -cd "${PROJECT_DIR}" -git add . -A -if git diff --quiet && git diff --cached --quiet -then - echo "Nothing to commit" -else - echo "Commiting changes" - git commit -m "Save changes on $(date)" -fi -GIT_BRANCH="$(git symbolic-ref --short HEAD)" -echo "Current branch: ${GIT_BRANCH}" - -echo "Fetching origin ${GIT_BRANCH}" -git fetch origin - -LOCAL=$(git rev-parse $GIT_BRANCH) -REMOTE=$(git rev-parse origin/$GIT_BRANCH) -BASE=$(git merge-base $GIT_BRANCH origin/$GIT_BRANCH) - -echo "Comparing local branch $GIT_BRANCH with origin/$GIT_BRANCH" - -if [ "$LOCAL" = "$REMOTE" ] -then - echo "Up to date with origin/$GIT_BRANCH." -elif [ "$LOCAL" = "$BASE" ] -then - echo "Need to pull. Local branch $GIT_BRANCH is behind origin/$GIT_BRANCH." - echo "Pulling from Server" - git pull origin ${GIT_BRANCH:-main} -elif [ "$REMOTE" = "$BASE" ] -then - echo "Need to push. Local branch $GIT_BRANCH is ahead of origin/$GIT_BRANCH." - echo "Pushing to Server" - git push -u origin ${GIT_BRANCH:-main} -else - echo "Branch $GIT_BRANCH has diverged from origin/$GIT_BRANCH." -fi diff --git a/_daily/noto/todo/__init__.py b/_daily/noto/todo/__init__.py deleted file mode 100644 index 7f17221..0000000 --- a/_daily/noto/todo/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -from _daily.noto.todo import ( - add, - complete, - delete, - edit, - find, - kanban, - list, - start, - stop, -) - -assert add -assert complete -assert edit -assert delete -assert find -assert kanban -assert list -assert start -assert stop diff --git a/_daily/noto/todo/__pycache__/__init__.cpython-310.pyc b/_daily/noto/todo/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index fa5a41d..0000000 Binary files a/_daily/noto/todo/__pycache__/__init__.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/_data.cpython-310.pyc b/_daily/noto/todo/__pycache__/_data.cpython-310.pyc deleted file mode 100644 index ceda3c5..0000000 Binary files a/_daily/noto/todo/__pycache__/_data.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/_group.cpython-310.pyc b/_daily/noto/todo/__pycache__/_group.cpython-310.pyc deleted file mode 100644 index cec5569..0000000 Binary files a/_daily/noto/todo/__pycache__/_group.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/_helper.cpython-310.pyc b/_daily/noto/todo/__pycache__/_helper.cpython-310.pyc deleted file mode 100644 index 161e8d6..0000000 Binary files a/_daily/noto/todo/__pycache__/_helper.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/add.cpython-310.pyc b/_daily/noto/todo/__pycache__/add.cpython-310.pyc deleted file mode 100644 index b34199a..0000000 Binary files a/_daily/noto/todo/__pycache__/add.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/complete.cpython-310.pyc b/_daily/noto/todo/__pycache__/complete.cpython-310.pyc deleted file mode 100644 index c5790f9..0000000 Binary files a/_daily/noto/todo/__pycache__/complete.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/delete.cpython-310.pyc b/_daily/noto/todo/__pycache__/delete.cpython-310.pyc deleted file mode 100644 index d3e03a6..0000000 Binary files a/_daily/noto/todo/__pycache__/delete.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/edit.cpython-310.pyc b/_daily/noto/todo/__pycache__/edit.cpython-310.pyc deleted file mode 100644 index 91a84ec..0000000 Binary files a/_daily/noto/todo/__pycache__/edit.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/find.cpython-310.pyc b/_daily/noto/todo/__pycache__/find.cpython-310.pyc deleted file mode 100644 index 6b4b6dc..0000000 Binary files a/_daily/noto/todo/__pycache__/find.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/list.cpython-310.pyc b/_daily/noto/todo/__pycache__/list.cpython-310.pyc deleted file mode 100644 index 9994ffd..0000000 Binary files a/_daily/noto/todo/__pycache__/list.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/start.cpython-310.pyc b/_daily/noto/todo/__pycache__/start.cpython-310.pyc deleted file mode 100644 index c1c5439..0000000 Binary files a/_daily/noto/todo/__pycache__/start.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/__pycache__/stop.cpython-310.pyc b/_daily/noto/todo/__pycache__/stop.cpython-310.pyc deleted file mode 100644 index d224b11..0000000 Binary files a/_daily/noto/todo/__pycache__/stop.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/_data.py b/_daily/noto/todo/_data.py deleted file mode 100644 index 4e77692..0000000 --- a/_daily/noto/todo/_data.py +++ /dev/null @@ -1,300 +0,0 @@ -import re -from datetime import datetime -from typing import List, Mapping, Optional - -from zrb.helper.accessories.color import colored -from zrb.helper.accessories.name import get_random_name - -from _daily.noto._config import CURRENT_TIME -from _daily.noto._helper import get_screen_width - -SCREEN_WIDTH = get_screen_width() - -STATUS_ICON_MAP = { - "NEW": "✨", - "STARTED": "🏃", - "STOPPED": "🌴", - "COMPLETED": "🏆", -} - -STATUS_COLOR_MAP = { - "NEW": "white", - "STARTED": "light_cyan", - "STOPPED": "light_red", - "COMPLETED": "light_green", -} - -STATUS_ATTRIBUTE_MAP = { - "NEW": [], - "STARTED": ["bold"], - "STOPPED": ["bold"], - "COMPLETED": [], -} - - -class Item: - def __init__( - self, - description: str, - old_description: Optional[str] = None, - completed: bool = False, - priority: Optional[str] = None, - completion_date: Optional[datetime] = None, - creation_date: Optional[datetime] = None, - contexts: List[str] = [], - projects: List[str] = [], - keyval: Mapping[str, str] = {}, - ): - self.completed = completed - self.priority = priority - self.completion_date = completion_date - self.creation_date = creation_date - self.description = description - self.old_description = old_description - self.contexts = contexts - self.projects = projects - self.keyval = keyval - if "id" not in self.keyval: - self.keyval["id"] = get_random_name() - - def match( - self, - contexts: List[str] = [], - projects: List[str] = [], - search: str = "", - completed: Optional[bool] = None, - ): - filter_by_context = len(contexts) > 0 - filter_by_project = len(projects) > 0 - filter_by_keyword = search != "" and search is not None - if completed is not None and self.completed != completed: - return False - if filter_by_context and not _has_intersection(self.contexts, contexts): - return False - if filter_by_project and not _has_intersection(self.projects, projects): - return False - if filter_by_keyword: - if re.search(search, self.description, re.IGNORECASE): - return True - if "id" in self.keyval: - if re.search(search, self.keyval.get("id"), re.IGNORECASE): - return True - return False - return True - - def set_keyval(self, new_keyval: Mapping[str, str]): - old_keyval = self.keyval - for key in ( - "id", - "createdAt", - "firstCreatedAt", - "lastStartedAt", - "status", - "workDuration", - ): - if key in old_keyval and key not in new_keyval: - new_keyval[key] = old_keyval[key] - self.keyval = new_keyval - - def start(self): - timestamp = round(CURRENT_TIME.timestamp()) - self.keyval["lastStartedAt"] = timestamp - if "firstStartedAt" not in self.keyval: - self.keyval["firstStartedAt"] = timestamp - if "workDuration" not in self.keyval: - self.keyval["workDuration"] = 0 - self.keyval["status"] = "started" - - def stop(self): - self._stop() - self.keyval["status"] = "stopped" - - def complete(self): - self._stop() - self.completed = True - self.completion_date = CURRENT_TIME - self.keyval["status"] = "completed" - - def _stop(self): - timestamp = round(CURRENT_TIME.timestamp()) - if self.get_status() != "STARTED": - return - self.keyval["lastStoppedAt"] = timestamp - last_started_at = int(self.keyval.get("lastStartedAt", str(timestamp))) - previous_duration = int(self.keyval.get("workDuration", "0")) - self.keyval["workDuration"] = previous_duration + (timestamp - last_started_at) - - def as_pretty_str(self, screen_width: int = SCREEN_WIDTH) -> str: - # complete - completed_str = "x" if self.completed else " " - completed_str = colored(completed_str, color="cyan") - # priority - priority_str = "( )" if self.priority is None else f"({self.priority})" - priority_str = colored(priority_str, color="magenta") - # completion date - completion_date_str = ( - " " * 10 - if self.completion_date is None - else self.completion_date.strftime("%Y-%m-%d") - ) - completion_date_str = colored(completion_date_str, color="yellow") - # creation date - creation_date_str = ( - " " * 10 - if self.creation_date is None - else self.creation_date.strftime("%Y-%m-%d") - ) - creation_date_str = colored(creation_date_str, color="green") - # project - project_str = " ".join([f"+{project}" for project in sorted(self.projects)]) - if project_str != "": - project_str = colored(f" {project_str}", color="yellow") - # context - context_str = " ".join([f"@{context}" for context in sorted(self.contexts)]) - if context_str != "": - context_str = colored(f" {context_str}", color="blue") - # keyval - keyval_str = " ".join( - f"{key}:{val}" for key, val in self._get_published_keyval().items() - ) - if keyval_str != "": - keyval_str = colored(f" {keyval_str}", color="magenta") - # id - id = self.keyval.get("id") - id_str = colored(f"[{id}]", attrs=["dark"]) - # description - description_str = self._get_colored_description() - # Status string - status_icon = self._get_status_icon() - # work duration - work_duration_str = self.get_work_duration_str() - if work_duration_str != "": - work_duration_str = colored(f" (⚙️ {work_duration_str})", color="cyan") - # duration - duration_str = self.get_duration_str() - if duration_str != "": - duration_str = colored(f" (🌱 {duration_str})", color="green") - # small screen - if screen_width <= 80: - return f"{completed_str} {priority_str} {status_icon} {id_str} {description_str}{project_str}{context_str}{keyval_str}{work_duration_str}" # noqa - # normal screen - return f"{completed_str} {priority_str} {completion_date_str} {creation_date_str} {status_icon} {id_str} {description_str}{project_str}{context_str}{keyval_str}{duration_str}{work_duration_str}" # noqa - - def _get_published_keyval(self): - return { - key: val - for key, val in self.keyval.items() - if key - not in [ - "id", - "createdAt", - "firstStartedAt", - "lastStartedAt", - "lastStoppedAt", - "status", - "workDuration", - ] - } - - def _get_colored_description(self): - status = self.get_status() - description_str = self.description - return colored( - description_str, - color=STATUS_COLOR_MAP.get(status), - attrs=STATUS_ATTRIBUTE_MAP.get(status), - ) - - def _get_status_icon(self): - status = self.get_status() - status_str = STATUS_ICON_MAP.get(status) - return status_str - - def get_status(self): - if self.completed: - return "COMPLETED" - status = self.keyval.get("status", "new").upper() - if status not in STATUS_ICON_MAP: - status = "NEW" - return status - - def get_work_duration_str(self): - status = self.keyval.get("status", "new").upper() - # get working duration - work_duration = int(self.keyval.get("workDuration", "0")) - if status == "STARTED": - last_started_at = int(self.keyval.get("lastStartedAt", "-1")) - if last_started_at != -1: - work_duration += round(CURRENT_TIME.timestamp() - last_started_at) - if work_duration == 0: - return "" - return _seconds_to_human_time(work_duration) - - def get_duration_str(self): - created_at = int(self.keyval.get("createdAt", "-1")) - if created_at == -1 and self.creation_date is not None: - created_at = self.creation_date.timestamp() - duration = round(CURRENT_TIME.timestamp() - created_at) - if duration == 0: - return "" - return _seconds_to_human_time(duration) - - def as_str(self) -> str: - # complete - completed_str = "x " if self.completed else "" - # priority - priority_str = "" if self.priority is None else f"({self.priority}) " - # completion date - completion_date_str = ( - "" - if self.completion_date is None - else self.completion_date.strftime("%Y-%m-%d") + " " - ) - # creation date - creation_date_str = ( - "" - if self.creation_date is None - else self.creation_date.strftime("%Y-%m-%d") + " " - ) - # project - project_str = " ".join([f"+{project}" for project in sorted(self.projects)]) - if project_str != "": - project_str = f" {project_str}" - # context - context_str = " ".join([f"@{context}" for context in sorted(self.contexts)]) - if context_str != "": - context_str = f" {context_str}" - # keyval - keyval_str = " ".join(f"{key}:{val}" for key, val in self.keyval.items()) - if keyval_str != "": - keyval_str = f" {keyval_str}" - return f"{completed_str}{priority_str}{completion_date_str}{creation_date_str}{self.description}{project_str}{context_str}{keyval_str}" # noqa - - -def _has_intersection(list1: List[str], list2: List[str]): - set1 = set(list1) - set2 = set(list2) - return not set1.isdisjoint(set2) - - -def _seconds_to_human_time(seconds: int): - years = seconds // 31536000 - seconds %= 31536000 - months = seconds // 2592000 - seconds %= 2592000 - days = seconds // 86400 - seconds %= 86400 - hours = seconds // 3600 - seconds %= 3600 - minutes = seconds // 60 - if years > 0: - return f"{years}y {months}m {days}d" - if months > 0: - return f"{months}m {days}d {hours}h" - if days > 0: - return f"{days}d {hours}h" - if hours > 0: - return f"{hours}h {minutes} min" - if minutes == 0: - return "" - return f"{minutes} min" diff --git a/_daily/noto/todo/_group.py b/_daily/noto/todo/_group.py deleted file mode 100644 index 70baaf1..0000000 --- a/_daily/noto/todo/_group.py +++ /dev/null @@ -1,3 +0,0 @@ -from zrb import Group - -TODO_GROUP = Group(name="todo", description="To do") diff --git a/_daily/noto/todo/_helper.py b/_daily/noto/todo/_helper.py deleted file mode 100644 index be96d5b..0000000 --- a/_daily/noto/todo/_helper.py +++ /dev/null @@ -1,198 +0,0 @@ -import os -import re -from datetime import datetime -from pathlib import Path -from typing import List, Mapping, Optional - -from _daily.noto._config import TODO_FILE_NAME -from _daily.noto._helper import get_screen_width -from _daily.noto.todo._data import Item - -SCREEN_WIDTH = get_screen_width() - - -def parse_item(line: str) -> Item: - line = line.strip() - # Check for completion - completed = line.startswith("x ") - if completed: - line = line[2:] - # Check for priority - priority_match = re.match(r"\(([A-Z])\) ", line) - priority = None - if priority_match: - priority, line = (priority_match.group(1), line[len(priority_match.group(0)) :]) - # Check for completion date - date_match = re.match(r"(\d{4}-\d{2}-\d{2}) ", line) - completion_date = None - if date_match: - completion_date, line = ( - datetime.strptime(date_match.group(1), "%Y-%m-%d"), - line[len(date_match.group(0)) :], - ) - # Check for creation date - date_match = re.match(r"(\d{4}-\d{2}-\d{2}) ", line) - creation_date = None - if date_match: - creation_date, line = ( - datetime.strptime(date_match.group(1), "%Y-%m-%d"), - line[len(date_match.group(0)) :], - ) - elif completion_date is not None: - creation_date = completion_date - completion_date = None - # Extract contexts and projects - contexts = [context.lstrip("@") for context in re.findall(r"@[\w\-]+", line)] - projects = [project.lstrip("+") for project in re.findall(r"\+[\w\-]+", line)] - keyval_match_list = re.findall(r"([\w\-]+):([\w\-]+)", line) - keyval = {} - for keyval_match in keyval_match_list: - keyval[keyval_match[0]] = keyval_match[1] - # Remove contexts, projects, and keyval from description - description = re.sub( - r"(@[\w\-]+|\+[\w\-]+|[\w\-]+:[\w\-]+)", "", line - ).strip() - return Item( - description=description, - old_description=description, - completed=completed, - priority=priority, - completion_date=completion_date, - creation_date=creation_date, - contexts=contexts, - projects=projects, - keyval=keyval, - ) - - -def append_item(item: Item, file_name: str = TODO_FILE_NAME) -> str: - dir_path = Path(os.path.dirname(file_name)) - dir_path.mkdir(parents=True, exist_ok=True) - items = get_items(file_name=file_name) - items.append(item) - _write_items(items, file_name) - - -def get_items( - contexts: List[str] = [], - projects: List[str] = [], - search: str = "", - completed: Optional[bool] = None, - file_name: str = TODO_FILE_NAME, -) -> List[Item]: - dir_path = Path(os.path.dirname(file_name)) - dir_path.mkdir(parents=True, exist_ok=True) - if not os.path.isfile(file_name): - return [] - with open(file_name, "r") as file: - content = file.read() - lines = content.split("\n") - items: List[Item] = [] - for line in lines: - line = line.strip() - if not line: - continue - item = parse_item(line) - if item.match( - contexts=contexts, projects=projects, search=search, completed=completed - ): - items.append(item) - return _sort_items(items) - - -def stop_item(item: Item, file_name: str = TODO_FILE_NAME): - item.stop() - replace_item(item, file_name) - - -def start_item(item: Item, file_name: str = TODO_FILE_NAME): - item.start() - replace_item(item, file_name) - - -def complete_item(item: Item, file_name: str = TODO_FILE_NAME): - item.complete() - replace_item(item, file_name) - - -def delete_item(item: Item, file_name: str = TODO_FILE_NAME): - items = [ - old_item - for old_item in get_items(file_name=file_name) - if old_item.description != item.old_description - ] - _write_items(items, file_name) - - -def replace_item(item: Item, file_name: str = TODO_FILE_NAME): - items = get_items(file_name=file_name) - for index, existing_item in enumerate(items): - if item.old_description == existing_item.description: - items[index] = item - break - _write_items(items, file_name) - - -def get_existing_contexts(file_name: str = TODO_FILE_NAME) -> List[str]: - existing_contexts = set() - items = get_items(file_name=file_name) - for item in items: - existing_contexts.update(item.contexts) - return sorted(list(existing_contexts)) - - -def get_existing_projects(file_name: str = TODO_FILE_NAME) -> List[str]: - existing_projects = set() - items = get_items(file_name=file_name) - for item in items: - existing_projects.update(item.projects) - return sorted(list(existing_projects)) - - -def get_pretty_item_lines( - items: List[Item], screen_width: int = SCREEN_WIDTH -) -> List[str]: - if screen_width <= 80: - return [ - " Description", - *[item.as_pretty_str(screen_width=screen_width) for item in items], - ] - return [ - " Completed Created Description", - *[item.as_pretty_str(screen_width=screen_width) for item in items], - ] - - -def read_keyval_input(keyval_input: str) -> Mapping[str, str]: - keyval = {} - for keyval_str in keyval_input.split(","): - keyval_part = keyval_str.strip().split(":") - if len(keyval_part) < 2: - raise Exception(f"Invalid keyval: {keyval_str}") - keyval[keyval_part[0]] = keyval_part[1] - return keyval - - -def _write_items(items: List[Item], file_name: str = TODO_FILE_NAME): - items = _sort_items(items) - with open(file_name, "w") as file: - file.write("\n".join([item.as_str() for item in items])) - file.write("\n") - - -def _sort_items(items: List[Item]) -> List[Item]: - return sorted( - items, - key=lambda item: ( - item.completed, - item.priority, - sorted(item.projects), - sorted(item.contexts), - ), - ) - - -def _has_intersection(list1: List[str], list2: List[str]): - set1 = set(list1) - set2 = set(list2) - return not set1.isdisjoint(set2) diff --git a/_daily/noto/todo/add.py b/_daily/noto/todo/add.py deleted file mode 100644 index 769e5e5..0000000 --- a/_daily/noto/todo/add.py +++ /dev/null @@ -1,106 +0,0 @@ -from zrb import StrInput, Task, python_task, runner -from zrb.helper.accessories.color import colored -from zrb.helper.task import show_lines - -from _daily.noto._config import CURRENT_DAY, CURRENT_MONTH, CURRENT_TIME, CURRENT_YEAR -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.todo._data import Item -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import ( - append_item, - get_existing_contexts, - get_existing_projects, - get_items, - get_pretty_item_lines, - read_keyval_input, -) - -_EXISTING_CONTEXT_STR = ",".join(get_existing_contexts()) -_EXISTING_PROJECT_STR = ",".join(get_existing_projects()) - - -@python_task( - name="add", - group=TODO_GROUP, - inputs=[ - StrInput( - name="description", - shortcut="t", - prompt="Description", - default="", - ), - StrInput( - name="priority", - prompt="Priority", - default="C", - ), - StrInput( - name="project", - prompt=f"Project, comma separated (e.g., {_EXISTING_PROJECT_STR})", - default="", - ), - StrInput( - name="context", - prompt=f"Context, comma separated (e.g., {_EXISTING_CONTEXT_STR})", - default="", - ), - StrInput( - name="keyval", - prompt=f"Keyval, comma separated (e.g., due:{CURRENT_YEAR}-{CURRENT_MONTH}-{CURRENT_DAY},jira:1234)", # noqa - default="", - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def add(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - description = kwargs.get("description") - if description.strip() == "": - task.print_err(colored("⚠️ NOT ADDED: Description cannot be empty")) - return - duplication = [item for item in get_items() if item.old_description == description] - if len(duplication) > 0: - task.print_err( - colored( - "⚠️ NOT ADDED: There is task with the same description", - color="light_red", - ), - ) - return - # priority - priority = kwargs.get("priority") - if priority.strip() == "": - priority = "C" - # contexts - contexts = [] - context_str = kwargs.get("context") - if context_str.strip() != "": - contexts = [context.strip() for context in context_str.split(",")] - # projects - projects = [] - project_str = kwargs.get("project") - if project_str.strip() != "": - projects = [project.strip() for project in project_str.split(",")] - # keyval - keyval = {} - keyval_input = kwargs.get("keyval") - if keyval_input.strip() != "": - keyval = read_keyval_input(keyval_input) - keyval["createdAt"] = round(CURRENT_TIME.timestamp()) - item = Item( - description=description, - priority=priority, - creation_date=CURRENT_TIME, - contexts=contexts, - projects=projects, - keyval=keyval, - ) - append_item(item=item) - sync_noto(task) - show_lines(task, *get_pretty_item_lines(get_items())) - - -runner.register(add) diff --git a/_daily/noto/todo/complete.py b/_daily/noto/todo/complete.py deleted file mode 100644 index 21862aa..0000000 --- a/_daily/noto/todo/complete.py +++ /dev/null @@ -1,55 +0,0 @@ -from zrb import StrInput, Task, python_task, runner -from zrb.helper.accessories.color import colored -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.log._helper import append_log, get_pretty_log_lines -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import complete_item, get_items, get_pretty_item_lines - - -@python_task( - name="complete", - group=TODO_GROUP, - inputs=[ - StrInput( - name="task", - shortcut="t", - prompt="Search pattern (regex)", - prompt_required=True, - default="", - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def complete(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - search = kwargs.get("task") - items = get_items(search=search, completed=False) - if len(items) == 0: - show_lines( - task, - colored("⚠️ NOT COMPLETED: Task not found", color="light_red"), - "List of available tasks:", - *get_pretty_item_lines(get_items(completed=False)), - ) - return - if len(items) > 1: - show_lines( - task, - colored("⚠️ NOT COMPLETED: Multiple task found", color="light_red"), - "List of matched tasks:", - *get_pretty_item_lines(items), - ) - return - item = items[0] - complete_item(item) - append_log(f"__COMPLETE__ {item.description}") - sync_noto(task) - show_lines(task, *get_pretty_log_lines(), "", *get_pretty_item_lines(get_items())) - - -runner.register(complete) diff --git a/_daily/noto/todo/delete.py b/_daily/noto/todo/delete.py deleted file mode 100644 index 192e5a5..0000000 --- a/_daily/noto/todo/delete.py +++ /dev/null @@ -1,53 +0,0 @@ -from zrb import StrInput, Task, python_task, runner -from zrb.helper.accessories.color import colored -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import delete_item, get_items, get_pretty_item_lines - - -@python_task( - name="delete", - group=TODO_GROUP, - inputs=[ - StrInput( - name="task", - shortcut="t", - prompt="Search pattern (regex)", - prompt_required=True, - default="", - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def delete(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - search = kwargs.get("task") - items = get_items(search=search) - if len(items) == 0: - show_lines( - task, - colored("⚠️ NOT DELETED: Task not found", color="light_red"), - "List of available tasks:", - *get_pretty_item_lines(get_items()), - ) - return - if len(items) > 1: - show_lines( - task, - colored("⚠️ NOT DELETED: Multiple task found", color="light_red"), - "List of matched tasks:", - *get_pretty_item_lines(items), - ) - return - item = items[0] - delete_item(item) - sync_noto(task) - show_lines(task, *get_pretty_item_lines(get_items())) - - -runner.register(delete) diff --git a/_daily/noto/todo/edit.py b/_daily/noto/todo/edit.py deleted file mode 100644 index c6fa3ea..0000000 --- a/_daily/noto/todo/edit.py +++ /dev/null @@ -1,122 +0,0 @@ -from zrb import StrInput, Task, python_task, runner -from zrb.helper.accessories.color import colored -from zrb.helper.task import show_lines - -from _daily.noto._config import CURRENT_DAY, CURRENT_MONTH, CURRENT_YEAR -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.log._helper import get_pretty_log_lines -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import ( - get_existing_contexts, - get_existing_projects, - get_items, - get_pretty_item_lines, - read_keyval_input, - replace_item, -) - -_EXISTING_CONTEXT_STR = ",".join(get_existing_contexts()) -_EXISTING_PROJECT_STR = ",".join(get_existing_projects()) - - -@python_task( - name="edit", - group=TODO_GROUP, - inputs=[ - StrInput( - name="task", - shortcut="t", - prompt="Task", - default="", - ), - StrInput( - name="description", - prompt="New description", - default="", - ), - StrInput( - name="priority", - prompt="New priority", - default="", - ), - StrInput( - name="project", - prompt=f"New project, comma separated (e.g., {_EXISTING_PROJECT_STR})", - default="", - ), - StrInput( - name="context", - prompt=f"New context, comma separated (e.g., {_EXISTING_CONTEXT_STR})", - default="", - ), - StrInput( - name="keyval", - prompt=f"New keyval, comma separated (e.g., due:{CURRENT_YEAR}-{CURRENT_MONTH}-{CURRENT_DAY},jira:1234)", # noqa - default="", - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def edit(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - # Getting the item - search = kwargs.get("task") - items = get_items(search=search, completed=False) - if len(items) == 0: - show_lines( - task, - colored("⚠️ NOT COMPLETED: Task not found", color="light_red"), - "List of available tasks:", - *get_pretty_item_lines(get_items(completed=False)), - ) - return - if len(items) > 1: - show_lines( - task, - colored("⚠️ NOT COMPLETED: Multiple task found", color="light_red"), - "List of matched tasks:", - *get_pretty_item_lines(items), - ) - return - item = items[0] - # description - description = kwargs.get("description") - if description.strip() != "": - duplication = [ - item for item in get_items() if item.old_description == description - ] - if len(duplication) > 0: - task.print_err( - colored( - "⚠️ NOT ADDED: There is task with the same description", - color="light_red", - ), - ) - return - item.description = description - # priority - priority = kwargs.get("priority") - if priority.strip() != "": - item.priority = priority - # contexts - context_str = kwargs.get("context") - if context_str.strip() != "": - item.contexts = [context.strip() for context in context_str.split(",")] - # projects - project_str = kwargs.get("project") - if project_str.strip() != "": - item.projects = [project.strip() for project in project_str.split(",")] - # keyval - keyval_input = kwargs.get("keyval") - if keyval_input.strip() != "": - item.set_keyval(read_keyval_input(keyval_input)) - # save item - replace_item(item) - sync_noto(task) - show_lines(task, *get_pretty_log_lines(), "", *get_pretty_item_lines(get_items())) - - -runner.register(edit) diff --git a/_daily/noto/todo/find.py b/_daily/noto/todo/find.py deleted file mode 100644 index 11ff4cc..0000000 --- a/_daily/noto/todo/find.py +++ /dev/null @@ -1,65 +0,0 @@ -from zrb import StrInput, Task, python_task, runner -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import ( - get_existing_contexts, - get_existing_projects, - get_items, - get_pretty_item_lines, -) - -_EXISTING_CONTEXT_STR = ",".join(get_existing_contexts()) -_EXISTING_PROJECT_STR = ",".join(get_existing_projects()) - - -@python_task( - name="find", - group=TODO_GROUP, - inputs=[ - StrInput( - name="task", - shortcut="t", - prompt="Search pattern (regex)", - default="", - ), - StrInput( - name="project", - prompt=f"Project, comma separated (e.g., {_EXISTING_PROJECT_STR})", - default="", - ), - StrInput( - name="context", - prompt=f"Context, comma separated (e.g., {_EXISTING_CONTEXT_STR})", - default="", - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def find(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - contexts = [] - context_str = kwargs.get("context") - if context_str: - contexts = [context.strip() for context in context_str.split(",")] - projects = [] - project_str = kwargs.get("project") - if project_str: - projects = [project.strip() for project in project_str.split(",")] - search = kwargs.get("search") - show_lines( - task, - f"Projects: {projects}", - f"Contexts: {contexts}", - f"Search: {search}", - *get_pretty_item_lines( - get_items(contexts=contexts, projects=projects, search=search) - ), - ) - - -runner.register(find) diff --git a/_daily/noto/todo/kanban/__init__.py b/_daily/noto/todo/kanban/__init__.py deleted file mode 100644 index 935a6ae..0000000 --- a/_daily/noto/todo/kanban/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from _daily.noto.todo.kanban import kanban - -assert kanban diff --git a/_daily/noto/todo/kanban/__pycache__/__init__.cpython-310.pyc b/_daily/noto/todo/kanban/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 6708139..0000000 Binary files a/_daily/noto/todo/kanban/__pycache__/__init__.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/kanban/__pycache__/_helper.cpython-310.pyc b/_daily/noto/todo/kanban/__pycache__/_helper.cpython-310.pyc deleted file mode 100644 index ab5e030..0000000 Binary files a/_daily/noto/todo/kanban/__pycache__/_helper.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/kanban/__pycache__/kanban.cpython-310.pyc b/_daily/noto/todo/kanban/__pycache__/kanban.cpython-310.pyc deleted file mode 100644 index 87d529a..0000000 Binary files a/_daily/noto/todo/kanban/__pycache__/kanban.cpython-310.pyc and /dev/null differ diff --git a/_daily/noto/todo/kanban/_helper.py b/_daily/noto/todo/kanban/_helper.py deleted file mode 100644 index 723bea1..0000000 --- a/_daily/noto/todo/kanban/_helper.py +++ /dev/null @@ -1,100 +0,0 @@ -from typing import List, Mapping - -from zrb.helper.accessories.color import colored - -from _daily.noto.todo._data import STATUS_ATTRIBUTE_MAP, STATUS_COLOR_MAP, Item - - -def get_kanban_lines(items: List[Item], screen_width: int) -> List[str]: - status_lines: Mapping[str][List[str]] = {} - status_max_length: Mapping[str][int] = {} - status_list = ("NEW", "STOPPED", "STARTED", "COMPLETED") - max_width = max(round(screen_width/4), 15) - for status in status_list: - status_lines[status] = [] - for item in items: - if item.get_status() != status: - continue - item_id = item.keyval.get("id", "") - if item_id != "": - status_lines[status].append(f"* [{item_id}]"[:max_width]) - status_lines[status].append(f" {item.description}"[:max_width]) - project_str = " ".join(f"+{project}" for project in sorted(item.projects)) - context_str = " ".join(f"@{context}" for context in sorted(item.contexts)) - work_duration = item.get_work_duration_str() - duration = item.get_duration_str() - if ( - project_str != "" - or context_str != "" - or work_duration != "" - or duration != "" - ): - status_lines[status].append("") - if project_str != "": - status_lines[status].append(f" {project_str}"[:max_width]) - if context_str != "": - status_lines[status].append(f" {context_str}"[:max_width]) - if work_duration != "": - status_lines[status].append(f" Work: {work_duration}"[:max_width]) - if duration != "": - status_lines[status].append(f" Age: {duration}"[:max_width]) - status_lines[status].append("") - status_max_length[status] = ( - max(len(s) for s in status_lines[status]) - if len(status_lines[status]) > 0 - else len(status) - ) - # initiate view - header = _get_kanban_header(status_list, status_max_length) - separator = _get_kanban_separator(status_list, status_max_length) - body = _get_kanban_body(status_list, status_max_length, status_lines) - return [separator, header, separator, *body, separator] - - -def _get_kanban_body( - status_list: List[str], - status_max_length: Mapping[str, int], - status_lines: Mapping[str, List[str]], -) -> List[str]: - lines = [] - index = 0 - while True: - # check stopping condition - should_stop = True - for status in status_list: - if index < len(status_lines[status]): - should_stop = False - if should_stop: - break - combined_line = "" - for status in status_list: - line_size = len(status_lines[status]) - line = status_lines[status][index] if index < line_size else "" - line = line.ljust(status_max_length[status] + 3) - line = colored(line, color=STATUS_COLOR_MAP[status]) - combined_line += line.ljust(status_max_length[status] + 3) - lines.append(combined_line) - index += 1 - return lines - - -def _get_kanban_header( - status_list: List[str], status_max_length: Mapping[str, int] -) -> str: - # header - header = "" - for status in status_list: - caption = status.ljust(status_max_length[status] + 3) - header += colored( - caption, - color=STATUS_COLOR_MAP[status], - attrs=STATUS_ATTRIBUTE_MAP[status], - ) - return header - - -def _get_kanban_separator( - status_list: List[str], status_max_length: Mapping[str, int] -) -> str: - max_length = sum([status_max_length[status] + 3 for status in status_list]) - return "-" * max_length diff --git a/_daily/noto/todo/kanban/kanban.py b/_daily/noto/todo/kanban/kanban.py deleted file mode 100644 index f329e3c..0000000 --- a/_daily/noto/todo/kanban/kanban.py +++ /dev/null @@ -1,28 +0,0 @@ -from zrb import Task, python_task, runner -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto, get_screen_width -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import get_items -from _daily.noto.todo.kanban._helper import get_kanban_lines - - -@python_task( - name="kanban", - group=TODO_GROUP, - envs=[PROJECT_DIR_ENV], - retry=0, -) -def kanban(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - items = get_items() - screen_width = get_screen_width() - show_lines( - task, - *get_kanban_lines(items, screen_width), - ) - - -runner.register(kanban) diff --git a/_daily/noto/todo/list.py b/_daily/noto/todo/list.py deleted file mode 100644 index 514e4f2..0000000 --- a/_daily/noto/todo/list.py +++ /dev/null @@ -1,25 +0,0 @@ -from zrb import Task, python_task, runner -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import get_items, get_pretty_item_lines - - -@python_task( - name="list", - group=TODO_GROUP, - envs=[PROJECT_DIR_ENV], - retry=0, -) -def list_todo(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - show_lines( - task, - *get_pretty_item_lines(get_items()), - ) - - -runner.register(list_todo) diff --git a/_daily/noto/todo/start.py b/_daily/noto/todo/start.py deleted file mode 100644 index 5bccc36..0000000 --- a/_daily/noto/todo/start.py +++ /dev/null @@ -1,55 +0,0 @@ -from zrb import StrInput, Task, python_task, runner -from zrb.helper.accessories.color import colored -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.log._helper import append_log, get_pretty_log_lines -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import get_items, get_pretty_item_lines, start_item - - -@python_task( - name="start", - group=TODO_GROUP, - inputs=[ - StrInput( - name="task", - shortcut="t", - prompt="Search pattern (regex)", - prompt_required=True, - default="", - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def start(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - search = kwargs.get("task") - items = get_items(search=search, completed=False) - if len(items) == 0: - show_lines( - task, - colored("⚠️ NOT STARTED: Task not found", color="light_red"), - "List of available tasks:", - *get_pretty_item_lines(get_items(completed=False)), - ) - return - if len(items) > 1: - show_lines( - task, - colored("⚠️ NOT STARTED: Multiple task found", color="light_red"), - "List of matched tasks:", - *get_pretty_item_lines(items), - ) - return - item = items[0] - start_item(item) - append_log(f"__START__ {item.description}") - sync_noto(task) - show_lines(task, *get_pretty_log_lines(), "", *get_pretty_item_lines(get_items())) - - -runner.register(start) diff --git a/_daily/noto/todo/stop.py b/_daily/noto/todo/stop.py deleted file mode 100644 index cff2b5a..0000000 --- a/_daily/noto/todo/stop.py +++ /dev/null @@ -1,55 +0,0 @@ -from zrb import StrInput, Task, python_task, runner -from zrb.helper.accessories.color import colored -from zrb.helper.task import show_lines - -from _daily.noto._env import PROJECT_DIR_ENV -from _daily.noto._helper import sync_noto -from _daily.noto.log._helper import append_log, get_pretty_log_lines -from _daily.noto.todo._group import TODO_GROUP -from _daily.noto.todo._helper import get_items, get_pretty_item_lines, stop_item - - -@python_task( - name="stop", - group=TODO_GROUP, - inputs=[ - StrInput( - name="task", - shortcut="t", - prompt="Search pattern (regex)", - prompt_required=True, - default="", - ), - ], - envs=[PROJECT_DIR_ENV], - retry=0, -) -def stop(*args, **kwargs): - task: Task = kwargs.get("_task") - sync_noto(task) - search = kwargs.get("task") - items = get_items(search=search, completed=False) - if len(items) == 0: - show_lines( - task, - colored("⚠️ NOT STOPPED: Task not found", color="light_red"), - "List of available tasks:", - *get_pretty_item_lines(get_items(completed=False)), - ) - return - if len(items) > 1: - show_lines( - task, - colored("⚠️ NOT STOPPED: Multiple task found", color="light_red"), - "List of matched tasks:", - *get_pretty_item_lines(items), - ) - return - item = items[0] - stop_item(item) - append_log(f"__STOP__ {item.description}") - sync_noto(task) - show_lines(task, *get_pretty_log_lines(), "", *get_pretty_item_lines(get_items())) - - -runner.register(stop) diff --git a/_daily/noto/wiki.py b/_daily/noto/wiki.py deleted file mode 100644 index 70b9b2f..0000000 --- a/_daily/noto/wiki.py +++ /dev/null @@ -1,10 +0,0 @@ -import os -from zrb import create_wiki_tasks, runner - -from _daily.noto._config import SRC_DIR -from _daily.noto._group import NOTO_WIKI_GROUP - -wiki_dir = os.path.join(SRC_DIR, "wiki") - -if os.path.isdir(wiki_dir): - create_wiki_tasks(directory=wiki_dir, group=NOTO_WIKI_GROUP, runner=runner)