mack 0.2.0.1 → 0.3.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/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ ===0.3.0
2
+ * Ticket: #8 Xml Builder Support
3
+ * Ticket: #7 Ability to drive certain content based on 'format'
4
+ * Ticket: #9 Added a global encryption system to make encrypting/decrypting of strings easy to use.
5
+ * gem: builder 2.1.2
6
+ * gem: crypt 1.1.4
7
+
1
8
  ===0.2.0.1
2
9
  * gem: cachetastic 1.4.1
3
10
  * gem: application_configuration 1.2.1
data/bin/mack CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/local/bin/ruby
1
2
  require 'fileutils'
2
3
  require 'optparse'
3
4
  require 'optparse/time'
@@ -0,0 +1,15 @@
1
+ module Kernel
2
+
3
+ # A helper method that calls Mack::Utils::Crypt::Keeper with the specified worker
4
+ # and calls the encrypt method on that worker.
5
+ def _encrypt(value, worker = :default)
6
+ Mack::Utils::Crypt::Keeper.instance.worker(worker).encrypt(value)
7
+ end
8
+
9
+ # A helper method that calls Mack::Utils::Crypt::Keeper with the specified worker
10
+ # and calls the decrypt method on that worker.
11
+ def _decrypt(value, worker = :default)
12
+ Mack::Utils::Crypt::Keeper.instance.worker(worker).decrypt(value)
13
+ end
14
+
15
+ end
@@ -35,4 +35,22 @@ class String
35
35
  Mack::Utils::Inflector.instance.singularize(self)
36
36
  end
37
37
 
38
+ # Maps to Kernel _encrypt
39
+ #
40
+ # Examples:
41
+ # "Hello World".encrypt
42
+ # "Hello World".encrypt(:my_crypt)
43
+ def encrypt(worker = :default)
44
+ _encrypt(self, worker)
45
+ end
46
+
47
+ # Maps to Kernel _decrypt
48
+ #
49
+ # Examples:
50
+ # some_encrypted_string.decrypt
51
+ # some_encrypted_string.decrypt(:my_crypt)
52
+ def decrypt(worker = :default)
53
+ _decrypt(self, worker)
54
+ end
55
+
38
56
  end
@@ -82,7 +82,7 @@ module Mack
82
82
  "mack::use_lint" => true,
83
83
  "mack::show_exceptions" => true,
84
84
  "mack::session_id" => "_mack_session_id",
85
- "mack::rendering_systems" => [:action, :text, :partial, :public, :url],
85
+ "mack::rendering_systems" => [:action, :text, :partial, :public, :url, :xml],
86
86
  "mack::cookie_values" => {
87
87
  "path" => "/"
88
88
  },
@@ -6,6 +6,8 @@ require 'application_configuration'
6
6
  require 'cachetastic'
7
7
  require 'fileutils'
8
8
  require 'log4r'
9
+ require 'crypt/rijndael'
10
+ require 'singleton'
9
11
 
10
12
  # Set up Mack constants, if they haven't already been set up.
11
13
  unless Object.const_defined?("MACK_ENV")
data/lib/mack.rb CHANGED
@@ -119,7 +119,7 @@ module Mack
119
119
  url = route[:redirect_to]
120
120
  options = self.request.all_params
121
121
  options.merge!(route)
122
- options - [:controller, :action, :redirect_to, :method, :status]
122
+ options - [:controller, :action, :redirect_to, :method, :status, :format]
123
123
  url = url_for_pattern(url, options)
124
124
  self.response.status = status
125
125
  self.response[:location] = url
@@ -35,10 +35,15 @@ module Mack
35
35
  raise MethodNotImplemented.new("render")
36
36
  end
37
37
 
38
+ # Maps to the view_binder's param method. See also Mack::ViewBinder params.
39
+ def params(key)
40
+ self.view_binder.params(key)
41
+ end
42
+
38
43
  private
39
44
  # Used to render a file from disk.
40
45
  def render_file(f, options = {})
41
- options = {:is_partial => false, :ext => ".html.erb", :dir => MACK_VIEWS}.merge(options)
46
+ options = {:is_partial => false, :ext => ".#{self.params(:format)}.erb", :dir => MACK_VIEWS}.merge(options)
42
47
  partial = f.to_s
43
48
  parts = partial.split("/")
44
49
  if parts.size == 1
@@ -10,7 +10,7 @@ module Mack
10
10
  rescue Errno::ENOENT => e
11
11
  begin
12
12
  # If the action doesn't exist on disk, try to render it from the public directory:
13
- t = render_file(options[:action], {:dir => MACK_PUBLIC, :ext => ".html", :layout => false}.merge(options))
13
+ t = render_file(options[:action], {:dir => MACK_PUBLIC, :ext => ".#{params(:format)}", :layout => false}.merge(options))
14
14
  # Because it's being served from public don't wrap a layout around it!
15
15
  # self.controller.instance_variable_get("@render_options").merge!({:layout => false})
16
16
  return t
@@ -0,0 +1,24 @@
1
+ module Mack
2
+ module Rendering
3
+ # Used when someone calls render(:xml => "rss_feed")
4
+ class Xml < Base
5
+
6
+ def render
7
+ begin
8
+ # Try to render the action:
9
+ return render_file(options[:xml], options.merge(:format => :xml, :ext => ".xml.erb"))
10
+ rescue Errno::ENOENT => e
11
+ begin
12
+ # If the action doesn't exist on disk, try to render it from the public directory:
13
+ t = render_file(options[:xml], {:dir => MACK_PUBLIC, :ext => ".xml.erb", :layout => false}.merge(options.merge(:format => :xml)))
14
+ return t
15
+ rescue Errno::ENOENT => ex
16
+ end
17
+ # Raise the original exception because something bad has happened!
18
+ raise e
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -223,6 +223,12 @@ module Mack
223
223
  end
224
224
  s = segs.join("/")
225
225
  s = "/" if s.blank?
226
+ if s.match(".:format")
227
+ s.gsub!(/\.:format/, "(\\..+|$)")
228
+ else
229
+ s << "(\\..+|$)"
230
+ end
231
+
226
232
  rx = /^#{s}$/
227
233
  rx
228
234
  end # regex_from_pattern
@@ -249,7 +255,13 @@ module Mack
249
255
  end
250
256
 
251
257
  def options_with_embedded_parameters(uri)
252
- opts = self.options
258
+ opts = {:format => :html}.merge(self.options)
259
+ m = uri.match(/\..+$/)
260
+ if m
261
+ m = m.to_s
262
+ opts[:format]= m[1..m.size].to_sym
263
+ uri.gsub!(/\..+$/, "")
264
+ end
253
265
  split_uri = uri.split("/")
254
266
  self.embedded_parameters.each_with_index do |val, ind|
255
267
  unless val.nil?
data/lib/routing/urls.rb CHANGED
@@ -18,12 +18,20 @@ module Mack
18
18
  def url_for_pattern(url, options = {})
19
19
  u = url.dup
20
20
  unused_params = []
21
+ format = nil
21
22
  options.each_pair do |k, v|
22
- vp = Rack::Utils.escape(v.to_param)
23
- if u.gsub!(":#{k}", vp).nil?
24
- unused_params << "#{Rack::Utils.escape(k)}=#{vp}"
23
+ unless k.to_sym == :format
24
+ vp = Rack::Utils.escape(v.to_param)
25
+ if u.gsub!(":#{k}", vp).nil?
26
+ unused_params << "#{Rack::Utils.escape(k)}=#{vp}"
27
+ end
28
+ else
29
+ format = v
25
30
  end
26
31
  end
32
+ if format
33
+ u << ".#{format}"
34
+ end
27
35
  unless unused_params.empty?
28
36
  u << "?" << unused_params.sort.join("&")
29
37
  end
@@ -31,6 +31,7 @@ module Mack
31
31
  @controller_name = params(:controller)
32
32
  @action_name = params(:action)
33
33
  @cookies = cookies
34
+ @wants_list = []
34
35
  end
35
36
 
36
37
  # Gives access to all the parameters for this request.
@@ -198,6 +199,36 @@ module Mack
198
199
  render(:text => redirect_html(request.path_info, url, options[:status]))
199
200
  end
200
201
 
202
+ # In an action wants will run blocks of code based on the content type that has
203
+ # been requested.
204
+ #
205
+ # Examples:
206
+ # class MyAwesomeController < Mack::Controller::Base
207
+ # def hello
208
+ # wants(:html) do
209
+ # render(:text => "<html>Hello World</html>")
210
+ # end
211
+ # wants(:xml) do
212
+ # render(:text => "<xml><greeting>Hello World</greeting></xml>")
213
+ # end
214
+ # end
215
+ # end
216
+ #
217
+ # If you were to go to: /my_awesome/hello you would get:
218
+ # "<html>Hello World</html>"
219
+ #
220
+ # If you were to go to: /my_awesome/hello.html you would get:
221
+ # "<html>Hello World</html>"
222
+ #
223
+ # If you were to go to: /my_awesome/hello.xml you would get:
224
+ # "<xml><greeting>Hello World</greeting></xml>"
225
+ def wants(header_type, &block)
226
+ header_type = header_type.to_sym
227
+ if header_type == params(:format).to_sym
228
+ yield
229
+ end
230
+ end
231
+
201
232
  # Returns true/false depending on whether the render action has been called yet.
