s4

view s4-blog.sh @ 557:591838015ac3

Put inaccessible mark on such attached file icon.
author HIROSE Yuuji <yuuji@gentei.org>
date Sat, 13 Apr 2019 19:00:56 +0900
parents 3fcaea2892a8
children 2f580c147434
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 # Compute file accessibility of attached file
307 err "----r=$aid fa=[$fa]----"
310 # First, check the availability of user-icon.
311 # If not existent, clear and reset row cache by rm $stampfile
312 if [ ! -s "$icon" ]; then
313 rm -f "$stampfile"; unset stampfile
314 fi
315 if test -s "$stampfile" &&
316 test -s "$cachefile" &&
317 { ts=`cat "$stampfile"`; test -n "$ts"; } &&
318 test "$ts" '>' "$tm" && # Cache timestamp is newer
319 test "$stampfile" -nt "$icon"; then # UserIcon is older
320 : Nothing to do
321 else
322 { ######## New ROW creation begins here ######## >$cachefile
323 tdcls="__NEWCLS__repatt"
324 if [ -s "$icon" ]; then
325 icfn=`echo "$icon"|htmlescape`
326 picon="<p class=\"proficon\"><a href=\"$hlink+$uid\"><img src=\"$icfn\"></a></p>"
327 else
328 echo "DELETE FROM user_s WHERE key='$iconcachekey' AND
329 val=`sqlquotestr \"$icon\"`;" >> $iconcleaner
330 picon=""
331 fi
333 cat<<EOF
334 <tr id="$id">
335 <td class="$tdcls">${picon}__EDIT__<a href="#$aid">#$aid</a>
336 <a href="$hlink+$uid">$uname</a>
337 $tm
338 <__NOTIFY__></td>
339 EOF
340 echo -n "<td id=\"$aid\" class=\"repl\">"
341 echo "$hte"|unhexize|htmlescape|hreflink|minitbl
342 usecache='' tsfile=$td/$id.stamp
343 for i in $imgids; do
344 mrid=${i%%:*}; i=${i#*:}; sz=`size_h ${i%%:*}`
345 fn=`echo "${i#*:}"|unhexize`
346 fnb=$fn"(${sz})"
347 case "$fn" in
348 *.[Pp][Nn][Gg]|*.[Jj][Pp][Gg]|*.[Jj][Pp][Ee][Gg]|*.[GgTt][Ii][Ff])
349 # fmt=${fn##*.} # convert - jpg:- is slow...why
350 case "$fn" in
351 *.[Pp][Nn][Gg]) fmt=png ;;
352 *.[Gg][Ii][Ff]) fmt=gif ;;
353 *) fmt=jpeg ;;
354 esac
355 outfile=$td/$mrid-${fn%.*}.$fmt
356 #err fn=$fn outfile=$outfile
357 #err "usecache=$usecache `ls -l $outfile`"
358 #err tm=$tm
359 #err tsfile=$tsfile=`cat $tsfile`
360 if [ -s "$outfile" ] && # $outfile should be > 0
361 { [ "$usecache" ] || # And usecache flag is true, or...
362 { [ -s "$tsfile" ] && [ x"`cat $tsfile`" = x"$tm" ]
363 };}; then
364 usecache=1 # Set usecache flag on
365 cat<<-EOF
366 <a href="$catlink+$mrid"><img src="$outfile">
367 $fnb</a>
368 EOF
369 # !!NOTE!! Create row stamp ONLY WHEN imgcache is active
370 else
371 query "SELECT hex(bin) FROM article_m WHERE rowid=$mrid;" \
372 | unhexize \
373 | convert -define ${fmt}:size=100x100 -resize 100x100'>' \
374 - ${fmt}:- \
375 | tee "$outfile" \
376 | hexize \
377 | sed -e 's/\(..\)/%\1/g' \
378 -e "s|^|<a href=\"$catlink+$mrid\"><img src=\"data:image/$fmt,|" \
379 -e "s|\$|\">$fnb</a>|"
380 unset stampfile # img data stream is not suitable to cache
381 echo $tm > $tsfile
382 fi
383 ;;
384 *)
385 echo "<__UNREADABLE__><a href=\"$catlink+$mrid\"><img src=\"$deficon\">$fnb</a>"
386 ;;
387 esac
388 done
389 echo "</td></tr>"
390 } > "$cachefile" ######## New ROW Creation Ends here ########
391 test -n "$stampfile" && date "+%F %T" > $stampfile
392 fi
393 # Printing a cached row
394 sed -e "/^<td class=/s/__NEWCLS__/$new${new:+ }/" \
395 -e "/^<td class=/s,__EDIT__,$editlink," \
396 -e "/^<__NOTIFY__>/s,,${notify:+$nt}," \
397 -e "/^<__UNREADABLE__>/s,,${fa:+$cannotread}," \
398 $cachefile
399 done
401 help="=== コメントに使用できる特殊記法 ===
402 行頭に href=URL でURLへのリンク
403 行頭に iframe=URL でURL先を開く iframe
404 [[#記事番号]] でs4内の記事番号に飛ぶリンク
405 [[#検索キーワード]] でs4内の記事検索(記号はいくつか使えない)
406 [[URL]] でURLへのリンク、 [[URL|文字列]]でアンカー文字列指定
407 {{画像URL}} でインライン画像、 {{画像URL|幅}} でピクセル幅指定
408 {{{URL}}} でURL先を開く iframe、 {{{URL|高さ}}} ピクセル高さ指定
409 行頭: ## 大見出し, ### 中見出し, #### 小見出し
410 行末の2連続スペースで強制改行(<br>)
411 |*見出し列|列2|列3… と行頭から始まる縦棒区切り行を続けて表
412 ' *語群* ' で強調(両側の空白必要、** でもっと強調。*の代わりに _ でも可)
413 - [ ] と - [x] でチェックボックス"
414 touchhelp="${touchpanel:+<p class=\"help\">$help</p>}"
415 filehelp="《添付の注意》
416 $file_accept_help"
417 textform='<div class="fold">
418 <input type="checkbox" id="cmt" checked><label
419 accesskey="c" title="C" for="cmt">コメントする</label><div>
420 <table class="b">
421 <tr><td><textarea name="text" cols="72" rows="4" title="'"$help"'">
422 </textarea>'"$touchhelp</td></tr>
423 <tr><td>添付ファイル(${filesize_max_MB}以下):"'
424 <input type="file" name="image"'" $file_accept title=\"$filehelp\" multiple></td></tr>"'
425 </table>
426 <input type="submit" value="送信">
427 <input type="reset" value="リセット"></div></div>
428 '
429 cat<<-EOF
430 </table> <!-- end of s4-blog:blog_showentry() main table -->
431 <p class="update_link"><a
432 href="?reload/$rowid" accesskey="r" title="R">再読込</a> / <a
433 href="#title" id="bottom" accesskey="t" title="T">先頭へ</a></p>
434 EOF
435 $iswritable && cat<<-EOF
436 <div class="blogcomment">
437 <input type="hidden" name="blogid" value="$id">
438 <input type="hidden" name="id" value="`genserial`">
439 <input type="hidden" name="stage" value="replyblog">
440 $textform
441 </div>
442 </form> <!-- End of s4-blog:blog_showentry() main form -->
443 EOF
444 # Clean up orphaned icon cache
445 [ -s $iconcleaner ] && query ".read '$iconcleaner'"
446 # Record access log
447 acclog blog $rowid
448 }
450 lshandout() {
451 # $1=rowid of blog
452 blog_writable $1 $user
453 rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member
454 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then
455 echo "メンバー以外は利用できません。" | html p; return
456 fi
457 time=`getvalbyid blog ctime $1|colrm 11`
458 owner=`getvalbyid blog owner $1`
459 title=`getvalbyid blog title $1`
460 ge=`gecos $owner`
461 fh=$tmpd/formhead
462 echo "$time [$title]@${ge:-$owner}" > $fh
463 lshandoutsub $owner "$@" \
464 |_m4 -D_TITLE_="提出状況" \
465 -D_FORMHEAD_="syscmd(cat $fh)" \
466 -D_FORM_="syscmd(cat)" -D_DUMPHEAD_= -D_DUMPTABLE_= \
467 $layout/html.m4.html $layout/form+dump-whead.m4.html
468 gn=`echo $owner|htmlescape`
469 echo "<p><a href=\"?lshandoutall+$1\">グループ $gn すべてのレポート板集計</a></p>"
470 }
471 gethandoutcsv() {
472 # contenttype; echo
473 CATCSV=1 lshandoutall "$1"
474 }
475 gethandoutcsv2() {
476 # contenttype; echo
477 SQL=$(cat<<-EOF
478 WITH this_blog_articles AS (
479 SELECT rtb.id bid, rtb.brid, a.id aid, author, title, ctime
480 FROM report_type_blogs rtb JOIN article a ON rtb.id=a.blogid
481 ), text_or_file AS (
482 SELECT bid, author, title, ctime, 'text' shu, count(val) cnt
483 FROM this_blog_articles tba, article_s s
484 ON tba.aid=s.id
485 WHERE key='text'
486 GROUP by bid, author
487 UNION
488 SELECT bid, author, title, ctime, 'file' shu, count(val) cnt
489 FROM this_blog_articles tba, article_m m
490 ON tba.aid=m.id
491 WHERE key='image'
492 GROUP by bid, author
493 ), count_list AS (
494 SELECT author,
495 substr(ctime, 1, 10)||upper(substr(shu, 1, 1)) unit,
496 cnt
497 FROM text_or_file
498 )
499 SELECT gecos "名前",
500 substr(author, 1, instr(author, '@')-1) "uname",
501 unit,
502 cnt "post"
503 FROM count_list cl JOIN gecoses g ON cl.author=g.name;
504 EOF
505 ) gethandoutcsv "$1"
506 }
507 lshandout_ulink_table() {
508 # NO Args. Read stdin as SQL
509 echo '<table class="b td3rr td3evw">'
510 hrb="<a href=\"?home+"
511 # echo "$sql" | sq -header -html $db \ # Formerly, this is called via sq()
513 printf ".mode html\n.header ON\n" | query
514 cat | query \
515 | sed -e "s,\(<TR><TD>\)\([^ ]*\) \(.*\)</TD>,\1$hrb\2\">\3</TD>," -e 's,<TD>0</TD>,<TD class="warn">0</TD>,'
516 echo '</table>'
517 printf ".mode list\n.header OFF\n" | query
518 }
519 lshandoutall() {
520 # $1=rowid of blog
521 blog_writable $1 $user
522 rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member
523 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then
524 echo "メンバー以外は利用できません。" | html p; return
525 fi
526 rowid=$(($1 + 0))
527 owner=`getvalbyid blog owner $1`
528 qowner=`sqlquotestr "$owner"`
530 query<<-EOF
531 CREATE TEMPORARY TABLE IF NOT EXISTS report_type_blogs AS
532 WITH blog_owner_mode AS (
533 SELECT id,
534 blog.rowid brid,
535 max(CASE key WHEN 'owner' THEN val END) owner,
536 max(CASE key WHEN 'mode' THEN val END) mode,
537 max(CASE key WHEN 'title' THEN val END) title,
538 max(CASE key WHEN 'ctime' THEN val END) ctime
539 FROM blog NATURAL JOIN blog_s
540 GROUP BY id
541 )
542 SELECT id, brid, title, ctime FROM blog_owner_mode
543 /* WHERE owner=$qowner AND mode LIKE '%report%'; */
544 WHERE owner=$qowner
545 AND
546 (mode LIKE '%report%' OR mode LIKE '%quiz%');
547 /* ↑これでレポート形式の blogid 一覧を得る */
548 EOF
549 if [ -z "$CATCSV" ]; then
550 _m4 -D_TITLE_="提出状況" $layout/html.m4.html
551 ge=`gecos "$owner"`
552 tbls=""
553 grptxt=`echo "${ge:-$owner}"|htmlescape`
554 echo "<h1>$grptxt 書き込み状況一覧</h1>"
555 fi
556 if [ -z "$SQL" ]; then
557 bridlist=`query "SELECT brid FROM report_type_blogs;"`
558 for brid in $bridlist; do # Skip this loop if $SQL set
559 brid=$(($brid + 0)) # Ensure to be a number
560 [ $brid = 0 ] && continue
561 time=`getvalbyid blog ctime $brid|colrm 11`
562 title=`getvalbyid blog title $brid|htmlescape`
563 state=`getvalbyid blog state $brid|htmlescape`
564 tt="handout_$brid"
565 [ "$state" = "frozen" ] && frozen=" $FROZEN_TAG" || frozen=""
566 if [ -z "$CATCSV" ]; then
567 echo "<h2>$time - <a href=\"?replyblog+$brid\">$title</a>$frozen</h2>"
568 lshandoutsub "$owner" $brid "$tt"
569 else
570 lshandoutsub "$owner" $brid "$tt" >/dev/null # Only create temp.table
571 fi
572 tbls="$tbls${tbls:+ NATURAL JOIN }$tt"
573 done
574 fi
575 sql=${SQL:-"SELECT * FROM $tbls;"}
576 if [ -z "$CATCSV" ]; then
577 echo "<hr><h2>総合</h2>"
578 echo "$sql" | lshandout_ulink_table
579 echo "<h2>総合(<a href=\"?gethandoutcsv+$rowid\">CSV</a>)</h2>"
580 printf ".mode csv\n.header ON\n" | query
581 echo '<pre class="list">'
582 echo "$sql" | query | sed 's/^"[0-9]* /"/'
583 echo "</pre>"
584 echo "<pre><a href=\"?gethandoutcsv2+$rowid\">縦持ちCSV</a></pre>"
585 else
586 contenttype "Application/CSV"
587 printf ".mode csv\n.header ON\n" | query >/dev/null
588 fn=report-count.csv
589 printf 'Content-Disposition: filename="%s"\n' "$fn"
590 outfile=$tmpd/out-$$.csv
591 echo "$sql" | query | sed 's/^"[0-9]* /"/' > $outfile
592 echo "Content-Length: " `cat $outfile | wc -c`; echo
594 cat $outfile
595 exit 0
596 fi
597 printf ".mode list\n.header OFF\n.separator |\n" | query
598 }
599 lshandoutsub() {
600 # $1=owner $2=rowid of blog &optional $3=temp_table name
601 qgname=`sqlquote "$1"`
602 if isgroup "$1"; then
603 sample="(select user from grp_mem where gname=$qgname)"
604 else
605 sample="(select distinct author as user from arts)"
606 echo "(集計は板への投稿者のみ)" | html p
607 fi
608 tmpname="${3:-handout_$2}"
609 sql="CREATE TEMPORARY TABLE IF NOT EXISTS $tmpname AS
610 with arts as (select id,author from article \
611 where blogid=(select id from blog where rowid=$2))\
612 select (select rowid from user where name=c0.user)||' '|| \
613 (select gecos from gecoses where name=c0.user) as 'メンバー',\
614 substr(c0.user, 1, instr(c0.user, '@')-1) 'uname',\
615 sum(case when c1.key is not null then 1 else 0 end)\
616 as '[$title] コメント記入',\
617 sum(case when c2.key is not null then 1 else 0 end)\
618 as '[$title] ファイルの提出'\
619 from $sample c0 \
620 left join (select id,author from arts) a\
621 on c0.user=a.author\
622 left join (select id,key from article_s where key='text') c1\
623 on a.id=c1.id left join (select id,key from article_m ) c2\
624 on c1.id=c2.id group by c0.user order by c0.user;\
625 \
626 SELECT * FROM $tmpname;"
627 err ishandoutsub: sql="$sql"
628 echo "$sql" | lshandout_ulink_table
629 }
630 gethandout() {
631 # $1=rowid of blog
632 blog_writable $1 $user
633 rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member
634 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then
635 echo "メンバー以外は利用できません。" | html p; return
636 fi
637 i=0
638 bd=$tmpd/archive.$$
639 mkdir $bd
640 query "select m.rowid,author,m.val from article a join article_m m\
641 on a.id=m.id where blogid=(select id from blog where rowid=$1)\
642 and m.key in ('image', 'document', 'binary');" \
643 | while IFS='|' read rowid author filename; do
644 err isfilereadable $user article_m $rowid
645 isfilereadable $user article_m $rowid || continue
646 err ok
647 i=$((i+1))
648 dir=`printf $bd/%03d $i`
649 mkdir $dir
650 query "select quote(bin) from article_m where rowid=$rowid;" \
651 | unhexize > $dir/$filename
652 done
653 if [ ! -d $bd/001 ]; then
654 contenttype; echo
655 echo "取得できるファイルがありませんでした。" | html p
656 return
657 fi
658 (cd $bd
659 ## err cdto$bd; (pwd; ls -lFa) 1>&3
660 tar zcf .archive.tar.gz * && mv .archive.tar.gz archive.tar.gz
661 err Creating tar archive "`ls -l archive.tar.gz`"
662 )
663 arc=$bd/archive.tar.gz
664 echo "Content-type: application/x-gzip"
665 echo "Content-Length: `cat $arc|wc -c`"
666 echo "Content-Disposition: filename=\"archive.tar.gz\""
667 echo
668 cat $arc
669 }
670 blogseen() { # $1 = blogid
671 blogid=${1%%[!0-9]*}
672 if [ -z "$blogid" ]; then
673 echo "Invalid blog id" | html p; exit
674 fi
675 blog_writable "$blogid" "$user"
676 rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member
677 if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then
678 echo "メンバー以外は利用できません。" | html p; return
679 fi
680 owner=`getvalbyid blog owner $rowid`
681 qowner=`sqlquotestr "$owner"`
682 grprowid=`query "SELECT rowid FROM grp WHERE gname=$qowner;"`
683 ge=`gecos "$owner" | htmlescape`
684 title=`getvalbyid blog title $rowid | htmlescape`
685 h1="アクセス時刻"
686 link2board="<a href=\"?replyblog+$rowid\">$title</a>"
687 link2group="<a href=\"?grp+$grprowid\">$ge</a>"
688 _m4 -D_TITLE_="$h1" $layout/html.m4.html
689 echo "$h1" | html h1
690 echo "[$link2board]@$link2group" | html h2
691 warn=' class="warn"'
692 cat <<-EOF
693 <table class="b">
694 <tr><th>メンバー</th><th>uname</th><th>最終閲覧時刻</th></tr>
695 EOF
696 query <<-EOF |
697 WITH grpmem as (
698 SELECT user, (SELECT gecos FROM gecoses WHERE name=user) gecos
699 FROM grp_mem
700 WHERE gname=(SELECT val FROM blog_s
701 WHERE id=(select id from blog where rowid=$blogid)
702 AND key='owner')
703 ), acctime AS (
704 SELECT user, max(time) atime
705 FROM tblaccesses
706 WHERE tbl='blog' AND tblrowid=$blogid
707 GROUP BY user
708 )
709 SELECT g.user,
710 (SELECT rowid FROM user u WHERE u.name=g.user),
711 hex(gecos),
712 atime
713 FROM grpmem g LEFT JOIN acctime t
714 ON g.user = t.user
715 GROUP BY g.user
716 ORDER BY atime DESC;
717 EOF
718 while IFS='|' read u uid hexge time; do
719 td=${time:+"<td>"} # If the variable time is set, td=<td>
720 td=${td:-"<td$warn>"} # else td=<td class="warn">
721 cat <<-EOF
722 <tr>
723 <td><a href="?home+$uid">`echo "$hexge"|unhexize|htmlescape`</a></td>
724 <td>`echo ${u%%@*}|htmlescape`</td>
725 $td${time:----}</td></tr>
726 EOF
727 done
728 cat <<-EOF
729 </table>
730 <p><a href="?replyblog+$rowid">[$title]に戻る</a></p>
731 </html>
732 EOF
733 }
734 lsmyfile() { # $1(optional)=SortBy
735 case "$1" in
736 ""|CTIME-DESC)
737 by="CTIME" ord="DESC" ;;
738 CTIME*) by="CTIME" ;;
739 FILE*) by="FILE" ;;
740 OWNER*) by="OWNER" ;;
741 TITLE*) by="TITLE" ;;
742 esac
743 case "$1" in
744 *DESC) ord="DESC" ;;
745 esac
746 case "$ord" in
747 DESC) lkod="" jord="降順" ;;
748 *) lkod="-DESC" jord="昇順" ;;
749 esac
750 sql="select m.val||'/'||m.rowid FILE,
751 coalesce(
752 case when (select name from user where name=bs.owner)
753 is not null
754 then (select val from user_s where name=bs.owner
755 and key='gecos')
756 when (select gname from grp where gname=bs.owner)
757 is not null
758 then (select val from grp_s where gname=bs.owner
759 and key='gecos')
760 else
761 null
762 end,
763 bs.owner
764 ) OWNER,
765 a_s.val CTIME,
766 ',t,'||bs.title||':'||b.rowid||'#'||a.id TITLE
767 from (select rowid,id,val from article_m where id
768 in (select id from article where author='$user')
769 and type like 'file:%')
770 m left join article a on m.id=a.id
771 left join article_s a_s on a.id=a_s.id and a_s.key='ctime'
772 left join (select id,
773 max(case key when 'owner' then val end) as owner,
774 max(case key when 'title' then val end) as title
775 from blog_s group by id)
776 bs on a.blogid=bs.id
777 left join blog b on bs.id=b.id
778 where m.val is not null order by $by $ord;"
779 err lshandoutbyauthor: sql=`echo "$sql"`
780 title="個人提出ファイル"
781 _m4 -D_TITLE_=$title $layout/html.m4.html
782 hra="<a href=\"?lsmyfile+"
783 hrb="<a href=\"?showattc+article_m+"
784 hrc="<a href=\"?replyblog+"
785 (echo '<table class="b">'
786 echo "$sql"|sq -html -header $db ) \
787 | sed -e "s|\(<TR><TD>\)\([^/]*\)/\([0-9]*\)|\1$hrb\3\">\2</a>|" \
788 -e "s|,t,\(.*\):\([^<]*\)\(</TD>\)|$hrc\2\">\1</a>\3|" \
789 -e "s|\(<TH>\)\([A-Z]*\)\(</TH>\)|\1$hra\2$lkod\">\2</a>|" \
790 | _m4 -D_TITLE_=$title -D_FORM_="<p>($by$jord)</p>" \
791 -D_DUMPTABLE_="syscmd(cat)" $layout/form+dump.m4.html
792 echo '</table>'
793 }
794 searchart() {
795 kwd=`getpar kwd|nkf -wZ1` # Convert Zenkaku-SPC to ASCII-SPC
796 bloglist=`getpar bloglist|sed 's/[^0-9,]//g'`
797 kwdgrp=""
798 authcond=""
799 if [ -z "$kwd" ]; then
800 echo "検索語を指定してください" | html p; return
801 fi
802 if logstart "$searchlog"; then
803 { echo "kwd=$kwd"
804 test -n "$bloglist" && echo "bloglist=$bloglist"
805 } >> $searchlog
806 logend "$searchlog"
807 fi
808 if expr x"$kwd" : 'x#[1-9][0-9]*$' >/dev/null 1>&2; then
809 # Like '#1234', assume as artID
810 rowid=$((${kwd#\#} + 0)) # Force to be a number
811 kc="ar.rowid = $rowid"
812 else
813 for k in `echo "$kwd" | sed "s/'/''/g"`; do # With wrap quotes
814 ctime=""
815 if expr x"$k" : 'x@[><= ]*[1-9][][0-9]*-[][0-9:-]*$' >/dev/null >&2; then
816 # '@<2016-10-10' -> ctime < '2016-10-10'
817 # '@>=2016-10-10' -> ctime >= '2016-10-10'
818 # '@2016-10-10' -> ctime GLOB '@2016-10-10'
819 k=${k#@}
820 case "$k" in
821 [\<\>]*) op=${k%%[!<>=]*}; ctime=${k##*[><= ]} ;;
822 *) op='GLOB'; ctime="${k##*[><= ]}*" ;;
823 esac
824 kc=$kc${kc:+" AND "}"ctime $op '${ctime}'"
825 # Not sure GROUP BY a.blogid is comfortable for searchers...?
826 ##### kwdgrp=" GROUP BY a.blogid" ## Add this to lessen results
827 elif [ x"$k" = x"@today" -o x"$k" = x"@今日" ]; then
828 ctime=`date +%F`
829 elif n=`expr x"$k" : 'x@\([0-9]*\)days*'` >/dev/null >&2; then
830 ctime=`query "SELECT datetime('now', 'localtime', '-$n days');"`
831 elif [ x"$k" = x"@week" ]; then
832 ctime=`query "SELECT datetime('now', 'localtime', '-7 days');"`
833 elif n=`expr x"$k" : 'x@\([0-9]*\)weeks*'` >/dev/null >&2; then
834 n=$((n * 7))
835 ctime=`query "SELECT datetime('now', 'localtime', '-$n days');"`
836 elif [ x"$k" = x"@month" ]; then
837 ctime=`query "SELECT datetime('now', 'localtime', '-1 month');"`
838 elif n=`expr x"$k" : 'x@\([0-9]*\)months*'` >/dev/null >&2; then
839 ctime=`query "SELECT datetime('now', 'localtime', '-$n month');"`
840 elif [ x"$k" = x"@year" ]; then
841 ctime=`query "SELECT datetime('now', 'localtime', '-1 year');"`
842 elif n=`expr x"$k" : 'x@\([0-9]*\)years*'` >/dev/null >&2; then
843 ctime=`query "SELECT datetime('now', 'localtime', '-$n year');"`
844 fi
845 if [ -n "$ctime" ]; then
846 kc=$kc${kc:+" AND "}"ctime > '${ctime}'"
847 else
848 e=""
849 case "$k" in
850 *${likeesc}*) e="" ;; # Giving up char-escaping
851 *%*|*_*) k=`echo "$k"|sed "s/\([%_]\)/${likeesc}\1/g"`
852 e=" ESCAPE '$likeesc'" ;;
853 esac
854 kc=$kc${kc:+" AND "}"content LIKE '%$k%'$e"
855 fi
856 done
857 fi
858 kwd=`echo "$kwd"|htmlescape`
859 owner=`getpar owner`
860 owner=${owner:-$1}
861 msg=""
862 if [ -n "$owner" ]; then
863 cond="where key='owner' and val='$owner'"
864 if isuser $owner; then
865 msg="(`linkhome $owner` さんの記録から)"
866 else
867 linkhome $owner 1>&3
868 msg="(`linkhome $owner` グループから)"
869 fi
870 elif { author=`getpar author`; test -n "$author"; }; then
871 atptn=`sqlquotestr $author`
872 #kc="$kc${kc:+ AND }author=$atptn"
873 authcond="WHERE author=$atptn"
874 if isuser $author; then
875 msg="(`linkhome $author` さんの書き込みから)"
876 fi
877 fi
878 if [ -n "$bloglist" ]; then
879 blogcond="AND bl.rid IN ($bloglist)"
880 fi
882 sf=`search_form "$search_form_args" "$kwd" | sed '1d;$d'` # rm <div></div>
883 echo "$sf" | sed -e "/POST SENTENCE/s/.*/__PS__/" -e "/EOF/q" \
884 | _m4 -D__PS__="による検索結果$msg"
885 echo "(上記入力窓で再検索すると下記の掲示板のみに絞って再検索します)" \
886 | html p 'class="small"'
887 # article_s: id=article-id, key='text', val='TEXT'
888 # article: id=article-id, blogid=blogkd
889 # blog: id=blog-id, author=LeaderAuthor
890 # blog_s: id=blog-id, key='title', val='BLOG-TITLE'
891 # WANT: blog-ROWid,article-id,val(TEXT)
892 sql2="`sql4readableblogs` -- Extract user-readable blogs
893 -- 0.3sec
894 WITH artsm AS (
895 SELECT a.id,ctime, text || ' ' || coalesce(files, '') content
896 FROM article a
897 LEFT JOIN
898 (SELECT ars.id, ctime, text, coalesce(files, '') files
899 FROM (SELECT id,
900 max(CASE key WHEN 'ctime' THEN val END) ctime,
901 max(CASE key WHEN 'text' THEN val END) text
902 FROM article_s
903 GROUP BY id) ars
904 LEFT JOIN
905 (SELECT id, group_concat(val) files
906 FROM article_m
907 WHERE type LIKE 'file:%'
908 GROUP BY id) arm
909 ON ars.id=arm.id
910 ) ar
911 ON a.id=ar.id
912 ), ar AS (
913 SELECT a.rowid, a.blogid, a.id, a.author, ctime, content
914 FROM article a JOIN artsm ON a.id=artsm.id
915 $authcond
916 ), bl AS (
917 SELECT blg.rid, blg.*, blog_s.val TITLE
918 FROM readableblogs blg JOIN blog_s ON blg.id=blog_s.id AND blog_s.key='title'
919 )
920 SELECT bl.rid||'#'||ar.id '',
921 bl.title TITLE,
922 (SELECT gecos FROM gecoses WHERE name=ar.author) AUTHOR,
923 substr(ctime, 0, 11) DATE,
924 substr(content, 0, 78) TEXT
925 FROM ar JOIN bl
926 ON ar.blogid=bl.id
927 WHERE $kc AND bl.id IN (SELECT id FROM blog_s $cond) $blogcond
928 ORDER by DATE DESC, TITLE, ctime;"
929 sedopt="s,<TR><TD>\([^<]*\)</TD>,<TR><TD><a\
930 href=\"?replyblog+\1\">VIEW</a></TD>,"
931 # echo "$sql2" > tmp/sql.out
932 result=$tmpd/result.$$
933 cat<<EOF
934 <table class="b searchart">
935 `sq -header -html $db "$sql2"|sed "$sedopt"|tee $result`
936 </table>
937 EOF
938 if [ -s "$result" ]; then
939 found=$((`grep "^<TR><TD>" $result | wc -l` + 0)) # Cast to INT
940 one=${found%1}
941 echo "$found match${one:+es} found"
942 # <a href="?replyblog+39#12345">VIEW</a>
943 # -> 39,49,55, -> 39,49,55
944 # -> <input type="hidden" name="bloglist" value="39,49,55">
945 sed -n "/.*href=.*replyblog\+\([0-9][0-9]*\).*/s//\1/p" "$result" \
946 | sort | uniq | tr '\n' ',' \
947 | sed -e 's/,$//' \
948 -e 's/^/<input type="hidden" name="bloglist" value="/' \
949 -e 's/$/">/'
950 else
951 echo orz...
952 fi
953 echo "$sf" | sed "1,/-- EOF/d" # Close <form>
954 }
955 listblog() (
956 # $1={user,group}
957 qow=`sqlquote $1`
958 cond="where a.id in (select id from blog_s where key='owner' and val=$qow) order by ctime desc"
959 DT_CHLD=article:blogid
960 cgi_form searchart<<EOF
961 <label>`cgi_text kwd`という語を含む記事をこの一覧から検索</label>
962 `cgi_hidden owner $user`
963 EOF
964 dumptable html blog 'ctime title heading' "$cond"
965 )
967 blog_addentry() {
968 # $1=GRPname(if it is a group)
969 grprowid=$1
970 rowid=`getpar rowid`
971 ## err blog_addentry0: rowid=$rowid
972 if [ -n "$grprowid" ]; then
973 owner=`getgroupbyid $grprowid`
974 else
975 owner=`getpar owner`
976 fi
977 err blog-add: \$1=$1 rowid=$rowid owner=$owner
978 if isgroup "$owner"; then
979 groupmode=1 listing=$owner guide="[${owner}]" GF_OWNER=$owner
980 else
981 usermode=1 listing=$user guide="[個人]"
982 fi
984 if [ -n "`getpar title`" ]; then
985 if [ "$usermode" ]; then
986 err usermode: user=$user owner=$owner
987 if [ x"$user" != x"$owner" ]; then
988 echo "他人の日記は書けません" | html p
989 return 2
990 fi
991 elif [ "$groupmode" ]; then # if write to group log
992 grp=$owner #\`getpar grp\`
993 err ismember: $user $grp
994 if ! ismember "$user" "$grp"; then
995 echo "(話題作成はこのグループに加入してから)" | html p
996 return 3
997 fi
998 fi
999 par2table $formdir/blog.def
1000 serial=`getpar serial`
1001 ## err SERIAL: $serial ROWID=$rowid listing=$listing
1002 id=""
1003 if [ -n "$rowid" ]; then
1004 # Here, id becomes NULL when removal of entries at par2table
1005 id=`query "select rowid from blog where rowid=$rowid;"`
1006 elif [ -n "$serial" ]; then
1007 # If new blog leader created, traverse to its head.
1008 id=`query "select rowid from blog where id='$serial';"`
1009 ## err new-Leader: "select rowid from blog where id='$serial';" id=$id
1010 fi
1011 if [ -n "$id" ]; then
1012 ## If new aritcle is entered, JUMP to blog_reply
1013 blog_reply $id
1014 return
1015 fi
1016 fi
1017 echo "${guide}新規話題作成" > $tmpd/title.$$
1018 listblog $listing > $tmpd/listblog.$$
1019 genform $formdir/blog.def \
1020 | _m4 -D_TITLE_="spaste(\`$tmpd/title.$$')" \
1021 -D_FORMHEAD_="序文は簡単に詳しくはコメントに" \
1022 -D_DUMPHEAD_="これまでの蓄積" \
1023 -D_FORM_="syscmd(\`cat')" \
1024 -D_DUMPTABLE_="spaste(\`$tmpd/listblog.$$')" \
1025 $layout/html.m4.html \
1026 $layout/form+dump-whead.m4.html
1029 blog_reply() { # Posting to blog article
1030 rowid=$1
1032 if [ -z "$rowid" ]; then
1033 echo "表示する日記番号が未指定です。" | html p
1034 return
1035 fi
1036 title=`getvalbyid blog title $rowid`
1037 owner=`getvalbyid blog owner $rowid`
1038 qowner=`sqlquotestr "$owner"`
1039 if [ -z "$title" ]; then
1040 echo "日記番号指定が無効です。" | html p
1041 return
1042 fi
1043 blog_writable $rowid $user; rc=$?
1044 if [ $rc = 0 ]; then
1045 iswritable=true
1046 else
1047 iswritable=false
1048 if [ $((rc & $BLOG_FROZEN)) -gt 0 ]; then
1049 isfrozen=true
1050 frozen_class='frozen"'
1051 frozen_flag=$FROZEN_TAG
1052 fi
1053 fi
1054 if isuser "$owner"; then
1055 subtitle="`gecos $owner` さんの話題"
1056 else
1057 grprowid=`query "select rowid from grp where gname=$qowner;"`
1058 subtitle="グループ
1059 <a href=\"?grp+$grprowid\" accesskey=\"h\" title=\"H\">$owner</a> での話題
1060 `query \"SELECT printf('(チーム:%s)', val)\
1061 FROM blog_s
1062 WHERE id=(SELECT id FROM blog WHERE rowid=$rowid)
1063 AND key='team';
1064 \"|htmlescape`"
1065 memclass=`grp_getbodyclass "$owner"`
1066 fi
1068 text=`getpar text`
1069 if [ -n "$text" ]; then
1070 if $iswritable; then
1071 par2table $formdir/article.def
1072 st=$?
1073 case $st in
1074 0|4)
1075 [ "$st" = "4" ] && act="書込削除"
1076 blog_notify_reply $rowid $user "$text" $act
1077 if [ -n "$grprowid" ]; then
1078 qgrp=$(sqlquote "$owner")
1079 dbsetbyid grp $owner wtime "`date '+%F %T'`"
1080 else
1081 dbsetbyid user "$user" wtime "`date '+%F %T'`"
1082 fi
1083 ;;
1084 esac
1085 else
1086 if $isfrozen; then
1087 title="$title(凍結板につき書き込み不可)"
1088 else
1089 title="$title(加入してないので書き込み不可)"
1090 fi
1091 fi
1092 fi
1093 def=$formdir/article.def
1094 echo "$title" > $tmpd/title.$$
1095 echo "$subtitle$frozen_flag" > $tmpd/subtitle.$$
1096 ${BLOG_SHOW:-blog_showentry} blog $rowid \
1097 | _m4 -D_TITLE_="spaste(\`$tmpd/title.$$')" \
1098 -D_BODYCLASS_=general"${memclass:+ $memclass}" \
1099 -D_FORMHEAD_="spaste(\`$tmpd/subtitle.$$')" \
1100 -D_FORM_='' \
1101 -D_DUMPTABLE_="syscmd(cat)" -D_DUMPHEAD_="" \
1102 $layout/html.m4.html $layout/form+dump-whead.m4.html
1105 blog_reply_article() { # Direct link to article in some blog
1106 arid=${1:-0} # Already sanitized to digits
1107 brid=`query "SELECT rowid FROM blog WHERE \
1108 id=(SELECT blogid FROM article WHERE rowid=$arid);"`
1109 if [ -n "$brid" ]; then
1110 newurl="?replyblog+$brid#$arid"
1111 echo "Refresh: 0; $newurl"; echo
1112 exit 0
1113 else
1114 contenttype; echo
1115 echo "無効な記事番号です." | html p
1116 fi