youtube-transcript-rb 0.1.0 → 0.2.3
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 +9 -0
- data/.rubocop_todo.yml +166 -0
- data/README.md +42 -42
- data/lib/youtube-transcript-rb.rb +4 -0
- data/lib/youtube_rb/formatters.rb +263 -0
- data/lib/youtube_rb/transcript/api.rb +144 -0
- data/lib/youtube_rb/transcript/errors.rb +215 -0
- data/lib/youtube_rb/transcript/settings.rb +26 -0
- data/lib/youtube_rb/transcript/transcript.rb +237 -0
- data/lib/youtube_rb/transcript/transcript_list.rb +168 -0
- data/lib/youtube_rb/transcript/transcript_list_fetcher.rb +220 -0
- data/lib/youtube_rb/transcript/transcript_parser.rb +81 -0
- data/lib/youtube_rb/transcript.rb +33 -0
- data/lib/youtube_rb/version.rb +5 -0
- data/sig/youtube_rb/transcript.rbs +4 -0
- data/spec/api_spec.rb +27 -27
- data/spec/errors_spec.rb +41 -41
- data/spec/formatters_spec.rb +45 -46
- data/spec/integration_spec.rb +39 -48
- data/spec/settings_spec.rb +16 -16
- data/spec/spec_helper.rb +52 -52
- data/spec/transcript_list_fetcher_spec.rb +38 -33
- data/spec/transcript_list_spec.rb +16 -19
- data/spec/transcript_parser_spec.rb +3 -3
- data/spec/transcript_spec.rb +23 -24
- metadata +17 -13
- data/lib/youtube/transcript/rb/api.rb +0 -150
- data/lib/youtube/transcript/rb/errors.rb +0 -217
- data/lib/youtube/transcript/rb/formatters.rb +0 -269
- data/lib/youtube/transcript/rb/settings.rb +0 -28
- data/lib/youtube/transcript/rb/transcript.rb +0 -239
- data/lib/youtube/transcript/rb/transcript_list.rb +0 -170
- data/lib/youtube/transcript/rb/transcript_list_fetcher.rb +0 -225
- data/lib/youtube/transcript/rb/transcript_parser.rb +0 -83
- data/lib/youtube/transcript/rb/version.rb +0 -9
- data/lib/youtube/transcript/rb.rb +0 -37
- data/sig/youtube/transcript/rb.rbs +0 -8
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require "spec_helper"
|
|
4
4
|
require "webmock/rspec"
|
|
5
5
|
|
|
6
|
-
RSpec.describe
|
|
6
|
+
RSpec.describe YoutubeRb::Transcript::TranscriptListFetcher do
|
|
7
7
|
let(:http_client) { Faraday.new }
|
|
8
8
|
let(:fetcher) { described_class.new(http_client: http_client) }
|
|
9
9
|
let(:video_id) { "dQw4w9WgXcQ" }
|
|
@@ -78,7 +78,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
78
78
|
|
|
79
79
|
it "returns a TranscriptList" do
|
|
80
80
|
result = fetcher.fetch(video_id)
|
|
81
|
-
expect(result).to be_a(
|
|
81
|
+
expect(result).to be_a(YoutubeRb::Transcript::TranscriptList)
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
it "returns a TranscriptList with the correct video_id" do
|
|
@@ -104,11 +104,11 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
104
104
|
|
|
105
105
|
it "includes proper body in innertube request" do
|
|
106
106
|
fetcher.fetch(video_id)
|
|
107
|
-
expect(WebMock).to
|
|
108
|
-
.with
|
|
107
|
+
expect(WebMock).to(have_requested(:post, innertube_url)
|
|
108
|
+
.with do |req|
|
|
109
109
|
body = JSON.parse(req.body)
|
|
110
110
|
body["videoId"] == video_id && body["context"]["client"]["clientName"] == "ANDROID"
|
|
111
|
-
|
|
111
|
+
end)
|
|
112
112
|
end
|
|
113
113
|
end
|
|
114
114
|
|
|
@@ -120,7 +120,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
it "raises IpBlocked error" do
|
|
123
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
123
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::IpBlocked)
|
|
124
124
|
end
|
|
125
125
|
end
|
|
126
126
|
|
|
@@ -135,7 +135,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
it "raises IpBlocked error" do
|
|
138
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
138
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::IpBlocked)
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
141
|
|
|
@@ -150,7 +150,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
it "raises YouTubeDataUnparsable error" do
|
|
153
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
153
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::YouTubeDataUnparsable)
|
|
154
154
|
end
|
|
155
155
|
end
|
|
156
156
|
|
|
@@ -169,7 +169,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
it "raises VideoUnavailable error" do
|
|
172
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
172
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::VideoUnavailable)
|
|
173
173
|
end
|
|
174
174
|
end
|
|
175
175
|
|
|
@@ -190,7 +190,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
190
190
|
end
|
|
191
191
|
|
|
192
192
|
it "raises InvalidVideoId error" do
|
|
193
|
-
expect { fetcher.fetch(url_video_id) }.to raise_error(
|
|
193
|
+
expect { fetcher.fetch(url_video_id) }.to raise_error(YoutubeRb::Transcript::InvalidVideoId)
|
|
194
194
|
end
|
|
195
195
|
end
|
|
196
196
|
|
|
@@ -209,7 +209,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
it "raises AgeRestricted error" do
|
|
212
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
212
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::AgeRestricted)
|
|
213
213
|
end
|
|
214
214
|
end
|
|
215
215
|
|
|
@@ -228,7 +228,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
228
228
|
end
|
|
229
229
|
|
|
230
230
|
it "raises RequestBlocked error" do
|
|
231
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
231
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::RequestBlocked)
|
|
232
232
|
end
|
|
233
233
|
end
|
|
234
234
|
|
|
@@ -257,7 +257,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
257
257
|
end
|
|
258
258
|
|
|
259
259
|
it "raises VideoUnplayable error" do
|
|
260
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
260
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::VideoUnplayable)
|
|
261
261
|
end
|
|
262
262
|
end
|
|
263
263
|
|
|
@@ -274,7 +274,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
274
274
|
end
|
|
275
275
|
|
|
276
276
|
it "raises TranscriptsDisabled error" do
|
|
277
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
277
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::TranscriptsDisabled)
|
|
278
278
|
end
|
|
279
279
|
end
|
|
280
280
|
|
|
@@ -290,7 +290,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
290
290
|
end
|
|
291
291
|
|
|
292
292
|
it "raises TranscriptsDisabled error" do
|
|
293
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
293
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::TranscriptsDisabled)
|
|
294
294
|
end
|
|
295
295
|
end
|
|
296
296
|
|
|
@@ -311,7 +311,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
311
311
|
end
|
|
312
312
|
|
|
313
313
|
it "raises TranscriptsDisabled error" do
|
|
314
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
314
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::TranscriptsDisabled)
|
|
315
315
|
end
|
|
316
316
|
end
|
|
317
317
|
|
|
@@ -322,7 +322,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
322
322
|
end
|
|
323
323
|
|
|
324
324
|
it "raises YouTubeRequestFailed error" do
|
|
325
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
325
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::YouTubeRequestFailed)
|
|
326
326
|
end
|
|
327
327
|
end
|
|
328
328
|
|
|
@@ -336,7 +336,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
336
336
|
end
|
|
337
337
|
|
|
338
338
|
it "raises YouTubeRequestFailed error" do
|
|
339
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
339
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::YouTubeRequestFailed)
|
|
340
340
|
end
|
|
341
341
|
end
|
|
342
342
|
end
|
|
@@ -369,7 +369,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
369
369
|
|
|
370
370
|
it "retries after setting consent cookie" do
|
|
371
371
|
result = fetcher.fetch(video_id)
|
|
372
|
-
expect(result).to be_a(
|
|
372
|
+
expect(result).to be_a(YoutubeRb::Transcript::TranscriptList)
|
|
373
373
|
expect(WebMock).to have_requested(:get, watch_url).times(2)
|
|
374
374
|
end
|
|
375
375
|
|
|
@@ -400,7 +400,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
400
400
|
end
|
|
401
401
|
|
|
402
402
|
it "raises FailedToCreateConsentCookie error" do
|
|
403
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
403
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::FailedToCreateConsentCookie)
|
|
404
404
|
end
|
|
405
405
|
end
|
|
406
406
|
|
|
@@ -411,7 +411,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
411
411
|
end
|
|
412
412
|
|
|
413
413
|
it "raises FailedToCreateConsentCookie error" do
|
|
414
|
-
expect { fetcher.fetch(video_id) }.to raise_error(
|
|
414
|
+
expect { fetcher.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::FailedToCreateConsentCookie)
|
|
415
415
|
end
|
|
416
416
|
end
|
|
417
417
|
end
|
|
@@ -441,7 +441,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
441
441
|
|
|
442
442
|
it "properly unescapes HTML entities" do
|
|
443
443
|
result = fetcher.fetch(video_id)
|
|
444
|
-
expect(result).to be_a(
|
|
444
|
+
expect(result).to be_a(YoutubeRb::Transcript::TranscriptList)
|
|
445
445
|
end
|
|
446
446
|
end
|
|
447
447
|
|
|
@@ -461,15 +461,19 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
461
461
|
|
|
462
462
|
stub_request(:post, innertube_url)
|
|
463
463
|
.to_return(
|
|
464
|
-
{ status: 200,
|
|
465
|
-
|
|
464
|
+
{ status: 200,
|
|
465
|
+
body: { "playabilityStatus" => { "status" => "LOGIN_REQUIRED",
|
|
466
|
+
"reason" => "Sign in to confirm you're not a bot" } }.to_json },
|
|
467
|
+
{ status: 200,
|
|
468
|
+
body: { "playabilityStatus" => { "status" => "LOGIN_REQUIRED",
|
|
469
|
+
"reason" => "Sign in to confirm you're not a bot" } }.to_json },
|
|
466
470
|
{ status: 200, body: sample_innertube_response.to_json }
|
|
467
471
|
)
|
|
468
472
|
end
|
|
469
473
|
|
|
470
474
|
it "retries the request" do
|
|
471
475
|
result = fetcher_with_proxy.fetch(video_id)
|
|
472
|
-
expect(result).to be_a(
|
|
476
|
+
expect(result).to be_a(YoutubeRb::Transcript::TranscriptList)
|
|
473
477
|
expect(WebMock).to have_requested(:post, innertube_url).times(3)
|
|
474
478
|
end
|
|
475
479
|
end
|
|
@@ -480,11 +484,12 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
480
484
|
.to_return(status: 200, body: sample_html)
|
|
481
485
|
|
|
482
486
|
stub_request(:post, innertube_url)
|
|
483
|
-
.to_return(status: 200, body: { "playabilityStatus" => { "status" => "LOGIN_REQUIRED",
|
|
487
|
+
.to_return(status: 200, body: { "playabilityStatus" => { "status" => "LOGIN_REQUIRED",
|
|
488
|
+
"reason" => "Sign in to confirm you're not a bot" } }.to_json)
|
|
484
489
|
end
|
|
485
490
|
|
|
486
491
|
it "raises RequestBlocked after exhausting retries" do
|
|
487
|
-
expect { fetcher_with_proxy.fetch(video_id) }.to raise_error(
|
|
492
|
+
expect { fetcher_with_proxy.fetch(video_id) }.to raise_error(YoutubeRb::Transcript::RequestBlocked)
|
|
488
493
|
expect(WebMock).to have_requested(:post, innertube_url).times(3)
|
|
489
494
|
end
|
|
490
495
|
end
|
|
@@ -492,29 +497,29 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptListFetcher do
|
|
|
492
497
|
|
|
493
498
|
describe "PlayabilityStatus module" do
|
|
494
499
|
it "defines OK status" do
|
|
495
|
-
expect(
|
|
500
|
+
expect(YoutubeRb::Transcript::PlayabilityStatus::OK).to eq("OK")
|
|
496
501
|
end
|
|
497
502
|
|
|
498
503
|
it "defines ERROR status" do
|
|
499
|
-
expect(
|
|
504
|
+
expect(YoutubeRb::Transcript::PlayabilityStatus::ERROR).to eq("ERROR")
|
|
500
505
|
end
|
|
501
506
|
|
|
502
507
|
it "defines LOGIN_REQUIRED status" do
|
|
503
|
-
expect(
|
|
508
|
+
expect(YoutubeRb::Transcript::PlayabilityStatus::LOGIN_REQUIRED).to eq("LOGIN_REQUIRED")
|
|
504
509
|
end
|
|
505
510
|
end
|
|
506
511
|
|
|
507
512
|
describe "PlayabilityFailedReason module" do
|
|
508
513
|
it "defines BOT_DETECTED reason" do
|
|
509
|
-
expect(
|
|
514
|
+
expect(YoutubeRb::Transcript::PlayabilityFailedReason::BOT_DETECTED).to eq("Sign in to confirm you're not a bot")
|
|
510
515
|
end
|
|
511
516
|
|
|
512
517
|
it "defines AGE_RESTRICTED reason" do
|
|
513
|
-
expect(
|
|
518
|
+
expect(YoutubeRb::Transcript::PlayabilityFailedReason::AGE_RESTRICTED).to eq("This video may be inappropriate for some users.")
|
|
514
519
|
end
|
|
515
520
|
|
|
516
521
|
it "defines VIDEO_UNAVAILABLE reason" do
|
|
517
|
-
expect(
|
|
522
|
+
expect(YoutubeRb::Transcript::PlayabilityFailedReason::VIDEO_UNAVAILABLE).to eq("This video is unavailable")
|
|
518
523
|
end
|
|
519
524
|
end
|
|
520
525
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
4
|
|
|
5
|
-
RSpec.describe
|
|
5
|
+
RSpec.describe YoutubeRb::Transcript::TranscriptList do
|
|
6
6
|
let(:http_client) { instance_double(Faraday::Connection) }
|
|
7
7
|
let(:video_id) { "test_video_123" }
|
|
8
8
|
|
|
@@ -141,8 +141,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptList do
|
|
|
141
141
|
|
|
142
142
|
describe "#each" do
|
|
143
143
|
it "yields each transcript" do
|
|
144
|
-
transcripts =
|
|
145
|
-
list.each { |t| transcripts << t }
|
|
144
|
+
transcripts = list.map { |t| t }
|
|
146
145
|
expect(transcripts.length).to eq(3)
|
|
147
146
|
end
|
|
148
147
|
|
|
@@ -196,22 +195,20 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptList do
|
|
|
196
195
|
end
|
|
197
196
|
|
|
198
197
|
it "tries language codes in order of priority" do
|
|
199
|
-
transcript = list.find_transcript([
|
|
198
|
+
transcript = list.find_transcript(%w[ja es en])
|
|
200
199
|
expect(transcript.language_code).to eq("es")
|
|
201
200
|
end
|
|
202
201
|
|
|
203
202
|
it "raises NoTranscriptFound when no match" do
|
|
204
|
-
expect
|
|
205
|
-
list.find_transcript([
|
|
206
|
-
|
|
203
|
+
expect do
|
|
204
|
+
list.find_transcript(%w[ja ko zh])
|
|
205
|
+
end.to raise_error(YoutubeRb::Transcript::NoTranscriptFound)
|
|
207
206
|
end
|
|
208
207
|
|
|
209
208
|
it "includes requested languages in error" do
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
expect(e.requested_language_codes).to eq(["ja", "ko"])
|
|
214
|
-
end
|
|
209
|
+
list.find_transcript(%w[ja ko])
|
|
210
|
+
rescue YoutubeRb::Transcript::NoTranscriptFound => e
|
|
211
|
+
expect(e.requested_language_codes).to eq(%w[ja ko])
|
|
215
212
|
end
|
|
216
213
|
end
|
|
217
214
|
|
|
@@ -231,15 +228,15 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptList do
|
|
|
231
228
|
end
|
|
232
229
|
|
|
233
230
|
it "does not return manually created transcripts" do
|
|
234
|
-
expect
|
|
231
|
+
expect do
|
|
235
232
|
list.find_generated_transcript(["en"])
|
|
236
|
-
|
|
233
|
+
end.to raise_error(YoutubeRb::Transcript::NoTranscriptFound)
|
|
237
234
|
end
|
|
238
235
|
|
|
239
236
|
it "raises NoTranscriptFound when no match" do
|
|
240
|
-
expect
|
|
237
|
+
expect do
|
|
241
238
|
list.find_generated_transcript(["ja"])
|
|
242
|
-
|
|
239
|
+
end.to raise_error(YoutubeRb::Transcript::NoTranscriptFound)
|
|
243
240
|
end
|
|
244
241
|
end
|
|
245
242
|
|
|
@@ -259,13 +256,13 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptList do
|
|
|
259
256
|
end
|
|
260
257
|
|
|
261
258
|
it "does not return generated transcripts" do
|
|
262
|
-
expect
|
|
259
|
+
expect do
|
|
263
260
|
list.find_manually_created_transcript(["en-auto"])
|
|
264
|
-
|
|
261
|
+
end.to raise_error(YoutubeRb::Transcript::NoTranscriptFound)
|
|
265
262
|
end
|
|
266
263
|
|
|
267
264
|
it "tries language codes in order" do
|
|
268
|
-
transcript = list.find_manually_created_transcript([
|
|
265
|
+
transcript = list.find_manually_created_transcript(%w[ja es])
|
|
269
266
|
expect(transcript.language_code).to eq("es")
|
|
270
267
|
end
|
|
271
268
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
|
-
require "
|
|
4
|
+
require "youtube_rb/transcript"
|
|
5
5
|
|
|
6
|
-
RSpec.describe
|
|
6
|
+
RSpec.describe YoutubeRb::Transcript::TranscriptParser do
|
|
7
7
|
describe "#initialize" do
|
|
8
8
|
it "creates a parser with preserve_formatting false by default" do
|
|
9
9
|
parser = described_class.new
|
|
@@ -34,7 +34,7 @@ RSpec.describe Youtube::Transcript::Rb::TranscriptParser do
|
|
|
34
34
|
result = parser.parse(xml)
|
|
35
35
|
expect(result).to be_an(Array)
|
|
36
36
|
expect(result.length).to eq(2)
|
|
37
|
-
expect(result.first).to be_a(
|
|
37
|
+
expect(result.first).to be_a(YoutubeRb::Transcript::TranscriptSnippet)
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it "parses text content correctly" do
|
data/spec/transcript_spec.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
|
-
require "
|
|
4
|
+
require "youtube_rb/transcript"
|
|
5
5
|
|
|
6
|
-
RSpec.describe
|
|
7
|
-
describe
|
|
6
|
+
RSpec.describe YoutubeRb::Transcript do
|
|
7
|
+
describe YoutubeRb::Transcript::TranslationLanguage do
|
|
8
8
|
let(:language) { described_class.new(language: "Spanish", language_code: "es") }
|
|
9
9
|
|
|
10
10
|
describe "#initialize" do
|
|
@@ -18,7 +18,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
describe
|
|
21
|
+
describe YoutubeRb::Transcript::TranscriptSnippet do
|
|
22
22
|
let(:snippet) { described_class.new(text: "Hello world", start: 1.5, duration: 2.0) }
|
|
23
23
|
|
|
24
24
|
describe "#initialize" do
|
|
@@ -58,7 +58,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
describe
|
|
61
|
+
describe YoutubeRb::Transcript::FetchedTranscript do
|
|
62
62
|
let(:transcript) do
|
|
63
63
|
described_class.new(
|
|
64
64
|
video_id: "test_video",
|
|
@@ -68,8 +68,8 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
68
68
|
)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
let(:snippet1) {
|
|
72
|
-
let(:snippet2) {
|
|
71
|
+
let(:snippet1) { YoutubeRb::Transcript::TranscriptSnippet.new(text: "Hello", start: 0.0, duration: 1.5) }
|
|
72
|
+
let(:snippet2) { YoutubeRb::Transcript::TranscriptSnippet.new(text: "World", start: 1.5, duration: 2.0) }
|
|
73
73
|
|
|
74
74
|
describe "#initialize" do
|
|
75
75
|
it "sets the video_id" do
|
|
@@ -85,7 +85,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
it "sets is_generated" do
|
|
88
|
-
expect(transcript.is_generated).to
|
|
88
|
+
expect(transcript.is_generated).to be(false)
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
it "initializes with empty snippets by default" do
|
|
@@ -131,13 +131,12 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
131
131
|
|
|
132
132
|
it "iterates over snippets" do
|
|
133
133
|
texts = transcript.map(&:text)
|
|
134
|
-
expect(texts).to eq([
|
|
134
|
+
expect(texts).to eq(%w[Hello World])
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
describe "#each" do
|
|
138
138
|
it "yields each snippet" do
|
|
139
|
-
yielded =
|
|
140
|
-
transcript.each { |s| yielded << s }
|
|
139
|
+
yielded = transcript.map { |s| s }
|
|
141
140
|
expect(yielded).to eq([snippet1, snippet2])
|
|
142
141
|
end
|
|
143
142
|
end
|
|
@@ -214,12 +213,12 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
214
213
|
end
|
|
215
214
|
end
|
|
216
215
|
|
|
217
|
-
describe
|
|
216
|
+
describe YoutubeRb::Transcript::TranscriptMetadata do
|
|
218
217
|
let(:http_client) { double("Faraday::Connection") }
|
|
219
218
|
let(:translation_languages) do
|
|
220
219
|
[
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
YoutubeRb::Transcript::TranslationLanguage.new(language: "Spanish", language_code: "es"),
|
|
221
|
+
YoutubeRb::Transcript::TranslationLanguage.new(language: "French", language_code: "fr")
|
|
223
222
|
]
|
|
224
223
|
end
|
|
225
224
|
|
|
@@ -261,7 +260,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
261
260
|
end
|
|
262
261
|
|
|
263
262
|
it "sets is_generated" do
|
|
264
|
-
expect(transcript.is_generated).to
|
|
263
|
+
expect(transcript.is_generated).to be(false)
|
|
265
264
|
end
|
|
266
265
|
|
|
267
266
|
it "sets translation_languages" do
|
|
@@ -293,15 +292,15 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
293
292
|
|
|
294
293
|
describe "#translate" do
|
|
295
294
|
it "raises NotTranslatable when not translatable" do
|
|
296
|
-
expect
|
|
295
|
+
expect do
|
|
297
296
|
transcript_without_translations.translate("es")
|
|
298
|
-
|
|
297
|
+
end.to raise_error(YoutubeRb::Transcript::NotTranslatable)
|
|
299
298
|
end
|
|
300
299
|
|
|
301
300
|
it "raises TranslationLanguageNotAvailable for unavailable language" do
|
|
302
|
-
expect
|
|
301
|
+
expect do
|
|
303
302
|
transcript.translate("de")
|
|
304
|
-
|
|
303
|
+
end.to raise_error(YoutubeRb::Transcript::TranslationLanguageNotAvailable)
|
|
305
304
|
end
|
|
306
305
|
|
|
307
306
|
it "returns a new Transcript for available language" do
|
|
@@ -347,7 +346,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
347
346
|
|
|
348
347
|
it "returns a FetchedTranscript" do
|
|
349
348
|
result = transcript.fetch
|
|
350
|
-
expect(result).to be_a(
|
|
349
|
+
expect(result).to be_a(YoutubeRb::Transcript::FetchedTranscript)
|
|
351
350
|
end
|
|
352
351
|
|
|
353
352
|
it "parses the transcript snippets" do
|
|
@@ -362,7 +361,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
362
361
|
expect(result.video_id).to eq("test_video")
|
|
363
362
|
expect(result.language).to eq("English")
|
|
364
363
|
expect(result.language_code).to eq("en")
|
|
365
|
-
expect(result.is_generated).to
|
|
364
|
+
expect(result.is_generated).to be(false)
|
|
366
365
|
end
|
|
367
366
|
|
|
368
367
|
it "raises PoTokenRequired when URL contains &exp=xpe" do
|
|
@@ -376,18 +375,18 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
376
375
|
translation_languages: []
|
|
377
376
|
)
|
|
378
377
|
|
|
379
|
-
expect { po_transcript.fetch }.to raise_error(
|
|
378
|
+
expect { po_transcript.fetch }.to raise_error(YoutubeRb::Transcript::PoTokenRequired)
|
|
380
379
|
end
|
|
381
380
|
|
|
382
381
|
context "when HTTP error occurs" do
|
|
383
382
|
it "raises IpBlocked for 429 status" do
|
|
384
383
|
allow(http_client).to receive(:get).and_return(double("Response", status: 429, body: ""))
|
|
385
|
-
expect { transcript.fetch }.to raise_error(
|
|
384
|
+
expect { transcript.fetch }.to raise_error(YoutubeRb::Transcript::IpBlocked)
|
|
386
385
|
end
|
|
387
386
|
|
|
388
387
|
it "raises YouTubeRequestFailed for 4xx/5xx status" do
|
|
389
388
|
allow(http_client).to receive(:get).and_return(double("Response", status: 500, body: ""))
|
|
390
|
-
expect { transcript.fetch }.to raise_error(
|
|
389
|
+
expect { transcript.fetch }.to raise_error(YoutubeRb::Transcript::YouTubeRequestFailed)
|
|
391
390
|
end
|
|
392
391
|
end
|
|
393
392
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: youtube-transcript-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- jeff.dean
|
|
@@ -60,6 +60,8 @@ extensions: []
|
|
|
60
60
|
extra_rdoc_files: []
|
|
61
61
|
files:
|
|
62
62
|
- ".rspec"
|
|
63
|
+
- ".rubocop.yml"
|
|
64
|
+
- ".rubocop_todo.yml"
|
|
63
65
|
- ".serena/.gitignore"
|
|
64
66
|
- ".serena/memories/code_style_and_conventions.md"
|
|
65
67
|
- ".serena/memories/project_overview.md"
|
|
@@ -71,17 +73,18 @@ files:
|
|
|
71
73
|
- PLAN.md
|
|
72
74
|
- README.md
|
|
73
75
|
- Rakefile
|
|
74
|
-
- lib/youtube
|
|
75
|
-
- lib/
|
|
76
|
-
- lib/
|
|
77
|
-
- lib/
|
|
78
|
-
- lib/
|
|
79
|
-
- lib/
|
|
80
|
-
- lib/
|
|
81
|
-
- lib/
|
|
82
|
-
- lib/
|
|
83
|
-
- lib/
|
|
84
|
-
-
|
|
76
|
+
- lib/youtube-transcript-rb.rb
|
|
77
|
+
- lib/youtube_rb/formatters.rb
|
|
78
|
+
- lib/youtube_rb/transcript.rb
|
|
79
|
+
- lib/youtube_rb/transcript/api.rb
|
|
80
|
+
- lib/youtube_rb/transcript/errors.rb
|
|
81
|
+
- lib/youtube_rb/transcript/settings.rb
|
|
82
|
+
- lib/youtube_rb/transcript/transcript.rb
|
|
83
|
+
- lib/youtube_rb/transcript/transcript_list.rb
|
|
84
|
+
- lib/youtube_rb/transcript/transcript_list_fetcher.rb
|
|
85
|
+
- lib/youtube_rb/transcript/transcript_parser.rb
|
|
86
|
+
- lib/youtube_rb/version.rb
|
|
87
|
+
- sig/youtube_rb/transcript.rbs
|
|
85
88
|
- spec/api_spec.rb
|
|
86
89
|
- spec/errors_spec.rb
|
|
87
90
|
- spec/formatters_spec.rb
|
|
@@ -98,6 +101,7 @@ licenses:
|
|
|
98
101
|
metadata:
|
|
99
102
|
bug_tracker_uri: https://github.com/stadia/youtube-transcript-rb/issues
|
|
100
103
|
documentation_uri: https://github.com/stadia/youtube-transcript-rb#readme
|
|
104
|
+
rubygems_mfa_required: 'true'
|
|
101
105
|
rdoc_options: []
|
|
102
106
|
require_paths:
|
|
103
107
|
- lib
|
|
@@ -112,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
112
116
|
- !ruby/object:Gem::Version
|
|
113
117
|
version: '0'
|
|
114
118
|
requirements: []
|
|
115
|
-
rubygems_version:
|
|
119
|
+
rubygems_version: 4.0.3
|
|
116
120
|
specification_version: 4
|
|
117
121
|
summary: Fetch YouTube video transcripts and subtitles
|
|
118
122
|
test_files: []
|