sinatra-rabbit 0.0.2 → 0.9

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.
@@ -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
-