task: Integrate into office module
Since I am striving for closer connection between my task management, my mail suite and my calendar appointments, it makes sense to unify all 'office' tasks into the single office module instead of keeping taskwarrior outside of it.
This commit is contained in:
parent
4b4afc68f3
commit
b534454a88
13 changed files with 18 additions and 22 deletions
32
office/.config/sh/alias.d/taskwarrior.sh
Normal file
32
office/.config/sh/alias.d/taskwarrior.sh
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# invoking t starts the task shell
|
||||
# passing arguments along passes them straight through to taskwarrior instead
|
||||
t() {
|
||||
# check for existence of tasksh before doing this whole song and dance
|
||||
if type tasksh >/dev/null 2>&1 && [ "$#" -eq 0 ]; then
|
||||
tasksh
|
||||
else
|
||||
task "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# copy the `task` zsh completions over to my little alias 😉
|
||||
# this is not very pretty and not super portable (needs ps) but
|
||||
# works for now. from here: https://unix.stackexchange.com/a/72564/414758
|
||||
if [ "$(ps -p $$ -o comm --no-headers)" = "zsh" ]; then compdef t=task; fi
|
||||
|
||||
# Make taskopen XDG conforming. If changing here, also change in taskrc alias.
|
||||
alias taskopen='taskopen --config=${XDG_CONFIG_HOME:-~/.config}/task/taskopenrc'
|
||||
|
||||
alias ta="task add"
|
||||
alias tal="task log"
|
||||
alias tan="task annotate"
|
||||
|
||||
alias tn="task next +READY"
|
||||
alias tun="task next urgency \> 4"
|
||||
|
||||
alias tra="task active"
|
||||
alias trw="task end.after:today-1wk completed"
|
||||
|
||||
alias to="task open"
|
||||
16
office/.config/sh/alias.d/timewarrior.sh
Normal file
16
office/.config/sh/alias.d/timewarrior.sh
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
if ! exist timew; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# invoking tim without arguments prints out timesheet summary
|
||||
# with ids attached.
|
||||
# otherwise tim passes through any arguments to timew
|
||||
tim() {
|
||||
if [ "$#" -eq 0 ]; then
|
||||
timew summary :ids
|
||||
else
|
||||
timew "$@"
|
||||
fi
|
||||
}
|
||||
6
office/.config/sh/env.d/taskwarrior-ensure-files.sh
Normal file
6
office/.config/sh/env.d/taskwarrior-ensure-files.sh
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env sh
|
||||
# Ensure necessary taskwarrior includes exist
|
||||
|
||||
|
||||
[ -e "${XDG_CONFIG_HOME:-$HOME/.config}/task/contexts" ] || touch "${XDG_CONFIG_HOME:-$HOME/.config}/task/contexts"
|
||||
[ -e "${XDG_CONFIG_HOME:-$HOME/.config}/task/task-sync.rc" ] || touch "${XDG_CONFIG_HOME:-$HOME/.config}/task/task-sync.rc"
|
||||
3
office/.config/sh/env.d/taskwarrior-xdg.sh
Normal file
3
office/.config/sh/env.d/taskwarrior-xdg.sh
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
[ -d "$XDG_DATA_HOME/task/notes" ] || mkdir -p "$XDG_DATA_HOME/task/notes"
|
||||
3
office/.config/sh/env.d/timewarrior-xdg.sh
Normal file
3
office/.config/sh/env.d/timewarrior-xdg.sh
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
export TIMEWARRIORDB="$XDG_CONFIG_HOME/timewarrior"
|
||||
17
office/.config/task/taskopenrc
Normal file
17
office/.config/task/taskopenrc
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[General]
|
||||
EDITOR = nvim
|
||||
taskbin = task
|
||||
path_ext = /usr/share/taskopen/scripts
|
||||
|
||||
[Actions]
|
||||
note_custom_ext.regex = "^Note\\.(.*)"
|
||||
note_custom_ext.command = "$EDITOR ${XDG_DATA_HOME:-~/.local/share}/task/notes/$UUID.$LAST_MATCH"
|
||||
|
||||
notes.regex = "^Note"
|
||||
notes.command = "$EDITOR ${XDG_DATA_HOME:-~/.local/share}/task/notes/$UUID.md"
|
||||
|
||||
links.regex = "^https?://"
|
||||
links.command = "xdg-open $FILE"
|
||||
|
||||
[CLI]
|
||||
|
||||
95
office/.config/task/taskrc
Normal file
95
office/.config/task/taskrc
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# Taskwarrior program configuration file.
|
||||
# For more documentation, see http://taskwarrior.org or try 'man task', 'man task-color',
|
||||
# 'man task-sync' or 'man taskrc'
|
||||
|
||||
# Here is an example of entries that use the default, override and blank values
|
||||
# variable=foo -- By specifying a value, this overrides the default
|
||||
# variable= -- By specifying no value, this means no default
|
||||
# #variable=foo -- By commenting out the line, or deleting it, this uses the default
|
||||
|
||||
# Use the command 'task show' to see all defaults and overrides
|
||||
|
||||
# Files
|
||||
data.location=$XDG_DATA_HOME/task/
|
||||
|
||||
# disable case sensitivity
|
||||
search.case.sensitive=no
|
||||
|
||||
# change verbosity to hide header (i.e. TASKRC override notification)
|
||||
verbose=blank,footnote,label,new-id,affected,edit,special,project,sync,unwait,override,recur
|
||||
|
||||
# german-style week start
|
||||
weekstart=monday
|
||||
|
||||
# Make daily burndown default alias
|
||||
alias.burndown=burndown.daily
|
||||
alias.open=exec taskopen "--config=${XDG_CONFIG_HOME:-$HOME/.config}/task/taskopenrc"
|
||||
|
||||
# Sort the columns a little differently
|
||||
active.indicator=>
|
||||
|
||||
# customize list report: focus on due dates
|
||||
report.list.columns=start.active,id,project,priority,due,description,tags,entry.age
|
||||
report.list.labels=,,Project,Pri,Due,Description,Tags,Age
|
||||
# customize next report: focus on urgencies
|
||||
report.next.columns=id,project,priority,urgency,due,description,tags,scheduled,entry.age,recur
|
||||
report.next.labels=,Project,Pri,Urg,Due,Description,Tags,Sched,Age,Recur
|
||||
|
||||
# customize overdue report: hide tasks which are due today, but scheduled for 00:00:00
|
||||
report.overdue.filter=(status:pending or +WAITING) and +OVERDUE and -TODAY
|
||||
# custom today report, sorted by urgency
|
||||
report.today.description=Tasks scheduled for today, sorted by urgency
|
||||
report.today.filter=status:pending -WAITING +TODAY or +OVERDUE limit:page
|
||||
report.today.sort=urgency-
|
||||
report.today.columns=id,project,priority,urgency,due,description,tags,scheduled,entry.age,recur
|
||||
report.today.labels=,Project,Pri,Urg,Due,Description,Tags,Sched,Age,Recur
|
||||
# report overview of tasks accomplished today
|
||||
report.today.completed.description=Tasks completed today
|
||||
report.today.completed.filter=status:completed end.after:tod
|
||||
report.today.completed.columns=id,project,priority,urgency,due,description,tags,scheduled,entry.age,recur
|
||||
report.today.completed.labels=,Project,Pri,Urg,Due,Description,Tags,Sched,Age,Recur
|
||||
|
||||
# reorder priorities so that explicitly tagged 'Low' items are lower than normal
|
||||
uda.priority.values=H,M,,L
|
||||
urgency.uda.priority.L.coefficient=0
|
||||
urgency.uda.priority..coefficient=1.8
|
||||
|
||||
# Just because its tagged/annotated doesn't mean its important
|
||||
urgency.tags.coefficient=0
|
||||
urgency.annotations.coefficient=0
|
||||
# maybe items are not urgent at all
|
||||
urgency.user.tag.maybe.coefficient=-100.0
|
||||
urgency.user.tag.next.coefficient=5.0
|
||||
|
||||
# things that are blocking simply have to be done before
|
||||
# being able to do the blocked thing. This ensures that.
|
||||
urgency.blocked.coefficient=0.0
|
||||
urgency.blocking.coefficient=0.0
|
||||
urgency.inherit=1
|
||||
|
||||
# Holidays for calendar
|
||||
include /usr/share/doc/task/rc/holidays.de-DE.rc
|
||||
|
||||
# Themes are in additional file
|
||||
include colorscheme
|
||||
|
||||
# Taskserver sync settings
|
||||
include task-sync.rc
|
||||
|
||||
# My personal tw contexts (e.g. work/personal)
|
||||
include contexts
|
||||
|
||||
# try to fix some color weirdness, especially in tmux
|
||||
# color.scheduled=on grey
|
||||
|
||||
# only ever show one result in the tasksh
|
||||
tasksh.autoclear=1
|
||||
# for tasksh review sessions
|
||||
uda.reviewed.type=date
|
||||
uda.reviewed.label=Reviewed
|
||||
report._reviewed.description=Tasksh review report. Adjust the filter to your needs.
|
||||
report._reviewed.columns=uuid
|
||||
report._reviewed.sort=reviewed+,modified+
|
||||
report._reviewed.filter=( reviewed.none: or reviewed.before:now-6days ) and ( +PENDING or +WAITING )
|
||||
|
||||
news.version=2.6.0
|
||||
8
office/.local/bin/task-overdue-prompt
Executable file
8
office/.local/bin/task-overdue-prompt
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env zsh
|
||||
# Simple script to display a skull if there are overdue tasks.
|
||||
# Intended for prompt use
|
||||
# (to be visibly reminded on the prompt of any tardiness)
|
||||
|
||||
type task >/dev/null 2>&1 || exit 1
|
||||
|
||||
[ "$(task +OVERDUE -TODAY count)" -ge 0 ] && print -P "💀"
|
||||
29
office/.local/share/task/hooks/DISABLED.on-exit.sync-to-server-silent.py
Executable file
29
office/.local/share/task/hooks/DISABLED.on-exit.sync-to-server-silent.py
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# From: https://gist.github.com/varunagrawal/2b93c5dc721520ff6876e940c420ab05
|
||||
# This hooks script syncs task warrior to the configured task server.
|
||||
# The on-exit event is triggered once, after all processing is complete.
|
||||
|
||||
# Make sure hooks are enabled and this hook script is executable.
|
||||
# Run `task diag` for diagnostics on the hook.
|
||||
|
||||
import sys
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
try:
|
||||
tasks = json.loads(sys.stdin.readline())
|
||||
except:
|
||||
# No input
|
||||
sys.exit(0)
|
||||
|
||||
# no tasks to work through, don't error
|
||||
if len(tasks) <= 0:
|
||||
sys.exit(0)
|
||||
|
||||
# Call the `sync` command
|
||||
# hooks=0 ensures that the sync command doesn't call the on-exit hook
|
||||
# verbose=nothing sets the verbosity to print nothing at all
|
||||
subprocess.Popen(["task", "rc.verbose=nothing", "rc.hooks=0", "sync"], close_fds=True)
|
||||
|
||||
sys.exit(0)
|
||||
102
office/.local/share/task/hooks/on-modify.timewarrior
Executable file
102
office/.local/share/task/hooks/on-modify.timewarrior
Executable file
|
|
@ -0,0 +1,102 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright 2016 - 2021, Thomas Lauf, Paul Beckingham, Federico Hernandez.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# https://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# Hook should extract all of the following for use as Timewarrior tags:
|
||||
# UUID
|
||||
# Project
|
||||
# Tags
|
||||
# Description
|
||||
# UDAs
|
||||
|
||||
try:
|
||||
input_stream = sys.stdin.buffer
|
||||
except AttributeError:
|
||||
input_stream = sys.stdin
|
||||
|
||||
# Make no changes to the task, simply observe.
|
||||
old = json.loads(input_stream.readline().decode("utf-8", errors="replace"))
|
||||
new = json.loads(input_stream.readline().decode("utf-8", errors="replace"))
|
||||
print(json.dumps(new))
|
||||
|
||||
|
||||
def extract_tags_from(json_obj):
|
||||
# Extract attributes for use as tags.
|
||||
tags = [json_obj['description']]
|
||||
|
||||
if 'project' in json_obj:
|
||||
tags.append(json_obj['project'])
|
||||
|
||||
if 'tags' in json_obj:
|
||||
tags.extend(json_obj['tags'])
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
def extract_annotation_from(json_obj):
|
||||
|
||||
if 'annotations' not in json_obj:
|
||||
return '\'\''
|
||||
|
||||
return json_obj['annotations'][0]['description']
|
||||
|
||||
|
||||
start_or_stop = ''
|
||||
|
||||
# Started task.
|
||||
if 'start' in new and 'start' not in old:
|
||||
start_or_stop = 'start'
|
||||
|
||||
# Stopped task.
|
||||
elif ('start' not in new or 'end' in new) and 'start' in old:
|
||||
start_or_stop = 'stop'
|
||||
|
||||
if start_or_stop:
|
||||
tags = extract_tags_from(new)
|
||||
|
||||
subprocess.call(['timew', start_or_stop] + tags + [':yes'])
|
||||
|
||||
# Modifications to task other than start/stop
|
||||
elif 'start' in new and 'start' in old:
|
||||
old_tags = extract_tags_from(old)
|
||||
new_tags = extract_tags_from(new)
|
||||
|
||||
if old_tags != new_tags:
|
||||
subprocess.call(['timew', 'untag', '@1'] + old_tags + [':yes'])
|
||||
subprocess.call(['timew', 'tag', '@1'] + new_tags + [':yes'])
|
||||
|
||||
old_annotation = extract_annotation_from(old)
|
||||
new_annotation = extract_annotation_from(new)
|
||||
|
||||
if old_annotation != new_annotation:
|
||||
subprocess.call(['timew', 'annotate', '@1', new_annotation])
|
||||
|
|
@ -8,8 +8,12 @@ imapfilter - rule-based filtering engine for your incoming mail
|
|||
vdirsyncer - mirror your contacts and calendars locally with two-way synchronization
|
||||
khal - terminal vdir-compatible calendar client
|
||||
calcurse - a pretty terminal calendar client, but not very vdir compatible
|
||||
taskwarrior - a super flexible terminal to-do list
|
||||
|
||||
Most of the credential/account setup of course is highly specific to my setup and should be changed as required.
|
||||
The module has three areas of concern: a functioning mail suite (receiving, sending, searching), to-do management, and contacts and calendaring.
|
||||
Take care that most of the credential/account setup of course is highly specific to my setup and should be changed as required.
|
||||
|
||||
## mail
|
||||
|
||||
The current mail setup uses `mbsync` (from the isync project) to locally mirror the GMail imap folder.
|
||||
It is run through a `sync-mail` script which can invoke pre- and post-sync hooks
|
||||
|
|
@ -20,8 +24,19 @@ The sync script also automatically unlocks any pass directory so that credential
|
|||
|
||||
[^1]: That being said, the script is a little dusty and could probably use a little overhaul. It *works* but could be more fantastic I feel.
|
||||
|
||||
## calendar and contacts
|
||||
|
||||
For calendars and contacts, the wonderful `vdirsyncer` is used to sync everything from a remote Dav client (hard-coded to my server currently) to the local directories in documents.
|
||||
This is then picked up by `khal` to allow you to browse and edit your events, and create new ones - all of which in turn ends up remotely.
|
||||
|
||||
You can also browse your events locally with `calcurse` which will import them on each startup, but will not sync back yet;
|
||||
meaning, any changes you do through the application will not reflect themselves back on any of your other connected devices unfortunately.
|
||||
|
||||
## tasks
|
||||
|
||||
Task management is done through the wonderful `taskwarrior`. I mostly use it as-is from the commandline, with some personal tweaks to urgencies and task dependencies.
|
||||
|
||||
The goal here is to integrate taskwarrior relatively tightly into mail
|
||||
(e.g. receiving a mail and turning it into a task, then being able to go back from the task to the respective mail)
|
||||
and calendaring (turning a to-do into a calendar event, and creating to-dos for individual events right from the calendar),
|
||||
but those goals are still a ways off and the suite is working fine enough for now.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue