culpa 0.1.1 → 0.2.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODRhZjgzN2MwYjZlMWVjNjZhMzk4NWYxYjFhOTE3YzQ5YzE3NjhlYQ==
4
+ M2RhNzVkZDU0NGRhNjVmNjFjYmJmNDFkMjJkM2IyMjg2MGVhMzk5Mw==
5
5
  data.tar.gz: !binary |-
6
- ZjJlMWU0ZTViOWE1NTFmM2E3ZmQ0YzY0NzMxM2RjYWM1ODBkMGM5Nw==
6
+ MGI1N2NmYmJlNDM2MDM2ZTYzZGU4ZmVjM2U0MzU4MDMxMDliY2VkNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ODk0NTAzM2FjZjQ5MmM5NDA3Yjc0MTZlOGEzNzFmODVkMzM3Y2NhNzM4ZTc4
10
- OTA1N2JhNDFhODEwZDdjMTA4NTI3ZGUxOWRmZTM5ZTM3NzIxZjk0NzhiNDM4
11
- ZjQyMDBhM2Q5ODc4NTAwZGVmZjdhNTBhYzk3YjM1NDg3NmE0YTE=
9
+ NzhjNTQ3ZWExZjg1Mzc3MmQ0YTdhZWY2NjM1ZTE4M2Q4MWE1MDRkZDNjOTE5
10
+ NTM0NzM1MTZjZDNhMGZkMGYwN2RlNzFhM2Y0ZGMxYzZjMGFhODZmMzRkZGZk
11
+ YTI1ODAzN2Y0ZjcwYjEzM2M1NTU0MTg5NGZhYjBjM2U0NWVkMDI=
12
12
  data.tar.gz: !binary |-
13
- M2VkOWY1NzFjOGZmYzMzNDNmYWM0MDlhNzZhNWU0Y2ZhMTJiZDI0YzYxMmQz
14
- ZjE0OTc2NWMxMDBlOThlMDRhZDllN2UxZTRiZmNkM2EwNGU2ZjVmMDgyNjQ3
15
- ZTg0Njk2ODM2NGYyOTY5NmJjOTMwOTZlYjY1NGRlMmI3MmU0MjU=
13
+ Zjk3OWRmMTgzZjgyODExYTFiN2UyMzM5OTViZTQ5NmIxYzYwNjNjM2EyYjY3
14
+ NzgwZmM0MTA2ZWI4OTc2MzJkYzI0N2FkMTNmYTg1MWNlMmZiOTA2MGE1ZGU2
15
+ YjgxYTBjMzRiOGQ1YmZjZWJkOTllODBlMTQ2MzZmN2YwODQxNzM=
data/lib/action.rb CHANGED
@@ -1,5 +1,60 @@
1
1
  class Action
2
2
 
3
+ RETURN_CODES = {
4
+ # Information codes
5
+ continue: 100,
6
+ switching_procotols: 101,
7
+ # Success codes
8
+ ok: 200,
9
+ created: 201,
10
+ accepted: 202,
11
+ non_authoritative_information: 203,
12
+ no_content: 204,
13
+ reset_content: 205,
14
+ partial_content: 206,
15
+ # Redirection codes
16
+ multiple_choices: 300,
17
+ moved_permanently: 301,
18
+ moved_temporarily: 302,
19
+ see_other: 303,
20
+ not_modified: 304,
21
+ use_proxy: 305,
22
+ temporary_redirect: 307,
23
+ permanent_redirect: 308,
24
+ too_many_redirects: 310,
25
+ # Clients error codes
26
+ bad_request: 400,
27
+ unauthorized: 401,
28
+ payment_required: 402,
29
+ forbidden: 403,
30
+ not_found: 404,
31
+ method_not_allowed: 405,
32
+ not_acceptable: 406,
33
+ proxy_authentication_required: 407,
34
+ request_time_out: 408,
35
+ conflict: 409,
36
+ gone: 410,
37
+ length_required: 411,
38
+ precondition_failed: 412,
39
+ request_entity_too_large: 413,
40
+ request_uri_too_long: 414,
41
+ unsupported_media_type: 415,
42
+ request_range_unsatisfiable: 416,
43
+ expectation_failed: 417,
44
+ im_a_tea_pot: 418,
45
+ bad_mapping: 412,
46
+ unavailable_for_legal_reason: 451,
47
+ # Server error codes
48
+ internal_server_error: 500,
49
+ not_implemented: 501,
50
+ bad_gateway: 502,
51
+ proxy_error: 502,
52
+ service_unavailable: 503,
53
+ gateway_time_out: 504,
54
+ bandwidth_limit_exceeded: 509,
55
+ unknown_error: 520
56
+ }
57
+
3
58
  attr_accessor :to_render
4
59
 
5
60
  def initialize(envelope, request)
@@ -8,8 +63,33 @@ class Action
8
63
  @to_render = nil
9
64
  end
10
65
 
