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

Sign up to get free protection for your applications and to get access to all the features.
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