yuuji@0: # yuuji@17: type cgiinit >/dev/null 2>&1 || . ./s4-funcs.sh yuuji@0: yuuji@397: # Global error flags yuuji@397: BLOG_NOTMEM=1 yuuji@397: BLOG_FROZEN=2 yuuji@399: FROZEN_TAG='[凍結]' yuuji@397: yuuji@0: blog_genform() { yuuji@0: # yuuji@0: t=$1 yuuji@0: } yuuji@0: yuuji@0: blog_writable() ( yuuji@0: # $1=articleid $2=user yuuji@397: # Return: $?=0 - Writable yuuji@397: # =1 - NOT Writable because user is not a member yuuji@397: # =2 - NOT Writable because blog is frozen yuuji@0: blogowner=`getvalbyid blog owner "$1"` yuuji@397: state=`getvalbyid blog state "$1"` yuuji@397: rc=0 yuuji@397: [ x"$blogowner" = x"$2" ] || isuser "$blogowner" || ismember "$2" "$blogowner" || rc=$((rc+$BLOG_NOTMEM)) yuuji@397: [ "$state" = "frozen" ] && rc=$((rc+$BLOG_FROZEN)) yuuji@397: return $rc yuuji@0: ) yuuji@138: blog_readable() { yuuji@138: # $1=articleid $2=user yuuji@138: mode=`getgroupattr $grp regmode` yuuji@138: } yuuji@50: blog_notify_reply() ( yuuji@222: # $1=blogid $2=ReplyingUser $3=WrittenText $4(optional)=Action yuuji@411: blogid="${1%%[!A-Z0-9a-z_]*}" yuuji@411: blogowner=`getvalbyid blog owner "$blogid"` yuuji@411: blogtitle=`getvalbyid blog title "$blogid"` yuuji@411: blogurl="$urlbase?replyblog+$blogid" yuuji@80: action=${4:-書き込み} yuuji@411: mode=`getvalbyid blog notify "$blogid"` yuuji@473: isgroup "$blogowner" && _isgroup=true || _isgroup=false yuuji@238: ### EXCEPT=`sqlquote "$user"` ## User should receive to feal some annoyance yuuji@50: case $mode in yuuji@48: admin) yuuji@473: if $_isgroup; then yuuji@117: emails=`getgroupadminmails $blogowner` yuuji@48: else yuuji@48: emails=`collectemail $blogowner` yuuji@48: fi yuuji@170: notifyto=`getpar notifyto` yuuji@191: if [ -n "$notifyto" ]; then yuuji@170: emails=$emails" `email4groupbyuid \"$blogowner\" $notifyto`" yuuji@170: fi yuuji@48: ;; yuuji@410: no) emails="" ;; yuuji@222: *) team=`query "SELECT val FROM blog_s yuuji@411: WHERE id=(SELECT id FROM blog WHERE rowid=$blogid) yuuji@222: AND key='team';"` yuuji@411: # team cannot get `getvalbyid blog team "$blogid"` because it's not yuuji@222: # defined in blog.def. Yes, it is Illegal USE!! yuuji@222: emails=`TEAM=$team collectemail $blogowner` ;; yuuji@48: esac yuuji@410: ## 2017-0210 Respond to the direct reply mark such as: >#1234 yuuji@413: replymark=`echo "$3"|nkf -w -Z0|grep '^ *>#'` yuuji@410: authgecos=`gecos $2` yuuji@410: if [ -z "$4" -a -n "$replymark" ]; then yuuji@410: # If the action is new subscription($4="") and has ">#123" marks... yuuji@411: ids=`echo "$replymark"|sed 's/[^#0-9]*#\([0-9]*\)[^#0-9]*/\1 /g'` yuuji@421: ids=`echo $ids|tr -dc '[0-9 ]'|tr ' ' ','` yuuji@411: # -> 123,345,347 yuuji@410: unames=`query "SELECT distinct author FROM article \ yuuji@410: WHERE rowid in ($ids)\ yuuji@411: AND blogid=(SELECT id FROM blog WHERE rowid=$blogid);"` yuuji@411: if [ -n "$unames" ]; then yuuji@473: e4g=$(if $_isgroup; then yuuji@473: email4group "$blogowner" $unames yuuji@473: else yuuji@473: for u in $unames; do yuuji@473: collectemail $u yuuji@473: done yuuji@473: fi) yuuji@473: emails=$emails" $e4g" yuuji@412: for e in $unames; do yuuji@412: g=`gecos $e` yuuji@415: whom=$whom"${whom:+,}${g:-$e}さん" yuuji@412: done yuuji@412: action="${whom}への返信" yuuji@411: fi yuuji@430: else yuuji@430: [ x"$2" = x"$blogowner" ] && return # If author=blogowner, unnecessary yuuji@410: fi yuuji@410: test -z "$emails" && return yuuji@165: err notify: user=$user Admins=`getgroupadmins $blogowner` Mode=$mode Emails="[$emails]" yuuji@168: SMAIL_TO="`echo "$blogowner" | nkf -jM | tr -d '\n'` readers <$admin>" \ yuuji@165: smail "$emails" "${action}通知 $urlbase"< /'` yuuji@0: EOF yuuji@50: ) yuuji@192: yuuji@0: blog_showentry() { yuuji@0: # $1=table $2=rowid yuuji@69: # if [ -n "$2" ]; then yuuji@69: # if [ -n "$imgcached" ]; then yuuji@69: # bstmpdir=$tmpdir/$imgcached/$thumbxy yuuji@69: # else yuuji@69: # bstmpdir=$tmpd yuuji@69: # # tmpd=`mktempd` yuuji@69: # # tmpfiles=$tmpfiles" $tmpd" yuuji@69: # fi yuuji@69: # fi yuuji@72: td=`getcachedir "article/$2"` yuuji@291: [ -d "$td" ] || mkdir -p $td yuuji@0: tbl=${1%%[!A-Z0-9a-z_]*} rowid=${2%%[!A-Z0-9a-z_]*} yuuji@356: err blow_showentry: rowid=$rowid, '$2'=$2 user=$user yuuji@0: ts=${tbl}_s tm=${tbl}_m yuuji@0: at=article as=article_s am=article_m yuuji@0: serial=$(($(date +%s)-1420038000))s$$ yuuji@397: blog_writable $rowid $user yuuji@397: rc=$? yuuji@397: if [ $rc = 0 ]; then yuuji@397: iswritable=true yuuji@397: ismem=true yuuji@397: else yuuji@397: iswritable=false yuuji@397: if [ $((rc & $BLOG_NOTMEM)) -gt 0 ]; then yuuji@397: ismem=false yuuji@397: else yuuji@397: ismem=true yuuji@397: fi yuuji@397: fi yuuji@0: # This function grasps blog entry definiton directly. yuuji@0: # blog: id yuuji@0: # blog_s: title,ctime,heading yuuji@0: # blog_m: *article yuuji@0: yuuji@443: blogowner=`getvalbyid blog owner "$2"` yuuji@443: isgroup "$blogowner" && isgroup=true || isgroup=false yuuji@465: isgrpadmin=false # Reversed later (*1) yuuji@443: yuuji@138: # 2015-10-05 check readable yuuji@138: if ! $iswritable; then yuuji@138: # err blogowner=$blogowner yuuji@443: if $isgroup; then yuuji@138: regmode=`getgroupattr $blogowner regmode` yuuji@138: # err regmode=$regmode yuuji@138: if [ x"$regmode" = x"moderated" ]; then yuuji@397: # if ! ismember $user $blogowner; then yuuji@397: if ! $ismem; then yuuji@138: echo "加入してからどうぞ" | html p yuuji@138: return yuuji@138: fi yuuji@138: fi yuuji@138: fi yuuji@465: else # if writable yuuji@465: isgrpowner "$user" "$blogowner" && isgrpadmin=true # (*1) yuuji@138: fi yuuji@170: case `getvalbyid blog notify "$2"` in # "all", "admin" or "no" (or NULL) yuuji@170: admin) notifyto=1 ;; yuuji@170: *) notifyto="" ;; yuuji@170: esac yuuji@154: yuuji@335: # err "SELECT id from $tbl where rowid=$rowid" yuuji@154: id=`query "select id from $tbl where rowid=$rowid;"` yuuji@335: #err id=$id yuuji@335: #err "select val from $ts where key='title' and id='$id';" yuuji@154: yuuji@154: yuuji@154: #(1)Display root article yuuji@154: cat< yuuji@154: yuuji@154: EOF yuuji@154: yuuji@341: href=" 編集 " yuuji@397: if $ismem; then yuuji@369: case `getvalbyid blog mode $rowid` in yuuji@369: *report*) yuuji@369: href2=" 提出状況 " yuuji@369: ;; yuuji@369: esac yuuji@341: href3="(ファイル取得)" yuuji@154: fi yuuji@341: href4=' 末尾へ' yuuji@465: $isgrpadmin && yuuji@465: href5=" 読刻" yuuji@443: quizmodefile=$td/quiz; rm -f "$quizmodefile" # XXX: Global state yuuji@154: yuuji@293: query<<-EOF | yuuji@293: SELECT coalesce((SELECT "yes" FROM blog yuuji@293: WHERE rowid=$rowid AND author='$user'), yuuji@293: ''), yuuji@293: max(CASE key WHEN 'ctime' THEN val END) ctime, yuuji@293: max(CASE key WHEN 'heading' THEN hex(val) END) heading, yuuji@293: CASE (SELECT val FROM $ts WHERE key="mode" AND id="$id") yuuji@293: WHEN 'report-closed' THEN 'レポート提出用(closed)' yuuji@293: WHEN 'report-open' THEN 'レポート提出用(open)' yuuji@442: WHEN 'quiz' THEN 'クイズ' yuuji@293: ELSE '' yuuji@293: END yuuji@293: FROM $ts WHERE id='$id' GROUP BY id; yuuji@293: EOF yuuji@293: { IFS='|' read edit ctime hexhead blogtype yuuji@293: cat<<-EOF yuuji@462: yuuji@397: yuuji@293: yuuji@293:
${edit:+$href }$ctime $blogtype $href2$href3 $href4 $href5
`echo "$hexhead"|unhexize|hreflink|minitbl`
yuuji@293: EOF yuuji@446: case "$blogtype" in yuuji@446: "クイズ") yuuji@446: echo "クイズモードは本人と管理者の書き込みのみが表示されます。" yuuji@446: ;; yuuji@446: esac | html p 'class="warn"' yuuji@446: echo '' yuuji@443: if [ x"$blogtype" = x"クイズ" ]; then yuuji@443: if $isgroup; then yuuji@443: if ! isgrpowner "$user" "$blogowner"; then yuuji@443: qgrp=`sqlquote "$blogowner"` yuuji@443: cat<<-EOF > $quizmodefile yuuji@443: AND (author IN (SELECT user FROM grp_adm WHERE gname=$qgrp) yuuji@443: OR yuuji@443: author='$user') yuuji@443: EOF yuuji@443: fi yuuji@446: else # if user's blog yuuji@446: if [ x"$user" != x"$blogowner" ]; then yuuji@446: cat<<-EOF > $quizmodefile yuuji@446: AND author IN ('$blogowner', '$user') yuuji@446: EOF yuuji@446: fi yuuji@443: fi yuuji@443: fi yuuji@293: } yuuji@154: lkhome=" '$atime' THEN 'new' ELSE '' END newer, yuuji@154: hex(s.TEXT), yuuji@154: (SELECT group_concat(rowid||':'||length(bin)||':'||hex(val), ' ') yuuji@154: FROM article_m yuuji@154: WHERE id=a.id AND key='image') imxgids yuuji@443: FROM (select rowid,id,author from article yuuji@443: where blogid in yuuji@443: (select id from blog where rowid=$rowid) yuuji@443: $cond_qz) a yuuji@154: LEFT JOIN yuuji@154: a_s s yuuji@154: ON a.id=s.id; yuuji@154: EOF yuuji@322: while IFS='|' read id edit notify uid uname icon aid tm new hte imgids; do yuuji@407: cachefile="$td/$id.row.html" yuuji@407: stampfile="$td/$id.row.stamp" yuuji@408: editlink="${edit:+編集 }" yuuji@409: nt="" yuuji@406: yuuji@406: # First, check the availability of user-icon. yuuji@406: # If not existent, clear and reset row cache by rm $stampfile yuuji@407: if [ ! -s "$icon" ]; then yuuji@407: rm -f "$stampfile"; unset stampfile yuuji@406: fi yuuji@403: if test -s "$stampfile" && yuuji@403: test -s "$cachefile" && yuuji@403: { ts=`cat "$stampfile"`; test -n "$ts"; } && yuuji@422: test "$ts" '>' "$tm" && # Cache timestamp is newer yuuji@422: test "$stampfile" -nt "$icon"; then # UserIcon is older yuuji@422: : Nothing to do yuuji@403: else yuuji@403: { ######## New ROW creation begins here ######## >$cachefile yuuji@403: tdcls="__NEWCLS__repatt" yuuji@407: if [ -s "$icon" ]; then yuuji@407: icfn=`echo "$icon"|htmlescape` yuuji@407: picon="

