equipment 0.1.0 → 1.4.84

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGES +9 -0
  2. data/LICENSE +340 -0
  3. data/README +29 -12
  4. data/Rakefile +157 -0
  5. data/TODO +14 -0
  6. data/doc/structure.dia +0 -0
  7. data/doc/structure.png +0 -0
  8. data/lib/camping_ext.rb +72 -0
  9. data/lib/equipment.rb +39 -116
  10. data/lib/ext.rb +33 -0
  11. data/lib/ext/active_record.rb +146 -0
  12. data/lib/ext/basic_auth.rb +15 -15
  13. data/lib/ext/controls.rb +16 -14
  14. data/lib/ext/flash.rb +35 -17
  15. data/lib/ext/form_helpers.rb +46 -0
  16. data/lib/ext/forward.rb +44 -15
  17. data/lib/ext/js_helpers.rb +66 -19
  18. data/lib/ext/logging.rb +61 -0
  19. data/lib/ext/mount.rb +33 -27
  20. data/lib/ext/negociate_content.rb +90 -0
  21. data/lib/ext/og.rb +18 -10
  22. data/lib/ext/og_scaffold.rb +5 -8
  23. data/lib/ext/resource.rb +127 -0
  24. data/lib/ext/security.rb +66 -31
  25. data/lib/ext/sendfile.rb +3 -4
  26. data/lib/ext/settings.rb +243 -0
  27. data/lib/ext/template_view.rb +9 -37
  28. data/lib/ext/use_helper.rb +6 -10
  29. data/lib/ext/view.rb +98 -0
  30. data/lib/ext/view_slot.rb +60 -0
  31. data/lib/mimetype_ext.rb +12 -0
  32. data/lib/more/typecast.rb +288 -0
  33. data/lib/ruby_ext.rb +126 -0
  34. data/share/js/date_ext.js +234 -0
  35. data/share/js/es-confirm.js +23 -0
  36. data/share/js/event-selector.js +145 -0
  37. data/share/js/jquery.js +1793 -0
  38. data/share/js/prototype.js +2012 -0
  39. metadata +50 -35
  40. data/ProjectInfo +0 -55
  41. data/examples/basicauthtest.rb +0 -59
  42. data/examples/erubytest.rb +0 -36
  43. data/examples/flashtest.rb +0 -46
  44. data/examples/index.erb +0 -9
  45. data/examples/mounttest.rb +0 -34
  46. data/examples/ogtest.rb +0 -41
  47. data/examples/patchestest.rb +0 -40
  48. data/examples/sendfiletest.rb +0 -29
  49. data/lib/ext/forms.rb +0 -22
  50. data/lib/ext/patches.rb +0 -130
  51. data/lib/ext/ressource.rb +0 -88
@@ -0,0 +1,61 @@
1
+ require 'equipment'
2
+ require 'logger'
3
+ require 'ext/app_util'
4
+
5
+ module Ext
6
+ # Adds loggins support to your app.
7
+ #
8
+ # == TODO
9
+ # * More doc
10
+ module Logging
11
+ extend Equipment
12
+ depends_on Ext::AppUtil
13
+
14
+ # restore ActiveSupport's changes
15
+ class Logger < ::Logger
16
+ # restore format_message
17
+ def format_message(severity, datetime, progname, msg)
18
+ (@formatter || @default_formatter).call(severity, datetime, progname, msg)
19
+ end
20
+ end
21
+
22
+ def self.equip(app)
23
+ app.const_set(:C,app) unless app.const_defined?(:C)
24
+ super
25
+ end
26
+
27
+ module Helpers
28
+ # Logger method available for Controllers and View
29
+ def logger
30
+ app.logger
31
+ end
32
+ alias_method :log, :logger
33
+ end
34
+
35
+ module CClassMethods
36
+ # Ext::Settings usage advised :
37
+ #
38
+ # setting :logger, '-' do |val|
39
+ # case val
40
+ # when Logger
41
+ # val
42
+ # when String
43
+ # Logger.new(val == '-' ? STDOUT : val)
44
+ # else
45
+ # raise ArgumentError, "unknown type"
46
+ # end
47
+ # end
48
+ #
49
+
50
+ attr_writer :logger
51
+ def logger
52
+ return @logger if @logger
53
+ @logger = ::Ext::Logging::Logger.new(STDOUT)
54
+ @logger.progname = self.name
55
+ @logger
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+
@@ -1,6 +1,5 @@
1
1
  require 'equipment'
2
2
  require 'ext/sendfile'
3
- require 'ext/patches'
4
3
 
5
4
  module Ext
6
5
  # That equipment allows you to mount whole directories as a camping
