sinatra-rabbit 0.0.2 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,123 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one or more
3
+ # contributor license agreements. See the NOTICE file distributed with
4
+ # this work for additional information regarding copyright ownership. The
5
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance with the
7
+ # License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations
15
+ # under the License.
16
+
17
+ require 'sinatra/rabbit/dsl'
18
+ require 'sinatra/rabbit/param'
19
+ require 'sinatra/rabbit/base_collection'
20
+ require 'sinatra/rabbit/validator'
21
+
22
+ module Sinatra
23
+ module Rabbit
24
+
25
+ STANDARD_OPERATIONS = {
26
+ :create => { :member => false, :method => :post, :collection => true },
27
+ :show => { :member => false, :method => :get },
28
+ :destroy => { :member => false, :method => :delete },
29
+ :index => { :member => false, :method => :get, :collection => true }
30
+ }
31
+
32
+ def self.configure(&block)
33
+ instance_eval(&block)
34
+ end
35
+
36
+ # Automatically register the DSL to Sinatra::Base if this
37
+ # module is included:
38
+ #
39
+ # Example:
40
+ #
41
+ # class MyApp << Sinatra::Base
42
+ # include Sinatra::Rabbit
43
+ # end
44
+ #
45
+ def self.included(base)
46
+ base.register(DSL)
47
+ end
48
+
49
+ class Collection < BaseCollection
50
+
51
+ def self.generate(name, &block)
52
+ @name = name.to_sym
53
+ class_eval(&block)
54
+ self
55
+ end
56
+
57
+ def self.path; @name; end
58
+
59
+ def self.description(text)
60
+ @description = text
61
+ end
62
+
63
+ def self.operation(operation_name, &block)
64
+ @operations ||= []
65
+ if operation_registred?(operation_name)
66
+ raise "Operation #{operation_name} already register in #{self.name} collection"
67
+ end
68
+ operation = operation_class(self, operation_name).generate(self, operation_name, &block)
69
+ send(http_method_for(operation_name), route_for(path, operation_name), {}, &operation.control)
70
+ self
71
+ end
72
+
73
+ def self.operations; @operations; end
74
+
75
+ class Operation
76
+
77
+ def self.generate(collection, name, &block)
78
+ @name, @params = name, []
79
+ class_eval(&block)
80
+ self
81
+ end
82
+
83
+ def self.description(text)
84
+ @description = text
85
+ end
86
+
87
+ def self.control(&block)
88
+ params_def = @params
89
+ @control ||= Proc.new do
90
+ begin
91
+ Rabbit::Validator.validate!(params, params_def)
92
+ rescue => e
93
+ if e.kind_of? Rabbit::Validator::ValidationError
94
+ status e.http_status_code
95
+ halt
96
+ else
97
+ raise e
98
+ end
99
+ end
100
+ instance_eval(&block)
101
+ end
102
+ end
103
+
104
+ def self.param(*args)
105
+ @params << Rabbit::Param.new(*args)
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ def self.operation_registred?(name)
112
+ @operations.any? { |o| o.name == name }
113
+ end
114
+
115
+ # Create an unique class name for all operations within Collection class
116
+ def self.operation_class(collection_klass, operation_name)
117
+ collection_klass.const_set(operation_name.to_s.camelize + 'Operation', Class.new(Operation))
118
+ end
119
+
120
+ end
121
+ end
122
+ end
123
+
@@ -0,0 +1,49 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one or more
3
+ # contributor license agreements. See the NOTICE file distributed with
4
+ # this work for additional information regarding copyright ownership. The
5
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance with the
7
+ # License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations
15
+ # under the License.
16
+
17
+ module Sinatra
18
+ module Rabbit
19
+
20
+ class BaseCollection < Sinatra::Base
21
+ attr_accessor :name, :description
22
+ attr_accessor :operations
23
+
24
+ set :views, Proc.new { File.join(File::dirname(__FILE__), "..", "..", "views") }
25
+ enable :method_overide
26
+
27
+ def self.route_for(collection, operation_name=nil)
28
+ if operation_name
29
+ o = Sinatra::Rabbit::STANDARD_OPERATIONS[operation_name]
30
+ operation_path = (o && o[:member]) ? operation_name.to_s : nil
31
+ id_param = (o && o[:collection]) ? nil : ":id"
32
+ [route_for(collection), id_param, operation_path].compact.join('/')
33
+ else
34
+ "/#{collection}"
35
+ end
36
+ end
37
+
38
+ def self.http_method_for(operation_name)
39
+ o = Sinatra::Rabbit::STANDARD_OPERATIONS[operation_name]
40
+ (o && o[:method]) ? o[:method] : :get
41
+ end
42
+
43
+ def self.collection_class(name)
44
+ Sinatra::Rabbit.const_set(name.to_s.camelize + 'Collection', Class.new(Collection))
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one or more
3
+ # contributor license agreements. See the NOTICE file distributed with
4
+ # this work for additional information regarding copyright ownership. The
5
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance with the
7
+ # License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations
15
+ # under the License.
16
+
17
+ module Sinatra
18
+ module Rabbit
19
+ module DSL
20
+
21
+ # Create DSL wrapper for creating a new collection
22
+ #
23
+ # Example:
24
+ #
25
+ # collection :images do
26
+ # description "Images collection"
27
+ #
28
+ # operation :index do
29
+ # ...
30
+ # end
31
+ # end
32
+ def collection(name, &block)
33
+ @collections ||= []
34
+ @collections << (current_collection = BaseCollection.collection_class(name).generate(name, &block))
35
+ use current_collection
36
+ end
37
+
38
+ # Return all defined collections
39
+ #
40
+ def collections
41
+ @collections
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,49 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one or more
3
+ # contributor license agreements. See the NOTICE file distributed with
4
+ # this work for additional information regarding copyright ownership. The
5
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance with the
7
+ # License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations
15
+ # under the License.
16
+
17
+ module Sinatra
18
+ module Rabbit
19
+ class Param
20
+ attr_reader :name, :klass, :required, :values, :description
21
+
22
+ def initialize(*args)
23
+ args.reverse!
24
+ @name, @klass = args.pop, args.pop
25
+ raise "DSL: You need to specify the name and param type (#{@name})" unless @name or @klass
26
+ parse_params!(args)
27
+ end
28
+
29
+ def required?; @required == true; end
30
+ def optional?; !required?; end
31
+ def enum?; !@values.nil?; end
32
+ def number?; [:integer, :float].include?(@klass); end
33
+
34
+ private
35
+
36
+ def parse_params!(args)
37
+ if args.pop == :required
38
+ @required = true
39
+ else
40
+ @required = false
41
+ end
42
+ @values = args.pop if args.last.kind_of? Array
43
+ @description = args.pop
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,59 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one or more
3
+ # contributor license agreements. See the NOTICE file distributed with
4
+ # this work for additional information regarding copyright ownership. The
5
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance with the
7
+ # License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations
15
+ # under the License.
16
+
17
+ module Sinatra
18
+ module Rabbit
19
+ module Validator
20
+
21
+ class ValidationError < StandardError
22
+ attr_reader :http_status_code
23
+ def initialize(code, message)
24
+ @http_status_code = code
25
+ super(message)
26
+ end
27
+ end
28
+
29
+ class RequiredParameter < ValidationError
30
+ def initialize(param_def, current_params)
31
+ super(400, "Required parameter '%s' not found in [%s]" % [param_def.name, current_params.keys.join(',')])
32
+ end
33
+ end
34
+
35
+ class InvalidValue < ValidationError
36
+ def initialize(param_def, current_value)
37
+ super(400, "Parameter '%s' value '%s' not found in list of allowed values [%s]" % [param_def.name,
38
+ current_value,
39
+ param_def.values.join(',')]
40
+ )
41
+ end
42
+ end
43
+
44
+ def self.validate!(current_params, operation_params)
45
+ operation_params.select { |p| p.required? }.each do |p|
46
+ unless current_params.keys.include?(p.name.to_s)
47
+ raise RequiredParameter.new(p, current_params)
48
+ end
49
+ end
50
+ operation_params.select { |p| p.enum? }.each do |p|
51
+ if p.enum? and !p.values.include?(current_params[p.name.to_s])
52
+ raise InvalidValue.new(p, current_params[p.name.to_s])
53
+ end
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -19,31 +17,31 @@
19
17
  require 'rake'