" yuuji@407: else yuuji@407: echo "DELETE FROM user_s WHERE key='$iconcachekey' AND yuuji@407: val=`sqlquotestr \"$icon\"`;" >> $iconcleaner yuuji@407: picon="" yuuji@407: fi yuuji@406: yuuji@403: cat< yuuji@420: yuuji@154: EOF yuuji@403: echo -n "" yuuji@403: } > "$cachefile" ######## New ROW Creation Ends here ######## yuuji@406: test -n "$stampfile" && date "+%F %T" > $stampfile yuuji@403: fi yuuji@403: # Printing a cached row yuuji@409: sed -e "/^
${picon}__EDIT__#$aid yuuji@154: $uname yuuji@287: $tm yuuji@409: <__NOTIFY__>" yuuji@403: echo "$hte"|unhexize|htmlescape|hreflink|minitbl yuuji@403: usecache='' tsfile=$td/$id.stamp yuuji@403: for i in $imgids; do yuuji@403: mrid=${i%%:*}; i=${i#*:}; sz=`size_h ${i%%:*}` yuuji@403: fn=`echo "${i#*:}"|unhexize` yuuji@403: fnb=$fn"(${sz})" yuuji@263: case "$fn" in yuuji@407: *.[Pp][Nn][Gg]|*.[Jj][Pp][Gg]|*.[Jj][Pp][Ee][Gg]|*.[GgTt][Ii][Ff]) yuuji@403: # fmt=${fn##*.} # convert - jpg:- is slow...why yuuji@403: case "$fn" in yuuji@403: *.[Pp][Nn][Gg]) fmt=png ;; yuuji@403: *.[Gg][Ii][Ff]) fmt=gif ;; yuuji@403: *) fmt=jpeg ;; yuuji@403: esac yuuji@403: outfile=$td/$mrid-${fn%.*}.$fmt yuuji@403: #err fn=$fn outfile=$outfile yuuji@403: #err "usecache=$usecache `ls -l $outfile`" yuuji@403: #err tm=$tm yuuji@403: #err tsfile=$tsfile=`cat $tsfile` yuuji@403: if [ -s "$outfile" ] && # $outfile should be > 0 yuuji@403: { [ "$usecache" ] || # And usecache flag is true, or... yuuji@403: { [ -s "$tsfile" ] && [ x"`cat $tsfile`" = x"$tm" ] yuuji@403: };}; then yuuji@403: usecache=1 # Set usecache flag on yuuji@403: cat<<-EOF yuuji@264: yuuji@264: $fnb yuuji@264: EOF yuuji@404: # !!NOTE!! Create row stamp ONLY WHEN imgcache is active yuuji@403: else yuuji@403: query "SELECT hex(bin) FROM article_m WHERE rowid=$mrid;" \ yuuji@403: | unhexize \ yuuji@403: | convert -define ${fmt}:size=100x100 -resize 100x100'>' \ yuuji@403: - ${fmt}:- \ yuuji@403: | tee "$outfile" \ yuuji@403: | hexize \ yuuji@403: | sed -e 's/\(..\)/%\1/g' \ yuuji@403: -e "s|^|$fnb|" yuuji@406: unset stampfile # img data stream is not suitable to cache yuuji@403: echo $tm > $tsfile yuuji@403: fi yuuji@403: ;; yuuji@403: *) yuuji@403: echo "$fnb" yuuji@403: ;; yuuji@403: esac yuuji@403: done yuuji@403: echo "
/s,,${notify:+$nt}," \ yuuji@408: $cachefile yuuji@263: done yuuji@452: yuuji@452: help="=== コメントに使用できる特殊記法 === yuuji@452: 行頭に href=URL でURLへのリンク yuuji@452: 行頭に iframe=URL でURL先を開く iframe yuuji@452: [[#記事番号]] でs4内の記事番号に飛ぶリンク yuuji@452: [[URL]] でURLへのリンク yuuji@452: [[URL|文字列]] でアンカー文字列を指定してのURLリンク yuuji@452: {{画像URL}} でインライン画像 yuuji@452: {{画像URL|幅}} でピクセル幅を指定したインライン画像 yuuji@452: {{{URL}}} でURL先を開く iframe yuuji@452: {{{URL|高さ}}} でピクセル高さを指定した iframe yuuji@452: ## 大見出し yuuji@452: ### 中見出し yuuji@453: #### 小見出し yuuji@453: |列1|列2|列3… と行頭から始まる縦棒区切り行を続けて表" yuuji@452: touchhelp="${touchpanel:+

$help

}" yuuji@193: textform='
yuuji@341:
yuuji@193: yuuji@452: yuuji@205: "' yuuji@154:
'"$touchhelp"'
添付ファイル: yuuji@206:
yuuji@154: yuuji@193:
yuuji@154: ' yuuji@219: cat<<-EOF yuuji@239:
yuuji@219: yuuji@219: EOF yuuji@219: $iswritable && cat<<-EOF yuuji@219:
yuuji@239: yuuji@268: yuuji@239: yuuji@239: $textform yuuji@239:
yuuji@239: yuuji@239: EOF yuuji@333: # Clean up orphaned icon cache yuuji@406: [ -s $iconcleaner ] && query ".read '$iconcleaner'" yuuji@154: # Record access log yuuji@154: acclog blog $rowid yuuji@154: } yuuji@154: yuuji@0: lshandout() { yuuji@0: # $1=rowid of blog yuuji@401: blog_writable $1 $user yuuji@461: rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member yuuji@401: if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then yuuji@64: echo "メンバー以外は利用できません。" | html p; return yuuji@64: fi yuuji@0: time=`getvalbyid blog ctime $1|colrm 11` yuuji@0: owner=`getvalbyid blog owner $1` yuuji@0: title=`getvalbyid blog title $1` yuuji@2: ge=`gecos $owner` yuuji@369: fh=$tmpd/formhead yuuji@369: echo "$time [$title]@${ge:-$owner}" > $fh yuuji@0: lshandoutsub $owner "$@" \ yuuji@189: |_m4 -D_TITLE_="提出状況" \ yuuji@369: -D_FORMHEAD_="syscmd(cat $fh)" \ yuuji@189: -D_FORM_="syscmd(cat)" -D_DUMPHEAD_= -D_DUMPTABLE_= \ yuuji@189: $layout/html.m4.html $layout/form+dump-whead.m4.html yuuji@369: gn=`echo $owner|htmlescape` yuuji@369: echo "

グループ $gn すべてのレポート板集計

" yuuji@369: } yuuji@369: gethandoutcsv() { yuuji@369: # contenttype; echo yuuji@369: CATCSV=1 lshandoutall "$1" yuuji@369: } yuuji@373: gethandoutcsv2() { yuuji@373: # contenttype; echo yuuji@373: SQL=$(cat<<-EOF) gethandoutcsv "$1" yuuji@373: WITH this_blog_articles AS ( yuuji@373: SELECT rtb.id bid, rtb.brid, a.id aid, author, title, ctime yuuji@373: FROM report_type_blogs rtb JOIN article a ON rtb.id=a.blogid yuuji@373: ), text_or_file AS ( yuuji@373: SELECT bid, author, title, ctime, 'text' shu, count(val) cnt yuuji@373: FROM this_blog_articles tba, article_s s yuuji@373: ON tba.aid=s.id yuuji@373: WHERE key='text' yuuji@373: GROUP by bid, author yuuji@373: UNION yuuji@373: SELECT bid, author, title, ctime, 'file' shu, count(val) cnt yuuji@373: FROM this_blog_articles tba, article_m m yuuji@373: ON tba.aid=m.id yuuji@373: WHERE key='image' yuuji@373: GROUP by bid, author yuuji@373: ), count_list AS ( yuuji@373: SELECT author, yuuji@373: substr(ctime, 1, 10)||upper(substr(shu, 1, 1)) unit, yuuji@373: cnt yuuji@373: FROM text_or_file yuuji@373: ) yuuji@373: SELECT gecos "名前", yuuji@373: substr(author, 1, instr(author, '@')-1) "uname", yuuji@373: unit, yuuji@374: cnt "post" yuuji@373: FROM count_list cl JOIN gecoses g ON cl.author=g.name; yuuji@373: EOF yuuji@373: } yuuji@369: lshandout_ulink_table() { yuuji@369: # NO Args. Read stdin as SQL yuuji@369: echo '' yuuji@369: hrb=",\1$hrb\2\">\3," -e 's,,,' yuuji@369: echo '
\)\([^ ]*\) \(.*\)00
' yuuji@369: printf ".mode list\n.header OFF\n" | query yuuji@369: } yuuji@369: lshandoutall() { yuuji@369: # $1=rowid of blog yuuji@402: blog_writable $1 $user yuuji@461: rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member yuuji@402: if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then yuuji@369: echo "メンバー以外は利用できません。" | html p; return yuuji@369: fi yuuji@369: rowid=$(($1 + 0)) yuuji@369: owner=`getvalbyid blog owner $1` yuuji@369: qowner=`sqlquotestr "$owner"` yuuji@369: yuuji@369: query<<-EOF yuuji@369: CREATE TEMPORARY TABLE IF NOT EXISTS report_type_blogs AS yuuji@369: WITH blog_owner_mode AS ( yuuji@369: SELECT id, yuuji@369: blog.rowid brid, yuuji@369: max(CASE key WHEN 'owner' THEN val END) owner, yuuji@369: max(CASE key WHEN 'mode' THEN val END) mode, yuuji@373: max(CASE key WHEN 'title' THEN val END) title, yuuji@373: max(CASE key WHEN 'ctime' THEN val END) ctime yuuji@369: FROM blog NATURAL JOIN blog_s yuuji@369: GROUP BY id yuuji@369: ) yuuji@373: SELECT id, brid, title, ctime FROM blog_owner_mode yuuji@369: WHERE owner=$qowner AND mode LIKE '%report%'; yuuji@369: /* ↑これでレポート形式の blogid 一覧を得る */ yuuji@369: EOF yuuji@369: if [ -z "$CATCSV" ]; then yuuji@369: _m4 -D_TITLE_="提出状況" $layout/html.m4.html yuuji@369: ge=`gecos "$owner"` yuuji@369: tbls="" yuuji@369: grptxt=`echo "${ge:-$owner}"|htmlescape` yuuji@369: echo "

