# HG changeset patch # User HIROSE Yuuji # Date 1387611200 -32400 # Node ID 48afc00ef5df22cecf204b4dac1dc0996d6f7c60 # Parent 00d203e72f8fcd8ba8a084d0383fcf0c4f0507ef Add filtering feature to schedule listing diff -r 00d203e72f8f -r 48afc00ef5df after5.rb --- a/after5.rb Thu Dec 19 12:09:58 2013 +0900 +++ b/after5.rb Sat Dec 21 16:33:20 2013 +0900 @@ -4,7 +4,7 @@ # Associative Scheduling Table - after5 # (C)2003, 2004, 2006, 2008, 2012, 2013 by HIROSE Yuuji [yuujigentei.org] # $Id: after5.rb,v 1.20 2012/12/03 15:54:20 yuuji Exp $ -# Last modified Thu Dec 19 12:09:19 2013 on firestorm +# Last modified Sat Dec 21 16:24:53 2013 on firestorm # See http://www.gentei.org/~yuuji/software/after5/ # このスクリプトはEUCで保存してください。 $hgid = <<_HGID_.split[1..-2].join(" ") @@ -108,7 +108,7 @@ name, value, text end def submit_reset(name) - submit(name, "GO")+reset(name, "Reset") + submit(name, "OK")+reset(name, "Reset") end def select(name, range, selected=nil) @@ -634,11 +634,14 @@ def name2group(name) @groupmap.find{|g, v| v.is_a?(Hash) && v['name']==name} end - def day_all(d, user=nil, personalonly = nil) + def day_all(d, user=nil, personalonly = nil, filter) y, m, d = d.scan(%r,(\d\d\d\d+)/(\d+)/(\d+),)[0] #daydir = File.join(@dir, "%04d"%y.to_i, "%02d"%m.to_i, "%02d"%d.to_i) daydir = File.join("s", "%04d"%y.to_i, "%02d"%m.to_i, "%02d"%d.to_i) sched = {} + grep = if filter && filter > '' + Regexp.new(filter.split(/\s+/).join("|")) + end return sched unless test(?d, daydir) Dir.foreach(daydir) {|time| next if /^\./ =~ time @@ -653,19 +656,19 @@ visible = false #next unless /@/ =~ who # user must be as user@do.ma.in next unless account_exists(who) - ## next if personalonly && who != user #2004/1/16 + ## next if private && who != user #2004/1/16 who.untaint dir = File.join(t, who) next unless test(?d, dir) && test(?x, dir) pub = File.join(dir, 'pub') if test(?f, pub) && test(?r, pub) && test(?s, pub) && - !personalonly # unneccessary if personal mode + !personalonly # unneccessary if personalonly mode if IO.readlines(pub)[0].to_i > 0 visible = true end end + next if grep && (grep !~ who && grep !~ nickname(who)) # 2013/12/19 - if ismember(user, who) || visible sched[time][who] = {} file = File.join(dir, @schedulefile) @@ -1117,7 +1120,7 @@ @mailmode = nil @mailadmdelimiter = "/" @mailadmsuffix = @mailadmdelimiter + "adm" - @saveprefsregexp = /^(display(mode|days)$|nt|headline)/ + @saveprefsregexp = /^(display(mode|days|filter)$|nt|headline)/ @opt = { 'conf' => @mybase+".cf", 'css' => @mybase+".css", @@ -1182,7 +1185,7 @@ p @params if $DEBUG ### @params['displaymode'] = @params['displaymode'] || @cookie['displaymode'] - personal = /personal/i =~ @params['displaymode'] + personal = /^personal/i =~ @params['displaymode'] bodyclass = if personal then {'class'=>'personal'} end ## x = {"align"=>'center'} @@ -1380,6 +1383,11 @@ 'head5char' => ['先頭5文字', 'Head 5 chars'], 'headline' => ['先頭1行', 'Headline only'], 'whole' => ['長くても全部', 'Whole text'], + 'filter' => ['登録者絞込', 'Selection by Registerer'], + 'filterhelp' => ['表示する予定を登録者アカウント名(の一部)で絞り込みできる。 +2つ以上の名前で絞りたいときはスペースで区切ればOK。', 'Can filter by (a part of)account name. +Multiple patterns delimited by spaces are acceptable.'], + 'filterreset' => ['絞込解除', 'Reset Selection'], 'hldays' => ['最新X日分強調', 'Hilight Recent X-days'], 'addedtogroup' => ['をグループに追加 →', 'added to the group:'], 'removedfromgp' => ['をグループから削除:', 'removed from the group:'], @@ -1402,7 +1410,7 @@ 'Though you are not member of group A, you are treated as a member of A, if you join to the group B, which is a member of A. Think the nesting of groups carefully, please. Group administrator can change the group nickname.'], 'address2send' => ['自分が参加しているグループのメンバーリストの先頭が自分。その直後にある入力欄には、そのML宛メッセージをどの宛先に配送するかを入れられる。そう、MLごとに自分への配送先を変えられるよ。', 'The first entry of member list of a group to which you belongs, is you. Entry box just after your name is for address list you want to deliver messages to that ML. Thus, you can define different addresses for each ML.'], - 'skip:' => ['MLへの送信専用メイルアドレスは、アドレスの前に空白入れずに skip: を付けて登録できるよ(例: skip:hoge@example.com。ML登録メンバーのみの投稿を許すMLに書いてエラーを食らったときには、投稿アドレスを skip: つきで登録しとくとええよ。', "You can prefix `skip:' without any blanks to email address to register POST-ONLY address for the ML(eg. skip:you@example.com). When you get rejecting message from ML which allows only members to post, try to add POST-ONLY address to your email addresses entry of that group."], + 'skip:' => ['MLへの送信専用メイルアドレスは、アドレスの前に空白入れずに skip: を付けて登録できるよ(例: skip:hoge@example.com。ML登録メンバーのみの投稿を許すMLに送信して拒否メッセージを食らったときには、その送信アドレスを skip: つきで登録しとくとええよ。', "You can prefix `skip:' without any blanks to email address to register POST-ONLY address for the ML(eg. skip:you@example.com). When you get rejecting message from ML which allows only members to post, try to add POST-ONLY address to your email addresses entry of that group."], 'wholemembers' => ['グループ内グループを考慮した上で、現在グループ %s への通知は以下のメンバーに送られる。', "Consiering the groups registered in another group, notification to the group `%s' is send to members as follows."], 'noadmingroup' => ['管理できるグループはないっす', @@ -1822,7 +1830,7 @@ me = @myname+"?-"; delim = " / " @H.a(me+'userman', msg('user', 'management')) + delim + \ @H.a(me+'groupman', msg('group', 'management')) + delim + \ - if /personal/i =~ @params['displaymode'] + if /^personal/i =~ @params['displaymode'] @H.a(me+'today_n', msg('normalmode')) else @H.a(me+'today_p', msg('personalmode')) @@ -1845,6 +1853,23 @@ def footer() footer1+footer2 end + def header_filter() + filter = @params['displayfilter'] + if filter && filter > "" + myarg = (ENV['REQUEST_URI']||"-today").sub(/.*\?/, "") + @H.elementln("form", {'action'=>@myname+"?"+myarg, "method"=>"POST"}) { + @H.elementln("p", {"class"=>"filter"}) { + @H.element("span") { + msg('filter')+"="+filter + } + \ + @H.hidden("displayfilter", "") + \ + @H.submit("GO", msg('filterreset')) + } + } + else + "" + end + end def nickname(userORgroup) if grepgroup(userORgroup) @sc.groupname(userORgroup) @@ -1874,16 +1899,19 @@ personal = /personal/ =~ @params['displaymode'] headline = @params['headline'] headlinehl = @params['headlinehl'] + filter = @params['displayfilter'] hldays = headlinehl.to_i * 3600*24 recent = {'class'=>'recent'} monthstr = sprintf "%d/%d", day.year, day.month + holiday = Holiday.new # create dayofweek header @O.print @H.elementln("h1", nil){monthstr} # which mode? @O.print @H.p(msg(personal ? 'personalmode' : 'normalmode')) - # + # @O.print @H.p(sprintf("filter=%s", filter)) + @O.print header_filter() # display table @O.print @H.startelement("table", {'border'=>"1", 'class'=>'main'}) @@ -1918,7 +1946,7 @@ @H.element("small"){hd.join("
")} end.to_s + \ @H.element("p", {'class'=>'topic'}){ - s = @sc.day_all(date, @params['user'], personal) + s = @sc.day_all(date, @params['user'], personal, filter) if !s.empty? s.keys.sort.collect{|time| s[time].keys.sort.collect{|who| @@ -1990,6 +2018,8 @@ @H.select('headline', choice, headline) + "/" + \ msg('hldays') + \ @H.select('headlinehl', 0..30, headlinehl) + \ + @H.element("abbr", {"title"=>msg('filterhelp')}) {msg('filter')} + \ + @H.text('displayfilter', @params['displayfilter'], 10, 80) +\ @H.submit("GO", "GO") } @O.print footer @@ -2015,7 +2045,7 @@ end # # Return the string of table - def dayTableString(user, datestr, range, personal = nil) + def dayTableString(user, datestr, range, personal = nil, filter = nil) #s = @sc.day_all(date, user, personal) #return '' if s.empty? r = '' @@ -2029,7 +2059,7 @@ datewn = @H.element("span", {'class'=>@wnames[d.wday]}){ sprintf("%s(%s)", date, @msg['wnames'][@lang][d.wday]) } - s = @sc.day_all(date, user, personal) + s = @sc.day_all(date, user, personal, filter) next if s.empty? r << @H.element("tr", nil){ @@ -2105,7 +2135,7 @@ '' end end - def dayTextString(user, datestr, range, personal = nil) + def dayTextString(user, datestr, range, personal = nil, filter = nil) r = '' cols = 20 header = "-" * cols + "\n" @@ -2116,7 +2146,7 @@ d = Time.at(day+i*3600*24) date = sprintf("%04d/%02d/%02d", d.year, d.month, d.day) datewn = sprintf("%s(%s)", date, @msg['wnames'][@lang][d.wday]) - s = @sc.day_all(date, user, personal) + s = @sc.day_all(date, user, personal, filter) next if s.empty? r << sprintf("TIME Who %s - What\n", datewn) @@ -2279,19 +2309,20 @@ return nil end user = safecopy(@params['user']) - personal = (/personal/i =~ @params['displaymode']) + personal = (/^personal/i =~ @params['displaymode']) @params['displaydays'] = @params['displaydays'] || @cookie['displaydays'] + filter = @params['displayfilter'] days = @params['displaydays'].to_i days = (days > 0 ? days : 3) - # str = @sc.day_all(date, user, personal) - outstr = dayTableString(user, date, days, personal) + outstr = dayTableString(user, date, days, personal, filter) @O.print @H.element("h1", nil){ sprintf msg('fmtdaysschedule'), date } @O.print @H.element("h2"){msg('schedtable')} ## @O.print @H.p() + @O.print header_filter() @O.print @H.elementln("form", {'action'=>@myname+"?-show+#{date}", 'method'=>'POST'}){ @H.elementln("p"){ msg(personal ? 'personalmode' : 'normalmode') + "
" + \ @@ -3091,7 +3122,7 @@ @H.elementln("tr"){ @H.element("td"){"Attachment"} + \ @H.element("td"){ - @H.element("input", "name"=>"attachment", "type"=>"file", 'multiple'=>true){} + "" } } + \ @H.elementln("tr"){ @@ -3192,10 +3223,10 @@ } } } + \ - "
\n" + @H.submit_reset("GO") + "
\n" + @H.element("span", "class"=>"danger"){@H.submit_reset("OK")} } - + @O.print footer() end def usermod() if !checkauth @@ -3644,7 +3675,7 @@ } } } + \ - "
\n" + @H.submit_reset("GO") + "
\n" + @H.element("span", "class"=>"danger"){@H.submit_reset("OK")} } @O.print footer()