202
233
  def render_performed?
203
234
  @render_performed
@@ -237,7 +268,13 @@ module Mack
237
268
  end
238
269
  else layout
239
270
  # use the layout specified by the layout method
240
- return Mack::ViewBinder.new(self).render(@render_options.merge({:action => "layouts/#{layout}"}))
271
+ begin
272
+ return Mack::ViewBinder.new(self).render(@render_options.merge({:action => "layouts/#{layout}"}))
273
+ rescue Errno::ENOENT => e
274
+ # if the layout doesn't exist, we don't care.
275
+ rescue Exception => e
276
+ raise e
277
+ end
241
278
  end
242
279
  # end
243
280
  @content_for_layout
@@ -28,6 +28,14 @@ module Mack
28
28
  Mack::Utils::Html
29
29
  end
30
30
 
31
+ # A wrapper to Mack::Utils::Html rss method.
32
+ #
33
+ # Example:
34
+ # <%= rss_tag(posts_index_url(:format => :xml)) %>
35
+ def rss_tag(url)
36
+ Mack::Utils::Html.rss(url)
37
+ end
38
+
31
39
  end # HtmlHelpers
32
40
  end # ViewHelpers
33
41
  end # Mack
@@ -1,3 +1,4 @@
1
+ require 'builder'
1
2
  # require 'erubis'
2
3
  # This class is used to do all the view level bindings.
3
4
  # It allows for seperation between the controller and the view levels.
@@ -10,6 +11,8 @@ class Mack::ViewBinder
10
11
  self.controller = cont
11
12
  self.options = {:locals => {}}.merge(opts)
12
13
  transfer_vars(@controller)
14
+ @xml_output = ""
15
+ @xml = Builder::XmlMarkup.new(:target => @xml_output, :indent => 1)
13
16
  end
14
17
 
15
18
  # Returns the binding for this class.
@@ -23,6 +26,15 @@ class Mack::ViewBinder
23
26
  self.options[:locals][sym]
24
27
  end
25
28
 
29
+ # Maps to the controller's param method. See also Mack::Controller::Base params.
30
+ def params(key)
31
+ self.controller.params(key)
32
+ end
33
+
34
+ def xml
35
+ @xml
36
+ end
37
+
26
38
  # Handles rendering calls both in the controller and in the view.
27
39
  # For full details of render examples see Mack::Controller::Base render.
28
40
  # Although the examples there are all in controllers, they idea is still
@@ -62,7 +74,12 @@ class Mack::ViewBinder
62
74
  # and returns a String. The io can be either an IO object or a String.
63
75
  def render(io, controller, options = {})
64
76
  vb = Mack::ViewBinder.new(controller, options)
65
- return ERB.new(io).result(vb.view_binding)
77
+ # TODO: find a nicer way of doing this:
78
+ if ((controller.params(:format).to_sym == :xml) || options[:format] == :xml) && (options[:action] || options[:xml])
79
+ return eval(io, vb.view_binding)
80
+ else
81
+ return ERB.new(io).result(vb.view_binding)
82
+ end
66
83
  # return Erubis::Eruby.new(io).result(vb.view_binding)
67
84
  end
68
85
 