$grptxt 書き込み状況一覧

" yuuji@369: fi yuuji@375: if [ -z "$SQL" ]; then yuuji@375: bridlist=`query "SELECT brid FROM report_type_blogs;"` yuuji@375: for brid in $bridlist; do # Skip this loop if $SQL set yuuji@375: brid=$(($brid + 0)) # Ensure to be a number yuuji@375: [ $brid = 0 ] && continue yuuji@375: time=`getvalbyid blog ctime $brid|colrm 11` yuuji@375: title=`getvalbyid blog title $brid|htmlescape` yuuji@399: state=`getvalbyid blog state $brid|htmlescape` yuuji@375: tt="handout_$brid" yuuji@399: [ "$state" = "frozen" ] && frozen=" $FROZEN_TAG" || frozen="" yuuji@375: if [ -z "$CATCSV" ]; then yuuji@399: echo "

$time - $title$frozen

" yuuji@375: lshandoutsub "$owner" $brid "$tt" yuuji@375: else yuuji@375: lshandoutsub "$owner" $brid "$tt" >/dev/null # Only create temp.table yuuji@375: fi yuuji@375: tbls="$tbls${tbls:+ NATURAL JOIN }$tt" yuuji@375: done yuuji@375: fi yuuji@373: sql=${SQL:-"SELECT * FROM $tbls;"} yuuji@369: if [ -z "$CATCSV" ]; then yuuji@369: echo "

