simple_tweet 3.0.0 → 3.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 +4 -4
- data/.rubocop.yml +7 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +55 -1
- data/Steepfile +11 -0
- data/lib/simple_tweet/v2_client.rb +38 -32
- data/lib/simple_tweet/version.rb +1 -1
- data/lib/simple_tweet.rb +1 -1
- data/rbs_collection.lock.yaml +50 -0
- data/rbs_collection.yaml +17 -0
- data/sig/simple_tweet.rbs +43 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eda2472eda06f1ddc2348a30e194c498e0cd9998036e7dabdbdee4850e1098dc
|
4
|
+
data.tar.gz: 50c944ffd64e0f687f968d254389bd2fab8b521b959c5433fbe2aecfe772507e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a24c2848c3164782c1e424ac6fa6504fb4c1df5b1d720e92323cea4c8298d9327d1878fc49e1b13091c1a043bd612efd06a409ad2bc218c82cb650b962222f3c
|
7
|
+
data.tar.gz: e03a4050dc75280addf7a86cad0faa1cc9541c39abbe2f9d1adca6a6fd4cb4898712ff68d7411b0c382de6d85bb6aab4c29f13ae305bd33fce31afd61662a108
|
data/.rubocop.yml
CHANGED
@@ -9,6 +9,9 @@ Style/StringLiteralsInInterpolation:
|
|
9
9
|
Enabled: true
|
10
10
|
EnforcedStyle: double_quotes
|
11
11
|
|
12
|
+
Style/FrozenStringLiteralComment:
|
13
|
+
Enabled: false
|
14
|
+
|
12
15
|
Layout/LineLength:
|
13
16
|
Max: 120
|
14
17
|
|
@@ -20,3 +23,7 @@ Metrics/MethodLength:
|
|
20
23
|
|
21
24
|
Metrics/AbcSize:
|
22
25
|
Max: 30
|
26
|
+
|
27
|
+
Metrics/BlockLength:
|
28
|
+
Exclude:
|
29
|
+
- 'spec/**/*'
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,40 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
simple_tweet (3.
|
4
|
+
simple_tweet (3.1.0)
|
5
5
|
multipart-post (>= 2.2.3)
|
6
6
|
oauth (~> 1.1.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
+
activesupport (7.0.8)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (>= 1.6, < 2)
|
14
|
+
minitest (>= 5.1)
|
15
|
+
tzinfo (~> 2.0)
|
16
|
+
addressable (2.8.5)
|
17
|
+
public_suffix (>= 2.0.2, < 6.0)
|
11
18
|
ast (2.4.2)
|
12
19
|
base64 (0.1.1)
|
20
|
+
concurrent-ruby (1.2.2)
|
21
|
+
crack (0.4.5)
|
22
|
+
rexml
|
23
|
+
csv (3.2.7)
|
13
24
|
diff-lcs (1.5.0)
|
25
|
+
ffi (1.15.5)
|
26
|
+
fileutils (1.7.1)
|
27
|
+
hashdiff (1.0.1)
|
14
28
|
hashie (5.0.0)
|
29
|
+
i18n (1.14.1)
|
30
|
+
concurrent-ruby (~> 1.0)
|
15
31
|
json (2.6.3)
|
16
32
|
language_server-protocol (3.17.0.3)
|
33
|
+
listen (3.8.0)
|
34
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
35
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
36
|
+
logger (1.5.3)
|
37
|
+
minitest (5.20.0)
|
17
38
|
multipart-post (2.3.0)
|
18
39
|
oauth (1.1.0)
|
19
40
|
oauth-tty (~> 1.0, >= 1.0.1)
|
@@ -25,9 +46,14 @@ GEM
|
|
25
46
|
parser (3.2.2.3)
|
26
47
|
ast (~> 2.4.1)
|
27
48
|
racc
|
49
|
+
public_suffix (5.0.3)
|
28
50
|
racc (1.7.1)
|
29
51
|
rainbow (3.1.1)
|
30
52
|
rake (13.0.6)
|
53
|
+
rb-fsevent (0.11.2)
|
54
|
+
rb-inotify (0.10.1)
|
55
|
+
ffi (~> 1.0)
|
56
|
+
rbs (3.2.1)
|
31
57
|
regexp_parser (2.8.1)
|
32
58
|
rexml (3.2.6)
|
33
59
|
rspec (3.12.0)
|
@@ -58,20 +84,48 @@ GEM
|
|
58
84
|
rubocop-ast (1.29.0)
|
59
85
|
parser (>= 3.2.1.0)
|
60
86
|
ruby-progressbar (1.13.0)
|
87
|
+
securerandom (0.2.2)
|
61
88
|
snaky_hash (2.0.1)
|
62
89
|
hashie
|
63
90
|
version_gem (~> 1.1, >= 1.1.1)
|
91
|
+
steep (1.5.3)
|
92
|
+
activesupport (>= 5.1)
|
93
|
+
concurrent-ruby (>= 1.1.10)
|
94
|
+
csv (>= 3.0.9)
|
95
|
+
fileutils (>= 1.1.0)
|
96
|
+
json (>= 2.1.0)
|
97
|
+
language_server-protocol (>= 3.15, < 4.0)
|
98
|
+
listen (~> 3.0)
|
99
|
+
logger (>= 1.3.0)
|
100
|
+
parser (>= 3.1)
|
101
|
+
rainbow (>= 2.2.2, < 4.0)
|
102
|
+
rbs (>= 3.1.0)
|
103
|
+
securerandom (>= 0.1)
|
104
|
+
strscan (>= 1.0.0)
|
105
|
+
terminal-table (>= 2, < 4)
|
106
|
+
strscan (3.0.6)
|
107
|
+
terminal-table (3.0.2)
|
108
|
+
unicode-display_width (>= 1.1.1, < 3)
|
109
|
+
tzinfo (2.0.6)
|
110
|
+
concurrent-ruby (~> 1.0)
|
64
111
|
unicode-display_width (2.4.2)
|
65
112
|
version_gem (1.1.3)
|
113
|
+
webmock (3.19.1)
|
114
|
+
addressable (>= 2.8.0)
|
115
|
+
crack (>= 0.3.2)
|
116
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
66
117
|
|
67
118
|
PLATFORMS
|
68
119
|
arm64-darwin-21
|
120
|
+
x86_64-linux
|
69
121
|
|
70
122
|
DEPENDENCIES
|
71
123
|
rake (~> 13.0)
|
72
124
|
rspec (~> 3.0)
|
73
125
|
rubocop (~> 1.56)
|
74
126
|
simple_tweet!
|
127
|
+
steep
|
128
|
+
webmock
|
75
129
|
|
76
130
|
BUNDLED WITH
|
77
131
|
2.3.24
|
data/Steepfile
ADDED
@@ -27,7 +27,7 @@ module SimpleTweet
|
|
27
27
|
|
28
28
|
# https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/migrate
|
29
29
|
def tweet(message:, media_ids: [])
|
30
|
-
json = { text: message }
|
30
|
+
json = { text: message } # : ::Hash[::Symbol, (::String|::Hash[::Symbol, ::Array[::String]])]
|
31
31
|
json[:media] = { media_ids: media_ids } unless media_ids.empty?
|
32
32
|
header = { "User-Agent": UA, "content-type": "application/json" }
|
33
33
|
access_token.post(TW_TWEET_PATH, json.to_json, header)
|
@@ -55,7 +55,10 @@ module SimpleTweet
|
|
55
55
|
@client.sign! req
|
56
56
|
|
57
57
|
url = ::URI.parse(TW_UPLOAD_ORIGIN + TW_MEDIA_UPLOAD_PATH)
|
58
|
-
https = ::Net::HTTP.new(
|
58
|
+
https = ::Net::HTTP.new(
|
59
|
+
url.host, # : ::String
|
60
|
+
url.port
|
61
|
+
)
|
59
62
|
https.use_ssl = true
|
60
63
|
|
61
64
|
https.start do |http|
|
@@ -63,6 +66,21 @@ module SimpleTweet
|
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
69
|
+
def request_with_retry(req:, expected_status_code:, error_kind_message:, retry_count: 3)
|
70
|
+
res = request(req)
|
71
|
+
return res if expected_status_code === res.code # rubocop:disable Style/CaseEquality
|
72
|
+
raise UploadMediaError.new(error_kind_message, response: res) unless retry_count.positive?
|
73
|
+
|
74
|
+
@client = nil # reset client
|
75
|
+
sleep 1 << (3 - retry_count)
|
76
|
+
request_with_retry(
|
77
|
+
req: req,
|
78
|
+
expected_status_code: expected_status_code,
|
79
|
+
error_kind_message: error_kind_message,
|
80
|
+
retry_count: retry_count - 1
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
66
84
|
# https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-upload
|
67
85
|
## maybe todo: multiple image
|
68
86
|
# ここはv1のAPIを叩いている。
|
@@ -85,55 +103,46 @@ module SimpleTweet
|
|
85
103
|
total_bytes: video.size,
|
86
104
|
media_type: "video/mp4"
|
87
105
|
)
|
88
|
-
init_res =
|
89
|
-
raise UploadMediaError.new("init failed", response: init_res) unless init_res.code == "202"
|
90
|
-
|
106
|
+
init_res = request_with_retry(req: init_req, expected_status_code: "202", error_kind_message: "init failed")
|
91
107
|
::JSON.parse(init_res.body)
|
92
108
|
end
|
93
109
|
|
94
|
-
def append(video:, media_id:, index
|
95
|
-
|
110
|
+
def append(video:, media_id:, index:)
|
111
|
+
req = ::Net::HTTP::Post::Multipart.new(
|
96
112
|
TW_MEDIA_UPLOAD_PATH,
|
97
113
|
command: "APPEND",
|
98
114
|
media_id: media_id,
|
99
115
|
media: video.read(APPEND_PER),
|
100
116
|
segment_index: index
|
101
117
|
)
|
102
|
-
|
103
|
-
return if res.code == "204"
|
104
|
-
raise UploadMediaError.new("append failed", response: res) unless retry_count <= @max_append_retry_
|
105
|
-
|
106
|
-
append(video: video, media_id: media_id, index: index, retry_count: retry_count + 1)
|
118
|
+
request_with_retry(req: req, expected_status_code: "204", error_kind_message: "append failed")
|
107
119
|
end
|
108
120
|
|
109
121
|
def finalize(media_id:)
|
110
|
-
|
122
|
+
req = ::Net::HTTP::Post::Multipart.new(
|
111
123
|
TW_MEDIA_UPLOAD_PATH,
|
112
124
|
command: "FINALIZE",
|
113
125
|
media_id: media_id
|
114
126
|
)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
::JSON.parse(finalize_res.body)
|
127
|
+
# finalizeは201が帰ってきてても、processing_infoにretry_afterが入っている場合がある(upload_video中で処理)。
|
128
|
+
res = request_with_retry(req: req, expected_status_code: /^20\d$/, error_kind_message: "finalize failed")
|
129
|
+
::JSON.parse(res.body)
|
119
130
|
end
|
120
131
|
|
121
132
|
def status(media_id:)
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
::JSON.parse(status_res.body)
|
133
|
+
# https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/get-media-upload-status
|
134
|
+
# これはGET
|
135
|
+
uri = ::URI.parse(TW_UPLOAD_ORIGIN + TW_MEDIA_UPLOAD_PATH)
|
136
|
+
uri.query = ::URI.encode_www_form(command: "STATUS", media_id: media_id)
|
137
|
+
req = ::Net::HTTP::Get.new(uri)
|
138
|
+
res = request_with_retry(req: req, expected_status_code: "200", error_kind_message: "status failed")
|
139
|
+
::JSON.parse(res.body)
|
131
140
|
end
|
132
141
|
|
133
142
|
# https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-upload-init
|
134
143
|
def upload_video(video:)
|
135
144
|
init_res = init(video: video)
|
136
|
-
media_id = init_res["media_id_string"]
|
145
|
+
media_id = init_res["media_id_string"] # : String
|
137
146
|
|
138
147
|
chunks_needed = (video.size - 1) / APPEND_PER + 1
|
139
148
|
chunks_needed.times do |i|
|
@@ -165,13 +174,10 @@ module SimpleTweet
|
|
165
174
|
end
|
166
175
|
|
167
176
|
def create_media_metadata(media_id:, alt_text:)
|
168
|
-
header = { "content-type"
|
177
|
+
header = { "content-type" => "application/json; charset=UTF-8" } # : ::Hash[::String, ::String]
|
169
178
|
req = ::Net::HTTP::Post.new(TW_METADATA_CREATE_PATH, header)
|
170
179
|
req.body = { media_id: media_id, alt_text: { text: alt_text } }.to_json
|
171
|
-
|
172
|
-
raise UploadMediaError.new("create_media_metadata failed", response: res) if res.code != "200"
|
173
|
-
|
174
|
-
res
|
180
|
+
request_with_retry(req: req, expected_status_code: "200", error_kind_message: "create_media_metadata failed")
|
175
181
|
end
|
176
182
|
end
|
177
183
|
end
|
data/lib/simple_tweet/version.rb
CHANGED
data/lib/simple_tweet.rb
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
---
|
2
|
+
sources:
|
3
|
+
- type: git
|
4
|
+
name: ruby/gem_rbs_collection
|
5
|
+
revision: 248499a924c3cb331d40ca667d40528814043788
|
6
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
7
|
+
repo_dir: gems
|
8
|
+
path: ".gem_rbs_collection"
|
9
|
+
gems:
|
10
|
+
- name: ast
|
11
|
+
version: '2.4'
|
12
|
+
source:
|
13
|
+
type: git
|
14
|
+
name: ruby/gem_rbs_collection
|
15
|
+
revision: 248499a924c3cb331d40ca667d40528814043788
|
16
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
17
|
+
repo_dir: gems
|
18
|
+
- name: base64
|
19
|
+
version: '0'
|
20
|
+
source:
|
21
|
+
type: stdlib
|
22
|
+
- name: hashie
|
23
|
+
version: '5.0'
|
24
|
+
source:
|
25
|
+
type: git
|
26
|
+
name: ruby/gem_rbs_collection
|
27
|
+
revision: 248499a924c3cb331d40ca667d40528814043788
|
28
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
29
|
+
repo_dir: gems
|
30
|
+
- name: json
|
31
|
+
version: '0'
|
32
|
+
source:
|
33
|
+
type: stdlib
|
34
|
+
- name: parallel
|
35
|
+
version: '1.20'
|
36
|
+
source:
|
37
|
+
type: git
|
38
|
+
name: ruby/gem_rbs_collection
|
39
|
+
revision: 248499a924c3cb331d40ca667d40528814043788
|
40
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
41
|
+
repo_dir: gems
|
42
|
+
- name: rainbow
|
43
|
+
version: '3.0'
|
44
|
+
source:
|
45
|
+
type: git
|
46
|
+
name: ruby/gem_rbs_collection
|
47
|
+
revision: 248499a924c3cb331d40ca667d40528814043788
|
48
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
49
|
+
repo_dir: gems
|
50
|
+
gemfile_lock_path: Gemfile.lock
|
data/rbs_collection.yaml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
sources:
|
2
|
+
- type: git
|
3
|
+
name: ruby/gem_rbs_collection
|
4
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
5
|
+
revision: main
|
6
|
+
repo_dir: gems
|
7
|
+
|
8
|
+
# A directory to install the downloaded RBSs
|
9
|
+
path: .gem_rbs_collection
|
10
|
+
|
11
|
+
gems:
|
12
|
+
# Skip loading rbs gem's RBS.
|
13
|
+
# It's unnecessary if you don't use rbs as a library.
|
14
|
+
- name: rbs
|
15
|
+
ignore: true
|
16
|
+
- name: steep
|
17
|
+
ignore: true
|
data/sig/simple_tweet.rbs
CHANGED
@@ -1,4 +1,46 @@
|
|
1
1
|
module SimpleTweet
|
2
2
|
VERSION: String
|
3
|
-
|
3
|
+
|
4
|
+
module V2
|
5
|
+
class Client
|
6
|
+
TW_API_ORIGIN: String
|
7
|
+
TW_UPLOAD_ORIGIN: String
|
8
|
+
TW_MEDIA_UPLOAD_PATH: String
|
9
|
+
TW_METADATA_CREATE_PATH: String
|
10
|
+
TW_TWEET_PATH: String
|
11
|
+
UA: String
|
12
|
+
APPEND_PER: Integer
|
13
|
+
|
14
|
+
def initialize: (consumer_key: String, consumer_secret: String, access_token: String, access_token_secret: String, ?max_append_retry: Integer) -> void
|
15
|
+
def tweet: (message: String, ?media_ids: Array[String]) -> Net::HTTPResponse
|
16
|
+
def tweet_with_media: (message: String, media_type: String, media: untyped, ?alt_text: String?) -> Net::HTTPResponse
|
17
|
+
|
18
|
+
@consumer_key_: String
|
19
|
+
@consumer_secret_: String
|
20
|
+
@access_token_: String
|
21
|
+
@access_token_secret_: String
|
22
|
+
@max_append_retry_: Integer
|
23
|
+
@client: untyped # ::OAuth::AccessToken
|
24
|
+
|
25
|
+
private
|
26
|
+
def access_token: (?site: String) -> untyped
|
27
|
+
def request: (Net::HTTPRequest req) -> Net::HTTPResponse
|
28
|
+
def request_with_retry: (req: Net::HTTPRequest, expected_status_code: String | Regexp, error_kind_message: String, ?retry_count: Integer) -> Net::HTTPResponse
|
29
|
+
def upload_media: (media_type: String, media: untyped) -> [String]
|
30
|
+
def init: (video: untyped) -> Hash[String, untyped]
|
31
|
+
def append: (video: untyped, media_id: String, index: untyped) -> Net::HTTPResponse
|
32
|
+
def finalize: (media_id: String) -> Hash[String, untyped]
|
33
|
+
def status: (media_id: String) -> Hash[String, untyped]
|
34
|
+
def upload_video: (video: untyped) -> [String]
|
35
|
+
def create_media_metadata: (media_id: String, alt_text: String?) -> Net::HTTPResponse
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Error < StandardError
|
40
|
+
end
|
41
|
+
|
42
|
+
class UploadMediaError < Error
|
43
|
+
attr_reader response: Net::HTTPResponse?
|
44
|
+
def initialize: (?String? message, ?response: Net::HTTPResponse?) -> void
|
45
|
+
end
|
4
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_tweet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kugayama Nana
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multipart-post
|
@@ -53,9 +53,12 @@ files:
|
|
53
53
|
- LICENSE.txt
|
54
54
|
- README.md
|
55
55
|
- Rakefile
|
56
|
+
- Steepfile
|
56
57
|
- lib/simple_tweet.rb
|
57
58
|
- lib/simple_tweet/v2_client.rb
|
58
59
|
- lib/simple_tweet/version.rb
|
60
|
+
- rbs_collection.lock.yaml
|
61
|
+
- rbs_collection.yaml
|
59
62
|
- sig/simple_tweet.rbs
|
60
63
|
- simple_tweet.gemspec
|
61
64
|
homepage: https://github.com/nota/simple_tweet
|