safrano 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f2ebcbe8cf374526aa263f93515e2424753898ad878904d6d5d087bc6317c4e
4
- data.tar.gz: 48190a71451991630bd48347c3cf2acb701423bb58266fa736b0cf7a5b6f3bdf
3
+ metadata.gz: 37c9ae21ef2d9a7cd8cc216719fcebc353a2588c2c2c9947b2490b7f7efa4e37
4
+ data.tar.gz: 3fa80a8985eee84c193783c4202efdb41aa64e77c173dc3a969164bdc5d0e832
5
5
  SHA512:
6
- metadata.gz: 70ef7d275b566269879e4cd37f019958cd354504d1dede907adcf4d078e47361412997c69eec2c403317013ef5ac8019315aeb8cc89715906f2f12bd59e885dc
7
- data.tar.gz: 1ff899294284a5e9531187533938e14ae304c1344131177dff1612037ca32e6a27dfcd72b367dd705afbb5cd5b9d38e9c11dc7b8f7766d470c2ac4c45686372b
6
+ metadata.gz: f17f10577a0296d0077e16271f4ebd5db84cafaf72a6c01ea445045e9be92b4d3d07b25a51e72d4174d4aa3ecc9d1aee92987ebbb46b7d2037ceb8843631876e
7
+ data.tar.gz: 68ce7bbad19ae58dcc96e9aa84db0eefb56f5e1f5ff8b02fbb3ae1d562362f29b08616b239a5adf6dfb768ce8da58d503a8a330095420d1c762bafe212a1b83a
@@ -8,6 +8,11 @@ module Safrano
8
8
  module Media
9
9
  # base class for Media Handler
10
10
  class Handler
11
+ def check_before_create(data:,
12
+ entity:,
13
+ filename:)
14
+ Contract::OK
15
+ end
11
16
  end
12
17
 
13
18
  # Simple static File/Directory based media store handler
@@ -54,13 +59,13 @@ module Safrano
54
59
  end
55
60
 
56
61
  # relative to @root
57
- # eg Photo/1/pommes-topaz.jpg
62
+ # eg Photo/1/1
58
63
  def filename(entity)
59
64
  Dir.chdir(abs_path(entity)) do
60
65
  # simple design: one file per directory, and the directory
61
66
  # contains the media entity-id --> implicit link between the media
62
67
  # entity
63
- File.join(media_path(entity), Dir.glob('*').min)
68
+ File.join(media_path(entity), Dir.glob('*').max)
64
69
  end
65
70
  end
66
71
 
@@ -147,15 +152,14 @@ module Safrano
147
152
 
148
153
  # this is relative to abs_klass_dir(entity) eg to /@root/Photo
149
154
  # tree-structure
150
- # media_path_ids = 1 --> 1
151
- # media_path_ids = 15 --> 1/5
152
- # media_path_ids = 555 --> 5/5/5
153
- # media_path_ids = 5,5,5 --> 5/00/5/00/5
154
- # media_path_ids = 5,00,5 --> 5/00/0/0/00/5
155
- # media_path_ids = 5,xyz,5 --> 5/00/x/y/z/00/5
155
+ # media_path_ids = 1 --> 1/v
156
+ # media_path_ids = 15 --> 1/5/v
157
+ # media_path_ids = 555 --> 5/5/5/v
158
+ # media_path_ids = 5,5,5 --> 5/00/5/00/5/v
159
+ # media_path_ids = 5,00,5 --> 5/00/0/0/00/5/v
160
+ # media_path_ids = 5,xyz,5 --> 5/00/x/y/z/00/5/v
156
161
  def media_directory(entity)
157
162
  StaticTree.path_builder(entity.media_path_ids)
158
- # entity.media_path_ids.map{|id| id.to_s.chars.join('/')}.join(@sep)
159
163
  end
160
164
 
161
165
  def in_media_directory(entity)
@@ -267,29 +271,39 @@ module Safrano
267
271
  missing: :skip)
268
272
  end
269
273
 