総合

" yuuji@369: echo "$sql" | lshandout_ulink_table yuuji@373: echo "

総合(CSV)

" yuuji@369: printf ".mode csv\n.header ON\n" | query yuuji@369: echo '
'
yuuji@369:     echo "$sql" | query | sed 's/^"[0-9]*	/"/'
yuuji@369:     echo "
" yuuji@373: echo "
縦持ちCSV
" yuuji@369: else yuuji@369: contenttype "Application/CSV" yuuji@369: printf ".mode csv\n.header ON\n" | query >/dev/null yuuji@369: fn=report-count.csv yuuji@369: printf 'Content-Disposition: filename="%s"\n' "$fn" yuuji@379: outfile=$tmpd/out-$$.csv yuuji@369: echo "$sql" | query | sed 's/^"[0-9]* /"/' > $outfile yuuji@369: echo "Content-Length: " `cat $outfile | wc -c`; echo yuuji@369: yuuji@369: cat $outfile yuuji@369: exit 0 yuuji@369: fi yuuji@369: printf ".mode list\n.header OFF\n.separator |\n" | query yuuji@0: } yuuji@0: lshandoutsub() { yuuji@369: # $1=owner $2=rowid of blog &optional $3=temp_table name yuuji@369: qgname=`sqlquote "$1"` yuuji@436: if isgroup "$1"; then yuuji@369: sample="(select user from grp_mem where gname=$qgname)" yuuji@2: else yuuji@2: sample="(select distinct author as user from arts)" yuuji@67: echo "(集計は板への投稿者のみ)" | html p yuuji@2: fi yuuji@369: tmpname="${3:-handout_$2}" yuuji@369: sql="CREATE TEMPORARY TABLE IF NOT EXISTS $tmpname AS yuuji@369: with arts as (select id,author from article \ yuuji@0: where blogid=(select id from blog where rowid=$2))\ yuuji@0: select (select rowid from user where name=c0.user)||' '|| \ yuuji@366: (select gecos from gecoses where name=c0.user) as 'メンバー',\ yuuji@373: substr(c0.user, 1, instr(c0.user, '@')-1) 'uname',\ yuuji@0: sum(case when c1.key is not null then 1 else 0 end)\ yuuji@369: as '[$title] コメント記入',\ yuuji@0: sum(case when c2.key is not null then 1 else 0 end)\ yuuji@369: as '[$title] ファイルの提出'\ yuuji@2: from $sample c0 \ yuuji@0: left join (select id,author from arts) a\ yuuji@0: on c0.user=a.author\ yuuji@0: left join (select id,key from article_s where key='text') c1\ yuuji@0: on a.id=c1.id left join (select id,key from article_m ) c2\ yuuji@369: on c1.id=c2.id group by c0.user order by c0.user;\ yuuji@369: \ yuuji@369: SELECT * FROM $tmpname;" yuuji@0: err ishandoutsub: sql="$sql" yuuji@369: echo "$sql" | lshandout_ulink_table yuuji@0: } yuuji@2: gethandout() { yuuji@2: # $1=rowid of blog yuuji@402: blog_writable $1 $user yuuji@461: rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member yuuji@402: if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then yuuji@64: echo "メンバー以外は利用できません。" | html p; return yuuji@64: fi yuuji@2: i=0 yuuji@2: bd=$tmpd/archive.$$ yuuji@2: mkdir $bd yuuji@2: query "select m.rowid,author,m.val from article a join article_m m\ yuuji@2: on a.id=m.id where blogid=(select id from blog where rowid=$1)\ yuuji@2: and m.key in ('image', 'document', 'binary');" \ yuuji@2: | while IFS='|' read rowid author filename; do yuuji@356: err isfilereadable $user article_m $rowid yuuji@63: isfilereadable $user article_m $rowid || continue yuuji@356: err ok yuuji@2: i=$((i+1)) yuuji@2: dir=`printf $bd/%03d $i` yuuji@2: mkdir $dir yuuji@2: query "select quote(bin) from article_m where rowid=$rowid;" \ yuuji@8: | unhexize > $dir/$filename yuuji@2: done yuuji@2: if [ ! -d $bd/001 ]; then yuuji@2: contenttype; echo yuuji@67: echo "取得できるファイルがありませんでした。" | html p yuuji@2: return yuuji@2: fi yuuji@2: (cd $bd yuuji@356: ## err cdto$bd; (pwd; ls -lFa) 1>&3 yuuji@2: tar zcf .archive.tar.gz * && mv .archive.tar.gz archive.tar.gz yuuji@356: err Creating tar archive "`ls -l archive.tar.gz`" yuuji@2: ) yuuji@2: arc=$bd/archive.tar.gz yuuji@2: echo "Content-type: application/x-gzip" yuuji@2: echo "Content-Length: `cat $arc|wc -c`" yuuji@2: echo "Content-Disposition: filename=\"archive.tar.gz\"" yuuji@2: echo yuuji@2: cat $arc yuuji@2: } yuuji@462: blogseen() { # $1 = blogid yuuji@462: blogid=${1%%[!0-9]*} yuuji@462: if [ -z "$blogid" ]; then yuuji@462: echo "Invalid blog id" | html p; exit yuuji@462: fi yuuji@462: blog_writable "$blogid" "$user" yuuji@462: rc=$? # =0: writable, $BLOG_NOTMEM bit set => not member yuuji@462: if [ $((rc & $BLOG_NOTMEM)) -gt 0 ] ; then yuuji@462: echo "メンバー以外は利用できません。" | html p; return yuuji@462: fi yuuji@462: owner=`getvalbyid blog owner $rowid` yuuji@467: qowner=`sqlquotestr "$owner"` yuuji@467: grprowid=`query "SELECT rowid FROM grp WHERE gname=$qowner;"` yuuji@467: ge=`gecos "$owner" | htmlescape` yuuji@467: title=`getvalbyid blog title $rowid | htmlescape` yuuji@467: h1="アクセス時刻" yuuji@467: link2board="$title" yuuji@467: link2group="$ge" yuuji@467: _m4 -D_TITLE_="$h1" $layout/html.m4.html yuuji@467: echo "$h1" | html h1 yuuji@467: echo "[$link2board]@$link2group" | html h2 yuuji@462: warn=' class="warn"' yuuji@462: cat <<-EOF yuuji@464: yuuji@462: yuuji@462: EOF yuuji@462: query <<-EOF | yuuji@462: WITH grpmem as ( yuuji@462: SELECT user, (SELECT gecos FROM gecoses WHERE name=user) gecos yuuji@462: FROM grp_mem yuuji@462: WHERE gname=(SELECT val FROM blog_s yuuji@463: WHERE id=(select id from blog where rowid=$blogid) yuuji@462: AND key='owner') yuuji@462: ), acctime AS ( yuuji@462: SELECT user, max(time) atime yuuji@462: FROM tblaccesses yuuji@463: WHERE tbl='blog' AND tblrowid=$blogid yuuji@462: GROUP BY user yuuji@462: ) yuuji@462: SELECT g.user, yuuji@462: (SELECT rowid FROM user u WHERE u.name=g.user), yuuji@462: hex(gecos), yuuji@462: atime yuuji@462: FROM grpmem g LEFT JOIN acctime t yuuji@462: ON g.user = t.user yuuji@470: GROUP BY g.user yuuji@462: ORDER BY atime DESC; yuuji@462: EOF yuuji@462: while IFS='|' read u uid hexge time; do yuuji@462: td=${time:+" yuuji@462: yuuji@462: yuuji@462: $td${time:----} yuuji@462: EOF yuuji@462: done yuuji@462: cat <<-EOF yuuji@462:
メンバーuname最終閲覧時刻
"} # If the variable time is set, td= yuuji@462: td=${td:-""} # else td= yuuji@462: cat <<-EOF yuuji@462:
`echo "$hexge"|unhexize|htmlescape``echo ${u%%@*}|htmlescape`
yuuji@462:

[$title]に戻る

yuuji@462: yuuji@462: EOF yuuji@462: } yuuji@80: lsmyfile() { # $1(optional)=SortBy yuuji@80: case "$1" in yuuji@80: ""|CTIME-DESC) yuuji@80: by="CTIME" ord="DESC" ;; yuuji@80: CTIME*) by="CTIME" ;; yuuji@80: FILE*) by="FILE" ;; yuuji@80: OWNER*) by="OWNER" ;; yuuji@80: TITLE*) by="TITLE" ;; yuuji@80: esac yuuji@80: case "$1" in yuuji@80: *DESC) ord="DESC" ;; yuuji@80: esac yuuji@80: case "$ord" in yuuji@80: DESC) lkod="" jord="降順" ;; yuuji@80: *) lkod="-DESC" jord="昇順" ;; yuuji@80: esac yuuji@80: sql="select m.val||'/'||m.rowid FILE, yuuji@80: coalesce( yuuji@80: case when (select name from user where name=bs.owner) yuuji@80: is not null yuuji@80: then (select val from user_s where name=bs.owner yuuji@80: and key='gecos') yuuji@80: when (select gname from grp where gname=bs.owner) yuuji@80: is not null yuuji@80: then (select val from grp_s where gname=bs.owner yuuji@80: and key='gecos') yuuji@80: else yuuji@80: null yuuji@80: end, yuuji@80: bs.owner yuuji@80: ) OWNER, yuuji@80: a_s.val CTIME, yuuji@80: ',t,'||bs.title||':'||b.rowid||'#'||a.id TITLE yuuji@80: from (select rowid,id,val from article_m where id yuuji@80: in (select id from article where author='$user') yuuji@80: and type like 'file:%') yuuji@80: m left join article a on m.id=a.id yuuji@80: left join article_s a_s on a.id=a_s.id and a_s.key='ctime' yuuji@80: left join (select id, yuuji@80: max(case key when 'owner' then val end) as owner, yuuji@80: max(case key when 'title' then val end) as title yuuji@80: from blog_s group by id) yuuji@80: bs on a.blogid=bs.id yuuji@80: left join blog b on bs.id=b.id yuuji@80: where m.val is not null order by $by $ord;" yuuji@80: err lshandoutbyauthor: sql=`echo "$sql"` yuuji@80: title="個人提出ファイル" yuuji@189: _m4 -D_TITLE_=$title $layout/html.m4.html yuuji@80: hra="' yuuji@80: echo "$sql"|sq -html -header $db ) \ yuuji@80: | sed -e "s|\(\)\([^/]*\)/\([0-9]*\)|\1$hrb\3\">\2|" \ yuuji@80: -e "s|,t,\(.*\):\([^<]*\)\(\)|$hrc\2\">\1\3|" \ yuuji@80: -e "s|\(\)\([A-Z]*\)\(\)|\1$hra\2$lkod\">\2|" \ yuuji@189: | _m4 -D_TITLE_=$title -D_FORM_="

($by$jord)

" \ yuuji@189: -D_DUMPTABLE_="syscmd(cat)" $layout/form+dump.m4.html yuuji@80: echo '' yuuji@80: } yuuji@78: searchart() { yuuji@301: kwd=`getpar kwd|nkf -wZ1` # Convert Zenkaku-SPC to ASCII-SPC yuuji@301: kwdgrp="" yuuji@337: authcond="" yuuji@78: if [ -z "$kwd" ]; then yuuji@78: echo "検索語を指定してください" | html p; return yuuji@78: fi yuuji@301: if expr x"$kwd" : 'x#[1-9][0-9]*$' >/dev/null 1>&2; then yuuji@301: # Like '#1234', assume as artID yuuji@301: rowid=$((${kwd#\#} + 0)) # Force to be a number yuuji@337: kc="ar.rowid = $rowid" yuuji@301: else yuuji@344: for k in `echo "$kwd" | sed "s/'/''/g"`; do # With wrap quotes yuuji@344: if expr x"$k" : 'x@[><= ]*[1-9][][0-9]*-[][0-9:-]*$' >/dev/null >&2; then yuuji@344: # '@<2016-10-10' -> ctime < '2016-10-10' yuuji@344: # '@>=2016-10-10' -> ctime >= '2016-10-10' yuuji@344: # '@2016-10-10' -> ctime GLOB '@2016-10-10' yuuji@344: k=${k#@} yuuji@344: case "$k" in yuuji@344: [\<\>]*) op=${k%%[!<>=]*}; ctime=${k##*[><= ]} ;; yuuji@344: *) op='GLOB'; ctime="${k##*[><= ]}*" ;; yuuji@344: esac yuuji@344: kc=$kc${kc:+" AND "}"ctime $op '${ctime}'" yuuji@301: # Not sure GROUP BY a.blogid is comfortable for searchers...? yuuji@331: ##### kwdgrp=" GROUP BY a.blogid" ## Add this to lessen results yuuji@304: elif [ x"$k" = x"@today" -o x"$k" = x"@今日" ]; then yuuji@304: ctime=`date +%F` yuuji@337: kc=$kc${kc:+" AND "}"ctime GLOB '${ctime}*'" yuuji@344: elif [ x"$k" = x"@week" ]; then yuuji@344: ctime=`query "SELECT datetime('now', 'localtime', '-7 days');"` yuuji@344: kc=$kc${kc:+" AND "}"ctime > '${ctime}'" yuuji@352: elif [ x"$k" = x"@month" ]; then yuuji@352: ctime=`query "SELECT datetime('now', 'localtime', '-1 month');"` yuuji@352: kc=$kc${kc:+" AND "}"ctime > '${ctime}'" yuuji@352: elif [ x"$k" = x"@year" ]; then yuuji@352: ctime=`query "SELECT datetime('now', 'localtime', '-1 year');"` yuuji@352: kc=$kc${kc:+" AND "}"ctime > '${ctime}'" yuuji@301: else yuuji@333: kc=$kc${kc:+" AND "}"content LIKE '%$k%'" yuuji@301: fi yuuji@301: done yuuji@301: fi yuuji@165: kwd=`echo "$kwd"|htmlescape` yuuji@78: owner=`getpar owner` yuuji@78: owner=${owner:-$1} yuuji@78: echo "「$kwd」による検索結果" | html p yuuji@78: if [ -n "$owner" ]; then yuuji@78: cond="where key='owner' and val='$owner'" yuuji@78: if isuser $owner; then yuuji@78: echo "(`linkhome $owner` さんの記録からの検索)" | html p yuuji@78: else yuuji@78: linkhome $owner 1>&3 yuuji@78: echo "(`linkhome $owner` グループからの検索)" | html p yuuji@78: fi yuuji@331: elif { author=`getpar author`; test -n "$author"; }; then yuuji@331: atptn=`sqlquotestr $author` yuuji@337: #kc="$kc${kc:+ AND }author=$atptn" yuuji@337: authcond="WHERE author=$atptn" yuuji@331: if isuser $author; then yuuji@331: echo "(`linkhome $author` さんの書き込みからの検索)" | html p yuuji@331: fi yuuji@78: fi yuuji@78: # article_s: id=article-id, key='text', val='TEXT' yuuji@78: # article: id=article-id, blogid=blogkd yuuji@78: # blog: id=blog-id, author=LeaderAuthor yuuji@78: # blog_s: id=blog-id, key='title', val='BLOG-TITLE' yuuji@78: # WANT: blog-ROWid,article-id,val(TEXT) yuuji@337: sql2="`sql4readableblogs` -- Extract user-readable blogs yuuji@337: -- 0.3sec yuuji@337: WITH artsm AS ( yuuji@337: SELECT a.id,ctime, text || ' ' || coalesce(files, '') content yuuji@337: FROM article a yuuji@337: LEFT JOIN yuuji@337: (SELECT ars.id, ctime, text, coalesce(files, '') files yuuji@337: FROM (SELECT id, yuuji@337: max(CASE key WHEN 'ctime' THEN val END) ctime, yuuji@337: max(CASE key WHEN 'text' THEN val END) text yuuji@337: FROM article_s yuuji@337: GROUP BY id) ars yuuji@337: LEFT JOIN yuuji@337: (SELECT id, group_concat(val) files yuuji@337: FROM article_m yuuji@337: WHERE type LIKE 'file:%' yuuji@337: GROUP BY id) arm yuuji@337: ON ars.id=arm.id yuuji@337: ) ar yuuji@337: ON a.id=ar.id yuuji@337: ), ar AS ( yuuji@338: SELECT a.rowid, a.blogid, a.id, a.author, ctime, content yuuji@338: FROM article a JOIN artsm ON a.id=artsm.id yuuji@337: $authcond yuuji@337: ), bl AS ( yuuji@337: SELECT blg.rid, blg.*, blog_s.val TITLE yuuji@337: FROM readableblogs blg JOIN blog_s ON blg.id=blog_s.id AND blog_s.key='title' yuuji@337: ) yuuji@337: SELECT bl.rid||'#'||ar.id '', yuuji@337: bl.title TITLE, yuuji@338: (SELECT gecos FROM gecoses WHERE name=ar.author) AUTHOR, yuuji@337: substr(ctime, 0, 11) DATE, yuuji@337: substr(content, 0, 78) TEXT yuuji@337: FROM ar JOIN bl yuuji@337: ON ar.blogid=bl.id yuuji@337: WHERE $kc AND bl.id IN (SELECT id FROM blog_s $cond) yuuji@337: ORDER by DATE DESC, TITLE, ctime;" yuuji@78: sedopt="s,\([^<]*\),VIEW," yuuji@337: # echo "$sql2" > tmp/sql.out yuuji@352: result=$tmpd/result.$$ yuuji@78: cat< yuuji@352: `sq -header -html $db "$sql2"|sed "$sedopt"|tee $result` yuuji@78: yuuji@78: EOF yuuji@352: if [ -s "$result" ]; then yuuji@356: found=$((`grep "^" $result | wc -l` + 0)) # Cast to INT yuuji@352: one=${found%1} yuuji@352: echo "$found match${one:+es} found" yuuji@352: else yuuji@352: echo orz... yuuji@352: fi yuuji@78: } yuuji@0: listblog() ( yuuji@67: # $1={user,group} yuuji@67: qow=`sqlquote $1` yuuji@67: cond="where a.id in (select id from blog_s where key='owner' and val=$qow) order by ctime desc" yuuji@0: DT_CHLD=article:blogid yuuji@0: cgi_form searchart<`cgi_text kwd`という語を含む記事をこの一覧から検索 yuuji@0: `cgi_hidden owner $user` yuuji@0: EOF yuuji@0: dumptable html blog 'ctime title heading' "$cond" yuuji@0: ) yuuji@0: yuuji@0: blog_addentry() { yuuji@0: # $1=GRPname(if it is a group) yuuji@16: grprowid=$1 yuuji@0: rowid=`getpar rowid` yuuji@356: ## err blog_addentry0: rowid=$rowid yuuji@80: if [ -n "$grprowid" ]; then yuuji@80: owner=`getgroupbyid $grprowid` yuuji@80: else yuuji@80: owner=`getpar owner` yuuji@80: fi yuuji@122: err blog-add: \$1=$1 rowid=$rowid owner=$owner yuuji@436: if isgroup "$owner"; then yuuji@80: groupmode=1 listing=$owner guide="[${owner}]" GF_OWNER=$owner yuuji@80: else yuuji@80: usermode=1 listing=$user guide="[個人]" yuuji@80: fi yuuji@80: yuuji@0: if [ -n "`getpar title`" ]; then yuuji@80: if [ "$usermode" ]; then yuuji@122: err usermode: user=$user owner=$owner yuuji@0: if [ x"$user" != x"$owner" ]; then yuuji@67: echo "他人の日記は書けません" | html p yuuji@80: return 2 yuuji@0: fi yuuji@80: elif [ "$groupmode" ]; then # if write to group log yuuji@0: grp=$owner #\`getpar grp\` yuuji@0: err ismember: $user $grp yuuji@0: if ! ismember "$user" "$grp"; then yuuji@67: echo "(話題作成はこのグループに加入してから)" | html p yuuji@80: return 3 yuuji@0: fi yuuji@0: fi yuuji@0: par2table $formdir/blog.def yuuji@0: serial=`getpar serial` yuuji@356: ## err SERIAL: $serial ROWID=$rowid listing=$listing yuuji@0: id="" yuuji@0: if [ -n "$rowid" ]; then yuuji@0: # Here, id becomes NULL when removal of entries at par2table yuuji@0: id=`query "select rowid from blog where rowid=$rowid;"` yuuji@0: elif [ -n "$serial" ]; then yuuji@0: # If new blog leader created, traverse to its head. yuuji@0: id=`query "select rowid from blog where id='$serial';"` yuuji@356: ## err new-Leader: "select rowid from blog where id='$serial';" id=$id yuuji@0: fi yuuji@0: if [ -n "$id" ]; then yuuji@0: ## If new aritcle is entered, JUMP to blog_reply yuuji@0: blog_reply $id yuuji@0: return yuuji@0: fi yuuji@0: fi yuuji@81: echo "${guide}新規話題作成" > $tmpd/title.$$ yuuji@81: listblog $listing > $tmpd/listblog.$$ yuuji@81: genform $formdir/blog.def \ yuuji@189: | _m4 -D_TITLE_="spaste(\`$tmpd/title.$$')" \ yuuji@189: -D_FORMHEAD_="序文は簡単に詳しくはコメントに" \ yuuji@189: -D_DUMPHEAD_="これまでの蓄積" \ yuuji@189: -D_FORM_="syscmd(\`cat')" \ yuuji@189: -D_DUMPTABLE_="spaste(\`$tmpd/listblog.$$')" \ yuuji@189: $layout/html.m4.html \ yuuji@189: $layout/form+dump-whead.m4.html yuuji@0: } yuuji@0: yuuji@379: blog_reply() { # Posting to blog article yuuji@0: rowid=$1 yuuji@0: yuuji@0: if [ -z "$rowid" ]; then yuuji@67: echo "表示する日記番号が未指定です。" | html p yuuji@0: return yuuji@0: fi yuuji@0: title=`getvalbyid blog title $rowid` yuuji@0: owner=`getvalbyid blog owner $rowid` yuuji@466: qowner=`sqlquotestr "$owner"` yuuji@397: if [ -z "$title" ]; then yuuji@397: echo "日記番号指定が無効です。" | html p yuuji@397: return yuuji@397: fi yuuji@397: blog_writable $rowid $user; rc=$? yuuji@397: if [ $rc = 0 ]; then yuuji@397: iswritable=true yuuji@397: else yuuji@397: iswritable=false yuuji@397: if [ $((rc & $BLOG_FROZEN)) -gt 0 ]; then yuuji@397: isfrozen=true yuuji@397: frozen_class='frozen"' yuuji@399: frozen_flag=$FROZEN_TAG yuuji@397: fi yuuji@397: fi yuuji@0: if isuser "$owner"; then yuuji@0: subtitle="`gecos $owner` さんの話題" yuuji@0: else yuuji@466: grprowid=`query "select rowid from grp where gname=$qowner;"` yuuji@341: subtitle="グループ yuuji@341: $owner での話題 yuuji@222: `query \"SELECT printf('(チーム:%s)', val)\ yuuji@222: FROM blog_s yuuji@222: WHERE id=(SELECT id FROM blog WHERE rowid=$rowid) yuuji@222: AND key='team'; yuuji@222: \"|htmlescape`" yuuji@288: memclass=`grp_getbodyclass "$owner"` yuuji@0: fi yuuji@0: yuuji@0: text=`getpar text` yuuji@0: if [ -n "$text" ]; then yuuji@397: if $iswritable; then yuuji@80: par2table $formdir/article.def yuuji@356: st=$? yuuji@80: case $st in yuuji@80: 0|4) yuuji@80: [ "$st" = "4" ] && act="書込削除" yuuji@386: blog_notify_reply $rowid $user "$text" $act yuuji@386: if [ -n "$grprowid" ]; then yuuji@386: qgrp=$(sqlquote "$owner") yuuji@386: dbsetbyid grp $owner wtime "`date '+%F %T'`" yuuji@386: fi yuuji@386: ;; yuuji@80: esac yuuji@0: else yuuji@397: if $isfrozen; then yuuji@397: title="$title(凍結板につき書き込み不可)" yuuji@397: else yuuji@397: title="$title(加入してないので書き込み不可)" yuuji@397: fi yuuji@0: fi yuuji@0: fi yuuji@0: def=$formdir/article.def yuuji@81: echo "$title" > $tmpd/title.$$ yuuji@397: echo "$subtitle$frozen_flag" > $tmpd/subtitle.$$ yuuji@154: ${BLOG_SHOW:-blog_showentry} blog $rowid \ yuuji@259: | _m4 -D_TITLE_="spaste(\`$tmpd/title.$$')" \ yuuji@259: -D_BODYCLASS_=general"${memclass:+ $memclass}" \ yuuji@189: -D_FORMHEAD_="spaste(\`$tmpd/subtitle.$$')" \ yuuji@189: -D_FORM_='' \ yuuji@189: -D_DUMPTABLE_="syscmd(cat)" -D_DUMPHEAD_="" \ yuuji@189: $layout/html.m4.html $layout/form+dump-whead.m4.html yuuji@0: } yuuji@451: yuuji@451: blog_reply_article() { # Direct link to article in some blog yuuji@451: arid=${1:-0} # Already sanitized to digits yuuji@451: brid=`query "SELECT rowid FROM blog WHERE \ yuuji@451: id=(SELECT blogid FROM article WHERE rowid=$arid);"` yuuji@451: if [ -n "$brid" ]; then yuuji@451: newurl="?replyblog+$brid#$arid" yuuji@451: echo "Refresh: 0; $newurl"; echo yuuji@451: exit 0 yuuji@451: else yuuji@451: contenttype; echo yuuji@451: echo "無効な記事番号です." | html p yuuji@451: fi yuuji@451: }