ribose 0.3.0 → 0.4.1

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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/test.yml +27 -0
  3. data/.rubocop.yml +21 -16
  4. data/CHANGELOG.md +20 -0
  5. data/README.md +99 -0
  6. data/lib/ribose/actions/create.rb +2 -1
  7. data/lib/ribose/actions/update.rb +2 -1
  8. data/lib/ribose/calendar.rb +2 -2
  9. data/lib/ribose/client.rb +27 -9
  10. data/lib/ribose/configuration.rb +13 -4
  11. data/lib/ribose/connection.rb +15 -0
  12. data/lib/ribose/conversation.rb +18 -0
  13. data/lib/ribose/event.rb +86 -0
  14. data/lib/ribose/file_uploader.rb +20 -2
  15. data/lib/ribose/file_version.rb +97 -0
  16. data/lib/ribose/request.rb +49 -10
  17. data/lib/ribose/session.rb +36 -22
  18. data/lib/ribose/space.rb +4 -0
  19. data/lib/ribose/space_category.rb +15 -0
  20. data/lib/ribose/space_file.rb +29 -0
  21. data/lib/ribose/user.rb +9 -5
  22. data/lib/ribose/version.rb +1 -1
  23. data/lib/ribose/version_uploader.rb +27 -0
  24. data/lib/ribose.rb +3 -0
  25. data/ribose.gemspec +3 -4
  26. data/spec/fixtures/calendar_event.json +48 -0
  27. data/spec/fixtures/conversation.json +1 -1
  28. data/spec/fixtures/event_created.json +21 -0
  29. data/spec/fixtures/event_updated.json +23 -0
  30. data/spec/fixtures/file_version.json +14 -0
  31. data/spec/fixtures/space_categories.json +150 -0
  32. data/spec/fixtures/space_file_icon.json +4 -0
  33. data/spec/ribose/connection_spec.rb +11 -0
  34. data/spec/ribose/conversation_spec.rb +14 -0
  35. data/spec/ribose/event_spec.rb +85 -0
  36. data/spec/ribose/file_uploader_spec.rb +15 -2
  37. data/spec/ribose/file_version_spec.rb +76 -0
  38. data/spec/ribose/session_spec.rb +2 -2
  39. data/spec/ribose/space_category_spec.rb +13 -0
  40. data/spec/ribose/space_file_spec.rb +44 -0
  41. data/spec/ribose/space_spec.rb +11 -0
  42. data/spec/support/fake_ribose_api.rb +93 -5
  43. data/spec/support/file_upload_stub.rb +21 -15
  44. metadata +32 -34
  45. data/.travis.yml +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2e0b15b878e195c9733369b05fd950d9bf77f079
4
- data.tar.gz: 7255d85171187ea37f9ff8bd1ffdf900daaf1808
2
+ SHA256:
3
+ metadata.gz: 6f07dcb32d639879659c0ff04134fb21531fb31184d9f446045b7c6bf159d7b8
4
+ data.tar.gz: 6b4b18cff60096ad9437c593a1d50c781d00226da781f3354192b01f4f83b300
5
5
  SHA512:
6
- metadata.gz: 60ca909d98a6b7ff1d640a95deaabf730f375dcea7fec4a8e8d7f71fba9e00918c7be49f118ef039ebaf50eb7fab3bc4a2535e5c5c1cf187826429e9b7a91303
7
- data.tar.gz: 231660d478721f30381564b376478de330ff47c116ea5932f99a6429cf6dd907812ffa71b1fa441a646f228f6d5c72d9060ce9eff8e465350ef937a5d5523a13
6
+ metadata.gz: 4a07d25023569d184f6250c9cf0f7106ee9e9a6e3ae465516f58a5be597ee96f064c047fe5c434a573385b519c55a78fc7776b75d56f8c37666d89e98819fb19
7
+ data.tar.gz: d09ccceb23eed385f3270b9adb4653f6f4787495dc435366c6989ab51dec49509833c7e4c5d40650d238eb3826334425e1f8aa598c5effae84cea849059aa386
@@ -0,0 +1,27 @@
1
+ name: test
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ tags: [ v* ]
7
+ pull_request:
8
+
9
+ jobs:
10
+ test:
11
+ name: RSpec
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ ruby: [ '2.4', '2.5', '2.6', '2.7' ] #3.0
17
+ os: [ ubuntu-latest, windows-latest, macos-latest ]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+
22
+ - uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: ${{ matrix.ruby }}
25
+ bundler-cache: true
26
+
27
+ - run: bundle exec rake
data/.rubocop.yml CHANGED
@@ -1,9 +1,4 @@
1
1
  AllCops:
2
- Include:
3
- - "**/*.rake"
4
- - "**/Gemfile"
5
- - "**/Rakefile"
6
-
7
2
  Exclude:
8
3
  - db/schema.rb
9
4
 
@@ -357,8 +352,18 @@ Style/TrailingCommaInArguments:
357
352
  - no_comma
358
353
  Enabled: true
359
354
 
360
- Style/TrailingCommaInLiteral:
361
- Description: 'Checks for trailing comma in array and hash literals.'
355
+ Style/TrailingCommaInArrayLiteral:
356
+ Description: 'Checks for trailing comma in array literals.'
357
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
358
+ EnforcedStyleForMultiline: comma
359
+ SupportedStylesForMultiline:
360
+ - comma
361
+ - consistent_comma
362
+ - no_comma
363
+ Enabled: true
364
+
365
+ Style/TrailingCommaInHashLiteral:
366
+ Description: 'Checks for trailing comma in hash literals.'
362
367
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
363
368
  EnforcedStyleForMultiline: comma
364
369
  SupportedStylesForMultiline:
@@ -403,6 +408,13 @@ Layout/AlignParameters:
403
408
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-double-indent'
404
409
  Enabled: false
405
410
 
411
+ Layout/ConditionPosition:
412
+ Description: >-
413
+ Checks for condition placed in a confusing position relative to
414
+ the keyword.
415
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#same-line-condition'
416
+ Enabled: false
417
+
406
418
  Layout/DotPosition:
407
419
  Description: 'Checks the position of the dot in multi-line method calls.'
408
420
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains'
@@ -455,13 +467,6 @@ Lint/CircularArgumentReference:
455
467
  Description: "Don't refer to the keyword argument in the default value."
456
468
  Enabled: false
457
469
 
458
- Lint/ConditionPosition:
459
- Description: >-
460
- Checks for condition placed in a confusing position relative to
461
- the keyword.
462
- StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#same-line-condition'
463
- Enabled: false
464
-
465
470
  Lint/DeprecatedClassMethods:
466
471
  Description: 'Check for deprecated class method calls.'
467
472
  Enabled: false
@@ -487,7 +492,7 @@ Lint/HandleExceptions:
487
492
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions'
488
493
  Enabled: false
489
494
 
490
- Lint/LiteralInCondition:
495
+ Lint/LiteralAsCondition:
491
496
  Description: 'Checks of literals used in conditions.'
492
497
  Enabled: false
493
498
 
@@ -528,7 +533,7 @@ Lint/UnderscorePrefixedVariableName:
528
533
  Description: 'Do not use prefix `_` for a variable that is used.'
529
534
  Enabled: false
530
535
 
531
- Lint/UnneededDisable:
536
+ Lint/UnneededCopDisableDirective:
532
537
  Description: >-
533
538
  Checks for rubocop:disable comments that can be removed.
534
539
  Note: this cop is not disabled when disabling all cops.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 0.4.0 (2018-12-15)
2
+
3
+ Features:
4
+ - Add new interface to remove a user's space
5
+ - Add an interface to disconnect a connection
6
+ - Interface to create & download file version
7
+
8
+ Fixes:
9
+ - Fix the unknown file upload related issues
10
+
11
+ ## 0.3.2 (2018-06-28)
12
+
13
+ Features:
14
+ - Add interface for calendar event resources
15
+ - Add interface for space category, file icon
16
+ - Add interface to fetch file version and etc.
17
+
18
+ Fixes:
19
+ - Fix file upload related error
20
+
1
21
  ## 0.2.0 (2017-11-30)
2
22
 
3
23
  Features:
data/README.md CHANGED
@@ -231,6 +231,12 @@ Ribose::SpaceFile.all(space_id, options)
231
231
  Ribose::SpaceFile.fetch(space_id, file_id, options = {})
232
232
  ```
233
233
 
234
+ #### Fetch a file icon
235
+
236
+ ```ruby
237
+ Ribose::SpaceFile.fetch_icon(space_id, file_id, options = {})
238
+ ```
239
+
234
240
  #### Create a file upload
235
241
 
236
242
  ```ruby
@@ -249,6 +255,28 @@ Ribose::SpaceFile.update(space_id, file_id, new_file_attributes = {})
249
255
  Ribose::SpaceFile.delete(space_id, file_id)
250
256
  ```
251
257
 
258
+ ### File Version
259
+
260
+ #### Fetch file version
261
+
262
+ ```ruby
263
+ Ribose::FileVersion.fetch(
264
+ space_id: space_id, file_id: file_id, version_id: version_id
265
+ )
266
+ ```
267
+
268
+ #### Create a new file version
269
+
270
+ ```ruby
271
+ Ribose::FileVersion.create(
272
+ space_id: your_space_id,
273
+ file_id: existing_file_id_in_space,
274
+ file: file_path_for_the_new_version,
275
+
276
+ **any_other_additional_attributes
277
+ )
278
+ ```
279
+
252
280
  ### Conversations
253
281
 
254
282
  #### Listing Space Conversations
@@ -283,6 +311,12 @@ Ribose::Conversation.update(space_id, conversation_id, new_attributes_hash)
283
311
  Ribose::Conversation.destroy(space_id: "space_id", conversation_id: "12345")
284
312
  ```
285
313
 
314
+ #### Mark a conversation as favorite
315
+
316
+ ```ruby
317
+ Ribose::Conversation.mark_as_favorite(space_id, conversation_id)
318
+ ```
319
+
286
320
  ### Message
287
321
 
288
322
  #### List Conversation Messages
@@ -373,6 +407,16 @@ and it will return the connection as `Sawyer::Resource`.
373
407
  Ribose::Connection.all
374
408
  ```
375
409
 
410
+ #### Disconnect a connection
411
+
412
+ To disconnect with an existing connection, we can use `Connection.disconnect`
413
+ interface as following. This expect us to provide the connection id, and it also
414
+ support an additional options hash to provide custom options.
415
+
416
+ ```ruby
417
+ Ribose::Connection.disconnect(connection_id, options)
418
+ ```
419
+
376
420
  #### Connection suggestions
377
421
 
378
422
  To retrieve the list of user connection suggestions,
@@ -556,6 +600,53 @@ Ribose::Calendar.create(
556
600
  Ribose::Calendar.delete(calendar_id)
557
601
  ```
558
602
 
603
+ ### Event
604
+
605
+ #### List calendar events
606
+
607
+ ```ruby
608
+ Ribose::Event.all(calendar_id)
609
+ ```
610
+
611
+ #### Fetch a calendar event
612
+
613
+ ```ruby
614
+ Ribose::Event.fetch(calendar_id, event_id)
615
+ ```
616
+
617
+ #### Create a calendar event
618
+
619
+ ```ruby
620
+ Ribose::Event.create(
621
+ calendar_id,
622
+ name: "Sample Event",
623
+ date_start: "04/04/2018",
624
+ time_start: "4:30pm",
625
+ date_finish: "04/04/2018",
626
+ time_finish: "5:30pm",
627
+ recurring_type: "not_repeat",
628
+ until: "never",
629
+ repeat_every: "1",
630
+ where: "Skype",
631
+ description: "Sample event",
632
+ all_day: false,
633
+ )
634
+ ```
635
+
636
+ #### Update a calendar event
637
+
638
+ ```ruby
639
+ Ribose::Event.update(
640
+ calendar_id, event_id, new_attributes_hash, options_params
641
+ )
642
+ ```
643
+
644
+ #### Delete a calendar event
645
+
646
+ ```ruby
647
+ Ribose::Event.delete(calendar_id, event_id)
648
+ ```
649
+
559
650
  ### User
560
651
 
561
652
  #### Create a signup request
@@ -610,6 +701,14 @@ Ribose::Wiki.update(
610
701
  Ribose::Wiki.delete(space_id, wiki_id)
611
702
  ```
612
703
 
704
+ ### Space categories
705
+
706
+ #### List space categories
707
+
708
+ ```ruby
709
+ Ribose::SpaceCategory.all
710
+ ```
711
+
613
712
  ## Development
614
713
 
615
714
  We are following Sandi Metz's Rules for this gem, you can read the
@@ -6,7 +6,8 @@ module Ribose
6
6
  extend Ribose::Actions::Base
7
7
 
8
8
  def create
9
- create_resource[resource]
9
+ response = create_resource
10
+ response[resource] || response
10
11
  end
11
12
 
12
13
  private
@@ -9,7 +9,8 @@ module Ribose
9
9
  #
10
10
  # @return [Sawyer::Resource] Update resource response
11
11
  def update
12
- update_resource[resource]
12
+ response = update_resource
13
+ response[resource] || response
13
14
  end
14
15
 
15
16
  private
@@ -14,14 +14,14 @@ module Ribose
14
14
  # @params length [Integer] How many days to fetch
15
15
  # @return [Sawyer::Resource] The calendar events
16
16
  #
17
- def self.fetch(calendar_ids, start: Date.today, length: 7)
17
+ def self.fetch(calendar_ids, start: Date.today, length: 7, **others)
18
18
  query = {
19
19
  length: length,
20
20
  cal_ids: Ribose.encode_ids(calendar_ids),
21
21
  start: start.to_time.to_i / (60 * 60 * 24),
22
22
  }
23
23
 
24
- super(nil, query: query)
24
+ super(nil, query: others.merge(query))
25
25
  end
26
26
 
27
27
  private
data/lib/ribose/client.rb CHANGED
@@ -1,25 +1,43 @@
1
1
  module Ribose
2
2
  class Client
3
- attr_reader :api_token, :user_email
3
+ attr_accessor :api_token, :api_email, :user_email,
4
+ :client_id, :uid, :access_token
4
5
 
5
6
  def initialize(options = {})
6
- @api_token = options.fetch(:token, configuration.api_token).to_s
7
- @user_email = options.fetch(:email, configuration.user_email).to_s
7
+ @api_token = options.fetch(:api_token, configuration.api_token).to_s
8
+ @api_email = options.fetch(:api_email, configuration.api_email).to_s
9
+ @client_id = options[:client_id]
10
+ @uid = options[:uid]
11
+ @access_token = options[:access_token]
8
12
  end
9
13
 
10
14
  # Initiate a ribose client
11
15
  #
12
- # This interface takes email and password and then it will
13
- # do all the underlying work to find out the authentication
14
- # token and retrun a ribose client.
16
+ # This interface takes email, password, api_email and api_token
17
+ # Then it will do all the underlying work to find out client id and uid
18
+ # Finally it will return a ribose client.
15
19
  #
16
20
  # @param :email [String] The email for your Ribose account
17
21
  # @param :password [String] The password for your account
22
+ # @param :api_email [String] The email for your API account
23
+ # @param :api_token [String] The authentication token for your API account
18
24
  # @return [Ribose::Client] A new client with your details
19
25
  #
20
- def self.from_login(email:, password:)
21
- session = Session.create(username: email, password: password)
22
- new(email: email, token: session["authentication_token"])
26
+ def self.from_login(email:, password:, api_email:, api_token:)
27
+ session = Session.create(
28
+ username: email,
29
+ password: password,
30
+ api_email: api_email,
31
+ api_token: api_token
32
+ )
33
+
34
+ new(
35
+ api_email: api_email,
36
+ api_token: api_token,
37
+ client_id: session.nil? ? nil : session['client'],
38
+ uid: session.nil? ? nil : session['uid'],
39
+ access_token: session.nil? ? nil : session['access-token'],
40
+ )
23
41
  end
24
42
 
25
43
  private
@@ -2,20 +2,29 @@ require "ribose/response/raise_error"
2
2
 
3
3
  module Ribose
4
4
  class Configuration
5
- attr_accessor :api_host, :api_token, :user_email, :debug_mode
5
+ attr_accessor :api_host, :api_email, :api_token,
6
+ :user_email, :user_password,
7
+ :verify_ssl,
8
+ :debug_mode
6
9
 
7
10
  def initialize
8
11
  @debug_mode = false
9
- @api_host ||= "www.ribose.com"
12
+ @verify_ssl = true
13
+ @api_host ||= "https://www.ribose.com"
10
14
  end
11
15
 
12
16
  def debug_mode?
13
17
  debug_mode == true
14
18
  end
15
19
 
16
- def web_url
17
- ["https", api_host].join("://")
20
+ def verify_ssl?
21
+ !!verify_ssl
18
22
  end
23
+
24
+ def ssl_verification_mode
25
+ verify_ssl? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
26
+ end
27
+
19
28
  def add_default_middleware(builder)
20
29
  builder.use(Ribose::Response::RaiseError)
21
30
  builder.response(:logger, nil, bodies: true) if debug_mode?
@@ -1,6 +1,7 @@
1
1
  module Ribose
2
2
  class Connection < Ribose::Base
3
3
  include Ribose::Actions::All
4
+ include Ribose::Actions::Delete
4
5
 
5
6
  # List Connections
6
7
  #
@@ -26,6 +27,20 @@ module Ribose
26
27
  suggested_connection
27
28
  end
28
29
 
30
+ # Disconnect
31
+ #
32
+ # Disconnect connection / contact with the provided
33
+ # connection id. This will return nothing for successful
34
+ # request, but if disconnect fails then it will raise an
35
+ # Error for the client.
36
+ #
37
+ # @params resource_id [Integer] Connection Id
38
+ # @return nil
39
+ #
40
+ def self.disconnect(resource_id, options = {})
41
+ delete(resource_id, options)
42
+ end
43
+
29
44
  private
30
45
 
31
46
  def resource
@@ -62,6 +62,24 @@ module Ribose
62
62
  new(space_id: space_id, conversation_id: conversation_id, **opts).delete
63
63
  end
64
64
 
65
+ def mark_as_favorite
66
+ response = Ribose::Request.put(
67
+ "#{resource_path}/mark_as_favorite",
68
+ resource_key.to_sym => { is_favorite: true },
69
+ )
70
+
71
+ response[resource]
72
+ end
73
+
74
+ # Mark a conversation a favorite
75
+ #
76
+ # @param space_id [String] The Space UUID
77
+ # @param conversation_id [String] Conversation UUID
78
+ #
79
+ def self.mark_as_favorite(space_id, conversation_id)
80
+ new(space_id: space_id, conversation_id: conversation_id).mark_as_favorite
81
+ end
82
+
65
83
  private
66
84
 
67
85
  attr_reader :space_id, :conversation_id
@@ -0,0 +1,86 @@
1
+ module Ribose
2
+ class Event < Ribose::Base
3
+ include Ribose::Actions::Fetch
4
+ include Ribose::Actions::Create
5
+ include Ribose::Actions::Update
6
+ include Ribose::Actions::Delete
7
+
8
+ # List calendar events
9
+ #
10
+ # @params calendar_id [Integer] Calendar Ids
11
+ # @params options [Hash] The options parameters
12
+ # @return [Sawyer::Resource] Calendar Events
13
+ #
14
+ def self.all(calendar_id, options = {})
15
+ Ribose::Calendar.fetch(calendar_id, options)
16
+ end
17
+
18
+ # Fetch a calendar event
19
+ #
20
+ # @params calendar_id - The calendar ID
21
+ # @params event_id - The calendar event ID
22
+ # @return [Sawyer::Resource] Event details
23
+ #
24
+ def self.fetch(calendar_id, event_id, options = {})
25
+ new(options.merge(calendar_id: calendar_id, resource_id: event_id)).fetch
26
+ end
27
+
28
+ # Create a calendar event
29
+ #
30
+ # @params calendar_id - The calendar Id
31
+ # @attributes [Hash] - New Event attributes
32
+ # @return [Sawyer::Resource] The new event
33
+ #
34
+ def self.create(calendar_id, attrs, options = {})
35
+ new(options.merge(calendar_id: calendar_id, **attrs)).create["events"]
36
+ end
37
+
38
+ # Update a calendar event
39
+ #
40
+ # @params calendar_id [Integer] The calendar Id
41
+ # @params event_id [Integer] The calendar event Id
42
+ # @params attributes [Hash] New attributes for event
43
+ # @params options [Hash] The additional query params
44
+ #
45
+ def self.update(calendar_id, event_id, attributes, options = {})
46
+ new(options.merge(
47
+ calendar_id: calendar_id, resource_id: event_id, **attributes,
48
+ )).update["events"]
49
+ end
50
+
51
+ # Delete a calendar event
52
+ #
53
+ # @params calendar_id The calendar Id
54
+ # @params event_id The calendar event Id
55
+ # @params options [Hash] The query params
56
+ #
57
+ def self.delete(calendar_id, event_id, options = {})
58
+ new(options.merge(calendar_id: calendar_id, resource_id: event_id)).delete
59
+ end
60
+
61
+ private
62
+
63
+ attr_reader :calendar_id
64
+
65
+ def resource
66
+ "event"
67
+ end
68
+
69
+ def validate(date_start:, date_finish:, time_start:, time_finish:, **others)
70
+ others.merge(
71
+ date_start: date_start,
72
+ time_start: time_start,
73
+ date_finish: date_finish,
74
+ time_finish: time_finish,
75
+ )
76
+ end
77
+
78
+ def extract_local_attributes
79
+ @calendar_id = attributes.delete(:calendar_id)
80
+ end
81
+
82
+ def resources_path
83
+ "calendar/calendar/#{calendar_id}/event"
84
+ end
85
+ end
86
+ end
@@ -1,4 +1,6 @@
1
+ require "json"
1
2
  require "faraday"
3
+ require "ostruct"
2
4
 
3
5
  module Ribose
4
6
  class FileUploader
@@ -49,7 +51,10 @@ module Ribose
49
51
 
50
52
  def notify_ribose_file_upload_endpoint(response, key)
51
53
  if response.status.to_i == 200
52
- Ribose::Request.post(space_file_path, file_attributes.merge(key: key))
54
+ attributes = notifiable_attributes(file_attributes, key)
55
+
56
+ content = Request.post(space_file_path, attributes)
57
+ content.is_a?(Sawyer::Resource) ? content : parse_to_ribose_os(content)
53
58
  end
54
59
  end
55
60
 
@@ -67,7 +72,16 @@ module Ribose
67
72
 
68
73
  def content_type_form_file
69
74
  require "mime/types"
70
- MIME::Types.type_for(file.path).first.content_type
75
+ mime = MIME::Types.type_for(file.path).first
76
+ mime ? mime.content_type : "application/octet-stream"
77
+ end
78
+
79
+ def parse_to_ribose_os(content)
80
+ JSON.parse(content, object_class: Ribose::OpenStruct)
81
+ end
82
+
83
+ def notifiable_attributes(attributes, key)
84
+ attributes.merge(key: key)
71
85
  end
72
86
 
73
87
  def file_attributes
@@ -90,4 +104,8 @@ module Ribose
90
104
  end
91
105
  end
92
106
  end
107
+
108
+ class OpenStruct < ::OpenStruct
109
+ alias :read_attribute_for_serialization :send
110
+ end
93
111
  end
@@ -0,0 +1,97 @@
1
+ require "ribose/version_uploader"
2
+
3
+ module Ribose
4
+ class FileVersion < Ribose::Base
5
+ include Ribose::Actions::Fetch
6
+
7
+ def download
8
+ download_file || raise(Ribose::BadRequest)
9
+ end
10
+
11
+ # Fetch file version
12
+ #
13
+ # @params :space_id [UUID] The space Id
14
+ # @params :file_id [UUID] The space file Id
15
+ # @params :version_id [UUID] The file version Id
16
+ # @returns [Sawyer::Resource] The file version
17
+ #
18
+ def self.fetch(space_id:, file_id:, version_id:, **options)
19
+ new(
20
+ file_id: file_id,
21
+ space_id: space_id,
22
+ resource_id: version_id,
23
+ **options,
24
+ ).fetch
25
+ end
26
+
27
+ # Download file version
28
+ #
29
+ # @param space_id [UUID] The space Id
30
+ # @param file_id [Integer] The file Id
31
+ # @param version_id [Hash] The file version Id
32
+ # @param options [Hash] Options as key and value pair
33
+ #
34
+ def self.download(space_id, file_id, version_id:, **options)
35
+ new(
36
+ file_id: file_id,
37
+ space_id: space_id,
38
+ resource_id: version_id,
39
+ **options,
40
+ ).download
41
+ end
42
+
43
+ # Create a new file version
44
+ #
45
+ # @params space_id [UUID] The space UUID
46
+ # @params file_id [Integer] The space file ID
47
+ # @params file [File] The new version for file
48
+ # @params attributes [Hash] Other file attributes
49
+ # @return [Sawyer::Resource] Newly updated version
50
+ #
51
+ def self.create(space_id, file_id, file:, **attributes)
52
+ upload = VersionUploader.upload(
53
+ space_id, file_id, attributes.merge(file: file)
54
+ )
55
+
56
+ upload[:attachment]
57
+ end
58
+
59
+ private
60
+
61
+ attr_reader :output, :file_id, :space_id
62
+
63
+ def resource
64
+ nil
65
+ end
66
+
67
+ def extract_local_attributes
68
+ @output = attributes.delete(:output)
69
+ @file_id = attributes.delete(:file_id)
70
+ @space_id = attributes.delete(:space_id)
71
+ end
72
+
73
+ def resource_path
74
+ [files_path, file_id, "versions", resource_id].join("/")
75
+ end
76
+
77
+ def files_path
78
+ ["spaces", space_id, "file", "files"].join("/")
79
+ end
80
+
81
+ def download_file
82
+ data = Ribose::Request.get(
83
+ resource_path, parse: false, headers: { accept: "text/html" }
84
+ )
85
+
86
+ if data.headers["status"].match?(/^30[12]/)
87
+ fetch_and_write_to_file(data)
88
+ end
89
+ end
90
+
91
+ def fetch_and_write_to_file(data)
92
+ File.open(output || "download", "w") do |file|
93
+ file << data.agent.call(:get, data.headers["location"]).data
94
+ end
95
+ end
96
+ end
97
+ end