@@ -16,7 +15,7 @@ module Ext
16
15
  #
17
16
  # * Equipment
18
17
  # * Sendfile
19
- # * Patches
18
+ # * View
20
19
  # * `mime-types` package
21
20
  #
22
21
  # == Example
@@ -63,9 +62,9 @@ module Ext
63
62
  #
64
63
  module Mount
65
64
  extend Equipment
66
- depends_on Patches
67
65
  depends_on Sendfile
68
66
 
67
+
69
68
  module ControllersClassMethods
70
69
  # Mounts the path given by 'path'
71
70
  #
@@ -88,7 +87,7 @@ module Ext
88
87
  }
89
88
  opts = defaults.merge(opts)
90
89
 
91
- urls = ["#{opts[:url]}(|/.*)"]
90
+ urls = ["#{opts[:url].sub(/\/+$/,'')}(|/.*)"]
92
91
 
93
92
  klass = Class.new() do
94
93
  meta_def(:urls) { urls }
@@ -97,20 +96,33 @@ module Ext
97
96
  end
98
97
  klass.class_eval do
99
98
  def get(file='') # :nodoc:
100
- @path = File.join(self.class.path, file)
101
- if File.directory?(@path) and self.class.listing?
102
- @files = Dir[File.join(@path, '*')].map{|f| File.basename(f)}
103
- if has_view?("#{self.class.name.downcase}_listing")
104
- render("#{self.class.name.downcase}_listing")
99
+ @private_path = File.join(self.class.path, file)
100
+ @rel_path = file
101
+ if File.directory?(@private_path)
102
+ if self.class.listing?
103
+ @public_path = @env.PATH_INFO.sub /\/$/, ''
104
+ @parent_path = @public_path.sub(/[^\/]*$/,'')
105
+ @files = Dir[File.join(@private_path, '*')].map{|f| File.basename(f)}
106
+ class_short = self.class.name.gsub(/^.*::/,'').downcase
107
+
108
+ view_name = "#{class_short}_listing"
109
+ if app::Views.instance_method(view_name)
110
+ render view_name
111
+ else
112
+ render(:mount_listing)
113
+ end
105
114
  else
106
- render(:mount_listing)
115
+ # TODO : Look if that controller exists
116
+ forward(self::Unauthorized)
107
117
  end
108
118
  else
109
- sendfile(@path)
119
+ sendfile(@private_path)
110
120
  end
111
121
  end
112
122
  end
113
- const_set(opts[:name], klass) if opts[:name]
123
+
124
+ const_set(opts[:name], klass)
125
+ self::r << klass # register route
114
126
 
115
127
  if $DBG
116
128
  puts "** mounted #{path}"
@@ -120,18 +132,21 @@ module Ext
120
132
 
121
133
  klass
122
134
  end
123
- alias :M :mount
124
135
  end
125
136
 
126
137
  module Views
127
- # Default dir listing. @files contains all the files.
138
+ # Default dir listing. Available variables :
139
+ # * @files : contains all the file's basenames.
140
+ # * @rel_path : relative path
141
+ # * @public_path : the actual public path
142
+ # * @parent_path : the public parent path
143
+ # * @private_path : the actual private folder path
128
144
  def mount_listing
129
- path_info = @env.PATH_INFO.sub /\/$/, ''
130
- h1 "Dir listing of #{path_info}"
145
+ h1 "Dir listing of #{@public_path}"
131
146
  ul do
132
- li { a '..', :href => path_info.sub(/\w*$/,'') }
147
+ li { a '..', :href => @parent_path } unless @rel_path == ''
133
148
  @files.each do |file|
134
- li { a file, :href => "#{path_info}/#{file}" }
149
+ li { a file, :href => "#{@public_path}/#{file}" }
135
150
  end
136
151
  nil
137
152
  end
@@ -141,12 +156,3 @@ module Ext
141
156
  end
142
157
  end
143
158
 
