Show a header above the ads
[git/dscho.git] / upload.sh
blob520ebe94be87241c582fe1c069f053d35ddb4dfa
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: have a configurable maximum number of entries per page, and links
15 # to older pages
17 # make sure we're in the correct working directory
18 cd "$(dirname "$0")"
20 GITWEBURL="$(git config gitweb.url)"
21 test -z "$GITWEBURL" && {
22 echo "Please set gitweb.url in the Git config first!" >&2
23 exit 1
26 URLPREFIX="$(dirname "$GITWEBURL")"/
27 REMOTEREPOSITORY="$(basename "$GITWEBURL")"
28 BRANCH=blog
29 URL="$REMOTEREPOSITORY?a=blob_plain;hb=$BRANCH;f="
30 ORIGURL=$URL
31 NEW=new
32 OUTPUT=index.html
33 RSS=blog.rss
34 TEST=test.html
35 TITLE="Dscho's blog"
37 LC_ALL=C
38 export LC_ALL
40 move_new_entry_back () {
41 test -f source-$now.txt &&
42 mv source-$now.txt $NEW &&
43 git rm --cached -f source-$now.txt
46 die () {
47 move_new_entry_back
48 echo "$*" >&2
49 exit 1
52 nth () {
53 # add illogical suffix
54 case "$1" in
55 *1?|*[04-9]) echo "$1th";;
56 *1) echo "$1st";;
57 *2) echo "$1nd";;
58 *3) echo "$1rd";;
59 esac
62 make_chinese_hour () {
63 case $1 in
64 23|00) echo Rat;;
65 01|02) echo Buffalo;;
66 03|04) echo Tiger;;
67 05|06) echo Rabbit;;
68 07|08) echo Dragon;;
69 09|10) echo Snake;;
70 11|12) echo Horse;;
71 13|14) echo Goat;;
72 15|16) echo Monkey;;
73 17|18) echo Rooster;;
74 19|20) echo Dog;;
75 21|22) echo Pig;;
76 esac
79 digit_to_roman () {
80 case $1 in
81 1) echo $2;;
82 2) echo $2$2;;
83 3) echo $2$2$2;;
84 4) echo $2$3;;
85 5) echo $3;;
86 6) echo $3$2;;
87 7) echo $3$2$2;;
88 8) echo $3$2$2$2;;
89 9) echo $2$4;;
90 esac
93 make_roman_number () {
94 case $1 in
95 '') ;;
96 ?) digit_to_roman $1 I V X;;
97 ??) echo $(digit_to_roman ${1%?} X L C)$(make_roman_number ${1#?});;
98 ???) echo $(digit_to_roman ${1%??} C D M)$(make_roman_number ${1#?});;
99 ????) echo $(digit_to_roman ${1%???} M)$(make_roman_number ${1#?});;
100 esac
103 make_date () {
104 printf "%s, %s of %s, Anno Domini %s, at the hour of the %s\n" \
105 $(date +%A -d @$1) \
106 $(nth $(date +%e -d @$1)) \
107 $(date +%B -d @$1) \
108 $(make_roman_number $(date +%Y -d @$1)) \
109 $(make_chinese_hour $(date +%H -d @$1))
112 # make an argument for sed, to replace $1..$1 by <$2>..</$2>
113 markup_substitution () {
114 case "$1" in
115 ?) echo "s/$1\\([^$1]*\\)$1/<$2>\\\\1<\/$2>/g";;
117 tmp="[^${1%?}]*"
118 tmp2="\\|${1%?}[^${1#?}]$tmp"
119 tmp3="\\($tmp\\($tmp2\\($tmp2\\($tmp2\\)\\)\\)\\)"
120 echo "s/$1$tmp3$1/<$2>\\\\1<\/$2>/g"
122 esac
125 # transform markup in stdin to HTML
126 markup () {
127 image_pattern="\\[\\[Image:\([^]]*\)"
128 image_pattern2="$image_pattern\(\\|[^\]]*\)\?\]\]"
129 case "$*" in
130 *invert-bash*) bash_bg=white; bash_fg=black;;
131 *) bash_bg=black; bash_fg=white;;
132 esac
133 sed -e 's!^$!</p><p>!' \
134 -e 's!IMHO!in my humble opinion!g' \
135 -e 's!BTW!By the way,!g' \
136 -e 's!repo.or.cz!<a href=http://&>&</a>!g' \
137 -e 's!:-)!\&#x263a;!g' \
138 -e "s!$image_pattern2!<center><img src=$URL\1></center>!g" \
139 -e 's!<bash>!<table\
140 border=1 bgcolor='$bash_bg'>\
141 <tr><td bgcolor=lightblue colspan=3>\
142 \&nbsp;\
143 </td></tr>\
144 <tr><td>\
145 <table cellspacing=5 border=0\
146 style="color:'$bash_fg';">\
147 <tr><td>\
148 <pre>!' \
149 -e 's!</bash>! </pre>\
150 </td></tr>\
151 </table>\
152 </td></tr>\
153 </table>!' \
154 -e "$(markup_substitution "''" i)" \
155 -e "$(markup_substitution "_" u)"
158 # output lines containing <timestamp> <filename> <title>
159 get_blog_entries () {
160 for file in $(ls -r source-*.txt)
162 basename=${file%.txt}
163 timestamp=${basename#source-}
164 title="$(sed 1q < $file | markup)"
165 echo "$timestamp $file $title"
166 done
169 # make HTML page
170 make_html () {
171 body_style="width:800px"
172 body_style="$body_style;background-image:url(${URL}paper.jpg)"
173 body_style="$body_style;background-repeat:repeat-y"
174 body_style="$body_style;background-attachment:scroll"
175 body_style="$body_style;padding:0px;"
176 text_style="width:610px"
177 text_style="$text_style;margin-left:120px"
178 text_style="$text_style;margin-top:50px"
179 text_style="$text_style;align:left"
180 text_style="$text_style;vertical-align:top;"
181 cat << EOF
182 <html>
183 <head>
184 <title>$TITLE</title>
185 <meta http-equiv="Content-Type"
186 content="text/html; charset=UTF-8"/>
187 </head>
188 <body style="$body_style">
189 <div style="$text_style">
190 <h1>$TITLE</h1>
192 indent='\t\t\t'
194 # make toc
195 toc_width=400px
196 toc_style="position:absolute;top:50px;left:810px;width=$toc_width"
198 echo "<div style=\"$toc_style\">"
199 echo "<table width=$toc_width bgcolor=#e0e0e0 border=1>"
200 echo "<tr><th>Table of contents:</th></tr>"
201 echo "<tr><td>"
202 echo '<p><ol>'
203 get_blog_entries |
204 while read timestamp filename title
206 date="$(date +"%d %b %Y" -d @$timestamp)"
207 echo "<li><a href=#$timestamp>$date $title</a>"
208 done
209 echo '</ol></p>'
210 echo '</td></tr></table>'
212 # RSS feed
213 rss_style="background-color:orange;text-decoration:none"
214 rss_style="$rss_style;color:white;font-family:sans-serif;"
215 echo '<br>'
216 echo '<div style="text-align:right;">'
217 echo "<a href=\"$ORIGURL$RSS\""
218 echo ' title="Subscribe to my RSS feed"'
219 echo ' class="rss" rel="nofollow"'
220 echo " style=\"$rss_style\">RSS</a>"
221 echo '</div>'
223 # Links
224 test -f links.html && {
225 echo "<br>"
226 echo "<table width=$toc_width bgcolor=#e0e0e0 border=1>"
227 echo "<tr><th>Links:</th></tr>"
228 echo "<tr><td>"
229 cat links.html
230 echo "</td></tr></table>"
233 # Google AdSense
234 test -z "$DRYRUN" && {
235 echo "<br>"
236 echo "<table width=$toc_width bgcolor=#e0e0e0 border=1>"
237 echo "<tr><th>Google Ads:</th></tr>"
238 echo "<tr><td align=center>"
239 cat << EOF
240 <script type="text/javascript"><!--
241 google_ad_client = "pub-5106407705643819";
242 /* 300x250, created 1/22/09 */
243 google_ad_slot = "6468207338";
244 google_ad_width = 300;
245 google_ad_height = 250;
246 //-->
247 </script>
248 <script type="text/javascript"
249 src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
250 </script>
252 echo "</td></tr></table>"
255 echo '</div>'
256 } | sed -s "s/^/$indent/"
259 # timestamps will not need padding to sort correctly, for some time...
260 get_blog_entries |
261 while read timestamp filename title
263 echo "<h6>$(make_date $timestamp)</h6>"
264 echo "<a name=$timestamp>"
265 echo "<h2>$title</h2>"
266 echo ""
267 echo "<p>"
268 sed 1d < $filename | markup
269 echo "</p>"
270 done |
271 sed -e "s/^./$indent&/" \
272 -e "/<pre>/,/<\/pre>/s/^$indent//"
274 cat << EOF
275 </div>
276 </body>
277 </html>
281 generate_rss () {
282 echo '<?xml version="1.0" encoding="utf-8"?>'
283 echo '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">'
284 echo '<channel>'
285 echo "<title>Dscho's blog</title>"
286 echo "<link>$URLPREFIX${URL}index.html</link>"
287 self="$URLPREFIX$ORIGURL$RSS"
288 selfattribs='rel="self" type="application/rss+xml"'
289 echo "<atom:link href=\"$self\" $selfattribs/>"
290 echo '<description>A few stories told by Dscho</description>'
291 echo "<lastBuildDate>$(date --rfc-2822)</lastBuildDate>"
292 echo '<language>en-us</language>'
294 get_blog_entries |
295 while read timestamp filename title
297 echo '<item>'
298 echo "<title>$title</title>"
299 echo "<link>$URLPREFIX${URL}index.html#$timestamp</link>"
300 echo "<guid>$URLPREFIX${URL}index.html#$timestamp</guid>"
301 echo "<pubDate>$(date --rfc-2822 -d @$timestamp)</pubDate>"
302 description="$(cat < $filename | markup invert-bash)"
303 echo "<description><![CDATA[$description]]></description>"
304 echo "</item>"
305 done
307 echo '</channel>'
308 echo '</rss>'
311 # never, ever have spaces in the file names
312 commit_new_images () {
313 generate_rss > $RSS &&
314 git add $RSS ||
315 die "Could not generate $RSS"
317 images=
318 for image in $(cat source-* |
319 tr ' ]|' '\n' |
320 sed -n 's/.*\[\[Image://p' |
321 sort |
322 uniq)
324 git add $image || die "Could not git add image $image"
325 images="$images $image"
326 done
328 git update-index --refresh &&
329 git diff-files --quiet -- $images &&
330 git diff --cached --quiet HEAD -- $images ||
331 git commit -s -m "Commit some images on $(make_date $now)" $images
336 # parse command line option
337 case "$1" in
338 *dry*) DRYRUN=1; shift;;
339 *show*) firefox "$(pwd)"/$TEST; exit;;
340 *remote*) firefox $URLPREFIX$URL$OUTPUT; exit;;
341 esac
343 test "$#" = 0 ||
344 die "Usage: $0 [--dry-run]"
346 # make sure we're on the correct branch
347 test refs/heads/$BRANCH = $(git symbolic-ref HEAD) ||
348 die "Not on branch $BRANCH"
350 # make sure there are no uncommitted changes
351 git update-index --refresh &&
352 git diff-files --quiet ||
353 die "Have unstaged changes!"
355 # rename the new blog entry if it exists
356 now=$(date +%s)
357 test ! -f $NEW || {
358 mv -i $NEW source-$now.txt &&
359 git add source-$now.txt
360 } ||
361 die "Could not rename source.txt"
363 # commit the images that are referenced and not yet committed
364 test ! -z "$DRYRUN" ||
365 commit_new_images ||
366 die "Could not commit new images"
368 # to find the images reliably, we have to use the commit name, not the branch
369 # we use the latest commit touching an image file.
370 IMAGEFILES="$(git ls-files |
371 grep -v '\.\(rss\|html\|gitignore\|in\|sh\|txt\)$')"
372 REV=$(git rev-list -1 HEAD -- $IMAGEFILES)
373 test -z "$REV" && REV=$BRANCH
374 URL="$REMOTEREPOSITORY?a=blob_plain;hb=$REV;f="
376 if test ! -z "$DRYRUN"
377 then
378 # Output to test.html and have local links into the current directory
379 OUTPUT=$TEST
380 URL=
383 make_html > $OUTPUT || die "Could not write $OUTPUT"
385 test ! -z "$DRYRUN" && {
386 move_new_entry_back
387 exit
390 git add $OUTPUT &&
391 git commit -s -m "Update $(make_date $now)" &&
392 git push origin +$BRANCH