11
- def render(response_object, options={})
12
- @to_render = {object: response_object, options: options}
66
+ def render(options={})
67
+ options[:headers] ||= {}
68
+ if options.has_key? :json
69
+ @to_render = {
70
+ format: :json,
71
+ status: RETURN_CODES[options[:status]] || 200,
72
+ headers: { 'Content-Type' => 'application/json' }.merge(options[:headers]),
73
+ object: options[:json]
74
+ }
75
+ elsif options.has_key? :file
76
+ @to_render = {
77
+ format: :file_from_path,
78
+ headers: {
79
+ 'Content-Type' => options[:content_type] || 'application/octet-stream'
80
+ }.merge(options[:headers]),
81
+ status: RETURN_CODES[options[:status]] || 200,
82
+ object: FileHelpers::Streamer.new(options[:file])
83
+ }
84
+ elsif options.has_key? :status
85
+ @to_render = {
86
+ format: :status,
87
+ headers: options[:headers],
88
+ status: RETURN_CODES[options[:status]]
89
+ }
90
+ else
91
+ raise Culpa::UnknownRenderCall.new
92
+ end
13
93
  end
14
94
 
15
95
  end
data/lib/culpa.rb CHANGED
@@ -4,6 +4,7 @@ require 'yaml'
4
4
 
5
5
  require 'envelope'
6
6
  require 'path_parser'
7
+ require 'file_helpers'
7
8
 
8
9
  ACTIONS_PATH ||= './actions/*.rb'
9
10
  MODELS_PATH ||= './models/*.rb'
@@ -25,6 +26,7 @@ module Culpa
25
26
 
26
27
  class UnpredictableSubCallError < StandardError; end
27
28
  class NoRenderCalled < StandardError; end
29
+ class UnknownRenderCall < StandardError; end
28
30
 
29
31
  class Application
30
32
 
@@ -32,45 +34,31 @@ module Culpa
32
34
  @router = router
33
35
  end
34
36
 
35
- # Router's helpers
36
37
  def call_action(options)
37
- # Preparing common parts
38
38
  router_method_name = "#{options[:sub_call]}_#{options[:res_name]}"
39
39
  envelope = Envelope.new
40
40
  request = EnvelopeRequest.new(options)
41
-
42
- # The router do not have the key
43
- if !@router || !@router.has_key?(router_method_name)
44
- default_class = options[:res_name].split('_').map{|w| w.capitalize}.join
45
- action_default_class = Actions.const_get(default_class).new(envelope, request)
46
- if action_default_class && action_default_class.respond_to?(options[:sub_call])
47
- action_default_class.send(options[:sub_call])
48
- if action_default_class.to_render
49
- return do_render action_default_class.to_render if action_default_class.to_render
50
- else
51
- raise NoRenderCalled.new
52
- end
53
- end
54
- return not_found
55
- end
56
-
57
- # The router have the key
41
+ return not_found unless @router.has_key? router_method_name
58
42
  @router[router_method_name].each do |method|
59
43
  action_class_name, method_name = method.split('.')
60
44
  action_class = Actions.const_get(action_class_name).new(envelope, request)
61
45
  action_class.send method_name
62
46
  return do_render action_class.to_render if action_class.to_render
63
47
  end
64
-
65
- # If nothing called do_render...
66
48
  raise NoRenderCalled.new
67
49
  end
68
50
 
69
- # Render a view
51
+ # Render a json or anything else
70
52
  def do_render(to_render)
71
- code = to_render[:options][:status] || 200
72
- content_type = to_render[:options][:content_type] || 'application/json'
73
- [code.to_s, {'Content-Type' => content_type}, [to_render[:object].to_json]]
53
+ body = case to_render[:format]
54
+ when :json
55
+ [ to_render[:object].to_json ]
56
+ when :file_from_path, :file_from_io
57
+ to_render[:object]
58
+ when :status
59
+ []
60
+ end
61
+ [ to_render[:status], to_render[:headers], body ]
74
62
  end
75
63
 
76
64
  # Called by rack
@@ -122,12 +110,12 @@ module Culpa
122
110
 
123
111
  # 400 : Bad request
124
112
  def bad_request
125
- ['400', {'Content-Type' => 'application/json'}, ['{ "error": "bad_request" }']]
113
+ ['400', {'Content-Type' => 'application/json'}, []]
126
114
  end
127
115
 
128
116
  # 404 : Not found
129
117
  def not_found
130
- ['404', {'Content-Type' => 'application/json'}, ['{ "error": "not_found" }']]
118
+ ['404', {'Content-Type' => 'application/json'}, []]
131
119
  end
132
120
 
133
121
  end
@@ -0,0 +1,14 @@
1
+ module FileHelpers
2
+
3
+ class Streamer
4
+ def initialize(element)
5
+ @element = element
6
+ end
7
+ def each(&blk)
8
+ @element.each(&blk)
9
+ ensure
10
+ @element.close
11
+ end
12
+ end
13
+
14
+ end
data/templates/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'culpa', '~> 0.0'
3
+ gem 'culpa', '~> 0.2'
4
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: culpa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jérémy SEBAN
@@ -49,6 +49,7 @@ files:
49
49
  - lib/action.rb
50
50
  - lib/culpa.rb
51
51
  - lib/envelope.rb
52
+ - lib/file_helpers.rb
52
53
  - lib/path_parser.rb
53
54
  - templates/Gemfile
54
55
  - templates/config.ru