Make debugging easier: rename the new entry back to "new" on failure
[git/dscho.git] / upload.sh
blob639523ef864f0ca4819d03ac77fc5901357edde7
1 #!/bin/sh
3 # This is a simple script that will produce my blog on repo.or.cz
5 # The idea is to have source-<timestamp>.txt files as input, having the
6 # stories, and this script turning them into nice HTML, committing
7 # everything, and then pushing it to my repository.
9 # The blog will then be served using gitweb.
11 # To make it easier on me, if a file "source.txt" exists, it is
12 # automatically renamed using the current timestamp.
14 # TODO: handle images (git add them and rewrite the URL dynamically)
15 # TODO: generate an RSS feed, too
16 # TODO: generate TOC
17 # TODO: have a configurable maximum number of entries per page, and links
18 # to older pages
19 # TODO: include the commit name in the URL, so that images will be found
21 # make sure we're in the correct working directory
22 cd "$(dirname "$0")"
24 GITWEBURL="$(git config gitweb.url)"
25 test -z "$GITWEBURL" && {
26 echo "Please set gitweb.url in the Git config first!" >&2
27 exit 1
30 URLPREFIX="$(dirname "$GITWEBURL")"/
31 REMOTEREPOSITORY="$(basename "$GITWEBURL")"
32 BRANCH=blog
33 URL="$REMOTEREPOSITORY?a=blob_plain;hb=$BRANCH;f="
34 CSS=blog.css
35 NEW=new
36 OUTPUT=index.html
37 TEST=test.html
38 TITLE="Dscho's blog"
40 LC_ALL=C
41 export LC_ALL
43 move_new_entry_back () {
44 test -f source-$now.txt &&
45 mv source-$now.txt $NEW &&
46 git rm --cached -f source-$now.txt
49 die () {
50 move_new_entry_back
51 echo "$*" >&2
52 exit 1
55 nth () {
56 # add illogical suffix
57 case "$1" in
58 *1?|*[04-9]) echo "$1th";;
59 *1) echo "$1st";;
60 *2) echo "$1nd";;
61 *3) echo "$1rd";;
62 esac
65 make_chinese_hour () {
66 case $1 in
67 23|00) echo Rat;;
68 01|02) echo Buffalo;;
69 03|04) echo Tiger;;
70 05|06) echo Rabbit;;
71 07|08) echo Dragon;;
72 09|10) echo Snake;;
73 11|12) echo Horse;;
74 13|14) echo Goat;;
75 15|16) echo Monkey;;
76 17|18) echo Rooster;;
77 19|20) echo Dog;;
78 21|22) echo Pig;;
79 esac
82 digit_to_roman () {
83 case $1 in
84 1) echo $2;;
85 2) echo $2$2;;
86 3) echo $2$2$2;;
87 4) echo $2$3;;
88 5) echo $3;;
89 6) echo $3$2;;
90 7) echo $3$2$2;;
91 8) echo $3$2$2$2;;
92 9) echo $2$4;;
93 esac
96 make_roman_number () {
97 case $1 in
98 '') ;;
99 ?) digit_to_roman $1 I V X;;
100 ??) echo $(digit_to_roman ${1%?} X L C)$(make_roman_number ${1#?});;
101 ???) echo $(digit_to_roman ${1%??} C D M)$(make_roman_number ${1#?});;
102 ????) echo $(digit_to_roman ${1%???} M)$(make_roman_number ${1#?});;
103 esac
106 make_date () {
107 printf "%s, %s of %s, Anno Domini %s, at the hour of the %s\n" \
108 $(date +%A -d @$1) \
109 $(nth $(date +%e -d @$1)) \
110 $(date +%B -d @$1) \
111 $(make_roman_number $(date +%Y -d @$1)) \
112 $(make_chinese_hour $(date +%H -d @$1))
115 # make an argument for sed, to replace $1..$1 by <$2>..</$2>
116 markup_substitution () {
117 case "$1" in
118 ?) echo "s/$1\\([^$1]*\\)$1/<$2>\\\\1<\/$2>/g";;
120 tmp="[^${1%?}]*"
121 tmp2="\\|${1%?}[^${1#?}]$tmp"
122 tmp3="\\($tmp\\($tmp2\\($tmp2\\($tmp2\\)\\)\\)\\)"
123 echo "s/$1$tmp3$1/<$2>\\\\1<\/$2>/g"
125 esac
128 # transform markup in stdin to HTML
129 markup () {
130 sed -e 's!^$!</p><p>!' \
131 -e 's!IMHO!in my humble opinion!g' \
132 -e 's!repo.or.cz!<a href=http://&>&</a>!g' \
133 -e 's!:-)!\&#x263a;!g' \
134 -e "$(markup_substitution "''" i)" \
135 -e "$(markup_substitution "_" u)"
138 # make HTML page
139 make_html () {
140 cat << EOF
141 <html>
142 <head>
143 <title>$TITLE</title>
144 <meta http-equiv="Content-Type"
145 content="text/html; charset=UTF-8"/>
146 <link rel="stylesheet" type="text/css" href="$URL$CSS">
147 </head>
148 <body>
149 <div class=content>
150 <h1>$TITLE</h1>
153 # timestamps will not need padding to sort correctly, for some time...
154 for file in $(ls -r source-*.txt)
156 basename=${file%.txt}
157 timestamp=${basename#source-}
158 echo "<h6>$(make_date $timestamp)</h6>"
159 echo "<h2>$(sed 1q < $file | markup)</h2>"
160 echo ""
161 echo "<p>"
162 sed 1d < $file | markup
163 echo "</p>"
164 done |
165 sed -e 's/^./\t\t\t&/'
167 cat << EOF
168 </div>
169 </body>
170 </html>
175 # parse command line option
176 case "$1" in
177 *dry*) DRYRUN=1; shift;;
178 *show*) firefox "$(pwd)"/$TEST; exit;;
179 *remote*) firefox $URLPREFIX$URL$OUTPUT; exit;;
180 esac
182 test "$#" = 0 ||
183 die "Usage: $0 [--dry-run]"
185 # make sure we're on the correct branch
186 test refs/heads/$BRANCH = $(git symbolic-ref HEAD) ||
187 die "Not on branch $BRANCH"
189 # make sure there are no uncommitted changes
190 git update-index --refresh &&
191 git diff-files --quiet &&
192 git diff-index --quiet --cached HEAD ||
193 die "Have uncommitted changes!"
195 # rename the new blog entry if it exists
196 now=$(date +%s)
197 test ! -f $NEW || {
198 mv -i $NEW source-$now.txt &&
199 git add source-$now.txt
200 } ||
201 die "Could not rename source.txt"
203 if test -z "$DRYRUN"
204 then
205 # rewrite URLs
206 sed -e "s/url(/&$URL/g" < $CSS.in > $CSS &&
207 git add $CSS ||
208 die "Rewriting $CSS failed"
209 else
210 OUTPUT=$TEST
211 CSS=$CSS.in
212 URL=
215 make_html > $OUTPUT || die "Could not write $OUTPUT"
217 test ! -z "$DRYRUN" && {
218 move_new_entry_back
219 exit
222 git add $OUTPUT &&
223 git commit -s -m "Update $(make_date $now)" &&
224 git push origin +$BRANCH