144
- ### Mime-types extensions
145
-
146
- js_type = MIME::Type.from_hash(
147
- 'Content-Type' => 'text/javascript',
148
- 'Extensions' => ['js']
149
- )
150
-
151
- MIME::Types.add(js_type)
152
-
@@ -0,0 +1,90 @@
1
+ require 'equipment'
2
+ require 'mimetype_ext' # requires that package
3
+
4
+ module Ext
5
+ # Returns an available content-type depending on what the browser wants.
6
+ #
7
+ # == Content-type negiciation stategy
8
+ #
9
+ # * Look for client's ACCEPT
10
+ # * If an extension is specifies, prioritize it's content-type (if available)
11
+ # * ...
12
+ #
13
+ # == Usage
14
+ #
15
+ # == TODO
16
+ #
17
+ # * Docs
18
+ # * Accept, Accept-Language, Accept-Charset et Accept-Encoding
19
+ # * q=0.000 #=> not selected
20
+ module NegociateContent
21
+ extend Equipment
22
+
23
+ # TODO : Set the Content-Type that was selected.
24
+ class ContentSelector
25
+ def initialize(env)
26
+ @accept = prioritize(env.HTTP_ACCEPT || '*/*').inject([]) do |arr, mime|
27
+ arr.push *MIME::Types[mime]
28
+ arr
29
+ end
30
+
31
+ # Prioritize according to the extension
32
+ if data = /\.(.+)$/.match(e['PATH_INFO']) and types = MIME::Types.of(data[1])
33
+ types.each do |type|
34
+ if @accept.include? type
35
+ @accept.delete(type)
36
+ @accept.unshift(type)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ # TODO : Complete this
43
+ def method_missing(m)
44
+ yield
45
+ end
46
+
47
+ private
48
+ def prioritize(str)
49
+ str.split(',').sort do |left, right|
50
+ get_priority(left) <=> get_priority(right)
51
+ end
52
+ end
53
+
54
+ def get_priority(item)
55
+ p item
56
+ if data = /;.*q=([0-9\.]+)$/.match(item)
57
+ p data[1].to_f
58
+ data[1].to_f
59
+ else
60
+ 1.0
61
+ end
62
+ end
63
+ end
64
+
65
+ module Base
66
+ attr_accessor :accept
67
+
68
+ # TODO : Refine this method
69
+ def respond_to
70
+ selector = ContentSelector.new(env)
71
+ data = yield selector
72
+
73
+ unless data
74
+ @status = 406
75
+ @headers['Content-Type'] = 'text/html'
76
+ data = selector.available_content_types
77
+ end
78
+
79
+ data
80
+ end
81
+
82
+ end
83
+
84
+ module CClassMethods
85
+ attr_accessor :default_language, :default_charset,
86
+ :default_encoding, :default_content_type
87
+ end
88
+
89
+ end
90
+ end
@@ -8,13 +8,17 @@ module Ext
8
8
  #
9
9
  # == BUGS
10
10
  #
11
- # Does not work if app.create was defined before inclusion of that module
12
- # and doesn't call `super`.
11
+ # The Camping::Reloader messes up that extension and creates a new OGTABLE
12
+ # table. This is because of how Og works. Needs to be changed.
13
+ #
14
+ # In other news, Og is really buggs so this module will not be
15
+ # developped further.
13
16
  #
14
17
  # == TODO
15
18
  #
16
- # * Change table names
17
- # * Add E as Entity in Models
19
+ # * Fix Og
20
+ # * Maybe change table names
21
+ # * Maybe add E as Entity in Models
18
22
  module Og
19
23
  extend Equipment
20
24
 
@@ -24,9 +28,9 @@ module Ext
24
28
 
25
29
  # Adds Og initialization when you start your app.
26
30
  def create
27
- @og_manager = ::Equipment::Og.setup(self) if self::Models.og
31
+ puts "INFO: Og#create called" if $DBG
32
+ @og_manager = ::Ext::Og.setup(self) if self::Models.og
28
33
  super
29
- rescue NoMethodError, ArgumentError
30
34
  end
31
35
  end
32
36
 
@@ -72,6 +76,8 @@ module Ext
72
76
  class << Og
73
77
  # Returns a manager for you app.
74
78
  def setup(app)
79
+
80
+ ::Og.raise_store_exceptions = $DBG if $DBG
75
81
  ::Og.thread_safe = false
76
82
  unless manager = managers[app.name]
77
83
  manager = ::Og::Manager.new(app::Models.og || {})
@@ -80,10 +86,12 @@ module Ext
80
86
 
81
87
  manager.unmanage_classes # needed ?
82
88
 
83
- app::Models.constants.each do |model|
84
- manager.manage_class(model) if manager.manageable?(model)
85
- end
86
-
89
+ classes = app::Models.constants.reject{|c|c=='Base'}.map{|c|app::Models.const_get(c)}
90
+
91
+ p "Manageable classes: " + classes.inspect if $DBG
92
+
93
+ manager.manage_classes classes #unless classes.empty?
94
+
87
95
  manager
88
96
  end
89
97
 
@@ -1,8 +1,7 @@
1
1
  require 'equipment'
2
2
  require 'ext/flash'
3
3
  require 'ext/og'
4
- require 'ext/ressource'
5
- require 'ext/forms'
4
+ require 'ext/resource'
6
5
 
7
6
  module Ext
