Update Thursday, 22nd of January, Anno Domini MMIX, at the hour of the Pig
[git/dscho.git] / upload.sh
blob86c5ef5e390c2d0e55b250bf58fec75948fe1137
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: generate an RSS feed, too
15 # TODO: have a configurable maximum number of entries per page, and links
16 # to older pages
18 # make sure we're in the correct working directory
19 cd "$(dirname "$0")"
21 GITWEBURL="$(git config gitweb.url)"
22 test -z "$GITWEBURL" && {
23 echo "Please set gitweb.url in the Git config first!" >&2
24 exit 1
27 URLPREFIX="$(dirname "$GITWEBURL")"/
28 REMOTEREPOSITORY="$(basename "$GITWEBURL")"
29 BRANCH=blog
30 URL="$REMOTEREPOSITORY?a=blob_plain;hb=$BRANCH;f="
31 NEW=new
32 OUTPUT=index.html
33 TEST=test.html
34 TITLE="Dscho's blog"
36 LC_ALL=C
37 export LC_ALL
39 move_new_entry_back () {
40 test -f source-$now.txt &&
41 mv source-$now.txt $NEW &&
42 git rm --cached -f source-$now.txt
45 die () {
46 move_new_entry_back
47 echo "$*" >&2
48 exit 1
51 nth () {
52 # add illogical suffix
53 case "$1" in
54 *1?|*[04-9]) echo "$1th";;
55 *1) echo "$1st";;
56 *2) echo "$1nd";;
57 *3) echo "$1rd";;
58 esac
61 make_chinese_hour () {
62 case $1 in
63 23|00) echo Rat;;
64 01|02) echo Buffalo;;
65 03|04) echo Tiger;;
66 05|06) echo Rabbit;;
67 07|08) echo Dragon;;
68 09|10) echo Snake;;
69 11|12) echo Horse;;
70 13|14) echo Goat;;
71 15|16) echo Monkey;;
72 17|18) echo Rooster;;
73 19|20) echo Dog;;
74 21|22) echo Pig;;
75 esac
78 digit_to_roman () {
79 case $1 in
80 1) echo $2;;
81 2) echo $2$2;;
82 3) echo $2$2$2;;
83 4) echo $2$3;;
84 5) echo $3;;
85 6) echo $3$2;;
86 7) echo $3$2$2;;
87 8) echo $3$2$2$2;;
88 9) echo $2$4;;
89 esac
92 make_roman_number () {
93 case $1 in
94 '') ;;
95 ?) digit_to_roman $1 I V X;;
96 ??) echo $(digit_to_roman ${1%?} X L C)$(make_roman_number ${1#?});;
97 ???) echo $(digit_to_roman ${1%??} C D M)$(make_roman_number ${1#?});;
98 ????) echo $(digit_to_roman ${1%???} M)$(make_roman_number ${1#?});;
99 esac
102 make_date () {
103 printf "%s, %s of %s, Anno Domini %s, at the hour of the %s\n" \
104 $(date +%A -d @$1) \
105 $(nth $(date +%e -d @$1)) \
106 $(date +%B -d @$1) \
107 $(make_roman_number $(date +%Y -d @$1)) \
108 $(make_chinese_hour $(date +%H -d @$1))
111 # make an argument for sed, to replace $1..$1 by <$2>..</$2>
112 markup_substitution () {
113 case "$1" in
114 ?) echo "s/$1\\([^$1]*\\)$1/<$2>\\\\1<\/$2>/g";;
116 tmp="[^${1%?}]*"
117 tmp2="\\|${1%?}[^${1#?}]$tmp"
118 tmp3="\\($tmp\\($tmp2\\($tmp2\\($tmp2\\)\\)\\)\\)"
119 echo "s/$1$tmp3$1/<$2>\\\\1<\/$2>/g"
121 esac
124 # transform markup in stdin to HTML
125 markup () {
126 image_pattern="\\[\\[Image:\([^]]*\)"
127 image_pattern2="$image_pattern\(\\|[^\]]*\)\?\]\]"
128 sed -e 's!^$!</p><p>!' \
129 -e 's!IMHO!in my humble opinion!g' \
130 -e 's!BTW!By the way,!g' \
131 -e 's!repo.or.cz!<a href=http://&>&</a>!g' \
132 -e 's!:-)!\&#x263a;!g' \
133 -e "s!$image_pattern2!<center><img src=$URL\1></center>!g" \
134 -e 's!<bash>!<table\
135 border=1 bgcolor=black>\
136 <tr><td bgcolor=lightblue colspan=3>\
137 \&nbsp;\
138 </td></tr>\
139 <tr><td>\
140 <table cellspacing=5 border=0\
141 style="color:#ffffff;">\
142 <tr><td>\
143 <pre>!' \
144 -e 's!</bash>! </pre>\
145 </td></tr>\
146 </table>\
147 </td></tr>\
148 </table>!' \
149 -e "$(markup_substitution "''" i)" \
150 -e "$(markup_substitution "_" u)"
153 # make HTML page
154 make_html () {
155 body_style="width:800px"
156 body_style="$body_style;background-image:url(${URL}paper.jpg)"
157 body_style="$body_style;background-repeat:repeat-y"
158 body_style="$body_style;background-attachment:scroll"
159 body_style="$body_style;padding:0px;"
160 text_style="width:610px"
161 text_style="$text_style;margin-left:120px"
162 text_style="$text_style;margin-top:50px"
163 text_style="$text_style;align:left"
164 text_style="$text_style;vertical-align:top;"
165 cat << EOF
166 <html>
167 <head>
168 <title>$TITLE</title>
169 <meta http-equiv="Content-Type"
170 content="text/html; charset=UTF-8"/>
171 </head>
172 <body style="$body_style">
173 <div style="$text_style">
174 <h1>$TITLE</h1>
176 indent='\t\t\t'
178 # make toc
179 toc_width=400px
180 toc_style="position:absolute;top:50px;left:810px;width=$toc_width"
182 echo "<div style=\"$toc_style\">"
183 echo "<table width=$toc_width bgcolor=#e0e0e0 border=1>"
184 echo "<tr><th>Table of contents:</th></tr>"
185 echo "<tr><td>"
186 echo '<p><ol>'
187 for file in $(ls -r source-*.txt)
189 basename=${file%.txt}
190 timestamp=${basename#source-}
191 date="$(date +"%d %b %Y" -d @$timestamp)"
192 title="$(sed 1q < $file | markup)"
193 echo "<li><a href=#$timestamp>$date $title</a>"
194 done
195 echo '</ol></p>'
196 echo '</td></tr></table>'
197 test -f links.html && {
198 echo "<br>"
199 echo "<table width=$toc_width bgcolor=#e0e0e0 border=1>"
200 echo "<tr><th>Links:</th></tr>"
201 echo "<tr><td>"
202 cat links.html
203 echo "</td></tr></table>"
205 echo '</div>'
206 } | sed -s "s/^/$indent/"
209 # timestamps will not need padding to sort correctly, for some time...
210 for file in $(ls -r source-*.txt)
212 basename=${file%.txt}
213 timestamp=${basename#source-}
214 echo "<h6>$(make_date $timestamp)</h6>"
215 echo "<a name=$timestamp>"
216 echo "<h2>$(sed 1q < $file | markup)</h2>"
217 echo ""
218 echo "<p>"
219 sed 1d < $file | markup
220 echo "</p>"
221 done |
222 sed -e "s/^./$indent&/" \
223 -e "/<pre>/,/<\/pre>/s/^$indent//"
225 cat << EOF
226 </div>
227 </body>
228 </html>
232 # never, ever have spaces in the file names
233 commit_new_images () {
234 images=
235 for image in $(cat source-* |
236 tr ' ]|' '\n' |
237 sed -n 's/.*\[\[Image://p' |
238 sort |
239 uniq)
241 git add $image || die "Could not git add image $image"
242 images="$images $image"
243 done
245 git update-index --refresh &&
246 git diff-files --quiet -- $images &&
247 git diff --cached --quiet HEAD -- $images ||
248 git commit -s -m "Commit some images on $(make_date $now)" $images
252 # parse command line option
253 case "$1" in
254 *dry*) DRYRUN=1; shift;;
255 *show*) firefox "$(pwd)"/$TEST; exit;;
256 *remote*) firefox $URLPREFIX$URL$OUTPUT; exit;;
257 esac
259 test "$#" = 0 ||
260 die "Usage: $0 [--dry-run]"
262 # make sure we're on the correct branch
263 test refs/heads/$BRANCH = $(git symbolic-ref HEAD) ||
264 die "Not on branch $BRANCH"
266 # make sure there are no uncommitted changes
267 git update-index --refresh &&
268 git diff-files --quiet ||
269 die "Have unstaged changes!"
271 # rename the new blog entry if it exists
272 now=$(date +%s)
273 test ! -f $NEW || {
274 mv -i $NEW source-$now.txt &&
275 git add source-$now.txt
276 } ||
277 die "Could not rename source.txt"
279 # commit the images that are referenced and not yet committed
280 test ! -z "$DRYRUN" ||
281 commit_new_images ||
282 die "Could not commit new images"
284 # to find the images reliably, we have to use the commit name, not the branch
285 # we use the latest commit touching an image file.
286 IMAGEFILES="$(git ls-files |
287 grep -v '\.\(html\|gitignore\|in\|sh\|txt\)$')"
288 REV=$(git rev-list -1 HEAD -- $IMAGEFILES)
289 test -z "$REV" && REV=$BRANCH
290 URL="$REMOTEREPOSITORY?a=blob_plain;hb=$REV;f="
292 if test ! -z "$DRYRUN"
293 then
294 # Output to test.html and have local links into the current directory
295 OUTPUT=$TEST
296 URL=
299 make_html > $OUTPUT || die "Could not write $OUTPUT"
301 test ! -z "$DRYRUN" && {
302 move_new_entry_back
303 exit
306 git add $OUTPUT &&
307 git commit -s -m "Update $(make_date $now)" &&
308 git push origin +$BRANCH