20
18
 
21
19
  Gem::Specification.new do |s|
22
- s.author = 'Red Hat, Inc.'
20
+ s.author = 'The Apache Software Foundation'
23
21
  s.homepage = "http://github.com/mifo/sinatra-rabbit"
24
- s.email = 'deltacloud-dev@incubator.apache.org'
22
+ s.email = 'dev@deltacloud.apache.org'
25
23
  s.name = 'sinatra-rabbit'
24
+ s.require_path = 'lib'
25
+ s.platform = Gem::Platform::RUBY
26
26
 
27
27
  s.description = <<-EOF
28
28
  Rabbit is a Sinatra extension which can help you writing
29
29
  a simple REST API using easy to undestand DSL.
30
30
  EOF
31
31
 
32
- s.version = '0.0.2'
32
+ s.version = '0.9'
33
33
  s.date = Time.now
34
34
  s.summary = %q{Sinatra REST API DSL}
35
35
  s.files = FileList[
36
36
  'lib/sinatra/*.rb',
37
37
  'lib/sinatra/rabbit/*.rb',
38
+ 'LICENSE',
39
+ 'README.md',
38
40
  'sinatra-rabbit.gemspec',
39
41
  ].to_a
40
42
 
41
- s.extra_rdoc_files = Dir["COPYING"]
43
+ s.extra_rdoc_files = Dir["LICENSE"]
42
44
  s.required_ruby_version = '>= 1.8.1'
