bike 0.2.1
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/LICENSE +19 -0
- data/README.rdoc +124 -0
- data/bin/bike +35 -0
- data/lib/_error.rb +14 -0
- data/lib/_field.rb +260 -0
- data/lib/_i18n.rb +144 -0
- data/lib/_parser.rb +256 -0
- data/lib/_path.rb +86 -0
- data/lib/_storage/_storage.rb +215 -0
- data/lib/_storage/file.rb +201 -0
- data/lib/_storage/sequel.rb +174 -0
- data/lib/_storage/temp.rb +73 -0
- data/lib/_widget/action_create.rb +23 -0
- data/lib/_widget/action_login.rb +22 -0
- data/lib/_widget/action_signup.rb +16 -0
- data/lib/_widget/action_update.rb +16 -0
- data/lib/_widget/crumb.rb +24 -0
- data/lib/_widget/done.rb +16 -0
- data/lib/_widget/login.rb +25 -0
- data/lib/_widget/me.rb +31 -0
- data/lib/_widget/message.rb +51 -0
- data/lib/_widget/navi.rb +88 -0
- data/lib/_widget/submit.rb +49 -0
- data/lib/_widget/view_ym.rb +77 -0
- data/lib/_workflow/_workflow.rb +89 -0
- data/lib/_workflow/attachment.rb +50 -0
- data/lib/_workflow/blog.rb +28 -0
- data/lib/_workflow/contact.rb +23 -0
- data/lib/_workflow/forum.rb +26 -0
- data/lib/_workflow/register.rb +39 -0
- data/lib/bike.rb +396 -0
- data/lib/meta/_meta.rb +20 -0
- data/lib/meta/group.rb +19 -0
- data/lib/meta/id.rb +59 -0
- data/lib/meta/owner.rb +21 -0
- data/lib/meta/timestamp.rb +118 -0
- data/lib/scalar/checkbox.rb +68 -0
- data/lib/scalar/file.rb +144 -0
- data/lib/scalar/img.rb +112 -0
- data/lib/scalar/password.rb +58 -0
- data/lib/scalar/radio.rb +47 -0
- data/lib/scalar/select.rb +47 -0
- data/lib/scalar/text.rb +38 -0
- data/lib/scalar/textarea.rb +35 -0
- data/lib/scalar/textarea_pre.rb +14 -0
- data/lib/scalar/textarea_wiki.rb +173 -0
- data/lib/set/_set.rb +196 -0
- data/lib/set/dynamic.rb +177 -0
- data/lib/set/static.rb +102 -0
- data/lib/set/static_folder.rb +96 -0
- data/locale/en/index.po +242 -0
- data/locale/index.pot +243 -0
- data/locale/ja/index.po +242 -0
- data/locale/lazy_parser.rb +54 -0
- data/skel/config.ru +27 -0
- data/skel/skin/_users/00000000_frank-avatar.jpg +0 -0
- data/skel/skin/_users/00000000_frank-avatar_small.jpg +0 -0
- data/skel/skin/_users/00000000_frank.yaml +12 -0
- data/skel/skin/_users/00000000_root-avatar.jpg +0 -0
- data/skel/skin/_users/00000000_root-avatar_small.jpg +0 -0
- data/skel/skin/_users/00000000_root.yaml +11 -0
- data/skel/skin/_users/css/users.css +21 -0
- data/skel/skin/_users/css/users.less +25 -0
- data/skel/skin/_users/done.html +42 -0
- data/skel/skin/_users/index.html +46 -0
- data/skel/skin/_users/index.yaml +3 -0
- data/skel/skin/_users/summary.html +40 -0
- data/skel/skin/css/base.css +93 -0
- data/skel/skin/css/base.less +139 -0
- data/skel/skin/css/coax.css +199 -0
- data/skel/skin/css/coax.less +244 -0
- data/skel/skin/examples/blog/20091214_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100630_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100630_0002.yaml +14 -0
- data/skel/skin/examples/blog/20100701_0001.yaml +8 -0
- data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f.jpg +0 -0
- data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f_small.jpg +0 -0
- data/skel/skin/examples/blog/20100701_0002.yaml +19 -0
- data/skel/skin/examples/blog/frank/20100701_0001.yaml +10 -0
- data/skel/skin/examples/blog/frank/index.yaml +4 -0
- data/skel/skin/examples/blog/index.html +51 -0
- data/skel/skin/examples/blog/rss.xml +18 -0
- data/skel/skin/examples/contact/20100701_0001-file.txt +1 -0
- data/skel/skin/examples/contact/20100701_0001.yaml +15 -0
- data/skel/skin/examples/contact/20100701_0002.yaml +8 -0
- data/skel/skin/examples/contact/20100701_0003.yaml +9 -0
- data/skel/skin/examples/contact/index.html +47 -0
- data/skel/skin/examples/contact/js/contact.js +13 -0
- data/skel/skin/examples/contact/summary.html +54 -0
- data/skel/skin/examples/forum/20100701_0001.yaml +41 -0
- data/skel/skin/examples/forum/20100701_0002.yaml +25 -0
- data/skel/skin/examples/forum/index.html +68 -0
- data/skel/skin/examples/forum/summary.html +47 -0
- data/skel/skin/examples/index.html +73 -0
- data/skel/skin/index.html +39 -0
- data/skel/skin/js/base.js +50 -0
- data/t/locale/de/index.po +19 -0
- data/t/locale/en-GB/index.po +25 -0
- data/t/locale/ja/index.po +30 -0
- data/t/skin/_users/00000000_test.yaml +3 -0
- data/t/skin/_users/index.html +13 -0
- data/t/skin/foo/20091120_0001.yaml +7 -0
- data/t/skin/foo/bar/20091120_0001.yaml +5 -0
- data/t/skin/foo/bar/index.yaml +5 -0
- data/t/skin/foo/baz/css/baz.css +1 -0
- data/t/skin/foo/css/foo.css +1 -0
- data/t/skin/foo/index.html +14 -0
- data/t/skin/foo/index.yaml +7 -0
- data/t/skin/foo/not_css/foo.css +1 -0
- data/t/skin/foo/qux/index.html +8 -0
- data/t/skin/foo/qux/moo/index.html +6 -0
- data/t/skin/foo/sub-20100306_0001.yaml +3 -0
- data/t/skin/index.yaml +3 -0
- data/t/skin/t_attachment/index.html +13 -0
- data/t/skin/t_contact/done.html +6 -0
- data/t/skin/t_contact/index.html +9 -0
- data/t/skin/t_file/index.html +16 -0
- data/t/skin/t_img/index.html +14 -0
- data/t/skin/t_img/test.jpg +0 -0
- data/t/skin/t_select/index.html +9 -0
- data/t/skin/t_store/index.html +9 -0
- data/t/skin/t_summary/20100326_0001.yaml +3 -0
- data/t/skin/t_summary/create.html +9 -0
- data/t/skin/t_summary/index.html +9 -0
- data/t/skin/t_summary/summary.html +9 -0
- data/t/t.rb +27 -0
- data/t/test_bike.rb +768 -0
- data/t/test_call.rb +1281 -0
- data/t/test_checkbox.rb +273 -0
- data/t/test_field.rb +330 -0
- data/t/test_file.rb +900 -0
- data/t/test_i18n.rb +325 -0
- data/t/test_id.rb +215 -0
- data/t/test_img.rb +328 -0
- data/t/test_meta.rb +57 -0
- data/t/test_parser.rb +1516 -0
- data/t/test_password.rb +188 -0
- data/t/test_radio.rb +226 -0
- data/t/test_role.rb +249 -0
- data/t/test_select.rb +182 -0
- data/t/test_set_complex.rb +527 -0
- data/t/test_set_dynamic.rb +1504 -0
- data/t/test_set_folder.rb +515 -0
- data/t/test_set_permit.rb +246 -0
- data/t/test_set_static.rb +468 -0
- data/t/test_storage.rb +915 -0
- data/t/test_text.rb +125 -0
- data/t/test_textarea.rb +138 -0
- data/t/test_timestamp.rb +473 -0
- data/t/test_workflow.rb +367 -0
- metadata +347 -0
data/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2010 Akira FUNAI <akira -at- funai -dot- com>
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
4
|
+
copy of this software and associated documentation files (the "Software"),
|
|
5
|
+
to deal in the Software without restriction, including without limitation
|
|
6
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
7
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
|
8
|
+
Software is furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
16
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
18
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
19
|
+
DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
= Bike
|
|
2
|
+
|
|
3
|
+
Bike is the easiest web application framework ever.
|
|
4
|
+
You can make various apps such like blog, forum, contact form by putting single (or several) HTML file with a bit of special markups. The view rules. There is no model definition, no server restart, and no coding at all.
|
|
5
|
+
|
|
6
|
+
== Wiki
|
|
7
|
+
|
|
8
|
+
http://wiki.github.com/afunai/bike/
|
|
9
|
+
|
|
10
|
+
== Features
|
|
11
|
+
|
|
12
|
+
* Model / View / Controller defined dynamically by good old HTML.
|
|
13
|
+
* Any block tags (<ul>, <table> etc.) can be an "app", by adding a workflow class like "app-blog".
|
|
14
|
+
* The contents inside the app tag will be the "model".
|
|
15
|
+
* The model is defined by special tags, like "$(foo = text 1..32)" or "$(bar = select a,b,c)".
|
|
16
|
+
* You can make nested apps inside an app (e.g. blog comments inside a blog entry).
|
|
17
|
+
* Authentication / Authorization / User admin are built in by default.
|
|
18
|
+
* Storage can be plain YAML files (default), or any RDB via Sequel.
|
|
19
|
+
* Bike itself is a Rack application.
|
|
20
|
+
|
|
21
|
+
== Quick Start
|
|
22
|
+
|
|
23
|
+
This is a quick tutorial for making a simple web application using Bike.
|
|
24
|
+
|
|
25
|
+
=== Step 1 - Install Bike
|
|
26
|
+
|
|
27
|
+
Open a command line terminal. Type:
|
|
28
|
+
|
|
29
|
+
gem install bike
|
|
30
|
+
|
|
31
|
+
If you want to make thumbnails for submitted images, you have to install QuickMagick as well.
|
|
32
|
+
http://rubyforge.org/projects/quickmagick/
|
|
33
|
+
|
|
34
|
+
=== Step 2 - Initialize a Bike Directory
|
|
35
|
+
|
|
36
|
+
In a command line terminal, go to an empty directory where you want to build Bike projects.
|
|
37
|
+
Then type:
|
|
38
|
+
|
|
39
|
+
bike init
|
|
40
|
+
|
|
41
|
+
This will create a "bike" directory, which includes:
|
|
42
|
+
|
|
43
|
+
bike/
|
|
44
|
+
config.ru
|
|
45
|
+
skin/
|
|
46
|
+
|
|
47
|
+
=== Step 3 - Start a Test Server
|
|
48
|
+
|
|
49
|
+
In the terminal, change to the newly created "bike" directory.
|
|
50
|
+
Type:
|
|
51
|
+
|
|
52
|
+
bike run
|
|
53
|
+
|
|
54
|
+
=== Step 4 - Try some examples
|
|
55
|
+
|
|
56
|
+
Now open this URL with your browser.
|
|
57
|
+
|
|
58
|
+
http://localhost:9292/
|
|
59
|
+
|
|
60
|
+
You will see the default homepage of Bike.
|
|
61
|
+
There is some links to examples such like Blog, Contact Form, Forum, etc. Just see what can be done by plain HTML files.
|
|
62
|
+
|
|
63
|
+
=== Step 5 - Create Your Own App
|
|
64
|
+
|
|
65
|
+
Let's call our app "fab".
|
|
66
|
+
It is a web-based forum where logged in users can submit their own articles, and everybody can read them.
|
|
67
|
+
We put links to signup / login at bottom of the app.
|
|
68
|
+
|
|
69
|
+
Create a new directory under bike/skin/:
|
|
70
|
+
|
|
71
|
+
mkdir skin/fab/
|
|
72
|
+
|
|
73
|
+
Then create a new HTML file with your favorite editor:
|
|
74
|
+
|
|
75
|
+
edit skin/fab/index.html
|
|
76
|
+
|
|
77
|
+
The content is: (You can just copy & paste, of course)
|
|
78
|
+
|
|
79
|
+
<html>
|
|
80
|
+
<head>
|
|
81
|
+
<title>fab forum</title>
|
|
82
|
+
<link rel="stylesheet" href="/css/base.css" type="text/css" media="screen" />
|
|
83
|
+
</head>
|
|
84
|
+
|
|
85
|
+
<body>
|
|
86
|
+
<h1><a href=".">fab forum</a></h1>
|
|
87
|
+
|
|
88
|
+
<ul id="main" class="app-forum">
|
|
89
|
+
<!-- 1..5 desc may_preview -->
|
|
90
|
+
<li>
|
|
91
|
+
<h2>$(title = text 32 1..32)</h2>
|
|
92
|
+
<div>
|
|
93
|
+
$(content = textarea-pre 60*10 1..)
|
|
94
|
+
<div>by $(_owner) @ $(_timestamp)</div>
|
|
95
|
+
</div>
|
|
96
|
+
</li>
|
|
97
|
+
</ul>
|
|
98
|
+
|
|
99
|
+
<p>$(.action_signup)$(.me)</p>
|
|
100
|
+
</body>
|
|
101
|
+
</html>
|
|
102
|
+
|
|
103
|
+
=== Step 6 - That's it!
|
|
104
|
+
|
|
105
|
+
See the URL:
|
|
106
|
+
|
|
107
|
+
http://localhost:9292/fab/
|
|
108
|
+
|
|
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. Also, you should check out the wiki: http://wiki.github.com/afunai/bike/
|
|
111
|
+
|
|
112
|
+
== Note on Patches/Pull Requests
|
|
113
|
+
|
|
114
|
+
* Fork the project.
|
|
115
|
+
* Make your feature addition or bug fix.
|
|
116
|
+
* Add tests for it. This is important so I don't break it in a
|
|
117
|
+
future version unintentionally.
|
|
118
|
+
* Commit, do not mess with rakefile, version, or history.
|
|
119
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
|
120
|
+
* Send me a pull request. Bonus points for topic branches.
|
|
121
|
+
|
|
122
|
+
== Copyright
|
|
123
|
+
|
|
124
|
+
Copyright (c) 2010 Akira FUNAI <akira -at- funai -dot- com>. See LICENSE for details.
|
data/bin/bike
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
|
|
4
|
+
# Author:: Akira FUNAI
|
|
5
|
+
# Copyright:: Copyright (c) 2009-2010 Akira FUNAI
|
|
6
|
+
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
|
|
9
|
+
$LOAD_PATH.unshift(::File.expand_path('../lib',::File.dirname(__FILE__)))
|
|
10
|
+
require 'bike'
|
|
11
|
+
|
|
12
|
+
case ARGV.shift
|
|
13
|
+
when 'init'
|
|
14
|
+
bike_dir = ::File.expand_path './bike'
|
|
15
|
+
|
|
16
|
+
if ::File.exists? bike_dir
|
|
17
|
+
$stderr.puts "#{bike_dir} already exists."
|
|
18
|
+
exit 1
|
|
19
|
+
else
|
|
20
|
+
$stderr.puts "Setting up Bike files in #{bike_dir}..."
|
|
21
|
+
::FileUtils.cp_r(
|
|
22
|
+
::File.expand_path('../skel',Bike.libdir),
|
|
23
|
+
'./bike',
|
|
24
|
+
:verbose => :true
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
when 'run'
|
|
28
|
+
::Dir.chdir(File.exists?('./config.ru') ? '.' : './bike') {
|
|
29
|
+
$stderr.puts "Starting a server with Bike files in #{::File.expand_path '.'}..."
|
|
30
|
+
system('rackup',*ARGV)
|
|
31
|
+
}
|
|
32
|
+
else
|
|
33
|
+
$stderr.puts 'Usage: bike {init|run [Rack options]}'
|
|
34
|
+
exit 1
|
|
35
|
+
end
|
data/lib/_error.rb
ADDED
data/lib/_field.rb
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
# Author:: Akira FUNAI
|
|
4
|
+
# Copyright:: Copyright (c) 2009-2010 Akira FUNAI
|
|
5
|
+
|
|
6
|
+
require 'rubygems'
|
|
7
|
+
require 'rack/utils'
|
|
8
|
+
|
|
9
|
+
$KCODE = 'UTF8' if RUBY_VERSION < '1.9.0'
|
|
10
|
+
|
|
11
|
+
class Bike::Field
|
|
12
|
+
|
|
13
|
+
include Bike::I18n
|
|
14
|
+
|
|
15
|
+
DEFAULT_META = {}
|
|
16
|
+
|
|
17
|
+
def self.instance(meta = {})
|
|
18
|
+
k = meta[:klass].to_s.split(/-/).inject(Bike) {|c, name|
|
|
19
|
+
name = name.capitalize
|
|
20
|
+
c.const_get(name)
|
|
21
|
+
}
|
|
22
|
+
k.new(meta) if k < self
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.h(val)
|
|
26
|
+
Rack::Utils.escape_html val.to_s
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
attr_reader :action, :result
|
|
30
|
+
|
|
31
|
+
def initialize(meta = {})
|
|
32
|
+
@meta = self.class.const_get(:DEFAULT_META).merge meta
|
|
33
|
+
@val = val_cast(nil)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def inspect
|
|
37
|
+
caller.grep(/`inspect'/).empty? ? super : "<#{self.class} name=\"#{my[:name]}\">"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def [](id, *arg)
|
|
41
|
+
respond_to?("meta_#{id}") ? __send__("meta_#{id}", *arg) : @meta[id]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def []=(id, v)
|
|
45
|
+
@meta[id] = v
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def val
|
|
49
|
+
@val
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def item(*item_steps)
|
|
53
|
+
item_steps = item_steps.first if item_steps.first.is_a? ::Array
|
|
54
|
+
item_steps.empty? ? self : nil # scalar has no item
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def find_ancestor(&block)
|
|
58
|
+
f = self
|
|
59
|
+
block.call(f) ? (return f) : (f = f[:parent]) until f.nil?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def meta_name
|
|
63
|
+
my[:parent] && !my[:parent].is_a?(Bike::Set::Static::Folder) ?
|
|
64
|
+
"#{my[:parent][:name]}-#{my[:id]}" : my[:id]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def meta_full_name
|
|
68
|
+
my[:parent] ? "#{my[:parent][:full_name]}-#{my[:id]}" : my[:id]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def meta_short_name
|
|
72
|
+
return '' if Bike.base && my[:full_name] == Bike.base[:full_name]
|
|
73
|
+
my[:parent] && Bike.base && my[:parent][:full_name] != Bike.base[:full_name] ?
|
|
74
|
+
"#{my[:parent][:short_name]}-#{my[:id]}" : my[:id]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def meta_folder
|
|
78
|
+
find_ancestor {|f| f.is_a? Bike::Set::Static::Folder }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def meta_sd
|
|
82
|
+
find_ancestor {|f| f.is_a? Bike::Set::Dynamic }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def meta_client
|
|
86
|
+
Bike.client
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def meta_owner
|
|
90
|
+
@meta[:owner] || (my[:parent] ? my[:parent][:owner] : 'root')
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def meta_owners
|
|
94
|
+
(my[:parent] ? my[:parent][:owners] : ['root']) | Array(@meta[:owner])
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def meta_admins
|
|
98
|
+
(my[:parent] ? my[:parent][:admins] : ['root']) | Array(@meta[:admin])
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def meta_group
|
|
102
|
+
@meta[:group] || (my[:parent] ? my[:parent][:group] : [])
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def meta_roles
|
|
106
|
+
roles = 0
|
|
107
|
+
roles |= Bike::Workflow::ROLE_ADMIN if my[:admins].include? my[:client]
|
|
108
|
+
roles |= Bike::Workflow::ROLE_GROUP if my[:group].include? my[:client]
|
|
109
|
+
roles |= Bike::Workflow::ROLE_OWNER if my[:owner] == my[:client]
|
|
110
|
+
roles |= (Bike.client == 'nobody') ? Bike::Workflow::ROLE_NONE : Bike::Workflow::ROLE_USER
|
|
111
|
+
roles
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def permit?(action)
|
|
115
|
+
return false if action == :create && @result == :load
|
|
116
|
+
return true unless my[:sd]
|
|
117
|
+
return true if my[:sd].workflow.permit?(my[:roles], action)
|
|
118
|
+
return true if find_ancestor {|f| f[:id] =~ Bike::REX::ID_NEW } # descendant of a new item
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def default_action
|
|
122
|
+
return :read unless my[:sd]
|
|
123
|
+
actions = my[:sd].workflow.class.const_get(:PERM).keys - [:read, :create, :update]
|
|
124
|
+
([:read, :create, :update] + actions).find {|action| permit? action }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def get(arg = {})
|
|
128
|
+
if permit_get? arg
|
|
129
|
+
_get(arg)
|
|
130
|
+
else
|
|
131
|
+
if arg[:action]
|
|
132
|
+
raise Bike::Error::Forbidden
|
|
133
|
+
else
|
|
134
|
+
arg[:action] = default_action
|
|
135
|
+
end
|
|
136
|
+
arg[:action] ? _get(arg) : 'xxx'
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def load_default
|
|
141
|
+
post :load_default
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def load(v = nil)
|
|
145
|
+
post :load, v
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def create(v = nil)
|
|
149
|
+
post :create, v
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def update(v = nil)
|
|
153
|
+
post :update, v
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def delete
|
|
157
|
+
post :delete
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def post(action, v = nil)
|
|
161
|
+
raise Bike::Error::Forbidden unless permit_post?(action, v)
|
|
162
|
+
|
|
163
|
+
if _post action, val_cast(v)
|
|
164
|
+
@result = (action == :load || action == :load_default) ? action : nil
|
|
165
|
+
@action = (action == :load || action == :load_default) ? nil : action
|
|
166
|
+
else
|
|
167
|
+
@result = nil
|
|
168
|
+
end
|
|
169
|
+
self
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def commit(type = :temp)
|
|
173
|
+
if valid?
|
|
174
|
+
@result = @action
|
|
175
|
+
@action = nil if type == :persistent
|
|
176
|
+
self
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def pending?
|
|
181
|
+
@action ? true : false
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def valid?
|
|
185
|
+
errors.empty?
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def empty?
|
|
189
|
+
val.respond_to?(:empty?) ? val.empty? : (val.to_s == '')
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def errors
|
|
193
|
+
[]
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
private
|
|
197
|
+
|
|
198
|
+
def my
|
|
199
|
+
self
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def _get(arg)
|
|
203
|
+
_get_by_method arg
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def _get_by_method(arg)
|
|
207
|
+
m = "_g_#{arg[:action]}"
|
|
208
|
+
respond_to?(m, true) ? __send__(m, arg) : _g_default(arg)
|
|
209
|
+
end
|
|
210
|
+
alias :_get_by_self_reference :_get_by_method
|
|
211
|
+
|
|
212
|
+
def _g_empty(arg)
|
|
213
|
+
end
|
|
214
|
+
alias :_g_login :_g_empty
|
|
215
|
+
alias :_g_done :_g_empty
|
|
216
|
+
alias :_g_message :_g_empty
|
|
217
|
+
|
|
218
|
+
def _g_default(arg)
|
|
219
|
+
Bike::Field.h val
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def _g_errors(arg)
|
|
223
|
+
<<_html unless _g_valid? arg
|
|
224
|
+
<span class="error_message">#{errors.join "<br/>\n"}</span>
|
|
225
|
+
_html
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def _g_class(arg)
|
|
229
|
+
c = self.class.to_s.sub('Bike::', '').gsub('::', '-').downcase
|
|
230
|
+
_g_valid?(arg) ? c : "#{c} error"
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def _g_valid?(arg)
|
|
234
|
+
valid? || (arg[:action] == :create && !item.pending?)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def _post(action, v)
|
|
238
|
+
case action
|
|
239
|
+
when :load_default
|
|
240
|
+
@val = val_cast(my[:defaults] || my[:default])
|
|
241
|
+
when :load, :create, :update
|
|
242
|
+
@val = v if @val != v
|
|
243
|
+
when :delete
|
|
244
|
+
true
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def permit_get?(arg)
|
|
249
|
+
permit? arg[:action]
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def permit_post?(action, v)
|
|
253
|
+
action == :load || action == :load_default || permit?(action)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def val_cast(v)
|
|
257
|
+
v
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
end
|