Mercurial > hgrepos > hgweb.cgi > after5
annotate after5.rb @ 100:43b6e8c1272c draft
add README.md
author | HIROSE Yuuji <yuuji@gentei.org> |
---|---|
date | Wed, 21 Aug 2019 10:20:51 +0900 |
parents | 5e30d1645411 |
children | d765239327e0 |
rev | line source |
---|---|
93 | 1 #!/usr/local/bin/ruby21 |
16 | 2 # -*- coding: euc-jp -*- |
0 | 3 # |
4 # Associative Scheduling Table - after5 | |
93 | 5 # (C)2003, 2004, 2006, 2008, 2012-2014 by HIROSE Yuuji [yuuji<at>gentei.org] |
76
53e747495502
Bug-fix: Regexp matching should be done in euc-jp.
HIROSE Yuuji <yuuji@gentei.org>
parents:
75
diff
changeset
|
6 # $Id: after5.rb,v 1.20 2012/12/03 15:54:20 yuuji Exp $ |
98
5e30d1645411
Enclose checkbutton with label element
HIROSE Yuuji <yuuji@gentei.org>
parents:
96
diff
changeset
|
7 # Last modified Wed Aug 21 09:57:32 2019 on firestorm |
0 | 8 # See http://www.gentei.org/~yuuji/software/after5/ |
9 # このスクリプトはEUCで保存してください。 | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
10 $hgid = <<_HGID_.split[1..-2].join(" ") |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
11 $HGid$ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
12 _HGID_ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
13 $myurl = "http://www.gentei.org/~yuuji/software/after5/" |
0 | 14 |
15 require 'kconv' | |
17 | 16 require 'nkf' |
0 | 17 |
18 $charset = 'EUC-JP' | |
19 | |
20 class HTMLout | |
21 def contenttype(type = "text/html", charset = $charset) | |
22 sprintf "Content-type: %s; charset=%s\n\n", type, charset | |
23 end | |
24 def initialize(title = "Document") | |
25 @title = title | |
26 @eltstack = [] | |
27 end | |
28 def resetstack() | |
29 @eltstack = [] | |
30 end | |
31 def head(title = @title, css = "style.css") | |
32 sprintf <<__EOS__, title, css | |
33 <html> | |
34 <head> | |
35 <title>%s</title> | |
36 <link rel="stylesheet" type="text/css" href="%s"> | |
37 </head> | |
38 __EOS__ | |
39 end | |
40 | |
41 def startelement(elt, attrs = {}, nl = true) | |
42 attr = "" | |
43 if attrs.is_a?(Hash) | |
44 for k in attrs.keys | |
45 attr += " %s=\"%s\"" % [k, attrs[k]] | |
46 end | |
47 end | |
48 @eltstack.push(elt) | |
49 sprintf "<%s%s>%s", elt, attr, nl ? "\n" : "" | |
50 end | |
51 def endelement(elt = nil, nl = true) | |
52 if elt | |
53 x = elt | |
54 @eltstack.pop | |
55 else | |
56 x = @eltstack.pop | |
57 end | |
58 sprintf "</%s>%s", x, nl ? "\n" : "" | |
59 end | |
60 def element(elt, attrs = nil, nl = nil) | |
61 attr = "" | |
62 lf = nl ? "\n" : "" | |
63 if attrs.is_a?(Hash) | |
64 for k in attrs.keys | |
85 | 65 attr += " %s=\"%s\"" % [k, attrs[k]] |
0 | 66 end |
67 end | |
68 body = yield | |
69 sprintf "<%s%s>%s%s%s</%s>%s", elt, attr, lf, body, lf, elt, lf | |
70 end | |
71 def elementln(elt, attr=nil) | |
72 body = yield | |
73 element(elt, attr, true){body} | |
74 end | |
75 def a(href, anchor = nil, attrs = {}) | |
76 attr = attrs | |
77 attr['href'] = href | |
78 element("a", attr){ | |
79 anchor or href | |
80 } | |
81 end | |
82 def p(msg, attrs=nil) | |
83 element("p", attrs){msg} | |
84 end | |
85 def text(name, value='', size=nil, maxlength=nil) | |
86 sprintf "<input type=\"text\" name=\"%s\" value=\"%s\"%s%s>", | |
87 name, value, | |
88 size ? " size=\"%s\""%size.to_s : '', | |
89 maxlength ? " maxlength=\"%s\""%maxlength.to_s : '' | |
90 end | |
91 def hidden(name, value='') | |
92 sprintf "<input type=\"hidden\" name=\"%s\" value=\"%s\">", name, value | |
93 end | |
94 def radio(name, value, text='', checked=nil) | |
98
5e30d1645411
Enclose checkbutton with label element
HIROSE Yuuji <yuuji@gentei.org>
parents:
96
diff
changeset
|
95 sprintf "%s<input type=\"radio\" name=\"%s\" value=\"%s\"%s>%s%s", |
5e30d1645411
Enclose checkbutton with label element
HIROSE Yuuji <yuuji@gentei.org>
parents:
96
diff
changeset
|
96 "<label>", name, value, checked ? " checked" : "", text, "</label>" |
0 | 97 end |
98 def checkbox(name, value, text='', checked=nil) | |
98
5e30d1645411
Enclose checkbutton with label element
HIROSE Yuuji <yuuji@gentei.org>
parents:
96
diff
changeset
|
99 sprintf "%s<input type=\"checkbox\" name=\"%s\" value=\"%s\"%s>%s%s", |
5e30d1645411
Enclose checkbutton with label element
HIROSE Yuuji <yuuji@gentei.org>
parents:
96
diff
changeset
|
100 "<label>", name, value, checked ? " checked" : "", text, "</label>" |
0 | 101 end |
102 def submit(name, value, text='') | |
103 sprintf "<input type=\"submit\" name=\"%s\" value=\"%s\">%s\n", | |
104 name, value, text | |
105 end | |
106 def reset(name, value, text='') | |
107 sprintf "<input type=\"reset\" name=\"%s\" value=\"%s\">\n", | |
108 name, value, text | |
109 end | |
110 def submit_reset(name) | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
111 submit(name, "OK")+reset(name, "Reset") |
0 | 112 end |
113 | |
2 | 114 def select(name, range, selected=nil) |
115 #start = (b<e ? b : e) | |
116 #last = (b>e ? b : e) | |
117 c=0 | |
0 | 118 "<select name=\"#{name}\">\n" + \ |
2 | 119 range.collect{|i| |
3 | 120 value = (i.is_a?(Array) ? i[1] : i).to_s |
121 sprintf "<option%s%s>%s%s</option>", | |
122 (selected.to_s==value.to_s) ? " selected" : "", | |
123 i.is_a?(Array) ? " value=\"%s\"" % value : '', | |
124 i.is_a?(Array) ? i[0] : i.to_s, | |
2 | 125 (c+=1)%6==0 ? "\n" : '' |
0 | 126 }.join + \ |
127 "\n</select>\n" | |
128 end | |
129 end | |
14 | 130 class TEXTout |
131 def isBlock(elt) | |
132 /\b(tr|[udo]l|p|div)\b/i =~ elt | |
133 end | |
134 def isEOC(elt) | |
135 /\bt[dh]\b/i =~ elt | |
136 end | |
137 def eoelem(elt) | |
138 r = "" | |
139 r << "\n" if isBlock(elt) | |
140 r << " " if isEOC(elt) | |
141 r | |
142 end | |
143 def contenttype(type = "text/plain", charset = $charset) | |
144 ### sprintf "Content-type: %s; charset=%s\n\n", type, charset | |
145 "" | |
146 end | |
147 def initialize(title = "Document") | |
148 @title = title | |
149 @eltstack = [] | |
150 end | |
151 def resetstack() | |
152 @eltstack = [] | |
153 end | |
154 def head(title = @title, css = "style.css") | |
155 sprintf <<__EOS__, title, css | |
156 ===== [[[ %s ]]] ===== | |
157 __EOS__ | |
158 end | |
159 | |
160 def startelement(elt, attrs = {}, nl = true) | |
161 attr = "" | |
162 x = sprintf "%s", " "*@eltstack.length | |
163 @eltstack.push(elt) | |
164 x | |
165 end | |
166 def endelement(elt = nil, nl = true) | |
167 if elt | |
168 x = elt | |
169 @eltstack.pop | |
170 else | |
171 x = @eltstack.pop | |
172 end | |
173 eoelem(x) | |
174 end | |
175 def element(elt, attrs = nil, nl = nil) | |
176 attr = "" | |
177 lf = nl ? "\n" : "" | |
178 body = yield | |
179 #sprintf "<%s%s>%s%s%s</%s>%s", elt, attr, lf, body, lf, elt, lf | |
180 sprintf "%s%s", body, eoelem(elt) | |
181 end | |
182 def elementln(elt, attr=nil) | |
183 body = yield | |
184 sprintf "%s\n", body | |
185 end | |
186 def a(href, anchor = nil, attrs = {}) | |
187 attr = attrs | |
188 attr['href'] = href | |
189 # sprintf "%s\n", href | |
190 anchor | |
191 end | |
192 def p(msg, attrs=nil) | |
193 element("p", attrs){msg} | |
194 end | |
195 def text(name, value='', size=nil, maxlength=nil) | |
196 "" | |
197 end | |
198 def hidden(name, value='') | |
199 "" | |
200 end | |
201 def radio(name, value, text='', checked=nil) | |
202 "" | |
203 end | |
204 def checkbox(name, value, text='', checked=nil) | |
205 "" | |
206 end | |
207 def submit(name, value, text='') | |
208 "" | |
209 end | |
210 def reset(name, value, text='') | |
211 "" | |
212 end | |
213 def submit_reset(name) | |
214 "" | |
215 end | |
216 def select(name, range, selected=nil) | |
217 "" | |
218 end | |
219 end | |
0 | 220 |
221 class PasswdMgr | |
222 def initialize(name, mode=0640) | |
223 require 'dbm' | |
224 @pdb = DBM.open(name, mode) | |
225 end | |
226 def checkpasswd(user, passwd) | |
227 if @pdb[user] then | |
228 @pdb[user] == passwd.crypt(@pdb[user]) | |
229 end | |
230 end | |
231 def setpasswd(user, passwd) | |
232 salt = [rand(64),rand(64)].pack("C*").tr("\x00-\x3f","A-Za-z0-9./") | |
233 @pdb[user] = passwd.crypt(salt) | |
234 end | |
235 def userexist?(user) | |
236 @pdb[user] ? true : false | |
237 end | |
238 def getpasswd(user) | |
239 @pdb[user] | |
240 end | |
241 def delete(user) | |
242 @pdb.delete(user) | |
243 end | |
244 def close() | |
245 @pdb.close() | |
246 end | |
247 def newpasswd(length) | |
61
502103680ea2
Call srand() without parameter.
HIROSE Yuuji <yuuji@gentei.org>
parents:
60
diff
changeset
|
248 srand() |
0 | 249 left = "qazxswedcvfrtgb12345" |
250 right = "yhnmjuik.lop;/67890-" | |
251 array = [left, right] | |
252 (1..length).collect{|i| | |
253 a = array[i%array.length] | |
254 a[rand(a.length), 1] | |
255 }.join('') | |
256 end | |
257 def users() | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
258 @pdb.keys.collect{|u| u.toeuc} # toeuc is for 1.9 :( |
0 | 259 end |
260 private :newpasswd | |
261 def setnewpasswd(user, length=8) | |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
262 length = length.to_i |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
263 length = 4 if length < 4 |
0 | 264 newp = newpasswd(length) |
265 setpasswd(user, newp) | |
266 newp | |
267 end | |
268 end | |
269 | |
270 class ScheduleDir | |
271 def initialize(dir = "s") | |
272 @dir = dir | |
273 @schedulefile = "sched" | |
274 @usermapdir = File.join(@dir, "usermap") | |
275 @usermap = mkusermap() | |
276 @groupmapdir = File.join(@dir, "groupmap") | |
277 @groupmap = mkgroupmap() | |
278 @crondir = File.join(@dir, "crondir") | |
279 | |
280 end | |
281 def mkusermap() | |
282 map = {} | |
283 unless test(?d, @usermapdir) | |
55
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
284 mkdir_p(@usermapdir, 0750) |
0 | 285 end |
286 Dir.foreach(@usermapdir){|u| | |
287 next if /^\./ =~ u | |
288 newu = '' | |
289 u.split('').each{|c| # for security wrapping | |
12 | 290 newu << c[0].chr if %r,[-A-Z0-9/+_.@],i =~ c |
0 | 291 } |
292 u = newu | |
293 map[u] = {} | |
17 | 294 d = File.join(@usermapdir, u).untaint |
0 | 295 next unless test(?d, d) |
296 Dir.foreach(d){|attr| | |
297 next if /^\./ =~ attr | |
12 | 298 attr.untaint if /^[A-Z_][-A-Z_0-9]*$/i =~ attr |
17 | 299 file = File.join(@usermapdir, u, attr).untaint |
0 | 300 next unless test(?s, file) && test(?r, file) |
17 | 301 map[u][attr] = IO.readlines(file).join.toeuc.strip |
0 | 302 } |
303 } | |
304 map | |
305 end | |
87 | 306 def ismembersemail(email, grp = nil) |
69
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
307 @usermap.keys.each {|u| |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
308 return u if u==email |
87 | 309 return u if mailaddress(u, grp).split(/,\s*|\s+/).collect{|m| |
310 m.sub(/^(skip|off):/i, "") | |
311 }.grep(email)[0] | |
69
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
312 } |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
313 nil |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
314 end |
0 | 315 def putuserattr(user, attr, text) |
316 # if text==nil, remove it | |
317 d = File.join(@usermapdir, user) | |
318 Dir.mkdir(d) unless test(?d, d) | |
319 file = File.join(d, attr) | |
320 begin | |
2 | 321 unless @usermap[user] |
322 @usermap[user] = {} | |
323 mkdir_p(d) unless test(?d, d) | |
324 end | |
0 | 325 @usermap[user][attr] = text |
326 if text==nil | |
327 File.unlink(file) | |
328 else | |
329 open(file, "w"){|w| w.puts @usermap[user][attr]} | |
330 end | |
331 rescue | |
332 return nil | |
333 end | |
334 return {attr => text} | |
335 end | |
336 def getuserattr(user, attr) | |
337 # Should we distinguish between attribute is nil and "" ? | |
338 if @usermap.has_key?(user) && @usermap[user][attr].is_a?(String) && | |
339 @usermap[user][attr] > '' | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
340 return @usermap[user][attr].untaint |
0 | 341 else |
342 return nil | |
343 end | |
344 end | |
345 | |
346 def nickname(user) | |
347 if @usermap.has_key?(user) && @usermap[user]['name'].is_a?(String) && | |
348 @usermap[user]['name'] > '' | |
349 return @usermap[user]['name'] | |
350 else | |
351 return user.sub(/@.*/, '') | |
352 end | |
353 end | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
354 def mailaddress(user, grp = nil) |
87 | 355 grp ? \ |
356 mail4grp(user, grp) : \ | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
357 (getuserattr(user, 'email') || user) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
358 end |
0 | 359 def setnickname(user, nickname) |
360 putuserattr(user, 'name', nickname) | |
361 end | |
362 | |
363 # | |
364 # make group map | |
365 def collectmembers(gname) | |
366 @visitedgroup=[] unless @visitedgroup | |
367 return [] unless @visitedgroup.grep(gname).empty? | |
368 @visitedgroup.push(gname) | |
36
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
369 mdir = File.join(@groupmapdir, gname, 'members').untaint |
0 | 370 return [] unless test(?d, mdir) |
371 members = [] | |
372 Dir.foreach(mdir){|item| | |
373 next if /^\./ =~ item | |
374 item.untaint | |
375 next unless test(?f, File.join(mdir, item)) | |
376 if /.+@.+/ =~ item | |
377 members << item | |
378 else | |
379 members += collectmembers(item) | |
380 end | |
381 } | |
382 @visitedgroup.pop | |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
383 members.uniq |
0 | 384 end |
385 def mkgroupmap() | |
386 map = {} | |
387 return map unless test(?d, @groupmapdir) | |
388 @visitedgroup = [] | |
389 Dir.foreach(@groupmapdir){|g| | |
390 next if /^\./ =~ g | |
391 newg = '' | |
392 next unless /^[-a-z0-9_.]+$/i =~ g | |
393 #g.untaint ## untaintじゃだめだ。map{g} のkeyがtaintedになっちゃうよ | |
394 gg = '' # for security wrapping | |
395 g.split('').each{|c| gg << c[0].chr if c != '`'} | |
396 g = gg | |
397 map[gg] = {} | |
17 | 398 d = File.join(@groupmapdir, g).untaint |
0 | 399 next unless test(?d, d) |
400 # get group name | |
17 | 401 gnf = File.join(d, 'name').untaint |
0 | 402 if test(?r, gnf) && test(?s, gnf) |
17 | 403 n = IO.readlines(gnf)[0].to_s.toeuc.strip |
0 | 404 map[g]['name'] = if n > '' then n else g end |
405 else | |
406 map[g]['name'] = g | |
407 end | |
408 # get administrators | |
409 # | |
17 | 410 gad = File.join(d, 'admin').untaint |
0 | 411 map[g]['admin'] = [] |
412 if test(?d, gad) | |
413 Dir.foreach(gad){|a| | |
414 # administrator should be a person (not group) | |
415 next unless /@/ =~ a | |
416 map[g]['admin'] << a | |
417 } | |
418 end | |
419 # collect members | |
420 #map[g]['members'] = collectmembers(g) | |
17 | 421 memd = File.join(d, 'members').untaint |
0 | 422 map[g]['members'] = [] |
423 if test(?d, memd) | |
424 Dir.foreach(memd){|a| | |
425 next if /^\./ =~ a | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
426 map[g]['members'] << a.untaint |
0 | 427 } |
428 end | |
47 | 429 # get other attributes |
430 Dir.foreach(d) {|attr| | |
431 next if /^\./ =~ attr | |
432 next unless /^[-_a-z]+$/i =~ attr | |
433 next if attr == "name" # already collected | |
434 attr.untaint | |
435 file = File.join(d, attr) #.untaint | |
436 next if test(?d, file) | |
437 next unless test(?s, file) && test(?r, file) | |
438 map[g][attr] = IO.readlines(file).join.toeuc.strip | |
439 } | |
0 | 440 } |
441 map | |
442 end | |
47 | 443 def putgroupattr(group, attr, value) |
444 d = File.join(@groupmapdir, group).untaint | |
445 Dir.mkdir(d) unless test(?d, d) | |
446 file = File.join(d, attr) | |
447 begin | |
448 unless @groupmap[group] | |
449 @groupmap[group] = {} | |
450 end | |
451 @groupmap[group][attr] = value | |
452 if value == nil | |
453 File.unlink(file) | |
454 else | |
455 open(file, "w"){|w| w.puts @groupmap[group][attr]} | |
456 end | |
457 rescue | |
458 return nil | |
459 end | |
460 return {attr => value} | |
461 end | |
462 def getgroupattr(group, attr) | |
463 if @groupmap.has_key?(group) && @groupmap[group][attr].is_a?(String) && | |
464 @groupmap[group][attr] > '' | |
465 return @groupmap[group][attr].untaint | |
466 else | |
467 return nil | |
468 end | |
469 end | |
0 | 470 def groupmap() |
471 @groupmap | |
472 end | |
473 def groups() | |
474 @groupmap.keys | |
475 end | |
2 | 476 def addgroup(group, users, remove=nil, role='members') |
477 grp = groups.grep(group)[0] # group may be tainted, using kept name | |
478 return nil unless grp | |
0 | 479 for u in users |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
480 m = nil |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
481 u, m = u if u.is_a?(Array) # ["user", "mailto"] |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
482 m = nil if mailaddress(u)==m || /@/ !~ m |
0 | 483 next unless account_exists(u) |
17 | 484 mdir = File.join(@groupmapdir, grp, role).untaint |
485 file = File.join(mdir, u).untaint | |
0 | 486 if remove |
487 @groupmap[grp][role].delete(u) | |
488 File.unlink(file) if test(?e, file) | |
489 else | |
490 @groupmap[grp][role] << u | |
491 @groupmap[grp][role].uniq | |
492 Dir.mkdir(file) unless test(?d, mdir) | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
493 open(file, "w"){|x|x.puts m if m} |
0 | 494 end |
495 end | |
496 grp | |
497 end | |
498 def setgroupname(grp, name) | |
499 return nil unless @groupmap[grp] | |
17 | 500 mdir = File.join(@groupmapdir, grp).untaint |
501 nfile = File.join(mdir, 'name').untaint | |
0 | 502 @groupmap[grp]['name'] = name |
503 if grp == name | |
504 # remove the name file because it is default name | |
505 File.unlink(nfile) if test(?e, nfile) | |
506 else | |
507 Dir.mkdir(mdir) unless test(?d, mdir) | |
508 open(nfile, "w"){|n| n.puts name.to_s.strip} | |
509 end | |
510 name | |
511 end | |
512 def creategroup(grp, grpname="", admin=[]) | |
2 | 513 grpptnOK = /^[-A-Z0-9._:!$%,]+$/i |
514 return nil unless grpptnOK =~ grp | |
515 gg = '' | |
516 grp.split('').each{|c| gg << c[0].chr if c =~ grpptnOK} | |
517 grp = gg | |
0 | 518 gdir = File.join(@groupmapdir, grp) |
519 mkdir_p(gdir) # Should not care errors here | |
520 Dir.mkdir(File.join(gdir, "admin")) | |
521 Dir.mkdir(File.join(gdir, "members")) | |
522 @groupmap[grp] = {} | |
523 if grpname == '' | |
524 @groupmap[grp]['name'] = grp | |
525 else | |
526 setgroupname(grp, grpname) | |
527 end | |
528 @groupmap[grp]['members'] = [] | |
529 @groupmap[grp]['admin'] = [] | |
530 addgroup(grp, admin) | |
531 addgroup(grp, admin, nil, 'admin') | |
532 return @groupmap[grp] | |
533 end | |
534 def createuser(user, email = nil) | |
535 return nil unless /@/ =~ user | |
536 return nil if %r@[\/()\;|,$\%^!\#&\'\"]@ =~ user | |
537 email = email || user | |
538 @usermap[user] = {} | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
539 dir = File.join(@usermapdir, user).untaint |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
540 test(?d, dir) || Dir.mkdir(dir) |
0 | 541 putuserattr(user, 'email', email) |
542 end | |
543 def deleteuser(user) | |
544 return nil unless @usermap[user] | |
545 begin | |
546 @usermap[user] # return value | |
547 ensure | |
548 @usermap.delete(user) | |
549 rm_rf(File.join(@usermapdir, user)) | |
550 rm_rf(File.join(@groupmapdir, "*/members/#{user}")) | |
551 rm_rf(File.join(@crondir, "[1-9]*-*-*/#{user}")) | |
552 rm_rf(File.join(@dir, "[1-9]*/[0-9][0-9]/[0-9][0-9]/[0-9]???/#{user}")) | |
553 end | |
554 end | |
555 def destroygroup(grp) | |
556 return nil unless @groupmap[grp] | |
557 begin | |
558 @groupmap[grp] # return value | |
559 ensure | |
560 @groupmap.delete(grp) | |
561 rm_rf(File.join(@groupmapdir, grp)) | |
562 rm_rf(File.join(@groupmapdir, "*/members/#{grp}")) | |
563 rm_rf(File.join(@crondir, "[1-9]*-*-*/#{grp}")) | |
564 rm_rf(File.join(@dir, "[1-9]*/[0-9][0-9]/[0-9][0-9]/[0-9]???/#{grp}")) | |
565 end | |
566 end | |
567 def rm_rf(path) | |
6 | 568 path.untaint |
0 | 569 if (list = Dir.glob(path))[0] |
570 for p in list | |
2 | 571 p.untaint |
0 | 572 system "/bin/rm -rf \"#{p}\"" |
573 end | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
574 cleanup_files(list) |
0 | 575 end |
576 end | |
577 def account_exists(instance) | |
578 if /@/ =~ instance | |
579 true | |
580 else | |
581 ! @groupmap.select{|k, v| k==instance}.empty? | |
582 end | |
583 end | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
584 def mail4grp(usr, group) |
87 | 585 # If members/user file contains only "skip:" keyword, |
586 # return "skip:email@add.re.ss" | |
587 default = mailaddress(usr) | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
588 file = File.expand_path((group+"/members/"+usr).untaint, @groupmapdir) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
589 if test(?s, file.untaint) |
87 | 590 rcpt = open(file, "r"){|f|f.gets.chomp}.untaint |
591 if /^(off|skip):/ =~ rcpt && /@/ !~ rcpt | |
592 rcpt = "skip:"+default | |
593 end | |
594 return rcpt | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
595 end |
87 | 596 default |
597 end | |
598 def delivergrpmail(user, grp) | |
599 | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
600 end |
0 | 601 def ismember(user, grouporuser) |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
602 return user if user==grouporuser |
0 | 603 if @groupmap[grouporuser] |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
604 @groupmap[grouporuser]['members'].grep(user)[0] && |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
605 mail4grp(user, grouporuser) |
0 | 606 end |
607 end | |
2 | 608 def isuser(user) |
609 @usermap[user] && @usermap.keys.grep(user)[0] | |
610 end | |
0 | 611 def isgroup(grp) |
612 @groupmap[grp] | |
613 end | |
614 def isadmin(user, group) | |
615 @groupmap[group] and @groupmap[group]['admin'].grep(user)[0] | |
616 end | |
617 def members(grp) | |
618 @groupmap[grp] and ####################@groupmap[grp]['members'] | |
619 collectmembers(grp) | |
620 end | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
621 def membernames(grp) |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
622 if isgroup(grp) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
623 members(grp).collect{|u| nickname(u)} |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
624 else |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
625 [nickname(grp)] |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
626 end |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
627 end |
0 | 628 def admins(grp) |
629 @groupmap[grp] and @groupmap[grp]['admin'] | |
630 end | |
631 def groupname(grp) | |
632 @groupmap[grp] && @groupmap[grp]['name'] | |
633 end | |
2 | 634 def name2group(name) |
635 @groupmap.find{|g, v| v.is_a?(Hash) && v['name']==name} | |
636 end | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
637 def day_all(d, user=nil, personalonly = nil, filter) |
0 | 638 y, m, d = d.scan(%r,(\d\d\d\d+)/(\d+)/(\d+),)[0] |
639 #daydir = File.join(@dir, "%04d"%y.to_i, "%02d"%m.to_i, "%02d"%d.to_i) | |
640 daydir = File.join("s", "%04d"%y.to_i, "%02d"%m.to_i, "%02d"%d.to_i) | |
641 sched = {} | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
642 grep = if filter && filter > '' |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
643 Regexp.new(filter.split(/\s+/).join("|")) |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
644 end |
0 | 645 return sched unless test(?d, daydir) |
646 Dir.foreach(daydir) {|time| | |
647 next if /^\./ =~ time | |
648 next unless /^\d\d\d\d$/ =~ time | |
649 time.untaint | |
650 t = File.join(daydir, time) | |
651 next unless test(?d, t) | |
652 sched[time] = {} | |
653 Dir.foreach(t){|who| | |
654 next if /^\./ =~ who | |
655 | |
656 visible = false | |
657 #next unless /@/ =~ who # user must be as user@do.ma.in | |
658 next unless account_exists(who) | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
659 ## next if private && who != user #2004/1/16 |
0 | 660 who.untaint |
661 dir = File.join(t, who) | |
662 next unless test(?d, dir) && test(?x, dir) | |
663 pub = File.join(dir, 'pub') | |
7 | 664 if test(?f, pub) && test(?r, pub) && test(?s, pub) && |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
665 !personalonly # unneccessary if personalonly mode |
0 | 666 if IO.readlines(pub)[0].to_i > 0 |
667 visible = true | |
668 end | |
669 end | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
670 next if grep && (grep !~ who && grep !~ nickname(who)) # 2013/12/19 |
0 | 671 |
672 if ismember(user, who) || visible | |
673 sched[time][who] = {} | |
674 file = File.join(dir, @schedulefile) | |
675 if test(?s, file) && test(?r, file) && test(?s, file) | |
17 | 676 sched[time][who]['sched'] = IO.readlines(file).join.toeuc.chomp! |
6 | 677 sched[time][who]['regtime'] = File.stat(file).mtime |
0 | 678 end |
679 sched[time][who]['pub'] = visible | |
680 end | |
681 } #|who| | |
682 sched.delete(time) if sched[time].empty? | |
683 } | |
684 sched | |
685 end | |
686 | |
687 def scheduledir(user, y, m, d, time) | |
688 sprintf("%s/%04d/%02d/%02d/%04d/%s", | |
44 | 689 @dir, y.to_i, m.to_i, d.to_i, time.to_i, user).untaint |
0 | 690 end |
691 def schedulefile(user, y, m, d, time) | |
692 File.join(scheduledir(user, y, m, d, time), @schedulefile) | |
693 end | |
694 def mkdir_p(path, mode=0777) | |
695 # Do not mkdir `path' for | |
696 # absolute paths | |
697 # those paths which contains `../' | |
698 # for the sake of security reason | |
699 return false if %r,\.\./|^/, =~ path | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
700 path = path.untaint |
0 | 701 p = 0 |
702 i=0 | |
703 while p=path.index("/", p) | |
704 dir = path[0..p].chop | |
705 p += 1 | |
706 break if i > 10 # overprotecting | |
707 next if test(?d, dir) | |
708 Dir.mkdir(dir, mode) | |
709 i += 1 | |
710 end | |
711 Dir.mkdir(path, mode) unless test(?d, path) | |
712 end | |
713 | |
714 # | |
715 # register schedule for user | |
716 # | |
717 def register(user, year, month, day, time, text, replace=nil) | |
718 # return code: 0 = succesfull new registration | |
719 # 1 = succesfull appending registration | |
720 dir = scheduledir(user, year, month, day, time) | |
721 file = schedulefile(user, year, month, day, time) | |
722 ret = 0 | |
723 um = File.umask(027) | |
724 begin | |
725 if !replace && test(?s, file) | |
726 ret = 1 | |
727 else | |
728 mkdir_p(dir, 0777) | |
729 end | |
730 ensure | |
731 File.umask(um) | |
732 end | |
733 open(file, replace ? "w" : "a"){|out|out.print text} | |
734 return ret | |
735 end | |
736 def getschedule(user, year, month, day, time) | |
737 file = schedulefile(user, year, month, day, time) | |
738 if test(?r, file) && test(?s, file) | |
17 | 739 return IO.readlines(file).join.toeuc |
0 | 740 end |
741 return nil | |
742 end | |
743 def remove(user, year, month, day, time) | |
744 file = schedulefile(user, year, month, day, time) | |
745 dir = File.dirname(file) | |
746 if test(?r, file) && test(?s, file) | |
747 File.unlink(file) | |
748 end | |
749 for f in Dir.glob(File.join(dir, "*")) | |
750 f.untaint | |
751 File.unlink(f) | |
752 end | |
753 Dir.rmdir(dir) if test(?d, dir) | |
754 begin | |
755 Dir.rmdir(File.dirname(dir)) | |
756 rescue | |
757 end | |
758 end | |
759 # | |
760 # register file | |
761 # | |
762 def putfile(user, year, month, day, time, file, contents) | |
763 scback = @schedulefile | |
764 begin | |
765 @schedulefile = File.basename(file) | |
766 register(user, year, month, day, time, contents, true) | |
767 ensure | |
768 @schedulefile = scback | |
769 end | |
770 end | |
771 def getfile(user, year, month, day, time, file) | |
772 scback = @schedulefile | |
773 begin | |
774 @schedulefile = File.basename(file) | |
775 getschedule(user, year, month, day, time) | |
776 ensure | |
777 @schedulefile = scback | |
778 end | |
779 end | |
780 def removefile(user, year, month, day, time, file) | |
781 dir = scheduledir(user, year, month, day, time) | |
782 file = File.join(dir, file) | |
783 if test(?e, file) | |
784 File.unlink(file) | |
785 end | |
786 end | |
787 # | |
788 # registration to crondir | |
789 # | |
790 def cronlink_file(nt_time, user, y, m, d, time) | |
791 subdir = nt_time.strftime("%Y-%m-%d-%H%M/#{user}") | |
792 cdir = File.join(@crondir, subdir) | |
793 File.join(cdir, sprintf("%04d-%02d-%02d-%04d", y, m, d, time)) | |
794 end | |
795 def register_crondir(nt_time, user, y, m, d, time) | |
796 linkfile = cronlink_file(nt_time, user, y, m, d, time) | |
797 mkdir_p(File.dirname(linkfile)) | |
798 scfile = schedulefile(user, y, m, d, time) | |
799 if test(?s, scfile) | |
800 sclink = File.join("../../..", scfile.sub!(Regexp.quote(@dir+'/'), '')) | |
801 File.symlink(sclink, linkfile) unless test(?e, linkfile) | |
802 return linkfile | |
803 end | |
804 return false | |
805 end | |
806 def remove_crondir(nt_time, user, y, m, d, time) | |
807 linkfile = cronlink_file(nt_time, user, y, m, d, time) | |
808 scfile = schedulefile(user, y, m, d, time) | |
809 if test(?e, linkfile) | |
810 File.unlink(linkfile) | |
811 begin | |
812 dir = linkfile | |
813 2.times {|x| | |
814 dir = File.dirname(dir) | |
815 if Dir.open(dir).collect.length <= 2 # is empty dir | |
816 Dir.rmdir(dir) | |
817 else | |
818 break | |
819 end | |
820 } | |
821 rescue | |
822 end | |
823 return linkfile | |
824 end | |
825 return false | |
826 end | |
827 | |
828 # | |
829 # return the Hash of crondir {user => files} | |
830 def notify_list(asof) | |
831 slack = 5*60 | |
832 gomifiles = [] | |
833 ntl = {} | |
834 return ntl unless test(?d, @crondir) | |
835 Dir.foreach(@crondir){|datedir| | |
2 | 836 next unless /(\d\d\d\d+)-(\d+)-(\d+)-(\d\d\d\d)/ =~ datedir |
10 | 837 ##datedir = sprintf("%04d-%02d-%02d-%04d", |
838 ## $1.to_i, $2.to_i, $3.to_i, $4.to_i) | |
839 datedir.untaint | |
0 | 840 dd = File.join(@crondir, datedir) |
841 next unless test(?d, dd) | |
842 y, m, d, hm = $1.to_i, $2.to_i, $3.to_i, $4.to_i | |
843 hh = hm/100 % 60 | |
844 mm = (hm%100) % 60 | |
845 t = Time.mktime(y, m, d, hh, mm) | |
846 next if t-slack > asof | |
847 # | |
848 # collect them | |
849 Dir.foreach(dd){|user| | |
2 | 850 # next unless /@/ =~ user || isgroup(user) |
851 next if /^\./ =~ user | |
852 if isgroup(user) | |
853 user = @groupmap.keys.grep(user)[0] | |
854 else | |
855 user = @usermap.keys.grep(user)[0] | |
856 end | |
857 next unless user | |
72
6a0c2f85faa3
Canonicalize arguments for isHoliday(), which will be sent to Time.mktime().
HIROSE Yuuji <yuuji@gentei.org>
parents:
71
diff
changeset
|
858 ud = File.join(dd, user).untaint |
0 | 859 next unless test(?d, ud) |
78 | 860 ntl[user] = {} unless ntl.has_key?(user) |
0 | 861 Dir.foreach(ud){|date| |
862 next if /^\./ =~ date | |
863 unless /(\d\d\d\d+)-(\d+)-(\d+)-(\d\d\d\d)/ =~ date | |
864 gomifiles << File.join(ud, date) | |
865 next | |
866 end | |
13 | 867 #date = sprintf("%04d-%02d-%02d-%04d", |
868 # $1.to_i, $2.to_i, $3.to_i, $4.to_i) | |
869 date.untaint | |
0 | 870 f = File.join(ud, date) |
871 if test(?s, f) | |
872 ntl[user][date] = {} | |
873 ntl[user][date]['file'] = f | |
33 | 874 ntl[user][date]['text'] = |
875 IO.readlines(f).collect{|l| l.toeuc} # ...why? :-( | |
0 | 876 else |
877 File.unlink(f) # symlink points to nonexistent file | |
878 end | |
879 } | |
880 if ntl[user].empty? | |
881 # if ud does not contain valid cron symlinks, | |
882 # ud had been left badly. Remove it. | |
883 ntl.delete(user) | |
884 cleanup_files(gomifiles) | |
885 end | |
886 } | |
887 } | |
888 ntl | |
889 end | |
890 # | |
891 # cleanup file and directories | |
892 def cleanup_crondir(time) | |
893 Dir.foreach(@crnondir){|datedir| | |
894 dd = File.join(@crondir, datedir) | |
895 next unless test(?d, dd) | |
896 next unless /(\d\d\d\d+)-(\d+)-(\d+)-(\d\d\d\d)/ =~ dd | |
897 y, m, d, hm = $1.to_i, $2.to_i, $3.to_i, $4.to_i | |
898 hh = hm/100 % 60 | |
899 mm = (hm%100) % 60 | |
900 t = Time.mktime(y, m, d, hh, mm) | |
901 if t < time | |
902 system "rm -rf #{dd}" | |
903 end | |
904 } | |
905 end | |
906 # | |
907 # remove files in FILES, and remove parent directory if possible | |
908 def cleanup_files(files) | |
909 sentinel = File.stat(@dir).ino | |
16 | 910 me = $0.dup.untaint |
911 scriptsuid = File.stat(me).uid | |
0 | 912 for f in files |
2 | 913 if $SAFE > 0 |
914 f.untaint | |
915 if test(?e, f) && File.stat(f).uid != scriptsuid | |
916 f.taint | |
917 end | |
918 end | |
919 printf "Removing %s\n", f if $DEBUG | |
0 | 920 File.unlink(f) if test(?e, f) |
921 d = f | |
922 loop { | |
923 d = File.dirname(d) | |
924 break if d.length < 2 | |
925 break if File.stat(d).ino == sentinel | |
926 begin | |
927 puts "rmdir #{d}" if $DEBUG | |
928 Dir.rmdir(d) | |
929 rescue | |
930 break | |
931 end | |
932 } | |
933 end | |
934 end | |
935 end | |
936 | |
937 class StringIO<IO | |
938 def initialize() | |
939 @str="" | |
940 end | |
941 def foo=(str) | |
942 @str = str | |
943 end | |
2 | 944 def append(str) |
945 @str = str+@str | |
946 end | |
0 | 947 def print(str) |
948 @str << str | |
949 end | |
950 def puts(str) | |
951 @str << str+"\n" | |
952 end | |
953 def printf(*args) | |
954 @str << sprintf(*args) | |
955 end | |
956 def write(bytes) | |
957 print(bytes) | |
958 end | |
959 def gets() | |
960 return nil if @str == '' | |
961 p = @str.index(?\n) | |
962 if p | |
963 r = @str[0..p] | |
964 @str=@str[p+1..-1] | |
965 else | |
966 r = @str | |
967 end | |
968 return r | |
969 end | |
970 def readline() | |
971 this.gets() | |
972 end | |
973 def readlines() | |
974 r = @str | |
975 @str='' | |
976 r | |
977 end | |
978 | |
979 def p(*obj) | |
980 STDOUT.p(*obj) | |
981 end | |
982 end | |
983 | |
984 class CMDTimeout < Exception | |
985 def initialize() | |
986 @pw = IO.pipe | |
987 @pr = IO.pipe | |
988 @pe = IO.pipe | |
989 @timeout = false | |
990 end | |
991 def start(cmd, timeout, mixstderr=false) | |
992 if @pid=fork | |
993 @pw[0].close | |
994 @pr[1].close | |
995 @pe[1].close | |
996 # puts "parent!" | |
997 if @tk=fork | |
998 # main | |
999 else | |
1000 @pw[1].close | |
1001 @pr[0].close | |
1002 @pe[0].close | |
1003 trap(:INT){exit 0} | |
1004 sleep timeout | |
1005 begin | |
1006 @timeout = true | |
1007 STDERR.puts "TIMEOUT" | |
1008 Process.kill :INT, @pid | |
1009 rescue | |
1010 #puts "Already done" | |
1011 end | |
1012 exit 0 | |
1013 end | |
1014 else | |
1015 # Running this block with pid=@pid | |
1016 trap(:INT){@timeout = true; exit 0} | |
1017 @pw[1].close | |
1018 STDIN.reopen(@pw[0]) | |
1019 @pw[0].close | |
1020 | |
1021 @pr[0].close | |
1022 STDOUT.reopen(@pr[1]) | |
1023 if mixstderr | |
1024 STDERR.reopen(@pr[1]) | |
1025 else | |
1026 STDERR.reopen(@pe[1]) | |
1027 end | |
1028 @pr[1].close | |
1029 @pe[0].close | |
1030 @pe[1].close | |
1031 | |
15 | 1032 exec(*cmd) |
0 | 1033 exit 0 |
1034 end | |
1035 return [@pw[1], @pr[0], @pe[0]] | |
1036 end | |
1037 def wait() | |
1038 Process.waitpid(@pid, nil) | |
1039 end | |
1040 def close() | |
1041 @pr.each{|p| p.close unless p.closed?} | |
1042 @pw.each{|p| p.close unless p.closed?} | |
1043 @pe.each{|p| p.close unless p.closed?} | |
1044 begin | |
1045 Process.kill :INT, @tk | |
1046 rescue | |
1047 end | |
1048 end | |
1049 def timeout() | |
1050 @timeout | |
1051 end | |
1052 end | |
1053 | |
1054 class Holiday | |
1055 def initialize(dir = ".") | |
1056 @@dir = dir | |
1057 defined?(@@holiday) || setupHoliday | |
1058 end | |
1059 def setupHoliday(file = "holiday") | |
1060 @@holiday = {} | |
1061 return unless test(?f, file) && test(?s, file) | |
1062 IO.foreach(file){|line| | |
17 | 1063 line = line.toeuc.strip |
0 | 1064 next if /^#/ =~ line |
1065 date, what = line.scan(/(\S+)\s+(.*)/)[0] | |
1066 if %r,(\d+)/(\d+)/(\d+), =~ date | |
1067 cdate = sprintf("%d/%d/%d", $1.to_i, $2.to_i, $3.to_i) | |
1068 @@holiday[cdate] || @@holiday[cdate] = [] | |
1069 @@holiday[cdate] << what | |
1070 elsif %r,(\d+)/(\d+), =~ date | |
1071 cdate = sprintf("%d/%d", $1.to_i, $2.to_i) | |
1072 @@holiday[cdate] || @@holiday[cdate] = [] | |
1073 @@holiday[cdate] << what | |
1074 elsif %r,(\d+)/(\w+), =~ date | |
1075 cdate = sprintf("%d/%s", $1.to_i, $2.downcase) | |
1076 @@holiday[cdate] || @@holiday[cdate] = [] | |
1077 @@holiday[cdate] << what | |
1078 end | |
1079 } | |
1080 end | |
1081 def isHoliday(y, m, d, wday=nil) | |
1082 y, m, d = y.to_i, m.to_i, d.to_i | |
1083 wname = %w[sun mon tue wed thu fri sat] | |
35 | 1084 wday = wname[wday || Time.mktime(y, m, d).wday] |
0 | 1085 holiday = @@holiday[sprintf("%d/%d/%d", y, m, d)] || |
1086 @@holiday[sprintf("%d/%d", m, d)] | |
1087 unless holiday | |
1088 nthweek = (d-1)/7+1 | |
1089 holiday = @@holiday[sprintf("%d/w%d%s", m, nthweek, wday)] | |
1090 end | |
35 | 1091 if !holiday && wday == "mon" && d > 0 # d<1 when column is before 1th |
1092 # holiday in lieu | |
1093 yesterday = Time.mktime(y, m, d)-3600*24 | |
1094 holiday = ["振替休日"] if | |
1095 isHoliday(yesterday.year, yesterday.mon, yesterday.day) | |
1096 end | |
0 | 1097 holiday |
1098 end | |
1099 def holidays() | |
1100 @@holiday | |
1101 end | |
1102 end | |
1103 | |
1104 class After5 | |
1105 def initialize() | |
1106 @me = File.expand_path($0) | |
1107 @mydir, @myname = File.dirname(@me), File.basename(@me) | |
1 | 1108 @mybase = @myname.sub(/\.\w+$/, '') |
0 | 1109 @mydir.untaint |
1 | 1110 @mybase.untaint |
0 | 1111 Dir.chdir @mydir |
1 | 1112 @myname='a5.cgi' if test(?f, "a5.cgi") |
0 | 1113 @conf = nil |
1114 @schedulearea = {'rows'=>'4', 'cols'=>'60', 'name'=>'schedule'} | |
1115 @oldagent = (%r,Mozilla/4, =~ ENV['HTTP_USER_AGENT']) | |
2 | 1116 @lang = 0 |
85 | 1117 @mlbasedir = "ml" |
1118 @attachmentdir = "a" | |
1119 @attachmentmax = 8*1024**2 | |
14 | 1120 @mailmode = nil |
57
d089cb42619d
ML's return-path changed from maintainer to group owners.
HIROSE Yuuji <yuuji@gentei.org>
parents:
56
diff
changeset
|
1121 @mailadmdelimiter = "/" |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
1122 @mailadmsuffix = @mailadmdelimiter + "adm" |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1123 @saveprefsregexp = /^(display(mode|days|filter)$|nt|headline)/ |
0 | 1124 @opt = { |
1125 'conf' => @mybase+".cf", | |
1126 'css' => @mybase+".css", | |
13 | 1127 'logfile' => 's/'+@mybase+".log", |
0 | 1128 "sendmail" => "/usr/sbin/sendmail", |
1129 'hostcmd' => '/usr/bin/host', | |
1130 'nslookup' => '/usr/sbin/nsookup', | |
1131 'bg' => 'ivory', | |
8 | 1132 'name' => nil, |
0 | 1133 'at_bsd' => '%H:%M %b %d %Y', |
1134 'at_solaris' => '%H:%M %b %d,%Y', | |
1135 'schedir' => 's', | |
1136 'tdskip' => '<br>', | |
1137 'forgot' => 'wasureta', | |
1138 'size' => @oldagent ? '15' : '40', | |
1139 'morning' => '6', | |
1140 'night' => '22', | |
1141 'alldaydir' => '3000', | |
1142 'pswdlen' => 4, | |
6 | 1143 'pswddb' => 's/a5pswd', |
2 | 1144 'lang' => 'j', |
6 | 1145 'notifymail' => true, |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1146 'mailbracket' => '[%n-ML]', |
0 | 1147 } |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1148 @subjtags = [['[GroupID:#]', "[%i:%c]"], |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1149 ['[GroupID:#####]', "[%i:%5c]"], |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1150 ['[GroupName:#]', "[%n:%c]"], |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1151 ['[GroupName:#####]', "[%n:%5c]"], |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1152 ['(GroupID:#)', "(%i:%c)"], |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1153 ['(GroupID:#####)', "(%i:%5c)"], |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1154 ['(GroupName:#)', "(%n:%c)"], |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
1155 ['(GroupName:#####)', "(%n:%5c)"], |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
1156 ['NONE', "NONE"]] |
0 | 1157 ##@job = "today" |
3 | 1158 @wnames = %w[sun mon tue wed thu fri sat] |
0 | 1159 @job = "login" |
1160 @sc = ScheduleDir.new | |
1161 @O = StringIO.new | |
1162 @H = HTMLout.new() | |
1163 @umback = File.umask | |
1164 @author = 'yuuji@gentei.org' | |
1165 @after5url = 'http://www.gentei.org/~yuuji/software/after5/' | |
1166 File.umask(007) | |
1167 end | |
1168 def doit() | |
1169 @params = getarg() | |
1170 @cookie = getcookie() | |
3 | 1171 importcookie() |
2 | 1172 @lang = (/^j/i =~ @opt['lang'] ? 0 : 1) |
50
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1173 @ntlist = [ # this shoud be set after @lang |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1174 ['nt10m', "10"+msg('minutes', 'before')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1175 ['nt30m', "30"+msg('minutes', 'before')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1176 ['nt60m', "60"+msg('minutes', 'before')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1177 ['nttoday', msg('theday')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1178 ['nt1d', "1"+msg('days', 'before')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1179 ['nt2d', "2"+msg('days', 'before')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1180 ['nt3d', "3"+msg('days', 'before')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1181 ['nt7d', "7"+msg('days', 'before')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1182 ['nt30d', "30"+msg('days', 'before')], |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1183 ] |
0 | 1184 p @cookie if $DEBUG |
1185 p @params if $DEBUG | |
1186 | |
3 | 1187 ### @params['displaymode'] = @params['displaymode'] || @cookie['displaymode'] |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1188 personal = /^personal/i =~ @params['displaymode'] |
2 | 1189 bodyclass = if personal then {'class'=>'personal'} end |
0 | 1190 |
1191 ## x = {"align"=>'center'} | |
1192 ## @H.element("p", x, "hoge", nil) | |
1193 ## @H.element("p", nil, "buha", nil) | |
1194 | |
3 | 1195 if nil |
0 | 1196 if !@params['passwd'] && @cookie['passwd'] |
1197 @params['passwd'] = @cookie['passwd'] | |
1198 end | |
1199 if !@params['user'] && @cookie['user'] | |
1200 @params['user'] = @cookie['user'] | |
1201 end | |
3 | 1202 end |
0 | 1203 @params['user'] = safecopy(@params['user']) |
2 | 1204 |
15 | 1205 ######eval @job |
8 | 1206 a5name = if @opt['name'] && @opt['name'] > '' |
1207 sprintf("(%s)", @opt['name']) | |
1208 else | |
1209 "" | |
1210 end | |
2 | 1211 @O.append(@H.contenttype() + |
8 | 1212 @H.head(a5name+"After 5"+@job.sub(/\s*/, ' '), @opt['css'])) |
2 | 1213 @O.print @H.startelement("body", bodyclass, true) |
15 | 1214 # @job should be here because its output shoud go after <body>. |
1215 eval @job | |
0 | 1216 @O.print @H.endelement(nil, true) # body |
14 | 1217 @O.print @H.endelement("html", true) # html |
0 | 1218 setcookie() |
1219 | |
1220 print @O.readlines | |
1221 end | |
1222 def msg(*keyword) | |
1223 unless defined?(@msg) | |
1224 @msg = { | |
3 | 1225 'title' => ['みんなの予定表 <img src="after5.png" alt="「アフター5」">', 'Schedule table for us all <img src="after5.png" alt="After 5">'], |
0 | 1226 'login' => ['ログイン', 'Login'], |
1227 'loginfirst' => ['最初にログインすべし', 'Login first'], | |
1228 'autherror' => ['認証エラーがあったと管理者に伝えてくれっす', | |
1229 'Unexpected authentication error. Please tell this to the administrator'], | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1230 'yourmail' => ['あなたのメイルアドレス', 'Your email address'], |
0 | 1231 'passwd' => ['パスワード<br>(初回時は空欄)', |
1232 'Passowrd<br>Left blank, first time'], | |
1233 'error' => ['エラー:', 'Error: '], | |
1234 'mailerror' => ['メイルアドレスが違います', 'Invalid email address'], | |
1235 'pswderror' => ['パスワードが違います', 'Password incorrect'], | |
22
8803e5d52611
Show guidance when wrong password entered.
HIROSE Yuuji <yuuji@gentei.org>
parents:
18
diff
changeset
|
1236 'forgotguide' => ['忘れた場合は %s と入力するよろし', |
8803e5d52611
Show guidance when wrong password entered.
HIROSE Yuuji <yuuji@gentei.org>
parents:
18
diff
changeset
|
1237 "Put \`%s' when you forgot password."], |
8 | 1238 'fmtdaysschedule'=> ['%s〜の予定', 'Schedule from %s'], |
18 | 1239 'schedtable' => ['予定表', 'Schedule Table'], |
0 | 1240 'noplan' => ['登録されている予定はありません', 'No plans'], |
1241 'allday' => ['全日', 'whole day'], | |
1242 'addsched' => ['新規予定項目の登録', 'Register new schedule'], | |
1243 'defthisday' => ['デフォルトの日付はこの日になってま', ''], | |
1244 '24hour' => ['24時間制4桁でね<br>(0000〜2359)<br>%sは時刻指定なし', 'in 24-hour<br>(0000-2359)<br>%s for whole day'], | |
14 | 1245 '24hourtxt' => ['24時間制4桁でね(0000〜2359), %sは時刻指定なし', 'in 24-hour(0000-2359), %s for whole day'], |
0 | 1246 'reqnotify' => ['通知メイルいるけ?', 'Previous notification'], |
1247 'rightnow' => ['登録時にすぐ', 'Right now on registration'], | |
1248 'immediatenote' => ['に以下の予定を登録しました', | |
1249 ", Your schedule has been registered as follows;"], | |
1250 'registerer_is' => ['登録名義: ', 'Register as '], | |
1251 'registerer' => ['登録者: ', 'registerer: '], | |
1252 'about' => ['約', 'about'], | |
1253 'minutes' => ['分', 'minutes'], | |
1254 'hours' => ['時間', 'hour(s)'], | |
1255 'days' => ['日', 'day(s)'], | |
2 | 1256 'daystodisplay' => ['日分表示', 'days to display'], |
0 | 1257 'before' => ['前', 'before'], |
2 | 1258 'precedingday' => ['前日', 'Preceding day'], |
0 | 1259 'theday' => ['当日朝', "the day's morning"], |
1260 'night' => ['(夜)', '(night)'], | |
63
e2aa6180c2c6
Show the number of group member in groupman().
HIROSE Yuuji <yuuji@gentei.org>
parents:
62
diff
changeset
|
1261 'publicok' => ['アカウント保持者全員<br>に見せてもええね?', |
e2aa6180c2c6
Show the number of group member in groupman().
HIROSE Yuuji <yuuji@gentei.org>
parents:
62
diff
changeset
|
1262 'visible to anyone who has account of this board?'], |
0 | 1263 'public' => ['公', 'pub'], |
1264 'nonpublic' => ['非', 'sec'], | |
2 | 1265 'through' => ['〜', '=>'], |
0 | 1266 'yes' => ['はいな', 'yes'], |
29
e7a01e561e28
Message 'no' should contain only 'no'.
HIROSE Yuuji <yuuji@gentei.org>
parents:
28
diff
changeset
|
1267 'no' => ['やだ', 'nope'], |
2 | 1268 'wnames' => [%w[日 月 火 水 木 金 土], |
1269 %w[sun mon tue wed thu fri sat]], | |
1270 'whichday' => ['<small>(まとめ登録の場合)</small><br>期間中のどの日に?', | |
1271 '<small>(On multiple registration)</small><br>Which days in the term?'], | |
1272 'singleday' => ['一日分だけ登録', '1day regist'], | |
1273 'everyday' => ['毎日', 'everyday'], | |
0 | 1274 'invaliddate' => ['日付指定が変みたい', 'Invalid time string'], |
1275 'past' => ['それはもう過去の話ね', 'It had Pasted'], | |
1276 'putsomething' => ['何か書こうや', 'Write some message please'], | |
1277 'appended' => ['既存の予定に追加しました', 'Appended'], | |
1278 'append' => ['追加', 'append'], | |
1279 'join' => ['参加', 'join'], | |
1280 'regist' => ['登録', 'register'], | |
1281 'remove' => ['削除', 'remove'], | |
14 | 1282 'move' => ['移動', 'move'], |
1283 'newdate' => ['移動先時刻', 'New date'], | |
0 | 1284 'deletion' => ['完全消去', 'deletion'], |
1285 'deletionwarn' => ['OK押したら即消去。確認とらないぞ', | |
1286 'Hitting OK immediately delets this group, be carefully!'], | |
1287 'deluser' => ['%s ユーザ消してええかの?', "Delete the user `%s'"], | |
1288 'delgroup' => ['%s グループ消してええかの?', "Delete the group `%s'"], | |
1289 'really?' => ['ほんまにええけ?', 'Really?'], | |
1290 'chicken' => ['ふっ、腰抜けめ', 'Hey, chicken boy'], | |
1291 'modify' => ['修正', 'modify'], | |
1292 'done' => ['完了', 'done'], | |
1293 'success' => ['成功', 'success'], | |
1294 'failure' => ['失敗', 'failure'], | |
1295 'tomonthlist' => ['%s の一覧', 'all %s table'], | |
1296 'notifysubj' => @mybase+"'s reminder for your plan", | |
1297 'introduce' => ['はいこんにちは、'+@mybase+'ですよ〜。', | |
1298 "Hi, this is #{@mybase}'s notification."], | |
1299 'notifymail' => ['こんな予定がありまっせ。', | |
1300 "You have some eschedule below;"], | |
1301 'notification' => ['の通知', 'notification'], | |
1302 'newaccount' => ["新しいアカウントを作りました。\n"+ | |
1303 "パスワードは %s さん宛に送信しておきました。\n", | |
1304 "You got new account for #{@mybase}\n" + | |
1305 "Password was sent to %s.\nThank you.\n"], | |
1306 'accessfrom' => ["%s からのアクセスによる送信\n", | |
1307 "This mail was sent by the access from %s\n"], | |
1308 'newpassword' => ["%s さんのパスワードは %s です。\n", | |
1309 "The password of %s is %s\n"], | |
50
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1310 'mischief' => ["身に覚えのない場合はMLへの代理登録の可能性があります。 |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1311 上記URLが見慣れたものならばアクセスしてみるか、 |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1312 このURLの管理人(%s さん)に問い合わせてみて下さい。 |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1313 それらも心当たりのない場合はいたずらです。対処しますので管理人まで御連絡下さい。", |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1314 'If you have no idea of the reason for getting this message, '+ |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1315 'it may be a invitation of mailing list from your friend. |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1316 Please try to access URL above if it is familiar one or |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1317 contact to the administrator of the site(is %s). |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1318 If you have completely no clue for this invitation, |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1319 it might be a mischief by someone else. Please notice the fact |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1320 to the administrator. Thank you.'], |
0 | 1321 'user' => ['ユーザ', 'user'], |
1322 'group' => ['グループ', 'group'], | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1323 'mladdress' => ['公開MLアドレス(%s以外にしたい場合設定する)', |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1324 "Public ML address(if you set to diffrent address than `%s')"], |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1325 'fromhack' => ['ML配送時のFrom:を常にMLのアドレスにする |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1326 (From:にしか返さないケータイ参加者が多いときにオススメ)', |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1327 'Set From: address of all ML messages to ML address, which is convenient |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1328 to keep responses from cellular phones surely to ML address. Most cellular |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1329 phones tend to return only from: address.'], |
66 | 1330 'inviteonly' => ['管理者のみ加入操作可能', |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
1331 'Only administrators can add new members.'], |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
1332 'invite-error' => ['%s への加入はグループ管理者のみが操作できます。', |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
1333 "Only administrator of this group(`%s') can add you."], |
69
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
1334 'limitsender' => ['アカウント保持者のみ送信可能', |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
1335 'Allow only account holders to post to ML'], |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
1336 'xmlname' => ['X-ML-Nameヘッダの値("%s" 以外にしたい場合設定する)', |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
1337 'Value of X-ML-Name header ("%s" for default)'], |
0 | 1338 'personal' => ['個人で', 'personal'], |
17 | 1339 'registas' => ['グループ予定として登録?', 'Register as group?'], |
1340 'headsched' => ['下の枠内に予定を記入: 1行以内で短めに。 | |
1341 長くなるときは2行目以降に詳細を。', | |
1342 'Put shortest sentence as possible within 1 line. | |
1343 Or, put short subject in the first line, details in latter lines.'], | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1344 'joinquit' => ['入退会', 'joining/quiting'], |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1345 'operation' => ['操作', 'operation'], |
0 | 1346 'of' => ['の', "'s"], |
47 | 1347 'id' => ['ID(英単語かローマ字の分かりやすい1単語半角空白なしで)', 'ID(without spaces)'], |
0 | 1348 'name' => ['名前', 'name'], |
1349 'anystring' => ['(日本語OK)', '(any length, any characters)'], | |
1350 'setto' => ['を設定 → ', 'set to '], | |
2 | 1351 'dupname' => ['あー、%sってグループ名は既にあるん素。別のにして.', |
1352 "Group name `%s' already exists, choose another name."], | |
0 | 1353 'management' => ['管理', 'management'], |
1354 'administrator' => ['管理者', 'Administrator'], | |
1355 'newgroup' => ['新規グループ作成', 'Create new group'], | |
1356 'adminop' => ['管理<br>操作', "Administrative<br>operation"], | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1357 'sendall' => ['一斉送信', "write to members"], |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1358 'sendall_err' => ["%s ファイルで mailprefix と maildomain を定義しとかないと送れまへん。 |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1359 例: mailprefix=yuuji-after5 |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1360 maildomain=gentei.org |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1361 |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1362 さらに、.qmail-$mailprefix-default も以下のように用意しておこね。 |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1363 | ./#{@myname} -list", |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1364 "You should define `mailprefix' and `maildomain' in %s file before |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1365 sending message to all. |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1366 (ex.) mailprefix=yuuji-after5 |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1367 maildomain=gentei.org |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1368 |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1369 And then prepare .qmail-$mailprefix-default file as below. |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1370 | ./#{@myname} -list"], |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1371 'sendall_head' => ['「%s」宛のメイル送信', "Send message to `%s'"], |
87 | 1372 'sendmem_head' => ['「%s」さん宛のメイル送信', "Send message to `%s'"], |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1373 'sendall_note' => ['メンバーへの連絡だけでなく、グループ非加入者がこれから加入する旨の通知などにも有用。', |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1374 "Send this message to all of group."], |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1375 'sendall_done' => ['送信完了', "sending message done"], |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1376 'body' => ['本文', 'Body'], |
85 | 1377 'rcptto' => ['宛先', 'Recipients'], |
0 | 1378 'member' => ['メンバー', 'Member'], |
2 | 1379 'personalmode' => ['自分のだけ表示モード', 'Display Personal Only'], |
1380 'normalmode' => ['全員分表示モード', "Display Everyone's"], | |
3 | 1381 'display' => ['予定表示行: ', 'Display schedule of: '], |
1382 'nameonly' => ['名前のみ', 'Name Only'], | |
1383 'head5char' => ['先頭5文字', 'Head 5 chars'], | |
1384 'headline' => ['先頭1行', 'Headline only'], | |
1385 'whole' => ['長くても全部', 'Whole text'], | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1386 'filter' => ['登録者絞込', 'Selection by Registerer'], |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1387 'filterhelp' => ['表示する予定を登録者アカウント名(の一部)で絞り込みできる。 |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1388 2つ以上の名前で絞りたいときはスペースで区切ればOK。', 'Can filter by (a part of)account name. |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1389 Multiple patterns delimited by spaces are acceptable.'], |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1390 'filterreset' => ['絞込解除', 'Reset Selection'], |
6 | 1391 'hldays' => ['最新X日分強調', 'Hilight Recent X-days'], |
0 | 1392 'addedtogroup' => ['をグループに追加 →', 'added to the group:'], |
1393 'removedfromgp' => ['をグループから削除:', 'removed from the group:'], | |
1394 'soleadmin' => ['%s は %s の唯一の管理者なのでやめられないのだ', | |
1395 "%s is sole administrator of %s. Cannot retire."], | |
1396 'recursewarn' => ['個人では加入してないが、別の加入グループがこのグループに入っているので実質参加していることになっている。', | |
1397 'Though this member does not join to this group, it is assumed to be joining this group because other group where one joins is joined to this group.'], | |
1398 'regaddress' => ['登録アカウント名', 'Account id'], | |
1399 'existent' => ['既にあるんすよ → ', 'Already exists: '], | |
1400 'mailaddress' => ['通知送付先アドレス', 'Notification email address'], | |
50
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1401 'multipleok' => ['<br>(スペースで区切って複数指定可)', |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1402 '<br>(Two or more addresses are OK by delimiting with space.)'], |
0 | 1403 'weburl' => ['ゲストブックとかURL<br><small>(予定への反応を書いて欲しい場所)</small>', 'Your guest book URL'], |
1404 'usermodwarn' => ['いちいち yes/no とか確認取らないから押したら最後、気いつけて。', | |
1405 'This is the final decision. Make sure and sure.'], | |
1406 'joinmyself' => ['自分自身が既存のグループに対して入る(IN)か出る(OUT)かを決めるのがここ。自分管理のグループに誰かを足すなら「管理操作」、新たにグループを作るなら', | |
1407 'In this page, you can decide put yourself IN or OUT of the existing groups. If you want to manage the member of your own group, go to'], | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1408 'aboutgroup' => ['グループ %s の操作', "Operations on group `%s'"], |
0 | 1409 'groupwarn' => ['自分が参加してないグループAに、自分が参加しているグループBが含まれている場合、グループAにも加入していると見なされるので気をつけよう。管理者はグループのニックネームを変えられるよ。', |
1410 '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.'], | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
1411 'address2send' => ['自分が参加しているグループのメンバーリストの先頭が自分。その直後にある入力欄には、そのML宛メッセージをどの宛先に配送するかを入れられる。そう、MLごとに自分への配送先を変えられるよ。', |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
1412 '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.'], |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1413 '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."], |
0 | 1414 'wholemembers' => ['グループ内グループを考慮した上で、現在グループ %s への通知は以下のメンバーに送られる。', |
1415 "Consiering the groups registered in another group, notification to the group `%s' is send to members as follows."], | |
1416 'noadmingroup' => ['管理できるグループはないっす', | |
1417 "'There's no groups under your administration."], | |
1418 'nickname' => ['ニックネーム', 'nickname'], | |
1419 'shortnameplz' => ['表が崩れるほど長すぎるニックネームは嫌われるよ。短めにね。', | |
1420 'Because nickname is displayed many times in table, shorter name is prefered.'], | |
1421 'nicknamenote' => ['ニックネームを消去するとデフォルト名になりんす.', | |
1422 'Default name is displayed if you remove nickname.'], | |
1423 'nothingtodo' => ['って何もやることあらへんかったで', | |
14 | 1424 'Nothing to do for this transaction.'], |
1425 'schedlist' => [' and %d days Schedule list', | |
1426 'から%d日間の予定一覧'], | |
1427 'nothing' => ['なんもないす', 'Nothing'], | |
1428 'sessionpswd' => ['セッションパスワード(これはいじらないでね)', | |
1429 'Session Password(Do not modify this)'], | |
1430 'date' => ['日付', 'Date'], | |
1431 'time' => ['時刻指定', 'Time'], | |
1432 'publicp' => ['公開=yes、非公開=no', 'Public?'], | |
1433 'neednotify' => ['通知メイル(要らないのは消してね)', | |
1434 'Leave lines for notification timing'], | |
1435 'schedulehere' => ['以下登録内容', 'Your Schedule below'] | |
0 | 1436 } |
1437 end | |
1438 keyword.collect{|k| | |
1439 if @msg[k].is_a?(Array) | |
2 | 1440 @msg[k][@lang] |
0 | 1441 elsif @msg[k].is_a?(String) |
1442 @msg[k] | |
1443 else | |
1444 '' | |
1445 end | |
2 | 1446 }.join(['', ' '][@lang]) |
0 | 1447 end |
1448 | |
3 | 1449 def importcookie() |
7 | 1450 @cookie.keys.grep(@saveprefsregexp){|v| |
3 | 1451 @params[v] = @params[v] || @cookie[v] |
1452 } | |
7 | 1453 for v in %w[user passwd] |
1454 @params[v] = @params[v] || @cookie[v] | |
1455 end | |
3 | 1456 end |
0 | 1457 def setcookie() |
7 | 1458 a = {} |
1459 a['user'] = @params['user'] if @params['user'] | |
1460 a['passwd'] = @params['passwd'] if @params['passwd'] | |
1461 ac = gencookie("value", a, 3600*6*1) | |
1462 printf "Set-Cookie: %s\n", ac if ac | |
0 | 1463 p = {} |
7 | 1464 @params.keys.grep(@saveprefsregexp){|v| |
6 | 1465 p[v] = @params[v].to_s.strip if @params[v] && @params[v] > '' |
0 | 1466 } |
7 | 1467 c = gencookie("prefs", p, 3600*24*7) |
1468 str = [ac, c].select{|x|x}.join("; ") | |
1469 # printf "Set-Cookie: %s\n", str if str>'' | |
0 | 1470 printf "Set-Cookie: %s\n", c if c |
1471 end | |
1472 | |
1473 def encode(string) # borrowed from cgi.rb | |
1474 string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do | |
1475 '%' + $1.unpack('H2' * $1.size).join('%').upcase | |
1476 end.tr(' ', '+') | |
1477 end | |
14 | 1478 def purify(string) |
1479 string.gsub(/[\040-\177]/) {encode($&)} | |
1480 end | |
0 | 1481 def decode!(string) |
1482 string.gsub!(/\+/, ' ') | |
1483 string.gsub!(/%(..)/){[$1.hex].pack("c")} | |
1484 end | |
14 | 1485 def decode(string) |
17 | 1486 string.gsub(/\+/, ' ').gsub(/%(..)/){[$1.hex].pack("c")} |
14 | 1487 end |
32
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
1488 def escape(string) |
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
1489 string.gsub(/&/n, '&').gsub(/\"/n, '"'). |
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
1490 gsub(/>/n, '>').gsub(/</n, '<') |
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
1491 end |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
1492 def quoted(string) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
1493 NKF.nkf('-eMQ', string) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
1494 end |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
1495 def unquoted(string) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
1496 NKF.nkf('-emQ', string) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
1497 end |
0 | 1498 |
7 | 1499 def gencookie(name, a, expire) |
0 | 1500 x = a.collect{|k, v| |
1501 sprintf("%s=%s", k, encode(v)) if v | |
1502 } | |
1503 x.delete(nil) | |
1504 return nil if x.empty? | |
1505 str = x.join('&') | |
1506 ex = (Time.new+expire).to_s | |
7 | 1507 sprintf "%s=%s; expires=%s", name, encode(str), ex |
0 | 1508 end |
1509 | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1510 def login(altaction = nil) |
0 | 1511 @O.print @H.elementln("h1", nil){msg('title')} |
1512 @O.print @H.elementln("h2", nil){msg('login')} | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1513 format = {'method'=>'POST', |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1514 'action'=> @myname+"?" +(altaction || "-today")} |
0 | 1515 @O.print @H.elementln("form", format){ |
1516 @H.elementln("table", nil){ | |
1517 @H.elementln("tr", nil){ | |
1518 @H.element("td", nil){msg('yourmail')} + \ | |
1519 @H.element("td", nil){ | |
1520 sprintf '<input type="text" size="%s" name="user">', @opt['size'] | |
1521 } | |
1522 } + \ | |
1523 @H.elementln("tr", nil){ | |
1524 @H.element("td", nil){msg('passwd')} + \ | |
1525 @H.element("td", nil){ | |
1526 sprintf '<input type="password" size="%s" name="passwd">', @opt['size'] | |
1527 } | |
1528 } | |
1529 } + '<input type="submit" value="LOGIN">' | |
1530 } | |
1531 @O.print footer2() | |
1532 end | |
1533 def open_pm() | |
1534 begin | |
1535 PasswdMgr.new(@opt['pswddb']) | |
1536 rescue | |
1537 STDERR.printf "Cannot open pswd file [%s]\n", @opt['pswddb'] | |
1538 STDERR.printf "euid=#{Process.euid}, uid=#{Process.uid}\n", @opt['pswddb'] | |
1539 nil | |
1540 end | |
1541 end | |
1542 def outputError(*msg) | |
1543 @O.print @H.p(msg('error')+sprintf(*msg)) | |
1544 end | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1545 def mailaddress(user, grp=nil) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1546 @sc.mailaddress(user, grp) |
0 | 1547 end |
1548 def webpage(user) | |
1549 @sc.getuserattr(user, "webpage") | |
1550 end | |
14 | 1551 def checkauth_mail() |
1552 return true # temporary | |
1553 end | |
0 | 1554 def checkauth() |
14 | 1555 if @mailmode && @params['sessionpw'] |
1556 return checkauth_mail | |
1557 end | |
1558 auth = catch(:auth) { | |
0 | 1559 unless @params['user'] |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1560 #outputError(@H.a(@myname, msg('loginfirst'))) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
1561 login(@oldargv.join('+')) |
0 | 1562 throw :auth, nil |
1563 end | |
1564 unless pm=open_pm() | |
1565 outputError(msg('autherror')) | |
1566 throw :auth, nil | |
1567 end | |
1568 user, passwd = @params['user'], @params['passwd'] | |
1569 email = mailaddress(user) | |
1570 if !checkmail(user) | |
1571 outputError(msg('mailerror')) | |
1572 throw :auth, nil | |
1573 end | |
1574 if pm.userexist?(user) | |
1575 if pm.checkpasswd(user, passwd) | |
1576 throw :auth, true | |
1577 elsif passwd == @opt['forgot'] | |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
1578 newp = pm.setnewpasswd(user, @opt['pswdlen'].to_i) |
0 | 1579 sendMail(email, "#{@mybase} password", |
1580 "(#{ENV['REMOTE_ADDR']} からのアクセスによる送信)\n" + | |
7 | 1581 @opt['url'] + "\n" + |
0 | 1582 "#{@mybase} 用の #{user} さんのパスワードは\n" + |
1583 (newp || "未定義") + "\nです。\n") | |
1584 @O.print @H.p("#{email} 宛に送信しておきました") | |
1585 throw :auth, nil | |
1586 else | |
1587 outputError(msg('pswderror')) | |
22
8803e5d52611
Show guidance when wrong password entered.
HIROSE Yuuji <yuuji@gentei.org>
parents:
18
diff
changeset
|
1588 @O.print @H.p(sprintf(msg('forgotguide'), @opt['forgot'])) |
0 | 1589 throw :auth, nil |
1590 end | |
7 | 1591 elsif passwd == '' |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1592 # Create new user from Web-UI |
0 | 1593 newp = pm.setnewpasswd(user, @opt['pswdlen']) |
1594 @sc.createuser(user, user) | |
50
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1595 putLog("New user [#{user}] created\n") |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1596 sendMail(@opt['maintainer'], "After5 New User", |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1597 sprintf("URL=%s\nREMOTE_ADDR=%s\nuser=%s", |
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1598 @opt['url'], ENV['REMOTE_ADDR'], user)) |
0 | 1599 sendMail(email, "#{@mybase} new account", |
1600 sprintf(msg('accessfrom'), ENV['REMOTE_ADDR']) + | |
7 | 1601 sprintf(@opt['url']) + "\n" + |
0 | 1602 sprintf(msg('newpassword'), user, newp) + |
93 | 1603 sprintf("%s\n", msg('mischief'))) |
0 | 1604 @O.print @H.p(sprintf(msg('newaccount'), user)) |
1605 @O.print @H.p(@H.a(@myname, msg('login'))) | |
1606 throw :auth, nil | |
7 | 1607 else |
1608 outputError(msg('pswderror')) | |
1609 throw :auth, nil | |
0 | 1610 end |
1611 } | |
1612 if auth | |
1613 return true | |
1614 else | |
1615 return false | |
1616 end | |
1617 end | |
1618 def safecopy(string) | |
1619 return nil unless string | |
1620 if $SAFE > 0 | |
1621 cpy='' | |
1622 string.split('').each{|c| | |
1623 cpy << c[0].chr if c[0] != ?` # ` | |
1624 } | |
28 | 1625 cpy.untaint |
0 | 1626 else |
1627 string | |
28 | 1628 end |
0 | 1629 end |
1630 def checkmail(mail) | |
1631 account, domain = mail.scan(/(.*)@(.*)/)[0] | |
1632 return false unless account != nil && domain != nil | |
17 | 1633 return false unless /^[-0-9a-z_.]+$/oi =~ domain.toeuc |
0 | 1634 domain = safecopy(domain) |
1635 require 'socket' | |
1636 begin | |
1637 TCPSocket.gethostbyname(domain) | |
1638 return true | |
1639 rescue | |
1640 if test(?x, @opt["hostcmd"]) | |
1641 open("| #{@opt['hostcmd']} -t mx #{domain}.", "r") {|ns| | |
1642 #p ns.readlines.grep(/\d,\s*mail exchanger/) | |
1643 return ! ns.readlines.grep(/is handled .*(by |=)\d+/).empty? | |
1644 } | |
1645 elsif test(?x, @opt["nslookup"]) | |
1646 open("| #{@opt['nslookup']} -type=mx #{domain}.", "r") {|ns| | |
1647 #p ns.readlines.grep(/\d,\s*mail exchanger/) | |
1648 return ! ns.readlines.grep(/\d,\s*mail exchanger/).empty? | |
1649 } | |
1650 end | |
1651 return false | |
1652 end | |
1653 end # checkmail | |
1654 | |
1655 # Logging | |
1656 # | |
1657 def putLog(msg) | |
1658 msg += "\n" unless /\n/ =~ msg | |
1659 open(@opt["logfile"], "a+") {|lp| | |
1660 lp.print Time.now.to_s + " " + msg | |
1661 } | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1662 msg |
0 | 1663 end |
1664 | |
1665 def sendnotify(whom, subj, body) | |
1666 users = users() | |
1667 if grepgroup(whom) | |
1668 recipients = @sc.members(whom) | |
1669 else | |
1670 recipients=[whom] | |
1671 end | |
1672 for u in recipients | |
1673 if users.grep(u)[0] | |
1674 sendMail(mailaddress(u), subj, body) | |
1675 end | |
1676 end | |
1677 end | |
1678 | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1679 def dospool(dir, outhandle) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1680 seq=1 |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1681 seqfile=File.expand_path("seq", dir).untaint |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1682 spooldir=File.expand_path("spool", dir).untaint |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1683 test(?d, spooldir) or Dir.mkdir(spooldir) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1684 if test(?s, seqfile) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1685 seq=open(seqfile, "r"){|s|s.gets.to_i} |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1686 end |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1687 seq+=1 while test(?s, (newfile=sprintf("%s/%d", spooldir, seq))) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1688 open(newfile, "w") do |spoolfile| |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1689 countdone = nil |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1690 while line=STDIN.gets |
76
53e747495502
Bug-fix: Regexp matching should be done in euc-jp.
HIROSE Yuuji <yuuji@gentei.org>
parents:
75
diff
changeset
|
1691 if !countdone && /^X-ML-Name: / =~ line.toeuc |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1692 line += sprintf("X-Mail-Count: %d\n", seq) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1693 coutndone=true |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1694 end |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1695 spoolfile.print line |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1696 outhandle.print line |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1697 end |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1698 end |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1699 open(seqfile, "w"){|s| s.puts seq.to_s} # update `seq' file |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1700 end |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1701 def mlseq(dir) |
65
3e91dd66deb6
Return 1 if /seq file is not there.
HIROSE Yuuji <yuuji@gentei.org>
parents:
64
diff
changeset
|
1702 test(?s, (seqfile = dir+"/seq")) ? |
3e91dd66deb6
Return 1 if /seq file is not there.
HIROSE Yuuji <yuuji@gentei.org>
parents:
64
diff
changeset
|
1703 open(seqfile, "r"){|s|s.gets.to_i+1} |
3e91dd66deb6
Return 1 if /seq file is not there.
HIROSE Yuuji <yuuji@gentei.org>
parents:
64
diff
changeset
|
1704 : 1 |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1705 end |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1706 def sendMail(to, subject, body, from=nil, rcptto=nil, header={}, |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1707 thru=nil, spoolto=false) |
87 | 1708 # rcptto should be an Array or nil |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1709 body = NKF.nkf("-j", body) unless thru |
85 | 1710 subject = NKF.nkf("-jM", (subject||"No subject").strip) |
0 | 1711 to = safecopy(to) # cleanup tainted address |
1712 subject.gsub!(/\n/, '') | |
87 | 1713 rcptto.reject!{|i| /^(skip|off):/i =~ i} if rcptto.is_a?(Array) |
0 | 1714 begin |
1715 if (m=open("|-", "w")) | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1716 header.each do |h, v| |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1717 m.printf("%s: %s\n", h.strip, v.strip) |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1718 end |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1719 unless thru |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1720 m.print "To: #{to}\n" |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1721 from and m.print "From: #{from}\n" |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1722 m.print "Subject: #{subject}\n" |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1723 m.puts "Mime-Version: 1.0 |
0 | 1724 Content-Transfer-Encoding: 7bit |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1725 Content-Type: Text/Plain; charset=iso-2022-jp" |
82
0ca2c48f8387
Refrain from putting Date: header at mail injection(with sendmail command).
HIROSE Yuuji <yuuji@gentei.org>
parents:
81
diff
changeset
|
1726 # m.puts "Date: #{Time.now.strftime("%a, %d %b %Y %T %z")}" |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1727 m.print "\n" |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1728 end |
85 | 1729 m.write body |
0 | 1730 m.close |
1731 else | |
1732 # exec(@attr['mail'], "-s", subject, to) | |
50
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
1733 recipient = rcptto || to.split(/,\s*|\s+/) |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1734 #p recipient |
56 | 1735 File.umask(027) |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1736 if spoolto && spoolto.is_a?(String) && |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1737 proc { |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1738 require 'fileutils' |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1739 begin |
67
a421c2fefc32
Fix the argument for FileUtils.mkdir_p()
HIROSE Yuuji <yuuji@gentei.org>
parents:
66
diff
changeset
|
1740 test(?d, spoolto) or FileUtils.mkdir_p(spoolto, :mode => 0750) |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1741 test(?w, spoolto) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1742 rescue |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1743 nil |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1744 end}.call && |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1745 (tee=open("|-", "w")) # popen should be done in if-condition |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1746 dospool(spoolto, tee) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1747 else |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1748 if ENV['MAILCMD'] |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1749 #exec("qmail-inject", "yuuji@gentei.org", "yuuji@koeki-u.ac.jp") |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1750 open("/tmp/body", "w") {|w| w.print STDIN.readlines.join |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1751 w.puts "---" |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1752 w.puts recipient.join(",\n") |
85 | 1753 w.puts header.inspect |
1754 w.puts "ENV: #{ENV.inspect}" | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1755 } |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1756 exit 0 |
85 | 1757 elsif header['Return-path'] && /-@/ =~ header['Return-path'] |
1758 # if VERP is requested | |
1759 mailcmd = ENV['MAILCMD'] || @opt['sendmail'] | |
1760 contents = STDIN.readlines | |
1761 recipient.uniq.each {|r| | |
1762 local, domain = header['Return-path'].split("@") | |
1763 newlocal = local+r.sub("@", "=") | |
1764 verp = newlocal+"@"+domain | |
1765 verp = safecopy(verp) | |
1766 open("| #{mailcmd} -f#{verp} -- #{r}", "w") {|m| | |
1767 m.write contents.join | |
1768 } | |
1769 } | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1770 else |
85 | 1771 recipient.unshift "-f"+header['Return-path'] if header['Return-path'] |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1772 exec(ENV['MAILCMD'] || @opt['sendmail'], *recipient) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
1773 end |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
1774 end |
0 | 1775 exit 0; |
1776 end | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
1777 putLog("Sent '#{subject.toeuc}' to #{to}\n") |
0 | 1778 return true |
1779 rescue | |
1780 putLog("FAILED! - Sent '#{subject}' to #{to}\n") | |
1781 return nil | |
1782 end | |
1783 end # sendMail | |
1784 | |
1785 def today() | |
1786 today = Time.now | |
1787 showtable(today) | |
1788 end | |
1789 def isleap?(y) | |
1790 if y%400 == 0 | |
1791 true | |
1792 elsif y%100 == 0 || y%4 != 0 | |
1793 false | |
1794 else | |
1795 true | |
1796 end | |
1797 end | |
1798 def daysofmonth(year, month) | |
1799 dl = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] | |
1800 if month != 2 || !isleap?(year) | |
1801 dl[month-1] | |
1802 else | |
1803 29 | |
1804 end | |
1805 end | |
1806 # | |
1807 # Return the Time object at the last day of last month | |
1808 def lastmonth(today) | |
1809 Time.at(Time.mktime(today.year, today.month)-3600*24) | |
1810 end | |
1811 # | |
1812 # Return the Time object at the first day of next month | |
1813 def nextmonth(today) | |
1814 y, m = today.year, today.month | |
1815 Time.at(Time.mktime(y, m, daysofmonth(y, m))+3600*24) | |
1816 end | |
1817 | |
1818 def month(month) | |
1819 y, m = month.scan(%r,(\d\d\d\d+)/(\d+),)[0] | |
1820 if y && m | |
1821 showtable(Time.mktime(y, m, 1)) | |
1822 else | |
1823 outputError "%s %s", msg('invaliddate'), month | |
1824 return nil | |
1825 end | |
1826 end | |
1827 def footer1() | |
1828 "<br>" + \ | |
1829 @H.element("p"){ | |
1830 me = @myname+"?-"; delim = " / " | |
1831 @H.a(me+'userman', msg('user', 'management')) + delim + \ | |
2 | 1832 @H.a(me+'groupman', msg('group', 'management')) + delim + \ |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1833 if /^personal/i =~ @params['displaymode'] |
2 | 1834 @H.a(me+'today_n', msg('normalmode')) |
1835 else | |
1836 @H.a(me+'today_p', msg('personalmode')) | |
1837 end | |
0 | 1838 } |
1839 end | |
1840 | |
1841 def footer2() | |
1842 "<hr>" + \ | |
1843 @H.element("code") { | |
1844 "This " + \ | |
1845 @H.a(@after5url, "After5") + \ | |
1846 " board is maintained by " + \ | |
55
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
1847 @opt['maintainer'].gsub(".", "<span>.</span>"). |
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
1848 sub('@', "@") + \ |
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
1849 '<span style="display: none;">.cut.here</span>' + \ |
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
1850 "." |
0 | 1851 } |
1852 end | |
1853 def footer() | |
1854 footer1+footer2 | |
1855 end | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1856 def header_filter() |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1857 filter = @params['displayfilter'] |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1858 if filter && filter > "" |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1859 myarg = (ENV['REQUEST_URI']||"-today").sub(/.*\?/, "") |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1860 @H.elementln("form", {'action'=>@myname+"?"+myarg, "method"=>"POST"}) { |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1861 @H.elementln("p", {"class"=>"filter"}) { |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1862 @H.element("span") { |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1863 msg('filter')+"="+filter |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1864 } + \ |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1865 @H.hidden("displayfilter", "") + \ |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1866 @H.submit("GO", msg('filterreset')) |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1867 } |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1868 } |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1869 else |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1870 "" |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1871 end |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1872 end |
0 | 1873 def nickname(userORgroup) |
1874 if grepgroup(userORgroup) | |
1875 @sc.groupname(userORgroup) | |
1876 else | |
1877 @sc.nickname(userORgroup) | |
1878 end | |
1879 end | |
1880 # | |
1881 # show specified month's calendar | |
1882 def showtable(day) | |
1883 if !checkauth | |
1884 return nil | |
1885 end | |
17 | 1886 |
0 | 1887 month = day.month.to_s |
1888 first = Time.mktime(day.year, day.month, 1) | |
1889 last = daysofmonth(day.year, day.month) | |
1890 wday1 = first.wday | |
1891 start = 1-wday1 | |
3 | 1892 wname = @wnames |
0 | 1893 today = Time.now |
8 | 1894 todayy = today.year |
0 | 1895 todaym = today.month |
1896 todayd = today.day | |
1897 tdclass = {} | |
1898 tdclass["width"] = "64px" if @oldagent # workaround for NN4 | |
2 | 1899 personal = /personal/ =~ @params['displaymode'] |
3 | 1900 headline = @params['headline'] |
6 | 1901 headlinehl = @params['headlinehl'] |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1902 filter = @params['displayfilter'] |
6 | 1903 hldays = headlinehl.to_i * 3600*24 |
1904 recent = {'class'=>'recent'} | |
3 | 1905 monthstr = sprintf "%d/%d", day.year, day.month |
1906 | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1907 |
0 | 1908 holiday = Holiday.new |
1909 # create dayofweek header | |
3 | 1910 @O.print @H.elementln("h1", nil){monthstr} |
2 | 1911 # which mode? |
1912 @O.print @H.p(msg(personal ? 'personalmode' : 'normalmode')) | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1913 # @O.print @H.p(sprintf("filter=%s", filter)) |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1914 @O.print header_filter() |
2 | 1915 # display table |
0 | 1916 @O.print @H.startelement("table", {'border'=>"1", 'class'=>'main'}) |
1917 | |
1918 # day of week | |
1919 @O.print @H.startelement("tr") | |
1920 for w in wname | |
1921 @O.print @H.element("th", {'class'=>w}){w.capitalize} | |
1922 end | |
1923 @O.print "\n"+@H.endelement(nil, true) | |
1924 | |
1925 # create day table | |
1926 column = start | |
1927 ## p day, last | |
1928 while column <= last | |
1929 @O.print @H.elementln("tr", nil){ | |
1930 (column..column+6).collect{|d| | |
8 | 1931 todayp = (day.year==todayy && day.month==todaym && d==todayd) |
0 | 1932 wd=d-column |
75 | 1933 thisday = first+(d-1)*3600*24 |
72
6a0c2f85faa3
Canonicalize arguments for isHoliday(), which will be sent to Time.mktime().
HIROSE Yuuji <yuuji@gentei.org>
parents:
71
diff
changeset
|
1934 hd = holiday.isHoliday(thisday.year, thisday.month, thisday.day, wd) |
0 | 1935 tdclass['class'] = (hd ? 'holiday' : wname[wd]) |
1936 @H.element("td", tdclass){ | |
13 | 1937 if d>0 |
1938 #date = "%d/%d/%d"%[day.year, day.month, d] | |
1939 date = "%d/%d/%d"%[thisday.year, thisday.month, thisday.day] | |
0 | 1940 @H.element("p", {'class'=>todayp ? 'todayline' : 'dayline'}){ |
13 | 1941 ##@H.a(@myname+"?-show+"+date, "%4d"%d) |
1942 @H.a(@myname+"?-show+"+date, "%4d"%thisday.day) | |
0 | 1943 } + \ |
1944 # isHoliday? | |
1945 if hd | |
1946 @H.element("small"){hd.join("<br>")} | |
1947 end.to_s + \ | |
1948 @H.element("p", {'class'=>'topic'}){ | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
1949 s = @sc.day_all(date, @params['user'], personal, filter) |
0 | 1950 if !s.empty? |
1951 s.keys.sort.collect{|time| | |
1952 s[time].keys.sort.collect{|who| | |
32
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
1953 text = escape(s[time][who]['sched']) |
6 | 1954 topic = sprintf "%s%s", |
3 | 1955 time == @opt['alldaydir'] ? '' : time+":", |
2 | 1956 if personal |
9 | 1957 (@params['user'] == who ? "" : nickname(who)+"=") + |
7 | 1958 text ## .split("\n") ##[0] |
2 | 1959 else |
5 | 1960 nickname(who) + \ |
3 | 1961 if headline == 'whole' |
5 | 1962 '=' + text |
3 | 1963 elsif headline == 'head5char' |
5 | 1964 '=' + text.gsub(/\n/, '').sub(/(.{5}).*/, '\1') |
3 | 1965 elsif headline == 'headline' |
5 | 1966 '=' + text.split("\n")[0] |
3 | 1967 end.to_s |
2 | 1968 end |
6 | 1969 if hldays > 0 && |
1970 (today - s[time][who]['regtime']) < hldays | |
1971 topic = @H.element("span", recent){topic} | |
1972 end | |
1973 topic | |
3 | 1974 }.join("<br>") |
1975 }.join("<br>\n") | |
0 | 1976 else |
1977 @opt['tdskip'] | |
1978 end | |
1979 } | |
1980 else | |
1981 @opt['tdskip'] | |
1982 end | |
1983 } | |
1984 }.join | |
1985 } | |
1986 column += 7 | |
1987 end | |
1988 | |
1989 # month-link | |
1990 @O.print @H.elementln("tr", {'class'=>'monthlink'}){ | |
1991 lm1 = lastmonth(day) | |
1992 lm2 = lastmonth(lm1) | |
1993 lm3 = lastmonth(lm2) | |
1994 nm1 = nextmonth(day) | |
1995 nm2 = nextmonth(nm1) | |
1996 nm3 = nextmonth(nm2) | |
1997 [lm3, lm2, lm1, nil, nm1, nm2, nm3].collect{|t| | |
1998 @H.element("td"){ | |
1999 if t.is_a?(Time) | |
2000 ym = sprintf("%d/%d", t.year, t.month) | |
2001 @H.a(sprintf("%s?-month+%s", @myname, ym), ym) | |
2002 else | |
2003 sprintf "%d/%d", day.year, day.month | |
2004 end | |
2005 } | |
2006 }.join("\n") | |
2007 } | |
2008 @O.print "\n"+@H.endelement(nil, true) | |
2009 | |
2010 @O.print "showtable" if @params['user'] == @author | |
3 | 2011 @O.print @H.elementln("form", {'action'=>@myname+"?-month+#{monthstr}", 'method'=>'POST'}){ |
2012 choice = [ | |
2013 [msg('nameonly'), 'name'], | |
2014 [msg('head5char'), 'head5char'], | |
2015 [msg('headline'), 'headline'], | |
2016 [msg('whole'), 'whole']] | |
2017 msg('display') + \ | |
6 | 2018 @H.select('headline', choice, headline) + "/" + \ |
2019 msg('hldays') + \ | |
2020 @H.select('headlinehl', 0..30, headlinehl) + \ | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2021 @H.element("abbr", {"title"=>msg('filterhelp')}) {msg('filter')} + \ |
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2022 @H.text('displayfilter', @params['displayfilter'], 10, 80) +\ |
3 | 2023 @H.submit("GO", "GO") |
2024 } | |
0 | 2025 @O.print footer |
2026 ##schedule.day_all("2003/12/22") | |
2027 # @O.print @H.endelement() | |
2028 end | |
2029 | |
2030 # | |
2031 # Put carrying values | |
2032 def hiddenvalues() | |
2 | 2033 h = %w[user displaymode].collect{|v| |
0 | 2034 if @params[v] |
2035 sprintf "<input type=\"hidden\" name=\"%s\" value=\"%s\">\n", | |
2036 v, @params[v] | |
2037 end | |
2038 } | |
2039 h.delete(nil) | |
2040 h.join | |
2041 end | |
2 | 2042 def date2ymd(date) |
2043 %r,(\d\d\d\d+)/(\d\d?)/(\d\d?), =~ date and | |
2044 [$1.to_i, $2.to_i, $3.to_i] | |
2045 end | |
0 | 2046 # |
2047 # Return the string of table | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2048 def dayTableString(user, datestr, range, personal = nil, filter = nil) |
2 | 2049 #s = @sc.day_all(date, user, personal) |
2050 #return '' if s.empty? | |
0 | 2051 r = '' |
2 | 2052 header = @H.startelement("table", {'border'=>'1'}, true) |
2053 | |
2054 day = Time.mktime(*date2ymd(datestr)) | |
2055 i = -1 | |
2056 while (i+=1) < range | |
2057 d = Time.at(day+i*3600*24) | |
2058 date = sprintf("%04d/%02d/%02d", d.year, d.month, d.day) | |
3 | 2059 datewn = @H.element("span", {'class'=>@wnames[d.wday]}){ |
2060 sprintf("%s(%s)", date, @msg['wnames'][@lang][d.wday]) | |
2061 } | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2062 s = @sc.day_all(date, user, personal, filter) |
2 | 2063 next if s.empty? |
2064 | |
2065 r << @H.element("tr", nil){ | |
2066 @H.element("th", {'class'=>'time'}){'TIME'} + \ | |
3 | 2067 @H.element("th", nil){'Who - '+datewn+' - What'} |
2 | 2068 } |
6 | 2069 for time in s.keys.sort |
2 | 2070 tstr = case time |
2071 when @opt['alldaydir'] | |
2072 msg('allday') | |
2073 else | |
2074 sprintf "%02d:%02d", time.to_i/100, time.to_i%100 | |
2075 end | |
2076 r << @H.startelement("tr", nil, true) | |
2077 r << @H.element("th", {'class'=>'time'}){tstr} | |
2078 r << @H.element("td"){ | |
2079 @H.elementln("table"){ | |
2080 s[time].keys.collect{|who| | |
2081 editable = (user==who || @sc.ismember(user, who)) | |
2082 groupp = grepgroup(who) | |
2083 @H.element("tr"){ | |
2084 @H.element("td", {'class'=>groupp ? 'group' : 'who'}){ | |
2085 if !groupp && webpage(who) | |
2086 @H.a(webpage(who), nickname(who)) | |
2087 else | |
2088 nickname(who) | |
2089 end | |
2090 } + \ | |
2091 @H.element("td"){ | |
2092 if editable | |
2093 s[time][who]['pub'] ? msg('public') : | |
2094 msg('nonpublic') | |
2095 else | |
2096 @opt['tdskip'] | |
2097 end | |
2098 } + \ | |
2099 @H.element("td"){ | |
2100 if editable | |
2101 @H.a(@myname+"?-modify+#{date}/#{time}/#{who}", | |
2102 msg('modify')) | |
2103 else | |
2104 @opt['tdskip'] | |
2105 end | |
2106 } + \ | |
2107 @H.element("td"){ | |
2108 if editable | |
2109 @H.a(@myname+"?-remove+#{date}/#{time}/#{who}", | |
2110 msg('remove')) | |
2111 else | |
2112 @opt['tdskip'] | |
2113 end | |
2114 } + \ | |
14 | 2115 @H.element("td"){ |
2116 if editable | |
2117 @H.a(@myname+"?-move+#{date}/#{time}/#{who}", | |
2118 msg('move')) | |
2119 else | |
2120 @opt['tdskip'] | |
2121 end | |
2122 } + \ | |
32
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
2123 @H.element("td"){escape(s[time][who]['sched'])} |
2 | 2124 } |
2125 }.join("\n") | |
2126 } | |
0 | 2127 } |
2 | 2128 r << @H.endelement() |
2129 end | |
0 | 2130 end |
2 | 2131 footer = @H.endelement() |
2132 if r > '' | |
2133 header + r + footer | |
2134 else | |
2135 '' | |
2136 end | |
0 | 2137 end |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2138 def dayTextString(user, datestr, range, personal = nil, filter = nil) |
14 | 2139 r = '' |
2140 cols = 20 | |
2141 header = "-" * cols + "\n" | |
2142 | |
2143 day = Time.mktime(*date2ymd(datestr)) | |
2144 i = -1 | |
2145 while (i+=1) < range | |
2146 d = Time.at(day+i*3600*24) | |
2147 date = sprintf("%04d/%02d/%02d", d.year, d.month, d.day) | |
2148 datewn = sprintf("%s(%s)", date, @msg['wnames'][@lang][d.wday]) | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2149 s = @sc.day_all(date, user, personal, filter) |
14 | 2150 next if s.empty? |
2151 | |
2152 r << sprintf("TIME Who %s - What\n", datewn) | |
2153 | |
2154 for time in s.keys.sort | |
2155 tstr = case time | |
2156 when @opt['alldaydir'] | |
2157 msg('allday') | |
2158 else | |
2159 sprintf "%02d:%02d", time.to_i/100, time.to_i%100 | |
2160 end | |
2161 r << s[time].keys.collect{|who| | |
2162 editable = (user==who || @sc.ismember(user, who)) | |
2163 groupp = grepgroup(who) | |
32
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
2164 sprintf("%-5s %-10s %s", |
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
2165 tstr, nickname(who), escape(s[time][who]['sched'])) |
14 | 2166 }.join("\n") + "\n" |
2167 end | |
2168 r << "-" * cols + "\n" | |
2169 end | |
2170 footer = "That's all\n" | |
2171 if r > '' | |
2172 header + r + footer | |
2173 else | |
2174 '' | |
2175 end | |
2176 | |
2177 end | |
0 | 2178 # |
2 | 2179 # new form |
2180 def displayRegistForm(date, multiple = true) | |
0 | 2181 # |
2182 # Link button to add new plan | |
2183 #now = Time.now+3600*24 | |
2 | 2184 thisyear, thismonth, thisday = date.scan(%r,(\d\d\d\d+)/(\d+)/(\d+),)[0] |
2185 user = @params['user'] | |
0 | 2186 now = Time.mktime(thisyear, thismonth, thisday.to_i, Time.now.hour) |
2187 y, m, d, h, min = now.year, now.month, now.day, now.hour, now.min | |
2 | 2188 nextweek = Time.at(now+3600*24*7) |
2189 ey, em, ed = nextweek.year, nextweek.month, nextweek.day | |
2190 rcsp = (multiple ? {'colspan'=>'2'} : nil) | |
2191 wnames = @msg['wnames'][@lang] | |
2192 wnames << @msg['everyday'][@lang] | |
2193 | |
0 | 2194 @O.print @H.element('h2', nil, true){msg('addsched')} |
2195 @O.print @H.element('p', nil){msg('defthisday')} | |
2 | 2196 |
0 | 2197 @O.print @H.element("form", {'action'=>@myname+"?-addsched", 'method'=>'POST'}){ |
2 | 2198 border1 = {'border'=>'1'} |
2199 border1c = {'border'=>'1', 'class'=>'c'} | |
2200 mygroup = @sc.groups().select{|g|@sc.ismember(user, g)} | |
0 | 2201 @H.elementln('table', border1){ |
2202 @H.elementln('tr'){ | |
2203 @H.element('th'){'Name'} + \ | |
2 | 2204 @H.element('td', rcsp){ |
0 | 2205 hiddenvalues() + @sc.nickname(user) |
2206 } | |
2207 } + \ | |
2208 @H.elementln('tr'){ | |
2209 @H.element('th'){'Year'} + \ | |
2 | 2210 @H.element('td'){@H.select("year", y..y+5, y)} + \ |
2211 if multiple | |
2212 @H.element('td'){ | |
2213 d1 = msg('singleday') | |
2214 msg('through')+@H.select("endyear", [d1]+(y..y+5).to_a, d1) | |
2215 } | |
2216 end | |
0 | 2217 } + \ |
2218 @H.elementln('tr'){ | |
2219 @H.element('th'){'Month'} + \ | |
2 | 2220 @H.element('td'){@H.select("month", 1..12, m)} + \ |
2221 if multiple | |
2222 @H.element('td'){ | |
2223 msg('through')+@H.select("endmonth", 1..12, em) | |
2224 } | |
2225 end | |
0 | 2226 } + \ |
2227 @H.elementln('tr'){ | |
2228 @H.element('th'){'Day'} + \ | |
2 | 2229 @H.element('td'){@H.select("day", 1..31, d)} + \ |
2230 if multiple | |
2231 @H.element('td'){ | |
2232 msg('through')+@H.select("endday", 1..31, ed) | |
2233 } | |
2234 end | |
0 | 2235 } + \ |
2 | 2236 if multiple |
2237 @H.elementln('tr'){ | |
2238 @H.element('th'){ | |
2239 msg('whichday') | |
2240 } + \ | |
2241 @H.element('td', rcsp){ | |
2242 @H.elementln('table', border1c){ | |
2243 @H.element('tr'){ | |
2244 i=-1 | |
2245 wnames.collect{|w| | |
2246 @H.element('td'){ | |
2247 i+=1 | |
2248 @H.radio('whichday', i.to_s, '', i==wnames.length-1) | |
2249 } | |
2250 }.join("\n") | |
2251 } + \ | |
2252 @H.element('tr'){ | |
2253 i=-1 | |
2254 wnames.collect{|w| | |
2255 @H.element('td'){w} | |
2256 }.join | |
2257 } | |
2258 } | |
2259 } | |
2260 } | |
2261 end + \ | |
0 | 2262 @H.elementln('tr'){ |
2263 @H.element('th'){'Time<br>'+ \ | |
2264 sprintf(msg('24hour'), @opt['alldaydir'])} + \ | |
2 | 2265 @H.element('td', rcsp){ |
0 | 2266 '<input type=text name="time" value="3000" size=8 maxlength="4">' |
2267 } | |
2268 } + \ | |
2269 @H.elementln('tr'){ | |
2270 @H.element('th'){msg('publicok')} + \ | |
2 | 2271 @H.element('td', rcsp){ |
0 | 2272 @H.radio('pub', 'yes', msg('yes')+'<br>', true) + \ |
2273 @H.radio('pub', 'no', msg('no')) | |
2274 } | |
2275 } | |
2276 ## table | |
2277 } + \ | |
2278 @H.elementln("p"){ # put notify mail checkbox | |
2279 msg('reqnotify') + '<br>' + \ | |
2280 @ntlist.collect{|n, v| | |
8 | 2281 # Actual variables of notifylist for submitting is "sub_"+n |
2282 @H.checkbox("sub_"+n, 'yes', v, @params[n]) | |
0 | 2283 }.join("\n") + \ |
2284 " " + @H.checkbox('rightnow', 'yes', msg('rightnow'), true) + \ | |
2285 "\n" | |
2286 } + \ | |
2287 if mygroup[0] | |
2288 @H.elementln("p"){ # put "register as" | |
2289 msg('registas') + "<br>\n" + \ | |
2290 mygroup.collect{|g| | |
2291 @H.radio('registas', g, @sc.groupname(g)) | |
2292 }.join(' ') + "\n/ " + \ | |
2293 @H.radio('registas', 'no', msg('personal')) | |
2294 } | |
2295 end.to_s + "\n" + \ | |
2 | 2296 @H.radio('editmode', 'remove', 'Delete?') + " / " + \ |
2297 @H.radio('editmode', 'modify', 'Overwrite?') + " / " + \ | |
2298 @H.radio('editmode', 'append', 'Append?', true) + "<br>\n" + \ | |
36
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
2299 @H.element("p"){msg('headsched') + "<br>\n" + \ |
17 | 2300 @H.element("textarea", @schedulearea){}} + # textarea |
0 | 2301 @H.submit_reset("GO") |
2302 } #form | |
2 | 2303 end |
2304 # | |
2305 # show the schedule list of specified date | |
2306 # | |
2307 def show(date) | |
2308 if !checkauth | |
2309 return nil | |
2310 end | |
2311 user = safecopy(@params['user']) | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2312 personal = (/^personal/i =~ @params['displaymode']) |
2 | 2313 @params['displaydays'] = @params['displaydays'] || @cookie['displaydays'] |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2314 filter = @params['displayfilter'] |
3 | 2315 days = @params['displaydays'].to_i |
18 | 2316 days = (days > 0 ? days : 3) |
2 | 2317 |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2318 outstr = dayTableString(user, date, days, personal, filter) |
2 | 2319 |
2320 @O.print @H.element("h1", nil){ | |
2321 sprintf msg('fmtdaysschedule'), date | |
2322 } | |
18 | 2323 @O.print @H.element("h2"){msg('schedtable')} |
2 | 2324 ## @O.print @H.p() |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
2325 @O.print header_filter() |
2 | 2326 @O.print @H.elementln("form", {'action'=>@myname+"?-show+#{date}", 'method'=>'POST'}){ |
2327 @H.elementln("p"){ | |
6 | 2328 msg(personal ? 'personalmode' : 'normalmode') + "<br>" + \ |
2 | 2329 @H.select("displaydays", 1..30, days) + msg('daystodisplay') + \ |
2330 @H.submit("GO", "GO") | |
2331 } | |
2332 } | |
2333 if outstr > '' | |
2334 @O.print outstr | |
2335 else | |
2336 @O.print @H.p(msg('noplan')) | |
2337 end #is_empty? | |
2338 thisyear, thismonth, thisday = date.scan(%r,(\d\d\d\d+)/(\d+)/(\d+),)[0] | |
2339 mstr = sprintf "%04d/%02d", thisyear.to_i, thismonth.to_i | |
2340 @O.print @H.a(@myname+"?-month+"+mstr, | |
2341 sprintf(msg('tomonthlist'), mstr)) | |
2342 | |
2343 | |
2344 # | |
2345 # Display registration form | |
2346 displayRegistForm(date) | |
0 | 2347 @O.print "show" if user == @author |
2348 end | |
2349 | |
2350 # | |
2351 # call process | |
2352 def call_process(cmd, input=nil, timeout=10) | |
2353 prc = CMDTimeout.new | |
2354 fds = prc.start(cmd, timeout, true) | |
2355 if input | |
2356 Thread.start { | |
2357 fds[0].sync = true | |
2358 fds[0].print.input | |
2359 fds[0] | |
2360 } | |
2361 end | |
2362 begin | |
2363 fds[1].readlines | |
2364 ensure | |
2365 prc.close() | |
2366 end | |
2367 end | |
2368 # | |
2369 # notification registerer | |
2370 def notify_time(year, month, day, time, symbol) | |
2371 if (t = time.to_i) > 2359 | |
2372 hh = mm = 0 | |
2373 else | |
2374 hh, mm = t/100, t%100 | |
2375 end | |
2376 base = Time.mktime(year.to_i, month.to_i, day.to_i, hh, mm) | |
2377 if /nt(\d+)([mh])$/ =~ symbol | |
2378 return nil if t > 2359 | |
2379 num, unit = $1.to_i, $2.downcase | |
2380 rate = {'h'=>3600, 'm'=>60}[unit] || 3600 | |
2381 return Time.at(base-rate*num) | |
2382 elsif /nt(\d+)d/ =~ symbol | |
2383 seconds = $1.to_i*3600*24 | |
14 | 2384 tday= Time.at(base-seconds) |
2385 target = [tday.year, tday.month, tday.day, @opt['night'].to_i] | |
2386 targetnight = Time.mktime(*target) | |
0 | 2387 elsif "nttoday" == symbol |
2388 Time.mktime(year.to_i, month.to_i, day.to_i, @opt['morning']) | |
2389 end | |
2390 end | |
2391 def reg_notify(user, year, month, day, time, text, cancelall = nil) | |
6 | 2392 return nil unless @opt['notifymail'] |
0 | 2393 threshold = 5*60 # Omit notifycation within 30min future |
2394 | |
2395 y, m, d, t, = year.to_i, month.to_i, day.to_i, time.to_i | |
2396 if t > 2359 | |
2397 hh = mm = 0 | |
2398 else | |
2399 hh = t/100 | |
2400 mm = t%100 | |
2401 end | |
2402 now = Time.now | |
2403 | |
2404 filearg = [user, year, month, day, t] | |
2405 @ntlist.each{|k, v| | |
8 | 2406 # @params[k]s are always defined in cookies, so we use @params["sub_"+k] |
2407 @params[k] = @params["sub_"+k] | |
0 | 2408 nt_time = notify_time(year, month, day, t, k) |
2409 if !nt_time | |
2410 # do nothing for allday schedule's notification before some minutes | |
2411 elsif cancelall || nt_time < now+threshold || | |
2412 /yes|on|true|1/ !~ @params[k] || !@params[k] | |
2413 # cancel | |
2414 uf = @sc.remove_crondir(nt_time, user, year, month, day, t) | |
2415 @sc.removefile(*(filearg+[k])) | |
2416 else | |
2417 # register | |
2418 lf = @sc.register_crondir(nt_time, user, year, month, day, t) | |
2419 @sc.putfile(*(filearg+[k, lf])) | |
2420 end | |
2421 } | |
2422 end | |
2423 def cancel_notify(user, year, month, day, time) | |
2424 reg_notify(user, year, month, day, time, 'dummy', true) | |
2425 end | |
2 | 2426 |
2427 def commit_schedule(who, y, m, d, timedir, text, repl, pub) | |
2428 | |
2429 end | |
2430 | |
14 | 2431 def regulate_time(y, m, d, tm) |
2432 if tm > 2399 | |
2433 sh, smin = 23, 59 | |
2434 timedir=@opt['alldaydir'] | |
2435 tmstr = msg('allday') | |
2436 else | |
2437 sh = (tm/100).to_i | |
2438 smin = (tm%100).to_i | |
2439 timedir = sprintf("%04d", tm) | |
2440 tmstr = sprintf("%d:%02d", sh, smin) | |
2441 end | |
2442 time = nil | |
2443 begin | |
2444 time = Time.mktime(y, m, d, sh, smin) | |
2445 rescue | |
2446 outputError "%s<br>\nyear=%s<br>month=%s<br>day=%s<br>time=%s\n", | |
2447 msg('invaliddate'), | |
2448 @params['year'], @params['month'], @params['day'], @params['time'] | |
2449 return nil | |
2450 end | |
2451 [time, timedir, tmstr] | |
2452 end | |
2453 | |
0 | 2454 # |
2455 # add or remove a schedule | |
2456 # | |
2457 def add_remove(remove = nil) | |
2458 if !checkauth | |
2459 return nil | |
2460 end | |
2461 user = registerer = @params['user'] | |
2462 as = @params['registas'] | |
2463 if as && as > '' && /^no$/ !~ as && @sc.ismember(user, as) | |
3 | 2464 if (gr=grepgroup(as)) |
2465 registerer = gr | |
2466 end | |
0 | 2467 end |
2468 now = Time.now | |
2 | 2469 #y, m, d, h, min = now.year, now.month, now.day, now.hour, now.min |
0 | 2470 |
2471 $KCODE='e' if $DEBUG | |
2472 @O.print @params.inspect if $DEBUG | |
2473 # | |
2474 # Check the validity of specified time | |
2475 sy = @params['year'].to_i | |
2476 sm = @params['month'].to_i | |
2477 sd = @params['day'].to_i | |
2478 tm = @params['time'].to_i | |
14 | 2479 |
2480 time, timedir, tmstr = regulate_time(sy, sm, sd, tm) | |
2 | 2481 |
2482 # | |
2483 # Check continuous schedule registration | |
2484 wwday = @params['whichday'].to_i | |
2485 if @params['endyear'] && @params['endmonth'] && @params['endday'] && | |
2486 (ey=@params['endyear'].to_i) > 0 && | |
2487 (em=@params['endmonth'].to_i) > 0 && | |
2488 (ed=@params['endday'].to_i) > 0 | |
2489 daylist = [] | |
2490 endtime = Time.mktime(ey, em, ed, 23, 59) | |
2491 ti = time | |
2492 begin | |
2493 if wwday==7 || wwday==ti.wday | |
2494 daylist << [ti.year, ti.month, ti.day] | |
2495 end | |
9 | 2496 end while (ti=Time.at(ti+3600*24)) <= endtime |
2 | 2497 else |
2498 daylist = [[sy, sm, sd]] | |
2499 end | |
2500 | |
2501 if !remove && !(@params['schedule'] && @params['schedule'].strip > '') | |
0 | 2502 outputError msg('putsomething') |
2503 return nil | |
2504 end | |
2505 | |
2 | 2506 |
2507 for y, m, d in daylist | |
2508 # do remove or addition | |
2509 if remove | |
2510 cancel_notify(registerer, y, m, d, timedir) | |
2511 begin | |
2512 @sc.remove(registerer, y, m, d, timedir) | |
2513 #########@O.print @H.p(msg('remove')+msg('done')) | |
2514 rescue | |
2515 outputError("Failed"+$!) | |
2516 end | |
2517 else | |
2518 if time < now | |
2519 outputError(msg('past')) | |
2520 return nil | |
2521 end | |
2522 begin | |
32
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
2523 |
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
2524 (text = @params['schedule'].toeuc.strip.gsub(/\r+\n/, $/)) << "\n" |
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
2525 # text = purify(text) |
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
2526 STDERR.print text |
2 | 2527 replace = (/modify/i =~ @params['editmode']) |
2528 rc = @sc.register(registerer, y, m, d, timedir, text, replace) | |
2529 if @params['pub'] && /yes/ =~ @params['pub'] | |
2530 @sc.putfile(registerer, y, m, d, timedir, 'pub', "1\n") | |
2531 else | |
2532 @sc.removefile(registerer, y, m, d, timedir, 'pub') | |
2533 end | |
2534 ######## @O.print @H.p(msg('appended')) if rc == 1 | |
2535 rescue | |
2536 outputError("Failed"+$!) | |
2537 end | |
17 | 2538 text = @sc.getschedule(registerer, y, m, d, timedir) |
2 | 2539 reg_notify(registerer, y, m, d, timedir, text) |
2540 | |
0 | 2541 end |
2 | 2542 |
2543 end | |
2544 | |
2545 if !remove && @params['rightnow'] && /yes/i =~ @params['rightnow'] | |
2546 header = sprintf("%s\n%s/%s/%s%s %s %s\n%s%s%s\n%s\n", | |
2547 @opt['url'], | |
2548 sy, sm, sd, | |
2549 if daylist.length > 1 | |
2550 "-%s/%s/%s" % daylist[-1] | |
2551 end, | |
2552 tmstr, msg('immediatenote'), | |
2553 msg('registerer_is'), nickname(registerer), | |
2554 if user!=registerer | |
2555 sprintf(" (%s%s)", | |
2556 msg('registerer'), nickname(user)) | |
2557 else | |
2558 "" | |
2559 end, | |
2560 "-"*70) | |
2561 sendnotify(registerer, "Registration completed", header+text) | |
0 | 2562 end |
14 | 2563 unless @mailmode |
2564 show(sprintf("%04d/%02d/%02d", sy, sm, sd)) | |
2565 @O.print "add_remove" if user == @author | |
2566 end | |
0 | 2567 end |
2568 | |
2569 # add | |
2570 def addsched() | |
14 | 2571 if "move" == @params['editmode'] |
2572 add_remove(:remove) | |
2573 for p in %w(year month day time) do | |
2574 @params[p] = @params["new"+p] | |
2575 end | |
2576 end | |
2577 add_remove(/^remove/i =~ @params['editmode']) | |
0 | 2578 end |
2579 | |
2580 # | |
2581 # Display remove or modify screen | |
14 | 2582 def remove_modify(datetime, editmode) |
0 | 2583 if !checkauth |
2584 return nil | |
2585 end | |
2586 | |
2587 user = @params['user'] | |
2588 y, m, d, time, dummy, as = | |
2589 datetime.scan(%r,(\d\d\d\d+)/(\d+)/(\d+)/(\d+)(/(.+))?,)[0] | |
2590 # datetime always contains trailing slash generated by parsedate | |
2591 # but if the trailing part is a user(not a group), it is removed | |
2592 # because it filtered out by grepgroup() function | |
2593 if ! (y && m && d && time) | |
2594 outputError "Invalid time specification" | |
2595 return nil | |
2596 elsif as && as > '' | |
2597 unless @sc.ismember(user, as) | |
2598 outputError "You have no permission to edit group %s's schedule", as | |
2599 return nil | |
2600 end | |
2601 user = as | |
2602 end | |
2603 unless text=@sc.getschedule(user, y, m, d, time) | |
2604 outputError "%s %s", datetime, msg('noplan') | |
2605 return nil | |
2606 end | |
32
d23a2b3c456b
Save schedule text `as is' in a file and escape them for browser.
HIROSE Yuuji <yuuji@gentei.org>
parents:
31
diff
changeset
|
2607 ## text = decode(text) |
0 | 2608 @O.print @H.elementln("h1"){ |
14 | 2609 sprintf "%s %s", datetime, msg(editmode) |
0 | 2610 } |
2611 @O.print @H.elementln("form", {'action'=>@myname+"?-addsched", 'method'=>'POST'}){ | |
2612 pubp=(@sc.getfile(user, y, m, d, time, 'pub').to_i > 0) | |
2613 if as | |
2614 @H.hidden("registas", as) | |
2615 end.to_s + \ | |
2616 "<input type=\"hidden\" name=\"year\" value=\"%04d\">\n" % y.to_i + \ | |
2617 "<input type=\"hidden\" name=\"month\" value=\"%02d\">\n" % m.to_i + \ | |
2618 "<input type=\"hidden\" name=\"day\" value=\"%02d\">\n" % d.to_i + \ | |
2619 "<input type=\"hidden\" name=\"time\" value=\"%04d\">\n" % time.to_i + \ | |
14 | 2620 if editmode=="move" |
2621 @H.elementln("table") { | |
2622 @H.elementln("tr", {"colspan" => "2"}) {msg('newdate')} + \ | |
2623 @H.elementln("tr") { | |
2624 @H.element("th"){"Year"} + \ | |
2625 @H.element("td"){@H.select("newyear", y.to_i..y.to_i+5, y)} | |
2626 } + \ | |
2627 @H.elementln("tr") { | |
2628 @H.element("th"){"Month"} + \ | |
2629 @H.element("td"){@H.select("newmonth", 1..12, m)} | |
2630 } + \ | |
2631 @H.elementln("tr") { | |
2632 @H.element("th"){"Day"} + \ | |
2633 @H.element("td"){@H.select("newday", 1..31, d)} | |
2634 } + \ | |
2635 @H.elementln("tr") { | |
2636 @H.element("th"){"Time"} + \ | |
2637 @H.element("td"){ | |
2638 "<input type=text name=\"newtime\" value=\"#{time}\" " + \ | |
2639 "size=\"8\" maxlength=\"4\">" | |
2640 } | |
2641 } | |
2642 } | |
2643 end.to_s + \ | |
2644 @H.elementln("div", {"style" => | |
2645 "visibility: " + | |
2646 (editmode=="move" ? "hidden" : "show") + "\""}) { | |
2647 msg('reqnotify') + "<br>\n" + \ | |
2648 @ntlist.collect{|nt, v| | |
2649 cronp = @sc.getfile(user, y, m, d, time, nt) | |
91
9ed5d139232f
Should use sub_nt* instead of nt* in modifying mode
HIROSE Yuuji <yuuji@gentei.org>
parents:
90
diff
changeset
|
2650 sprintf "<input type=\"checkbox\" name=\"sub_%s\"%s>%s \n", |
14 | 2651 nt, (cronp ? " checked" : ""), v |
2652 }.join + "<br>" | |
2653 } + \ | |
0 | 2654 @H.element("textarea", @schedulearea) {text} + "<br>" + \ |
2655 @H.radio("editmode", "append", msg('append')) + ' / ' + \ | |
14 | 2656 @H.radio("editmode", "modify", msg('modify'), editmode=="modify")+' / '+\ |
2657 @H.radio("editmode", "remove", msg('remove'), editmode=="remove")+' / '+\ | |
2658 @H.radio("editmode", "move", msg('move'), editmode=="move") + ' / ' + \ | |
0 | 2659 "<br>\n" + \ |
2660 msg('publicok') + \ | |
2661 @H.radio("pub", "yes", msg('yes'), pubp) + \ | |
2662 @H.radio("pub", "no", msg('no'), !pubp) + \ | |
2663 '<br>' + \ | |
2664 @H.submit_reset("GO") | |
2665 } | |
2666 @O.print "remove_modify" if user == @author | |
2667 end | |
2668 def remove(datetime) | |
14 | 2669 remove_modify(datetime, "remove") |
0 | 2670 end |
2671 def modify(datetime) | |
14 | 2672 remove_modify(datetime, "modify") |
2673 end | |
2674 def move(datetime) | |
2675 remove_modify(datetime, "move") | |
0 | 2676 end |
2677 | |
2678 def prohibitviahttp() | |
2679 %w[REMOTE_ADDR REMOTE_HOST SERVER_NAME].each{|v| | |
2680 if ENV[v] | |
2681 print "Content-type: text/plain\n\n" | |
2682 print "Do not call this via CGI" | |
2683 exit 0 | |
2684 end | |
2685 } | |
2686 end | |
2687 # | |
2688 # notify: call via cron | |
2689 def notify() | |
2690 prohibitviahttp() | |
2691 unless @opt['maintainer'] | |
2692 STDERR.printf "Set maintainer(email-address) in %s\n", @opt['conf'] | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2693 STDERR.print "(ex.) maintainer=yuuji@gentei.org\n" |
0 | 2694 exit 0 |
2695 end | |
2696 Dir.chdir @mydir | |
2697 line = "-"*25 | |
2698 indent = " " | |
2699 now = Time.now | |
78 | 2700 ntlist = @sc.notify_list(now) |
2701 p "notifylist", ntlist if $DEBUG | |
2702 ntlist.each{|u, datehash| | |
0 | 2703 dellist = [] |
2704 content = datehash.sort.collect{|date, filehash| | |
2705 next unless /(\d\d\d\d+)-(\d+)-(\d+)-(\d\d\d\d)/ =~ date | |
2706 y, m, d, t = $1.to_i, $2.to_i, $3.to_i, $4.to_i | |
11 | 2707 ddiff=(Time.mktime(y, m, d) \ |
2708 - Time.mktime(now.year, now.month, now.day))/3600/24 | |
0 | 2709 if t > 2359 |
2710 hhmm = msg('allday') | |
11 | 2711 if ddiff > 1 |
2712 comment = "%d%s" % [ddiff, msg('days', 'before')] | |
2713 else | |
2714 comment = msg(now.hour > 18 ? 'precedingday' : 'theday') | |
2715 end | |
0 | 2716 else |
2717 hhmm = sprintf "%02d:%02d", t/100, t%100 | |
2 | 2718 diff = Time.mktime(y, m, d, t/100, t%100) - now |
0 | 2719 if diff < 7200 |
2720 comment = "%d%s" % [diff/60, msg('minutes', 'before')] | |
11 | 2721 elsif (ddiff == 0) |
0 | 2722 comment = "%s%d%s" % |
2723 [msg('about'), diff/3600, msg('hours', 'before')] | |
2724 else | |
2725 comment = "%d%s" % [ddiff, msg('days', 'before')] | |
2726 end | |
2727 end | |
2728 dellist << filehash['file'] | |
2729 sprintf("%s[[[%d/%d/%d %s]]]%s\n", line, y, m, d, hhmm, line) + \ | |
2730 sprintf("(%s %s)\n", comment, msg('notification')) + \ | |
31
aceb533dfa32
Schedule file is already decoded. No need to decode again.
HIROSE Yuuji <yuuji@gentei.org>
parents:
30
diff
changeset
|
2731 indent+filehash['text'].join(indent) + "\n\n" |
0 | 2732 } |
2733 # content.delete(nil) | |
2734 if content | |
2735 if $DEBUG | |
2736 print content | |
2737 else | |
2738 content.unshift(msg('introduce')+"\n"+msg('notifymail')+"\n") | |
2739 content.unshift(@opt['url'].to_s+"\n") | |
2740 if sendnotify(u, msg('notifysubj'), content.join) | |
2741 # send mail completed | |
2742 begin | |
2743 @sc.cleanup_files(dellist) | |
2744 rescue | |
2745 end | |
2746 end | |
2747 end | |
2748 end | |
2749 } | |
79 | 2750 if !(list = @sc.notify_list(now)).empty? |
0 | 2751 subj = @mybase+": Undeleted old cron files detected" |
79 | 2752 files = list.collect{|who, whash| |
0 | 2753 whash.sort.collect{|date, fhash| fhash['file']}.join("\n") |
2754 }.join("\n") | |
2755 sendMail(@opt['maintainer'], subj, | |
2756 "This is `#{@mybase}' in #{@mydir}\n" + | |
2757 "You'd better check and remove these files.\n\n"+files) | |
2758 end | |
2759 | |
2760 exit 0 | |
2761 end | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2762 # ML functions |
47 | 2763 def parseaddress(spec) # from catchup.rb |
2764 # Return [email, comment] | |
2765 # nil if comment does not exitst. | |
2766 if /(.*)\s*<(.*)>/ =~ spec then | |
2767 [$2, $1.strip] | |
2768 elsif /(.*)\s*\((.*)\)/ =~ spec then | |
2769 [$1.strip, $2] | |
2770 else | |
2771 [spec.strip, nil] | |
2772 end | |
2773 end | |
2774 def rewritefrom(email, comment, newseed) # from catchup.rb | |
2775 # no need to setcomment here because if comment set, it's enough | |
2776 comment.sub!(/(\"?)(.*)\1/, '\2') | |
2777 comment += "/" if comment>"" | |
2778 return comment.gsub(/([^\x00-\x7f]+)/){NKF.nkf('-jM', $1)} + | |
2779 email.sub("@", "=")+" <"+newseed+">" | |
2780 # end | |
2781 end | |
2782 | |
2783 def tagify_subj(body, tag, removeregexp, fromhack = nil) | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
2784 # This method should be generic for other headers than `Subject'? |
40 | 2785 hold = [] |
2786 ret = [] | |
2787 skip = false | |
2788 while line = body.shift | |
2789 case line.toeuc | |
85 | 2790 # #Below does not work correctly when (from|subject): is final line |
2791 # when /^$/ | |
2792 # hold << "\n" | |
2793 # break | |
2794 # ## when /^(subject|from): /i | |
2795 when /^(\S+): /i, /^$/ # if new header comes or header ends | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2796 if /^subject:/i =~ hold[0] # check previous header in hold space |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2797 sj = hold.join.toeuc.sub("Subject: ", "").gsub(tag, "").strip |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2798 removeregexp && sj && sj.gsub!(removeregexp, "") |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2799 sj = sj.sub(/^(re: *)+/i, "Re: ").gsub("\n", "") |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2800 hold = ["Subject: "+NKF.nkf('-jM', tag+" "+sj).strip+"\n"] |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2801 elsif /^from/i =~ hold[0] && fromhack.is_a?(String) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2802 from = hold.join.toeuc.sub(/From: */i, "").strip |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2803 email, comment = parseaddress(from) |
92
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2804 if (!comment || comment=="") |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2805 if comment = @sc.ismembersemail(email) |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2806 # Reverse conversion of uname<->email |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2807 comment = @sc.nickname(comment) || "whoareyou" |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2808 else |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2809 comment = email # email from alien |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2810 end |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2811 end |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2812 hold = ["From: "+rewritefrom(email, comment, fromhack)+"\n"] |
89
00d203e72f8f
Put original received headers aside to reduce hop count
HIROSE Yuuji <yuuji@gentei.org>
parents:
88
diff
changeset
|
2813 elsif /^received:/i =~ line |
00d203e72f8f
Put original received headers aside to reduce hop count
HIROSE Yuuji <yuuji@gentei.org>
parents:
88
diff
changeset
|
2814 # Put original received headers aside to reduce hop count |
00d203e72f8f
Put original received headers aside to reduce hop count
HIROSE Yuuji <yuuji@gentei.org>
parents:
88
diff
changeset
|
2815 line = "X-pre"+line |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2816 end |
85 | 2817 if /^$/ =~ line.toeuc |
2818 hold << line | |
2819 break | |
2820 end | |
40 | 2821 ret += hold |
2822 hold = [line] | |
2823 when /^\s/ # continued line | |
2824 hold << line | |
2825 end | |
2826 end | |
2827 ret + hold + body | |
2828 end | |
92
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2829 def recompose_multipart(string) |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2830 /(\r?)\n\r?\n/ =~ string or return string |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2831 $1 > "" ? eol = "\r\n" : eol = "\n" |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2832 head, body = $`, $' |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2833 r = Hash.new |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2834 if %r,^Content-type:\s*text/plain,i =~ head |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2835 # open("/tmp/a", "a"){|a| a.printf("str=<<<%s>>>\n\n", string)} |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2836 r["name"] = ":TEXT" |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2837 r["value"] = body.sub(Regexp.new(".*?"+eol+eol, Regexp::MULTILINE), "") |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2838 return [head, r] |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2839 elsif %r,^Content-type:\s*(multipart/(.*));\s*boundary=([\'\"])?(.*)\3,mi =~ |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2840 head |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2841 ct, boundary = $1, $4 |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2842 [head] + body.split(eol+"--"+boundary).collect {|pc| |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2843 recompose_multipart(pc) |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2844 } |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2845 elsif %r,^Content-type:\s*(.*);\s*name=([\'\"])?(\S*)\2,mi =~ head |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2846 r["name"] = $3 |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2847 %r,filename=([\'\"])?(\S+)\1,mi =~ head |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2848 r["filename"] = $2 |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2849 content = body.sub(Regexp.new(".*?"+eol+eol, Regexp::MULTILINE), "") |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2850 r['value'] = content |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2851 return [head, r] |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2852 end |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2853 end |
85 | 2854 def extract_attachment(attachment) |
2855 # Must return [text, href] strings to attached files | |
92
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2856 # Argument ATTACHMENT is a array of attached files. |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2857 # Each element is an Hash of a form of: |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
2858 # {'filename'=>name, 'value'=>content, 'content-type'=>contentType} |
85 | 2859 href = ""; text = "" |
87 | 2860 dir = @attachmentdir + Time.now.strftime("/%Y%m") |
85 | 2861 if %r,(https?://[^/]+), =~ @opt['url'] |
2862 server = $1 | |
2863 else | |
2864 msg = "`url' not set in after5.cf" | |
2865 return [msg, msg] | |
2866 end | |
87 | 2867 kakasi = @opt['kakasi'] && @opt['kakasi']+" -Ha -Ka -Ja -Ea -ka" |
85 | 2868 urlbase = sprintf("%s%s/%s", |
2869 server, File.dirname(ENV['SCRIPT_NAME']), dir) | |
2870 count=0 | |
2871 attachment.each {|a| | |
2872 basename = safecopy(File.basename(a['filename'])) | |
87 | 2873 encname = (kakasi ? |
2874 IO.popen(kakasi, "r+") do |k| | |
2875 k.puts basename | |
2876 k.close_write # force flush | |
2877 k.gets.chomp.downcase | |
2878 end | |
2879 : | |
2880 basename | |
96
65024f29b497
Filename escaping should not work on upper letters.
HIROSE Yuuji <yuuji@gentei.org>
parents:
95
diff
changeset
|
2881 ).gsub(/([^-_0-9a-z=,.@])/i){"~"+$1.unpack("H*")[0].to_s} |
87 | 2882 filename = safecopy(dir+"/"+encname) |
85 | 2883 umask = File.umask(022) |
2884 sz = a['value'].bytesize | |
2885 next if sz == 0 | |
2886 count += 1 | |
2887 if sz > @attachmentmax | |
2888 msg = sprintf("%d: %s is too large(%dMB), skipped\n", | |
2889 count, basename, sz/1024**2) | |
2890 text += msg; href += msg | |
2891 next | |
2892 end | |
2893 begin | |
87 | 2894 require 'fileutils' |
2895 (test(?d, dir) && test(?w, dir)) or FileUtils.mkdir_p(dir) | |
85 | 2896 open(filename, "w") {|x| x.write a['value']} |
2897 File.chmod(0664, filename) | |
87 | 2898 text += sprintf("%d: %s/%s\n", count, urlbase, encname) |
85 | 2899 href += sprintf("%d: <a href=\"%s\">%s/%s</a>\n", |
87 | 2900 count, filename, urlbase, encname) |
85 | 2901 rescue |
2902 ensure | |
2903 File.umask(umask) | |
2904 end | |
2905 } | |
2906 if count>0 | |
2907 text="\n\n[[Attached files below]]\n"+text | |
2908 href="[[Attached files]]\n"+href | |
2909 end | |
2910 [text.chomp, href.chomp] | |
2911 end | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2912 def defaultmladdress(name) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2913 prefix = (@opt['mailprefix'] || "") |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2914 dash = prefix > '' ? "-" : "" |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2915 sprintf("%s%s%s@%s", prefix, dash, name, @opt['maildomain']) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
2916 end |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2917 def list() |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2918 # For debug: |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2919 # LOCAL=1 DEFAULT=name ./after5.rb -list |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2920 # $DEFAULT is ML name |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2921 viamail = ENV['LOCAL'] && ENV['DEFAULT'] # called via mail |
85 | 2922 from = toadmin = groupmode = fromhack = extract_report = nil |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2923 unless @opt['mailprefix'] && @opt['maildomain'] |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
2924 if viamail |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
2925 STDERR.print msg('sendall_err') % [@opt['conf']] |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
2926 exit 0 |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
2927 else |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
2928 @O.print @H.elementln("pre"){msg('sendall_err') % [@opt['conf']]} |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
2929 return true |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
2930 end |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2931 end |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2932 if viamail then |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2933 prohibitviahttp() |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2934 name = unquoted(ENV['DEFAULT']) |
87 | 2935 user = @sc.ismembersemail(ENV['SENDER']) # should here be (,name)?? |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
2936 if Regexp.new("(.*)("+Regexp.quote(@mailadmsuffix)+")") =~ name |
58 | 2937 # To: GROUP/adm*@domain |
57
d089cb42619d
ML's return-path changed from maintainer to group owners.
HIROSE Yuuji <yuuji@gentei.org>
parents:
56
diff
changeset
|
2938 # -> Forward to group administrator(s) |
d089cb42619d
ML's return-path changed from maintainer to group owners.
HIROSE Yuuji <yuuji@gentei.org>
parents:
56
diff
changeset
|
2939 name, toadmin = $1, $2 |
58 | 2940 sendMail("dummy", 'dummy', # Original To: and Subject: go through |
57
d089cb42619d
ML's return-path changed from maintainer to group owners.
HIROSE Yuuji <yuuji@gentei.org>
parents:
56
diff
changeset
|
2941 STDIN.readlines.join, nil, @sc.admins(name), |
d089cb42619d
ML's return-path changed from maintainer to group owners.
HIROSE Yuuji <yuuji@gentei.org>
parents:
56
diff
changeset
|
2942 {"Return-path" => @opt['maintainer']}, :thru) |
d089cb42619d
ML's return-path changed from maintainer to group owners.
HIROSE Yuuji <yuuji@gentei.org>
parents:
56
diff
changeset
|
2943 exit 0 |
d089cb42619d
ML's return-path changed from maintainer to group owners.
HIROSE Yuuji <yuuji@gentei.org>
parents:
56
diff
changeset
|
2944 end |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2945 if @sc.isuser(name) # groupmode = nil |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2946 # First, compare with username |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2947 # groupmode = nil |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2948 # Then, check group name |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2949 elsif grepgroup(name) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2950 groupmode = true |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2951 else # not found |
56 | 2952 sendMail(@opt['maintainer'], "no group", |
2953 sprintf("Invalid group address: %s(%s@%s)\nSent by %s\n" + | |
2954 "URL: %s\n------------\n", | |
2955 name, ENV['LOCAL'], ENV['HOST'], ENV['SENDER'], | |
2956 @opt['url']) + | |
2957 "> "+STDIN.readlines.join("> ")) | |
2958 exit 0 # should exit 0 in mail mode | |
2959 end | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2960 else # via http |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2961 return nil unless checkauth |
85 | 2962 # HERE CGI Params name, subject, attachment and body |
2963 # comes with enctype=multipart/form-data, | |
2964 # So we get them via Array | |
2965 name = unquoted(@params['name'][0]['value'].untaint) | |
2966 user = @params['user'] | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2967 if @sc.isuser(name) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2968 # groupmode = nil |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2969 elsif grepgroup(name) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2970 groupmode = true |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2971 else |
56 | 2972 @O.print @H.p("No such group: #{name}") |
2973 return true | |
2974 end | |
85 | 2975 nick = @sc.nickname(user) |
2976 from = sprintf("%s <%s>", nick, user) | |
87 | 2977 subj = @params['subject'][0]['value'].toeuc || "Message from "+@myname |
85 | 2978 body = @params['body'][0]['value'].gsub("\r", "").untaint |
2979 # Extract attachment file | |
2980 if @params['attachment'].is_a?(Array) | |
2981 body += (extract_report = extract_attachment(@params['attachment']))[0] | |
2982 end | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
2983 end |
85 | 2984 # Variables here |
2985 # name: Destination group/user name | |
2986 # user: Member account or nil(not member) | |
2987 | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2988 # Set values for header rewriting |
85 | 2989 # We have to setup these variables: |
2990 # to: Header To: | |
2991 # subj: Header Subject: | |
2992 # from: Header From: | |
2993 # rcpts: Array of recipients addresses | |
2994 # header: Hash of additional header values | |
2995 # body: String of mail body | |
2996 # spooling: Flag if spool ML files nor not | |
2997 # mldir: spooling directory name | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
2998 if groupmode # Run as ML |
85 | 2999 # To: should be ML address |
3000 # Return-path: should be verp of PREFIX-RCPT@DOMAIN | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3001 bracket = @sc.getgroupattr(name, 'subjtag') || @opt['mailbracket'] |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3002 xmlname = @sc.getgroupattr(name, 'xmlname') || name |
85 | 3003 mldir = @mlbasedir+"/"+name |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3004 to = @sc.getgroupattr(name, 'mladdress') || defaultmladdress(name) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3005 if @sc.getgroupattr(name, 'fromhack') |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3006 fromhack = to |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3007 end |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3008 spooling = @opt['mlspooling'] |
85 | 3009 returnpath = to.sub("@", @mailadmsuffix+"-@") |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3010 else # Run as p2p mail |
85 | 3011 # To: should be Destination user name |
3012 # Return-path: should be PREFIX-USER@DOMAIN or $SENDER(not member) | |
3013 bracket = "NONE" # Through Subject | |
3014 if user | |
3015 returnpath = defaultmladdress(quoted(user)) | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3016 else |
85 | 3017 returnpath = ENV['SENDER'] |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3018 end |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3019 ###fromhack = sprintf("%s <%s>", nick, sender) |
85 | 3020 fromhack = returnpath |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3021 |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3022 xmlname = name |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3023 to = name |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3024 spooling = mldir = nil |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3025 end |
69
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3026 adminaddr = to.sub("@", @mailadmsuffix+"@") |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3027 if bracket == "NONE" |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3028 sjtag = "" |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3029 tagre = nil |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3030 else |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3031 sjtag = bracket.gsub("%n", nickname(name)). |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3032 gsub("%i", name). |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3033 gsub(/%(\d*)c/){("%0"+$1+"d") % [mlseq(mldir)]} |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3034 tagpt = Regexp.quote(bracket). # compute bracket pattern |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3035 gsub("%n", Regexp.quote(nickname(name))). |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3036 gsub("%i", Regexp.quote(name)). |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3037 gsub(/%(\d*)c/, '\d+') |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3038 tagre = Regexp.new(tagpt) |
85 | 3039 if !viamail |
3040 subj = sjtag.strip+" "+subj.gsub(Regexp.new(tagpt), "") | |
3041 end | |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3042 end |
40 | 3043 if viamail then |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3044 body = tagify_subj(STDIN.readlines, sjtag, tagre, fromhack).join |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3045 elsif fromhack # via http |
85 | 3046 from = rewritefrom(user, nick, groupmode ? to : returnpath) |
40 | 3047 end |
38
39da23b2edb9
Prepend bracket tag to subject.
HIROSE Yuuji <yuuji@gentei.org>
parents:
37
diff
changeset
|
3048 header = { |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3049 "X-ML-Driver" => ($hgid || @myname), |
38
39da23b2edb9
Prepend bracket tag to subject.
HIROSE Yuuji <yuuji@gentei.org>
parents:
37
diff
changeset
|
3050 "X-ML-Driver-URI" => $myurl, |
85 | 3051 "Return-path" => returnpath |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3052 } |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3053 if groupmode |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3054 header["Reply-to"] = to |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3055 header["X-ML-Name"] = xmlname |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3056 header["X-ML-URI"] = sprintf("%s?-groupman+%s", @opt['url'], name) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3057 end |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3058 Dir.chdir @mydir |
85 | 3059 if groupmode # (#includeself) |
3060 rcpts = if viamail | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3061 @sc.members(name) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3062 else |
85 | 3063 @sc.members(name) + [user] |
3064 end.collect {|u| | |
3065 mailaddress(u, name).split(/,\s*|\s+/)}.flatten.uniq | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3066 else |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3067 rcpts = @sc.mailaddress(name).split(/,\s*|\s+/).flatten |
86
26c81703a80c
Do not send to $SENDER when viamail mode
HIROSE Yuuji <yuuji@gentei.org>
parents:
85
diff
changeset
|
3068 if user && !viamail # HTTP mode |
26c81703a80c
Do not send to $SENDER when viamail mode
HIROSE Yuuji <yuuji@gentei.org>
parents:
85
diff
changeset
|
3069 rcpts += @sc.mailaddress(user).split(/,\s*|\s+/).flatten # +sender |
26c81703a80c
Do not send to $SENDER when viamail mode
HIROSE Yuuji <yuuji@gentei.org>
parents:
85
diff
changeset
|
3070 end |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3071 end |
85 | 3072 # ENV["QMAILINJECT"] = "r" # for ML mode, use verp |
3073 # For vodafone, QMAILINJECT=r doesn't work correctly | |
69
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3074 # On mail mode, check if sender can send message to list. |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3075 if viamail && @sc.getgroupattr(name, 'limitsender') |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3076 s = ENV['SENDER'] |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3077 if !catch(:senderok) { |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3078 throw :senderok, true if rcpts.grep(s)[0] |
87 | 3079 throw :senderok, true if @sc.ismembersemail(s, name) |
69
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3080 } |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3081 # sender is not allowed to send to ML |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3082 sendMail(s, "You are not allowed to send to this ML", |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3083 ("Before posting to this list(%s),\n"+ |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3084 "subscribe to %s") % [to, @opt['url']], |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3085 adminaddr, nil, {"Return-path" => returnpath}) |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3086 exit 0 |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3087 end |
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3088 end |
70
2e293d4d8db4
Not using proc.call for the sake of displaying document title.
HIROSE Yuuji <yuuji@gentei.org>
parents:
69
diff
changeset
|
3089 # |
2e293d4d8db4
Not using proc.call for the sake of displaying document title.
HIROSE Yuuji <yuuji@gentei.org>
parents:
69
diff
changeset
|
3090 # OK to send, go ahead |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3091 sendMail(to, subj, body, from, rcpts, |
38
39da23b2edb9
Prepend bracket tag to subject.
HIROSE Yuuji <yuuji@gentei.org>
parents:
37
diff
changeset
|
3092 header, |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3093 ENV['SENDER'], |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3094 spooling ? mldir : nil) |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3095 if !viamail then |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3096 @O.print @H.elementln("h1"){msg('sendall_done')} |
87 | 3097 @O.print @H.p(sprintf(msg(groupmode ? 'sendall_head' : 'sendmem_head'), |
38
39da23b2edb9
Prepend bracket tag to subject.
HIROSE Yuuji <yuuji@gentei.org>
parents:
37
diff
changeset
|
3098 nickname(name))+" "+msg('done')) |
87 | 3099 @O.print @H.elementln("pre"){extract_report[1].toeuc} |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3100 link2home() |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3101 @O.print footer() |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3102 return true |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3103 end |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3104 exit 0 |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3105 end |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3106 def listdraft(name) |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3107 return nil unless checkauth |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3108 return nil unless name |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3109 unless @opt['mailprefix'] && @opt['maildomain'] |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3110 @O.print @H.elementln("pre"){msg('sendall_err') % [@opt['conf']]} |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3111 return true |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3112 end |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3113 |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3114 user=@params['user'] |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3115 nickname = @sc.nickname(user) |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3116 groupmode = @sc.isgroup(name) |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3117 @O.print @H.elementln("h1") { |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3118 @mybase+' '+msg('sendall').sub("<br>", " ") |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3119 } |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3120 @O.print @H.elementln("h2") { |
88
c4ea79816b2d
Alter messege according to mode
HIROSE Yuuji <yuuji@gentei.org>
parents:
87
diff
changeset
|
3121 sprintf(msg(groupmode ? 'sendall_head' : 'sendmem_head'), nickname(name)) |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3122 } |
85 | 3123 if groupmode # (#includeself) |
3124 list = @sc.members(name) # +user | |
3125 else | |
3126 list = [name, user] | |
3127 end | |
3128 @O.print @H.p(sprintf("%s: %s", msg('rcptto'), | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3129 list.collect {|u| |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3130 @H.element("abbr", "title"=>u){ |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3131 @sc.nickname(u) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3132 } |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3133 }.join(",\n"))) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3134 @O.print @H.p(sprintf("(total %d)", list.length))+"\n" |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3135 @O.print \ |
85 | 3136 @H.elementln("form", { |
3137 'action' => @myname+'?-list', 'method'=>"POST", | |
3138 'enctype' => "multipart/form-data"}) { | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3139 @H.elementln("table"){ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3140 @H.elementln("tr"){ |
85 | 3141 @H.element("td"){"To"} + \ |
3142 @H.element("td"){ | |
3143 @H.element("code"){ | |
3144 groupmode ? defaultmladdress(quoted(name)) : @sc.nickname(name) | |
3145 } | |
3146 } | |
3147 } + \ | |
3148 @H.elementln("tr"){ | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3149 @H.element("td"){"Subject"} + \ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3150 @H.element("td"){ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3151 @H.text("subject", "", 40, 128) |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3152 } |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3153 } + \ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3154 @H.elementln("tr"){ |
85 | 3155 @H.element("td"){"Attachment"} + \ |
3156 @H.element("td"){ | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
3157 "<input name=\"attachment\" type=\"file\" multiple>" |
85 | 3158 } |
3159 } + \ | |
3160 @H.elementln("tr"){ | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3161 @H.element("td"){ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3162 msg('body') |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3163 } + \ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3164 @H.element("td"){ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3165 @H.element("textarea", @schedulearea.merge({"name"=>"body"})){} |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3166 } |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3167 } |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3168 } + # </table> |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3169 @H.hidden("name", name) + |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3170 @H.submit("send", "SEND") + |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3171 @H.reset("clear", "Clear") |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3172 } |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3173 @O.print @H.p(msg('sendall_note')) |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3174 end |
0 | 3175 |
36
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3176 # put Link to home |
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3177 def link2home() |
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3178 @O.print @H.p("-> " + @H.a(@myname+"?-today", "Home")) |
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3179 end |
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3180 |
0 | 3181 # |
3182 # user management | |
3183 def userman() | |
3184 if !checkauth | |
3185 return nil | |
3186 end | |
3187 user=@params['user'] | |
3188 nickname = @sc.nickname(user) | |
3189 tdclass = {} | |
3190 tdclass["width"] = "80px" if @oldagent # workaround for NN4 | |
3191 | |
3192 @O.print @H.elementln("h1"){ | |
3193 @mybase+' '+msg('user', 'management') | |
3194 } | |
3195 @O.print @H.p(@sc.mkusermap.inspect) if $DEBUG | |
3196 @O.print @H.p(msg('usermodwarn')) | |
3197 @O.print \ | |
3198 @H.elementln("form", {'action'=>@myname+"?-usermod", 'method'=>'POST'}){ | |
50
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
3199 @H.elementln("table", {"class" => "border"}){ |
0 | 3200 @H.elementln("tr"){ |
3201 @H.element("td", tdclass) {msg('regaddress')} + \ | |
3202 @H.element("td") { | |
3203 @H.element("code"){user} | |
3204 } | |
3205 } + \ | |
3206 @H.elementln("tr"){ | |
50
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
3207 @H.element("td", tdclass) {msg('mailaddress', 'multipleok')} + \ |
0 | 3208 @H.element("td") { |
55
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
3209 @H.text("newmail", mailaddress(user), @opt['size'], 180) |
0 | 3210 } |
3211 } + \ | |
3212 @H.elementln("tr"){ | |
3213 @H.element("td", tdclass) {msg('weburl')} + \ | |
3214 @H.element("td") { | |
3215 @H.text("webpage", webpage(user), @opt['size'], 80) | |
3216 } | |
3217 } + \ | |
3218 @H.elementln("tr"){ | |
3219 @H.element("td") {msg('nickname')} + \ | |
3220 @H.element("td") { | |
3221 @H.text("nickname", nickname, @opt['size'], 10) | |
3222 } | |
3223 } | |
3224 } + \ | |
50
0b104c49457a
Multiple email addresses can be acceptable
HIROSE Yuuji <yuuji@gentei.org>
parents:
48
diff
changeset
|
3225 @H.elementln("p"){msg('shortnameplz')} + \ |
0 | 3226 '<br>' + \ |
3227 @H.submit_reset("GO") | |
3228 } # form | |
3229 | |
3230 # | |
3231 # Next section, REMOVE USER! | |
3232 @O.print @H.elementln("h2"){ | |
3233 sprintf "%s %s %s", msg('user'), user, msg('deletion') | |
3234 } | |
3235 @O.print @H.p(msg('deletionwarn'))+"\n" | |
3236 @O.print @H.elementln("form", {'action'=>@myname+"?-delusersub+#{user}", 'method'=>'POST'}){ | |
3237 @H.hidden("user", user) + "\n" + \ | |
3238 @H.elementln("table"){ | |
3239 @H.elementln("tr"){ | |
3240 @H.elementln("td"){ | |
3241 sprintf msg('deluser'), user | |
3242 } + \ | |
3243 @H.elementln("td"){ | |
3244 @H.radio("delete", "yes", msg('yes')) + ' ' + \ | |
3245 @H.radio("delete", "no", msg('no'), true) | |
3246 } | |
3247 } + \ | |
3248 @H.elementln("tr"){ | |
3249 @H.elementln("td"){ | |
3250 sprintf msg('really?'), user | |
3251 } + \ | |
3252 @H.elementln("td"){ | |
3253 @H.radio("delete2", "yes", msg('yes')) + ' ' + \ | |
3254 @H.radio("delete2", "no", msg('no'), true) | |
3255 } | |
3256 } | |
3257 } + \ | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
3258 "<br>\n" + @H.element("span", "class"=>"danger"){@H.submit_reset("OK")} |
0 | 3259 } |
3260 | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
3261 @O.print footer() |
0 | 3262 end |
3263 def usermod() | |
3264 if !checkauth | |
3265 return nil | |
3266 end | |
3267 @O.print @H.elementln("h1"){ | |
3268 msg('user', 'management')+" "+msg('done') | |
3269 } | |
3270 user=@params['user'] | |
3271 email = mailaddress(user) | |
3272 newmail = @params['newmail'] | |
3273 nickname = @sc.nickname(user) | |
3274 newnn = @params['nickname'].to_s.strip | |
3275 webpage = webpage(user) | |
3276 newweb = @params['webpage'] | |
3277 if email != newmail | |
3278 # change user's address | |
3279 if newmail == user | |
3280 newvalue = nil | |
3281 elsif checkmail(newmail) | |
3282 newvalue = newmail | |
3283 else | |
3284 @O.print @H.elementln("pre"){"Invalid mail address"} | |
3285 end | |
3286 @O.print @H.elementln("pre"){ | |
3287 if @sc.putuserattr(user, 'email', newvalue) | |
3288 sprintf "new mail address=\"%s\"", mailaddress(user) | |
3289 else | |
3290 sprintf "Setting new mail address to \"%s\" failed", newvalue | |
3291 end | |
3292 } | |
3293 end | |
3294 if nickname != newnn | |
3295 if @sc.setnickname(user, newnn) | |
3296 @O.print @H.p(msg('success')) | |
3297 @O.print @H.elementln("pre"){ | |
3298 sprintf "user=\"%s\"\nnickname=\"%s\"", user, @sc.nickname(user) | |
3299 } | |
3300 @O.print @H.p(msg('nicknamenote')) if newnn == '' | |
3301 else | |
3302 @O.print @H.p(msg('failure')) | |
3303 end | |
3304 end | |
3305 if newweb > '' && webpage != newweb | |
3306 if @sc.putuserattr(user, "webpage", newweb) | |
3307 @O.print @H.p(msg('success')) | |
3308 @O.print @H.elementln("pre"){ | |
3309 sprintf "user=\"%s\"\nwebpage=\"%s\"", user, webpage(user) | |
3310 } | |
3311 else | |
3312 @O.print @H.p("Update webpage"+msg('failure')) | |
3313 end | |
3314 end | |
36
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3315 link2home |
0 | 3316 end |
3317 # | |
3318 # Display form of group management | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3319 def groupman(grp = nil) |
0 | 3320 if !checkauth |
3321 return nil | |
3322 end | |
3323 user=@params['user'] | |
3324 nickname = @sc.nickname(user) | |
3325 tdclass = {} | |
3326 tdclass["width"] = "80px" if @oldagent # workaround for NN4 | |
3327 admclass = {'class'=>'admin'} | |
3328 grmap = @sc.groupmap | |
3329 | |
3330 @O.print @H.elementln("h1"){ | |
3331 @mybase+' '+msg('group', 'management') | |
3332 } | |
3333 $KCODE='e' if $DEBUG | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3334 if grp && group = grepgroup(grp) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3335 @O.print @H.elementln("h2"){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3336 sprintf(msg('aboutgroup'), group) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3337 } |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3338 grmap = {group => grmap[group]} |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3339 end |
0 | 3340 @O.print grmap.inspect if $DEBUG |
3341 @O.print @H.p(msg('joinmyself')+ | |
3342 @H.a(@myname+"?-newgroup", msg('newgroup'))) | |
3343 @O.print @H.p(msg('usermodwarn')) | |
3344 @O.print \ | |
3345 @H.elementln("form", {'action'=>@myname+"?-groupmod", 'method'=>'POST'}){ | |
55
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
3346 @H.elementln("table", {'class'=>'border'}){ |
47 | 3347 grmap.sort.collect{|g, ghash| |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3348 memberp = @sc.ismember(user, g) |
68
db1502243712
Do not hover mail addresses of users for non-administrator list.
HIROSE Yuuji <yuuji@gentei.org>
parents:
67
diff
changeset
|
3349 adminp = @sc.isadmin(user, g) |
0 | 3350 @H.elementln("tr"){ |
68
db1502243712
Do not hover mail addresses of users for non-administrator list.
HIROSE Yuuji <yuuji@gentei.org>
parents:
67
diff
changeset
|
3351 @H.element("td", adminp ? admclass : nil){ |
63
e2aa6180c2c6
Show the number of group member in groupman().
HIROSE Yuuji <yuuji@gentei.org>
parents:
62
diff
changeset
|
3352 g + "<br>("+@sc.members(g).length.to_s+")" |
0 | 3353 } + \ |
3354 @H.element("td"){ | |
3355 @H.element("div", {'class'=>'c'}) { | |
68
db1502243712
Do not hover mail addresses of users for non-administrator list.
HIROSE Yuuji <yuuji@gentei.org>
parents:
67
diff
changeset
|
3356 if adminp |
0 | 3357 @H.a(@myname+"?-admgroup+#{g}", msg('adminop')) |
3358 else | |
3359 '--' | |
3360 end | |
3361 } | |
3362 } + \ | |
3363 @H.element("td"){ | |
3364 if ghash['admin'].grep(user)[0] | |
94
568f4c467966
Group name length 12 is too short. Changed to 30.
HIROSE Yuuji <yuuji@gentei.org>
parents:
93
diff
changeset
|
3365 @H.text("groupname-#{g}", ghash['name'], nil, 30) |
0 | 3366 else |
3367 ghash['name'] | |
3368 end + '<br>' + \ | |
66 | 3369 # If this group is inviteonly and the user is not a member, |
67
a421c2fefc32
Fix the argument for FileUtils.mkdir_p()
HIROSE Yuuji <yuuji@gentei.org>
parents:
66
diff
changeset
|
3370 # one cannot join. |
68
db1502243712
Do not hover mail addresses of users for non-administrator list.
HIROSE Yuuji <yuuji@gentei.org>
parents:
67
diff
changeset
|
3371 if memberp && adminp || !@sc.getgroupattr(g, 'inviteonly') |
66 | 3372 @H.radio("groupadd-#{g}", "yes", "IN", memberp) + " / " + \ |
3373 @H.radio("groupadd-#{g}", "no", "OUT", !memberp) | |
3374 else | |
3375 @H.element("small"){"("+msg('inviteonly')+")"} | |
3376 end | |
0 | 3377 } + \ |
3378 @H.element("td"){ | |
47 | 3379 @H.element("div", {'class'=>'memlist5'}){ |
3380 memlist = ghash['members'] | |
3381 if memberp # move this user to the beginning of list | |
3382 memlist.delete(user) | |
3383 memlist.unshift(user) | |
3384 end | |
3385 memlist.collect{|u| | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3386 if u == user |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3387 @sc.nickname(u) + \ |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3388 "("+@H.text("mail4-#{g}", memberp, 30, 180)+")" |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3389 else |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3390 @H.a(@myname+"?-listdraft+#{u}", |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3391 @H.element("abbr", "title"=>u) { |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3392 @sc.nickname(u) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3393 }) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3394 end |
47 | 3395 }.join(", ") |
3396 } | |
3397 } + \ | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3398 @H.element("td"){ |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3399 @H.a(@myname+"?-listdraft+#{g}", msg('sendall')) |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
3400 } |
0 | 3401 } |
27 | 3402 }.join("\n") |
0 | 3403 } + \ |
3404 '' + \ | |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3405 @H.p(msg('address2send')) + \ |
87 | 3406 @H.p(msg('skip:')) + \ |
0 | 3407 @H.p(msg('groupwarn', 'shortnameplz')) + \ |
3408 @H.submit_reset("GO") | |
3409 } # form | |
87 | 3410 link2home() |
3411 @O.print footer() | |
0 | 3412 end |
2 | 3413 def groupnamesString() |
3414 @H.elementln("p", {'class'=>'listup'}){ | |
3415 @sc.groups().collect{|g|@sc.groupname(g)}.join(", ") | |
3416 } | |
3417 end | |
0 | 3418 def groupmod() |
3419 if !checkauth | |
3420 return nil | |
3421 end | |
3422 @O.print @H.elementln("h1"){ | |
3423 msg('group', 'management')+" "+msg('done') | |
3424 } | |
3425 user=@params['user'] | |
3426 @O.print @params.inspect if $DEBUG | |
3427 | |
3428 for grp in @sc.groups() | |
3429 # | |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3430 # As a member, participate or retire |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3431 |
0 | 3432 key = "groupadd-#{grp}" |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3433 memberp = @sc.ismember(user, grp) |
0 | 3434 removep = (/no/i =~ @params[key]) |
3435 if @params[key] | |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3436 # |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3437 # Check the group is invitation-only mode. |
95
4c6561489602
Do check the invieonly attr on user participation request
HIROSE Yuuji <yuuji@gentei.org>
parents:
94
diff
changeset
|
3438 if !removep && !memberp \ |
4c6561489602
Do check the invieonly attr on user participation request
HIROSE Yuuji <yuuji@gentei.org>
parents:
94
diff
changeset
|
3439 && @sc.getgroupattr(grp, 'inviteonly') \ |
4c6561489602
Do check the invieonly attr on user participation request
HIROSE Yuuji <yuuji@gentei.org>
parents:
94
diff
changeset
|
3440 && !@sc.isadmin(user, grp) |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3441 @O.print @H.elementln("p") { |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3442 sprintf(msg('invite-error'), grp) + "<br>\n" + \ |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3443 @sc.admins(grp).join(", ") |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3444 } |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3445 sendMail(defaultmladdress(grp).sub("@", @mailadmsuffix+"@"), |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3446 "Group paticipation attempt to #{grp}", |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3447 putLog("User `%s' tried to join `%s' from %s" % |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3448 [user, grp, ENV['REMOTE_ADDR']]), |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3449 nil, |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3450 @sc.admins(grp)) |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3451 next |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3452 end |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3453 # |
95
4c6561489602
Do check the invieonly attr on user participation request
HIROSE Yuuji <yuuji@gentei.org>
parents:
94
diff
changeset
|
3454 # OK to join/retire |
0 | 3455 if (!removep) ^ memberp |
3456 @sc.addgroup(grp, [user], removep) | |
3457 @O.print @H.elementln("p"){ | |
3458 sprintf "%s [%s] %s %s", msg('user'), user, | |
3459 removep ? msg('removedfromgp') : msg('addedtogroup'), grp | |
3460 } | |
3461 end | |
3462 end | |
3463 # | |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3464 # As a member, change group-specific mailto address. |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3465 key = "mail4-#{grp}" |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3466 if memberp && @params[key] && memberp != @params[key] |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3467 @sc.addgroup(grp, [[user, @params[key]]]) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3468 newmemp = @sc.ismember(user, grp) |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3469 @O.print @H.elementln("p") { |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3470 sprintf("%s `%s' %s => %s%s", |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3471 msg('group'), grp, msg('mailaddress'), @params[key], |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3472 @params[key]==mailaddress(user) ? "(same)" : "") |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3473 } |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3474 end |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
3475 # |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3476 # as an owner, change the name of group |
0 | 3477 if @sc.isadmin(user, grp) && |
3478 (newname = @params["groupname-#{grp}"]) && | |
3479 @sc.groupname(grp) != newname | |
2 | 3480 @O.printf "@sc.name2group=%s<br>\n", @sc.name2group(newname) |
3481 if dupl=@sc.name2group(newname) | |
3482 @O.print @H.p(sprintf(msg('dupname'), newname)) | |
3483 @O.print groupnamesString() | |
3484 | |
3485 else | |
3486 @sc.setgroupname(grp, newname) | |
3487 @O.print @H.elementln("p"){ | |
3488 sprintf "%s %s%s %s", | |
3489 msg('group'), grp, msg('of', 'name', 'setto'), newname | |
3490 } | |
3491 end | |
0 | 3492 end |
3493 end | |
36
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3494 link2home |
0 | 3495 end |
3496 def users() | |
3497 unless pm=open_pm() | |
3498 outputError(msg('autherror')) | |
3499 return nil | |
3500 end | |
3501 pm.users | |
3502 end | |
3503 def grepgroup(gname) | |
3504 gr = @sc.groups.grep(gname)[0] | |
3505 end | |
3506 def admgroup(group = nil) | |
3507 # if group==nil, create new | |
3508 if !checkauth | |
3509 return nil | |
3510 end | |
3511 @O.print @H.elementln("h1"){ | |
3512 msg('group', 'management') | |
3513 } | |
3514 user=@params['user'] | |
3515 | |
3516 # Check the existent group's validity | |
3517 if group | |
3518 unless (gr=grepgroup(group)) | |
3519 @O.print @H.p("No such group #{group}") | |
3520 return nil | |
3521 end | |
3522 group = gr | |
3523 unless @sc.isadmin(user, group) | |
3524 @O.print @H.p("You are not administrator of #{group}.") | |
3525 return nil | |
3526 end | |
3527 @O.print @H.elementln("h2"){ | |
3528 msg('group')+" #{group}" + | |
3529 if group != @sc.groupname(group) | |
3530 " (#{@sc.groupname(group)})" | |
3531 end.to_s | |
3532 } | |
3533 actionmethod={'action'=>@myname+"?-admgroupsub", 'method'=>'POST'} | |
3534 else | |
3535 # New group creation | |
3536 @O.print @H.elementln("h2"){ | |
3537 msg('newgroup') | |
3538 } | |
3539 actionmethod={'action'=>@myname+"?-newgroupsub", 'method'=>'POST'} | |
3540 end | |
3541 | |
43 | 3542 userlist = ([user] + users()).uniq.sort |
0 | 3543 myselfclass = {'class'=>'admin'} |
55
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
3544 yesclass = {'class' => 'yes'} |
0 | 3545 colspan2 = {'colspan'=>'2'} |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3546 colspan3 = {'colspan'=>'3'} |
0 | 3547 warnclass = {'class'=>'warn'} |
3548 warnp = nil | |
3549 | |
3550 @O.print @H.elementln("form", actionmethod){ | |
3551 @H.hidden('group', group) + "\n" + \ | |
3552 if group | |
64
2445a87742d0
Gather the current group-member at the beginning of the user list.
HIROSE Yuuji <yuuji@gentei.org>
parents:
63
diff
changeset
|
3553 # Non symmetric job: Move the current users above. |
2445a87742d0
Gather the current group-member at the beginning of the user list.
HIROSE Yuuji <yuuji@gentei.org>
parents:
63
diff
changeset
|
3554 gmemlist = userlist.select{|u| @sc.ismember(u, group)} |
2445a87742d0
Gather the current group-member at the beginning of the user list.
HIROSE Yuuji <yuuji@gentei.org>
parents:
63
diff
changeset
|
3555 userlist = (gmemlist + userlist).uniq |
2445a87742d0
Gather the current group-member at the beginning of the user list.
HIROSE Yuuji <yuuji@gentei.org>
parents:
63
diff
changeset
|
3556 # In this context, should return simply "". |
0 | 3557 "" |
3558 else | |
3559 # new group creation | |
3560 grps = @sc.groups() | |
3561 i=1 | |
3562 defname = "group%03d"%i | |
3563 while grps.grep(defname)[0] | |
3564 defname = "group%03d"%(i+=1) | |
3565 end | |
3566 @H.element("pre"){ | |
3567 msg('group', 'of', 'id')+"\n"+@H.text("group", defname) + "\n" + \ | |
3568 msg('group', 'of', 'name', 'anystring')+"\n"+ \ | |
3569 @H.text("gname", '') + "\n" | |
3570 } | |
3571 end + \ | |
47 | 3572 @H.elementln("div", {'class'=>'memlist'}){ |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3573 @H.elementln("table", {'border'=>'1'}){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3574 @H.elementln("tr") { |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3575 @H.elementln("th", colspan3) { |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3576 msg('member', 'of', 'joinquit', 'operation')} |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3577 } + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3578 @H.elementln("tr"){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3579 @H.element("th"){msg('join')} + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3580 @H.element("th"){msg('administrator')} + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3581 @H.element("th"){msg('member')} |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3582 } + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3583 userlist.collect{|u| |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3584 recursememp = nil |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3585 if group |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3586 memberp = (@sc.ismember(u, group) && true) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3587 adminp = (@sc.isadmin(u, group) && true) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3588 if !memberp && @sc.members(group).grep(u)[0] |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3589 recursememp = true |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3590 end |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3591 else |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3592 memberp = adminp = (u == user) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3593 end |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3594 @H.elementln("tr", (u==user ? myselfclass : nil)){ |
55
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
3595 @H.element("td", memberp && yesclass){ |
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
3596 yes = memberp ? 'YES' : 'yes' |
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
3597 @H.radio('mem-'+u, 'yes', yes+' / ', memberp) + \ |
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
3598 @H.radio('mem-'+u, 'no', 'no', !memberp) |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3599 } + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3600 @H.element("td"){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3601 @H.radio('adm-'+u, 'yes', 'Admin / ', adminp) + \ |
55
9a82edb295ca
Adjust umask. Max width of email entry, enlarged.
HIROSE Yuuji <yuuji@gentei.org>
parents:
50
diff
changeset
|
3602 @H.radio('adm-'+u, 'no', 'no', !adminp) |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3603 } + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3604 @H.element("td"){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3605 @H.element("abbr", "title"=>mailaddress(u)) { |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3606 @sc.nickname(u) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3607 } + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3608 if recursememp |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3609 warnp = true |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3610 @H.element("span", warnclass){"(*)"} |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3611 end.to_s |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3612 } |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3613 } |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3614 }.join + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3615 # group names |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3616 @H.elementln("tr") { |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3617 @H.elementln("th", colspan3) { |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3618 msg('group', 'of', 'joinquit', 'operation')} |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3619 } + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3620 @H.elementln("tr"){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3621 @H.element("th", colspan2){msg('join')} + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3622 @H.element("th"){msg('group')} |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3623 } + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3624 @sc.groups().sort.collect{|g| |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3625 next if group == g |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3626 memberp = @sc.ismember(g, group) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3627 @H.element("tr"){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3628 @H.element("td", colspan2){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3629 @H.radio('mem-'+g, 'yes', 'YES / ', memberp) + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3630 @H.radio('mem-'+g, 'no', 'NO', !memberp) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3631 } + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3632 @H.element("td"){ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3633 if @sc.isadmin(user, g) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3634 @H.a(@myname+"?-admgroup+#{g}", @sc.groupname(g)) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3635 else |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3636 @sc.groupname(g) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3637 end |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3638 } |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3639 } |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3640 }.join |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3641 } |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3642 } + \ |
69
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3643 ["fromhack", "inviteonly", "limitsender"].collect do |param| |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3644 @H.checkbox(param, "yes", msg(param), |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3645 @sc.getgroupattr(group, param)) + "<br>\n" |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3646 end.join + \ |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3647 (group ? @H.elementln("p") { |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3648 sprintf(msg('mladdress'), defaultmladdress(group)) + \ |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3649 @H.text("mladdress", @sc.getgroupattr(group, 'mladdress'), |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3650 @opt['size'], 80) |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3651 } + \ |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3652 @H.elementln('p') { |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3653 sprintf(msg('xmlname'), group) + \ |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3654 @H.text("xmlname", @sc.getgroupattr(group, 'xmlname'), |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
3655 @opt['size'], 80) |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3656 } : "") + \ |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3657 @H.elementln('p') { |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3658 n = -1 |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3659 curtag = @sc.getgroupattr(group, 'subjtag') |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3660 values = @subjtags.collect {|x| |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3661 sprintf(' <option value="%d"%s>%s</option>', n+=1, |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3662 curtag==@subjtags[n][1] ? ' selected' : "", |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3663 x[0]) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3664 }.join("\n") |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3665 "Subject tag: " + \ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3666 <<-_EOF_ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3667 <select name="subjtag"> |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3668 <option value="">DEFAULT</option> |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3669 #{values} |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3670 </select> |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3671 _EOF_ |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3672 } + \ |
0 | 3673 @H.submit_reset("GO") |
3674 } # form | |
3675 @O.print @H.p(@H.element("span", warnclass){"(*)"}+ | |
3676 msg('recursewarn')) if warnp | |
2 | 3677 if group && (members = @sc.members(group))[0] |
0 | 3678 @O.print @H.p(sprintf(msg('wholemembers'), group)) |
3679 @O.print @H.elementln("p", {'class'=>'listup'}){ | |
2 | 3680 members.collect{|u|@sc.nickname(u)}.join(", ")} |
0 | 3681 end |
3682 | |
3683 # | |
3684 # Next section, REMOVE GROUP! | |
3685 return nil unless group | |
3686 @O.print @H.elementln("h2"){ | |
3687 sprintf "%s %s %s", msg('group'), group, msg('deletion') | |
3688 } | |
3689 @O.print @H.p(msg('deletionwarn'))+"\n" | |
3690 @O.print @H.elementln("form", {'action'=>@myname+"?-delgroupsub+#{group}", 'method'=>'POST'}){ | |
3691 @H.hidden("group", group) + "\n" + \ | |
3692 @H.elementln("table"){ | |
3693 @H.elementln("tr"){ | |
3694 @H.elementln("td"){ | |
3695 sprintf msg('delgroup'), group | |
3696 } + \ | |
3697 @H.elementln("td"){ | |
3698 @H.radio("delete", "yes", msg('yes')) + ' ' + \ | |
3699 @H.radio("delete", "no", msg('no'), true) | |
3700 } | |
3701 } + \ | |
3702 @H.elementln("tr"){ | |
3703 @H.elementln("td"){ | |
3704 sprintf msg('really?'), group | |
3705 } + \ | |
3706 @H.elementln("td"){ | |
3707 @H.radio("delete2", "yes", msg('yes')) + ' ' + \ | |
3708 @H.radio("delete2", "no", msg('no'), true) | |
3709 } | |
3710 } | |
3711 } + \ | |
90
48afc00ef5df
Add filtering feature to schedule listing
HIROSE Yuuji <yuuji@gentei.org>
parents:
89
diff
changeset
|
3712 "<br>\n" + @H.element("span", "class"=>"danger"){@H.submit_reset("OK")} |
0 | 3713 } |
3714 | |
3715 @O.print footer() | |
3716 end | |
3717 def newgroup() | |
3718 admgroup(nil) | |
3719 end | |
3720 | |
3721 def delgroupsub(group) | |
3722 if !checkauth | |
3723 return nil | |
3724 end | |
3725 user = @params['user'] | |
3726 if group != @params['group'] | |
3727 @O.print @H.p("Group mismatch") | |
3728 return nil | |
3729 end | |
3730 unless (gr=grepgroup(group)) | |
3731 @O.print @H.p("No such group #{group}") | |
3732 return nil | |
3733 end | |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3734 group = safecopy(gr) |
0 | 3735 unless @sc.isadmin(user, group) |
3736 @O.print @H.p("You are not administrator of #{group}.") | |
3737 return nil | |
3738 end | |
3739 unless @params['delete'] && /yes/i =~ @params['delete'] \ | |
3740 && @params['delete2'] && /yes/i =~ @params['delete2'] | |
3741 @O.print @H.p(msg('chicken')) | |
3742 return nil | |
3743 end | |
3744 @O.print @H.elementln("h1"){ | |
3745 msg('group')+" #{group} "+msg('deletion') | |
3746 } | |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3747 if @sc.destroygroup(group) |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3748 system(sprintf("rm -r ml/%s", group)) |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3749 resmsg = msg("done") |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3750 else |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3751 resmsg = Omsg("failure") |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3752 end |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3753 @O.print @H.p(resmsg) |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3754 putLog("Delete group '#{group}' #{resmsg}\n") |
0 | 3755 |
3756 @O.print footer() | |
3757 end | |
3758 | |
3759 def deleteuser(user) | |
3760 @sc.deleteuser(user) && | |
3761 begin | |
3762 pm = open_pm | |
3763 pm.delete(user) | |
3764 pm.close() | |
3765 true | |
3766 rescue | |
3767 nil | |
3768 end | |
3769 end | |
3770 def delusersub(user) | |
3771 if !checkauth | |
3772 return nil | |
3773 end | |
3774 user = @params['user'] | |
3775 if user != @params['user'] | |
3776 @O.print @H.p("User mismatch") | |
3777 return nil | |
3778 end | |
3779 unless (us=users().grep(user)[0]) | |
3780 @O.print @H.p("No such user #{user}") | |
3781 return nil | |
3782 end | |
3783 user = us | |
3784 unless @params['delete'] && /yes/i =~ @params['delete'] \ | |
3785 && @params['delete2'] && /yes/i =~ @params['delete2'] | |
3786 @O.print @H.p(msg('chicken')) | |
3787 return nil | |
3788 end | |
3789 @O.print @H.elementln("h1"){ | |
3790 msg('user')+" #{user} "+msg('deletion') | |
3791 } | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3792 resmsg = deleteuser(user) ? msg("done") : msg("failure") |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3793 @O.print @H.p(resmsg) |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3794 putLog("Delete user '#{user}' #{resmsg}\n") |
0 | 3795 |
7 | 3796 @O.print @H.p(@H.a(@myname, msg('login'))) |
0 | 3797 end |
3798 | |
3799 def admgroupsub() | |
3800 if !checkauth | |
3801 return nil | |
3802 end | |
3803 user = @params['user'] | |
3804 group = @params['group'] | |
3805 unless (gr=grepgroup(group)) | |
3806 @O.print @H.element("pre"){"No such group #{group.inspect}"} | |
3807 return nil | |
3808 end | |
3809 unless @sc.isadmin(user, group) | |
3810 @O.print @H.p("You are not administrator of #{group}.") | |
3811 return nil | |
3812 end | |
3813 gorup = gr | |
3814 @O.print @H.elementln("h1"){ | |
3815 msg('group', 'management', 'done') | |
3816 } | |
3817 @O.print @H.elementln("h2"){ | |
3818 msg('group')+" #{group}" + | |
3819 if group != @sc.groupname(group) | |
3820 " (#{@sc.groupname(group)})" | |
3821 end.to_s | |
3822 } | |
3823 somethingdone = nil | |
3824 for u in users() | |
2 | 3825 u = @sc.isuser(u) # users() value is considered tainted. |
3826 next unless u # Use registered value in @sc. | |
0 | 3827 for var, kind in { |
3828 "mem"=>['members', 'member'], 'adm'=>['admin', 'administrator']} | |
3829 memv = "#{var}-#{u}" | |
3830 if @params[memv] | |
3831 joinp = ((/^yes/i =~ @params[memv]) && true) | |
3832 membp = if var=='mem' | |
3833 @sc.ismember(u, group) | |
3834 else # admin | |
3835 @sc.isadmin(u, group) | |
3836 end && true | |
3837 if var=='adm' && @sc.admins(group).length == 1 && membp && !joinp | |
3838 @O.print @H.p(sprintf(msg('soleadmin'), u, group)) | |
3839 elsif joinp ^ membp | |
3840 somethingdone = true | |
3841 @sc.addgroup(group, [u], !joinp, kind[0]) | |
3842 @O.print @H.elementln("p"){ | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3843 putLog(sprintf "%s [%s](%s) %s %s", msg('user'), u, |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3844 msg(kind[1]), |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3845 joinp ? msg('addedtogroup'): msg('removedfromgp'), group) |
0 | 3846 } |
3847 end | |
3848 end | |
3849 end | |
3850 end # users() | |
3851 | |
3852 # add or remove for group in groups | |
3853 for g in @sc.groups() | |
3854 next if g == group | |
3855 memv = "mem-#{g}" | |
3856 if @params[memv] | |
3857 joinp = ((/^yes/i =~ @params[memv]) && true) | |
3858 membp = (@sc.ismember(g, group) && true) | |
3859 if joinp ^ membp | |
3860 somethingdone = true | |
3861 @sc.addgroup(group, [g], !joinp) | |
3862 @O.print @H.elementln("p"){ | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3863 putLog(sprintf("%s [%s] %s %s", |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3864 msg('group'), g, |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3865 joinp ? |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3866 msg('addedtogroup') |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3867 : msg('removedfromgp'), group)) |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3868 } |
0 | 3869 end |
3870 end | |
3871 end # groups | |
47 | 3872 # Change parameter(s) |
3873 # To be more generic... | |
69
bdb7e40c2d4f
`limitsender' option to prohibit anonymous user to send to ML
HIROSE Yuuji <yuuji@gentei.org>
parents:
68
diff
changeset
|
3874 ["fromhack", "inviteonly", "limitsender"].each {|param| |
62
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3875 parsetp = (@params[param] && /^yes/i =~ @params[param]) |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3876 cursetp = (@sc.getgroupattr(group, param)!=nil) |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3877 if cursetp ^ parsetp |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3878 @sc.putgroupattr(group, param, @params[param]) |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3879 @O.print @H.elementln("p") { |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3880 putLog(sprintf("group: %s[%s] -> %s", |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3881 group, param, @params[param].inspect)) |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3882 } |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3883 somethingdone = true |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3884 end |
2d33f85c3d9f
Introduce invitation-only mode for groups.
HIROSE Yuuji <yuuji@gentei.org>
parents:
61
diff
changeset
|
3885 } |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3886 # mladdress |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3887 newmladdress = @params['mladdress'] |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3888 newmladdress = nil if newmladdress == "" |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3889 curmladdress = @sc.getgroupattr(group, 'mladdress') |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3890 if newmladdress != curmladdress |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3891 defmladdress = defaultmladdress(group) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3892 @sc.putgroupattr(group, 'mladdress', newmladdress) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3893 @O.print @H.elementln("p") { |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3894 putLog(sprintf("group: %s[mladdress] <%s> -> <%s>", |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3895 group, |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3896 curmladdress || defmladdress, |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3897 newmladdress || defmladdress)) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3898 } |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3899 somethingdone = true |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3900 end |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3901 # Subject tag bracket |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3902 newtag = @params['subjtag'] |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3903 if newtag == '' |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3904 newtag = nil |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3905 else |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3906 newtag = @subjtags[newtag.to_i % @subjtags.length][1] |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3907 end |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3908 @sc.putgroupattr(group, 'subjtag', newtag) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3909 if newtag && newtag > "" |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3910 @O.print @H.elementln("p") { |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3911 putLog(sprintf("group: %s[subjtag] set to '%s'", group, newtag)) |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3912 } |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3913 somethingdone = true |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
3914 end |
83
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3915 # X-ML-Name: Header value |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3916 xmlname = @params['xmlname'] |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3917 xmlname = nil if xmlname == "" |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3918 curxmlname = @sc.getgroupattr(group, 'xmlname') |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3919 if xmlname != curxmlname && /^[-A-Z_a-z\/0-9+@(),.<>]+$/ =~ xmlname |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3920 @sc.putgroupattr(group, 'xmlname', xmlname) |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3921 @O.print @H.elementln("p") { |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3922 putLog(sprintf("X-ML-Name: Set to %s", xmlname)) |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3923 } |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3924 somethingdone = true |
54d85f7d5676
- The parameter pswdlen surely works
HIROSE Yuuji <yuuji@gentei.org>
parents:
82
diff
changeset
|
3925 end |
0 | 3926 unless somethingdone |
3927 # @O.print @H.p(msg('nothingtodo')) | |
3928 end | |
36
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3929 # @O.print footer() |
e67737e49a5d
add a5userman.html multiplenotify.html
HIROSE Yuuji <yuuji@gentei.org>
parents:
35
diff
changeset
|
3930 link2home |
0 | 3931 end |
3932 def newgroupsub() | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3933 return nil unless checkauth |
0 | 3934 user = @params['user'] |
3935 newgroup = @params['group'] | |
3936 newgname = @params['gname'] | |
3937 | |
3938 | |
3939 if @sc.groups.grep(newgroup)[0] | |
3940 @O.print @H.p(msg('existent')+newgroup) | |
3941 return nil | |
3942 end | |
2 | 3943 if dupl=@sc.name2group(newgname) |
3944 @O.print @H.p(sprintf(msg('dupname'), newgname)) | |
3945 @O.print groupnamesString() | |
3946 return nil | |
3947 end | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3948 @sc.creategroup(newgroup, newgname, [user]) && |
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
3949 putLog("New group '#{newgroup}'(#{newgname}) created\n") |
47 | 3950 admgroupsub() |
0 | 3951 end |
3952 | |
14 | 3953 # |
3954 # Methods Related to viaMail functions | |
3955 def gen_sessionpswd() | |
3956 | |
3957 end | |
3958 def viamail_registform() | |
3959 c = "# " | |
3960 nl = "\n" | |
3961 user = @params['user'] | |
3962 msg('addsched') + "-" * 20 + nl*2 + \ | |
3963 c + msg('user') + nl + \ | |
3964 "user=" + user + nl*2 + \ | |
3965 c + msg('sessionpswd') + nl + \ | |
3966 "sp=hoge" + nl*2 + \ | |
3967 c + msg('date') + nl + \ | |
3968 "date="+Time.now.strftime("%Y/%m/%d") + nl*2 + \ | |
3969 c + msg('time') + sprintf(msg('24hourtxt'), @opt['alldaydir']) + nl + \ | |
3970 "time=3000"+nl*2 + \ | |
3971 c + msg('publicp') + nl + \ | |
3972 "public=yes" + nl*2 + \ | |
3973 c + msg('neednotify') + nl + \ | |
3974 "nt10m=yes (%s) | |
3975 nttoday=yes (%s) | |
3976 nt1d=yes (%s) | |
3977 nt7d=yes (%s)" % ["10"+msg('minutes')+msg('before'), | |
3978 msg('theday'), msg('precedingday'), | |
3979 "7"+msg('days')+msg('before')] + nl*2 + \ | |
3980 | |
3981 c + msg('schedulehere') | |
3982 end | |
3983 def viamail_footer() | |
3984 viamail_registform() | |
3985 end | |
3986 def show_by_text(date, days) | |
3987 user = @params['user'] | |
3988 personal = true | |
3989 sched = dayTextString(user, date, days, personal) | |
3990 # @O.print outstr | |
3991 | |
3992 sendMail(mailaddress(user), | |
3993 "After5 Schedule", | |
3994 @opt['url'] + "\n" + \ | |
3995 Time.now.strftime("%Y/%m/%d") + \ | |
3996 sprintf(msg('schedlist'), days) + "\n\n" + \ | |
3997 if sched > '' | |
3998 sched | |
3999 else | |
4000 msg('noplan')+"\n" | |
4001 end + \ | |
4002 viamail_footer | |
4003 ) | |
4004 | |
4005 end | |
4006 def parseHeader | |
4007 contline=nil | |
4008 header=Hash.new | |
4009 text=Array.new | |
4010 | |
4011 field=nil | |
4012 # header | |
4013 while line=STDIN.gets | |
4014 text << line | |
4015 break if /^$/ =~ line | |
4016 | |
4017 if /^\s+/ =~ line | |
4018 if field | |
4019 header[field][-1] << line | |
4020 end | |
4021 else | |
4022 if /^([^:]+):\s*(.*)/ =~ line | |
4023 field=$1.downcase | |
4024 header[field] or header[field] = [] | |
4025 header[field] << $2 | |
4026 end | |
4027 end | |
4028 end | |
4029 header | |
4030 end | |
4031 def mail_regsched() | |
4032 @params = Hash.new # Reset | |
4033 | |
4034 reqparams = %w[user sp date time public] | |
4035 otherparams = %w[nt10m nttoday nt1d nt7d] | |
4036 setall = lambda{ | |
4037 reqparams.each{|key| return false unless @params.has_key?(key)} | |
4038 return true | |
4039 } | |
4040 stack = "" | |
4041 while line=gets # !setall.call && line=gets | |
4042 if /^(\S+)=(.*)/ =~ line | |
4043 next unless reqparams.index($1) || otherparams.index($1) | |
4044 @params[$1] = $2 | |
4045 #if reqparams.index($1) | |
4046 STDERR.print "Set #{$1} to #{$2}\n" | |
4047 #end | |
4048 buf = "" | |
4049 elsif /^\s*\#|^$/ =~ line | |
4050 # skip comments | |
4051 else | |
4052 buf += line | |
4053 end | |
4054 end | |
4055 unless setall.call | |
4056 STDERR.print "Insufficient variables\n" | |
4057 exit 1 | |
4058 end | |
4059 p buf | |
4060 | |
4061 y, m, d = date2ymd(@params["date"]) | |
4062 @params["year"] = y | |
4063 @params["month"] = m | |
4064 @params["day"] = d | |
4065 @params["schedule"] = buf | |
4066 @params["editmode"] = "modify" | |
4067 @params["sessionpw"] = @params["sp"] | |
4068 p @params | |
4069 add_remove() | |
4070 end | |
4071 def mail_getsched() | |
4072 user = nil | |
4073 while bline=gets | |
4074 if /(\S+@\S+)/ =~ bline | |
4075 break if user=@sc.isuser($1) | |
4076 end | |
4077 end | |
4078 unless user | |
4079 sendMail(@opt['maintainer'], "viaMail Request Error", | |
4080 "This is `#{@mybase}' in #{@mydir}\n" + | |
4081 "Invalid schedule request from #{ENV['SENDER']}.\n\n") | |
4082 exit 1 | |
4083 end | |
4084 today = Time.now.strftime("%Y/%m/%d") | |
4085 days = 7 | |
4086 if bline=gets | |
4087 if /\d+/ =~ bline | |
4088 days = bline.to_i | |
4089 end | |
4090 end | |
4091 # Send user to schedules of today and near future | |
4092 @params['user'] = user | |
4093 show_by_text(today, days) | |
4094 end | |
4095 def doMail() | |
4096 days = 7 | |
4097 # Confirm `via Mail' | |
4098 prohibitviahttp() | |
4099 @H = TEXTout.new | |
4100 unless ENV['RECIPIENT'] && ENV['SENDER'] | |
4101 STDERR.print "Call me via qmail\n" | |
4102 exit 1 | |
4103 end | |
4104 @mailmode = true | |
4105 header = parseHeader # is this necessary? | |
4106 if /regist/ =~ ENV["EXT"] | |
4107 mail_regsched() | |
4108 else | |
4109 mail_getsched() | |
4110 end | |
4111 end | |
4112 | |
4113 # | |
4114 # Password related Methos | |
0 | 4115 def setpasswd(user) |
4116 prohibitviahttp() | |
4117 pm = open_pm() | |
4118 exit 1 unless pm | |
4119 if pm.userexist?(user) then | |
4120 begin | |
4121 system "stty -echo" | |
4122 STDERR.print "New passwd: " | |
4123 p1 = STDIN.gets | |
4124 STDERR.print "\nAgain: " | |
4125 p2 = STDIN.gets | |
4126 ensure | |
4127 system "stty echo" | |
4128 end | |
4129 if (p1 == p2) then | |
4130 pm.setpasswd(user, p1.chop!) | |
4131 end | |
4132 STDERR.print "New password for #{user} set successfully\n" | |
4133 else | |
4134 STDERR.print "User #{user} not found\n" | |
4135 end | |
4136 pm.close() | |
4137 exit 0 | |
4138 end | |
4139 def adduser(user) | |
4140 prohibitviahttp() | |
4141 pm = open_pm() | |
4142 exit 1 unless pm | |
60 | 4143 if pm.userexist?(user) && !ENV['PWRESET'] |
59
595ff0134cd9
Skip creation of user which is already registered.
HIROSE Yuuji <yuuji@gentei.org>
parents:
58
diff
changeset
|
4144 printf("User %s already exists. Skip.\n", user) |
60 | 4145 printf("If you reset passwd to new one, PWRESET=1 #{$0} ...\n") |
59
595ff0134cd9
Skip creation of user which is already registered.
HIROSE Yuuji <yuuji@gentei.org>
parents:
58
diff
changeset
|
4146 exit 1 |
595ff0134cd9
Skip creation of user which is already registered.
HIROSE Yuuji <yuuji@gentei.org>
parents:
58
diff
changeset
|
4147 end |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
4148 email = nil |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
4149 if /(.*@.*)=(.*@.*)/ =~ user |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
4150 user, email = $1, $2 |
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
4151 end |
0 | 4152 newpwd = pm.setnewpasswd(user, 4) |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
4153 @sc.createuser(user, email) |
0 | 4154 print "#{user}'s password is #{newpwd}\n" |
4155 pm.close() | |
4156 exit 0 | |
4157 end | |
4158 def deluser(user) | |
4159 prohibitviahttp() | |
4160 pm = open_pm() | |
4161 exit 1 unless pm | |
4162 pm.delete(user) | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
4163 @sc.deleteuser(user) |
0 | 4164 pm.close() |
4165 exit 0 | |
4166 end | |
4167 | |
4168 # read configuratoin file | |
4169 def readconf(conf) | |
4170 cf = "after5.cf" #conf # || @opt['conf'] | |
4171 cf = File.join(@mydir, cf) unless test(?s, cf) | |
4172 cf = File.join(ENV["HOME"], cf) unless test(?s, cf) | |
4173 return unless test(?s, cf) | |
4174 begin | |
4175 IO.foreach(cf){|line| | |
26 | 4176 line = line.toeuc |
0 | 4177 next if /^\s *#/ =~ line |
4178 line.chop! | |
4179 line.sub!(/^\s*#.*/, '') | |
4180 next if /^$/ =~ line | |
4181 case line | |
4182 # title, type = line.split(/\t+/) | |
4183 when /^([a-z]+)=(.*)/oi | |
4184 key, value = $1, $2 | |
4185 case value | |
6 | 4186 when /^(no|none|null|nil|false|0|off)$/io |
0 | 4187 @opt[key] = nil |
4188 else | |
45
1b16890d61d6
ML: digited subject, ML-specific email addresses, spooling
HIROSE Yuuji <yuuji@gentei.org>
parents:
44
diff
changeset
|
4189 @opt[key] = value.untaint |
0 | 4190 end |
4191 print "#{key} set to #{value}\n" if $DEBUG | |
4192 end | |
4193 } | |
4194 rescue | |
26 | 4195 STDERR.printf("Configuration file %s not readable\n", cf) |
0 | 4196 end |
4197 end | |
4198 | |
4199 def parsedate(string) | |
4200 if %r,^(\d\d\d\d+)/(\d+)/(\d+)/(\d+)/([^/]+)$, =~ string | |
4201 sprintf "%04d/%02d/%02d/%04d/%s", $1.to_i, $2.to_i, $3.to_i, $4.to_i, | |
4202 grepgroup($5) | |
4203 elsif %r,^(\d\d\d\d+)/(\d+)/(\d+)/(\d+), =~ string | |
4204 sprintf "%04d/%02d/%02d/%04d", $1.to_i, $2.to_i, $3.to_i, $4.to_i | |
4205 elsif %r,^(\d\d\d\d+)/(\d+)/(\d+), =~ string | |
4206 sprintf "%04d/%02d/%02d", $1.to_i, $2.to_i, $3.to_i | |
4207 elsif %r,^(\d\d\d\d+)/(\d+), =~ string | |
4208 sprintf "%04d/%02d", $1.to_i, $2.to_i | |
4209 elsif %r,^(\d\d\d\d+)/(\d+), =~ string | |
4210 sprintf "%04d", $1.to_i | |
4211 end | |
4212 end | |
4213 | |
4214 def getarg() | |
4215 argument = {} | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
4216 @oldargv = ARGV.dup |
0 | 4217 |
4218 while /^-/ =~ ARGV[0] | |
4219 case ARGV[0] | |
4220 when '-f' | |
4221 conf = ARGV[1] | |
4222 ARGV.shift | |
4223 when "-d" | |
4224 $DEBUG = true | |
4225 when "-install" | |
14 | 4226 when "-stream" |
4227 # ARGV.shift | |
4228 # @job = 'show_by_text "2005/1/18"' | |
4229 @job = 'doMail' | |
0 | 4230 when "-addsched" |
4231 @job = "addsched" | |
4232 when "-today" | |
4233 @job = "today" | |
2 | 4234 when "-today_p" |
4235 argument['displaymode'] = 'personal' | |
4236 @job = "today" | |
4237 when "-today_n" | |
4238 argument['displaymode'] = 'normal' | |
4239 @job = "today" | |
0 | 4240 when "-remove" |
4241 ARGV.shift | |
4242 @job = 'remove "'+parsedate(ARGV[0])+'"' | |
14 | 4243 when "-move" |
4244 ARGV.shift | |
4245 @job = 'move "'+parsedate(ARGV[0])+'"' | |
0 | 4246 when "-modify" |
4247 ARGV.shift | |
4248 @job = 'modify "'+parsedate(ARGV[0])+'"' | |
4249 when "-month" | |
4250 ARGV.shift | |
4251 @job = 'month "'+parsedate(ARGV[0])+'"' | |
4252 when "-show" | |
4253 ARGV.shift | |
4254 # @job = "show '"+ARGV[0]+"'" | |
4255 @job = "show '"+parsedate(ARGV[0])+"'" | |
4256 when "-login" | |
4257 @job = "login" | |
4258 when "-userman" | |
4259 @job = "userman" | |
4260 when "-usermod" | |
4261 @job = "usermod" | |
4262 when "-groupinout" | |
4263 @job = "groupinout" | |
4264 when "-groupsubmit" | |
4265 @job = "groupsubmit" | |
4266 when "-groupman" | |
48
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
4267 ARGV.shift |
05de5274c110
Another ml-address can be set.
HIROSE Yuuji <yuuji@gentei.org>
parents:
47
diff
changeset
|
4268 x=ARGV[0] |
70
2e293d4d8db4
Not using proc.call for the sake of displaying document title.
HIROSE Yuuji <yuuji@gentei.org>
parents:
69
diff
changeset
|
4269 @job = "groupman("+(x ? "'#{x.dup.untaint}'" : "") + ")" |
0 | 4270 when "-groupmod" |
4271 @job = "groupmod" | |
4272 when "-notify" | |
4273 @job = 'notify' # + exit | |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
4274 when "-list" |
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
4275 @job = 'list' # + exit |
0 | 4276 when "-newgroup" |
4277 @job = 'newgroup' | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
4278 when /^-(admgroup|listdraft)$/ |
0 | 4279 ARGV.shift |
84
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
4280 #gr = safecopy(grepgroup(ARGV[0])) |
f67f5304baac
Add feature of sending message to a user
HIROSE Yuuji <yuuji@gentei.org>
parents:
83
diff
changeset
|
4281 gr = safecopy(ARGV[0]) # -listdraft can be called with user 2013/12/12 |
0 | 4282 ##gr.untaint |
37
1515ea889ea1
First implementation of ML feature.
HIROSE Yuuji <yuuji@gentei.org>
parents:
36
diff
changeset
|
4283 @job = safecopy($1)+' "'+gr+'"' |
0 | 4284 when "-admgroupsub" |
4285 @job = 'admgroupsub' | |
4286 when "-newgroupsub" | |
4287 @job = 'newgroupsub' | |
4288 when "-delusersub" | |
4289 ARGV.shift | |
6 | 4290 usr = safecopy(users().grep(ARGV[0])[0]) |
0 | 4291 @job = 'delusersub "'+usr+'"' |
4292 when "-delgroupsub" | |
4293 ARGV.shift | |
42
07ef43ac4f15
Some ruby-1.9 workarounds and enhancement to logging and messaging.
HIROSE Yuuji <yuuji@gentei.org>
parents:
41
diff
changeset
|
4294 gr = safecopy(grepgroup(ARGV[0])) |
0 | 4295 @job = 'delgroupsub "'+gr+'"' |
4296 when /-(setpasswd|deluser|adduser)$/ | |
4297 ARGV.shift | |
4298 @job = $1+ " '#{ARGV[0]}'" # + exit | |
92
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4299 when "-mp" |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4300 ARGV.shift |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4301 r = recompose_multipart(ARGF.readlines.join) |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4302 open("/tmp/a", "w"){|a| |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4303 |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4304 a.printf("R:(((%s)))\n", r) |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4305 } |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4306 |
52a3c4444a4c
Set from:comment to email if post from alien
HIROSE Yuuji <yuuji@gentei.org>
parents:
91
diff
changeset
|
4307 exit 0 |
0 | 4308 when "" |
4309 end | |
4310 ARGV.shift | |
4311 end | |
4312 | |
4313 readconf(@conf) | |
4314 | |
4315 query = '' | |
4316 method = ENV["REQUEST_METHOD"] | |
4317 if /POST/i =~ method then | |
4318 length = ENV["CONTENT_LENGTH"].to_i | |
4319 query = STDIN.read(length) | |
4320 elsif /GET/i =~ method then | |
4321 query = ENV["QUERY_STRING"] | |
4322 else # executed from command line | |
4323 query = ARGV.join("&") | |
4324 end | |
4325 | |
85 | 4326 if ENV['CONTENT_TYPE'] && |
4327 %r,multipart/form-data.*boundary=(.*),i =~ ENV['CONTENT_TYPE'] | |
4328 boundary = $1 | |
4329 query.split("\r\n--"+boundary).each {|unit| | |
4330 if /Content-Disposition.*\bname=([\'\"])?(\S*)\1/i =~ unit | |
4331 argument.has_key?(key=$2) or argument[key]=[] | |
4332 newvalue = Hash.new | |
4333 if /^Content.*filename=([\'\"])?(\S*)\1/i =~ unit | |
4334 newvalue['filename'] = $2 | |
4335 end | |
87 | 4336 newvalue['value'] = unit.sub(/.*?\r\n\r\n/m, "") # Shortest match |
85 | 4337 if /^Content-type:\s*(\S*)/i =~ unit |
4338 newvalue['content-type'] = $1 | |
4339 else | |
4340 newvalue['value'].gsub!("\r\n", "\n") | |
4341 end | |
4342 argument[key] << newvalue | |
4343 end | |
4344 } | |
4345 if $DEBUG | |
4346 open("/tmp/body", "w"){|x| | |
4347 x.write query.split("\r\n--"+boundary+"\r\n")[-1] | |
4348 argument.each{|k,v| | |
4349 x.printf(" %s => %s\n", k.inspect, v.inspect)} | |
4350 x.printf("boundary=\n%s\n",boundary) | |
4351 x.printf("ENV=%s\n",ENV.inspect) | |
4352 x.write query} | |
4353 end | |
4354 else | |
4355 for unit in query.split(/\&/) | |
4356 if /^([a-z][-_0-9@%a-z.]*)=(.*)/i =~ unit | |
4357 key, value = $1, $2 | |
4358 #value.gsub!(/%(..)/){[$1.hex].pack("c")} # これでURLデコードが一発 | |
4359 decode!(value) | |
4360 decode!(key) | |
4361 value = Kconv::toeuc(value) # EUCに変換 | |
4362 printf "[%s] = %s\n", key, value if $DEBUG | |
4363 argument[key] = value | |
4364 end | |
0 | 4365 end |
4366 end | |
4367 argument | |
4368 end | |
4369 def getcookie() | |
4370 cookie = {} | |
7 | 4371 return cookie unless ENV['HTTP_COOKIE'] |
4372 #if /value=(.*)/ =~ ENV['HTTP_COOKIE'] | |
4373 for cv in ENV['HTTP_COOKIE'].split(/[\; ]+/).grep(/(value|prefs)=(.*)/) | |
0 | 4374 # value=$1.gsub!(/%(..)/){[$1.hex].pack("c")} |
7 | 4375 next unless /\w+=(.*)/ =~ cv |
0 | 4376 value=decode!($1) |
7 | 4377 next unless value |
0 | 4378 for line in value.split("&") |
4379 if /(\w+)=(.*)/ =~ line | |
4380 key, value = $1, $2 | |
4381 #value.gsub!(/%(..)/){[$1.hex].pack("c")} # これでURLデコードが一発 | |
4382 decode!(value) | |
4383 value = Kconv::toeuc(value) # EUCに変換 | |
4384 printf "cookie[%s] = %s\n", key, value if $DEBUG | |
4385 cookie[key] = value | |
4386 end | |
4387 end | |
4388 end | |
4389 cookie | |
4390 end | |
4391 end | |
4392 | |
17 | 4393 $KCODE='e' if RUBY_VERSION < "1.9" |
0 | 4394 After5.new.doit |
4395 | |
4396 if __FILE__ == $0 | |
4397 end | |
4398 | |
4399 | |
4400 # Local variables: | |
4401 # buffer-file-coding-system: euc-jp | |
4402 # End: |