ribose 0.3.2 → 0.4.0

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
- SHA256:
3
- metadata.gz: c12513b80d2e78ad9faf2e3c64de85c0943ac3ba3b9ea7e048820e3fd35564eb
4
- data.tar.gz: 373f583f12f65efb0ab2f76f6123d9f140c52e25fffd557718f0165b8bbff1f2
2
+ SHA1:
3
+ metadata.gz: e18f5e392f562d3757a8dffaf903af1f63c2f8d0
4
+ data.tar.gz: bcef222cf96830b6d150ead2571d31607f06b4d0
5
5
  SHA512:
6
- metadata.gz: 734153a69502c7a0ffde70a561d9ba7842c5654c5f0cfde03267799a3a9dd2d0c0311382cab689135c87cfb28ca0349a6d4642abca7bac1786906e007af6b5f9
7
- data.tar.gz: 578bab38e786870468f9a22c71785e819d06ee46e94fe050ea65e0aed1083abd96558bea5189939b9d64ffde608c5b19aa7303f7b697c17eb070b340d76069b6
6
+ metadata.gz: 49235eefd2aa174afc2eb97febd0d5fb34b5832aa016665c37e17f6d52ff3a02ee29e352e287e623f9f2074b5176bb41488508e90ab47bb5cab0e3b531d22303
7
+ data.tar.gz: c85dc140fa9b23184aa77d6ef9334e59afe0286ad23f5b85417746ad70b78958fe0591ce3b0d6a9712ccab40e3f79babf8e3891d7f3fd87100a17fc681cf18ea
@@ -1,3 +1,13 @@
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
+
1
11
  ## 0.3.2 (2018-06-28)
2
12
 
3
13
  Features:
data/README.md CHANGED
@@ -265,6 +265,18 @@ Ribose::FileVersion.fetch(
265
265
  )
266
266
  ```
267
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
+
268
280
  ### Conversations
269
281
 
270
282
  #### Listing Space Conversations
@@ -395,6 +407,16 @@ and it will return the connection as `Sawyer::Resource`.
395
407
  Ribose::Connection.all
396
408
  ```
397
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
+
398
420
  #### Connection suggestions
399
421
 
400
422
  To retrieve the list of user connection suggestions,
@@ -16,6 +16,7 @@ module Ribose
16
16
  def web_url
17
17
  ["https", api_host].join("://")
18
18
  end
19
+
19
20
  def add_default_middleware(builder)
20
21
  builder.use(Ribose::Response::RaiseError)
21
22
  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
@@ -51,7 +51,9 @@ module Ribose
51
51
 
52
52
  def notify_ribose_file_upload_endpoint(response, key)
53
53
  if response.status.to_i == 200
54
- content = 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)
55
57
  content.is_a?(Sawyer::Resource) ? content : parse_to_ribose_os(content)
56
58
  end
57
59
  end
@@ -70,13 +72,18 @@ module Ribose
70
72
 
71
73
  def content_type_form_file
72
74
  require "mime/types"
73
- 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"
74
77
  end
75
78
 
76
79
  def parse_to_ribose_os(content)
77
80
  JSON.parse(content, object_class: Ribose::OpenStruct)
78
81
  end
79
82
 
83
+ def notifiable_attributes(attributes, key)
84
+ attributes.merge(key: key)
85
+ end
86
+
80
87
  def file_attributes
81
88
  @file_attributes ||= {
82
89
  filesize: file.size,
@@ -1,7 +1,13 @@
1
+ require "ribose/version_uploader"
2
+
1
3
  module Ribose
2
4
  class FileVersion < Ribose::Base
3
5
  include Ribose::Actions::Fetch
4
6
 
7
+ def download
8
+ download_file || raise(Ribose::BadRequest)
9
+ end
10
+
5
11
  # Fetch file version
6
12
  #
7
13
  # @params :space_id [UUID] The space Id
@@ -18,15 +24,48 @@ module Ribose
18
24
  ).fetch
19
25
  end
20
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
+
21
59
  private
22
60
 
23
- attr_reader :file_id, :space_id
61
+ attr_reader :output, :file_id, :space_id
24
62
 
25
63
  def resource
26
64
  nil
27
65
  end
