Class: Praxis::MultipartPart

Inherits:
Object
  • Object
show all
Includes:
Attributor::Type
Defined in:
lib/praxis/multipart/part.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(body, headers = {}, name: nil, filename: nil, payload_attribute: nil, headers_attribute: nil, filename_attribute: nil) ⇒ MultipartPart

Returns a new instance of MultipartPart.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/praxis/multipart/part.rb', line 75

def initialize(body, headers={}, name: nil, filename: nil, payload_attribute: nil, headers_attribute: nil, filename_attribute: nil)
  @name = name
  @body = body
  @headers = headers

  if content_type.nil?
    self.content_type = 'text/plain'
  end

  @filename = filename

  @payload_attribute = payload_attribute
  @headers_attribute = headers_attribute
  @filename_attribute = filename_attribute

  reset_content_disposition
end

Instance Attribute Details

#bodyObject Also known as: payload

Returns the value of attribute body.



5
6
7
# File 'lib/praxis/multipart/part.rb', line 5

def body
  @body
end

#filenameObject

Returns the value of attribute filename.



7
8
9
# File 'lib/praxis/multipart/part.rb', line 7

def filename
  @filename
end

#filename_attributeObject

Returns the value of attribute filename_attribute.



11
12
13
# File 'lib/praxis/multipart/part.rb', line 11

def filename_attribute
  @filename_attribute
end

#headersObject

Returns the value of attribute headers.



6
7
8
# File 'lib/praxis/multipart/part.rb', line 6

def headers
  @headers
end

#headers_attributeObject

Returns the value of attribute headers_attribute.



10
11
12
# File 'lib/praxis/multipart/part.rb', line 10

def headers_attribute
  @headers_attribute
end

#nameObject

Returns the value of attribute name.



8
9
10
# File 'lib/praxis/multipart/part.rb', line 8

def name
  @name
end

#payload_attributeObject

Returns the value of attribute payload_attribute.



9
10
11
# File 'lib/praxis/multipart/part.rb', line 9

def payload_attribute
  @payload_attribute
end

Class Method Details

.check_option!(name, definition) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/praxis/multipart/part.rb', line 13

def self.check_option!(name, definition)
  case name
  when :payload_attribute, :headers_attribute, :filename_attribute
    unless definition.nil? || definition.kind_of?(Attributor::Attribute)
      raise Attributor::AttributorException.new("Value for option #{name.inspect} must be an Attribute. Got #{definition.class.name}")
    end
  else
    return :unknown
  end

  :ok
end

.describe(shallow = true, example: nil, options: {}) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/praxis/multipart/part.rb', line 56

def self.describe(shallow=true, example: nil, options:{})
  hash = super(shallow, example: example)

  if (payload_attribute = options[:payload_attribute])
    payload_example = example.payload if example
    hash[:payload] = payload_attribute.describe(shallow, example: payload_example)
  end
  if (headers_attribute = options[:headers_attribute])
    headers_example = example.headers if example
    hash[:headers] = headers_attribute.describe(shallow, example: headers_example)
  end
  if (filename_attribute = options[:filename_attribute])
    filename_example = example.filename if example
    hash[:filename] = filename_attribute.describe(shallow, example: filename_example)
  end

  hash
end

.example(context = nil, options: {}) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/praxis/multipart/part.rb', line 30

def self.example(context=nil, options:{})
  if (payload_attribute = options[:payload_attribute])
    payload = payload_attribute.example(context + ['payload'])
  end

  headers = if (headers_attribute = options[:headers_attribute])
    headers_attribute.example(context + ['headers'])
  else
    {}
  end

  name = options[:name]

  filename = if (filename_attribute = options[:filename_attribute])
    filename_attribute.example(context + ['filename'])
  else
    nil
  end

  self.new(payload, headers, name: name, filename: filename,
           payload_attribute: payload_attribute,
           headers_attribute: headers_attribute,
           filename_attribute: filename_attribute)
end

.native_typeObject



26
27
28
# File 'lib/praxis/multipart/part.rb', line 26

def self.native_type
  self
end

Instance Method Details

#attribute=(attribute) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/praxis/multipart/part.rb', line 96

