s4

view s4-blog.sh @ 588:33fab353a39e

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