28
66
 
29
67
  def extract_local_attributes
68
+ @output = attributes.delete(:output)
30
69
  @file_id = attributes.delete(:file_id)
31
70
  @space_id = attributes.delete(:space_id)
32
71
  end
@@ -38,5 +77,21 @@ module Ribose
38
77
  def files_path
39
78
  ["spaces", space_id, "file", "files"].join("/")
40
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
41
96
  end
42
97
  end
@@ -20,8 +20,11 @@ module Ribose
20
20
  # @return [Sawyer::Resource]
21
21
  #
22
22
  def request(options = {})
23
+ parsable = extract_config_option(:parse) != false
23
24
  options[:query] = extract_config_option(:query) || {}
24
- agent.call(http_method, api_endpoint, data, options).data
25
+
26
+ response = agent.call(http_method, api_endpoint, data, options)
27
+ parsable == true ? response.data : response
25
28
  end
26
29
 
27
30
  # Make a HTTP GET Request
@@ -79,12 +82,15 @@ module Ribose
79
82
 
80
83
  def find_suitable_client
81
84
  client = extract_config_option(:client) || Ribose::Client.new
82
- client.is_a?(Ribose::Client) ? client: raise(Ribose::Unauthorized)
85
+ client.is_a?(Ribose::Client) ? client : raise(Ribose::Unauthorized)
83
86
  end
84
87
 
85
88
  def require_auth_headers?
86
- auth_header = extract_config_option(:auth_header)
87
- auth_header == false ? false : true
89
+ extract_config_option(:auth_header) != false
90
+ end
91
+
92
+ def custom_content_headers
93
+ extract_config_option(:headers) || {}
88
94
  end
89
95
 
90
96
  def api_endpoint
@@ -107,10 +113,17 @@ module Ribose
107
113
  end
108
114
  end
109
115
 
116
+ def set_content_type(headers)
117
+ header = custom_content_headers
118
+ default_type = "application/json"
119
+
120
+ headers[:content_type] = default_type
121
+ headers[:accept] = header.fetch(:accept, default_type)
122
+ end
123
+
110
124
  def agent
111
125
  @agent ||= Sawyer::Agent.new(ribose_host, sawyer_options) do |http|
112
- http.headers[:accept] = "application/json"
113
- http.headers[:content_type] = "application/json"
126
+ set_content_type(http.headers)
114
127
 
115
128
  if require_auth_headers?
116
129
  http.headers["X-Indigo-Token"] = client.api_token
@@ -15,6 +15,10 @@ module Ribose
15
15
  Ribose::Request.post("spaces/#{space_uuid}/freeze", options)
16
16
  end
17
17
 
18
+ def self.delete(space_uuid, confirmation:, **options)
19
+ remove(space_uuid, options.merge(password_confirmation: confirmation))
20
+ end
21
+
18
22
  private
19
23
 
20
24
  attr_reader :space
@@ -34,6 +34,21 @@ module Ribose
34
34
  new(space_id: space_id, resource_id: file_id, **options).fetch
35
35
  end
36
36
 
37
+ # Download a space file
38
+ #
39
+ # @param space_id [UUID] The Space UUID
40
+ # @param file_id [Integer] The File Id
41
+ # @param options [Hash] Options as key and value pair.
42
+ #
43
+ # Two important keys are :version_id, and :output and
44
+ # if these are provided then it will use those otherwise
45
+ # it will do additional request to retirve those details
46
+ #
47
+ def self.download(space_id, file_id, options = {})
48
+ options[:version_id] ||= fetch(space_id, file_id).current_version_id
49
+ Ribose::FileVersion.download(space_id, file_id, **options)
50
+ end
51
+
37
52
  # Create a new file upload
38
53
  #
39
54
  # @param space_id [String] The Space UUID
@@ -1,3 +1,3 @@
1
1
  module Ribose
2
- VERSION = "0.3.2".freeze
2
+ VERSION = "0.4.0".freeze
3
3
  end
@@ -0,0 +1,27 @@
1
+ require "ribose/file_uploader"
2
+
3
+ module Ribose
4
+ class VersionUploader < Ribose::FileUploader
5
+ def initialize(space_id, file_id, file:, **attributes)
6
+ @file_id = file_id
7
+ super(space_id, file: file, **attributes)
8
+ end
9
+
10
+ def self.upload(space_id, file_id, file:, **attributes)
11
+ new(space_id, file_id, attributes.merge(file: file)).create
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :file_id
17
+
18
+ def notifiable_attributes(attributes, key)
19
+ attributes[:file_info_version] = attributes.delete(:file_info)
20
+ attributes.merge(key: key)
21
+ end
22
+
23
+ def space_file_path
24
+ ["spaces", space_id, "file", "files", file_id, "versions"].join("/")
25
+ end
26
+ end
27
+ end
@@ -23,4 +23,15 @@ RSpec.describe Ribose::Connection do
23
23
  expect(suggestions.first.name).to eq("Jennie Doe")
24
24
  end
25
25
  end
26
+
27
+ describe ".disconnect" do
28
+ it "disconnect with provided connection" do
29
+ connection_id = 123_456
30
+ stub_ribose_connection_delete_api(connection_id)
31
+
32
+ expect do
33
+ Ribose::Connection.disconnect(connection_id)
34
+ end.not_to raise_error
35
+ end
36
+ end
26
37
  end
@@ -14,11 +14,24 @@ RSpec.describe Ribose::FileUploader do
14
14
  expect(file_upload.attachment.content_type).to eq("image/png")
15
15
  end
16
16
  end
17
+
18
+ context "with unknown file type" do
19
+ it "creates a new upload as octet-stream" do
20
+ space_id = 123_456_789
21
+ attributes = file_attributes(File.join(Ribose.root, "Rakefile"))
22
+
23
+ stub_ribose_space_file_upload_api(space_id, attributes)
24
+ file_upload = Ribose::FileUploader.upload(space_id, attributes)
25
+
26
+ expect(file_upload.attachment.id).not_to be_nil
27
+ expect(file_upload.attachment.author).to eq("John Doe")
28
+ end
29
+ end
17
30
  end
18
31
 
19
- def file_attributes
32
+ def file_attributes(file = nil)
20
33
  {
21
- file: sample_fixture_file,
34
+ file: file || sample_fixture_file,
22
35
  tag_list: "sample, file, samplefile",
23
36
  description: "This is a sample file",
24
37
  }
@@ -17,4 +17,60 @@ RSpec.describe Ribose::FileVersion do
17
17
  expect(file_version.current_version_id).to eq(789012)
18
18
  end
19
19
  end
20
+
21
+ describe ".download" do
22
+ context "with version id specified" do
23
+ it "downloads the specific file version" do
24
+ file_id = 123_456
25
+ space_id = 456_789
26
+ version_id = 789_012
27
+
28
+ output_file = "./tmp/download"
29
+ content = "This is the content in the file"
30
+
31
+ stub_aws_file_version_download_api(content)
32
+ buffer = stub_file_write_to_io(output_file)
33
+ stub_ribose_file_version_download_api(space_id, file_id, version_id)
34
+
35
+ Ribose::FileVersion.download(
36
+ space_id, file_id, version_id: version_id, output: output_file
37
+ )
38
+
39
+ expect(buffer).to eq(content)
40
+ end
41
+ end
42
+ end
43
+
44
+ describe ".create" do
45
+ it "create a new file version" do
46
+ file_id = 123_456
47
+ space_id = 456_789
48
+
49
+ stub_ribose_space_file_upload_api(space_id, file_attributes, file_id)
50
+ file = Ribose::FileVersion.create(space_id, file_id, file_attributes)
51
+
52
+ expect(file.id).not_to be_nil
53
+ expect(file.author).to eq("John Doe")
54
+ expect(file.content_type).to eq("image/png")
55
+ end
56
+ end
57
+
58
+ def file_attributes
59
+ {
60
+ file: sample_fixture_file,
61
+ description: "Version 2.0",
62
+ tag_list: "tags for new version",
63
+ }
64
+ end
65
+
66
+ def sample_fixture_file
67
+ @sample_fixture_file ||= File.join(Ribose.root, "spec/fixtures/sample.png")
68
+ end
69
+
70
+ def stub_file_write_to_io(output_file)
71
+ buffer = StringIO.new
72
+ allow(File).to receive(:open).with(output_file, "w").and_yield(buffer)
73
+
74
+ buffer.string
75
+ end
20
76
  end
