s4

view s4-blog.sh @ 559:2f580c147434

File accessibility flag behavior corrected
author HIROSE Yuuji <yuuji@gentei.org>
date Sat, 13 Apr 2019 19:36:47 +0900
parents 591838015ac3
children 9328392f7c55
line source
1 #
2 type cgiinit >/dev/null 2>&1 || . ./s4-funcs.sh
4 # Global error flags
5 BLOG_NOTMEM=1
6 BLOG_FROZEN=2
7 FROZEN_TAG='<span class="frozen">[凍結]</span>'
9 blog_genform() {
10 #
11 t=$1
12 }
14 blog_writable() (
15 # $1=articleid $2=user
16 # Return: $?=0 - Writable
17 # =1 - NOT Writable because user is not a member
18 # =2 - NOT Writable because blog is frozen
19 blogowner=`getvalbyid blog owner "$1"`
20 state=`getvalbyid blog state "$1"`
21 rc=0
22 [ x"$blogowner" = x"$2" ] || isuser "$blogowner" || ismember "$2" "$blogowner" || rc=$((rc+$BLOG_NOTMEM))
23 [ "$state" = "frozen" ] && rc=$((rc+$BLOG_FROZEN))
24 return $rc
25 )
26 blog_readable() {
27 # $1=articleid $2=user
28 mode=`getgroupattr $grp regmode`
29 }
30 blog_notify_reply() (
31 # $1=blogid $2=ReplyingUser $3=WrittenText $4(optional)=Action
32 blogid="${1%%[!A-Z0-9a-z_]*}"
33 blogowner=`getvalbyid blog owner "$blogid"`
34 blogtitle=`getvalbyid blog title "$blogid"`
35 blogurl="$urlbase?replyblog+$blogid"
36 action=${4:-書き込み}
37 mode=`getvalbyid blog notify "$blogid"`
38 isgroup "$blogowner" && _isgroup=true || _isgroup=false
39 ### EXCEPT=`sqlquote "$user"` ## User should receive to feal some annoyance
40 case $mode in
41 admin)
42 if $_isgroup; then
43 emails=`getgroupadminmails $blogowner`
44 else
45 emails=`collectemail $blogowner`
46 fi
47 notifyto=`getpar notifyto`
48 if [ -n "$notifyto" ]; then
49 emails=$emails" `email4groupbyuid \"$blogowner\" $notifyto`"
50 fi
51 ;;
52 no) emails="" ;;
53 *) team=`query "SELECT val FROM blog_s
54 WHERE id=(SELECT id FROM blog WHERE rowid=$blogid)
55 AND key='team';"`
56 # team cannot get `getvalbyid blog team "$blogid"` because it's not
57 # defined in blog.def. Yes, it is Illegal USE!!
58 emails=`TEAM=$team collectemail $blogowner` ;;
59 esac
60 ## 2017-0210 Respond to the direct reply mark such as: >#1234
61 replymark=`echo "$3"|nkf -w -Z0|grep '^ *>#'`
62 authgecos=`gecos $2`
63 if [ -z "$4" -a -n "$replymark" ]; then
64 # If the action is new subscription($4="") and has ">#123" marks...
65 ids=`echo "$replymark"|sed 's/[^#0-9]*#\([0-9]*\)[^#0-9]*/\1 /g'`
66 ids=`echo $ids|tr -dc '[0-9 ]'|tr ' ' ','`
67 # -> 123,345,347
68 unames=`query "SELECT distinct author FROM article \
69 WHERE rowid in ($ids)\
70 AND blogid=(SELECT id FROM blog WHERE rowid=$blogid);"`
71 if [ -n "$unames" ]; then
72 e4g=$(if $_isgroup; then
73 email4group "$blogowner" $unames
74 else
75 for u in $unames; do
76 collectemail $u
77 done
78 fi)
79 emails=$emails" $e4g"
80 for e in $unames; do
81 g=`gecos $e`
82 whom=$whom"${whom:+,}${g:-$e}さん"
83 done
84 action="${whom}への返信"
85 fi
86 else
87 [ x"$2" = x"$blogowner" ] && return # If author=blogowner, unnecessary
88 fi
89 test -z "$emails" && return
90 err notify: user=$user Admins=`getgroupadmins $blogowner` Mode=$mode Emails="[$emails]"
91 SMAIL_TO="`echo "$blogowner" | nkf -jM | tr -d '\n'` readers <$admin>" \
92 smail "$emails" "${action}通知 $urlbase"<<EOF
93 [$blogtitle]板に${action}がありました。
94 ※このメイルに返信しても通知者には伝わりません(管理者宛になる)。
95 場所: $blogurl (返信先)
96 所有: $blogowner
97 題目: $blogtitle
98 筆者: $authgecos
99 内容:
100 `echo "$3"|sed 's/^/> /'`
101 EOF
102 )
104 blog_showentry() {
105 # $1=table $2=rowid
106 # if [ -n "$2" ]; then
107 # if [ -n "$imgcached" ]; then
108 # bstmpdir=$tmpdir/$imgcached/$thumbxy
109 # else
110 # bstmpdir=$tmpd
111 # # tmpd=`mktempd`
112 # # tmpfiles=$tmpfiles" $tmpd"
113 # fi
114 # fi
115 td=`getcachedir "article/$2"`
116 [ -d "$td" ] || mkdir -p $td
117 tbl=${1%%[!A-Z0-9a-z_]*} rowid=${2%%[!A-Z0-9a-z_]*}
118 err blow_showentry: rowid=$rowid, '$2'=$2 user=$user
119 ts=${tbl}_s tm=${tbl}_m
120 at=article as=article_s am=article_m
121 serial=$(($(date +%s)-1420038000))s$$
122 cannotread='<div class="relative"><img class="overlap" src="img/key.png" alt="(読み取り不可)"></div>'
123 blog_writable $rowid $user
124 rc=$?
125 if [ $rc = 0 ]; then
126 iswritable=true
127 ismem=true
128 else
129 iswritable=false
130 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ]; then
131 ismem=false
132 else
133 ismem=true
134 fi
135 fi
136 # This function grasps blog entry definiton directly.
137 # blog: id
138 # blog_s: title,ctime,heading
139 # blog_m: *article
141 blogowner=`getvalbyid blog owner "$2"`
142 isgroup "$blogowner" && isgroup=true || isgroup=false
143 isgrpadmin=false # Reversed later (*1)
145 # 2015-10-05 check readable
146 if ! $iswritable; then
147 # err blogowner=$blogowner
148 if $isgroup; then
149 regmode=`getgroupattr $blogowner regmode`
150 # err regmode=$regmode
151 if [ x"$regmode" = x"moderated" ]; then
152 # if ! ismember $user $blogowner; then
153 if ! $ismem; then
154 echo "加入してからどうぞ" | html p
155 return
156 fi
157 fi
158 fi
159 else # if writable
160 isgrpowner "$user" "$blogowner" && isgrpadmin=true # (*1)
161 fi
162 case `getvalbyid blog notify "$rowid"` in # "all", "admin" or "no" (or NULL)
163 admin) notifyto=1 ;;
164 *) notifyto="" ;;
165 esac
166 case `getvalbyid blog mode "$rowid"` in
167 *quiz*|*close*) f_exclusive=1 ;;
168 *) f_exclusive='' ;;
169 esac
171 # err "SELECT id from $tbl where rowid=$rowid"
172 id=`query "select id from $tbl where rowid=$rowid;"`
173 #err id=$id
174 #err "select val from $ts where key='title' and id='$id';"
176 #(1)Display root article
177 cat<<EOF
178 <form class="replyblog" action="$myname?replyblog+${rowid}#bottom" method="POST" enctype="multipart/form-data">
179 <table class="bloghead">
180 EOF
182 href="<a href=\"?editheading+$rowid\" accesskey=\"e\" title=\"E\"> 編集 </a>"
183 if $ismem; then
184 case `getvalbyid blog mode $rowid` in
185 *report*|*quiz*)
186 href2="<a href=\"?lshandout+$rowid\" accesskey=\"l\" title=\"L\"> 提出状況 </a>"
187 ;;
188 esac
189 href3="(<a href=\"?gethandout+$rowid\" accesskey=\"f\" title=\"F\">ファイル取得</a>)"
190 fi
191 href4='<a href="#bottom" accesskey="b" title="B"> 末尾へ</a>'
192 $isgrpadmin &&
193 href5="<a href=\"?blogseen+$rowid\" accesskey=\"s\" title=\"S\"> 読刻</a>"
194 quizmodefile=$td/quiz; rm -f "$quizmodefile" # XXX: Global state
196 query<<-EOF |
197 SELECT coalesce((SELECT "yes" FROM blog
198 WHERE rowid=$rowid AND author='$user'),
199 ''),
200 max(CASE key WHEN 'ctime' THEN val END) ctime,
201 max(CASE key WHEN 'heading' THEN hex(val) END) heading,
202 CASE (SELECT val FROM $ts WHERE key="mode" AND id="$id")
203 WHEN 'report-closed' THEN 'レポート提出用(closed)'
204 WHEN 'report-open' THEN 'レポート提出用(open)'
205 WHEN 'quiz' THEN 'クイズ'
206 ELSE ''
207 END
208 FROM $ts WHERE id='$id' GROUP BY id;
209 EOF
210 { IFS='|' read edit ctime hexhead blogtype
211 cat<<-EOF
212 <tr><td>${edit:+$href }$ctime $blogtype $href2$href3 $href4 $href5</td></tr>
213 <tr class="preface${frozen_class:+ }$frozen_class">
214 <td>`echo "$hexhead"|unhexize|hreflink|minitbl`</td></tr>
215 </table>
216 EOF
217 case "$blogtype" in
218 "クイズ")
219 echo "クイズモードは本人と管理者の書き込みのみが表示されます。"
220 ;;
221 esac | html p 'class="warn"'
222 echo '<table class="blog_replies">'
223 if [ x"$blogtype" = x"クイズ" ]; then
224 if $isgroup; then
225 if ! isgrpowner "$user" "$blogowner"; then
226 qgrp=`sqlquote "$blogowner"`
227 cat<<-EOF > $quizmodefile
228 AND (author IN (SELECT user FROM grp_adm WHERE gname=$qgrp)
229 OR
230 author='$user')
231 EOF
232 fi
233 else # if user's blog
234 if [ x"$user" != x"$blogowner" ]; then
235 cat<<-EOF > $quizmodefile
236 AND author IN ('$blogowner', '$user')
237 EOF
238 fi
239 fi
240 fi
241 }
242 lkhome="<a href=\"$myname?home" lke='">'
243 lkedit="<a href=\"$myname?editart"
244 hlink="$myname?home" elink="$myname?editart"
245 catlink="$myname?showattc+article_m"
246 deficon="img/file-icon.png"
247 # 2016-08-15 Newer flag introduced
248 atime=`query "SELECT time FROM acclog
249 WHERE tbl='blog' AND tblrowid=$rowid AND user='$user';"`
250 iconcleaner=$tmpd/iconcleaner.$$
251 [ -s $quizmodefile ] && cond_qz=`cat $quizmodefile`
252 # *** DO NOT USE query(), use "sq $db" instead here ***
253 # because the next block in pipe line uses query() repeatedly.
254 sq $db<<EOF |
255 WITH a_s AS (
256 SELECT id,
257 max(CASE key WHEN 'ctime' THEN val END) TIME,
258 max(CASE key WHEN 'text' THEN val END) TEXT
259 FROM article_s
260 GROUP by id
261 )
262 SELECT a.id,
263 CASE author
264 WHEN '$user' THEN a.rowid||'+'||$rowid
265 ELSE ''
266 END edit,
267 CASE -- 「通知送信」ボタンの有無
268 WHEN '$notifyto' = '' THEN '' -- 不要モードならなし
269 WHEN '$user' = author THEN '' -- 筆者自身ならなし
270 ELSE "yes"
271 END notify,
272 (SELECT rowid FROM user WHERE name=author) user_rid,
273 coalesce((SELECT val FROM user_s
274 WHERE name=author AND key='gecos'),
275 author) uname,
276 (SELECT val FROM user_s WHERE name=author AND key='$iconcachekey')
277 icon,
278 a.rowid,
279 s.TIME,
280 CASE WHEN s.TIME > '$atime' THEN 'new' ELSE '' END newer,
281 hex(s.TEXT),
282 CASE -- File Accessibility to attached file
283 WHEN '$f_exclusive' = '' THEN ''
284 WHEN '$isgrpadmin' = 'true' THEN ''
285 WHEN '$user' = author THEN ''
286 ELSE 'Unreadable'
287 END cannotread,
288 (SELECT group_concat(rowid||':'||length(bin)||':'||hex(val), ' ')
289 FROM article_m
290 WHERE id=a.id AND key='image') imxgids
291 FROM (select rowid,id,author from article
292 where blogid in
293 (select id from blog where rowid=$rowid)
294 $cond_qz) a
295 LEFT JOIN
296 a_s s
297 ON a.id=s.id;
298 EOF
299 while IFS='|' read id edit notify uid uname icon aid tm new hte fa imgids
300 do
301 cachefile="$td/$id.row.html"
302 stampfile="$td/$id.row.stamp"
303 editlink="${edit:+<a href="$elink+$edit">編集</a> }"
304 nt="<label style=\"font-size: 70%;\"><input type=\"checkbox\"\
305 name=\"notifyto\" value=\"$uid\">返信通知送信</label>"
306 # fa is file accessibility flag # err "----r=$aid fa=[$fa]----"
308 # First, check the availability of user-icon.
309 # If not existent, clear and reset row cache by rm $stampfile
310 if [ ! -s "$icon" ]; then
311 rm -f "$stampfile"; unset stampfile
312 fi
313 if test -s "$stampfile" &&
314 test -s "$cachefile" &&
315 { ts=`cat "$stampfile"`; test -n "$ts"; } &&
316 test "$ts" '>' "$tm" && # Cache timestamp is newer
317 test "$stampfile" -nt "$icon"; then # UserIcon is older
318 : Nothing to do
319 else
320 { ######## New ROW creation begins here ######## >$cachefile
321 tdcls="__NEWCLS__repatt"
322 if [ -s "$icon" ]; then
323 icfn=`echo "$icon"|htmlescape`
324 picon="<p class=\"proficon\"><a href=\"$hlink+$uid\"><img src=\"$icfn\"></a></p>"
325 else
326 echo "DELETE FROM user_s WHERE key='$iconcachekey' AND
327 val=`sqlquotestr \"$icon\"`;" >> $iconcleaner
328 picon=""
329 fi
331 cat<<EOF
332 <tr id="$id">
333 <td class="$tdcls">${picon}__EDIT__<a href="#$aid">#$aid</a>
334 <a href="$hlink+$uid">$uname</a>
335 $tm
336 <__NOTIFY__></td>
337 EOF
338 echo -n "<td id=\"$aid\" class=\"repl\">"
339 echo "$hte"|unhexize|htmlescape|hreflink|minitbl
340 usecache='' tsfile=$td/$id.stamp
341 for i in $imgids; do
342 mrid=${i%%:*}; i=${i#*:}; sz=`size_h ${i%%:*}`
343 fn=`echo "${i#*:}"|unhexize`
344 fnb=$fn"(${sz})"
345 case "$fn" in
346 *.[Pp][Nn][Gg]|*.[Jj][Pp][Gg]|*.[Jj][Pp][Ee][Gg]|*.[GgTt][Ii][Ff])
347 # fmt=${fn##*.} # convert - jpg:- is slow...why
348 case "$fn" in
349 *.[Pp][Nn][Gg]) fmt=png ;;
350 *.[Gg][Ii][Ff]) fmt=gif ;;
351 *) fmt=jpeg ;;
352 esac
353 outfile=$td/$mrid-${fn%.*}.$fmt
354 #err fn=$fn outfile=$outfile
355 #err "usecache=$usecache `ls -l $outfile`"
356 #err tm=$tm
357 #err tsfile=$tsfile=`cat $tsfile`
358 if [ -s "$outfile" ] && # $outfile should be > 0
359 { [ "$usecache" ] || # And usecache flag is true, or...
360 { [ -s "$tsfile" ] && [ x"`cat $tsfile`" = x"$tm" ]
361 };}; then
362 usecache=1 # Set usecache flag on
363 cat<<-EOF
364 <a href="$catlink+$mrid"><img src="$outfile">
365 $fnb</a>
366 EOF
367 # !!NOTE!! Create row stamp ONLY WHEN imgcache is active
368 else
369 query "SELECT hex(bin) FROM article_m WHERE rowid=$mrid;" \
370 | unhexize \
371 | convert -define ${fmt}:size=100x100 -resize 100x100'>' \
372 - ${fmt}:- \
373 | tee "$outfile" \
374 | hexize \
375 | sed -e 's/\(..\)/%\1/g' \
376 -e "s|^|<a href=\"$catlink+$mrid\"><img src=\"data:image/$fmt,|" \
377 -e "s|\$|\">$fnb</a>|"
378 unset stampfile # img data stream is not suitable to cache
379 echo $tm > $tsfile
380 fi
381 ;;
382 *)
383 echo "<__UNREADABLE__><a href=\"$catlink+$mrid\"><img src=\"$deficon\">$fnb</a>"
384 ;;
385 esac
386 done
387 echo "</td></tr>"
388 } > "$cachefile" ######## New ROW Creation Ends here ########
389 test -n "$stampfile" && date "+%F %T" > $stampfile
390 fi
391 # Printing a cached row
392 sed -e "/^<td class=/s/__NEWCLS__/$new${new:+ }/" \
393 -e "/^<td class=/s,__EDIT__,$editlink," \
394 -e "/^<__NOTIFY__>/s,,${notify:+$nt}," \
395 -e "/<__UNREADABLE__>/s,,${fa:+$cannotread}," \
396 $cachefile
397 done
399 help="=== コメントに使用できる特殊記法 ===
400 行頭に href=URL でURLへのリンク
401 行頭に iframe=URL でURL先を開く iframe
402 [[#記事番号]] でs4内の記事番号に飛ぶリンク
403 [[#検索キーワード]] でs4内の記事検索(記号はいくつか使えない)
404 [[URL]] でURLへのリンク、 [[URL|文字列]]でアンカー文字列指定
405 {{画像URL}} でインライン画像、 {{画像URL|幅}} でピクセル幅指定
406 {{{URL}}} でURL先を開く iframe、 {{{URL|高さ}}} ピクセル高さ指定
407 行頭: ## 大見出し, ### 中見出し, #### 小見出し
408 行末の2連続スペースで強制改行(<br>)
409 |*見出し列|列2|列3… と行頭から始まる縦棒区切り行を続けて表
410 ' *語群* ' で強調(両側の空白必要、** でもっと強調。*の代わりに _ でも可)
411 - [ ] と - [x] でチェックボックス"
412 touchhelp="${touchpanel:+<p class=\"help\">$help</p>}"
413 filehelp="《添付の注意》
414 $file_accept_help"
415 textform='<div class="fold">
416 <input type="checkbox" id="cmt" checked><label
417 accesskey="c" title="C" for="cmt">コメントする</label><div>
418 <table class="b">
419 <tr><td><textarea name="text" cols="72" rows="4" title="'"$help"'">
420 </textarea>'"$touchhelp</td></tr>
421 <tr><td>添付ファイル(${filesize_max_MB}以下):"'
422 <input type="file" name="image"'" $file_accept title=\"$filehelp\" multiple></td></tr>"'
423 </table>
424 <input type="submit" value="送信">
425 <input type="reset" value="リセット"></div></div>
426 '
427 cat<<-EOF
428 </table> <!-- end of s4-blog:blog_showentry() main table -->
429 <p class="update_link"><a
430 href="?reload/$rowid" accesskey="r" title="R">再読込</a> / <a
431 href="#title" id="bottom" accesskey="t" title="T">先頭へ</a></p>
432 EOF
433 $iswritable && cat<<-EOF
434 <div class="blogcomment">
435 <input type="hidden" name="blogid" value="$id">
436 <input type="hidden" name="id" value="`genserial`">
437 <input type="hidden" name="stage" value="replyblog">
438 $textform
439 </div>
440 </form> <!-- End of s4-blog:blog_showentry() main form -->
441 EOF
442 # Clean up orphaned icon cache
443 [ -s $iconcleaner ] && query ".read '$iconcleaner'"
444 # Record access log
445 acclog blog $rowid
446 }
448 lshandout() {
449 # $1=rowid of blog
450 blog_writable $1 $user
451 rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member
452 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then
453 echo "メンバー以外は利用できません。" | html p; return
454 fi
455 time=`getvalbyid blog ctime $1|colrm 11`
456 owner=`getvalbyid blog owner $1`
457 title=`getvalbyid blog title $1`
458 ge=`gecos $owner`
459 fh=$tmpd/formhead
460 echo "$time [$title]@${ge:-$owner}" > $fh
461 lshandoutsub $owner "$@" \
462 |_m4 -D_TITLE_="提出状況" \
463 -D_FORMHEAD_="syscmd(cat $fh)" \
464 -D_FORM_="syscmd(cat)" -D_DUMPHEAD_= -D_DUMPTABLE_= \
465 $layout/html.m4.html $layout/form+dump-whead.m4.html
466 gn=`echo $owner|htmlescape`
467 echo "<p><a href=\"?lshandoutall+$1\">グループ $gn すべてのレポート板集計</a></p>"
468 }
469 gethandoutcsv() {
470 # contenttype; echo
471 CATCSV=1 lshandoutall "$1"
472 }
473 gethandoutcsv2() {
474 # contenttype; echo
475 SQL=$(cat<<-EOF
476 WITH this_blog_articles AS (
477 SELECT rtb.id bid, rtb.brid, a.id aid, author, title, ctime
478 FROM report_type_blogs rtb JOIN article a ON rtb.id=a.blogid
479 ), text_or_file AS (
480 SELECT bid, author, title, ctime, 'text' shu, count(val) cnt
481 FROM this_blog_articles tba, article_s s
482 ON tba.aid=s.id
483 WHERE key='text'
484 GROUP by bid, author
485 UNION
486 SELECT bid, author, title, ctime, 'file' shu, count(val) cnt
487 FROM this_blog_articles tba, article_m m
488 ON tba.aid=m.id
489 WHERE key='image'
490 GROUP by bid, author
491 ), count_list AS (
492 SELECT author,
493 substr(ctime, 1, 10)||upper(substr(shu, 1, 1)) unit,
494 cnt
495 FROM text_or_file
496 )
497 SELECT gecos "名前",
498 substr(author, 1, instr(author, '@')-1) "uname",
499 unit,
500 cnt "post"
501 FROM count_list cl JOIN gecoses g ON cl.author=g.name;
502 EOF
503 ) gethandoutcsv "$1"
504 }
505 lshandout_ulink_table() {
506 # NO Args. Read stdin as SQL
507 echo '<table class="b td3rr td3evw">'
508 hrb="<a href=\"?home+"
509 # echo "$sql" | sq -header -html $db \ # Formerly, this is called via sq()
511 printf ".mode html\n.header ON\n" | query
512 cat | query \
513 | sed -e "s,\(<TR><TD>\)\([^ ]*\) \(.*\)</TD>,\1$hrb\2\">\3</TD>," -e 's,<TD>0</TD>,<TD class="warn">0</TD>,'
514 echo '</table>'
515 printf ".mode list\n.header OFF\n" | query
516 }
517 lshandoutall() {
518 # $1=rowid of blog
519 blog_writable $1 $user
520 rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member
521 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then
522 echo "メンバー以外は利用できません。" | html p; return
523 fi
524 rowid=$(($1 + 0))
525 owner=`getvalbyid blog owner $1`
526 qowner=`sqlquotestr "$owner"`
528 query<<-EOF
529 CREATE TEMPORARY TABLE IF NOT EXISTS report_type_blogs AS
530 WITH blog_owner_mode AS (
531 SELECT id,
532 blog.rowid brid,
533 max(CASE key WHEN 'owner' THEN val END) owner,
534 max(CASE key WHEN 'mode' THEN val END) mode,
535 max(CASE key WHEN 'title' THEN val END) title,
536 max(CASE key WHEN 'ctime' THEN val END) ctime
537 FROM blog NATURAL JOIN blog_s
538 GROUP BY id
539 )
540 SELECT id, brid, title, ctime FROM blog_owner_mode
541 /* WHERE owner=$qowner AND mode LIKE '%report%'; */
542 WHERE owner=$qowner
543 AND
544 (mode LIKE '%report%' OR mode LIKE '%quiz%');
545 /* ↑これでレポート形式の blogid 一覧を得る */
546 EOF
547 if [ -z "$CATCSV" ]; then
548 _m4 -D_TITLE_="提出状況" $layout/html.m4.html
549 ge=`gecos "$owner"`
550 tbls=""
551 grptxt=`echo "${ge:-$owner}"|htmlescape`
552 echo "<h1>$grptxt 書き込み状況一覧</h1>"
553 fi
554 if [ -z "$SQL" ]; then
555 bridlist=`query "SELECT brid FROM report_type_blogs;"`
556 for brid in $bridlist; do # Skip this loop if $SQL set
557 brid=$(($brid + 0)) # Ensure to be a number
558 [ $brid = 0 ] && continue
559 time=`getvalbyid blog ctime $brid|colrm 11`
560 title=`getvalbyid blog title $brid|htmlescape`
561 state=`getvalbyid blog state $brid|htmlescape`
562 tt="handout_$brid"
563 [ "$state" = "frozen" ] && frozen=" $FROZEN_TAG" || frozen=""
564 if [ -z "$CATCSV" ]; then
565 echo "<h2>$time - <a href=\"?replyblog+$brid\">$title</a>$frozen</h2>"
566 lshandoutsub "$owner" $brid "$tt"
567 else
568 lshandoutsub "$owner" $brid "$tt" >/dev/null # Only create temp.table
569 fi
570 tbls="$tbls${tbls:+ NATURAL JOIN }$tt"
571 done
572 fi
573 sql=${SQL:-"SELECT * FROM $tbls;"}
574 if [ -z "$CATCSV" ]; then
575 echo "<hr><h2>総合</h2>"
576 echo "$sql" | lshandout_ulink_table
577 echo "<h2>総合(<a href=\"?gethandoutcsv+$rowid\">CSV</a>)</h2>"
578 printf ".mode csv\n.header ON\n" | query
579 echo '<pre class="list">'
580 echo "$sql" | query | sed 's/^"[0-9]* /"/'
581 echo "</pre>"
582 echo "<pre><a href=\"?gethandoutcsv2+$rowid\">縦持ちCSV</a></pre>"
583 else
584 contenttype "Application/CSV"
585 printf ".mode csv\n.header ON\n" | query >/dev/null
586 fn=report-count.csv
587 printf 'Content-Disposition: filename="%s"\n' "$fn"
588 outfile=$tmpd/out-$$.csv
589 echo "$sql" | query | sed 's/^"[0-9]* /"/' > $outfile
590 echo "Content-Length: " `cat $outfile | wc -c`; echo
592 cat $outfile
593 exit 0
594 fi
595 printf ".mode list\n.header OFF\n.separator |\n" | query
596 }
597 lshandoutsub() {
598 # $1=owner $2=rowid of blog &optional $3=temp_table name
599 qgname=`sqlquote "$1"`
600 if isgroup "$1"; then
601 sample="(select user from grp_mem where gname=$qgname)"
602 else
603 sample="(select distinct author as user from arts)"
604 echo "(集計は板への投稿者のみ)" | html p
605 fi
606 tmpname="${3:-handout_$2}"
607 sql="CREATE TEMPORARY TABLE IF NOT EXISTS $tmpname AS
608 with arts as (select id,author from article \
609 where blogid=(select id from blog where rowid=$2))\
610 select (select rowid from user where name=c0.user)||' '|| \
611 (select gecos from gecoses where name=c0.user) as 'メンバー',\
612 substr(c0.user, 1, instr(c0.user, '@')-1) 'uname',\
613 sum(case when c1.key is not null then 1 else 0 end)\
614 as '[$title] コメント記入',\
615 sum(case when c2.key is not null then 1 else 0 end)\
616 as '[$title] ファイルの提出'\
617 from $sample c0 \
618 left join (select id,author from arts) a\
619 on c0.user=a.author\
620 left join (select id,key from article_s where key='text') c1\
621 on a.id=c1.id left join (select id,key from article_m ) c2\
622 on c1.id=c2.id group by c0.user order by c0.user;\
623 \
624 SELECT * FROM $tmpname;"
625 err ishandoutsub: sql="$sql"
626 echo "$sql" | lshandout_ulink_table
627 }
628 gethandout() {
629 # $1=rowid of blog
630 blog_writable $1 $user
631 rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member
632 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then
633 echo "メンバー以外は利用できません。" | html p; return
634 fi
635 i=0
636 bd=$tmpd/archive.$$
637 mkdir $bd
638 query "select m.rowid,author,m.val from article a join article_m m\
639 on a.id=m.id where blogid=(select id from blog where rowid=$1)\
640 and m.key in ('image', 'document', 'binary');" \
641 | while IFS='|' read rowid author filename; do
642 err isfilereadable $user article_m $rowid
643 isfilereadable $user article_m $rowid || continue
644 err ok
645 i=$((i+1))
646 dir=`printf $bd/%03d $i`
647 mkdir $dir
648 query "select quote(bin) from article_m where rowid=$rowid;" \
649 | unhexize > $dir/$filename
650 done
651 if [ ! -d $bd/001 ]; then
652 contenttype; echo
653 echo "取得できるファイルがありませんでした。" | html p
654 return
655 fi
656 (cd $bd
657 ## err cdto$bd; (pwd; ls -lFa) 1>&3
658 tar zcf .archive.tar.gz * && mv .archive.tar.gz archive.tar.gz
659 err Creating tar archive "`ls -l archive.tar.gz`"
660 )
661 arc=$bd/archive.tar.gz
662 echo "Content-type: application/x-gzip"
663 echo "Content-Length: `cat $arc|wc -c`"
664 echo "Content-Disposition: filename=\"archive.tar.gz\""
665 echo
666 cat $arc
667 }
668 blogseen() { # $1 = blogid
669 blogid=${1%%[!0-9]*}
670 if [ -z "$blogid" ]; then
671 echo "Invalid blog id" | html p; exit
672 fi
673 blog_writable "$blogid" "$user"
674 rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member
675 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then
676 echo "メンバー以外は利用できません。" | html p; return
677 fi
678 owner=`getvalbyid blog owner $rowid`
679 qowner=`sqlquotestr "$owner"`
680 grprowid=`query "SELECT rowid FROM grp WHERE gname=$qowner;"`
681 ge=`gecos "$owner" | htmlescape`
682 title=`getvalbyid blog title $rowid | htmlescape`
683 h1="アクセス時刻"
684 link2board="<a href=\"?replyblog+$rowid\">$title</a>"
685 link2group="<a href=\"?grp+$grprowid\">$ge</a>"
686 _m4 -D_TITLE_="$h1" $layout/html.m4.html
687 echo "$h1" | html h1
688 echo "[$link2board]@$link2group" | html h2
689 warn=' class="warn"'
690 cat <<-EOF
691 <table class="b">
692 <tr><th>メンバー</th><th>uname</th><th>最終閲覧時刻</th></tr>
693 EOF
694 query <<-EOF |
695 WITH grpmem as (
696 SELECT user, (SELECT gecos FROM gecoses WHERE name=user) gecos
697 FROM grp_mem
698 WHERE gname=(SELECT val FROM blog_s
699 WHERE id=(select id from blog where rowid=$blogid)
700 AND key='owner')
701 ), acctime AS (
702 SELECT user, max(time) atime
703 FROM tblaccesses
704 WHERE tbl='blog' AND tblrowid=$blogid
705 GROUP BY user
706 )
707 SELECT g.user,
708 (SELECT rowid FROM user u WHERE u.name=g.user),
709 hex(gecos),
710 atime
711 FROM grpmem g LEFT JOIN acctime t
712 ON g.user = t.user
713 GROUP BY g.user
714 ORDER BY atime DESC;
715 EOF
716 while IFS='|' read u uid hexge time; do
717 td=${time:+"<td>"} # If the variable time is set, td=<td>
718 td=${td:-"<td$warn>"} # else td=<td class="warn">
719 cat <<-EOF
720 <tr>
721 <td><a href="?home+$uid">`echo "$hexge"|unhexize|htmlescape`</a></td>
722 <td>`echo ${u%%@*}|htmlescape`</td>
723 $td${time:----}</td></tr>
724 EOF
725 done
726 cat <<-EOF
727 </table>
728 <p><a href="?replyblog+$rowid">[$title]に戻る</a></p>
729 </html>
730 EOF
731 }
732 lsmyfile() { # $1(optional)=SortBy
733 case "$1" in
734 ""|CTIME-DESC)
735 by="CTIME" ord="DESC" ;;
736 CTIME*) by="CTIME" ;;
737 FILE*) by="FILE" ;;
738 OWNER*) by="OWNER" ;;
739 TITLE*) by="TITLE" ;;
740 esac
741 case "$1" in
742 *DESC) ord="DESC" ;;
743 esac
744 case "$ord" in
745 DESC) lkod="" jord="降順" ;;
746 *) lkod="-DESC" jord="昇順" ;;
747 esac
748 sql="select m.val||'/'||m.rowid FILE,
749 coalesce(
750 case when (select name from user where name=bs.owner)
751 is not null
752 then (select val from user_s where name=bs.owner
753 and key='gecos')
754 when (select gname from grp where gname=bs.owner)
755 is not null
756 then (select val from grp_s where gname=bs.owner
757 and key='gecos')
758 else
759 null
760 end,
761 bs.owner
762 ) OWNER,
763 a_s.val CTIME,
764 ',t,'||bs.title||':'||b.rowid||'#'||a.id TITLE
765 from (select rowid,id,val from article_m where id
766 in (select id from article where author='$user')
767 and type like 'file:%')
768 m left join article a on m.id=a.id
769 left join article_s a_s on a.id=a_s.id and a_s.key='ctime'
770 left join (select id,
771 max(case key when 'owner' then val end) as owner,
772 max(case key when 'title' then val end) as title
773 from blog_s group by id)
774 bs on a.blogid=bs.id
775 left join blog b on bs.id=b.id
776 where m.val is not null order by $by $ord;"
777 err lshandoutbyauthor: sql=`echo "$sql"`
778 title="個人提出ファイル"
779 _m4 -D_TITLE_=$title $layout/html.m4.html
780 hra="<a href=\"?lsmyfile+"
781 hrb="<a href=\"?showattc+article_m+"
782 hrc="<a href=\"?replyblog+"
783 (echo '<table class="b">'
784 echo "$sql"|sq -html -header $db ) \
785 | sed -e "s|\(<TR><TD>\)\([^/]*\)/\([0-9]*\)|\1$hrb\3\">\2</a>|" \
786 -e "s|,t,\(.*\):\([^<]*\)\(</TD>\)|$hrc\2\">\1</a>\3|" \
787 -e "s|\(<TH>\)\([A-Z]*\)\(</TH>\)|\1$hra\2$lkod\">\2</a>|" \
788 | _m4 -D_TITLE_=$title -D_FORM_="<p>($by$jord)</p>" \
789 -D_DUMPTABLE_="syscmd(cat)" $layout/form+dump.m4.html
790 echo '</table>'
791 }
792 searchart() {
793 kwd=`getpar kwd|nkf -wZ1` # Convert Zenkaku-SPC to ASCII-SPC
794 bloglist=`getpar bloglist|sed 's/[^0-9,]//g'`
795 kwdgrp=""
796 authcond=""
797 if [ -z "$kwd" ]; then
798 echo "検索語を指定してください" | html p; return
799 fi
800 if logstart "$searchlog"; then
801 { echo "kwd=$kwd"
802 test -n "$bloglist" && echo "bloglist=$bloglist"
803 } >> $searchlog
804 logend "$searchlog"
805 fi
806 if expr x"$kwd" : 'x#[1-9][0-9]*$' >/dev/null 1>&2; then
807 # Like '#1234', assume as artID
808 rowid=$((${kwd#\#} + 0)) # Force to be a number
809 kc="ar.rowid = $rowid"
810 else
811 for k in `echo "$kwd" | sed "s/'/''/g"`; do # With wrap quotes
812 ctime=""
813 if expr x"$k" : 'x@[><= ]*[1-9][][0-9]*-[][0-9:-]*$' >/dev/null >&2; then
814 # '@<2016-10-10' -> ctime < '2016-10-10'
815 # '@>=2016-10-10' -> ctime >= '2016-10-10'
816 # '@2016-10-10' -> ctime GLOB '@2016-10-10'
817 k=${k#@}
818 case "$k" in
819 [\<\>]*) op=${k%%[!<>=]*}; ctime=${k##*[><= ]} ;;
820 *) op='GLOB'; ctime="${k##*[><= ]}*" ;;
821 esac
822 kc=$kc${kc:+" AND "}"ctime $op '${ctime}'"
823 # Not sure GROUP BY a.blogid is comfortable for searchers...?
824 ##### kwdgrp=" GROUP BY a.blogid" ## Add this to lessen results
825 elif [ x"$k" = x"@today" -o x"$k" = x"@今日" ]; then
826 ctime=`date +%F`
827 elif n=`expr x"$k" : 'x@\([0-9]*\)days*'` >/dev/null >&2; then
828 ctime=`query "SELECT datetime('now', 'localtime', '-$n days');"`
829 elif [ x"$k" = x"@week" ]; then
830 ctime=`query "SELECT datetime('now', 'localtime', '-7 days');"`
831 elif n=`expr x"$k" : 'x@\([0-9]*\)weeks*'` >/dev/null >&2; then
832 n=$((n * 7))
833 ctime=`query "SELECT datetime('now', 'localtime', '-$n days');"`
834 elif [ x"$k" = x"@month" ]; then
835 ctime=`query "SELECT datetime('now', 'localtime', '-1 month');"`
836 elif n=`expr x"$k" : 'x@\([0-9]*\)months*'` >/dev/null >&2; then
837 ctime=`query "SELECT datetime('now', 'localtime', '-$n month');"`
838 elif [ x"$k" = x"@year" ]; then
839 ctime=`query "SELECT datetime('now', 'localtime', '-1 year');"`
840 elif n=`expr x"$k" : 'x@\([0-9]*\)years*'` >/dev/null >&2; then
841 ctime=`query "SELECT datetime('now', 'localtime', '-$n year');"`
842 fi
843 if [ -n "$ctime" ]; then
844 kc=$kc${kc:+" AND "}"ctime > '${ctime}'"
845 else
846 e=""
847 case "$k" in
848 *${likeesc}*) e="" ;; # Giving up char-escaping
849 *%*|*_*) k=`echo "$k"|sed "s/\([%_]\)/${likeesc}\1/g"`
850 e=" ESCAPE '$likeesc'" ;;
851 esac
852 kc=$kc${kc:+" AND "}"content LIKE '%$k%'$e"
853 fi
854 done
855 fi
856 kwd=`echo "$kwd"|htmlescape`
857 owner=`getpar owner`
858 owner=${owner:-$1}
859 msg=""
860 if [ -n "$owner" ]; then
861 cond="where key='owner' and val='$owner'"
862 if isuser $owner; then
863 msg="(`linkhome $owner` さんの記録から)"
864 else
865 linkhome $owner 1>&3
866 msg="(`linkhome $owner` グループから)"
867 fi
868 elif { author=`getpar author`; test -n "$author"; }; then
869 atptn=`sqlquotestr $author`
870 #kc="$kc${kc:+ AND }author=$atptn"
871 authcond="WHERE author=$atptn"
872 if isuser $author; then
873 msg="(`linkhome $author` さんの書き込みから)"
874 fi
875 fi
876 if [ -n "$bloglist" ]; then
877 blogcond="AND bl.rid IN ($bloglist)"
878 fi
880 sf=`search_form "$search_form_args" "$kwd" | sed '1d;$d'` # rm <div></div>
881 echo "$sf" | sed -e "/POST SENTENCE/s/.*/__PS__/" -e "/EOF/q" \
882 | _m4 -D__PS__="による検索結果$msg"
883 echo "(上記入力窓で再検索すると下記の掲示板のみに絞って再検索します)" \
884 | html p 'class="small"'
885 # article_s: id=article-id, key='text', val='TEXT'
886 # article: id=article-id, blogid=blogkd
887 # blog: id=blog-id, author=LeaderAuthor
888 # blog_s: id=blog-id, key='title', val='BLOG-TITLE'
889 # WANT: blog-ROWid,article-id,val(TEXT)
890 sql2="`sql4readableblogs` -- Extract user-readable blogs
891 -- 0.3sec
892 WITH artsm AS (
893 SELECT a.id,ctime, text || ' ' || coalesce(files, '') content
894 FROM article a
895 LEFT JOIN
896 (SELECT ars.id, ctime, text, coalesce(files, '') files
897 FROM (SELECT id,
898 max(CASE key WHEN 'ctime' THEN val END) ctime,
899 max(CASE key WHEN 'text' THEN val END) text
900 FROM article_s
901 GROUP BY id) ars
902 LEFT JOIN
903 (SELECT id, group_concat(val) files
904 FROM article_m
905 WHERE type LIKE 'file:%'
906 GROUP BY id) arm
907 ON ars.id=arm.id
908 ) ar
909 ON a.id=ar.id
910 ), ar AS (
911 SELECT a.rowid, a.blogid, a.id, a.author, ctime, content
912 FROM article a JOIN artsm ON a.id=artsm.id
913 $authcond
914 ), bl AS (
915 SELECT blg.rid, blg.*, blog_s.val TITLE
916 FROM readableblogs blg JOIN blog_s ON blg.id=blog_s.id AND blog_s.key='title'
917 )
918 SELECT bl.rid||'#'||ar.id '',
919 bl.title TITLE,
920 (SELECT gecos FROM gecoses WHERE name=ar.author) AUTHOR,
921 substr(ctime, 0, 11) DATE,
922 substr(content, 0, 78) TEXT
923 FROM ar JOIN bl
924 ON ar.blogid=bl.id
925 WHERE $kc AND bl.id IN (SELECT id FROM blog_s $cond) $blogcond
926 ORDER by DATE DESC, TITLE, ctime;"
927 sedopt="s,<TR><TD>\([^<]*\)</TD>,<TR><TD><a\
928 href=\"?replyblog+\1\">VIEW</a></TD>,"
929 # echo "$sql2" > tmp/sql.out
930 result=$tmpd/result.$$
931 cat<<EOF
932 <table class="b searchart">
933 `sq -header -html $db "$sql2"|sed "$sedopt"|tee $result`
934 </table>
935 EOF
936 if [ -s "$result" ]; then
937 found=$((`grep "^<TR><TD>" $result | wc -l` + 0)) # Cast to INT
938 one=${found%1}
939 echo "$found match${one:+es} found"
940 # <a href="?replyblog+39#12345">VIEW</a>
941 # -> 39,49,55, -> 39,49,55
942 # -> <input type="hidden" name="bloglist" value="39,49,55">
943 sed -n "/.*href=.*replyblog\+\([0-9][0-9]*\).*/s//\1/p" "$result" \
944 | sort | uniq | tr '\n' ',' \
945 | sed -e 's/,$//' \
946 -e 's/^/<input type="hidden" name="bloglist" value="/' \
947 -e 's/$/">/'
948 else
949 echo orz...
950 fi
951 echo "$sf" | sed "1,/-- EOF/d" # Close <form>
952 }
953 listblog() (
954 # $1={user,group}
955 qow=`sqlquote $1`
956 cond="where a.id in (select id from blog_s where key='owner' and val=$qow) order by ctime desc"
957 DT_CHLD=article:blogid
958 cgi_form searchart<<EOF
959 <label>`cgi_text kwd`という語を含む記事をこの一覧から検索</label>
960 `cgi_hidden owner $user`
961 EOF
962 dumptable html blog 'ctime title heading' "$cond"
963 )
965 blog_addentry() {
966 # $1=GRPname(if it is a group)
967 grprowid=$1
968 rowid=`getpar rowid`
969 ## err blog_addentry0: rowid=$rowid
970 if [ -n "$grprowid" ]; then
971 owner=`getgroupbyid $grprowid`
972 else
973 owner=`getpar owner`
974 fi
975 err blog-add: \$1=$1 rowid=$rowid owner=$owner
976 if isgroup "$owner"; then
977 groupmode=1 listing=$owner guide="[${owner}]" GF_OWNER=$owner
978 else
979 usermode=1 listing=$user guide="[個人]"
980 fi
982 if [ -n "`getpar title`" ]; then
983 if [ "$usermode" ]; then
984 err usermode: user=$user owner=$owner
985 if [ x"$user" != x"$owner" ]; then
986 echo "他人の日記は書けません" | html p
987 return 2
988 fi
989 elif [ "$groupmode" ]; then # if write to group log
990 grp=$owner #\`getpar grp\`
991 err ismember: $user $grp
992 if ! ismember "$user" "$grp"; then
993 echo "(話題作成はこのグループに加入してから)" | html p
994 return 3
995 fi
996 fi
997 par2table $formdir/blog.def
998 serial=`getpar serial`
999 ## err SERIAL: $serial ROWID=$rowid listing=$listing
1000 id=""
1001 if [ -n "$rowid" ]; then
1002 # Here, id becomes NULL when removal of entries at par2table
1003 id=`query "select rowid from blog where rowid=$rowid;"`
1004 elif [ -n "$serial" ]; then
1005 # If new blog leader created, traverse to its head.
1006 id=`query "select rowid from blog where id='$serial';"`
1007 ## err new-Leader: "select rowid from blog where id='$serial';" id=$id
1008 fi
1009 if [ -n "$id" ]; then
1010 ## If new aritcle is entered, JUMP to blog_reply
1011 blog_reply $id
1012 return
1013 fi
1014 fi
1015 echo "${guide}新規話題作成" > $tmpd/title.$$
1016 listblog $listing > $tmpd/listblog.$$
1017 genform $formdir/blog.def \
1018 | _m4 -D_TITLE_="spaste(\`$tmpd/title.$$')" \
1019 -D_FORMHEAD_="序文は簡単に詳しくはコメントに" \
1020 -D_DUMPHEAD_="これまでの蓄積" \
1021 -D_FORM_="syscmd(\`cat')" \
1022 -D_DUMPTABLE_="spaste(\`$tmpd/listblog.$$')" \
1023 $layout/html.m4.html \
1024 $layout/form+dump-whead.m4.html
1027 blog_reply() { # Posting to blog article
1028 rowid=$1
1030 if [ -z "$rowid" ]; then
1031 echo "表示する日記番号が未指定です。" | html p
1032 return
1033 fi
1034 title=`getvalbyid blog title $rowid`
1035 owner=`getvalbyid blog owner $rowid`
1036 qowner=`sqlquotestr "$owner"`
1037 if [ -z "$title" ]; then
1038 echo "日記番号指定が無効です。" | html p
1039 return
1040 fi
1041 blog_writable $rowid $user; rc=$?
1042 if [ $rc = 0 ]; then
1043 iswritable=true
1044 else
1045 iswritable=false
1046 if [ $((rc & $BLOG_FROZEN)) -gt 0 ]; then
1047 isfrozen=true
1048 frozen_class='frozen"'
1049 frozen_flag=$FROZEN_TAG
1050 fi
1051 fi
1052 if isuser "$owner"; then
1053 subtitle="`gecos $owner` さんの話題"
1054 else
1055 grprowid=`query "select rowid from grp where gname=$qowner;"`
1056 subtitle="グループ
1057 <a href=\"?grp+$grprowid\" accesskey=\"h\" title=\"H\">$owner</a> での話題
1058 `query \"SELECT printf('(チーム:%s)', val)\
1059 FROM blog_s
1060 WHERE id=(SELECT id FROM blog WHERE rowid=$rowid)
1061 AND key='team';
1062 \"|htmlescape`"
1063 memclass=`grp_getbodyclass "$owner"`
1064 fi
1066 text=`getpar text`
1067 if [ -n "$text" ]; then
1068 if $iswritable; then
1069 par2table $formdir/article.def
1070 st=$?
1071 case $st in
1072 0|4)
1073 [ "$st" = "4" ] && act="書込削除"
1074 blog_notify_reply $rowid $user "$text" $act
1075 if [ -n "$grprowid" ]; then
1076 qgrp=$(sqlquote "$owner")
1077 dbsetbyid grp $owner wtime "`date '+%F %T'`"
1078 else
1079 dbsetbyid user "$user" wtime "`date '+%F %T'`"
1080 fi
1081 ;;
1082 esac
1083 else
1084 if $isfrozen; then
1085 title="$title(凍結板につき書き込み不可)"
1086 else
1087 title="$title(加入してないので書き込み不可)"
1088 fi
1089 fi
1090 fi
1091 def=$formdir/article.def
1092 echo "$title" > $tmpd/title.$$
1093 echo "$subtitle$frozen_flag" > $tmpd/subtitle.$$
1094 ${BLOG_SHOW:-blog_showentry} blog $rowid \
1095 | _m4 -D_TITLE_="spaste(\`$tmpd/title.$$')" \
1096 -D_BODYCLASS_=general"${memclass:+ $memclass}" \
1097 -D_FORMHEAD_="spaste(\`$tmpd/subtitle.$$')" \
1098 -D_FORM_='' \
1099 -D_DUMPTABLE_="syscmd(cat)" -D_DUMPHEAD_="" \
1100 $layout/html.m4.html $layout/form+dump-whead.m4.html
1103 blog_reply_article() { # Direct link to article in some blog
1104 arid=${1:-0} # Already sanitized to digits
1105 brid=`query "SELECT rowid FROM blog WHERE \
1106 id=(SELECT blogid FROM article WHERE rowid=$arid);"`
1107 if [ -n "$brid" ]; then
1108 newurl="?replyblog+$brid#$arid"
1109 echo "Refresh: 0; $newurl"; echo
1110 exit 0
1111 else
1112 contenttype; echo
1113 echo "無効な記事番号です." | html p
1114 fi