equipment 0.1.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/ProjectInfo +55 -0
- data/README +67 -0
- data/examples/basicauthtest.rb +59 -0
- data/examples/erubytest.rb +36 -0
- data/examples/flashtest.rb +46 -0
- data/examples/index.erb +9 -0
- data/examples/mounttest.rb +34 -0
- data/examples/ogtest.rb +41 -0
- data/examples/patchestest.rb +40 -0
- data/examples/sendfiletest.rb +29 -0
- data/lib/equipment.rb +195 -0
- data/lib/ext/app_util.rb +28 -0
- data/lib/ext/basic_auth.rb +71 -0
- data/lib/ext/controls.rb +26 -0
- data/lib/ext/eruby_view.rb +83 -0
- data/lib/ext/flash.rb +81 -0
- data/lib/ext/forms.rb +22 -0
- data/lib/ext/forward.rb +70 -0
- data/lib/ext/js_helpers.rb +50 -0
- data/lib/ext/mount.rb +152 -0
- data/lib/ext/og.rb +95 -0
- data/lib/ext/og_scaffold.rb +119 -0
- data/lib/ext/og_session.rb +76 -0
- data/lib/ext/patches.rb +130 -0
- data/lib/ext/ressource.rb +88 -0
- data/lib/ext/security.rb +83 -0
- data/lib/ext/sendfile.rb +84 -0
- data/lib/ext/template_view.rb +72 -0
- data/lib/ext/use_helper.rb +83 -0
- data/lib/ext/xml_view.rb +47 -0
- metadata +78 -0
data/lib/ext/og.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'equipment'
|
2
|
+
require 'og'
|
3
|
+
|
4
|
+
module Ext
|
5
|
+
|
6
|
+
# Add some facilities for using Og in Camping. Stores the manager outside of
|
7
|
+
# the app so that you can reload it without sideeffects.
|
8
|
+
#
|
9
|
+
# == BUGS
|
10
|
+
#
|
11
|
+
# Does not work if app.create was defined before inclusion of that module
|
12
|
+
# and doesn't call `super`.
|
13
|
+
#
|
14
|
+
# == TODO
|
15
|
+
#
|
16
|
+
# * Change table names
|
17
|
+
# * Add E as Entity in Models
|
18
|
+
module Og
|
19
|
+
extend Equipment
|
20
|
+
|
21
|
+
module CClassMethods
|
22
|
+
# Useful for extenal control. Filled by .create.
|
23
|
+
attr_reader :og_manager
|
24
|
+
|
25
|
+
# Adds Og initialization when you start your app.
|
26
|
+
def create
|
27
|
+
@og_manager = ::Equipment::Og.setup(self) if self::Models.og
|
28
|
+
super
|
29
|
+
rescue NoMethodError, ArgumentError
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module ModelsClassMethods
|
34
|
+
# Og setting.
|
35
|
+
#
|
36
|
+
# == Sqlite example
|
37
|
+
#
|
38
|
+
# MyApp::Models.og = { :store => :sqlite }
|
39
|
+
#
|
40
|
+
# == MySQL example
|
41
|
+
#
|
42
|
+
# MyApp::Models.og = {
|
43
|
+
# :store => :mysql,
|
44
|
+
# :name => 'data',
|
45
|
+
# :hostname => 'localhost',
|
46
|
+
# :user => 'root',
|
47
|
+
# :pass => '1234'
|
48
|
+
# }
|
49
|
+
attr_accessor :og
|
50
|
+
end
|
51
|
+
|
52
|
+
module Views
|
53
|
+
|
54
|
+
def _form_for(entity, opts)
|
55
|
+
entity = entity.new if entity.kind_of? Class
|
56
|
+
form({:method=>:post}.merge(opts)) do
|
57
|
+
entity.class.serializable_attributes.each do |prop|
|
58
|
+
unless /^oid$|_oid$/.match prop.to_s
|
59
|
+
label prop.to_s, :for=>prop; br
|
60
|
+
input :type=>:text, :name=>prop, :value=>entity.send(prop); br
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
input :type=>:hidden, :name=>'oid', :value=>entity.oid
|
65
|
+
input :type=>:submit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class << Og
|
73
|
+
# Returns a manager for you app.
|
74
|
+
def setup(app)
|
75
|
+
::Og.thread_safe = false
|
76
|
+
unless manager = managers[app.name]
|
77
|
+
manager = ::Og::Manager.new(app::Models.og || {})
|
78
|
+
managers[app.name] = manager
|
79
|
+
end
|
80
|
+
|
81
|
+
manager.unmanage_classes # needed ?
|
82
|
+
|
83
|
+
app::Models.constants.each do |model|
|
84
|
+
manager.manage_class(model) if manager.manageable?(model)
|
85
|
+
end
|
86
|
+
|
87
|
+
manager
|
88
|
+
end
|
89
|
+
|
90
|
+
def managers
|
91
|
+
@managers ||= {}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'equipment'
|
2
|
+
require 'ext/flash'
|
3
|
+
require 'ext/og'
|
4
|
+
require 'ext/ressource'
|
5
|
+
require 'ext/forms'
|
6
|
+
|
7
|
+
module Ext
|
8
|
+
|
9
|
+
# Allows Og Entities scaffolding. Not working yet.
|
10
|
+
#
|
11
|
+
# == Dependencies
|
12
|
+
#
|
13
|
+
# * Equipment
|
14
|
+
# * Og
|
15
|
+
# * Ressources
|
16
|
+
# * Flash
|
17
|
+
# * FormHelper
|
18
|
+
#
|
19
|
+
# == TODO
|
20
|
+
#
|
21
|
+
# * Not working. Finish this.
|
22
|
+
module OgScaffold
|
23
|
+
extend Equipment
|
24
|
+
depends_on Flash
|
25
|
+
depends_on Og
|
26
|
+
depends_on Ressource
|
27
|
+
depends_on Forms
|
28
|
+
|
29
|
+
module ControllersClassMethods
|
30
|
+
def scaffold(model, opts={})
|
31
|
+
defaults = {
|
32
|
+
:path => "/#{model.downcase}",
|
33
|
+
:name => "#{model}Scaffold"
|
34
|
+
}
|
35
|
+
opts = opts.merge(defaults)
|
36
|
+
|
37
|
+
klass = Class.new(OgScaffolder)
|
38
|
+
klass.path, klass.model = opts[:path], model
|
39
|
+
|
40
|
+
const_set(opts[:name], klass) if opts[:name]
|
41
|
+
|
42
|
+
klass
|
43
|
+
end
|
44
|
+
alias :S :scaffold
|
45
|
+
end
|
46
|
+
|
47
|
+
class OgScaffolder < Equipment::Ressource::RestController
|
48
|
+
class << self
|
49
|
+
attr_accessor :model
|
50
|
+
end
|
51
|
+
|
52
|
+
### CRUD ###
|
53
|
+
def create
|
54
|
+
m = model.new
|
55
|
+
input.fill(m) # TODO : Make this work
|
56
|
+
m.save
|
57
|
+
flash.errors = m.errors
|
58
|
+
redirect R(self, :show, m.oid)
|
59
|
+
end
|
60
|
+
|
61
|
+
def show(oid)
|
62
|
+
@model = model
|
63
|
+
@model_instance = model[oid]
|
64
|
+
render :show
|
65
|
+
end
|
66
|
+
|
67
|
+
def update(oid)
|
68
|
+
m = model[oid]
|
69
|
+
input.fill(m)
|
70
|
+
m.save
|
71
|
+
flash.errors = m.errors
|
72
|
+
redirect R(self, :show, m.oid)
|
73
|
+
end
|
74
|
+
|
75
|
+
def destroy(oid)
|
76
|
+
flash.errors = model.delete(oid)
|
77
|
+
redirect R(self)
|
78
|
+
end
|
79
|
+
|
80
|
+
### Views ###
|
81
|
+
|
82
|
+
def index
|
83
|
+
@model = model
|
84
|
+
render :index
|
85
|
+
end
|
86
|
+
|
87
|
+
def edit(oid)
|
88
|
+
@model = model
|
89
|
+
@model_instance = model[oid]
|
90
|
+
render :edit
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def _model; self.class.model; end
|
95
|
+
def render(view, *a, &b) # look for local redefinition
|
96
|
+
if has_view?("#{self.class.name.downcase}_#{view}")
|
97
|
+
super("#{self.class.name.downcase}_#{view}", *a, &b)
|
98
|
+
else
|
99
|
+
super("og_scaffold_#{view}", *a, &b)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
module Views
|
105
|
+
def og_scaffold_index
|
106
|
+
form_for(@model)
|
107
|
+
end
|
108
|
+
|
109
|
+
def og_scaffold_show
|
110
|
+
print(@model_instance)
|
111
|
+
end
|
112
|
+
|
113
|
+
def og_scaffold_edit
|
114
|
+
form_for(@model, @model_instance)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'equipment'
|
2
|
+
require 'ext/og'
|
3
|
+
require 'glue/timestamped'
|
4
|
+
|
5
|
+
module Ext
|
6
|
+
|
7
|
+
# It's like Camping's Session but works with Og.
|
8
|
+
#
|
9
|
+
# TODO : Not working. Test this.
|
10
|
+
module OgSession
|
11
|
+
include Equipment
|
12
|
+
depends_on Og
|
13
|
+
|
14
|
+
module Models
|
15
|
+
class OgSession
|
16
|
+
attr_accessor :hashid, String
|
17
|
+
attr_accessor :ivars, Hash
|
18
|
+
|
19
|
+
is Glue::Timestamped
|
20
|
+
|
21
|
+
def []=(k, v)
|
22
|
+
self.ivars[k] = v
|
23
|
+
end
|
24
|
+
def [](k)
|
25
|
+
self.ivars[k] rescue nil
|
26
|
+
end
|
27
|
+
|
28
|
+
RAND_CHARS = [*'A'..'Z'] + [*'0'..'9'] + [*'a'..'z']
|
29
|
+
|
30
|
+
# Generates a new session ID and creates a row for the new session in the database.
|
31
|
+
def self.generate cookies
|
32
|
+
rand_max = RAND_CHARS.size
|
33
|
+
sid = (0...32).inject("") { |ret,_| ret << RAND_CHARS[rand(rand_max)] }
|
34
|
+
sess = self.create :hashid => sid, :ivars => Camping::H[]
|
35
|
+
cookies.camping_sid = sess.hashid
|
36
|
+
sess
|
37
|
+
end
|
38
|
+
|
39
|
+
# Gets the existing session based on the <tt>camping_sid</tt> available in cookies.
|
40
|
+
# If none is found, generates a new session.
|
41
|
+
def self.persist cookies
|
42
|
+
if cookies.camping_sid
|
43
|
+
session = self.find_by_hashid cookies.camping_sid
|
44
|
+
end
|
45
|
+
unless session
|
46
|
+
session = self.generate cookies
|
47
|
+
end
|
48
|
+
session
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module Base
|
54
|
+
# This <tt>service</tt> method, when mixed into controllers, intercepts requests
|
55
|
+
# and wraps them with code to start and close the session. If a session isn't found
|
56
|
+
# in the database it is created. The <tt>@state</tt> variable is set and if it changes,
|
57
|
+
# it is saved back into the database.
|
58
|
+
def service(*a)
|
59
|
+
session = OgSession.persist @cookies
|
60
|
+
app = self.class.name.gsub(/^(\w+)::.+$/, '\1')
|
61
|
+
@state = (session[app] ||= Camping::H[])
|
62
|
+
hash_before = Marshal.dump(@state).hash
|
63
|
+
s = super(*a)
|
64
|
+
if session
|
65
|
+
hash_after = Marshal.dump(@state).hash
|
66
|
+
unless hash_before == hash_after
|
67
|
+
session[app] = @state
|
68
|
+
session.save
|
69
|
+
end
|
70
|
+
end
|
71
|
+
s
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
data/lib/ext/patches.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'equipment'
|
2
|
+
require 'ext/app_util'
|
3
|
+
|
4
|
+
module Ext
|
5
|
+
|
6
|
+
# Fixes some Camping defaults.
|
7
|
+
#
|
8
|
+
# == Dependencies
|
9
|
+
#
|
10
|
+
# * Equipment
|
11
|
+
# * AppUtil
|
12
|
+
#
|
13
|
+
module Patches
|
14
|
+
extend Equipment
|
15
|
+
depends_on AppUtil
|
16
|
+
|
17
|
+
# Removes method_missing, it makes things too complicated and debug
|
18
|
+
# unclear.
|
19
|
+
#
|
20
|
+
# Redefines the D method
|
21
|
+
def self.equip(app)
|
22
|
+
super
|
23
|
+
|
24
|
+
=begin
|
25
|
+
# remove method_missing, it makes things too complicated
|
26
|
+
if app::Base.method_defined? :method_missing
|
27
|
+
app::Base.send :undef_method, :method_missing
|
28
|
+
end
|
29
|
+
=end
|
30
|
+
|
31
|
+
=begin # not needed in 1.5
|
32
|
+
app::Controllers.module_eval do
|
33
|
+
# New D method which uses respond_to? instead of kind_of?(R)
|
34
|
+
def self.D(path)
|
35
|
+
puts "REQUEST: #{path}" if $DBG
|
36
|
+
constants.inject(nil) do |d,c|
|
37
|
+
k = const_get(c)
|
38
|
+
k.meta_def(:urls){["/#{c.downcase}"]}unless k.respond_to? :urls
|
39
|
+
d||([k, $~[1..-1]] if k.urls.find { |x| path =~ /^#{x}\/?$/ })
|
40
|
+
end||[self::NotFound, [path]]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
=end
|
44
|
+
|
45
|
+
# app::Controllers::NotFound.send :include, app::C, app::Base, app::Models
|
46
|
+
# app::Controllers::ServerError.send :include, app::C, app::Base, app::Models
|
47
|
+
end
|
48
|
+
module Base
|
49
|
+
|
50
|
+
# = Re-defined render
|
51
|
+
#
|
52
|
+
# The method_missing method is great but it ties the system too much to
|
53
|
+
# markaby. It makes also harder to debunk wrong methods since the call-
|
54
|
+
# stack is longer. Finally, it encourages to put the view in the
|
55
|
+
# controller, which is considered bad in MVC style (that's what ppl say)
|
56
|
+
#
|
57
|
+
# Render is a method that gets the view and puts a layout around it if
|
58
|
+
# found.
|
59
|
+
#
|
60
|
+
# Layout was renamed to _layout because it is a partial. Also partials
|
61
|
+
# don't use the layout feature (so layout doesn't have a layout)
|
62
|
+
def render(m, *a, &b)
|
63
|
+
str = view(m, *a, &b)
|
64
|
+
# allow content-negotiation
|
65
|
+
if m.to_s[0] != ?_ and has_view? :_layout
|
66
|
+
str = view(:_layout) { str }
|
67
|
+
end
|
68
|
+
str
|
69
|
+
end
|
70
|
+
|
71
|
+
# Temporary there until markaview is restored or replaced in
|
72
|
+
# camping-unabridged.
|
73
|
+
def markaview(m,*a,&b)
|
74
|
+
h=markaby
|
75
|
+
h.send m,*a,&b
|
76
|
+
h.to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
# Useful if you want to implement your own view
|
80
|
+
alias :view :markaview
|
81
|
+
|
82
|
+
# Shortcut.
|
83
|
+
#
|
84
|
+
# This is useful if you want to implement your own view lookup
|
85
|
+
# (cf. TemplateView, ErubisView)
|
86
|
+
def has_view?(v)
|
87
|
+
/text\/html|\*\/\*/ =~ (env.HTTP_ACCEPT || '*/*') and
|
88
|
+
app::Views.method_defined? v # this is specific to markaby
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
=begin
|
93
|
+
module Controllers
|
94
|
+
# Changed usage of markaby template after removing method_missing.
|
95
|
+
class NotFound
|
96
|
+
def self.urls; [] end # do not serve urls directly
|
97
|
+
def get(p); r(404, app::Mab.new { h1 "Camping Problem!"; h2 "#{p} not found"}) end
|
98
|
+
end
|
99
|
+
|
100
|
+
class ServerError
|
101
|
+
def self.urls; [] end # do not serve urls directly
|
102
|
+
def get(k,m,e)
|
103
|
+
r(500, app::Mab.new do
|
104
|
+
h1 "Camping Problem!"
|
105
|
+
# if $DBG
|
106
|
+
h2 "#{k}.#{m}"
|
107
|
+
h3 "#{e.class} #{e.message}:"
|
108
|
+
ul { e.backtrace.each { |bt| li bt } }
|
109
|
+
# end
|
110
|
+
end.to_s
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
=end
|
116
|
+
|
117
|
+
=begin
|
118
|
+
module CClassMethods
|
119
|
+
# Does noting. Allows calling super to chain initialization processes
|
120
|
+
# without having to check for NoMethodError.
|
121
|
+
def create
|
122
|
+
super
|
123
|
+
rescue NoMethodError, ArgumentError
|
124
|
+
end
|
125
|
+
end
|
126
|
+
=end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'equipment'
|
2
|
+
|
3
|
+
module Ext
|
4
|
+
# Unfinished work.
|
5
|
+
#
|
6
|
+
# I'm currently implementing a Controller that works like rail's
|
7
|
+
# ActiveRessouce.
|
8
|
+
#
|
9
|
+
# == Dependencies
|
10
|
+
#
|
11
|
+
# * None
|
12
|
+
#
|
13
|
+
module Ressource
|
14
|
+
class RestController
|
15
|
+
class << self
|
16
|
+
attr_accessor :model, :path
|
17
|
+
|
18
|
+
def urls
|
19
|
+
@__urls ||= [
|
20
|
+
# POST GET POST POST
|
21
|
+
"#{path}/(create)", "#{path}/(show)/(\d+)", "#{path}/(update)/(\d+)", "#{path}/(destroy)/(\d+)",
|
22
|
+
"#{path}/(\d+)", "#{path}", # POST,GET,PUT,DELETE : rest methods
|
23
|
+
"#{path};(\w+)", "#{path}/(\d+);(\w+)" # POST,GET : forms
|
24
|
+
]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# GET method dispatching
|
29
|
+
def get(action, id)
|
30
|
+
if action.to_i > 0 #/id , /id;actions
|
31
|
+
id = 'show' unless id
|
32
|
+
send(id, action)
|
33
|
+
elsif id #/show/id
|
34
|
+
show(id)
|
35
|
+
else # ;actions
|
36
|
+
action = 'index' if action.empty?
|
37
|
+
send(action)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# POST method dispatching
|
42
|
+
def post(action, id)
|
43
|
+
if action.to_i > 0
|
44
|
+
id = id ? "_#{id}" : 'update'
|
45
|
+
send(id, action)
|
46
|
+
elsif id
|
47
|
+
send(action, id)
|
48
|
+
elsif action=='create'
|
49
|
+
create
|
50
|
+
else
|
51
|
+
send("_#{action}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def put(id); update(id); end
|
56
|
+
def delete(id); destroy(id); end
|
57
|
+
|
58
|
+
### CRUD operations ###
|
59
|
+
|
60
|
+
def create # POST
|
61
|
+
end
|
62
|
+
|
63
|
+
def show(id) # GET
|
64
|
+
end
|
65
|
+
|
66
|
+
def update(id) # PUT
|
67
|
+
redirect R(self, :show, id)
|
68
|
+
end
|
69
|
+
|
70
|
+
def destroy(id) # DELETE
|
71
|
+
redirect R(self, :index)
|
72
|
+
end
|
73
|
+
|
74
|
+
### Pages ###
|
75
|
+
|
76
|
+
def index
|
77
|
+
end
|
78
|
+
|
79
|
+
def new
|
80
|
+
end
|
81
|
+
|
82
|
+
def edit
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|