happy 0.1.0.pre.1 → 0.1.0.pre.2

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/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1 @@
1
+ --no-private --protected --embed-mixins lib/**/*.rb - README LEGAL
data/Rakefile CHANGED
@@ -1,2 +1,7 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+
4
+ # integrate rspec
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new('spec')
7
+ task :default => :spec
@@ -19,4 +19,9 @@ Gem::Specification.new do |gem|
19
19
  gem.add_dependency 'rack', '~> 1.4'
20
20
  gem.add_dependency 'happy-helpers' # TODO: , '~> 0.1.0'
21
21
  gem.add_dependency 'allowance', '>= 0.1.1'
22
+
23
+ gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'rspec', '~> 2.8'
25
+ gem.add_development_dependency 'rspec-html-matchers'
26
+ gem.add_development_dependency 'rack-test'
22
27
  end
@@ -2,11 +2,12 @@ require 'active_support/all' # SMELL
2
2
 
3
3
  require 'happy/context'
4
4
  require 'happy/controller'
5
- require 'happy/static'
6
5
 
7
6
  module Happy
8
- class HappyError < StandardError ; end
9
- class NotFoundError < HappyError ; end
7
+ module Errors
8
+ class Base < StandardError ; end
9
+ class NotFound < Base ; end
10
+ end
10
11
 
11
12
  def self.env
12
13
  ActiveSupport::StringInquirer.new(ENV['RACK_ENV'] || 'development')
@@ -1,9 +1,9 @@
1
1
  require 'happy/request'
2
- require 'happy/helpers'
2
+ require 'happy/context_ext/helpers'
3
3
 
4
4
  module Happy
5
5
  class Context
6
- include Helpers
6
+ include ContextExtensions::Helpers
7
7
 
8
8
  attr_reader :request, :response, :remaining_path
9
9
  attr_accessor :layout, :controller
@@ -0,0 +1,39 @@
1
+ require 'happy-helpers'
2
+
3
+ module Happy
4
+ module ContextExtensions
5
+ module Helpers
6
+ include HappyHelpers::Helpers
7
+
8
+ def render(what, options = {}, &blk)
9
+ case what
10
+ when String then render_template(what, options, &blk)
11
+ when Enumerable then what.map { |i| render(i, options, &blk) }.join
12
+ else render_resource(what, options)
13
+ end
14
+ end
15
+
16
+ def render_template(name, variables = {}, &blk)
17
+ HappyHelpers::Templates.render(name, self, variables, &blk)
18
+ end
19
+
20
+ def render_resource(resource, options = {})
21
+ # build name strings
22
+ singular_name = resource.class.to_s.tableize.singularize
23
+ plural_name = singular_name.pluralize
24
+
25
+ # set options
26
+ options = {
27
+ singular_name => resource
28
+ }.merge(options)
29
+
30
+ # render
31
+ render_template("#{plural_name}/_#{singular_name}.html.haml", options)
32
+ end
33
+
34
+ alias_method :h, :escape_html
35
+ alias_method :l, :localize
36
+ alias_method :t, :translate
37
+ end
38
+ end
39
+ end
@@ -1,12 +1,12 @@
1
- require 'happy/routing'
2
- require 'happy/actions'
3
- require 'happy/rackable'
1
+ require 'happy/controller_ext/routing'
2
+ require 'happy/controller_ext/actions'
3
+ require 'happy/controller_ext/rackable'
4
4
 
5
5
  module Happy
6
6
  class Controller
7
- include Routing
8
- include Actions
9
- include Rackable
7
+ include ControllerExtensions::Routing
8
+ include ControllerExtensions::Actions
9
+ include ControllerExtensions::Rackable
10
10
 
11
11
  attr_reader :options, :env
12
12
 