270
- # to_one rels are create with FK data set on the parent entity
271
- if parent
272
- odata_create_save_entity_and_rel(req, new_entity, assoc, parent)
273
- else
274
- # in-changeset requests get their own transaction
275
- new_entity.save(transaction: !req.in_changeset)
276
- end
274
+ # call before_create_entity media hook
275
+ new_entity.before_create_media_entity(data: data, mimetype: mimetype) if new_entity.respond_to? :before_create_media_entity
276
+
277
+ media_handler.check_before_create(data: data,
278
+ entity: new_entity,
279
+ filename: filename).if_valid { |_ret|
280
+ # to_one rels are create with FK data set on the parent entity
281
+ if parent
282
+ odata_create_save_entity_and_rel(req, new_entity, assoc, parent)
283
+ else
284
+ # in-changeset requests get their own transaction
285
+ new_entity.save(transaction: !req.in_changeset)
286
+ end
287
+
288
+ req.register_content_id_ref(new_entity)
289
+ new_entity.copy_request_infos(req)
277
290
 
278
- req.register_content_id_ref(new_entity)
279
- new_entity.copy_request_infos(req)
291
+ # call before_create_media hook
292
+ new_entity.before_create_media if new_entity.respond_to? :before_create_media
280
293
 
281
- # call before_create_media hook
282
- new_entity.before_create_media if new_entity.respond_to? :before_create_media
294
+ media_handler.save_file(data: data,
295
+ entity: new_entity,
296
+ filename: filename)
283
297
 
284
- media_handler.save_file(data: data,
285
- entity: new_entity,
286
- filename: filename)
298
+ # call after_create_media hook
299
+ new_entity.after_create_media if new_entity.respond_to? :after_create_media
287
300
 
288
- # call after_create_media hook
289
- new_entity.after_create_media if new_entity.respond_to? :after_create_media
301
+ # json is default content type so we dont need to specify it here again
302
+ # Contract.valid([201, EMPTY_HASH, new_entity.to_odata_post_json(service: req.service)])
303
+ # TODO quirks array mode !
304
+ Contract.valid([201, EMPTY_HASH, new_entity.to_odata_create_json(request: req)])
305
+ }.tap_error { |e| return e.odata_get(req) }.result
290
306
 
291
- # json is default content type so we dont need to specify it here again
292
- [201, EMPTY_HASH, new_entity.to_odata_post_json(service: req.service)]
293
307
  else # TODO: other formats
294
308
  415
295
309
  end
data/lib/odata/entity.rb CHANGED
@@ -112,10 +112,11 @@ module Safrano
112
112
  selvals
113
113
  end
114
114
 
115
- # post paylod expects the new entity in an array
116
- def to_odata_post_json(service:)
117
- innerj = service.get_coll_odata_h(array: [self],
118
- template: self.class.default_template).to_json
115
+ # some clients wrongly expect post payload with the new entity in an array
116
+ # TODO quirks array mode !
117
+ def to_odata_array_json(request:)
118
+ innerj = request.service.get_coll_odata_h(array: [self],
119
+ template: self.class.default_template).to_json
119
120
  "#{DJ_OPEN}#{innerj}#{DJ_CLOSE}"
120
121
  end
121
122
 
@@ -263,6 +264,7 @@ module Safrano
263
264
  ret
264
265
  end
265
266
  end
267
+
266
268
  # end of module SafranoEntity
267
269
  module Entity
268
270
  include EntityBase
@@ -438,5 +440,22 @@ module Safrano
438
440
  pk_hash.values
439
441
  end
440
442
  end
441
- end
442
- # end of Module OData
443
+
444
+ module EntityCreateStandardOutput
445
+ # Json formatter for a create entity POST call / Standard version; return as json object
446
+ def to_odata_create_json(request:)
447
+ # TODO Perf: reduce method call overhead
448
+ # we added this redirection for readability and flexibility
449
+ to_odata_json(request: request)
450
+ end
451
+ end
452
+
453
+ module EntityCreateArrayOutput
454
+ # Json formatter for a create entity POST call Array version
455
+ def to_odata_create_json(request:)
456
+ # TODO Perf: reduce method call overhead
457
+ # we added this redirection for readability and flexibility
458
+ to_odata_array_json(request: request)
459
+ end
460
+ end
461
+ end # end of Module OData
data/lib/odata/error.rb CHANGED
@@ -114,6 +114,18 @@ module Safrano
114
114
  end
