From b26818dad13db472b20e299d96d0fb124417a5e6 Mon Sep 17 00:00:00 2001 From: Stepanov Aleksey Date: Sun, 11 May 2025 14:12:21 +0500 Subject: add taskwarrior-tui-scripts project --- lib/edit.sh | 107 +++++++++++++++++++++ lib/environment.sh | 43 +++++++++ lib/global.sh | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/project.sh | 78 ++++++++++++++++ 4 files changed, 493 insertions(+) create mode 100755 lib/edit.sh create mode 100755 lib/environment.sh create mode 100755 lib/global.sh create mode 100755 lib/project.sh (limited to 'lib') diff --git a/lib/edit.sh b/lib/edit.sh new file mode 100755 index 0000000..be271aa --- /dev/null +++ b/lib/edit.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash + +#****F* lib/global.sh +# NAME +# +# global.sh - общие функции для всех скриптов. +# +# USES +# +# - environment.sh +#****** + +function getIdsTask() { + local nameProject + + nameProject=$(getNameProject "$1") + + readarray -t idsTaskProject < <(task project:"$nameProject" +current _ids) + printf '%s\n' "${idsTaskProject[@]}" +} + +function getFileHash() { + sha256sum "$1" | awk '{print $1}' +} + +function checkFilesHash() { + local originalHash + local currentHash + + originalHash=$(getFileHash "/tmp/tskw.edit.bak") + currentHash=$(getFileHash "/tmp/tskw.edit") + + if [[ "$originalHash" != "$currentHash" ]]; then + readarray -t taskStages < <(grep -v "^#" /tmp/tskw.edit + fi + + if [[ "${#tasksProject[@]}" -eq 0 ]]; then + + echo "# Проект без этапов. Эта строка будет проигнорирована." >>/tmp/tskw.edit + + backupStages + editStages + checkFilesHash + + return 0 + fi + + for taskID in "${tasksProject[@]}"; do + local uuid + uuid=$(task _get "$taskID".uuid) + + task _get "$uuid".description >>/tmp/tskw.edit + done + + backupStages + editStages + checkFilesHash +} + +function deleteProject() { + local idsTaskProject + local nameProject + + idsTaskProject=$(getIdsTask "$1") + nameProject=$(getNameProject "$1") + + if [[ "${#idsTaskProject[@]}" -eq 0 ]]; then + return + else + task rc.bulk=0 rc.confirmation=off project:"$nameProject" -COMPLETED -DELETED +current delete + fi +} + +function recreateProject() { + for taskIndex in "${!taskStages[@]}"; do + if [[ "$taskIndex" -eq 0 ]]; then + task add "${taskStages[$taskIndex]}" project:"$nameProject" order:$(("$taskIndex" + 2 - 1)) +current + else + task add "${taskStages[$taskIndex]}" project:"$nameProject" depends:"$uuidNewTask" order:$(("$taskIndex" + 2 - 1)) +current + fi + + local uuidNewTask + uuidNewTask=$(getLatestTaskUuid) + done +} diff --git a/lib/environment.sh b/lib/environment.sh new file mode 100755 index 0000000..00f69e7 --- /dev/null +++ b/lib/environment.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2016 + +#****F* lib/environment.sh +# NAME +# +# environment.sh - файл c основными константами и переменными. +# +# USED BY +# +# - edit_project.sh +# - jtx.sh +# - someday.sh +# - project.sh +# - start_stop.sh +#****** + +# Global +# +#****d* environment.sh/ROOT_DIR +# NAME +# +# ROOT_DIR - корень проекта. +#****** +export ROOT_DIR="$HOME/bin/taskwarrior-tui-scripts" + +#****d* environment.sh/LIB_DIR +# NAME +# +# LIB_DIR - папка с вспомогательными функциями. +#****** +export LIB_DIR="$ROOT_DIR/lib" + +#****d* environment.sh/MY_CAL +# NAME +# +# MY_CAL - папка с ics файлами календаря my_cal. +# +# NOTES +# +# https://baikal.bluig.xyz/dav.php/calendars/me/my_cal/ +#****** +export MY_CAL="$XDG_DATA_HOME/.calendars/my_cal" diff --git a/lib/global.sh b/lib/global.sh new file mode 100755 index 0000000..58f8721 --- /dev/null +++ b/lib/global.sh @@ -0,0 +1,265 @@ +#!/usr/bin/env bash + +#****F* lib/global.sh +# NAME +# +# global.sh - общие функции для всех скриптов. +# +# USES +# +# - environment.sh +#****** + +#****f* global.sh/notify +# NAME +# +# notify - вывод сообщения через notify-send. +# +# ARGUMENTS +# +# category - категория уведомления. +# message - строка сообщения. +# +# USAGE +# +# notify +# +# EXAMPLE +# +# notify "msg-error" "Ошибка!" +# +# NOTES +# +# Категории уведомлений находятся в $HOME/.config/mako/category +# +# USES +# +# - global.sh +# - project.sh +# - edit.sh +# - someday.sh +# - start_stop.sh +# - edit_project.sh +#****** +function notify() { + notify-send -t 3000 -a "taskwarrior" -c "$1" "$2" +} + +#****f* global.sh/getLatestTaskId +# NAME +# +# getLatestTaskId - возвращает id задачи. +# +# DESCRIPTION +# +# Возвращает id задачи с тегом +LATEST, которая является самой последней из добавленных. +# +# USES +# +# - project.sh +# +# NOTES +# +# https://taskwarrior.org/docs/tags/ +# +# RETURN VALUE +# +# return {string} - Id задачи +#****** +function getLatestTaskId() { + task +LATEST _id +} + +#****f* global.sh/getLatestTaskUuid +# NAME +# +# getLatestTaskUuid - возвращает id задачи. +# +# DESCRIPTION +# +# Возвращает uuid задачи с тегом +LATEST, которая является самой последней из добавленных. +# +# USES +# +# - project.sh +# +# NOTES +# +# https://taskwarrior.org/docs/tags/ +# +# RETURN VALUE +# +# return {string} - Uuid задачи +#****** +function getLatestTaskUuid() { + task +LATEST _uuid +} + +#****f* global.sh/getTags +# NAME +# +# getTags - возвращает массив тегов задачи. +# +# ARGUMENTS +# +# id | uuid - id или uuid задачи. +# +# USAGE +# +# getTags +# +# USES +# +# - project.sh +# - someday.sh +# - edit_project.sh +# +# RETURN VALUE +# +# return {Array} - Массив тегов +#****** +function getTags() { + task "$1" export | jq -r '.[].tags? | .[]?' +} + +#****f* global.sh/getNameProject +# NAME +# +# getNameProject - возвращает название проекта задачи. +# +# ARGUMENTS +# +# id | uuid - id или uuid задачи. +# +# USAGE +# +# getNameProject +# +# USES +# +# - edit.sh +# +# RETURN VALUE +# +# return {String} - Uuid задачи +#****** +function getNameProject() { + task "$1" _project +} + +#****f* global.sh/getAnnotationCount +# NAME +# +# getAnnotationCount - возвращает длину массива аннотаций задачи. +# +# ARGUMENTS +# +# id | uuid - id или uuid задачи. +# +# USAGE +# +# getAnnotationCount +# +# USES +# +# - project.sh +# +# RETURN VALUE +# +# return {String} - Количество аннотаций +#****** +function getAnnotationCount() { + task "$1" export | jq -r '.[] | .annotations | length' +} + +#****f* global.sh/checkExistingProject +# NAME +# +# checkExistingProject - проверка на наличие существующего проекта. +# +# ARGUMENTS +# +# id | uuid - id или uuid задачи. +# +# USAGE +# +# checkExistingProject +# +# USES +# +# - project.sh +#****** +function checkExistingProject() { + local task + local nameNewProject + + task="$1" + nameNewProject=$(task _get "$task".description) + readarray -t listExistingProjects < <(task _project | grep "$nameNewProject") + + if [[ "${#listExistingProjects[@]}" -ge 1 ]]; then + notify "msg-error" "Проект с таким названием уже существует. Выход..." + exit 1 + fi +} + +#****f* global.sh/hasProject +# NAME +# +# hasProject - проверка на наличие проекта у задачи. +# +# ARGUMENTS +# +# id | uuid - id или uuid задачи. +# +# USAGE +# +# hasProject +# +# USES +# +# - project.sh +#****** +function hasProject() { + local task + local hasProject + + task="$1" + + hasProject=$(task "$task" export | jq -r '.[] | .project') + + if [[ ! "$hasProject" == "null" ]]; then + clear + notify "msg-error" "Одна из выбранных задач имеет проект, выход..." + exit 1 + fi +} + +#****f* global.sh/denotateAllAnnotations +# NAME +# +# denotateAllAnnotations - удаление всех аннотаций у задачи. +# +# ARGUMENTS +# +# id | uuid - id или uuid задачи. +# +# USAGE +# +# denotateAllAnnotations +# +# USES +# +# - project.sh +#****** +function denotateAllAnnotations() { + local task + local countAnnotations + + task="$1" + countAnnotations=$(getAnnotationCount "$task") + + for ((i = 0; i < countAnnotations; i++)); do + task "$task" denotate + done +} diff --git a/lib/project.sh b/lib/project.sh new file mode 100755 index 0000000..03e322f --- /dev/null +++ b/lib/project.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +#****F* lib/project.sh +# NAME +# +# project.sh - bash-скрипт для создания проекта в taskwarrior-tui. +#****** + +function getProjName() { + task _get "$1".description +} + +function getExitCriteria() { + task _get "$1".annotations.1.description +} + +function taskCheck() { + local task + + task="$1" + annotationCount=$(getAnnotationCount "$task") + + case "$annotationCount" in + 0) + notify "msg-error" "Нет критерия завершения, выход..." + + return 1 + ;; + 1) + notify "msg-error" "Нет первого шага у проекта, выход..." + + return 1 + ;; + *) + checkExistingProject "$task" + hasProject "$task" + + return 0 + ;; + esac +} + +function taskProj() { + local task + local projName + local exitCriteria + local idTask + local tags + + task="$1" + tags=$(getTags "$1") + projName=$(getProjName "$1") + exitCriteria=$(getExitCriteria "$1") + + readarray -t annotations < <(task "$1" export | jq -r '.[] | .annotations[1:] | .[].description') + + if [[ "$tags" =~ "someday" ]]; then + task "$task" modify priority: -someday + fi + + task "$task" modify project:"$projName" description:"$exitCriteria" + + denotateAllAnnotations "$task" + + for taskIndex in "${!annotations[@]}"; do + if [[ "$taskIndex" -eq 0 ]]; then + task add "${annotations[$taskIndex]}" project:"$projName" order:"$((taskIndex + 2))" + + idTask=$(getLatestTaskId) + + continue + fi + + task add "${annotations[$taskIndex]}" project:"$projName" order:"$((taskIndex + 2))" depends:"$idTask" + + idTask=$(getLatestTaskId) + done +} -- cgit