-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathorgserver
executable file
·190 lines (176 loc) · 6.66 KB
/
orgserver
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/bin/bash
# orgserver
#
# Start the org-mode data server, on the specified org data Git
# repository $ORG, with the specified projects $PRO. Attempts to
# refresh the org data and project with "git pull origin master". If
# changes are detected in the source, attempts to restart the server.
#
# Can be run with a cron job to regularly refresh the org data,
# and attempt to restart the server.
#
export PYTHONPATH=/usr/local/lib/python2.7/site-packages:${PYTHONPATH}
QUI=1
RUN="${0##*/}-$( printf "%05d" $$ ):"
DIR=$( dirname $( n=${BASH_SOURCE[0]}; while nn=$( readlink -n $n ); do n=$nn; done; echo "$n" ))
ORG=${ORG_DIRECTORY:-~/org}
PRO=${ORG_PROJECTS:-}
RES=0 # restart any running server
REF=0 # refresh git repos
LOG="-"
ADR=""
SVR=""
STY=
DAY=
HLP=0
status=0
while (( $# > 0 )); do
if [[ "$1" == "--verbose" ]]; then
QUI=0
elif [[ "$1" == "--restart" ]]; then
RES=1
elif [[ "$1" == "--refresh" ]]; then
REF=1
elif [[ "$1" == "--server" ]]; then
shift
SVR=${1}
elif [[ "$1" == "--style" ]]; then
shift
STY=${1}
elif [[ "$1" == "--org" ]]; then
shift
ORG=${1}
elif [[ "$1" == "--log" ]]; then
shift
LOG=${1}
elif [[ "$1" == "--address" ]]; then
shift
ADR=${1}
elif [[ "$1" == "--day" ]]; then
shift
DAY=${1}
elif [[ "$1" == "--help" ]]; then
HLP=1
elif [[ "${1#-}" != "${1}" ]]; then
echo "Unrecognized option: ${1}"
HLP=1
status=1
else
# All other non-options are projects
PRO="${PRO}${PRO:+ }${1}"
fi
shift
done
if (( HLP )); then
echo "${0##*/} [--<option> [...]] [<project> [...]]"
echo " --help This help"
echo " --verbose Log activity"
echo " --restart Restart any running server (default: no)"
echo " --refresh Refresh Git repositories (default: no)"
echo " --address <i[:p]> Bind to interface:port (default: *:8080)"
echo " Performs a \"git pull origin master\" on both the org data"
echo " directory, and the orgserver directory. In either case,"
echo " if the master branch's commit changes, the orgserver will"
echo " forcibly restart any running orgserver.py."
echo " --org <dir> org-mode data Git repository (default: ~/org)"
echo " --log <file> Log appending onto file (default: -)"
echo " If not relative: (.[.]/*) to current directory, or"
echo " absolute: (/*), we assume it's relative to the org directory"
echo " --server <name> Specify Web Server platform (default: web.py)"
echo " --style <style> Specify Burndown style (default: 'effort')"
echo " --day <hours> Specify number of hours per day (default: 8)"
echo " <project> .org files to parse (default: project)"
exit $status
fi
# Our PID file is always in the target Org data directory. We add a ".#####"
# extension of this orgserver PID to the name; the file contains the PID of this
# orgserver's orgserver.py server process.
PID=${ORG}/orgserver.pid
if [[ "${LOG}" != "-" && "${LOG#/}" == "${LOG}" ]]; then
# Log file path not default (stdout) and not absolute!
if [[ "${LOG#.}" == "${LOG}" ]]; then
# And not relative; must be a bare name. Make relative to Org directory.
LOG="${ORG}/${LOG}"
else
# Explicitly relative; make relative to current directory.
LOG="$( pwd )/${LOG}"
fi
fi
(( ! QUI )) && echo "${RUN} Burndown: ${DIR}"
(( ! QUI )) && echo "${RUN} Style: ${STY:-effort}"
(( ! QUI )) && echo "${RUN} Org Data: ${ORG}"
(( ! QUI )) && echo "${RUN} Projects: ${PRO}"
(( ! QUI )) && echo "${RUN} Log: ${LOG}"
# Kill our orgserver.py and clean up our PID file on exit. This is executed on
# any exit (eg. ^C, or due to exit after waiting for completion of orgserver, so
# the orgserver.py process may not be alive). Also, if killed by another, the
# PID file may no longer exist (so cat may fail); dump all stderr output.
trap cleanup EXIT
cleanup () {
kill $( cat $PID.$$ 2>&1 ) >/dev/null 2>&1
(( $? && ! QUI )) && echo "${RUN} No orgserver.py running"
rm -f $PID.$$
}
# Refresh the Git repositories, if --refresh, and deduce if we should restart
# the orgserver.py (due to a commit to its Git repo). We always fetch and
# checkout --force origin/master on the Org repo, because Git can't handle
# merging them very well.
if (( REF )); then
(( ! QUI )) && echo "${RUN} Refreshing Org Data: $ORG"
pull=$( cd $ORG && git fetch --all origin 2>&1 && git checkout master 2>&1 && git pull --force origin master 2>&1 )
(( $? || ! QUI )) && echo "${RUN} Org Data update: $pull"
fi
master=$( cd $DIR && git show --oneline --shortstat | head -1 )
if (( REF )); then
(( ! QUI )) && echo "${RUN} Refreshing Burndown: $DIR"
pull=$( cd $DIR && git pull origin master 2>&1 )
(( $? || ! QUI )) && echo "${RUN} Burndown update: $pull"
if [[ "$( cd $DIR && git show --oneline --shortstat | head -1 )" != "$master" ]]; then
(( ! QUI )) && echo "${RUN} Detected $DIR update"
RES=1
fi
fi
if (( RES )); then
(( ! QUI )) && echo "${RUN} Restarting orgserver.py"
SLP=0
for pid in $PID.*; do
if [ -f $pid ]; then
kill $( cat $pid ) >/dev/null 2>&1
rm -f $pid
SLP=1
fi
done
(( SLP )) && sleep $SLP
fi
# Construct orgserver.py options list and command to run. If not explicitly or
# automatically wanting a restart; then if server already running, have
# orgserver.py fail silently without error, if we cannot bind to the socket.
OPT=""
(( ! RES )) && OPT="${OPT}${OPT+ }--redundant"
[[ "${ADR}" != "" ]] && OPT="${OPT}${OPT+ }--address ${ADR}"
[[ "${SVR}" != "" ]] && OPT="${OPT}${OPT+ }--server ${SVR}"
[[ "${LOG}" != "-" ]] && OPT="${OPT}${OPT+ }--log ${LOG}"
[[ "${STY}" != "" ]] && OPT="${OPT}${OPT+ }--style ${STY}"
[[ "${DAY}" != "" ]] && OPT="${OPT}${OPT+ }--day ${DAY}"
CMD="./orgserver.py ${OPT} ${ORG} ${PRO}"
# Run orgserver.py, savings its PID, and waiting 'til it exits. Since web.py
# access all /static content relative to its CWD, ensure that we change
# directory to the proper target before executing. Any $LOG file has been
# safely converted to an absolute address.
(( ! QUI )) && echo "${RUN} In: $DIR, Running: $CMD"
cd $DIR
if (( QUI )); then
$CMD </dev/null >/dev/null 2>&1 &
pid=$!
else
$CMD &
pid=$!
fi
echo $pid >> $PID.$$
# Harvest result of orgserver.py execution, and exit with that status
wait $!
status=$?
if (( status )); then
(( ! QUI )) && echo "${RUN} Failed: $status"
fi
exit $status