@@ -28,6 +28,37 @@ RSpec.describe Ribose::SpaceFile do
28
28
  end
29
29
  end
30
30
 
31
+ describe ".download" do
32
+ context "without specific version id" do
33
+ it "fetch version id and then downloads the file" do
34
+ file_id = 123_456_789
35
+ space_id = 456_789_012
36
+
37
+ allow(Ribose::FileVersion).to receive(:download)
38
+ stub_ribose_space_file_fetch_api(space_id, file_id)
39
+
40
+ Ribose::SpaceFile.download(space_id, file_id)
41
+
42
+ expect(Ribose::FileVersion).to have_received(:download).
43
+ with(space_id, file_id, version_id: 11559)
44
+ end
45
+ end
46
+
47
+ context "with specific version id" do
48
+ it "sends downlod message to the downloader" do
49
+ file_id = 123_456_789
50
+ space_id = 456_789_012
51
+ version_id = 123_456_789
52
+
53
+ allow(Ribose::FileVersion).to receive(:download)
54
+ Ribose::SpaceFile.download(space_id, file_id, version_id: version_id)
55
+
56
+ expect(Ribose::FileVersion).to have_received(:download).
57
+ with(space_id, file_id, version_id: version_id)
58
+ end
59
+ end
60
+ end
61
+
31
62
  describe ".create" do
32
63
  it "creates a new file with provided details" do
33
64
  space_id = 123_456_789
@@ -59,6 +59,17 @@ RSpec.describe Ribose::Space do
59
59
  end
60
60
  end
61
61
 
62
+ describe ".delete" do
63
+ it "deletes an existing space" do
64
+ space_id = 123_456_789
65
+ stub_ribose_space_remove_api(space_id, password_confirmation: 1234)
66
+
67
+ expect do
68
+ Ribose::Space.delete(space_id, confirmation: 1234)
69
+ end.not_to raise_error
70
+ end
71
+ end
72
+
62
73
  def space_attributes
63
74
  {
64
75
  access: "private",
@@ -30,6 +30,12 @@ module Ribose
30
30
  )
31
31
  end
32
32
 
33
+ def stub_ribose_space_delete_api(space_id, options = {})
34
+ stub_api_response(
35
+ :delete, "spaces/#{space_id}", data: options, filename: "empty"
36
+ )
37
+ end
38
+
33
39
  def stub_ribose_feed_api
34
40
  stub_api_response(:get, "feeds", filename: "feeds")
35
41
  end
@@ -220,6 +226,17 @@ module Ribose
220
226
  )
221
227
  end
222
228
 
229
+ def stub_ribose_file_version_download_api(sid, fid, vid)
230
+ version = ["spaces", sid, "file/files", fid, "versions", vid].join("/")
231
+ stub_request(:get, ribose_endpoint(version)).to_return(
232
+ headers: { location: "https://ribose-data.aws.com", status: 302 },
233
+ )
234
+ end
235
+
236
+ def stub_aws_file_version_download_api(content)
237
+ stub_request(:get, "https://ribose-data.aws.com").to_return(body: content)
238
+ end
239
+
223
240
  def stub_ribose_space_conversation_list(space_id)
