post-for-me 0.1.0.pre.alpha.8 → 0.1.0.pre.alpha.10
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 +4 -4
- data/CHANGELOG.md +52 -0
- data/README.md +1 -1
- data/lib/post_for_me/errors.rb +25 -11
- data/lib/post_for_me/file_part.rb +10 -7
- data/lib/post_for_me/internal/transport/base_client.rb +18 -8
- data/lib/post_for_me/internal/transport/pooled_net_requester.rb +40 -33
- data/lib/post_for_me/internal/type/base_page.rb +1 -1
- data/lib/post_for_me/internal/type/file_input.rb +7 -4
- data/lib/post_for_me/internal/util.rb +8 -7
- data/lib/post_for_me/models/bluesky_configuration_dto.rb +87 -1
- data/lib/post_for_me/models/create_social_post.rb +221 -2
- data/lib/post_for_me/models/facebook_configuration_dto.rb +106 -2
- data/lib/post_for_me/models/instagram_configuration_dto.rb +104 -2
- data/lib/post_for_me/models/linkedin_configuration_dto.rb +87 -1
- data/lib/post_for_me/models/pinterest_configuration_dto.rb +87 -1
- data/lib/post_for_me/models/social_account.rb +9 -1
- data/lib/post_for_me/models/social_account_create_auth_url_params.rb +43 -1
- data/lib/post_for_me/models/social_account_disconnect_response.rb +9 -1
- data/lib/post_for_me/models/social_post.rb +221 -2
- data/lib/post_for_me/models/threads_configuration_dto.rb +87 -1
- data/lib/post_for_me/models/tiktok_configuration.rb +96 -2
- data/lib/post_for_me/models/twitter_configuration_dto.rb +180 -2
- data/lib/post_for_me/models/youtube_configuration_dto.rb +87 -1
- data/lib/post_for_me/version.rb +1 -1
- data/lib/post_for_me.rb +1 -0
- data/manifest.yaml +1 -0
- data/rbi/post_for_me/errors.rbi +29 -2
- data/rbi/post_for_me/file_part.rbi +1 -1
- data/rbi/post_for_me/internal/transport/base_client.rbi +9 -5
- data/rbi/post_for_me/internal/transport/pooled_net_requester.rbi +6 -2
- data/rbi/post_for_me/internal/type/base_model.rbi +8 -4
- data/rbi/post_for_me/internal/type/base_page.rbi +1 -1
- data/rbi/post_for_me/internal/util.rbi +1 -1
- data/rbi/post_for_me/models/bluesky_configuration_dto.rbi +180 -0
- data/rbi/post_for_me/models/create_social_post.rbi +424 -0
- data/rbi/post_for_me/models/facebook_configuration_dto.rbi +198 -0
- data/rbi/post_for_me/models/instagram_configuration_dto.rbi +205 -3
- data/rbi/post_for_me/models/linkedin_configuration_dto.rbi +182 -0
- data/rbi/post_for_me/models/pinterest_configuration_dto.rbi +184 -0
- data/rbi/post_for_me/models/social_account.rbi +8 -0
- data/rbi/post_for_me/models/social_account_create_auth_url_params.rbi +104 -0
- data/rbi/post_for_me/models/social_account_disconnect_response.rbi +8 -0
- data/rbi/post_for_me/models/social_post.rbi +414 -0
- data/rbi/post_for_me/models/threads_configuration_dto.rbi +180 -0
- data/rbi/post_for_me/models/tiktok_configuration.rbi +180 -0
- data/rbi/post_for_me/models/twitter_configuration_dto.rbi +390 -2
- data/rbi/post_for_me/models/youtube_configuration_dto.rbi +180 -0
- data/sig/post_for_me/errors.rbs +7 -0
- data/sig/post_for_me/file_part.rbs +1 -1
- data/sig/post_for_me/internal/transport/base_client.rbs +2 -0
- data/sig/post_for_me/internal/transport/pooled_net_requester.rbs +4 -1
- data/sig/post_for_me/models/bluesky_configuration_dto.rbs +73 -1
- data/sig/post_for_me/models/create_social_post.rbs +180 -1
- data/sig/post_for_me/models/facebook_configuration_dto.rbs +83 -1
- data/sig/post_for_me/models/instagram_configuration_dto.rbs +86 -4
- data/sig/post_for_me/models/linkedin_configuration_dto.rbs +73 -1
- data/sig/post_for_me/models/pinterest_configuration_dto.rbs +73 -1
- data/sig/post_for_me/models/social_account.rbs +5 -0
- data/sig/post_for_me/models/social_account_create_auth_url_params.rbs +37 -0
- data/sig/post_for_me/models/social_account_disconnect_response.rbs +5 -0
- data/sig/post_for_me/models/social_post.rbs +180 -1
- data/sig/post_for_me/models/threads_configuration_dto.rbs +73 -1
- data/sig/post_for_me/models/tiktok_configuration.rbs +78 -1
- data/sig/post_for_me/models/twitter_configuration_dto.rbs +163 -4
- data/sig/post_for_me/models/youtube_configuration_dto.rbs +73 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f08a4f8e227f322ee7b0d29a30c415f41d249ab7522893a827f436897b1d618c
|
|
4
|
+
data.tar.gz: 58515896f263b04c98c2251a662b52a283c3d7a67b677361a4375391c080987b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7fb396a4a563b2dc101a3226c6cae480249ce4eabfc32320d2c70fdad267c27078636da74a1d4fd5716533c6873e6b3d3effb0f8fdc36d1959cc8114f39bbdd2
|
|
7
|
+
data.tar.gz: 1f15d35794ada3b12e1839818c8ef5d1f6cf885f170f480a341eb9a95d3ad247da2efaa22b4c5b111ff8f56e620852d4a824382db6d8cce0b7da6b199008d303
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.10 (2025-11-05)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.1.0-alpha.9...v0.1.0-alpha.10](https://github.com/DayMoonDevelopment/post-for-me-ruby/compare/v0.1.0-alpha.9...v0.1.0-alpha.10)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **api:** api update ([129bf08](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/129bf0849de95a151f9fb756f8ae18feee7ca85b))
|
|
10
|
+
* handle thread interrupts in the core HTTP client ([67a9096](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/67a9096a8cdf6200f708a3f58063405bceb7f7ca))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* absolutely qualified uris should always override the default ([2f8e594](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/2f8e594d99b3c79d12b6e6dcb50d1928df5af7c0))
|
|
16
|
+
* better thread safety via early initializing SSL store during HTTP client creation ([b9e0151](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/b9e01515a5ff7e201462dded310b312800a0276d))
|
|
17
|
+
* should not reuse buffers for `IO.copy_stream` interop ([4a8bedd](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/4a8bedda953dabf110a699a183b62d338713b44f))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Chores
|
|
21
|
+
|
|
22
|
+
* bump dependency version and update sorbet types ([936adc6](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/936adc671f5a30e84245daa790743dd9183b0a17))
|
|
23
|
+
* ignore linter error for tests having large collections ([8b60378](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/8b60378131cc5ff32c7dc2e96aa3d7db84280d6b))
|
|
24
|
+
|
|
25
|
+
## 0.1.0-alpha.9 (2025-10-03)
|
|
26
|
+
|
|
27
|
+
Full Changelog: [v0.1.0-alpha.8...v0.1.0-alpha.9](https://github.com/DayMoonDevelopment/post-for-me-ruby/compare/v0.1.0-alpha.8...v0.1.0-alpha.9)
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
* **api:** api update ([29166f7](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/29166f7dd2eebd6f9a49e99c553f4212233879e9))
|
|
32
|
+
* **api:** api update ([c75db7a](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/c75db7ab2fcc16f9e831ed1722e837d4dc1fbd91))
|
|
33
|
+
* **api:** api update ([11635c1](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/11635c16438bf92c6aec3d4c524f09768bf8f2cc))
|
|
34
|
+
* expose response headers for both streams and errors ([c4a0864](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/c4a0864dab0421eca1ba510038376497ca4c3d1f))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Bug Fixes
|
|
38
|
+
|
|
39
|
+
* coroutine leaks from connection pool ([5ca79a4](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/5ca79a4bbab523051dbecd1f48eb95ad5bf93af7))
|
|
40
|
+
* shorten multipart boundary sep to less than RFC specificed max length ([e467fe7](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/e467fe77aacf67eeff2f4abd38177476c925c411))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Performance Improvements
|
|
44
|
+
|
|
45
|
+
* faster code formatting ([58bee30](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/58bee30eb5b12ee89f3271e386d425d119641227))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Chores
|
|
49
|
+
|
|
50
|
+
* allow fast-format to use bsd sed as well ([b753209](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/b7532090e9056a27ce382fe54965a90a1bf65cce))
|
|
51
|
+
* do not install brew dependencies in ./scripts/bootstrap by default ([ba2ba3c](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/ba2ba3cc8fa0b6e756a840035bcd6f30054a1831))
|
|
52
|
+
* **internal:** codegen related update ([11c589f](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/11c589fc01e8a1c650e271dffb5c9bd9ef2f4da3))
|
|
53
|
+
* **internal:** codegen related update ([6e6de4f](https://github.com/DayMoonDevelopment/post-for-me-ruby/commit/6e6de4f6f1424334a37de60918ea43190593d522))
|
|
54
|
+
|
|
3
55
|
## 0.1.0-alpha.8 (2025-09-06)
|
|
4
56
|
|
|
5
57
|
Full Changelog: [v0.1.0-alpha.7...v0.1.0-alpha.8](https://github.com/DayMoonDevelopment/post-for-me-ruby/compare/v0.1.0-alpha.7...v0.1.0-alpha.8)
|
data/README.md
CHANGED
|
@@ -17,7 +17,7 @@ To use this gem, install via Bundler by adding the following to your application
|
|
|
17
17
|
<!-- x-release-please-start-version -->
|
|
18
18
|
|
|
19
19
|
```ruby
|
|
20
|
-
gem "post-for-me", "~> 0.1.0.pre.alpha.
|
|
20
|
+
gem "post-for-me", "~> 0.1.0.pre.alpha.10"
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
<!-- x-release-please-end -->
|
data/lib/post_for_me/errors.rb
CHANGED
|
@@ -40,6 +40,9 @@ module PostForMe
|
|
|
40
40
|
# @return [Integer, nil]
|
|
41
41
|
attr_accessor :status
|
|
42
42
|
|
|
43
|
+
# @return [Hash{String=>String}, nil]
|
|
44
|
+
attr_accessor :headers
|
|
45
|
+
|
|
43
46
|
# @return [Object, nil]
|
|
44
47
|
attr_accessor :body
|
|
45
48
|
|
|
@@ -47,13 +50,15 @@ module PostForMe
|
|
|
47
50
|
#
|
|
48
51
|
# @param url [URI::Generic]
|
|
49
52
|
# @param status [Integer, nil]
|
|
53
|
+
# @param headers [Hash{String=>String}, nil]
|
|
50
54
|
# @param body [Object, nil]
|
|
51
55
|
# @param request [nil]
|
|
52
56
|
# @param response [nil]
|
|
53
57
|
# @param message [String, nil]
|
|
54
|
-
def initialize(url:, status: nil, body: nil, request: nil, response: nil, message: nil)
|
|
58
|
+
def initialize(url:, status: nil, headers: nil, body: nil, request: nil, response: nil, message: nil)
|
|
55
59
|
@url = url
|
|
56
60
|
@status = status
|
|
61
|
+
@headers = headers
|
|
57
62
|
@body = body
|
|
58
63
|
@request = request
|
|
59
64
|
@response = response
|
|
@@ -74,6 +79,7 @@ module PostForMe
|
|
|
74
79
|
#
|
|
75
80
|
# @param url [URI::Generic]
|
|
76
81
|
# @param status [nil]
|
|
82
|
+
# @param headers [Hash{String=>String}, nil]
|
|
77
83
|
# @param body [nil]
|
|
78
84
|
# @param request [nil]
|
|
79
85
|
# @param response [nil]
|
|
@@ -81,6 +87,7 @@ module PostForMe
|
|
|
81
87
|
def initialize(
|
|
82
88
|
url:,
|
|
83
89
|
status: nil,
|
|
90
|
+
headers: nil,
|
|
84
91
|
body: nil,
|
|
85
92
|
request: nil,
|
|
86
93
|
response: nil,
|
|
@@ -95,6 +102,7 @@ module PostForMe
|
|
|
95
102
|
#
|
|
96
103
|
# @param url [URI::Generic]
|
|
97
104
|
# @param status [nil]
|
|
105
|
+
# @param headers [Hash{String=>String}, nil]
|
|
98
106
|
# @param body [nil]
|
|
99
107
|
# @param request [nil]
|
|
100
108
|
# @param response [nil]
|
|
@@ -102,6 +110,7 @@ module PostForMe
|
|
|
102
110
|
def initialize(
|
|
103
111
|
url:,
|
|
104
112
|
status: nil,
|
|
113
|
+
headers: nil,
|
|
105
114
|
body: nil,
|
|
106
115
|
request: nil,
|
|
107
116
|
response: nil,
|
|
@@ -116,21 +125,24 @@ module PostForMe
|
|
|
116
125
|
#
|
|
117
126
|
# @param url [URI::Generic]
|
|
118
127
|
# @param status [Integer]
|
|
128
|
+
# @param headers [Hash{String=>String}, nil]
|
|
119
129
|
# @param body [Object, nil]
|
|
120
130
|
# @param request [nil]
|
|
121
131
|
# @param response [nil]
|
|
122
132
|
# @param message [String, nil]
|
|
123
133
|
#
|
|
124
134
|
# @return [self]
|
|
125
|
-
def self.for(url:, status:, body:, request:, response:, message: nil)
|
|
126
|
-
kwargs =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
135
|
+
def self.for(url:, status:, headers:, body:, request:, response:, message: nil)
|
|
136
|
+
kwargs =
|
|
137
|
+
{
|
|
138
|
+
url: url,
|
|
139
|
+
status: status,
|
|
140
|
+
headers: headers,
|
|
141
|
+
body: body,
|
|
142
|
+
request: request,
|
|
143
|
+
response: response,
|
|
144
|
+
message: message
|
|
145
|
+
}
|
|
134
146
|
|
|
135
147
|
case status
|
|
136
148
|
in 400
|
|
@@ -162,15 +174,17 @@ module PostForMe
|
|
|
162
174
|
#
|
|
163
175
|
# @param url [URI::Generic]
|
|
164
176
|
# @param status [Integer]
|
|
177
|
+
# @param headers [Hash{String=>String}, nil]
|
|
165
178
|
# @param body [Object, nil]
|
|
166
179
|
# @param request [nil]
|
|
167
180
|
# @param response [nil]
|
|
168
181
|
# @param message [String, nil]
|
|
169
|
-
def initialize(url:, status:, body:, request:, response:, message: nil)
|
|
182
|
+
def initialize(url:, status:, headers:, body:, request:, response:, message: nil)
|
|
170
183
|
message ||= {url: url.to_s, status: status, body: body}
|
|
171
184
|
super(
|
|
172
185
|
url: url,
|
|
173
186
|
status: status,
|
|
187
|
+
headers: headers,
|
|
174
188
|
body: body,
|
|
175
189
|
request: request,
|
|
176
190
|
response: response,
|
|
@@ -38,18 +38,21 @@ module PostForMe
|
|
|
38
38
|
def to_yaml(*a) = read.to_yaml(*a)
|
|
39
39
|
|
|
40
40
|
# @param content [Pathname, StringIO, IO, String]
|
|
41
|
-
# @param filename [String, nil]
|
|
41
|
+
# @param filename [Pathname, String, nil]
|
|
42
42
|
# @param content_type [String, nil]
|
|
43
43
|
def initialize(content, filename: nil, content_type: nil)
|
|
44
|
-
@
|
|
44
|
+
@content_type = content_type
|
|
45
45
|
@filename =
|
|
46
|
-
case content
|
|
47
|
-
in Pathname
|
|
48
|
-
|
|
46
|
+
case [filename, (@content = content)]
|
|
47
|
+
in [String | Pathname, _]
|
|
48
|
+
::File.basename(filename)
|
|
49
|
+
in [nil, Pathname]
|
|
50
|
+
content.basename.to_path
|
|
51
|
+
in [nil, IO]
|
|
52
|
+
content.to_path
|
|
49
53
|
else
|
|
50
|
-
filename
|
|
54
|
+
filename
|
|
51
55
|
end
|
|
52
|
-
@content_type = content_type
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
58
|
end
|
|
@@ -47,7 +47,7 @@ module PostForMe
|
|
|
47
47
|
# @api private
|
|
48
48
|
#
|
|
49
49
|
# @param status [Integer]
|
|
50
|
-
# @param headers [Hash{String=>String}
|
|
50
|
+
# @param headers [Hash{String=>String}]
|
|
51
51
|
#
|
|
52
52
|
# @return [Boolean]
|
|
53
53
|
def should_retry?(status, headers:)
|
|
@@ -85,7 +85,7 @@ module PostForMe
|
|
|
85
85
|
#
|
|
86
86
|
# @param status [Integer]
|
|
87
87
|
#
|
|
88
|
-
# @param response_headers [Hash{String=>String}
|
|
88
|
+
# @param response_headers [Hash{String=>String}]
|
|
89
89
|
#
|
|
90
90
|
# @return [Hash{Symbol=>Object}]
|
|
91
91
|
def follow_redirect(request, status:, response_headers:)
|
|
@@ -201,7 +201,8 @@ module PostForMe
|
|
|
201
201
|
self.class::PLATFORM_HEADERS,
|
|
202
202
|
{
|
|
203
203
|
"accept" => "application/json",
|
|
204
|
-
"content-type" => "application/json"
|
|
204
|
+
"content-type" => "application/json",
|
|
205
|
+
"user-agent" => user_agent
|
|
205
206
|
},
|
|
206
207
|
headers
|
|
207
208
|
)
|
|
@@ -219,6 +220,11 @@ module PostForMe
|
|
|
219
220
|
# @return [Hash{String=>String}]
|
|
220
221
|
private def auth_headers = {}
|
|
221
222
|
|
|
223
|
+
# @api private
|
|
224
|
+
#
|
|
225
|
+
# @return [String]
|
|
226
|
+
private def user_agent = "#{self.class.name}/Ruby #{PostForMe::VERSION}"
|
|
227
|
+
|
|
222
228
|
# @api private
|
|
223
229
|
#
|
|
224
230
|
# @return [String]
|
|
@@ -378,6 +384,7 @@ module PostForMe
|
|
|
378
384
|
rescue PostForMe::Errors::APIConnectionError => e
|
|
379
385
|
status = e
|
|
380
386
|
end
|
|
387
|
+
headers = PostForMe::Internal::Util.normalized_headers(response&.each_header&.to_h)
|
|
381
388
|
|
|
382
389
|
case status
|
|
383
390
|
in ..299
|
|
@@ -390,7 +397,7 @@ module PostForMe
|
|
|
390
397
|
in 300..399
|
|
391
398
|
self.class.reap_connection!(status, stream: stream)
|
|
392
399
|
|
|
393
|
-
request = self.class.follow_redirect(request, status: status, response_headers:
|
|
400
|
+
request = self.class.follow_redirect(request, status: status, response_headers: headers)
|
|
394
401
|
send_request(
|
|
395
402
|
request,
|
|
396
403
|
redirect_count: redirect_count + 1,
|
|
@@ -399,9 +406,9 @@ module PostForMe
|
|
|
399
406
|
)
|
|
400
407
|
in PostForMe::Errors::APIConnectionError if retry_count >= max_retries
|
|
401
408
|
raise status
|
|
402
|
-
in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers:
|
|
409
|
+
in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: headers)
|
|
403
410
|
decoded = Kernel.then do
|
|
404
|
-
PostForMe::Internal::Util.decode_content(
|
|
411
|
+
PostForMe::Internal::Util.decode_content(headers, stream: stream, suppress_error: true)
|
|
405
412
|
ensure
|
|
406
413
|
self.class.reap_connection!(status, stream: stream)
|
|
407
414
|
end
|
|
@@ -409,6 +416,7 @@ module PostForMe
|
|
|
409
416
|
raise PostForMe::Errors::APIStatusError.for(
|
|
410
417
|
url: url,
|
|
411
418
|
status: status,
|
|
419
|
+
headers: headers,
|
|
412
420
|
body: decoded,
|
|
413
421
|
request: nil,
|
|
414
422
|
response: response
|
|
@@ -485,19 +493,21 @@ module PostForMe
|
|
|
485
493
|
send_retry_header: send_retry_header
|
|
486
494
|
)
|
|
487
495
|
|
|
488
|
-
|
|
496
|
+
headers = PostForMe::Internal::Util.normalized_headers(response.each_header.to_h)
|
|
497
|
+
decoded = PostForMe::Internal::Util.decode_content(headers, stream: stream)
|
|
489
498
|
case req
|
|
490
499
|
in {stream: Class => st}
|
|
491
500
|
st.new(
|
|
492
501
|
model: model,
|
|
493
502
|
url: url,
|
|
494
503
|
status: status,
|
|
504
|
+
headers: headers,
|
|
495
505
|
response: response,
|
|
496
506
|
unwrap: unwrap,
|
|
497
507
|
stream: decoded
|
|
498
508
|
)
|
|
499
509
|
in {page: Class => page}
|
|
500
|
-
page.new(client: self, req: req, headers:
|
|
510
|
+
page.new(client: self, req: req, headers: headers, page_data: decoded)
|
|
501
511
|
else
|
|
502
512
|
unwrapped = PostForMe::Internal::Util.dig(decoded, unwrap)
|
|
503
513
|
PostForMe::Internal::Type::Converter.coerce(model, unwrapped)
|
|
@@ -16,10 +16,11 @@ module PostForMe
|
|
|
16
16
|
class << self
|
|
17
17
|
# @api private
|
|
18
18
|
#
|
|
19
|
+
# @param cert_store [OpenSSL::X509::Store]
|
|
19
20
|
# @param url [URI::Generic]
|
|
20
21
|
#
|
|
21
22
|
# @return [Net::HTTP]
|
|
22
|
-
def connect(url)
|
|
23
|
+
def connect(cert_store:, url:)
|
|
23
24
|
port =
|
|
24
25
|
case [url.port, url.scheme]
|
|
25
26
|
in [Integer, _]
|
|
@@ -33,6 +34,8 @@ module PostForMe
|
|
|
33
34
|
Net::HTTP.new(url.host, port).tap do
|
|
34
35
|
_1.use_ssl = %w[https wss].include?(url.scheme)
|
|
35
36
|
_1.max_retries = 0
|
|
37
|
+
|
|
38
|
+
(_1.cert_store = cert_store) if _1.use_ssl?
|
|
36
39
|
end
|
|
37
40
|
end
|
|
38
41
|
|
|
@@ -102,7 +105,7 @@ module PostForMe
|
|
|
102
105
|
pool =
|
|
103
106
|
@mutex.synchronize do
|
|
104
107
|
@pools[origin] ||= ConnectionPool.new(size: @size) do
|
|
105
|
-
self.class.connect(url)
|
|
108
|
+
self.class.connect(cert_store: @cert_store, url: url)
|
|
106
109
|
end
|
|
107
110
|
end
|
|
108
111
|
|
|
@@ -128,37 +131,47 @@ module PostForMe
|
|
|
128
131
|
url, deadline = request.fetch_values(:url, :deadline)
|
|
129
132
|
|
|
130
133
|
req = nil
|
|
131
|
-
eof = false
|
|
132
134
|
finished = false
|
|
133
|
-
closing = nil
|
|
134
135
|
|
|
135
136
|
# rubocop:disable Metrics/BlockLength
|
|
136
137
|
enum = Enumerator.new do |y|
|
|
137
|
-
|
|
138
|
-
next if finished
|
|
139
|
-
|
|
140
|
-
req, closing = self.class.build_request(request) do
|
|
141
|
-
self.class.calibrate_socket_timeout(conn, deadline)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
self.class.calibrate_socket_timeout(conn, deadline)
|
|
145
|
-
unless conn.started?
|
|
146
|
-
conn.keep_alive_timeout = self.class::KEEP_ALIVE_TIMEOUT
|
|
147
|
-
conn.start
|
|
148
|
-
end
|
|
138
|
+
next if finished
|
|
149
139
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
140
|
+
with_pool(url, deadline: deadline) do |conn|
|
|
141
|
+
eof = false
|
|
142
|
+
closing = nil
|
|
143
|
+
::Thread.handle_interrupt(Object => :never) do
|
|
144
|
+
::Thread.handle_interrupt(Object => :immediate) do
|
|
145
|
+
req, closing = self.class.build_request(request) do
|
|
146
|
+
self.class.calibrate_socket_timeout(conn, deadline)
|
|
147
|
+
end
|
|
154
148
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
149
|
+
self.class.calibrate_socket_timeout(conn, deadline)
|
|
150
|
+
unless conn.started?
|
|
151
|
+
conn.keep_alive_timeout = self.class::KEEP_ALIVE_TIMEOUT
|
|
152
|
+
conn.start
|
|
153
|
+
end
|
|
158
154
|
|
|
159
155
|
self.class.calibrate_socket_timeout(conn, deadline)
|
|
156
|
+
conn.request(req) do |rsp|
|
|
157
|
+
y << [req, rsp]
|
|
158
|
+
break if finished
|
|
159
|
+
|
|
160
|
+
rsp.read_body do |bytes|
|
|
161
|
+
y << bytes.force_encoding(Encoding::BINARY)
|
|
162
|
+
break if finished
|
|
163
|
+
|
|
164
|
+
self.class.calibrate_socket_timeout(conn, deadline)
|
|
165
|
+
end
|
|
166
|
+
eof = true
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
ensure
|
|
170
|
+
begin
|
|
171
|
+
conn.finish if !eof && conn&.started?
|
|
172
|
+
ensure
|
|
173
|
+
closing&.call
|
|
160
174
|
end
|
|
161
|
-
eof = true
|
|
162
175
|
end
|
|
163
176
|
end
|
|
164
177
|
rescue Timeout::Error
|
|
@@ -168,17 +181,10 @@ module PostForMe
|
|
|
168
181
|
end
|
|
169
182
|
# rubocop:enable Metrics/BlockLength
|
|
170
183
|
|
|
171
|
-
|
|
184
|
+
_, response = enum.next
|
|
172
185
|
body = PostForMe::Internal::Util.fused_enum(enum, external: true) do
|
|
173
186
|
finished = true
|
|
174
|
-
|
|
175
|
-
enum.next
|
|
176
|
-
rescue StopIteration
|
|
177
|
-
nil
|
|
178
|
-
end
|
|
179
|
-
ensure
|
|
180
|
-
conn.finish if !eof && conn&.started?
|
|
181
|
-
closing&.call
|
|
187
|
+
loop { enum.next }
|
|
182
188
|
end
|
|
183
189
|
[Integer(response.code), response, body]
|
|
184
190
|
end
|
|
@@ -189,6 +195,7 @@ module PostForMe
|
|
|
189
195
|
def initialize(size: self.class::DEFAULT_MAX_CONNECTIONS)
|
|
190
196
|
@mutex = Mutex.new
|
|
191
197
|
@size = size
|
|
198
|
+
@cert_store = OpenSSL::X509::Store.new.tap(&:set_default_paths)
|
|
192
199
|
@pools = {}
|
|
193
200
|
end
|
|
194
201
|
|
|
@@ -39,7 +39,7 @@ module PostForMe
|
|
|
39
39
|
#
|
|
40
40
|
# @param client [PostForMe::Internal::Transport::BaseClient]
|
|
41
41
|
# @param req [Hash{Symbol=>Object}]
|
|
42
|
-
# @param headers [Hash{String=>String}
|
|
42
|
+
# @param headers [Hash{String=>String}]
|
|
43
43
|
# @param page_data [Object]
|
|
44
44
|
def initialize(client:, req:, headers:, page_data:)
|
|
45
45
|
@client = client
|
|
@@ -82,17 +82,20 @@ module PostForMe
|
|
|
82
82
|
#
|
|
83
83
|
# @return [Pathname, StringIO, IO, String, Object]
|
|
84
84
|
def dump(value, state:)
|
|
85
|
-
# rubocop:disable Lint/DuplicateBranch
|
|
86
85
|
case value
|
|
86
|
+
in StringIO | String
|
|
87
|
+
# https://datatracker.ietf.org/doc/html/rfc7578#section-4.2
|
|
88
|
+
# while not required, a filename is recommended, and in practice many servers do expect this
|
|
89
|
+
PostForMe::FilePart.new(value, filename: "upload")
|
|
87
90
|
in IO
|
|
88
91
|
state[:can_retry] = false
|
|
92
|
+
value.to_path.nil? ? PostForMe::FilePart.new(value, filename: "upload") : value
|
|
89
93
|
in PostForMe::FilePart if value.content.is_a?(IO)
|
|
90
94
|
state[:can_retry] = false
|
|
95
|
+
value
|
|
91
96
|
else
|
|
97
|
+
value
|
|
92
98
|
end
|
|
93
|
-
# rubocop:enable Lint/DuplicateBranch
|
|
94
|
-
|
|
95
|
-
value
|
|
96
99
|
end
|
|
97
100
|
|
|
98
101
|
# @api private
|
|
@@ -346,8 +346,9 @@ module PostForMe
|
|
|
346
346
|
base_path, base_query = lhs.fetch_values(:path, :query)
|
|
347
347
|
slashed = base_path.end_with?("/") ? base_path : "#{base_path}/"
|
|
348
348
|
|
|
349
|
-
|
|
350
|
-
|
|
349
|
+
merged = {**parse_uri(rhs.fetch(:path)), **rhs.except(:path, :query)}
|
|
350
|
+
parsed_path, parsed_query = merged.fetch_values(:path, :query)
|
|
351
|
+
override = URI::Generic.build(**merged.slice(:scheme, :host, :port), path: parsed_path)
|
|
351
352
|
|
|
352
353
|
joined = URI.join(URI::Generic.build(lhs.except(:path, :query)), slashed, override)
|
|
353
354
|
query = deep_merge(
|
|
@@ -473,10 +474,9 @@ module PostForMe
|
|
|
473
474
|
# @return [Enumerable<String>]
|
|
474
475
|
def writable_enum(&blk)
|
|
475
476
|
Enumerator.new do |y|
|
|
476
|
-
buf = String.new
|
|
477
477
|
y.define_singleton_method(:write) do
|
|
478
|
-
self <<
|
|
479
|
-
|
|
478
|
+
self << _1.dup
|
|
479
|
+
_1.bytesize
|
|
480
480
|
end
|
|
481
481
|
|
|
482
482
|
blk.call(y)
|
|
@@ -566,7 +566,8 @@ module PostForMe
|
|
|
566
566
|
#
|
|
567
567
|
# @return [Array(String, Enumerable<String>)]
|
|
568
568
|
private def encode_multipart_streaming(body)
|
|
569
|
-
|
|
569
|
+
# RFC 1521 Section 7.2.1 says we should have 70 char maximum for boundary length
|
|
570
|
+
boundary = SecureRandom.urlsafe_base64(46)
|
|
570
571
|
|
|
571
572
|
closing = []
|
|
572
573
|
strio = writable_enum do |y|
|
|
@@ -647,7 +648,7 @@ module PostForMe
|
|
|
647
648
|
#
|
|
648
649
|
# Assumes each chunk in stream has `Encoding::BINARY`.
|
|
649
650
|
#
|
|
650
|
-
# @param headers [Hash{String=>String}
|
|
651
|
+
# @param headers [Hash{String=>String}]
|
|
651
652
|
# @param stream [Enumerable<String>]
|
|
652
653
|
# @param suppress_error [Boolean]
|
|
653
654
|
#
|
|
@@ -29,6 +29,14 @@ module PostForMe
|
|
|
29
29
|
# @return [String]
|
|
30
30
|
required :url, String
|
|
31
31
|
|
|
32
|
+
# @!attribute tags
|
|
33
|
+
# List of tags to attach to the media
|
|
34
|
+
#
|
|
35
|
+
# @return [Array<PostForMe::Models::BlueskyConfigurationDto::Media::Tag>, nil]
|
|
36
|
+
optional :tags,
|
|
37
|
+
-> { PostForMe::Internal::Type::ArrayOf[PostForMe::BlueskyConfigurationDto::Media::Tag] },
|
|
38
|
+
nil?: true
|
|
39
|
+
|
|
32
40
|
# @!attribute thumbnail_timestamp_ms
|
|
33
41
|
# Timestamp in milliseconds of frame to use as thumbnail for the media
|
|
34
42
|
#
|
|
@@ -41,12 +49,90 @@ module PostForMe
|
|
|
41
49
|
# @return [Object, nil]
|
|
42
50
|
optional :thumbnail_url, PostForMe::Internal::Type::Unknown, nil?: true
|
|
43
51
|
|
|
44
|
-
# @!method initialize(url:, thumbnail_timestamp_ms: nil, thumbnail_url: nil)
|
|
52
|
+
# @!method initialize(url:, tags: nil, thumbnail_timestamp_ms: nil, thumbnail_url: nil)
|
|
45
53
|
# @param url [String] Public URL of the media
|
|
46
54
|
#
|
|
55
|
+
# @param tags [Array<PostForMe::Models::BlueskyConfigurationDto::Media::Tag>, nil] List of tags to attach to the media
|
|
56
|
+
#
|
|
47
57
|
# @param thumbnail_timestamp_ms [Object, nil] Timestamp in milliseconds of frame to use as thumbnail for the media
|
|
48
58
|
#
|
|
49
59
|
# @param thumbnail_url [Object, nil] Public URL of the thumbnail for the media
|
|
60
|
+
|
|
61
|
+
class Tag < PostForMe::Internal::Type::BaseModel
|
|
62
|
+
# @!attribute id
|
|
63
|
+
# Facebook User ID, Instagram Username or Instagram product id to tag
|
|
64
|
+
#
|
|
65
|
+
# @return [String]
|
|
66
|
+
required :id, String
|
|
67
|
+
|
|
68
|
+
# @!attribute platform
|
|
69
|
+
# The platform for the tags
|
|
70
|
+
#
|
|
71
|
+
# @return [Symbol, PostForMe::Models::BlueskyConfigurationDto::Media::Tag::Platform]
|
|
72
|
+
required :platform, enum: -> { PostForMe::BlueskyConfigurationDto::Media::Tag::Platform }
|
|
73
|
+
|
|
74
|
+
# @!attribute type
|
|
75
|
+
# The type of tag, user to tag accounts, product to tag products (only supported
|
|
76
|
+
# for instagram)
|
|
77
|
+
#
|
|
78
|
+
# @return [Symbol, PostForMe::Models::BlueskyConfigurationDto::Media::Tag::Type]
|
|
79
|
+
required :type, enum: -> { PostForMe::BlueskyConfigurationDto::Media::Tag::Type }
|
|
80
|
+
|
|
81
|
+
# @!attribute x
|
|
82
|
+
# Percentage distance from left edge of the image, Not required for videos or
|
|
83
|
+
# stories
|
|
84
|
+
#
|
|
85
|
+
# @return [Float, nil]
|
|
86
|
+
optional :x, Float
|
|
87
|
+
|
|
88
|
+
# @!attribute y_
|
|
89
|
+
# Percentage distance from top edge of the image, Not required for videos or
|
|
90
|
+
# stories
|
|
91
|
+
#
|
|
92
|
+
# @return [Float, nil]
|
|
93
|
+
optional :y_, Float, api_name: :y
|
|
94
|
+
|
|
95
|
+
# @!method initialize(id:, platform:, type:, x: nil, y_: nil)
|
|
96
|
+
# Some parameter documentations has been truncated, see
|
|
97
|
+
# {PostForMe::Models::BlueskyConfigurationDto::Media::Tag} for more details.
|
|
98
|
+
#
|
|
99
|
+
# @param id [String] Facebook User ID, Instagram Username or Instagram product id to tag
|
|
100
|
+
#
|
|
101
|
+
# @param platform [Symbol, PostForMe::Models::BlueskyConfigurationDto::Media::Tag::Platform] The platform for the tags
|
|
102
|
+
#
|
|
103
|
+
# @param type [Symbol, PostForMe::Models::BlueskyConfigurationDto::Media::Tag::Type] The type of tag, user to tag accounts, product to tag products (only supported f
|
|
104
|
+
#
|
|
105
|
+
# @param x [Float] Percentage distance from left edge of the image, Not required for videos or stor
|
|
106
|
+
#
|
|
107
|
+
# @param y_ [Float] Percentage distance from top edge of the image, Not required for videos or stori
|
|
108
|
+
|
|
109
|
+
# The platform for the tags
|
|
110
|
+
#
|
|
111
|
+
# @see PostForMe::Models::BlueskyConfigurationDto::Media::Tag#platform
|
|
112
|
+
module Platform
|
|
113
|
+
extend PostForMe::Internal::Type::Enum
|
|
114
|
+
|
|
115
|
+
FACEBOOK = :facebook
|
|
116
|
+
INSTAGRAM = :instagram
|
|
117
|
+
|
|
118
|
+
# @!method self.values
|
|
119
|
+
# @return [Array<Symbol>]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# The type of tag, user to tag accounts, product to tag products (only supported
|
|
123
|
+
# for instagram)
|
|
124
|
+
#
|
|
125
|
+
# @see PostForMe::Models::BlueskyConfigurationDto::Media::Tag#type
|
|
126
|
+
module Type
|
|
127
|
+
extend PostForMe::Internal::Type::Enum
|
|
128
|
+
|
|
129
|
+
USER = :user
|
|
130
|
+
PRODUCT = :product
|
|
131
|
+
|
|
132
|
+
# @!method self.values
|
|
133
|
+
# @return [Array<Symbol>]
|
|
134
|
+
end
|
|
135
|
+
end
|
|
50
136
|
end
|
|
51
137
|
end
|
|
52
138
|
end
|