runo 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|