115
115
  end
116
116
 
117
+ # http Unprocessable Entity for example when trying to
118
+ # upload duplicated media ressource
119
+ class UnprocessableEntityError
120
+ extend ErrorClass
121
+ include ErrorInstance
122
+ HTTP_CODE = 422
123
+ @msg = 'Unprocessable Entity'
124
+ def initialize(reason)
125
+ @msg = reason
126
+ end
127
+ end
128
+
117
129
  # http Bad Req.
118
130
  class BadRequestError
119
131
  extend ErrorClass
@@ -125,6 +137,13 @@ module Safrano
125
137
  end
126
138
  end
127
139
 
140
+ # for upload empty media
141
+ class BadRequestEmptyMediaUpload < BadRequestError
142
+ include ErrorInstance
143
+ def initialize( path )
144
+ @msg = "Bad Request: empty media file #{path}"
145
+ end
146
+ end
128
147
  # Generic failed changeset
129
148
  class BadRequestFailedChangeSet < BadRequestError
130
149
  @msg = 'Bad Request: Failed changeset '
@@ -627,7 +627,9 @@ module Safrano
627
627
  req.register_content_id_ref(new_entity)
628
628
  new_entity.copy_request_infos(req)
629
629
  # json is default content type so we dont need to specify it here again
630
- [201, EMPTY_HASH, new_entity.to_odata_post_json(service: req.service)]
630
+ # TODO quirks array mode !
631
+ # [201, EMPTY_HASH, new_entity.to_odata_post_json(service: req.service)]
632
+ [201, EMPTY_HASH, new_entity.to_odata_create_json(request: req)]
631
633
  else # TODO: other formats
632
634
  415
633
635
  end
@@ -204,6 +204,12 @@ module Safrano
204
204
  (@v2.xserver_url = @xserver_url) if @v2
205
205
  end
206
206
 
207
+ # keep the bug active for now, but allow to activate the fix,
208
+ # later we will change the default to be fixed
209
+ def bugfix_create_response(bool = false)
210
+ @bugfix_create_response = bool
211
+ end
212
+
207
213
  # end public API
208
214
 
209
215
  def set_uribase
@@ -361,6 +367,9 @@ module Safrano
361
367
  @collections.each do |klass|
362
368
  klass.build_uri(@uribase)
363
369
  klass.include(klass.time_cols.empty? ? Safrano::NoMappingBeforeOutput : Safrano::MappingBeforeOutput)
370
+
371
+ # Output create (POST) as single entity (Standard) or as array (non-standard buggy)
372
+ klass.include ( @bugfix_create_response ? Safrano::EntityCreateStandardOutput : Safrano::EntityCreateArrayOutput)
364
373
  end
365
374
 
366
375
  # build allowed transitions (requires that @collections are filled and sorted for having a
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Safrano
4
- VERSION = '0.4.5'
4
+ VERSION = '0.4.6'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - oz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-27 00:00:00.000000000 Z
11
+ date: 2021-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -108,7 +108,7 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.51'
111
- description: Safrano is an OData server library based on Ruby, Rack and Sequel.
111
+ description: Safrano is an OData server library based on Ruby Sequel and Rack.
112
112
  email: dev@aithscel.eu
113
113
  executables: []
114
114
  extensions: []
@@ -189,8 +189,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
189
  - !ruby/object:Gem::Version
190
190
  version: '0'
191
191
  requirements: []
192
- rubygems_version: 3.2.0.rc.2
192
+ rubygems_version: 3.2.5
193
193
  signing_key:
194
194
  specification_version: 4
195
- summary: Safrano is a Ruby OData server library based on Sequel and Rack
195
+ summary: Safrano is an OData server library based on Ruby Sequel and Rack
196
196
  test_files: []