224
241
  stub_api_response(
225
242
  :get, conversations_path(space_id), filename: "conversations"
@@ -310,6 +327,12 @@ module Ribose
310
327
  stub_api_response(:get, "people/connections?s=", filename: "connections")
311
328
  end
312
329
 
330
+ def stub_ribose_connection_delete_api(id)
331
+ stub_api_response(
332
+ :delete, ["people", "connections", id].join("/"), filename: "empty"
333
+ )
334
+ end
335
+
313
336
  def stub_ribose_suggestion_list_api
314
337
  stub_api_response(
315
338
  :get, "people_finding", filename: "connection_suggestion"
@@ -2,16 +2,16 @@ require "faraday"
2
2
 
3
3
  module Ribose
4
4
  module FileUploadStub
5
- def stub_ribose_space_file_upload_api(space_id, attributes)
5
+ def stub_ribose_space_file_upload_api(space_id, attributes, file_id = nil)
6
6
  stub_ribose_aws_s3_file_upload_api
7
- stub_ribose_file_prepare_api(space_id, attributes)
8
- stub_ribose_file_upload_notify_api(space_id, attributes)
7
+ stub_ribose_file_prepare_api(space_id, attributes, file_id)
8
+ stub_ribose_file_upload_notify_api(space_id, attributes, file_id)
9
9
  end
10
10
 
11
- def stub_ribose_file_prepare_api(space_id, attributes)
11
+ def stub_ribose_file_prepare_api(space_id, attributes, file_id = nil)
12
12
  stub_api_response(
13
13
  :get,
14
- ribose_prepare_endpoint(space_id, attributes),
14
+ ribose_prepare_endpoint(space_id, attributes, file_id),
15
15
  filename: "file_upload_prepared",
16
16
  )
17
17
  end
@@ -22,11 +22,11 @@ module Ribose
22
22
  to_return(response_with(filename: "empty", status: 200))
23
23
  end
24
24
 
25
- def stub_ribose_file_upload_notify_api(space_id, attributes)
25
+ def stub_ribose_file_upload_notify_api(space_id, attributes, file_id = nil)
26
26
  stub_api_response(
27
27
  :post,
28
- ribose_file_endpoint(space_id),
29
- data: build_notify_request_body(attributes),
28
+ ribose_file_endpoint(space_id, file_id),
29
+ data: build_notify_request_body(attributes, file_id),
30
30
  filename: "file_uploaded",
31
31
  content_type: "text/html",
32
32
  )
@@ -34,12 +34,14 @@ module Ribose
34
34
 
35
35
  private
36
36
 
37
- def ribose_file_endpoint(space_id)
38
- ["spaces", space_id, "file", "files"].join("/")
37
+ def ribose_file_endpoint(space_id, file_id = nil)
38
+ end_path = file_id ? "#{file_id}/versions" : nil
39
+ ["spaces", space_id, "file", "files", end_path].compact.join("/")
39
40
  end
40
41
 
41
- def ribose_prepare_endpoint(sid, attrs)
42
- [ribose_file_endpoint(sid), "prepare?#{prepare_params(attrs)}"].join("/")
42
+ def ribose_prepare_endpoint(sid, attrs, file_id = nil)
43
+ [ribose_file_endpoint(sid, file_id), "prepare?#{prepare_params(attrs)}"].
44
+ join("/")
43
45
  end
44
46
 
45
47
  def prepare_params(attributes)
@@ -50,16 +52,19 @@ module Ribose
50
52
  )
51
53
  end
52
54
 
53
- def build_notify_request_body(attributes)
55
+ def build_notify_request_body(attributes, file_id = nil)
56
+ file_info_key = file_id ? "file_info_version" : "file_info"
57
+
54
58
  extract_file_details(attributes).merge(
55
- file_info: extract_file_info(attributes),
59
+ file_info_key.to_sym => extract_file_info(attributes),
56
60
  key: "uploads/123456789/${filename}",
57
61
  )
58
62
  end
59
63
 
60
64
  def content_type_form_file(file)
61
65
  require "mime/types"
62
- MIME::Types.type_for(file).first.content_type
66
+ mime = MIME::Types.type_for(file).first
67
+ mime ? mime.content_type : "application/octet-stream"
63
68
  end
64
69
 
65
70
  def extract_file_details(attributes)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ribose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-29 00:00:00.000000000 Z
11
+ date: 2018-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: id_pack
@@ -199,6 +199,7 @@ files:
199
199
  - lib/ribose/stream.rb
200
200
  - lib/ribose/user.rb
201
201
  - lib/ribose/version.rb
202
+ - lib/ribose/version_uploader.rb
202
203
  - lib/ribose/widget.rb
203
204
  - lib/ribose/wiki.rb
204
205
  - ribose.gemspec
@@ -315,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
315
316
  version: '0'
316
317
  requirements: []
317
318
  rubyforge_project:
318
- rubygems_version: 2.7.7
319
+ rubygems_version: 2.6.8
319
320
  signing_key:
320
321
  specification_version: 4
321
322
  summary: The Ruby interface for Ribose API