x 0.15.2 → 0.15.4

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: 7cfab6bc6d2c061c2cbe6f9da48e613c369fd15b32e54a342524427c3c82fbb5
4
- data.tar.gz: 06bd2eb46de55e43248988e8ccd4bccb2fd1c96e3728184f1ad91447bfe8e06c
3
+ metadata.gz: 731556dfa3e6417d5e0ea9305d6a6b87cc87bd360d71277df0b3dd1c5c8400b5
4
+ data.tar.gz: a1170fee36003355b65fe7a6a2732eb750ab0681bae74539d3f1eb17bfd96f65
5
5
  SHA512:
6
- metadata.gz: '018190e33912b68cd56cf9fba8faffca851ec75b1e8201f6c20371388329c183be7d6a05ee189869d71e66d48b1eefc70ff3860eb8067914b6abe39f285d9b86'
7
- data.tar.gz: c80967cefb5eadee6894614ee70de27412cfda613db79d5f30d836f40df6cf02234d97d1db45b11ef38ee71faebc239908acb139e3d32fc927fbbb38de61e625
6
+ metadata.gz: ec96213eaf3a727ba153c9df7f4f92649b45d3089944d3c02bf6c56960a593845818b7e9e4c947b0317dc6ec4325c7563652d9bcebd911c677171ba1d397fd21
7
+ data.tar.gz: dc3d6fb361ec7de40ac47d065c3840dd4972f7a32ebb17ed3969b56fc6257272d82c66d035b298956ac1209548c54e46530c75dbea3d23b8ebcd341480670a41
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.15.4] - 2025-05-02
2
+ * Use dedicated endpoints for chunked media upload (d54d0d0)
3
+
4
+ ## [0.15.3] - 2025-04-24
5
+ * Add missing base64 dependency (3ca8512)
6
+ * Set binary read for media files to be uploaded (fd066e6)
7
+
1
8
  ## [0.15.2] - 2025-03-28
2
9
  * Use media_id instead of media_key to upload media (f1dd577)
3
10
 
@@ -30,7 +30,7 @@ module X
30
30
  media = init(client:, file_path:, media_type:, media_category:)
31
31
  chunk_size = chunk_size_mb * BYTES_PER_MB
32
32
  append(client:, file_paths: split(file_path, chunk_size), media:, media_type:, boundary:)
33
- client.post("media/upload?command=FINALIZE&media_id=#{media["id"]}")&.fetch("data")
33
+ client.post("media/upload/#{media["id"]}/finalize")&.fetch("data")
34
34
  end
35
35
 
36
36
  def await_processing(client:, media:)
@@ -77,24 +77,23 @@ module X
77
77
 
78
78
  def init(client:, file_path:, media_type:, media_category:)
79
79
  total_bytes = File.size(file_path)
80
- query = "command=INIT&media_type=#{media_type}&media_category=#{media_category}&total_bytes=#{total_bytes}"
81
- client.post("media/upload?#{query}")&.fetch("data")
80
+ data = {media_type:, media_category:, total_bytes:}.to_json
81
+ client.post("media/upload/initialize", data)&.fetch("data")
82
82
  end
83
83
 
84
84
  def append(client:, file_paths:, media:, media_type:, boundary: SecureRandom.hex)
85
85
  threads = file_paths.map.with_index do |file_path, index|
86
86
  Thread.new do
87
- upload_body = construct_upload_body(file_path:, media_type:, boundary:)
88
- query = "command=APPEND&media_id=#{media["id"]}&segment_index=#{index}"
87
+ upload_body = construct_upload_body(file_path:, media_type:, segment_index: index, boundary:)
89
88
  headers = {"Content-Type" => "multipart/form-data, boundary=#{boundary}"}
90
- upload_chunk(client:, query:, upload_body:, file_path:, headers:)
89
+ upload_chunk(client:, media_id: media["id"], upload_body:, file_path:, headers:)
91
90
  end
92
91
  end
93
92
  threads.each(&:join)
94
93
  end
95
94
 
96
- def upload_chunk(client:, query:, upload_body:, file_path:, headers: {})
97
- client.post("media/upload?#{query}", upload_body, headers:)
95
+ def upload_chunk(client:, media_id:, upload_body:, file_path:, headers: {})
96
+ client.post("media/upload/#{media_id}/append", upload_body, headers:)
98
97
  rescue NetworkError, ServerError
