runo 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/lib/_field.rb +5 -5
- data/lib/_i18n.rb +5 -2
- data/lib/_storage/_storage.rb +5 -3
- data/lib/_storage/file.rb +5 -4
- data/lib/_storage/sequel.rb +1 -1
- data/lib/_storage/temp.rb +1 -1
- data/lib/_widget/message.rb +2 -2
- data/lib/_widget/navi.rb +1 -1
- data/lib/_workflow/attachment.rb +1 -1
- data/lib/meta/timestamp.rb +2 -2
- data/lib/runo.rb +5 -5
- data/lib/scalar/file.rb +2 -2
- data/lib/scalar/img.rb +1 -1
- data/lib/scalar/password.rb +1 -1
- data/lib/scalar/textarea_wiki.rb +1 -1
- data/lib/set/_set.rb +3 -3
- data/lib/set/dynamic.rb +4 -4
- data/lib/set/static.rb +1 -1
- data/t/test_img.rb +3 -3
- data/t/test_runo_call.rb +1 -1
- data/t/test_runo_i18n.rb +7 -0
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -107,7 +107,7 @@ See the URL:
|
|
107
107
|
http://localhost:9292/fab/
|
108
108
|
|
109
109
|
You have just created your first app. Open a bottle of your favorite drink and make yourself comfortable.
|
110
|
-
When you need more complicated tricks, HTMLs under skin/examples/ will be your help.
|
110
|
+
When you need more complicated tricks, HTMLs under skin/examples/ will be your help. Also, you should check out the wiki: http://wiki.github.com/afunai/runo/
|
111
111
|
|
112
112
|
== Note on Patches/Pull Requests
|
113
113
|
|
data/lib/_field.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
# Author:: Akira FUNAI
|
4
|
-
# Copyright:: Copyright (c) 2009 Akira FUNAI
|
4
|
+
# Copyright:: Copyright (c) 2009-2010 Akira FUNAI
|
5
5
|
|
6
6
|
require 'rubygems'
|
7
7
|
require 'rack/utils'
|
8
8
|
|
9
|
-
$KCODE = 'UTF8'
|
9
|
+
$KCODE = 'UTF8' if RUBY_VERSION < '1.9.0'
|
10
10
|
|
11
11
|
class Runo::Field
|
12
12
|
|
@@ -91,11 +91,11 @@ class Runo::Field
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def meta_owners
|
94
|
-
(my[:parent] ? my[:parent][:owners] : ['root']) | @meta[:owner]
|
94
|
+
(my[:parent] ? my[:parent][:owners] : ['root']) | Array(@meta[:owner])
|
95
95
|
end
|
96
96
|
|
97
97
|
def meta_admins
|
98
|
-
(my[:parent] ? my[:parent][:admins] : ['root']) | @meta[:admin]
|
98
|
+
(my[:parent] ? my[:parent][:admins] : ['root']) | Array(@meta[:admin])
|
99
99
|
end
|
100
100
|
|
101
101
|
def meta_group
|
@@ -186,7 +186,7 @@ class Runo::Field
|
|
186
186
|
end
|
187
187
|
|
188
188
|
def empty?
|
189
|
-
val.to_s == ''
|
189
|
+
val.respond_to?(:empty?) ? val.empty? : (val.to_s == '')
|
190
190
|
end
|
191
191
|
|
192
192
|
def errors
|
data/lib/_i18n.rb
CHANGED
@@ -10,6 +10,7 @@ module Runo::I18n
|
|
10
10
|
if args.first.is_a? ::Hash
|
11
11
|
self.gsub(/%\{(\w+)\}/) { args.first[$1.intern].to_s }
|
12
12
|
else
|
13
|
+
args = args.first if args.first.is_a? ::Array
|
13
14
|
::String.new(self.gsub(/%\{(\w+)\}/, '%s')) % args
|
14
15
|
end
|
15
16
|
end
|
@@ -83,7 +84,9 @@ module Runo::I18n
|
|
83
84
|
range.sub(/-.*/, ''),
|
84
85
|
].uniq.each {|r|
|
85
86
|
po_file = ::File.join(self.po_dir, r, "#{self.domain}.po")
|
86
|
-
return open(po_file
|
87
|
+
return ::File.open(po_file, ((RUBY_VERSION < '1.9') ? 'r' : 'r:utf-8')) {|f|
|
88
|
+
self.parse_msg f
|
89
|
+
} if ::File.readable? po_file
|
87
90
|
return {} if r == 'en' # default
|
88
91
|
}
|
89
92
|
}
|
@@ -123,7 +126,7 @@ module Runo::I18n
|
|
123
126
|
module_function
|
124
127
|
|
125
128
|
def _(msgid)
|
126
|
-
Runo::I18n::Msgstr.new(Runo::I18n.msg[msgid].
|
129
|
+
Runo::I18n::Msgstr.new(Array(Runo::I18n.msg[msgid]).first || msgid)
|
127
130
|
end
|
128
131
|
|
129
132
|
def n_(msgid, msgid_plural, n)
|
data/lib/_storage/_storage.rb
CHANGED
@@ -102,6 +102,7 @@ class Runo::Storage
|
|
102
102
|
([:d, :id, :p] & conds.keys).each {|cid|
|
103
103
|
case cid
|
104
104
|
when :d
|
105
|
+
conds[:d] = conds[:d].first if conds[:d].is_a? ::Array
|
105
106
|
conds[:d] = conds[:d].to_s
|
106
107
|
conds[:d] = last(:d, conds) if conds[:d] =~ /9999(99)?(99)?/
|
107
108
|
conds[:d] = nil unless conds[:d] =~ Runo::REX::COND_D
|
@@ -117,6 +118,7 @@ class Runo::Storage
|
|
117
118
|
end
|
118
119
|
}.uniq.compact
|
119
120
|
when :p
|
121
|
+
conds[:p] = conds[:p].first if conds[:p].is_a? ::Array
|
120
122
|
conds[:p] = conds[:p].to_s
|
121
123
|
conds[:p] = last(:p, conds) if conds[:p] == 'last'
|
122
124
|
conds[:p] = nil unless conds[:p] =~ /^\d+$/
|
@@ -127,7 +129,7 @@ class Runo::Storage
|
|
127
129
|
|
128
130
|
def _select(conds)
|
129
131
|
if conds[:id]
|
130
|
-
_select_by_id(conds) | (@sd.instance_variable_get(:@item_object).keys & conds[:id]
|
132
|
+
_select_by_id(conds) | (@sd.instance_variable_get(:@item_object).keys & Array(conds[:id]))
|
131
133
|
elsif cid = (conds.keys - [:order, :p]).first
|
132
134
|
m = "_select_by_#{cid}"
|
133
135
|
respond_to?(m, true) ? __send__(m, conds) : []
|
@@ -146,7 +148,7 @@ class Runo::Storage
|
|
146
148
|
|
147
149
|
page = conds[:p].to_i
|
148
150
|
page = 1 if page < 1
|
149
|
-
item_ids[(page - 1) * size, size]
|
151
|
+
Array item_ids[(page - 1) * size, size]
|
150
152
|
end
|
151
153
|
|
152
154
|
def _sibs_id(conds)
|
@@ -174,7 +176,7 @@ class Runo::Storage
|
|
174
176
|
end
|
175
177
|
|
176
178
|
def cast_ids(ids)
|
177
|
-
ids.
|
179
|
+
Array(ids).collect {|i|
|
178
180
|
id = (i =~ /^[a-z]/) ? "00000000_#{i}" : i
|
179
181
|
id if id =~ Runo::REX::ID
|
180
182
|
}.compact
|
data/lib/_storage/file.rb
CHANGED
@@ -106,7 +106,7 @@ class Runo::Storage::File < Runo::Storage
|
|
106
106
|
private
|
107
107
|
|
108
108
|
def _select_by_id(conds)
|
109
|
-
glob(conds[:id]
|
109
|
+
glob(Array(conds[:id])).collect {|f| f[/\d.*/][Runo::REX::ID] }.compact
|
110
110
|
end
|
111
111
|
|
112
112
|
def _select_by_d(conds)
|
@@ -138,7 +138,7 @@ class Runo::Storage::File < Runo::Storage
|
|
138
138
|
|
139
139
|
def load(id)
|
140
140
|
v = nil
|
141
|
-
file = glob(id
|
141
|
+
file = glob(Array(id)).sort.first
|
142
142
|
::File.open(::File.join(@dir, file), 'r') {|f|
|
143
143
|
f.flock ::File::LOCK_SH
|
144
144
|
f.binmode
|
@@ -165,6 +165,7 @@ class Runo::Storage::File < Runo::Storage
|
|
165
165
|
|
166
166
|
file = "#{file_prefix}#{id}.#{ext}"
|
167
167
|
if old_id && f = ::File.open(::File.join(@dir, file), 'a')
|
168
|
+
f.seek(0, IO::SEEK_END)
|
168
169
|
return if f.pos != 0 # duplicate id
|
169
170
|
move(old_id, id) unless old_id == :new_id
|
170
171
|
end
|
@@ -180,7 +181,7 @@ class Runo::Storage::File < Runo::Storage
|
|
180
181
|
end
|
181
182
|
|
182
183
|
def remove_file(id)
|
183
|
-
glob_pattern = "#{file_prefix}#{pattern_for id
|
184
|
+
glob_pattern = "#{file_prefix}#{pattern_for Array(id)}[.-]*"
|
184
185
|
files = ::Dir.chdir(@dir) { ::Dir.glob glob_pattern } # may include child files
|
185
186
|
files.each {|file|
|
186
187
|
::File.unlink ::File.join(@dir, file)
|
@@ -188,7 +189,7 @@ class Runo::Storage::File < Runo::Storage
|
|
188
189
|
end
|
189
190
|
|
190
191
|
def rename_file(old_id, new_id)
|
191
|
-
glob_pattern = "#{file_prefix}#{pattern_for old_id
|
192
|
+
glob_pattern = "#{file_prefix}#{pattern_for Array(old_id)}*"
|
192
193
|
files = ::Dir.chdir(@dir) { ::Dir.glob glob_pattern } # may include child files
|
193
194
|
rex = /^\A#{file_prefix}#{old_id}/
|
194
195
|
files.each {|file|
|
data/lib/_storage/sequel.rb
CHANGED
data/lib/_storage/temp.rb
CHANGED
data/lib/_widget/message.rb
CHANGED
@@ -40,10 +40,10 @@ class Runo::Set::Dynamic
|
|
40
40
|
end
|
41
41
|
|
42
42
|
message.keys.collect {|type|
|
43
|
-
lis = message[type].collect {|m| " <li>#{Runo::Field.h m}</li>\n" }
|
43
|
+
lis = Array(message[type]).collect {|m| " <li>#{Runo::Field.h m}</li>\n" }
|
44
44
|
<<_html
|
45
45
|
<ul class="message #{type}">
|
46
|
-
#{lis}</ul>
|
46
|
+
#{lis.join}</ul>
|
47
47
|
_html
|
48
48
|
}.join if message
|
49
49
|
end
|
data/lib/_widget/navi.rb
CHANGED
@@ -66,7 +66,7 @@ class Runo::Set::Dynamic
|
|
66
66
|
base_conds.delete :p
|
67
67
|
conds = arg[:navi][:sibs].values.first
|
68
68
|
if p = arg[:conds][:p]
|
69
|
-
range = ['1', conds.last] + ((p.to_i - 5)..(p.to_i + 5)).
|
69
|
+
range = ['1', conds.last] + Array((p.to_i - 5)..(p.to_i + 5)).collect {|i| i.to_s }
|
70
70
|
conds = conds & range
|
71
71
|
end
|
72
72
|
conds.collect {|cond|
|
data/lib/_workflow/attachment.rb
CHANGED
@@ -37,7 +37,7 @@ _html
|
|
37
37
|
item_tmpl = item[:tmpl][:index].sub(/[\w\W]*\$\(.*?\)/, "\\&#{button}")
|
38
38
|
item.send(:_get_by_tmpl, item_arg, item_tmpl)
|
39
39
|
}
|
40
|
-
tmpl = my[:tmpl][:index].gsub('$()', item_outs
|
40
|
+
tmpl = my[:tmpl][:index].gsub('$()', item_outs)
|
41
41
|
_get_by_tmpl({:p_action => arg[:p_action], :action => :update}, tmpl)
|
42
42
|
end
|
43
43
|
}
|
data/lib/meta/timestamp.rb
CHANGED
@@ -13,8 +13,8 @@ class Runo::Meta::Timestamp < Runo::Field
|
|
13
13
|
|
14
14
|
def initialize(meta = {})
|
15
15
|
meta[:size] = $&.to_i if meta[:tokens] && meta[:tokens].find {|t| t =~ /^\d+$/ }
|
16
|
-
meta[:can_edit] = true if meta[:tokens].
|
17
|
-
meta[:can_update] = true if meta[:tokens].
|
16
|
+
meta[:can_edit] = true if Array(meta[:tokens]).include? 'can_edit'
|
17
|
+
meta[:can_update] = true if Array(meta[:tokens]).include? 'can_update'
|
18
18
|
super
|
19
19
|
end
|
20
20
|
|
data/lib/runo.rb
CHANGED
@@ -326,7 +326,7 @@ class Runo
|
|
326
326
|
'Content-Length' => body.size.to_s,
|
327
327
|
}
|
328
328
|
),
|
329
|
-
body,
|
329
|
+
[body],
|
330
330
|
]
|
331
331
|
end
|
332
332
|
|
@@ -349,7 +349,7 @@ _html
|
|
349
349
|
'Content-Length' => body.size.to_s,
|
350
350
|
'Location' => result[:location],
|
351
351
|
},
|
352
|
-
body
|
352
|
+
[body]
|
353
353
|
]
|
354
354
|
end
|
355
355
|
|
@@ -361,7 +361,7 @@ _html
|
|
361
361
|
'Content-Type' => 'text/html',
|
362
362
|
'Content-Length' => body.size.to_s,
|
363
363
|
},
|
364
|
-
body,
|
364
|
+
[body],
|
365
365
|
]
|
366
366
|
end
|
367
367
|
|
@@ -373,7 +373,7 @@ _html
|
|
373
373
|
'Content-Type' => 'text/html',
|
374
374
|
'Content-Length' => body.size.to_s,
|
375
375
|
},
|
376
|
-
body
|
376
|
+
[body]
|
377
377
|
]
|
378
378
|
end
|
379
379
|
|
@@ -389,7 +389,7 @@ _html
|
|
389
389
|
'Content-Length' => body.size.to_s,
|
390
390
|
}
|
391
391
|
),
|
392
|
-
body,
|
392
|
+
[body],
|
393
393
|
]
|
394
394
|
end
|
395
395
|
|
data/lib/scalar/file.rb
CHANGED
@@ -122,13 +122,13 @@ _html
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def val_cast(v)
|
125
|
-
if v && v[:tempfile]
|
125
|
+
if v.is_a?(::Hash) && v[:tempfile]
|
126
126
|
v[:tempfile].rewind
|
127
127
|
@body = v[:tempfile].read
|
128
128
|
{
|
129
129
|
'basename' => File.basename(v[:filename]),
|
130
130
|
'type' => v[:type] || 'application/octet-stream',
|
131
|
-
'size' => @body.size,
|
131
|
+
'size' => @body.respond_to?(:bytesize) ? @body.bytesize : @body.size,
|
132
132
|
}
|
133
133
|
elsif v.is_a?(::Hash) && v['basename']
|
134
134
|
{
|
data/lib/scalar/img.rb
CHANGED
data/lib/scalar/password.rb
CHANGED
@@ -44,7 +44,7 @@ _html
|
|
44
44
|
@val = v
|
45
45
|
when :create, :update
|
46
46
|
if v.is_a?(::String) && !v.empty?
|
47
|
-
salt = ('a'..'z')
|
47
|
+
salt = Array('a'..'z')[rand(26)] + Array('a'..'z')[rand(26)]
|
48
48
|
@size = v.size
|
49
49
|
@val = v.crypt salt
|
50
50
|
elsif @val.nil?
|
data/lib/scalar/textarea_wiki.rb
CHANGED
data/lib/set/_set.rb
CHANGED
@@ -149,7 +149,7 @@ module Runo::Set
|
|
149
149
|
item_arg = item_arg(arg, item[:id])
|
150
150
|
next if item.empty? && ![:create, :update].include?(item_arg[:action])
|
151
151
|
block ? block.call(item, item_arg) : item.get(item_arg)
|
152
|
-
}
|
152
|
+
}.join
|
153
153
|
end
|
154
154
|
|
155
155
|
def _g_errors(arg)
|
@@ -157,7 +157,7 @@ module Runo::Set
|
|
157
157
|
end
|
158
158
|
|
159
159
|
def item_arg(arg, steps)
|
160
|
-
steps.
|
160
|
+
Array(steps).inject(arg) {|a, s|
|
161
161
|
i = a[s] || {}
|
162
162
|
i[:p_action] = a[:action]
|
163
163
|
unless i[:action]
|
@@ -179,7 +179,7 @@ module Runo::Set
|
|
179
179
|
elsif id =~ Runo::REX::ID_NEW
|
180
180
|
permit? :create
|
181
181
|
else
|
182
|
-
item_action = v[:action] || :update
|
182
|
+
item_action = (v.is_a?(::Hash) && v[:action]) || :update
|
183
183
|
item(id) && item(id).permit?(item_action)
|
184
184
|
end
|
185
185
|
}
|
data/lib/set/dynamic.rb
CHANGED
@@ -24,10 +24,10 @@ class Runo::Set::Dynamic < Runo::Field
|
|
24
24
|
}
|
25
25
|
|
26
26
|
my[:p_size] = meta[:max] if meta[:max]
|
27
|
-
my[:preview] = :optional if meta[:tokens].
|
28
|
-
my[:preview] = :mandatory if meta[:tokens].
|
29
|
-
my[:order] = 'id' if meta[:tokens].
|
30
|
-
my[:order] = '-id' if meta[:tokens].
|
27
|
+
my[:preview] = :optional if Array(meta[:tokens]).include?('may_preview')
|
28
|
+
my[:preview] = :mandatory if Array(meta[:tokens]).include?('should_preview')
|
29
|
+
my[:order] = 'id' if Array(meta[:tokens]).include? 'asc'
|
30
|
+
my[:order] = '-id' if Array(meta[:tokens]).include? 'desc'
|
31
31
|
end
|
32
32
|
|
33
33
|
def meta_href
|
data/lib/set/static.rb
CHANGED
@@ -86,7 +86,7 @@ _html
|
|
86
86
|
|
87
87
|
def collect_item(conds = {}, &block)
|
88
88
|
items = my[:item].keys
|
89
|
-
items &= conds[:id]
|
89
|
+
items &= Array(conds[:id]) if conds[:id] # select item(s) by id
|
90
90
|
items.sort.collect {|id|
|
91
91
|
item = @item_object[id] ||= Runo::Field.instance(
|
92
92
|
my[:item][id].merge(:id => id, :parent => self)
|
data/t/test_img.rb
CHANGED
@@ -211,7 +211,7 @@ _eos
|
|
211
211
|
{
|
212
212
|
:input => input,
|
213
213
|
'CONTENT_TYPE' => 'multipart/form-data; boundary=-foobarbaz',
|
214
|
-
'CONTENT_LENGTH' => input.
|
214
|
+
'CONTENT_LENGTH' => input.respond_to?(:bytesize) ? input.bytesize : input.size,
|
215
215
|
}
|
216
216
|
)
|
217
217
|
tid = res.headers['Location'][Runo::REX::TID]
|
@@ -236,8 +236,8 @@ _eos
|
|
236
236
|
'Runo#call to a img item should return the mime type of the file'
|
237
237
|
)
|
238
238
|
assert_equal(
|
239
|
-
@img.size,
|
240
|
-
res.body.size,
|
239
|
+
@img.respond_to?(:bytesize) ? @img.bytesize : @img.size,
|
240
|
+
res.body.respond_to?(:bytesize) ? res.body.bytesize : res.body.size,
|
241
241
|
'Runo#call to a img item should return the binary body of the file'
|
242
242
|
)
|
243
243
|
|
data/t/test_runo_call.rb
CHANGED
@@ -682,7 +682,7 @@ _html
|
|
682
682
|
res = Rack::MockRequest.new(@runo).post(
|
683
683
|
"http://example.com/t_attachment/main/update.html",
|
684
684
|
{
|
685
|
-
:input => "_012-comment=abc&.status-public=create"
|
685
|
+
:input => "_012-comment=abc&.status-public=create&_token=#{Runo.token}"
|
686
686
|
}
|
687
687
|
)
|
688
688
|
res.headers['Location'] =~ Runo::REX::PATH_ID
|
data/t/test_runo_i18n.rb
CHANGED
@@ -302,6 +302,13 @@ _eos
|
|
302
302
|
"Runo::I18n::Msgstr#% should regard %{...} as '%s' if given a scalar"
|
303
303
|
)
|
304
304
|
|
305
|
+
s = n_('one foo', '%{n} foo %{bar}', 2)
|
306
|
+
assert_equal(
|
307
|
+
'2 foo selected',
|
308
|
+
s % [2, 'selected'],
|
309
|
+
"Runo::I18n::Msgstr#% should regard %{...} as '%s' if given an array"
|
310
|
+
)
|
311
|
+
|
305
312
|
s = n_('one color', '%{n} colors', 1)
|
306
313
|
assert_instance_of(
|
307
314
|
Runo::I18n::Msgstr,
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 1
|
8
7
|
- 2
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Akira FUNAI
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-07-
|
17
|
+
date: 2010-07-20 00:00:00 +09:00
|
18
18
|
default_executable: runo
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|