@@ -0,0 +1,28 @@
1
+ module Mack
2
+ module Utils # :nodoc:
3
+ module Crypt # :nodoc:
4
+ # The default worker is one that is used when no other worker is specified or the
5
+ # specified worker does not exist. It uses the Crypt::Rijndael library and get's
6
+ # it's secret key from app_config.default_secret_key
7
+ class DefaultWorker
8
+
9
+ def initialize
10
+ @aes_key = ::Crypt::Rijndael.new(app_config.default_secret_key || (String.randomize(40)))
11
+ end
12
+
13
+ # Encrypts a string using the Crypt::Rijndael library and the secret key found in
14
+ # app_config.default_secret_key
15
+ def encrypt(x)
16
+ @aes_key.encrypt_string(x)
17
+ end
18
+
19
+ # Decrypts a string using the Crypt::Rijndael library and the secret key found in
20
+ # app_config.default_secret_key
21
+ def decrypt(x)
22
+ @aes_key.decrypt_string(x)
23
+ end
24
+
25
+ end # DefaultWorker
26
+ end # Crypt
27
+ end # Utils
28
+ end # Mack
@@ -0,0 +1,46 @@
1
+ module Mack
2
+ module Utils
3
+ module Crypt
4
+ # A singleton class that holds/manages all the workers for the system.
5
+ #
6
+ # A worker must be defined as Mack::Utils::Crypt::<name>Worker and must
7
+ # define an encrypt(value) method and a decrypt(value) method.
8
+ #
9
+ # Example:
10
+ # class Mack::Utils::Crypt::ReverseWorker
11
+ # def encrypt(x)
12
+ # x.reverse
13
+ # end
14
+ #
15
+ # def decrypt(x)
16
+ # x.reverse
17
+ # end
18
+ # end
19
+ class Keeper
20
+ include Singleton
21
+
22
+ def initialize
23
+ @crypt_workers_cache = {}
24
+ end
25
+
26
+ # Returns a worker object to handle the encrytion/decryption.
27
+ # If the specified worker doesn't exist then Mack::Utils::Crypt::DefaultWorker
28
+ # is returned.
29
+ def worker(key = :default)
30
+ worker = @crypt_workers_cache[key.to_sym]
31
+ if worker.nil?
32
+ worker_klass = key.to_s.camelcase + "Worker"
33
+ if Mack::Utils::Crypt.const_defined?(worker_klass)
34
+ worker = "Mack::Utils::Crypt::#{worker_klass}".constantize.new
35
+ else
36
+ worker = Mack::Utils::Crypt::DefaultWorker.new
37
+ end
38
+ @crypt_workers_cache[key.to_sym] = worker
39
+ end
40
+ worker
41
+ end
42
+
43
+ end # Keeper
44
+ end # Crypt
45
+ end # Utils
46
+ end # Mack
data/lib/utils/html.rb CHANGED
@@ -46,6 +46,14 @@ module Mack
46
46
 
47
47
  alias_method :a, :href
48
48
 
49
+ # A wrapper to generate an auto discovery tag so browsers no the page contains an RSS feed.
50
+ #
51
+ # Example:
52
+ # <%= Mack::Utils::Html.rss(posts_index_url(:format => :xml)) %>
53
+ def rss(url)
54
+ "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS\" href=\"#{url}\">"
55
+ end
56
+
49
57
  # Wraps the content_tag method.
50
58
  #
51
59
  # Examples:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - markbates
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-03-14 00:00:00 -04:00
12
+ date: 2008-03-19 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -66,6 +66,24 @@ dependencies:
66
66
  - !ruby/object:Gem::Version
67
67
  version: 0.7.0
68
68
  version:
69
+ - !ruby/object:Gem::Dependency
70
+ name: builder
71
+ version_requirement:
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "="
75
+ - !ruby/object:Gem::Version
76
+ version: 2.1.2
77
+ version:
78
+ - !ruby/object:Gem::Dependency
79
+ name: crypt
80
+ version_requirement:
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "="
84
+ - !ruby/object:Gem::Version
85
+ version: 1.1.4
86
+ version:
69
87
  description: "mack was developed by: markbates"
70
88
  email: mark@mackframework.com
71
89
  executables:
@@ -94,6 +112,7 @@ files:
94
112
  - bin/templates/public/stylesheets/scaffold.css.template
95
113
  - bin/templates/Rakefile.template
96
114
  - lib/core_extensions/hash.rb
115
+ - lib/core_extensions/kernel.rb
97
116
  - lib/core_extensions/module.rb
98
117
  - lib/core_extensions/nil.rb
99
118
  - lib/core_extensions/object.rb
@@ -128,6 +147,7 @@ files:
128
147
  - lib/rendering/classes/public.rb
129
148
  - lib/rendering/classes/text.rb
130
149
  - lib/rendering/classes/url.rb
150
+ - lib/rendering/classes/xml.rb
131
151
  - lib/routing/route_map.rb
132
152
  - lib/routing/urls.rb
133
153
  - lib/sea_level/controller_base.rb
@@ -148,6 +168,8 @@ files:
148
168
  - lib/tasks/test_tasks.rake
149
169
  - lib/test_extensions/test_assertions.rb
150
170
  - lib/test_extensions/test_helpers.rb
171
+ - lib/utils/crypt/default_worker.rb
172
+ - lib/utils/crypt/keeper.rb
151
173
  - lib/utils/html.rb
152
174
  - lib/utils/inflections.rb
153
175
  - lib/utils/inflector.rb