8
7
 
@@ -11,10 +10,9 @@ module Ext
11
10
  # == Dependencies
12
11
  #
13
12
  # * Equipment
14
- # * Og
15
- # * Ressources
16
13
  # * Flash
17
- # * FormHelper
14
+ # * Og
15
+ # * Resource
18
16
  #
19
17
  # == TODO
20
18
  #
@@ -23,8 +21,7 @@ module Ext
23
21
  extend Equipment
24
22
  depends_on Flash
25
23
  depends_on Og
26
- depends_on Ressource
27
- depends_on Forms
24
+ depends_on Resource
28
25
 
29
26
  module ControllersClassMethods
30
27
  def scaffold(model, opts={})
@@ -44,7 +41,7 @@ module Ext
44
41
  alias :S :scaffold
45
42
  end
46
43
 
47
- class OgScaffolder < Equipment::Ressource::RestController
44
+ class OgScaffolder < Equipment::Resource::RestController
48
45
  class << self
49
46
  attr_accessor :model
50
47
  end
@@ -0,0 +1,127 @@
1
+ require 'equipment'
2
+ require 'ext/forward'
3
+
4
+ module Ext
5
+ # Unfinished work.
6
+ #
7
+ # I'm currently implementing a Controller that works like rail's
8
+ # ActiveResouce.
9
+ #
10
+ # == Dependencies
11
+ #
12
+ # * Equipment
13
+ # * Forward
14
+ #
15
+ module Resource
16
+ extend Equipment
17
+ depends_on Forward
18
+
19
+ module Controllers
20
+ class Rest
21
+ class << self
22
+ attr_accessor :model, :path
23
+
24
+ def urls
25
+ return [] unless @path
26
+ @__urls ||= [
27
+ "#{path}", "#{path}/(\\d+)", "#{path}/(\\w+)",
28
+ "#{path}/(\\w+)/(\\d+)", "#{path}/(\d+)/(\\w+)"
29
+ ]
30
+ end
31
+
32
+ def inherited(c)
33
+ c.path = "/#{c.name.gsub(/^.*::/,'').downcase}"
34
+ end
35
+
36
+ end
37
+
38
+ # GET method dispatching
39
+ # TODO : Test this method
40
+ def get(action=nil, id=nil)
41
+ # corrections
42
+ if (new_id = action.to_i) > 0
43
+ action = id ? id : 'show'
44
+ id = new_id
45
+ elsif not action
46
+ action = 'index'
47
+ end
48
+
49
+ if respond_to?(action) and not ['create','update','delete'].include?(action)
50
+ if id and method(action).arity > 0
51
+ return send(action, id)
52
+ elsif method(action).arity < 1
53
+ return send(action)
54
+ end
55
+ end
56
+ puts "Action not found" if $DBG
57
+ forward NotFound, 'get', @env.SCRIPT_INFO
58
+ end
59
+
60
+ # POST method dispatching
61
+ # TODO : Update this method
62
+ def post(action=nil, id=nil)
63
+ # corrections
64
+ if (new_id = action.to_i) > 0
65
+ action = id ? id : 'update'
66
+ id = new_id
67
+ elsif not action
68
+ action = 'create'
69
+ end
70
+
71
+ # prefix other actions
72
+ action = '_' + action unless ['create','update','delete'].include?(action)
73
+
74
+ if respond_to?(action)
75
+ if id and method(action).arity > 0
76
+ return send(action, id)
77
+ elsif method(action).arity < 1
78
+ return send(action)
79
+ end
80
+ end
81
+ puts "Action not found" if $DBG
82
+ forward NotFound, 'get', @env.SCRIPT_INFO
83
+ end
84
+
85
+ def put(id); update(id); end
86
+ def delete(id); destroy(id); end
87
+
88
+ ### CRUD operations ###
89
+
90
+ def create # POST
91
+ render name + '_create'
92
+ end
93
+
94
+ def show(id) # GET
95
+ render name + '_show'
96
+ end
97
+
98
+ def update(id) # PUT
99
+ redirect R(self, :show, id)
100
+ end
101
+
102
+ def destroy(id) # DELETE
103
+ redirect R(self, :index)
104
+ end
105
+
106
+ ### Pages ###
107
+
108
+ def index
109
+ render name + '_index'
110
+ end
111
+
112
+ def new
113
+ render name + '_new'
114
+ end
115
+
116
+ def edit
117
+ render name + '_edit'
118
+ end
119
+
120
+ protected
121
+ def path; self.class.path; end
122
+ def name; path.sub(/^\//, '').gsub(/\//,'_'); end
123
+ end
124
+
125
+ end
126
+ end
127
+ end