@@ -0,0 +1,80 @@
1
+ module Happy
2
+ module ControllerExtensions
3
+ module Actions
4
+ def serve!(data, options = {})
5
+ # Don't serve if there are still bits of path remaining.
6
+ return unless remaining_path.empty?
7
+
8
+ # Don't serve is data is not a string.
9
+ return unless data.is_a?(String)
10
+
11
+ # Mix in default options
12
+ options = {
13
+ layout: context.layout
14
+ }.merge(options)
15
+
16
+ # Add optional headers et al
17
+ response.status = options[:status] if options.has_key?(:status)
18
+ response['Content-type'] = options[:content_type] if options.has_key?(:content_type)
19
+
20
+ # Apply layout, if available
21
+ if options[:layout]
22
+ data = render(options[:layout]) { data }
23
+ end
24
+
25
+ # Set response body and finish request
26
+ response.body = [data]
27
+ halt!
28
+ end
29
+
30
+ def halt!(message = :done)
31
+ throw message
32
+ end
33
+
34
+ def redirect!(to, status = 302)
35
+ header "Location", url_for(to)
36
+ response.status = status
37
+ halt!
38
+ end
39
+
40
+ def layout(name)
41
+ context.layout = name
42
+ end
43
+
44
+ def content_type(type)
45
+ header 'Content-type', type
46
+ end
47
+
48
+ def max_age(t, options = {})
49
+ options = {
50
+ :public => true,
51
+ :must_revalidate => true
52
+ }.merge(options)
53
+
54
+ s = []
55
+ s << 'public' if options[:public]
56
+ s << 'must-revalidate' if options[:must_revalidate]
57
+ s << "max-age=#{t.to_i}"
58
+
59
+ cache_control s.join(', ')
60
+ end
61
+
62
+ def cache_control(s)
63
+ header 'Cache-control', s
64
+ end
65
+
66
+ def header(name, value)
67
+ response[name] = value
68
+ end
69
+
70
+ def invoke(klass, options = {}, &blk)
71
+ klass.new(env, options, &blk).perform
72
+ end
73
+
74
+ def run(app)
75
+ context.response = app.call(request.env)
76
+ halt!
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,26 @@
1
+ module Happy
2
+ module ControllerExtensions
3
+ module Rackable
4
+ extend ActiveSupport::Concern
5
+
6
+ def call(env)
7
+ @env = env
8
+
9
+ catch :done do
10
+ serve! perform
11
+
12
+ # If we get here, #serve decided not to serve.
13
+ raise Errors::NotFound
14
+ end
15
+
16
+ response
17
+ end
18
+
19
+ module ClassMethods
20
+ def call(env)
21
+ new.call(env)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,58 @@
1
+ module Happy
2
+ module ControllerExtensions
3
+ module Routing
4
+ def path_to_regexp(path)
5
+ path = ":#{path}" if path.is_a?(Symbol)
6
+ Regexp.compile('^'+path.gsub(/\)/, ')?').gsub(/\//, '\/').gsub(/\./, '\.').gsub(/:(\w+)/, '(?<\\1>.+)')+'$')
7
+ end
8
+
9
+ def path(*args, &blk)
10
+ options = (args.pop if args.last.is_a?(Hash)) || {}
11
+ args = [nil] if args.empty?
12
+
13
+ args.each do |name|
14
+ if name.present?
15
+ path_match = path_to_regexp(name).match(remaining_path.first)
16
+ end
17
+
18
+ method_matched = [nil, request.request_method.downcase.to_sym].include?(options[:method])
19
+ path_matched = (path_match || (name.nil? && remaining_path.empty?))
20
+
21
+ # Only do something here if method and requested path both match
22
+ if path_matched && method_matched
23
+ # Transfer variables contained in path name to params hash
24
+ if path_match
25
+ path_match.names.each { |k| request.params[k] = path_match[k] }
26
+ remaining_path.shift
27
+ end
28
+
29
+ serve! instance_exec(&blk)
30
+
31
+ # If we get here, #serve decided not to serve.
32
+ raise Errors::NotFound
33
+ end
34
+ end
35
+ end
36
+
37
+ def get(*args, &blk)
38
+ args.last.is_a?(Hash) ? args.last.merge(method: :get) : args.push(method: :get)
39
+ path(*args, &blk)
40
+ end
41
+
42
+ def post(*args, &blk)
43
+ args.last.is_a?(Hash) ? args.last.merge(method: :post) : args.push(method: :post)
44
+ path(*args, &blk)
45
+ end
46
+
47
+ def put(*args, &blk)
48
+ args.last.is_a?(Hash) ? args.last.merge(method: :put) : args.push(method: :put)
49
+ path(*args, &blk)
50
+ end
51
+
52
+ def delete(*args, &blk)
53
+ args.last.is_a?(Hash) ? args.last.merge(method: :delete) : args.push(method: :delete)
54
+ path(*args, &blk)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ require 'allowance'
2
+
3
+ module Happy
4
+ module Extensions
5
+ module Permissions
6
+ module ContextExtensions
7
+ extend ActiveSupport::Concern
8
+
9
+ def permissions(&blk)
10
+ @permissions ||= Allowance.define
11
+ end
12
+
13
+ def can?(*args)
14
+ permissions.allowed?(*args)
15
+ end
16
+ end
17
+
18
+ module ControllerExtensions
19
+ extend ActiveSupport::Concern
20
+
21
+ included do
22
+ delegate :can?, :to => :context
23
+ end
24
+
25
+ module ClassMethods
26
+ attr_accessor :permissions_blk
27
+
28
+ def permissions(&blk)
29
+ self.permissions_blk = blk
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ Happy::Context.send(:include, Happy::Extensions::Permissions::ContextExtensions)
38
+ Happy::Controller.send(:include, Happy::Extensions::Permissions::ControllerExtensions)
@@ -0,0 +1,116 @@
1
+ require 'happy/ext/permissions'
2
+
3
+ module Happy
4
+ module Extensions
5
+ module Resources
6
+ module ControllerExtensions
7
+ def resource(klass, options = {}, &blk)
8
+ invoke ResourceMounter, options.merge(:class => klass), &blk
9
+ end
10
+ end
11
+
12
+ class ResourceMounter < Happy::Controller
13
+ def render_resource_template(name)
14
+ render "#{options[:plural_name]}/#{name}.html.haml"
15
+ end
16
+
17
+ def resource
18
+ options[:class]
19
+ end
20
+
21
+ def resource_with_permission_scope(*args)
22
+ context.permissions.scoped_model(*args, options[:class])
23
+ end
24
+
25
+ def require_permission!(*args)
26
+ raise "not allowed" unless can?(*args, options[:class])
27
+ end
28
+
29
+ def set_plural_variable(v)
30
+ context.instance_variable_set "@#{options[:plural_name]}", v
31
+ end
32
+
33
+ def plural_variable
34
+ context.instance_variable_get "@#{options[:plural_name]}"
35
+ end
36
+
37
+ def set_singular_variable(v)
38
+ context.instance_variable_set "@#{options[:singular_name]}", v
39
+ end
40
+
41
+ def singular_variable
42
+ context.instance_variable_get "@#{options[:singular_name]}"
43
+ end
44
+
45
+ def do_index
46
+ require_permission! :index
47
+ set_plural_variable resource_with_permission_scope(:index).all
48
+ render_resource_template 'index'
49
+ end
50
+
51
+ def do_show
52
+ require_permission! :show
53
+ set_singular_variable resource_with_permission_scope(:show).find(params['id'])
54
+ render_resource_template 'show'
55
+ end
56
+
57
+ def do_new
58
+ require_permission! :new
59
+ set_singular_variable resource_with_permission_scope(:new).new(params[options[:singular_name]], :as => options[:role])
60
+ render_resource_template 'new'
61
+ end
62
+
63
+ def do_create
64
+ require_permission! :create
65
+ set_singular_variable resource_with_permission_scope(:create).new(params[options[:singular_name]], :as => options[:role])
66
+
67
+ if singular_variable.save
68
+ redirect! singular_variable
69
+ else
70
+ render_resource_template 'new'
71
+ end
72
+ end
73
+
74
+ def do_edit
75
+ require_permission! :edit
76
+ set_singular_variable resource_with_permission_scope(:edit).find(params['id'])
77
+ render_resource_template 'edit'
78
+ end
79
+
80
+ def do_update
81
+ require_permission! :update
82
+ set_singular_variable resource_with_permission_scope(:update).find(params['id'])
83
+ singular_variable.assign_attributes params[options[:singular_name]], :as => options[:role]
84
+
85
+ if singular_variable.save
86
+ redirect! singular_variable
87
+ else
88
+ render_resource_template 'edit'
89
+ end
90
+ end
91
+
92
+ def route
93
+ @options = {
94
+ singular_name: options[:class].to_s.tableize.singularize,
95
+ plural_name: options[:class].to_s.tableize.pluralize
96
+ }.merge(@options)
97
+
98
+ path options[:plural_name] do
99
+ get('new') { do_new }
100
+
101
+ path :id do
102
+ get { do_show }
103
+ post { do_update }
104
+ get('edit') { do_edit }
105
+ end
106
+
107
+ post { do_create }
108
+ get { do_index }
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ Happy::Controller.send(:include, Happy::Extensions::Resources::ControllerExtensions)
@@ -0,0 +1,9 @@
1
+ module Happy
2
+ module Extensions
3
+ class Static < Happy::Controller
4
+ def route
5
+ run Rack::File.new(options[:path])
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module Happy
2
- VERSION = "0.1.0.pre.1"
2
+ VERSION = "0.1.0.pre.2"
3
3
  end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module Happy
4
+ describe Controller do
5
+ it "should have more specs"
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ SPEC_DIR = File.dirname(__FILE__)
2
+ lib_path = File.expand_path("#{SPEC_DIR}/../lib")
3
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
4
+
5
+ require 'rubygems'
6
+ require 'bundler/setup'
7
+ require 'rack/test'
8
+
9
+ require 'happy'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: happy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.1
4
+ version: 0.1.0.pre.2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70164769147200 !ruby/object:Gem::Requirement
16
+ requirement: &70265405180720 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70164769147200
24
+ version_requirements: *70265405180720
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rack
27
- requirement: &70164769146300 !ruby/object:Gem::Requirement
27
+ requirement: &70265405180020 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '1.4'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70164769146300
35
+ version_requirements: *70265405180020
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: happy-helpers
38
- requirement: &70164769145860 !ruby/object:Gem::Requirement
38
+ requirement: &70265405178080 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70164769145860
46
+ version_requirements: *70265405178080
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: allowance
49
- requirement: &70164769145220 !ruby/object:Gem::Requirement
49
+ requirement: &70265405175720 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,51 @@ dependencies:
54
54
  version: 0.1.1
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70164769145220
57
+ version_requirements: *70265405175720
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &70265405174800 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70265405174800
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: &70265405173920 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: '2.8'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70265405173920
80
+ - !ruby/object:Gem::Dependency
81
+ name: rspec-html-matchers
82
+ requirement: &70265405172780 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70265405172780
91
+ - !ruby/object:Gem::Dependency
92
+ name: rack-test
93
+ requirement: &70265405170780 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70265405170780
58
102
  description: A happy little toolkit for writing web applications.
59
103
  email:
60
104
  - hendrik@mans.de
@@ -63,23 +107,27 @@ extensions: []
63
107
  extra_rdoc_files: []
64
108
  files:
65
109
  - .gitignore
110
+ - .rspec
111
+ - .yardopt
66
112
  - Gemfile
67
113
  - LICENSE
68
114
  - README.md
69
115
  - Rakefile
70
116
  - happy.gemspec
71
117
  - lib/happy.rb
72
- - lib/happy/actions.rb
73
118
  - lib/happy/context.rb
119
+ - lib/happy/context_ext/helpers.rb
74
120
  - lib/happy/controller.rb
75
- - lib/happy/helpers.rb
76
- - lib/happy/permissions.rb
77
- - lib/happy/rackable.rb
121
+ - lib/happy/controller_ext/actions.rb
122
+ - lib/happy/controller_ext/rackable.rb
123
+ - lib/happy/controller_ext/routing.rb
124
+ - lib/happy/ext/permissions.rb
125
+ - lib/happy/ext/resources.rb
126
+ - lib/happy/ext/static.rb
78
127
  - lib/happy/request.rb
79
- - lib/happy/resources.rb
80
- - lib/happy/routing.rb
81
- - lib/happy/static.rb
82
128
  - lib/happy/version.rb
129
+ - spec/controller_spec.rb
130
+ - spec/spec_helper.rb
83
131
  homepage: https://github.com/hmans/happy
84
132
  licenses: []
85
133
  post_install_message:
@@ -104,5 +152,7 @@ rubygems_version: 1.8.11
104
152
  signing_key:
105
153
  specification_version: 3
106
154
  summary: A happy little toolkit for writing web applications.
107
- test_files: []
155
+ test_files:
156
+ - spec/controller_spec.rb
157
+ - spec/spec_helper.rb
108
158
  has_rdoc:
@@ -1,78 +0,0 @@
1
- module Happy
2
- module Actions
3
- def serve!(data, options = {})
4
- # Don't serve if there are still bits of path remaining.
5
- return unless remaining_path.empty?
6
-
7
- # Don't serve is data is not a string.
8
- return unless data.is_a?(String)
9
-
10
- # Mix in default options
11
- options = {
12
- layout: context.layout
13
- }.merge(options)
14
-
15
- # Add optional headers et al
16
- response.status = options[:status] if options.has_key?(:status)
17
- response['Content-type'] = options[:content_type] if options.has_key?(:content_type)
18
-
19
- # Apply layout, if available
20
- if options[:layout]
21
- data = render(options[:layout]) { data }
22
- end
23
-
24
- # Set response body and finish request
25
- response.body = [data]
26
- halt!
27
- end
28
-
29
- def halt!(message = :done)
30
- throw message
31
- end
32
-
33
- def redirect!(to, status = 302)
34
- header "Location", url_for(to)
35
- response.status = status
36
- halt!
37
- end
38
-
39
- def layout(name)
40
- context.layout = name
41
- end
42
-
43
- def content_type(type)
44
- header 'Content-type', type
45
- end
46
-
47
- def max_age(t, options = {})
48
- options = {
49
- :public => true,
50
- :must_revalidate => true
51
- }.merge(options)
52
-
53
- s = []
54
- s << 'public' if options[:public]
55
- s << 'must-revalidate' if options[:must_revalidate]
56
- s << "max-age=#{t.to_i}"
57
-
58
- cache_control s.join(', ')
59
- end
60
-
61
- def cache_control(s)
62
- header 'Cache-control', s
63
- end
64
-
65
- def header(name, value)
66
- response[name] = value
67
- end
68
-
69
- def invoke(klass, options = {}, &blk)
70
- klass.new(env, options, &blk).perform
71
- end
72
-
73
- def run(app)
74
- context.response = app.call(request.env)
75
- halt!
76
- end
77
- end
78
- end
@@ -1,37 +0,0 @@
1
- require 'happy-helpers'
2
-
3
- module Happy
4
- module Helpers
5
- include HappyHelpers::Helpers
6
-
7
- def render(what, options = {}, &blk)
8
- case what
9
- when String then render_template(what, options, &blk)
10
- when Enumerable then what.map { |i| render(i, options, &blk) }.join
11
- else render_resource(what, options)
12
- end
13
- end
14
-
15
- def render_template(name, variables = {}, &blk)
16
- HappyHelpers::Templates.render(name, self, variables, &blk)
17
- end
18
-
19
- def render_resource(resource, options = {})
20
- # build name strings
21
- singular_name = resource.class.to_s.tableize.singularize
22
- plural_name = singular_name.pluralize
23
-
24
- # set options
25
- options = {
26
- singular_name => resource
27
- }.merge(options)
28
-
29
- # render
30
- render_template("#{plural_name}/_#{singular_name}.html.haml", options)
31
- end
32
-
33
- alias_method :h, :escape_html
34
- alias_method :l, :localize
35
- alias_method :t, :translate
36
- end
37
- end
@@ -1,34 +0,0 @@
1
- module Happy
2
- module Permissions
3
- module ContextExtensions
4
- extend ActiveSupport::Concern
5
-
6
- def permissions(&blk)
7
- @permissions ||= Allowance.define
8
- end
9
-
10
- def can?(*args)
11
- permissions.allowed?(*args)
12
- end
13
- end
14
-
15
- module ControllerExtensions
16
- extend ActiveSupport::Concern
17
-
18
- included do
19
- delegate :can?, :to => :context
20
- end
21
-
22
- module ClassMethods
23
- attr_accessor :permissions_blk
24
-
25
- def permissions(&blk)
26
- self.permissions_blk = blk
27
- end
28
- end
29
- end
30
- end
31
- end
32
-
33
- Happy::Context.send(:include, Happy::Permissions::ContextExtensions)
34
- Happy::Controller.send(:include, Happy::Permissions::ControllerExtensions)
@@ -1,24 +0,0 @@
1
- module Happy
2
- module Rackable
3
- extend ActiveSupport::Concern
4
-
5
- def call(env)
6
- @env = env
7
-
8
- catch :done do
9
- serve! perform
10
-
11
- # If we get here, #serve decided not to serve.
12
- raise NotFoundError
13
- end
14
-
15
- response
16
- end
17
-
18
- module ClassMethods
19
- def call(env)
20
- new.call(env)
21
- end
22
- end
23
- end
24
- end
@@ -1,112 +0,0 @@
1
- module Happy
2
- module Resources
3
- module ControllerExtensions
4
- def resource(klass, options = {}, &blk)
5
- invoke Happy::Resources::ResourceMounter, options.merge(:class => klass), &blk
6
- end
7
- end
8
-
9
- class ResourceMounter < Happy::Controller
10
- def render_resource_template(name)
11
- render "#{options[:plural_name]}/#{name}.html.haml"
12
- end
13
-
14
- def resource
15
- options[:class]
16
- end
17
-
18
- def resource_with_permission_scope(*args)
19
- context.permissions.scoped_model(*args, options[:class])
20
- end
21
-
22
- def require_permission!(*args)
23
- raise "not allowed" unless can?(*args, options[:class])
24
- end
25
-
26
- def set_plural_variable(v)
27
- context.instance_variable_set "@#{options[:plural_name]}", v
28
- end
29
-
30
- def plural_variable
31
- context.instance_variable_get "@#{options[:plural_name]}"
32
- end
33
-
34
- def set_singular_variable(v)
35
- context.instance_variable_set "@#{options[:singular_name]}", v
36
- end
37
-
38
- def singular_variable
39
- context.instance_variable_get "@#{options[:singular_name]}"
40
- end
41
-
42
- def do_index
43
- require_permission! :index
44
- set_plural_variable resource_with_permission_scope(:index).all
45
- render_resource_template 'index'
46
- end
47
-
48
- def do_show
49
- require_permission! :show
50
- set_singular_variable resource_with_permission_scope(:show).find(params['id'])
51
- render_resource_template 'show'
52
- end
53
-
54
- def do_new
55
- require_permission! :new
56
- set_singular_variable resource_with_permission_scope(:new).new(params[options[:singular_name]], :as => options[:role])
57
- render_resource_template 'new'
58
- end
59
-
60
- def do_create
61
- require_permission! :create
62
- set_singular_variable resource_with_permission_scope(:create).new(params[options[:singular_name]], :as => options[:role])
63
-
64
- if singular_variable.save
65
- redirect! singular_variable
66
- else
67
- render_resource_template 'new'
68
- end
69
- end
70
-
71
- def do_edit
72
- require_permission! :edit
73
- set_singular_variable resource_with_permission_scope(:edit).find(params['id'])
74
- render_resource_template 'edit'
75
- end
76
-
77
- def do_update
78
- require_permission! :update
79
- set_singular_variable resource_with_permission_scope(:update).find(params['id'])
80
- singular_variable.assign_attributes params[options[:singular_name]], :as => options[:role]
81
-
82
- if singular_variable.save
83
- redirect! singular_variable
84
- else
85
- render_resource_template 'edit'
86
- end
87
- end
88
-
89
- def route
90
- @options = {
91
- singular_name: options[:class].to_s.tableize.singularize,
92
- plural_name: options[:class].to_s.tableize.pluralize
93
- }.merge(@options)
94
-
95
- path options[:plural_name] do
96
- get('new') { do_new }
97
-
98
- path :id do
99
- get { do_show }
100
- post { do_update }
101
- get('edit') { do_edit }
102
- end
103
-
104
- post { do_create }
105
- get { do_index }
106
- end
107
- end
108
- end
109
- end
110
- end
111
-
112
- Happy::Controller.send(:include, Happy::Resources::ControllerExtensions)
@@ -1,56 +0,0 @@
1
- module Happy
2
- module Routing
3
- def path_to_regexp(path)
4
- path = ":#{path}" if path.is_a?(Symbol)
5
- Regexp.compile('^'+path.gsub(/\)/, ')?').gsub(/\//, '\/').gsub(/\./, '\.').gsub(/:(\w+)/, '(?<\\1>.+)')+'$')
6
- end
7
-
8
- def path(*args, &blk)
9
- options = (args.pop if args.last.is_a?(Hash)) || {}
10
- args = [nil] if args.empty?
11
-
12
- args.each do |name|
13
- if name.present?
14
- path_match = path_to_regexp(name).match(remaining_path.first)
15
- end
16
-
17
- method_matched = [nil, request.request_method.downcase.to_sym].include?(options[:method])
18
- path_matched = (path_match || (name.nil? && remaining_path.empty?))
19
-
20
- # Only do something here if method and requested path both match
21
- if path_matched && method_matched
22
- # Transfer variables contained in path name to params hash
23
- if path_match
24
- path_match.names.each { |k| request.params[k] = path_match[k] }
25
- remaining_path.shift
26
- end
27
-
28
- serve! instance_exec(&blk)
29
-
30
- # If we get here, #serve decided not to serve.
31
- raise NotFoundError
32
- end
33
- end
34
- end
35
-
36
- def get(*args, &blk)
37
- args.last.is_a?(Hash) ? args.last.merge(method: :get) : args.push(method: :get)
38
- path(*args, &blk)
39
- end
40
-
41
- def post(*args, &blk)
42
- args.last.is_a?(Hash) ? args.last.merge(method: :post) : args.push(method: :post)
43
- path(*args, &blk)
44
- end
45
-
46
- def put(*args, &blk)
47
- args.last.is_a?(Hash) ? args.last.merge(method: :put) : args.push(method: :put)
48
- path(*args, &blk)
49
- end
50
-
51
- def delete(*args, &blk)
52
- args.last.is_a?(Hash) ? args.last.merge(method: :delete) : args.push(method: :delete)
53
- path(*args, &blk)
54
- end
55
- end
56
- end
@@ -1,7 +0,0 @@
1
- module Happy
2
- class Static < Happy::Controller
3
- def route
4
- run Rack::File.new(options[:path])
5
- end
6
- end
7
- end