safrano 0.4.5 → 0.4.6

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,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: []