youtube-rb 0.2.0 → 0.3.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.
@@ -50,17 +50,7 @@ RSpec.describe "YoutubeRb + yt-dlp Integration", :integration do
50
50
  end
51
51
  end
52
52
 
53
- describe "backend selection" do
54
- it "creates client with yt-dlp backend enabled" do
55
- client = YoutubeRb::Client.new(use_ytdlp: true, verbose: false)
56
- expect(client.options.use_ytdlp).to be true
57
- end
58
-
59
- it "creates client with fallback mode" do
60
- client = YoutubeRb::Client.new(ytdlp_fallback: true, verbose: false)
61
- expect(client.options.ytdlp_fallback).to be true
62
- end
63
-
53
+ describe "client configuration" do
64
54
  it "creates client with verbose mode" do
65
55
  client = YoutubeRb::Client.new(verbose: true)
66
56
  expect(client.options.verbose).to be true
@@ -94,7 +84,6 @@ RSpec.describe "YoutubeRb + yt-dlp Integration", :integration do
94
84
  it "downloads video segment using yt-dlp backend" do
95
85
  client = YoutubeRb::Client.new(
96
86
  output_path: output_dir,
97
- use_ytdlp: true,
98
87
  verbose: false
99
88
  )
100
89
 
@@ -63,7 +63,6 @@ RSpec.describe "Real video downloads", :real_download do
63
63
 
64
64
  client = YoutubeRb::Client.new(
65
65
  output_path: output_dir,
66
- use_ytdlp: true,
67
66
  verbose: true
68
67
  )
69
68
 
@@ -112,7 +111,6 @@ RSpec.describe "Real video downloads", :real_download do
112
111
 
113
112
  client = YoutubeRb::Client.new(
114
113
  output_path: output_dir,
115
- use_ytdlp: true,
116
114
  verbose: true
117
115
  )
118
116
 
@@ -128,39 +126,12 @@ RSpec.describe "Real video downloads", :real_download do
128
126
  end
129
127
  end
130
128
 
131
- describe "fallback mechanism" do
132
- let(:test_url) { 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }
133
-
134
- it "falls back to yt-dlp when pure Ruby fails", :very_slow do
135
- puts "\n → Testing automatic fallback to yt-dlp"
136
- puts " → This may download ~240MB of video data..."
137
-
138
- client = YoutubeRb::Client.new(
139
- output_path: output_dir,
140
- use_ytdlp: false, # Start with pure Ruby
141
- ytdlp_fallback: true, # Enable fallback
142
- verbose: true
143
- )
144
-
145
- # This should try pure Ruby first, then fall back to yt-dlp
146
- output_file = client.download(test_url)
147
-
148
- expect(output_file).to be_a(String)
149
- expect(File.exist?(output_file)).to be true
150
- expect(File.size(output_file)).to be > 10_000_000 # At least 10MB
151
-
152
- puts " ✓ Fallback worked, file downloaded"
153
- puts " ✓ File size: #{(File.size(output_file) / 1024.0 / 1024.0).round(2)} MB"
154
- end
155
- end
156
-
157
129
  describe "error handling" do
158
130
  it "raises error for invalid video ID" do
159
131
  puts "\n → Testing error handling for invalid video"
160
132
 
161
133
  client = YoutubeRb::Client.new(
162
- output_path: output_dir,
163
- use_ytdlp: true
134
+ output_path: output_dir
164
135
  )
165
136
 
166
137
  invalid_url = 'https://www.youtube.com/watch?v=invalidvideoid'
@@ -1,18 +1,113 @@
1
+ require 'json'
2
+ require 'fileutils'
3
+
1
4
  module MockingHelper
2
- # Mock the Extractor to return video info without making HTTP requests
3
- def mock_extractor(video_data)
5
+ # Mock the YtdlpWrapper to return video info without making actual yt-dlp calls
6
+ def mock_ytdlp(video_data)
4
7
  video_info = YoutubeRb::VideoInfo.new(video_data)
5
8
 
