-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclin.zsh
executable file
·124 lines (112 loc) · 6.7 KB
/
clin.zsh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/bin/zsh
## Clock In script
# In collaboration with clout.zsh, clnote.zsh, and clp_state.zsh, it maintains/uses/parses these files:
# ~/.clock_log/clin_time --> ASCII one line
# if clocked in: the output of `date +"%F %H:%M:%S"` recording when you clocked in
# if clocked out: OUT
# acts as CLOCK STATUS (am I in or out?)
# ~/.clock_log/YYYY-MM-DD.log --> log of that day's in/outs
# ~/.clock_log/state --> short, human-readable current status
# "IN HH:MM" w/ HH:MM the time clocked in , or
# "OUT"
# ~/.clock_log/clin_notes --> A log of timestamped, one-line notes
# describing actions, notes, ideas that you want to log while clocked in
# It is an error to try to modify this
# while not clocked in.
# This file only ever contains a log for
# the current session. This is then
# written out to a .log file and deleted.
# ~/.clock_log/clout_notes --> A log of timestamped, one-line notes
# describing actions, notes, ideas that occur when
# you're not focusing on a particular project/outcome
# It is an error to try to modify this
# while clocked in (this is for focused or
# potentially billable time).
# This file only ever contains a log for
# the current session. This is then
# written out to a .log file and deleted.
#User has tried to clock in, so check state
# TODO: Add error checks
# file should exist
# file should always have specifically formatted data
# TODO: make directories variables instead of hard-coded
#
#At first, just get the raw state (should be OUT or a clock in time)
cur_state=`cat ~/.clock_log/clin_time | awk '{$1=$1;print}'` #awk magic ($1=$1 has side-effect of re-evaluating $0 and rebuilding with default separators) trims outer spaces and squeezes internal spaces to 1
#Use matching regex (three capital letter code) sentinel to get context (optional! if blank, ignore)
cur_context=`cat ~/.clock_log/clin_time | awk '$1 ~ /[A-Z]{3}:/ {$1=$1;print}'`
cur_context_code=`cat ~/.clock_log/clin_time | awk '$1 ~ /[A-Z]{3}:/ {$1=$1;printf "%.3s", $1}'`
cur_context_desc=`cat ~/.clock_log/clin_time | awk '$1 ~ /[A-Z]{3}:/ {$1="";print $0}'`
if [[ $cur_state == 'OUT' ]]; then
#We're here, so state was clocked out.
#Good, that's what's expected for a clock in operation.
cur_context=""
cur_context_code=""
cur_context_desc=""
#If the optional context is provided, prepare directories
if [[ $# -gt 0 ]]; then
#See if this is a new ('XXX: desc of XXX') or an existing context ('XXX')
#TODO: Assuming proper form for now, need to error-check
#Take all arguments except the first/0th (name of script)
cur_context=${@:1:${#@[@]}}
#Use matching regex (three capital letter code) sentinel to get context details
#We assume form "XXX: human-readable desc of XXX" for new contexts
# "XXX" for existing contexts
cur_context_code=`echo ${cur_context} | awk '$1 ~ /[A-Z]{3}:/ {$1=$1;printf "%.3s", $1}'`
cur_context_desc=`echo ${cur_context} | awk '$1 ~ /[A-Z]{3}:/ {$1="";print $0}'`
if [[ -z "$cur_context_code" ]]; then
#We didn't get the form for a new context, so this context must
#exist ($cur_context="XXX"). Extract it.
cur_context_code=`cat ~/.clock_log/${cur_context}/context_description | awk '$1 ~ /[A-Z]{3}:/ {$1=$1;printf "%.3s", $1}'`
cur_context_desc=`cat ~/.clock_log/${cur_context}/context_description | awk '$1 ~ /[A-Z]{3}:/ {$1="";print $0}'`
cur_context="${cur_context_code}: ${cur_context_desc}"
echo "reading in existing context: ${cur_context}"
else
#The user has defined a new context, store the info
cur_context="${cur_context_code}: ${cur_context_desc}"
echo "creating context ${cur_context}"
mkdir -p ~/.clock_log/$cur_context_code
echo "${cur_context_code}: ${cur_context_desc}" > ~/.clock_log/${cur_context_code}/context_description
fi
fi
#`with_slash` is a hacky string that acts as a boolean. empty means no
#context.
with_slash=""
if [[ -d ~/.clock_log/$cur_context_code ]]; then
with_slash=$cur_context_code/
fi
#Store any clocked out log in ~/.clock_log/YYYY-MM-DD.log
#Also, if a context code is given, store context-specific notes in their logs
if [[ -f ~/.clock_log/clout_notes ]]; then
if [[ -n $cur_context_code ]]; then
echo "Context code: $cur_context_code" >> ~/.clock_log/`date +"%F"`.log
cat ~/.clock_log/clout_notes >> ~/.clock_log/`date +"%F"`.log
cat ~/.clock_log/clout_notes >> ~/.clock_log/${with_slash}`date +"%F"`.log
else
cat ~/.clock_log/clout_notes >> ~/.clock_log/`date +"%F"`.log
fi
rm ~/.clock_log/clout_notes
fi
date +"%F %H:%M:%S" > ~/.clock_log/clin_time
with_parens=''
if [[ -n $cur_context_code ]]; then
echo $cur_context >> ~/.clock_log/clin_time
with_parens=\(${cur_context_code}\)
fi
date +"IN${with_parens} %H:%M" > ~/.clock_log/state
#The state's updated,
#my POWERLEVEL9K configuration has a custom segment that reads the state
#file, so this is all we need to do to update the prompt
else
echo "You've already clocked in!"
#We can now be guaranteed the state info is available, so grab it
cur_state=`cat ~/.clock_log/clin_time | awk '$1 ~ /[0-9]{4}-[0-9]{2}-[0-9]{2}/ {$1=$1;print}'` #awk magic ($1=$1 has side-effect of re-evaluating $0 and rebuilding with default separators) trims outer spaces and squeezes internal spaces to 1
echo " IN@ " $cur_state
if [[ -n $cur_context ]]; then
echo " ctx: " $cur_context
fi
fi
# TODO implement clest? I'm kinda OK with just clnote... we'll see
#
# `clest HH:MM:SS` to estimate the time they clocked out or
# `clest +HH:MM:SS` to estimate the time they worked after last clocking in