43
45
 
44
- s.add_runtime_dependency 'sinatra', '>= 0.9.4'
45
- s.add_runtime_dependency 'rack-accept', '>= 0.4.3'
46
-
47
- s.add_dependency('haml', '>= 2.2.17')
48
-
46
+ s.add_runtime_dependency 'sinatra', '>= 1.3.0'
49
47
  end
metadata CHANGED
@@ -1,121 +1,66 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: sinatra-rabbit
3
- version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 2
10
- version: 0.0.2
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.9'
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
13
- - Red Hat, Inc.
7
+ authors:
8
+ - The Apache Software Foundation
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2010-11-01 00:00:00 +01:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-12-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: sinatra
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70240995322640 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 51
30
- segments:
31
- - 0
32
- - 9
33
- - 4
34
- version: 0.9.4
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.0
35
22
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: rack-accept
39
23
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- hash: 9
46
- segments:
47
- - 0
48
- - 4
49
- - 3
50
- version: 0.4.3
51
- type: :runtime
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: haml
55
- prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 37
62
- segments:
63
- - 2
64
- - 2
65
- - 17
66
- version: 2.2.17
67
- type: :runtime
68
- version_requirements: *id003
69
- description: " Rabbit is a Sinatra extension which can help you writing\n a simple REST API using easy to undestand DSL.\n"
70
- email: deltacloud-dev@incubator.apache.org
24
+ version_requirements: *70240995322640
25
+ description: ! " Rabbit is a Sinatra extension which can help you writing\n a
26
+ simple REST API using easy to undestand DSL.\n"
27
+ email: dev@deltacloud.apache.org
71
28
  executables: []
72
-
73
29
  extensions: []
74
-
75
- extra_rdoc_files:
76
- - COPYING
77
- files:
30
+ extra_rdoc_files:
31
+ - LICENSE
32
+ files:
78
33
  - lib/sinatra/rabbit.rb
79
- - lib/sinatra/rabbit/url_for.rb
80
- - lib/sinatra/rabbit/validation.rb
81
- - lib/sinatra/rabbit/respond_to.rb
34
+ - lib/sinatra/rabbit/base.rb
35
+ - lib/sinatra/rabbit/base_collection.rb
36
+ - lib/sinatra/rabbit/dsl.rb
37
+ - lib/sinatra/rabbit/param.rb
38
+ - lib/sinatra/rabbit/validator.rb
39
+ - LICENSE
40
+ - README.md
82
41
  - sinatra-rabbit.gemspec
83
- - COPYING
84
- has_rdoc: true
85
42
  homepage: http://github.com/mifo/sinatra-rabbit
86
43
  licenses: []
87
-
88
44
  post_install_message:
89
45
  rdoc_options: []
90
-
91
- require_paths:
46
+ require_paths:
92
47
  - lib
93
- required_ruby_version: !ruby/object:Gem::Requirement
48
+ required_ruby_version: !ruby/object:Gem::Requirement
94
49
  none: false
95
- requirements:
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- hash: 53
99
- segments:
100
- - 1
101
- - 8
102
- - 1
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
103
53
  version: 1.8.1
104
- required_rubygems_version: !ruby/object:Gem::Requirement
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
55
  none: false
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- hash: 3
110
- segments:
111
- - 0
112
- version: "0"
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
113
60
  requirements: []
114
-
115
61
  rubyforge_project:
116
- rubygems_version: 1.3.7
62
+ rubygems_version: 1.8.10
117
63
  signing_key:
118
64
  specification_version: 3
119
65
  summary: Sinatra REST API DSL
120
66
  test_files: []
121
-