def attribute=(attribute)
  unless self.kind_of?(attribute.type)
    raise ArgumentError, "invalid attribute type #{attribute.type}"
  end

  if attribute.options.key? :payload_attribute
    @payload_attribute = attribute.options[:payload_attribute]
  end

  if attribute.options.key? :headers_attribute
    @headers_attribute = attribute.options[:headers_attribute]
  end

  if attribute.options.key? :filename_attribute
    @filename_attribute = attribute.options[:filename_attribute]
  end

end

#content_typeMediaTypeIdentifier

Determine the content type of this response.

Returns:



136
137
138
# File 'lib/praxis/multipart/part.rb', line 136

def content_type
  @content_type ||= MediaTypeIdentifier.load(headers['Content-Type']).freeze
end

#content_type=(identifier) ⇒ String

TODO:

DRY this out (also used in Response)

Set the content type for this response.

Parameters:

Returns:

  • (String)


145
146
147
148
# File 'lib/praxis/multipart/part.rb', line 145

def content_type=(identifier)
  @content_type = nil
  headers['Content-Type'] = MediaTypeIdentifier.load(identifier).to_s
end

#dump(**opts) ⇒ Object



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/praxis/multipart/part.rb', line 217

def dump(**opts)
  header_string = self.headers.collect do |name, value|
    "#{name}: #{value}"
  end.join("\r\n")

  body = self.payload_attribute.dump(self.payload, **opts)

  body_string = case body
  when Hash, Array
    handler.generate(body)
  else
    body
  end

  "#{header_string}\r\n\r\n#{body_string}"
end

#encode!Object



154
155
156
157
158
159
160
161
162
# File 'lib/praxis/multipart/part.rb', line 154

def encode!
  case @body
  when Hash, Array
    # response payload is structured data; transform it into an entity using the handler
    # implied by the response's media type. If no handler is registered for this
    # name, assume JSON as a default handler.
    @body = JSON.pretty_generate(@body)
  end
end

#handlerObject



212
213
214
215
# File 'lib/praxis/multipart/part.rb', line 212

def handler
  handlers = Praxis::Application.instance.handlers
  (content_type && handlers[content_type.handler_name]) || handlers['json']
end

#load_headers(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object



127
128
129
130
131
# File 'lib/praxis/multipart/part.rb', line 127

def load_headers(context=Attributor::DEFAULT_ROOT_CONTEXT)
  if self.headers_attribute
    self.headers = self.headers_attribute.load(self.headers)
  end
end

#load_payload(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/praxis/multipart/part.rb', line 115

def load_payload(context=Attributor::DEFAULT_ROOT_CONTEXT)
  if self.payload_attribute
    value = if self.payload.kind_of?(String)
      handler.parse(self.payload)
    else
      self.payload
    end

    self.payload = self.payload_attribute.load(value)
  end
end

#reset_content_dispositionObject



188
189
190
191
192
193
194
195
196
197
# File 'lib/praxis/multipart/part.rb', line 188

def reset_content_disposition
  self.headers['Content-Disposition'] = begin
    disposition = "form-data; name=#{name}"
    if filename
      disposition += "; filename=#{filename}"
    end

    disposition
  end
end

#statusObject



150
151
152
# File 'lib/praxis/multipart/part.rb', line 150

def status
  @headers['Status'].to_i
end

#validate(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object



182
183
184
185
186
# File 'lib/praxis/multipart/part.rb', line 182

def validate(context=Attributor::DEFAULT_ROOT_CONTEXT)
  errors = validate_headers(context)
  errors.push *validate_payload(context)
  errors.push *validate_filename(context)
end

#validate_filename(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object



176
177
178
179
180
# File 'lib/praxis/multipart/part.rb', line 176

def validate_filename(context=Attributor::DEFAULT_ROOT_CONTEXT)
  return [] unless self.filename_attribute

  self.filename_attribute.validate(filename, context + ['filename'])
end

#validate_headers(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object



164
165
166
167
168
# File 'lib/praxis/multipart/part.rb', line 164

def validate_headers(context=Attributor::DEFAULT_ROOT_CONTEXT)
  return [] unless self.headers_attribute

  self.headers_attribute.validate(headers, context + ['headers'])
end

#validate_payload(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object



170
171
172
173
174
# File 'lib/praxis/multipart/part.rb', line 170

def validate_payload(context=Attributor::DEFAULT_ROOT_CONTEXT)
  return [] unless self.payload_attribute

  self.payload_attribute.validate(payload, context + ['payload'])
end