6
- allow_any_instance_of(YoutubeRb::Extractor).to receive(:extract_info).and_return(video_info)
7
- allow_any_instance_of(YoutubeRb::Extractor).to receive(:extract_formats).and_return(video_data['formats'] || [])
8
- allow_any_instance_of(YoutubeRb::Extractor).to receive(:extract_subtitles).and_return(video_data['subtitles'] || {})
9
+ # Mock YtdlpWrapper availability
10
+ allow(YoutubeRb::YtdlpWrapper).to receive(:available?).and_return(true)
11
+
12
+ # Mock extract_info to return video data
13
+ allow_any_instance_of(YoutubeRb::YtdlpWrapper).to receive(:extract_info).and_return(video_data)
14
+
15
+ # Mock download methods - create actual files
16
+ allow_any_instance_of(YoutubeRb::YtdlpWrapper).to receive(:download) do |instance, url, output_path|
17
+ # If output_path is provided, use it; otherwise generate from options
18
+ if output_path
19
+ output_file = output_path
20
+ else
21
+ options = instance.instance_variable_get(:@options)
22
+ output_dir = options.output_path || (@test_output_dir || './test_downloads')
23
+ template = options.output_template || '%(title)s-%(id)s.%(ext)s'
24
+
25
+ # Simple template replacement
26
+ filename = template
27
+ .gsub('%(title)s', (video_data['title'] || 'video').gsub(/[\/\\:*?"<>|]/, '_'))
28
+ .gsub('%(id)s', video_data['id'] || 'unknown')
29
+ .gsub('%(ext)s', video_data['ext'] || 'mp4')
30
+
31
+ output_file = File.join(output_dir, filename)
32
+ end
33
+
34
+ # Ensure directory exists
35
+ FileUtils.mkdir_p(File.dirname(output_file))
36
+
37
+ # Create a fake video file
38
+ File.write(output_file, "fake video data" * 1000)
39
+
40
+ # Create subtitle files if requested
41
+ options = instance.instance_variable_get(:@options)
42
+ if options && (options.write_subtitles || options.write_auto_sub)
43
+ base_name = File.basename(output_file, File.extname(output_file))
44
+ subtitle_langs = options.subtitle_langs || ['en']
45
+ subtitle_format = options.subtitle_format || 'srt'
46
+ available_subtitles = video_data['subtitles'] || {}
47
+
48
+ subtitle_langs.each do |lang|
49
+ # Only create subtitle file if language is available in video data
50
+ next unless available_subtitles.key?(lang)
51
+
52
+ subtitle_file = File.join(File.dirname(output_file), "#{base_name}.#{lang}.#{subtitle_format}")
53
+ File.write(subtitle_file, "WEBVTT\n\n00:00:00.000 --> 00:00:10.000\nTest subtitle")
54
+ end
55
+ end
56
+
57
+ # Create metadata files if requested
58
+ if options
59
+ base_name = File.basename(output_file, File.extname(output_file))
60
+ dir = File.dirname(output_file)
61
+
62
+ if options.write_info_json
63
+ info_file = File.join(dir, "#{base_name}.info.json")
64
+ File.write(info_file, JSON.generate(video_data))
65
+ end
66
+
67
+ if options.write_thumbnail && video_data['thumbnail']
68
+ ext = File.extname(video_data['thumbnail']).split('?').first || '.jpg'
69
+ thumbnail_file = File.join(dir, "#{base_name}#{ext}")
70
+ File.write(thumbnail_file, "fake thumbnail data")
71
+ end
72
+
73
+ if options.write_description && video_data['description']
74
+ desc_file = File.join(dir, "#{base_name}.description")
75
+ File.write(desc_file, video_data['description'])
76
+ end
77
+ end
78
+
79
+ output_file
80
+ end
81
+
82
+ # Mock download_segment
83
+ allow_any_instance_of(YoutubeRb::YtdlpWrapper).to receive(:download_segment) do |_, url, start_time, end_time, output_path|
84
+ output_file = output_path || File.join(@test_output_dir || './test_downloads', "segment-#{start_time}-#{end_time}.mp4")
85
+
86
+ # Ensure directory exists
87
+ FileUtils.mkdir_p(File.dirname(output_file))
88
+
89
+ # Create a fake segment file
90
+ File.write(output_file, "fake segment data" * 1000)
91
+
92
+ output_file
93
+ end
9
94
 
10
95
  video_info
11
96
  end
12
97
 
13
- # Mock extractor to raise error
14
- def mock_extractor_error(error_class = YoutubeRb::Extractor::ExtractionError, message = 'Test error')
15
- allow_any_instance_of(YoutubeRb::Extractor).to receive(:extract_info).and_raise(error_class, message)
98
+ # For backward compatibility with tests that use mock_extractor
99
+ alias_method :mock_extractor, :mock_ytdlp
100
+
101
+ # Mock YtdlpWrapper to raise error
102
+ def mock_ytdlp_error(message = 'Test error')
103
+ allow(YoutubeRb::YtdlpWrapper).to receive(:available?).and_return(true)
104
+ allow_any_instance_of(YoutubeRb::YtdlpWrapper).to receive(:extract_info)
105
+ .and_raise(YoutubeRb::YtdlpWrapper::YtdlpError, message)
106
+ end
107
+
108
+ # For backward compatibility
109
+ def mock_extractor_error(error_class = nil, message = 'Test error')
110
+ mock_ytdlp_error(message)
16
111
  end
17
112
  end
18
113
 
@@ -59,8 +59,6 @@ RSpec.describe YoutubeRb do
59
59
  expect(options.format).to eq('best')
60
60
  expect(options.quality).to eq('best')
61
61
  expect(options.output_path).to eq('./downloads')
62
- expect(options.use_ytdlp).to eq(false)
63
- expect(options.ytdlp_fallback).to eq(true)
64
62
  expect(options.verbose).to eq(false)
65
63
  end
66
64
 
@@ -69,26 +67,22 @@ RSpec.describe YoutubeRb do
69
67
  format: '1080p',
70
68
  output_path: '/tmp',
71
69
  write_subtitles: true,
72
- use_ytdlp: true,
73
70
  verbose: true
74
71
  )
75
72
  expect(options.format).to eq('1080p')
76
73
  expect(options.output_path).to eq('/tmp')
77
74
  expect(options.write_subtitles).to eq(true)
78
- expect(options.use_ytdlp).to eq(true)
79
75
  expect(options.verbose).to eq(true)
80
76
  end
81
77
  end
82
78
 
83
79
  describe "#to_h" do
84
80
  it "returns hash representation" do
85
- options = YoutubeRb::Options.new(format: 'best', use_ytdlp: true)
81
+ options = YoutubeRb::Options.new(format: 'best', verbose: true)
86
82
  hash = options.to_h
87
83
  expect(hash).to be_a(Hash)
88
84
  expect(hash[:format]).to eq('best')
89
- expect(hash[:use_ytdlp]).to eq(true)
90
- expect(hash).to have_key(:ytdlp_fallback)
91
- expect(hash).to have_key(:verbose)
85
+ expect(hash[:verbose]).to eq(true)
92
86
  end
93
87
  end
94
88
 
@@ -169,16 +163,6 @@ RSpec.describe YoutubeRb do
169
163
  end
170
164
  end
171
165
 
172
- describe YoutubeRb::Extractor do
173
- let(:extractor) { YoutubeRb::Extractor.new('https://www.youtube.com/watch?v=test') }
174
-
175
- describe "#initialize" do
176
- it "creates extractor with URL" do
177
- expect(extractor.url).to eq('https://www.youtube.com/watch?v=test')
178
- end
179
- end
180
- end
181
-
182
166
  describe YoutubeRb::Downloader do
183
167
  let(:url) { 'https://www.youtube.com/watch?v=test' }
184
168
  let(:options) { YoutubeRb::Options.new(output_path: './test_downloads') }
data/youtube-rb.gemspec CHANGED
@@ -12,9 +12,9 @@ Gem::Specification.new do |spec|
12
12
  spec.license = "MIT"
13
13
  spec.required_ruby_version = ">= 3.4.0"
14
14
 
15
- spec.metadata["homepage_uri"] = spec.homepage
16
15
  spec.metadata["source_code_uri"] = "https://github.com/Qew7/youtube-rb"
17
16
  spec.metadata["changelog_uri"] = "https://github.com/Qew7/youtube-rb/blob/master/CHANGELOG.md"
17
+ spec.metadata["bug_tracker_uri"] = "https://github.com/Qew7/youtube-rb/issues"
18
18
 
19
19
  # Specify which files should be added to the gem when it is released.
20
20
  spec.files = Dir.glob("{lib,bin,spec}/**/*") + %w[README.md LICENSE Rakefile youtube-rb.gemspec]
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency "base64", "~> 0.2"
32
32
 
33
33
  # Development dependencies
34
- spec.add_development_dependency "bundler", ">= 2.7"
34
+ spec.add_development_dependency "bundler", ">= 2.0"
35
35
  spec.add_development_dependency "rake", "~> 13.0"
36
36
  spec.add_development_dependency "rspec", "~> 3.13"
37
37
  spec.add_development_dependency "webmock", "~> 3.26"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: youtube-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxim Veysgeym
@@ -99,14 +99,14 @@ dependencies:
99
99
  requirements:
100
100
  - - ">="
101
101
  - !ruby/object:Gem::Version
102
- version: '2.7'
102
+ version: '2.0'
103
103
  type: :development
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
- version: '2.7'
109
+ version: '2.0'
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: rake
112
112
  requirement: !ruby/object:Gem::Requirement
@@ -181,7 +181,6 @@ files:
181
181
  - lib/youtube-rb.rb
182
182
  - lib/youtube-rb/client.rb
183
183
  - lib/youtube-rb/downloader.rb
184
- - lib/youtube-rb/extractor.rb
185
184
  - lib/youtube-rb/options.rb
186
185
  - lib/youtube-rb/version.rb
187
186
  - lib/youtube-rb/video_info.rb
@@ -206,9 +205,9 @@ homepage: https://github.com/Qew7/youtube-rb
206
205
  licenses:
207
206
  - MIT
208
207
  metadata:
209
- homepage_uri: https://github.com/Qew7/youtube-rb
210
208
  source_code_uri: https://github.com/Qew7/youtube-rb
211
209
  changelog_uri: https://github.com/Qew7/youtube-rb/blob/master/CHANGELOG.md
210
+ bug_tracker_uri: https://github.com/Qew7/youtube-rb/issues
212
211
  rdoc_options: []
213
212
  require_paths:
214
213
  - lib