sony-ci-api 0.0.2 → 0.1.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
2
  SHA1:
3
- metadata.gz: 78ddca4a90c4040cd7dd9061255f8093be1f6ad0
4
- data.tar.gz: 7dc66ce63747e28bba420c2002a8ee521559060c
3
+ metadata.gz: c344e4f79a93bc0fab03b439d9279c3a49a4710d
4
+ data.tar.gz: 8071312023cf6bb2652931f383c431888a11401e
5
5
  SHA512:
6
- metadata.gz: cb0604d3a6b3b1dabafc68c8ea32637b5855fcc9bd747e1eb2d4ef5c02c826100160c983432f09df973aa7533d183173483fe6cf7779f7318046dbefaf39fd49
7
- data.tar.gz: d037bef8500d5b8f45f6e9f363306ee4871ce295a9e38e260a132861352368040183a4a4e7395a4bfbd30b825d86487f9e75b9cf56a90b437487c1e2da3c4bb6
6
+ metadata.gz: bc671a8b8b8c98a98d06b32cd15715e687cf97b6c3210d02fae851f27d722f2812fb4831cc94769ab8fdf971c65cc71707945ebc02facd6577c33e1881d165f8
7
+ data.tar.gz: 626375b4070d753c6a3239f09905d5d185f871234159304e2d7ca83d3af1d3e171b8728949e26361dc5ea6f0408239a2192aaacd34665e9edcf232411c6cf5f2
data/bin/sony-ci-api CHANGED
@@ -10,7 +10,7 @@ end
10
10
 
11
11
  ci = SonyCiAdmin.new(
12
12
  # verbose: true,
13
- credentials_path: 'ci.yml')
13
+ credentials_path: 'config/ci.yml')
14
14
 
15
15
  begin
16
16
  case args.keys.sort
data/lib/sony-ci-api.rb CHANGED
@@ -1,2 +1,4 @@
1
- require_relative 'sony-ci-api/sony_ci_basic'
2
1
  require_relative 'sony-ci-api/sony_ci_admin'
2
+ # Nothing else: The outside world doesn't need to worry
3
+ # about the particular classes which are required, and
4
+ # sony_ci_admin.rb loads its own dependencies.
@@ -38,48 +38,34 @@ class SonyCiAdmin < SonyCiBasic
38
38
  Detailer.new(self).detail(asset_id)
39
39
  end
40
40
 
41
- class CiClient #:nodoc:
42
- # This class hierarchy might be excessive, but it gives us:
43
- # - a single place for the `perform` method
44
- # - and an isolated container for related private methods
45
-
46
- def perform(curl, mime=nil)
47
- # TODO: Is this actually working?
48
- # curl.on_missing { |data| puts "4xx: #{data}" }
49
- # curl.on_failure { |data| puts "5xx: #{data}" }
50
- curl.verbose = @ci.verbose
51
- curl.headers['Authorization'] = "Bearer #{@ci.access_token}"
52
- curl.headers['Content-Type'] = mime if mime
53
- curl.perform
54
- end
55
- end
56
-
57
- class Detailer < CiClient #:nodoc:
41
+ class Detailer < SonyCiClient #:nodoc:
58
42
  def initialize(ci)
59
43
  @ci = ci
60
44
  end
61
45
 
62
46
  def detail(asset_id)
63
47
  curl = Curl::Easy.http_get('https:'"//api.cimediacloud.com/assets/#{asset_id}") do |c|
64
- perform(c)
48
+ add_headers(c)
65
49
  end
50
+ handle_errors(curl)
66
51
  JSON.parse(curl.body_str)
67
52
  end
68
53
  end
69
54
 
70
- class Deleter < CiClient #:nodoc:
55
+ class Deleter < SonyCiClient #:nodoc:
71
56
  def initialize(ci)
72
57
  @ci = ci
73
58
  end
74
59
 
75
60
  def delete(asset_id)
76
- Curl::Easy.http_delete('https:'"//api.cimediacloud.com/assets/#{asset_id}") do |c|
77
- perform(c)
61
+ curl = Curl::Easy.http_delete('https:'"//api.cimediacloud.com/assets/#{asset_id}") do |c|
62
+ add_headers(c)
78
63
  end
64
+ handle_errors(curl)
79
65
  end
80
66
  end
81
67
 