99
98
  retries ||= 0
100
99
  ((retries += 1) < MAX_RETRIES) ? retry : raise
@@ -108,11 +107,13 @@ module X
108
107
  Dir.delete(dirname) if Dir.empty?(dirname)
109
108
  end
110
109
 
111
- def construct_upload_body(file_path:, media_type:, boundary: SecureRandom.hex)
112
- "--#{boundary}\r\n" \
110
+ def construct_upload_body(file_path:, media_type:, segment_index: nil, boundary: SecureRandom.hex)
111
+ body = ""
112
+ body += "--#{boundary}\r\nContent-Disposition: form-data; name=\"segment_index\"\r\n\r\n#{segment_index}\r\n" if segment_index
113
+ "#{body}--#{boundary}\r\n" \
113
114
  "Content-Disposition: form-data; name=\"media\"; filename=\"#{File.basename(file_path)}\"\r\n" \
114
115
  "Content-Type: #{media_type}\r\n\r\n" \
115
- "#{File.read(file_path)}\r\n" \
116
+ "#{File.binread(file_path)}\r\n" \
116
117
  "--#{boundary}--\r\n"
117
118
  end
118
119
  end
data/lib/x/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require "rubygems/version"
2
2
 
3
3
  module X
4
- VERSION = Gem::Version.create("0.15.2")
4
+ VERSION = Gem::Version.create("0.15.4")
5
5
  end
data/sig/x.rbs CHANGED
@@ -275,9 +275,9 @@ module X
275
275
  def split: (String file_path, Integer chunk_size) -> Array[String]
276
276
  def init: (client: Client, file_path: String, media_type: String, media_category: String) -> untyped
277
277
  def append: (client: Client, file_paths: Array[String], media: untyped, media_type: String, ?boundary: String) -> Array[String]
278
- def upload_chunk: (client: Client, query: String, upload_body: String, file_path: String, ?headers: Hash[String, String]) -> Integer?
278
+ def upload_chunk: (client: Client, media_id: String, upload_body: String, file_path: String, ?headers: Hash[String, String]) -> Integer?
279
279
  def cleanup_file: (String file_path) -> Integer?
280
280
  def finalize: (client: Client, media: untyped) -> untyped
281
- def construct_upload_body: (file_path: String, media_type: String, ?boundary: String) -> String
281
+ def construct_upload_body: (file_path: String, media_type: String, ?segment_index: Integer, ?boundary: String) -> String
282
282
  end
283
283
  end
metadata CHANGED
@@ -1,16 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: x
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.2
4
+ version: 0.15.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Berlin
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-03-27 00:00:00.000000000 Z
12
- dependencies: []
13
- description:
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0.2'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0.2'
14
26
  email:
15
27
  - sferik@gmail.com
16
28
  executables: []
@@ -60,13 +72,13 @@ licenses:
60
72
  - MIT
61
73
  metadata:
62
74
  allowed_push_host: https://rubygems.org
63
- rubygems_mfa_required: 'true'
64
- homepage_uri: https://sferik.github.io/x-ruby
65
- source_code_uri: https://github.com/sferik/x-ruby
66
- changelog_uri: https://github.com/sferik/x-ruby/blob/master/CHANGELOG.md
67
75
  bug_tracker_uri: https://github.com/sferik/x-ruby/issues
76
+ changelog_uri: https://github.com/sferik/x-ruby/blob/master/CHANGELOG.md
68
77
  documentation_uri: https://rubydoc.info/gems/x/
69
- post_install_message:
78
+ funding_uri: https://github.com/sponsors/sferik/
79
+ homepage_uri: https://sferik.github.io/x-ruby
80
+ rubygems_mfa_required: 'true'
81
+ source_code_uri: https://github.com/sferik/x-ruby
70
82
  rdoc_options: []
71
83
  require_paths:
72
84
  - lib
@@ -81,8 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
93
  - !ruby/object:Gem::Version
82
94
  version: '0'
83
95
  requirements: []
84
- rubygems_version: 3.4.19
85
- signing_key:
96
+ rubygems_version: 3.6.8
86
97
  specification_version: 4
87
98
  summary: A Ruby interface to the X API.
88
99
  test_files: []