simple_tweet 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|