82
- class Lister < CiClient #:nodoc:
68
+ class Lister < SonyCiClient #:nodoc:
83
69
  include Enumerable
84
70
 
85
71
  def initialize(ci)
@@ -89,8 +75,9 @@ class SonyCiAdmin < SonyCiBasic
89
75
  def list(limit, offset)
90
76
  curl = Curl::Easy.http_get('https:''//api.cimediacloud.com/workspaces/' \
91
77
  "#{@ci.workspace_id}/contents?limit=#{limit}&offset=#{offset}") do |c|
92
- perform(c)
78
+ add_headers(c)
93
79
  end
80
+ handle_errors(curl)
94
81
  JSON.parse(curl.body_str)['items']
95
82
  end
96
83
 
@@ -106,7 +93,7 @@ class SonyCiAdmin < SonyCiBasic
106
93
  end
107
94
  end
108
95
 
109
- class Uploader < CiClient #:nodoc:
96
+ class Uploader < SonyCiClient #:nodoc:
110
97
  def initialize(ci, path, log_path)
111
98
  @ci = ci
112
99
  @path = path
@@ -115,9 +102,12 @@ class SonyCiAdmin < SonyCiBasic
115
102
 
116
103
  def upload
117
104
  file = File.new(@path)
118
- if file.size > 5 * 1024 * 1024
105
+ if file.size >= 5 * 1024 * 1024
119
106
  initiate_multipart_upload(file)
120
- do_multipart_upload_part(file)
107
+ part = 0
108
+ while part do
109
+ part = do_multipart_upload_part(file, part)
110
+ end
121
111
  complete_multipart_upload
122
112
  else
123
113
  singlepart_upload(file)
@@ -137,22 +127,16 @@ class SonyCiAdmin < SonyCiBasic
137
127
  MULTIPART_URI = 'https://io.cimediacloud.com/upload/multipart'
138
128
 
139
129
  def singlepart_upload(file)
140
- curl = "curl -s -XPOST '#{SINGLEPART_URI}'" \
141
- " -H 'Authorization: Bearer #{@ci.access_token}'" \
142
- " -F filename='@#{file.path}'" \
143
- " -F metadata=\"{'workspaceId': '#{@ci.workspace_id}'}\""
144
- body_str = `#{curl}`
145
- @asset_id = JSON.parse(body_str)['assetId']
146
- fail "Upload failed: #{body_str}" unless @asset_id
147
- # TODO: This shouldn't be hard, but it just hasn't worked for me.
148
- # params = {
149
- # File.basename(file) => file.read,
150
- # 'metadata' => JSON.generate({})
151
- # }.map { |k,v| Curl::PostField.content(k,v) }
152
- # curl = Curl::Easy.http_post(SINGLEPART_URI, params) do |c|
153
- # c.multipart_form_post = true
154
- # perform(c)
155
- # end
130
+ params = [
131
+ Curl::PostField.file('filename', file.path, File.basename(file.path)),
132
+ Curl::PostField.content('metadata', JSON.generate('workspaceId' => @ci.workspace_id))
133
+ ]
134
+ curl = Curl::Easy.http_post(SINGLEPART_URI, params) do |c|
135
+ c.multipart_form_post = true
136
+ add_headers(c)
137
+ end
138
+ handle_errors(curl)
139
+ @asset_id = JSON.parse(curl.body_str)['assetId']
156
140
  end
157
141
 
158
142
  def initiate_multipart_upload(file)
@@ -160,21 +144,29 @@ class SonyCiAdmin < SonyCiBasic
160
144
  'size' => file.size,
161
145
  'workspaceId' => @ci.workspace_id)
162
146
  curl = Curl::Easy.http_post(MULTIPART_URI, params) do |c|
163
- perform(c, 'application/json')
147
+ add_headers(c, 'application/json')
164
148
  end
149
+ handle_errors(curl)
165
150
  @asset_id = JSON.parse(curl.body_str)['assetId']
166
151
  end
167
152
 
168
- def do_multipart_upload_part(file)
169
- Curl::Easy.http_put("#{MULTIPART_URI}/#{@asset_id}/1", file.read) do |c|
170
- perform(c, 'application/octet-stream')
153
+ CHUNK_SIZE = 10 * 1024 * 1024
154
+
155
+ def do_multipart_upload_part(file, part)
156
+ fragment = file.read(CHUNK_SIZE)
157
+ return unless fragment
158
+ curl = Curl::Easy.http_put("#{MULTIPART_URI}/#{@asset_id}/#{part + 1}", fragment) do |c|
159
+ add_headers(c, 'application/octet-stream')
171
160
  end
161
+ handle_errors(curl)
162
+ return part + 1
172
163
  end
173
164
 
174
165
  def complete_multipart_upload
175
- Curl::Easy.http_post("#{MULTIPART_URI}/#{@asset_id}/complete") do |c|
176
- perform(c)
166
+ curl = Curl::Easy.http_post("#{MULTIPART_URI}/#{@asset_id}/complete") do |c|
167
+ add_headers(c)
177
168
  end
169
+ handle_errors(curl)
178
170
  end
179
171
  end
180
172
  end
@@ -1,6 +1,7 @@
1
1
  require 'yaml'
2
2
  require 'curb'
3
3
  require 'json'
4
+ require_relative 'sony_ci_client'
4
5
 
5
6
  class SonyCiBasic
6
7
  attr_reader :access_token
@@ -36,7 +37,6 @@ class SonyCiBasic
36
37
  c.password = credentials['password']
37
38
  # c.on_missing { |curl, data| puts "4xx: #{data}" }
38
39
  # c.on_failure { |curl, data| puts "5xx: #{data}" }
39
- c.perform
40
40
  end
41
41
 
42
42
  @access_token = JSON.parse(curl.body_str)['access_token']
@@ -50,23 +50,7 @@ class SonyCiBasic
50
50
  Downloader.new(self).download(asset_id)
51
51
  end
52
52
 
53
- class CiClient #:nodoc:
54
- # This class hierarchy might be excessive, but it gives us:
55
- # - a single place for the `perform` method
56
- # - and an isolated container for related private methods
57
-
58
- def perform(curl, mime=nil)
59
- # TODO: Is this actually working?
60
- # curl.on_missing { |data| puts "4xx: #{data}" }
61
- # curl.on_failure { |data| puts "5xx: #{data}" }
62
- curl.verbose = @ci.verbose
63
- curl.headers['Authorization'] = "Bearer #{@ci.access_token}"
64
- curl.headers['Content-Type'] = mime if mime
65
- curl.perform
66
- end
67
- end
68
-
69
- class Downloader < CiClient #:nodoc:
53
+ class Downloader < SonyCiClient #:nodoc:
70
54
  @@cache = {}
71
55
 
72
56
  def initialize(ci)
@@ -76,9 +60,11 @@ class SonyCiBasic
76
60
  def download(asset_id)
77
61
  hit = @@cache[asset_id]
78
62
  if !hit || hit[:expires] < Time.now
63
+
79
64
  curl = Curl::Easy.http_get('https'"://api.cimediacloud.com/assets/#{asset_id}/download") do |c|
80
- perform(c)
65
+ add_headers(c)
81
66
  end
67
+ handle_errors(curl)
82
68
  url = JSON.parse(curl.body_str)['location']
83
69
  @@cache[asset_id] = { url: url, expires: Time.now + 3 * 60 * 60 }
84
70
  end
@@ -0,0 +1,14 @@
1
+ class SonyCiClient #:nodoc:
2
+ def add_headers(curl, mime=nil)
3
+ # on_missing and on_failure exist...
4
+ # but any exceptions are caught and turned into warnings:
5
+ # You need to check the response code at the end
6
+ # if you want the execution path to change.
7
+ curl.verbose = @ci.verbose
8
+ curl.headers['Authorization'] = "Bearer #{@ci.access_token}"
9
+ curl.headers['Content-Type'] = mime if mime
10
+ end
11
+ def handle_errors(curl)
12
+ raise "#{curl.status}: #{curl.url}" if curl.response_code.to_s !~ /^2../
13
+ end
14
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sony-ci-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck McCallum
@@ -21,6 +21,7 @@ files:
21
21
  - lib/sony-ci-api.rb
22
22
  - lib/sony-ci-api/sony_ci_admin.rb
23
23
  - lib/sony-ci-api/sony_ci_basic.rb
24
+ - lib/sony-ci-api/sony_ci_client.rb
24
25
  homepage: https://github.com/WGBH/sony-ci-api
25
26
  licenses:
26
27
  - MIT