yuuji@0: #!/bin/sh
yuuji@0: # Here's global variable table. Do not use this names.
yuuji@1: # $HGid$
yuuji@26:
yuuji@26: [ -f s4-config.sh ] && . ./s4-config.sh
yuuji@26:
yuuji@0: myname=`basename ${SCRIPT_NAME:-$0}`
yuuji@0: mydir=`dirname ${SCRIPT_FILENAME:-$0}`
yuuji@0: myargs="$@"
yuuji@8: PATH=/usr/local/sqlite3/bin:/usr/local/vim7/bin:/usr/iekei/ImageMagick/bin:/usr/local/ImageMagick/bin:$PATH
yuuji@0: tmpdir=${TMPDIR:-tmp}
yuuji@2: dbdir=${DBDIR:-db}
yuuji@0: tmpfiles=""
yuuji@2: db=${DB:-$dbdir/cgi.sq3}
yuuji@83: admin=${ADMIN:-hostmaster@example.org}
yuuji@3: templ=${TEMPL:-templ}
yuuji@67: layout=${LAYOUT:-$templ/default}
yuuji@67: formdir=${FORMDIR:-$templ/form}
yuuji@67: imgdir=${IMGDIR:-img}
yuuji@16: url=${URL:-"${REQUEST_SCHEME:-http${HTTPS:+s}}://$HTTP_HOST$REQUEST_URI"}
yuuji@0: urlbase=${url%%\?*}
yuuji@117: msgdir=$templ/msg
yuuji@0: timeout="+2 days"
yuuji@117: memoplimitdays="7"
yuuji@252: dumpcollen=22
yuuji@67: #thumbxy=120x120
yuuji@0: thumbxy=96x96
yuuji@322: iconxy_S=80x80
yuuji@322: iconxy_M=400x400
yuuji@0: maximagexy=1600x1600
yuuji@0: ### maximagexy=400x400
yuuji@209: file_accept='accept="image/*,text/*,audio/*,application/vnd.oasis.*,application/pdf,application/x-*"'
yuuji@236: blogreadflagrowid=0
yuuji@471: blogcutoffflagrowid=-1
yuuji@358: querylog=$tmpdir/query.log
yuuji@207:
yuuji@0: tconfs=""
yuuji@231: imgcached=cache/img.`date +%Y/%m`
yuuji@4: conftbl=_tblconf
yuuji@0: nl="
yuuji@0: "
yuuji@322: iconcachekey="profimgcache_S"
yuuji@352: case "$HTTP_USER_AGENT" in
yuuji@352: *i[Pp]hone*|*[Aa]ndroid*) touchpanel=1 ;;
yuuji@352: *) touchpanel="" ;;
yuuji@352: esac
yuuji@17: . ./s4-cgi.sh
yuuji@0:
yuuji@0: : < "hoge", "owner" => "yuuji", "date" => "2015-04-27",
yuuji@0: "text" => "hogehoge ..",
yuuji@0: "reply" => [ {"serial" => 1,
yuuji@0: "author" => "taro",
yuuji@0: "date" => "2015-04-28",
yuuji@0: "parent" => "/",
yuuji@0: "path" => "/1",
yuuji@0: "text" => "blah, blah, ....",
yuuji@0: "image" => ["a.jpg", "b.jpg"] },
yuuji@0: {"serial" => 2,
yuuji@0: "author" => "hanako",
yuuji@0: "date" => "2015-04-29",
yuuji@0: "parent" => "/",
yuuji@0: "path" => "/2",
yuuji@0: "text" => "blah, blah, ....",
yuuji@0: "image" => [] }]},
yuuji@0: {"title" => "buha", ...} ]
yuuji@0:
yuuji@0:
yuuji@0: user:=
yuuji@0: ユーザ名(英数字):name:p:text:length="20" maxlength="40"
yuuji@0: パスワード:pswd:s:password:length="20" maxlength="40"
yuuji@0: 説明(日本語OK):gecos:s:text:length="20" maxlength="40"
yuuji@0: セッションキー:skey:s:session
yuuji@0: メイルアドレス:email:m:text:length="20" maxlength="40"
yuuji@0: 住所:address:m:textarea:maxlength="400"
yuuji@0: プロフィール画像:profimg:m:image:maxlength="400K"
yuuji@0: 履歴書:profpdf:m:document:maxlength="4M"
yuuji@0:
yuuji@0: 変換表
yuuji@0: /user/email=m
yuuji@0:
yuuji@0: blog:=
yuuji@0: シリアル:id:p:serial
yuuji@0: タイトル:title:s:text:
yuuji@0: 所有者:owner:s:owner:
yuuji@0: 時刻:ctime:s:stamp:
yuuji@0: リード文:heading:s:textarea:
yuuji@0: リプライ:reply:m:*article:
yuuji@0:
yuuji@0: article:=
yuuji@0: シリアル:id:p:serial
yuuji@0: 筆者:author:s:owner
yuuji@0: 時刻:ctime:s:stamp:
yuuji@0: 参照元:parent:s:parent:
yuuji@0: パス:path:s:path:
yuuji@0: 本文:text:s:textarea:
yuuji@0: 画像:image:m:image:
yuuji@0:
yuuji@0: 履歴書:profpdf:m:document:maxlength="4M"
yuuji@0:
yuuji@0:
yuuji@0: EOF
yuuji@0:
yuuji@0: sq() {
yuuji@0: # ./args.rb -cmd ".timeout 3000" "$@"
yuuji@0: sqlite3 -cmd 'PRAGMA foreign_keys=ON' -cmd ".timeout 3000" "$@"
yuuji@0: }
yuuji@163: dbsetup() {
yuuji@163: [ -d $tmpdir ] || mkdir -m 1777 $tmpdir
yuuji@163: [ -d $dbdir ] || mkdir -m 1775 $dbdir
yuuji@163: sqi=$tmpdir/sqi.$$
yuuji@163: sqo=$tmpdir/sqo.$$
yuuji@163: mkfifo $sqi $sqo
yuuji@163: #tail -f $sqi | sq $db & # "tail -f" is too heavy. DO NOT USE!!
yuuji@163: sq $db < $sqi &
yuuji@163: sq3pid="`jobs -p` $!"
yuuji@163: exec 2>> $tmpdir/error.out
yuuji@163: exec 3>> $tmpdir/debug.out
yuuji@163: exec 5> $sqi # Turning $sqi access through fd5 for continuous open state
yuuji@163: rm $sqi
yuuji@163: }
yuuji@396: cleanup2() { # Dirty workaround for produced zombie processes
yuuji@396: pkill -9 -u `id -u` -P 1
yuuji@396: }
yuuji@163: cleanup() {
yuuji@337: trap '' INT HUP EXIT TERM PIPE
yuuji@163: echo .quit >&5
yuuji@163: kill $sq3pid
yuuji@163: kill $sq3pid
yuuji@163: rm -f $sqo $sqi
yuuji@163: rm -rf $tmpfiles
yuuji@396: cleanup2
yuuji@118: }
yuuji@358: # We want to use piped function to put querylog, but we use
yuuji@358: # simple redirection for the sake of speed.
yuuji@0: query() {
yuuji@180: echo ".once $sqo" >&5
yuuji@359: echo "`date '+%F %T'`:[${user:-NULL}] <<<" >> $querylog
yuuji@180: if [ -z "$1" ]; then
yuuji@358: tee -a $querylog
yuuji@180: else
yuuji@358: echo "$@" >> $querylog
yuuji@180: echo "$@"
yuuji@358: fi >&5
yuuji@0: cat $sqo
yuuji@358: echo '>>>' >> $querylog
yuuji@0: }
yuuji@187: _m4() {
yuuji@187: #_S4NAME_=f,f,f
yuuji@187: m4 ${_S4NAME_:+"-D_S4NAME_=${_S4NAME_}"} "$@"
yuuji@187: }
yuuji@0: ismember() {
yuuji@0: # $1=user, $2=group
yuuji@16: err ismem: "select user from grp_mem where gname=$(sqlquote $2) and user='$1';"
yuuji@431: test -n "`query \"select user from grp_mem where gname=$(sqlquote \"$2\") and user='$1';\"`"
yuuji@0: }
yuuji@0: isuser() { # Check if $1 is a valid user
yuuji@0: test -n "`query \"select name from user where name='$1';\"`"
yuuji@0: }
yuuji@0: isgroup() { # Check if $1 is a valid group
yuuji@16: err isgroup: "select gname from grp where gname=$(sqlquote $1);"
yuuji@431: test -n "`query \"select gname from grp where gname=$(sqlquote \"$1\");\"`"
yuuji@0: }
yuuji@16: isgrpowner() (
yuuji@0: # $1=user, $2=group
yuuji@16: gn=`sqlquote "$2"`
yuuji@16: sql="select user from grp_adm where gname=$gn and user='$1';"
yuuji@16: err isgrpowner: $sql
yuuji@16: test -n "`query $sql`"
yuuji@16: )
yuuji@117: getgroupadminmails() {
yuuji@117: # $1=group
yuuji@117: for i in $(getgroupadmins $1); do
yuuji@117: email4group "$1" "$i" ;
yuuji@117: done
yuuji@117: }
yuuji@56: getgroupadmins() { # $1=group
yuuji@56: # This function is called in a backquote, so needn't to be subshellized
yuuji@56: qgrp=`sqlquote "$1"`
yuuji@56: query "select user from grp_adm where gname=$qgrp;"
yuuji@56: }
yuuji@117: getgroupattr() { # $1=group $2=attr
yuuji@117: # This function is called in a backquote, so needn't to be subshellized
yuuji@117: getvalbyid grp $2 \
yuuji@431: $(query "select rowid from grp where gname=`sqlquote \"$1\"`;")
yuuji@117: }
yuuji@56: getgroupbyid() {
yuuji@16: # $1=id|gname
yuuji@431: sql="select coalesce((select gname from grp where gname=$(sqlquote \"$1\")),
yuuji@16: (select gname from grp where rowid=$(sqlquote $1)));"
yuuji@71: # err ggbyid: `echo $sql`
yuuji@16: query $sql
yuuji@56: }
yuuji@0: isfilereadable() { # $1=user $2=tbl $3=rowid
yuuji@0: # Return true if user($1) can read attachment files in tbl($2):rowid($3)
yuuji@0: [ -z "$1" -o -z "$2" -o -z "$3" ] && return 1 # invalid argument
yuuji@78:
yuuji@78: # Return true when anonymous mode
yuuji@78: [ "$anonymousmode" ] && return 0
yuuji@0: # case `getvalbyid blog mode $2` in
yuuji@0: # normal|*open*|"") return 0 ;;
yuuji@0: # *closed*)
yuuji@0: # owner=`getvalbyid blog owner $2`
yuuji@0: # if isgrp $owner; then
yuuji@0: # isgrpowner $1 $owner && return 0 || return 1
yuuji@0: # elif isuser $owner; then
yuuji@0: # [ x"$1" = x"$owner" ] && return 0 || return 1
yuuji@0: # fi
yuuji@0: # esac
yuuji@0: # ↑ 要はこういう処理を↓で一気にやっている
yuuji@0: sql="with getblog as (\
yuuji@0: select key,val from blog_s where id=(\
yuuji@0: select blogid from article where id in\
yuuji@0: (select id from $2 where rowid=$3))),\
yuuji@0: getowner as (select val from getblog where key='owner'),\
yuuji@0: getmode as (select val from getblog where key='mode')\
yuuji@0: select case\
yuuji@0: when (select author from article where\
yuuji@0: id=(select id from $2 where rowid=$3))='$1' \
yuuji@0: then 'author'\
yuuji@0: when (select val from getmode) in ('report-open', 'normal')\
yuuji@0: then 'open'\
yuuji@0: when (select val from getmode) is null \
yuuji@0: then 'open'
yuuji@0: when (select val from getowner) in (select gname from grp)\
yuuji@0: then (select user from grp_adm where \
yuuji@0: gname=(select val from getowner) and \
yuuji@0: user='$1')\
yuuji@39: when (select author from article where\
yuuji@39: id=(select id from $2 where rowid=$3))='$1'
yuuji@39: then 'user+author'
yuuji@39: else '' end;"
yuuji@356: ## err isfilereadable: sql="`echo $sql`"
yuuji@0: # caseのネストで内側のcaseがスカラーtrueを返しても外側はtrue扱いにならない
yuuji@0: result=`query "$sql"`
yuuji@0: [ -n "$result" ] && return 0
yuuji@0: return 2
yuuji@0: }
yuuji@0: linkhome() {
yuuji@0: # $1=UserOrGroup
yuuji@0: echo -n '`gecos $1`"
yuuji@0: }
yuuji@208: hreflink() {
yuuji@284: # s4 specific notation:
yuuji@284: # ^href=URL
yuuji@284: # ^iframe=URL
yuuji@478: # [[#NUM]] - Jump to article ID NUM
yuuji@478: # [[#Keyword] - Jump to keywrod search for "Keyword"
yuuji@284: # OSM umap Wikistyle Notation:
yuuji@284: # [[URL]] - Simle Link
yuuji@284: # [[URL|Word]] - Link with anchor word
yuuji@284: # {{URL}} -
yuuji@284: # {{URL|width}} -
yuuji@284: # {{{URL}} } -
yuuji@284: # {{{URL|height}} -
yuuji@485: # Other Style
yuuji@485: # ---- - (In the beginning of line)
yuuji@485: # *Word* - Word
yuuji@485: # _Word_ - Word
yuuji@485: # **Word** - Word
yuuji@485: # __Word__ - Word
yuuji@267: _hrefptn="[-A-Za-z0-9,.:;/~_%#&+?=@!]*"
yuuji@482: _hrefptn="[A-Za-z0-9/~%+?=@!.][^][()<> ]*" # URL should start with ASCII
yuuji@451: sed -e "s|\[\[\#\([0-9][0-9]*\)\]\]|#\1|g" \
yuuji@479: -e "s|\[\[#\([^]&]*\)\]\]|\#\1|g" \
yuuji@451: -e "s|\[\[\($_hrefptn\)\|\([^]]*\)\]\]|\2|g" \
yuuji@284: -e "s|\[\[\($_hrefptn\)\]\]|\1|" \
yuuji@284: -e "s|{{{\($_hrefptn\)\|\(.*\)}}}||g" \
yuuji@284: -e "s|{{{\($_hrefptn\)}}}||g" \
yuuji@284: -e "s|{{\($_hrefptn\)\|\(.*\)}}||g" \
yuuji@284: -e "s|{{\($_hrefptn\)}}||g"\
yuuji@284: -e "s|^href=\($_hrefptn\)|\1|" \
yuuji@425: -e "s|^iframe=\($_hrefptn\)||" \
yuuji@426: -e "s,^#### *\(.*\),
\1
," \
yuuji@426: -e "s,^### *\(.*\),
\1
," \
yuuji@483: -e "s,^## *\(.*\),
\1
," \
yuuji@485: -e 's,^----*$,,' \
yuuji@486: -e 's, \*\*\([^* |][^*|]*[^ |]\)\*\* ,\1,g' \
yuuji@486: -e 's, __\([^_ |][^_]*[^ ]\)__ ,\1,g' \
yuuji@486: -e 's, \*\([^* |][^*|]*[^ |]\)\* ,\1,g' \
yuuji@486: -e 's, _\([^_ ][^_]*[^ ]\)_ ,\1,g'
yuuji@208: }
yuuji@291: minitbl() {
yuuji@291: sed -n '
yuuji@295: /^|.*|/ {; # If the line begin with "|" and has 2 or more "|"
yuuji@291: s,|$,,; # Remove trailing "|" first
yuuji@291: s,|\* *\([^|]*\) *,
\1
,g; # "|*..." to "
...
"
yuuji@291: s,| *\([^|]*\) *,
\1
,g; # "|..." to "
...
"
yuuji@291: s,^,
,; s,$,
,; # Enclose with "
" and "
"
yuuji@291: H; # Concat this line to HoldSpace
yuuji@291: s/.*//; # Delete PatternSpace for finalization
yuuji@291: $ b cont
yuuji@291: d; # If in final line, output the rest, else jump to next turn
yuuji@291: }
yuuji@291: :cont
yuuji@291: x; # For non-"|" lines, check HoldSpace
yuuji@291: /^./ {; # If HoldSpace has "|" table elements
yuuji@398: s|^.|
|; # Enclose whole elements like this:
yuuji@398: # . of ^. is workaround for FreeBSD sed
yuuji@291: # s|$|
|; #
..\n..
yuuji@291: p; # Print whole "table" element
yuuji@291: s/.*//; # Erase all when done.
yuuji@291: x; s|^||; x; # Preppend /table to the next line
yuuji@291: }
yuuji@291: x; # Back to the newest line
yuuji@489: p; # Print rest' | miniul
yuuji@489: }
yuuji@489: miniul() {
yuuji@489: sed -e '
yuuji@489: /^\* / {; # 行頭 "* "
yuuji@489: x; s,^,
"
yuuji@319: viewtable $formdir/user.def user $1
yuuji@319: echo "
"
yuuji@319: } > $pf
yuuji@146:
yuuji@147: sqcond="WHERE name='$uname' AND key='profimg' AND type LIKE 'file:image%'"
yuuji@146: img=`query "SELECT type FROM user_m $sqcond LIMIT 1;"`
yuuji@148: imf=$tmpd/profimg.$$; touch $imf
yuuji@146: if [ -n "$img" ]; then
yuuji@311: if true; then
yuuji@311: tbl=user_m
yuuji@322: enticond="name='$uname'"
yuuji@322: imgsrc_cache "$td/main" user_m "$enticond" M
yuuji@311: else
yuuji@311: { printf '%s' "'
yuuji@311: }
yuuji@311: fi > $imf
yuuji@146: fi
yuuji@150: nblog=`query "SELECT count(id) FROM blog_s WHERE key='owner' AND \
yuuji@150: val='$uname';"`
yuuji@81: listblog $uname > $bf
yuuji@260:
yuuji@260: hometail=$tmpd/tail.$$
yuuji@260: mkfifo $hometail
yuuji@260:
yuuji@260: #Calling listgroupbytable, originally here
yuuji@81:
yuuji@260: (
yuuji@328: # Display Most Recent Entry
yuuji@328: shortval=${dumpcollen:+"substr(val, 0, $dumpcollen)"}
yuuji@328: shortval=${shortval:-val}
yuuji@252:
yuuji@340: # The m.aid in the next line is suspicious. But works fine in SQLite3...
yuuji@328: DT_SQL="SELECT b.rowid || '#' || m.aid LINK,
yuuji@253: ctime,
yuuji@253: (SELECT $shortval FROM blog_s WHERE key='title' AND id=b.id) title,
yuuji@253: (SELECT gecos FROM gecoses
yuuji@253: WHERE name=(SELECT val FROM blog_s
yuuji@257: WHERE key='owner' AND id=b.id)) owner,
yuuji@257: (SELECT $shortval val FROM article_s WHERE id=m.aid AND key='text') text
yuuji@253: FROM blog b
yuuji@253: JOIN
yuuji@254: (SELECT distinct blogid, a.id aid, max(val) ctime
yuuji@253: FROM article a, article_s s
yuuji@328: ON a.id=s.id AND a.author='$uname' AND s.key='ctime'
yuuji@253: GROUP BY blogid ORDER BY val DESC LIMIT 50
yuuji@253: ) m
yuuji@253: ON b.id=m.blogid;"
yuuji@328: # This should be as follows
yuuji@328: : <最近の書き込み先
yuuji@260:
yuuji@194: `DT_VIEW=replyblog dumptable html blog`
yuuji@194:
yuuji@194: EOF
yuuji@328: unset DT_SQL
yuuji@328: if [ x"$user" = x"$uname" ]; then
yuuji@81: # Display NEWS
yuuji@351: # 2016-06-26
yuuji@351: if [ x"`getpar readchk``getpar read`" = x"yesyes" ]; then
yuuji@351: acclog blog $blogreadflagrowid
yuuji@351: # echo "全部既読にしました" | html p
yuuji@175: fi
yuuji@351: # 2016-02-19 Counting NEWS without using dumptable.
yuuji@351: sql=`listnewblogsql "$user"`
yuuji@471: # echo "$sql" > tmp/listnew
yuuji@351: new10=`DT_SQL="$sql" DT_VIEW=replyblog dumptable html blog`
yuuji@81: cont=`echo "$new10"|grep "^
"|wc -l`
yuuji@81: cont=$((cont-1))
yuuji@81: err newcount=$cont
yuuji@81: if [ $cont -gt 0 ]; then
yuuji@260: #echo "全体の新着記事${cont}傑" | html h2
yuuji@340: cgi_radio foldtabs yes 'id="new10" accesskey="f"'
yuuji@428: echo "
'
yuuji@0: done
yuuji@0: echo ''
yuuji@0: }
yuuji@0: iconhref() (
yuuji@0: # $1=icon-file, $2=Href $3=title $4...=anchor
yuuji@326: data=`percenthex "$1"`
yuuji@326: ct=`file --mime-type - < "$1"|cut -d' ' -f2`
yuuji@356: ## err iconhref: \$1=$1 \$2=$2 \$3="$@"
yuuji@0: href=$2; title=$3; shift 3
yuuji@0: echo "$@"
yuuji@0: )
yuuji@0: iconhref2() (
yuuji@0: # $1=icon-file, $2=Href $3=title $4...=anchor
yuuji@0: src=$1
yuuji@0: href=$2; title=$3; shift 3
yuuji@0: echo "$@"
yuuji@0: )
yuuji@0: listentry() (
yuuji@246: # $1=user/group $2=SearchKeyword $3=condition(if any) $4=grprowid(if in grp)
yuuji@0: # Referring variable $iamowner=$grp to attach owner-request links
yuuji@356: ## err listentry: \$1=$1 \$2=$2 \$3=$3
yuuji@246: cond='' hiddens=''
yuuji@447: offset=`getpar offset`; offset=${offset%%[!0-9]*}
yuuji@447: if [ -z "$offset" ]; then
yuuji@447: offset=`getpar start`; offset=${offset%%[!0-9]*}
yuuji@447: offset=$((offset-1))
yuuji@447: fi
yuuji@0: offset=$((offset + 0)) # change to numeric forcibly
yuuji@0: [ $offset -lt 0 ] && offset=0
yuuji@0: limit=30
yuuji@78: dir=`getcachedir "$1"`
yuuji@0: if [ x"$1" = x"user" ]; then
yuuji@0: hrb="$myname?home"
yuuji@0: deficon=person-default.png
yuuji@246: entity="ユーザ" tbl=user link=rowid nm=name # stage=mems
yuuji@246: [ -n "$4" ] && hiddens=`cgi_hidden grid $4`
yuuji@33: gcs=gecos
yuuji@0: else # if group
yuuji@0: hrb="$myname?grp"
yuuji@22: deficon=group-default.png
yuuji@16: entity="グループ" tbl=grp link=rowid nm=gname stage=grps
yuuji@33: gcs=name
yuuji@0: tagline=`grep :tag: $formdir/grp.def|cut -d: -f5-`
yuuji@0: if [ -n "$tagline" ]; then
yuuji@0: tagconv=`echo $tagline|sed 's/\([^= :]*\)=\([^= :]*\)/-D\2=\1/g'`
yuuji@356: ## err tagconv=$tagconv
yuuji@0: fi
yuuji@0: fi
yuuji@0: if [ ! -d $dir ]; then
yuuji@0: mkdir -p $dir
yuuji@131: fi
yuuji@131: if [ ! -s $dir/$deficon ]; then
yuuji@0: convert -geometry $thumbxy $imgdir/$deficon $dir/$deficon
yuuji@0: fi
yuuji@0: if [ -n "$2" ]; then
yuuji@0: cond="where nick like '%$2%' or b.name like '%$2%'"
yuuji@0: fi
yuuji@0:
yuuji@0: # XX: これ複雑すぎるかな。もっとシンプルにしたい。$3条件も。2015-07-08
yuuji@33: # grpは呼出し元の動的スコープ変数でよくないな...
yuuji@33: ##qgrp=`sqlquote $grp`
yuuji@33: getgrp="(select gname from grp where rowid=${rowid:--1})"
yuuji@220: sql="select a.rowid, a.$link,
yuuji@220: coalesce(b.$gcs, a.$nm) as nick,
yuuji@388: quote(a.$nm) as qname,
yuuji@388: (SELECT val FROM ${tbl}_s
yuuji@388: WHERE $nm=a.$nm AND key='$iconcachekey') icon,
yuuji@220: coalesce(b.gecos, a.$nm) /* If group, concat (Nusers) */
yuuji@220: || case when a.$nm in (select gname from grp)
yuuji@220: then printf('(%d名)',
yuuji@220: (select count(user) from grp_mem where gname=a.$nm))
yuuji@233: else ' <'||a.$nm||'>'
yuuji@220: end
yuuji@220: as name,
yuuji@33: b.tag,
yuuji@13: case when a.$nm in (select user from grp_adm
yuuji@69: where gname=$getgrp) then '(管理者)'
yuuji@13: when '$user' in (select user from grp_adm where gname=a.$nm)
yuuji@13: then '(ADMIN)'
yuuji@171: when '$user' in (select user from grp_mem where gname=a.$nm)
yuuji@171: then '(Member)'
yuuji@13: when '$iamowner' = '' then ''
yuuji@259: else ',not='||a.rowid end as ownerlink,
yuuji@259: CASE '$entity'
yuuji@259: WHEN 'グループ'
yuuji@259: THEN coalesce(
yuuji@259: (SELECT val FROM grp_s WHERE gname=a.$nm AND key='regmode'),
yuuji@259: 'open')
yuuji@259: ||
yuuji@259: CASE WHEN '$user'
yuuji@259: IN (SELECT user FROM grp_mem WHERE gname=a.$nm)
yuuji@259: THEN ' ismember'
yuuji@259: ELSE ''
yuuji@259: END
yuuji@259: ELSE 'user'
yuuji@259: END regmode
yuuji@0: from $tbl a left join
yuuji@0: (select $nm as name,
yuuji@0: max(case key when 'gecos' then val end) as gecos,
yuuji@297: max(case key when 'tag' then val end) as tag,
yuuji@387: max(case key when 'mtime' then val end) as mtime,
yuuji@475: max(case key when 'wtime' then val end) as wtime,
yuuji@474: max(case key when 'login' then val end) as login
yuuji@0: from ${tbl}_s group by $nm)
yuuji@0: b on a.$nm=b.name $cond $3
yuuji@474: order by b.wtime desc, b.login desc,
yuuji@474: b.mtime desc, b.tag desc, a.rowid asc"
yuuji@297: # Give precedence to newer maintained groups (2016-09-24)
yuuji@297: # Note that mtime is stored only in grp_s.
yuuji@356: ## err LE:sql.1="$sql"
yuuji@0: total=`query "with x as ($sql) select count(*) from x;"`
yuuji@61: echo "${entity} 一覧" | html h2
yuuji@0: if [ $total -gt $limit ]; then
yuuji@0: echo '
yuuji@33: `cgi_hidden grp $rowid`
yuuji@0: EOF
yuuji@117: if [ x`getgroupattr $grp regmode` = x'moderated' -a -z "$ismem" ]; then
yuuji@117: echo "moderated (承認加入の)グループなので実際に参加できるのは
yuuji@117: グループ管理者が承認操作をした後になります。" | html p 'class="warn"'
yuuji@117: fi
yuuji@26: echo '
'
yuuji@0: echo '
話題一覧
'
yuuji@418: thelp="1ヶ月分のまとめには上部検索窓に @month と入れてください。"
yuuji@418: cat<<-EOF
yuuji@418:
yuuji@418: EOF
yuuji@60: cond="where a.id in (select id from blog_s where key='owner' and val=$qgrp) order by ctime desc"
yuuji@397: colstate="state:稼動状態:frozen=rowclass=凍結"
yuuji@0: DT_CHLD=article:blogid \
yuuji@371: DT_VIEW=replyblog dumptable html blog \
yuuji@438: "ctime title heading team notify:通知$colmd $colstate" "$cond"
yuuji@0:
yuuji@33: getgname="(select gname from grp where rowid=$rowid)"
yuuji@246: c="group by a.name having a.name in (select user from grp_mem where gname=$getgname)"
yuuji@33: cm="?commission+$rowid"
yuuji@246: thumbxy=50x50 listmember "" "$c" "$rowid" \
yuuji@153: |sed -e "s|\( \),not=\(.*\)|\1|" # 間違って押しやすい
yuuji@222: # team list
yuuji@222: hexteams=`hexteams "$grp"`
yuuji@222: if [ -n "$hexteams" ]; then
yuuji@222: echo "チーム一覧" | html h2
yuuji@222: echo '
'
yuuji@222: sq $db -html -header<<-EOF
yuuji@222: SELECT val TEAM,
yuuji@222: group_concat((SELECT gecos FROM gecoses WHERE name=user), ',')
yuuji@222: MEMBERS
yuuji@224: FROM grp_mem_m WHERE gname=$qgrp AND key='team' GROUP BY val;
yuuji@222: EOF
yuuji@222: echo '
'
yuuji@222: fi
yuuji@0: }
yuuji@288: grp_getbodyclass() {
yuuji@288: # Get css class name for document.
yuuji@288: # `moderated' for moderated groups
yuuji@288: # `ismember' for groups where user belongs
yuuji@288: # $1=GroupName (w/o quote)
yuuji@288: # $user=userNameCurrentlyLogin
yuuji@356: ## err grp_getbodyclass: 1="$1"
yuuji@288: qgrp=`sqlquote "$1"`
yuuji@288: query<<-EOF
yuuji@288: SELECT coalesce(
yuuji@288: (SELECT val FROM grp_s WHERE gname=$qgrp AND key='regmode'),
yuuji@288: 'open')
yuuji@288: ||
yuuji@288: CASE WHEN '$user'
yuuji@288: IN (SELECT user FROM grp_mem WHERE gname=$qgrp)
yuuji@288: THEN ' ismember'
yuuji@288: ELSE ''
yuuji@288: END;
yuuji@288: EOF
yuuji@288: }
yuuji@59: grpaction() { # $1=group-rowid
yuuji@79: err GRP_ACTION:IN
yuuji@79: grid=${1:-`getpar grp`}
yuuji@79: grp=`getgroupbyid "$grid"`
yuuji@79: if [ -z "$grp" ]; then
yuuji@118: echo "無効な指定です。" | html p; return
yuuji@118: fi
yuuji@433: if ! ismember $user "$grp"; then
yuuji@118: echo "加入者のみに許可された操作です。" | html p; return
yuuji@79: fi
yuuji@81: echo "グループ $grp 個別選択操作" \
yuuji@288: | _m4 -D_TITLE_="syscmd(\`cat')" \
yuuji@288: -D_BODYCLASS_="`grp_getbodyclass \"$grp\"`" \
yuuji@288: $layout/html.m4.html
yuuji@79:
yuuji@117: isowner=""
yuuji@117: isgrpowner "$user" "$grp" && isowner="yes"
yuuji@59: usel=`getpar usel`
yuuji@59: if [ -n "$usel" ]; then
yuuji@59: uids=$(echo `echo $usel`|tr ' ' ',')
yuuji@356: ## err grpaction-1: grp=$grp, `echo $sql`
yuuji@59: text=`getpar text`
yuuji@59:
yuuji@59: rm=`getpar rm` cfm=`getpar confirm`
yuuji@356: ## err rm=$rm cfm=$cfm
yuuji@59: if [ x"$rm" = x"yes" ]; then
yuuji@117: if [ "$isowner" ]; then
yuuji@59: if [ x"$rm$cfm" = x"yesyes" ]; then
yuuji@59: # Eliminate
yuuji@59: cond="where gname=(select gname from grp where rowid=$grid) and user in (select name from user where rowid in ($uids))"
yuuji@59: for tbl in grp_mem grp_mem_s grp_mem_m; do
yuuji@59: sql="delete from $tbl $cond;"
yuuji@59: # echo "sql=$sql"
yuuji@59: query "$sql"
yuuji@59: err rmGRPuser "$sql"
yuuji@59: done
yuuji@59: num=`query "select count(*) from user where rowid in ($uids);"`
yuuji@59: #err num=$num
yuuji@59: if [ 0$num -gt 0 ]; then
yuuji@59: sql="select coalesce(b.val,a.name) from user a left join \
yuuji@59: user_s b on a.name=b.name and key='gecos' where a.rowid in ($uids);"
yuuji@59: # err `echo "$sql"`
yuuji@59: html pre<@'`
yuuji@300: myuid=`query "SELECT rowid FROM user WHERE name='$user';"`
yuuji@300: fromad=`email4groupbyuid "$grp" "$myuid"`
yuuji@300: mail_from="$safegc <$fromad>"
yuuji@300: else
yuuji@300: mail_from="$admin"
yuuji@300: fi
yuuji@300: MAIL_FROM=$mail_from \
yuuji@300: smail "`email4groupbyuid "$grp" $usel` $user" \
yuuji@300: "$gecos さんからのメッセージ" <"
yuuji@490: to_input=""
yuuji@492: fromtonote="
POST集計: $from_input - $to_input
"
yuuji@59: # New entry
yuuji@435: sql="WITH mems AS (
yuuji@435: SELECT g.rowid, name, gecos FROM grp_mem gm LEFT JOIN gecoses g
yuuji@435: ON gm.user=g.name
yuuji@435: WHERE gname=(SELECT gname FROM grp WHERE rowid=$grid)
yuuji@490: ), target_article AS (
yuuji@490: SELECT id FROM article_s
yuuji@490: WHERE key='ctime' AND val BETWEEN '${from:-0000}' AND '${to:-9999}'
yuuji@435: ), posts AS (
yuuji@435: SELECT author, count(author) post
yuuji@490: FROM article NATURAL JOIN article_s NATURAL JOIN target_article
yuuji@435: WHERE blogid IN (SELECT id FROM blog_s
yuuji@435: WHERE key='owner'
yuuji@435: AND val=(SELECT gname FROM grp WHERE rowid=$grid))
yuuji@435: AND key='text'
yuuji@435: GROUP BY author
yuuji@435: ), teams AS (
yuuji@435: SELECT user, group_concat(val, ', ') team
yuuji@435: FROM grp_mem_m
yuuji@435: WHERE gname=(SELECT gname FROM grp WHERE rowid=$grid)
yuuji@435: AND key='team'
yuuji@435: GROUP BY user
yuuji@435: ), user_post AS (
yuuji@435: SELECT m.rowid, name, m.gecos, coalesce(post, 0) as POST
yuuji@435: FROM mems m LEFT JOIN posts
yuuji@435: ON m.name=posts.author
yuuji@435: GROUP by m.rowid
yuuji@435: )
yuuji@435: SELECT
yuuji@435: CASE
yuuji@435: WHEN (SELECT user FROM grp_adm
yuuji@435: WHERE gname=(SELECT gname FROM grp WHERE rowid=$grid)
yuuji@435: AND user=up.name) IS NOT NULL
yuuji@435: then 'k'
yuuji@435: ELSE ''
yuuji@435: END || rowid || ',' || gecos NAME,
yuuji@435: post POST, team TEAM
yuuji@435: FROM user_post up LEFT JOIN teams t
yuuji@435: ON up.name=t.user
yuuji@435: ORDER BY gecos;"
yuuji@356: ## err grpaction: "`echo \"$sql\"`"
yuuji@81: tf=$tmpd/title.$$
yuuji@291: echo "グループ[$grp]参加メンバーに対する操作" > $tf
yuuji@291: cmmsg="`cgi_radio rm commission id=\"cmadmin\"`
yuuji@153:
"
yuuji@222: # Get team list to which current user belongs into $hexteams
yuuji@222: myhexteams=$(hexteams "$grp" "$user")
yuuji@222: allhexteams=$(hexteams "$grp")
yuuji@227: if [ -n "$myhexteams" ]; then
yuuji@291: rmteammsg="`cgi_radio rm rmteam 'id=\"cmrmteam\"'`
yuuji@228: