ribose 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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