yt-dlp.rb 0.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 +7 -0
- data/.github/workflows/ci.yml +54 -0
- data/.gitignore +16 -0
- data/.rubocop.yml +11 -0
- data/.rubocop_todo.yml +135 -0
- data/.ruby-version +1 -0
- data/1.0_RELEASE_GOALS.md +7 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +62 -0
- data/Rakefile +28 -0
- data/lib/yt-dlp/options.rb +179 -0
- data/lib/yt-dlp/runner.rb +99 -0
- data/lib/yt-dlp/support.rb +60 -0
- data/lib/yt-dlp/version.rb +11 -0
- data/lib/yt-dlp/video.rb +129 -0
- data/lib/yt-dlp.rb +61 -0
- data/vendor/bin/yt-dlp +0 -0
- data/vendor/bin/yt-dlp.exe +0 -0
- data/yt-dlp.rb.gemspec +30 -0
- metadata +146 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 5376972dc27fa3ad59be7ba8c80c0ff9a5046854aefbdf3a33fca45433fc1c16
|
|
4
|
+
data.tar.gz: e96a6c8677803fb682bb03c7add405dc0a20c38b49997696dac30b4f66cefa31
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: cf93abf7e6ece1e46dc3a116c2a8220b2018654c2d34c152379b690bb60fbe2f0aea0f557e60544fa1a4c415c8d7cdd11c1041fde5924163eefe0f1295eea971
|
|
7
|
+
data.tar.gz: 8c4beb1285df288c15fe9b2cfb63c628f17ee77752ee82bd856f8faccaebc470ab6bd36203c574d708d2d89d09960a979cf391aa60d9a0fceaf0d8efc7bbd684
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
ruby_dependencies:
|
|
11
|
+
name: Ruby - download and cache dependencies
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout code
|
|
16
|
+
uses: actions/checkout@v2
|
|
17
|
+
|
|
18
|
+
- name: Setup Ruby
|
|
19
|
+
uses: ruby/setup-ruby@v1
|
|
20
|
+
|
|
21
|
+
- name: Ruby gem cache
|
|
22
|
+
uses: actions/cache@v1
|
|
23
|
+
with:
|
|
24
|
+
path: vendor/bundle
|
|
25
|
+
key: gems-${{ hashFiles('**/Gemfile.lock') }}
|
|
26
|
+
restore-keys: gems-
|
|
27
|
+
|
|
28
|
+
- name: Install gems
|
|
29
|
+
run: bundle install --jobs 4 --retry 3 --path vendor/bundle
|
|
30
|
+
|
|
31
|
+
tests:
|
|
32
|
+
name: Run tests
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
needs: ruby_dependencies
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout code
|
|
38
|
+
uses: actions/checkout@v2
|
|
39
|
+
|
|
40
|
+
- name: Setup Ruby
|
|
41
|
+
uses: ruby/setup-ruby@v1
|
|
42
|
+
|
|
43
|
+
- name: Ruby gem cache
|
|
44
|
+
uses: actions/cache@v1
|
|
45
|
+
with:
|
|
46
|
+
path: vendor/bundle
|
|
47
|
+
key: gems-${{ hashFiles('**/Gemfile.lock') }}
|
|
48
|
+
restore-keys: gems-
|
|
49
|
+
|
|
50
|
+
- name: Install gems
|
|
51
|
+
run: bundle install --jobs 4 --retry 3 --path vendor/bundle
|
|
52
|
+
|
|
53
|
+
- name: Run tests
|
|
54
|
+
run: bundle exec rake test
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2015-10-19 08:34:35 -0400 using RuboCop version 0.34.2.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 7
|
|
10
|
+
Lint/AmbiguousRegexpLiteral:
|
|
11
|
+
Exclude:
|
|
12
|
+
- 'test/yt-dlp/runner_test.rb'
|
|
13
|
+
- 'test/yt-dlp/support_test.rb'
|
|
14
|
+
- 'test/yt-dlp_test.rb'
|
|
15
|
+
|
|
16
|
+
# Offense count: 1
|
|
17
|
+
Lint/Debugger:
|
|
18
|
+
Exclude:
|
|
19
|
+
- 'tmp/parse_formats.rb'
|
|
20
|
+
|
|
21
|
+
# Offense count: 2
|
|
22
|
+
# Cop supports --auto-correct.
|
|
23
|
+
Lint/DeprecatedClassMethods:
|
|
24
|
+
Exclude:
|
|
25
|
+
- 'test/yt-dlp/runner_test.rb'
|
|
26
|
+
- 'test/yt-dlp/support_test.rb'
|
|
27
|
+
|
|
28
|
+
# Offense count: 3
|
|
29
|
+
Metrics/AbcSize:
|
|
30
|
+
Max: 22
|
|
31
|
+
|
|
32
|
+
# Offense count: 3
|
|
33
|
+
# Configuration parameters: CountComments.
|
|
34
|
+
Metrics/MethodLength:
|
|
35
|
+
Max: 14
|
|
36
|
+
|
|
37
|
+
# Offense count: 2
|
|
38
|
+
# Cop supports --auto-correct.
|
|
39
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
40
|
+
Style/AccessModifierIndentation:
|
|
41
|
+
Enabled: false
|
|
42
|
+
|
|
43
|
+
# Offense count: 1
|
|
44
|
+
# Cop supports --auto-correct.
|
|
45
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
|
|
46
|
+
Style/BlockDelimiters:
|
|
47
|
+
Enabled: false
|
|
48
|
+
|
|
49
|
+
# Offense count: 2
|
|
50
|
+
# Cop supports --auto-correct.
|
|
51
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
52
|
+
Style/BracesAroundHashParameters:
|
|
53
|
+
Exclude:
|
|
54
|
+
- 'test/yt-dlp/output_test.rb'
|
|
55
|
+
- 'test/yt-dlp/runner_test.rb'
|
|
56
|
+
|
|
57
|
+
# Offense count: 1
|
|
58
|
+
# Configuration parameters: Exclude.
|
|
59
|
+
Style/Documentation:
|
|
60
|
+
Exclude:
|
|
61
|
+
- 'lib/yt-dlp/version.rb'
|
|
62
|
+
|
|
63
|
+
# Offense count: 1
|
|
64
|
+
# Cop supports --auto-correct.
|
|
65
|
+
Style/EmptyLinesAroundAccessModifier:
|
|
66
|
+
Exclude:
|
|
67
|
+
- 'lib/yt-dlp/video.rb'
|
|
68
|
+
|
|
69
|
+
# Offense count: 1
|
|
70
|
+
# Cop supports --auto-correct.
|
|
71
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
72
|
+
Style/EmptyLinesAroundClassBody:
|
|
73
|
+
Exclude:
|
|
74
|
+
- 'lib/yt-dlp/output.rb'
|
|
75
|
+
|
|
76
|
+
# Offense count: 5
|
|
77
|
+
# Cop supports --auto-correct.
|
|
78
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
79
|
+
Style/EmptyLinesAroundModuleBody:
|
|
80
|
+
Exclude:
|
|
81
|
+
- 'lib/yt-dlp/output.rb'
|
|
82
|
+
- 'lib/yt-dlp/runner.rb'
|
|
83
|
+
- 'lib/yt-dlp/support.rb'
|
|
84
|
+
- 'lib/yt-dlp/video.rb'
|
|
85
|
+
|
|
86
|
+
# Offense count: 2
|
|
87
|
+
# Configuration parameters: Exclude.
|
|
88
|
+
Style/FileName:
|
|
89
|
+
Exclude:
|
|
90
|
+
- 'lib/yt-dlp.rb'
|
|
91
|
+
- 'test/yt-dlp_test.rb'
|
|
92
|
+
|
|
93
|
+
# Offense count: 1
|
|
94
|
+
Style/ModuleFunction:
|
|
95
|
+
Exclude:
|
|
96
|
+
- 'lib/yt-dlp.rb'
|
|
97
|
+
|
|
98
|
+
# Offense count: 1
|
|
99
|
+
# Cop supports --auto-correct.
|
|
100
|
+
# Configuration parameters: AllowMultipleReturnValues.
|
|
101
|
+
Style/RedundantReturn:
|
|
102
|
+
Exclude:
|
|
103
|
+
- 'lib/yt-dlp/support.rb'
|
|
104
|
+
|
|
105
|
+
# Offense count: 1
|
|
106
|
+
# Cop supports --auto-correct.
|
|
107
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
|
|
108
|
+
Style/RegexpLiteral:
|
|
109
|
+
Exclude:
|
|
110
|
+
- 'test/yt-dlp_test.rb'
|
|
111
|
+
|
|
112
|
+
# Offense count: 3
|
|
113
|
+
# Cop supports --auto-correct.
|
|
114
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
115
|
+
Style/SpaceAroundEqualsInParameterDefault:
|
|
116
|
+
Enabled: false
|
|
117
|
+
|
|
118
|
+
# Offense count: 12
|
|
119
|
+
# Cop supports --auto-correct.
|
|
120
|
+
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles.
|
|
121
|
+
Style/SpaceInsideHashLiteralBraces:
|
|
122
|
+
Enabled: false
|
|
123
|
+
|
|
124
|
+
# Offense count: 2
|
|
125
|
+
# Cop supports --auto-correct.
|
|
126
|
+
Style/SpecialGlobalVars:
|
|
127
|
+
Exclude:
|
|
128
|
+
- 'test/test_helper.rb'
|
|
129
|
+
- 'tmp/parse_formats.rb'
|
|
130
|
+
|
|
131
|
+
# Offense count: 22
|
|
132
|
+
# Cop supports --auto-correct.
|
|
133
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
134
|
+
Style/StringLiterals:
|
|
135
|
+
Enabled: false
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.7.2
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
yt-dlp.rb hits 1.0 when:
|
|
2
|
+
|
|
3
|
+
* [x] It works on all major Unix platforms
|
|
4
|
+
* [x] It works on Windows
|
|
5
|
+
* [ ] It fully supports all features of yt-dlp in a Ruby-friendly way
|
|
6
|
+
* [ ] It supports logging
|
|
7
|
+
* [ ] [It uses v1.0 Terrapin](https://github.com/thoughtbot/terrapin/blob/master/GOALS)
|
data/Gemfile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
|
+
|
|
5
|
+
# Specify your gem's dependencies in yt-dlp.rb.gemspec
|
|
6
|
+
gemspec
|
|
7
|
+
|
|
8
|
+
gem 'erb'
|
|
9
|
+
|
|
10
|
+
group :development do
|
|
11
|
+
gem 'rubocop', '~> 1.22', '>= 1.22.3'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
group :extras do
|
|
15
|
+
gem 'byebug'
|
|
16
|
+
gem 'm'
|
|
17
|
+
end
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2015 sapslaj
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# yt-dlp
|
|
2
|
+
|
|
3
|
+
Wrapper for the [yt-dlp](https://github.com/yt-dlp/yt-dlp) video download tool. This gem is heavily inspired by the youtube_dl.rb gem
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## Install the gem
|
|
9
|
+
|
|
10
|
+
Add this line to your application's Gemfile:
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
gem 'yt-dlp.rb'
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
And then execute:
|
|
17
|
+
|
|
18
|
+
$ bundle
|
|
19
|
+
|
|
20
|
+
Or install it yourself as:
|
|
21
|
+
|
|
22
|
+
$ gem install yt-dlp.rb
|
|
23
|
+
|
|
24
|
+
## Install yt-dlp
|
|
25
|
+
This gem ships with the latest (working) version of yt-dlp built-in, so you don't have to install yt-dlp at all! Unless you want to.
|
|
26
|
+
|
|
27
|
+
Some features of yt-dlp require ffmpeg or avconf to be installed. Normally these are available for installation from your distribution's repositories.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
Pretty simple.
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
YtDlp.download "https://www.youtube.com/watch?v=gvdf5n-zI14", output: 'some_file.mp4'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
All options available to yt-dlp can be passed to the options hash
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
options = {
|
|
41
|
+
username: 'someone',
|
|
42
|
+
password: 'password1',
|
|
43
|
+
rate_limit: '50K',
|
|
44
|
+
format: :worst,
|
|
45
|
+
continue: false
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
YtDlp.download "https://www.youtube.com/watch?v=gvdf5n-zI14", options
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Options passed as `options = {option: true}` or `options = {option: false}` are passed to yt-dlp as `--option` or `--no-option`
|
|
52
|
+
|
|
53
|
+
## Contributing
|
|
54
|
+
|
|
55
|
+
1. Fork it
|
|
56
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
57
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
58
|
+
4. Pass test suite (`rake test`)
|
|
59
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
|
60
|
+
6. Create a new Pull Request
|
|
61
|
+
|
|
62
|
+
Remember: commit now, commit often.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rake/testtask'
|
|
5
|
+
require 'erb'
|
|
6
|
+
|
|
7
|
+
Rake::TestTask.new do |t|
|
|
8
|
+
t.pattern = 'test/**/*_test.rb'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
task default: [:test]
|
|
12
|
+
|
|
13
|
+
namespace :binaries do
|
|
14
|
+
def get_binaries(version)
|
|
15
|
+
puts 'Updating python script'
|
|
16
|
+
system("wget -O ./vendor/bin/yt-dlp https://github.com/yt-dlp/yt-dlp/releases/download/#{version}/yt-dlp")
|
|
17
|
+
puts 'Updating Windows EXE'
|
|
18
|
+
system("wget -O ./vendor/bin/yt-dlp.exe https://github.com/yt-dlp/yt-dlp/releases/download/#{version}/yt-dlp.exe")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc 'Get binaries for specific version (run with `rake binaries:version[2015.07.07]`)'
|
|
22
|
+
task :version, [:ver] do |_t, a|
|
|
23
|
+
get_binaries(a[:ver])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
__END__
|
|
28
|
+
# Version file
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module YtDlp
|
|
4
|
+
# Option and configuration getting, setting, and storage, and all that
|
|
5
|
+
class Options
|
|
6
|
+
# @return [Hash] key value storage object
|
|
7
|
+
attr_accessor :store
|
|
8
|
+
|
|
9
|
+
# @return [Array] array of keys that won't be saved to the options store
|
|
10
|
+
attr_accessor :banned_keys
|
|
11
|
+
|
|
12
|
+
# Options initializer
|
|
13
|
+
#
|
|
14
|
+
# @param options [Hash] a hash of options
|
|
15
|
+
def initialize(options = {})
|
|
16
|
+
@store = if options.is_a? Hash
|
|
17
|
+
options
|
|
18
|
+
else
|
|
19
|
+
options.to_h
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
@banned_keys = []
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns options as a hash
|
|
26
|
+
#
|
|
27
|
+
# @return [Hash] hash of options
|
|
28
|
+
def to_hash
|
|
29
|
+
remove_banned
|
|
30
|
+
@store
|
|
31
|
+
end
|
|
32
|
+
alias to_h to_hash
|
|
33
|
+
|
|
34
|
+
# Iterate through the paramized keys and values.
|
|
35
|
+
#
|
|
36
|
+
# @yield [paramized_key, value]
|
|
37
|
+
# @return [Object] @store
|
|
38
|
+
#
|
|
39
|
+
# TODO: Enumerable?
|
|
40
|
+
def each_paramized
|
|
41
|
+
@store.each do |key, value|
|
|
42
|
+
yield(paramize(key), value)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Iterate through the keys and their paramized counterparts.
|
|
47
|
+
#
|
|
48
|
+
# @yield [key, paramized_key]
|
|
49
|
+
# @return [Object] @store
|
|
50
|
+
def each_paramized_key
|
|
51
|
+
@store.each_key do |key|
|
|
52
|
+
yield(key, paramize(key))
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Set options using a block
|
|
57
|
+
#
|
|
58
|
+
# @yield [config] self
|
|
59
|
+
def configure
|
|
60
|
+
yield(self) if block_given?
|
|
61
|
+
remove_banned
|
|
62
|
+
self
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Get option with brackets syntax
|
|
66
|
+
#
|
|
67
|
+
# @param key [Object] key
|
|
68
|
+
# @return [Object] value
|
|
69
|
+
def [](key)
|
|
70
|
+
remove_banned
|
|
71
|
+
return nil if banned? key
|
|
72
|
+
|
|
73
|
+
@store[key.to_sym]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Set option with brackets syntax
|
|
77
|
+
#
|
|
78
|
+
# @param key [Object] key
|
|
79
|
+
# @param value [Object] value
|
|
80
|
+
# @return [Object] whatever Hash#= returns
|
|
81
|
+
def []=(key, value)
|
|
82
|
+
remove_banned
|
|
83
|
+
return if banned? key
|
|
84
|
+
|
|
85
|
+
@store[key.to_sym] = value
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Merge options with given hash, removing banned keys, and returning a
|
|
89
|
+
# new instance of Options.
|
|
90
|
+
#
|
|
91
|
+
# @param hash [Hash] Hash to merge options with
|
|
92
|
+
# @return [YtDlp::Options] Merged Options instance
|
|
93
|
+
def with(hash)
|
|
94
|
+
merged = Options.new(@store.merge(hash.to_h))
|
|
95
|
+
merged.banned_keys = @banned_keys
|
|
96
|
+
merged.send(:remove_banned)
|
|
97
|
+
merged
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Option getting and setting using ghost methods
|
|
101
|
+
#
|
|
102
|
+
# @param method [Symbol] method name
|
|
103
|
+
# @param args [Array] list of arguments passed
|
|
104
|
+
# @param block [Proc] implicit block given
|
|
105
|
+
# @return [Object] the value of method in the options store
|
|
106
|
+
def method_missing(method, *args, &_block)
|
|
107
|
+
remove_banned
|
|
108
|
+
if method.to_s.include? '='
|
|
109
|
+
method = method.to_s.tr('=', '').to_sym
|
|
110
|
+
return nil if banned? method
|
|
111
|
+
|
|
112
|
+
@store[method] = args.first
|
|
113
|
+
else
|
|
114
|
+
return nil if banned? method
|
|
115
|
+
|
|
116
|
+
@store[method]
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Calls a block to do operations on keys
|
|
121
|
+
# See sanitize_keys! for examples
|
|
122
|
+
#
|
|
123
|
+
# @param block [Proc] Block with operations on keys
|
|
124
|
+
# @yieldparam key [Object] Original key
|
|
125
|
+
# @yieldreturn [Object] Manipulated key
|
|
126
|
+
def manipulate_keys!(&block)
|
|
127
|
+
@store.keys.each do |old_name|
|
|
128
|
+
new_name = block.call(old_name)
|
|
129
|
+
unless new_name == old_name
|
|
130
|
+
@store[new_name] = @store[old_name]
|
|
131
|
+
@store.delete(old_name)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Symbolizes and sanitizes keys in the option store
|
|
137
|
+
#
|
|
138
|
+
# @return [Object] @store
|
|
139
|
+
def sanitize_keys!
|
|
140
|
+
# Symbolize
|
|
141
|
+
manipulate_keys! { |key_name| key_name.is_a?(Symbol) ? key_name : key_name.to_sym }
|
|
142
|
+
|
|
143
|
+
# Underscoreize (because Terrapin doesn't like hyphens)
|
|
144
|
+
manipulate_keys! { |key_name| key_name.to_s.tr('-', '_').to_sym }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Symbolizes and sanitizes keys and returns a copy of self
|
|
148
|
+
#
|
|
149
|
+
# @return [YtDlp::Options] Options with sanitized keys.
|
|
150
|
+
def sanitize_keys
|
|
151
|
+
safe_copy = dup
|
|
152
|
+
safe_copy.sanitize_keys!
|
|
153
|
+
safe_copy
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Check if key is a banned key
|
|
157
|
+
#
|
|
158
|
+
# @param key [Object] key to check
|
|
159
|
+
# @return [Boolean] true if key is banned, false if not.
|
|
160
|
+
def banned?(key)
|
|
161
|
+
@banned_keys.include? key
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
# Helper function to convert option keys into command-line-friendly parameters
|
|
167
|
+
#
|
|
168
|
+
# @param key [Symbol, String] key to paramize
|
|
169
|
+
# @return [String] paramized key
|
|
170
|
+
def paramize(key)
|
|
171
|
+
key.to_s.tr('_', '-')
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Helper to remove banned keys from store
|
|
175
|
+
def remove_banned
|
|
176
|
+
@store.delete_if { |key, _value| banned? key }
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module YtDlp
|
|
4
|
+
# Utility class for running and managing yt-dlp
|
|
5
|
+
class Runner
|
|
6
|
+
include YtDlp::Support
|
|
7
|
+
|
|
8
|
+
# @return [String] URL to download
|
|
9
|
+
attr_accessor :url
|
|
10
|
+
|
|
11
|
+
# @return [YtDlp::Options] Options access.
|
|
12
|
+
attr_accessor :options
|
|
13
|
+
|
|
14
|
+
# @return [String] Executable path
|
|
15
|
+
attr_reader :executable_path
|
|
16
|
+
|
|
17
|
+
# @return [String] Executable name to use
|
|
18
|
+
attr_accessor :executable
|
|
19
|
+
|
|
20
|
+
# Command Line runner initializer
|
|
21
|
+
#
|
|
22
|
+
# @param url [String] URL to pass to yt-dlp executable
|
|
23
|
+
# @param options [Hash, Options] options to pass to the executable. Automatically converted to Options if it isn't already
|
|
24
|
+
def initialize(url, options = {})
|
|
25
|
+
@url = url
|
|
26
|
+
@options = YtDlp::Options.new(options)
|
|
27
|
+
@executable = 'yt-dlp'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns usable executable path for yt-dlp
|
|
31
|
+
#
|
|
32
|
+
# @return [String] usable executable path for yt-dlp
|
|
33
|
+
def executable_path
|
|
34
|
+
@executable_path ||= usable_executable_path_for(@executable)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns Terrapin's runner engine
|
|
38
|
+
#
|
|
39
|
+
# @return [CommandLineRunner] backend runner class
|
|
40
|
+
def backend_runner
|
|
41
|
+
Terrapin::CommandLine.runner
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Sets Terrapin's runner engine
|
|
45
|
+
#
|
|
46
|
+
# @param terrapin_runner [CommandLineRunner] backend runner class
|
|
47
|
+
# @return [Object] whatever Terrapin::CommandLine.runner= returns.
|
|
48
|
+
def backend_runner=(terrapin_runner)
|
|
49
|
+
Terrapin::CommandLine.runner = terrapin_runner
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns the command string without running anything
|
|
53
|
+
#
|
|
54
|
+
# @return [String] command line string
|
|
55
|
+
def to_command
|
|
56
|
+
terrapin_line(options_to_commands).command(@options.store)
|
|
57
|
+
end
|
|
58
|
+
alias command to_command
|
|
59
|
+
|
|
60
|
+
# Runs the command
|
|
61
|
+
#
|
|
62
|
+
# @return [String] the output of yt-dlp
|
|
63
|
+
def run
|
|
64
|
+
terrapin_line(options_to_commands).run(@options.store)
|
|
65
|
+
end
|
|
66
|
+
alias download run
|
|
67
|
+
|
|
68
|
+
# Options configuration.
|
|
69
|
+
# Just aliases to options.configure
|
|
70
|
+
#
|
|
71
|
+
# @yield [config] options
|
|
72
|
+
# @param a [Array] arguments to pass to options#configure
|
|
73
|
+
# @param b [Proc] block to pass to options#configure
|
|
74
|
+
def configure(*a, &b)
|
|
75
|
+
options.configure(*a, &b)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
# Parses options and converts them to Terrapin's syntax
|
|
81
|
+
#
|
|
82
|
+
# @return [String] commands ready to do terrapin
|
|
83
|
+
def options_to_commands
|
|
84
|
+
commands = []
|
|
85
|
+
@options.sanitize_keys.each_paramized_key do |key, paramized_key|
|
|
86
|
+
case @options[key].to_s
|
|
87
|
+
when 'true'
|
|
88
|
+
commands.push "--#{paramized_key}"
|
|
89
|
+
when 'false'
|
|
90
|
+
commands.push "--no-#{paramized_key}"
|
|
91
|
+
else
|
|
92
|
+
commands.push "--#{paramized_key} :#{key}"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
commands.push quoted(url)
|
|
96
|
+
commands.join(' ')
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module YtDlp
|
|
4
|
+
# Some support methods and glue logic.
|
|
5
|
+
module Support
|
|
6
|
+
# Returns a usable yt-dlp executable (system or vendor)
|
|
7
|
+
#
|
|
8
|
+
# @param exe [String] Executable to search for
|
|
9
|
+
# @return [String] executable path
|
|
10
|
+
def usable_executable_path_for(exe)
|
|
11
|
+
system_path = which(exe)
|
|
12
|
+
if system_path.nil?
|
|
13
|
+
# TODO: Search vendor bin for executable before just saying it's there.
|
|
14
|
+
vendor_path = File.absolute_path("#{__FILE__}/../../../vendor/bin/#{exe}")
|
|
15
|
+
File.chmod(775, vendor_path) unless File.executable?(vendor_path) # Make sure vendor binary is executable
|
|
16
|
+
vendor_path
|
|
17
|
+
else
|
|
18
|
+
system_path.strip
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
alias executable_path_for usable_executable_path_for
|
|
23
|
+
|
|
24
|
+
# Helper for doing lines of terrapin (initializing, auto executable stuff, etc)
|
|
25
|
+
#
|
|
26
|
+
# @param command [String] command switches to run
|
|
27
|
+
# @param executable_path [String] executable to run. Defaults to usable yt-dlp.
|
|
28
|
+
# @return [Terrapin::CommandLine] initialized Terrapin instance
|
|
29
|
+
def terrapin_line(command, executable_path = nil)
|
|
30
|
+
executable_path = executable_path_for('yt-dlp') if executable_path.nil?
|
|
31
|
+
Terrapin::CommandLine.new(executable_path, command)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Helper to add quotes to beginning and end of a URL or whatever you want....
|
|
35
|
+
#
|
|
36
|
+
# @param url [String] Raw URL
|
|
37
|
+
# @return [String] Quoted URL
|
|
38
|
+
def quoted(url)
|
|
39
|
+
"\"#{url}\""
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Cross-platform way of finding an executable in the $PATH.
|
|
43
|
+
# Stolen from http://stackoverflow.com/a/5471032
|
|
44
|
+
#
|
|
45
|
+
# which('ruby') #=> /usr/bin/ruby
|
|
46
|
+
#
|
|
47
|
+
# @param cmd [String] cmd to search for
|
|
48
|
+
# @return [String] full path for the cmd
|
|
49
|
+
def which(cmd)
|
|
50
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
|
51
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
|
52
|
+
exts.each do |ext|
|
|
53
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
|
54
|
+
return exe if File.executable?(exe) && !File.directory?(exe)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Version file
|
|
4
|
+
# If you are updating this code, make sure you are updating
|
|
5
|
+
# lib/yt-dlp/version.rb as well as the Rakefile.
|
|
6
|
+
|
|
7
|
+
module YtDlp
|
|
8
|
+
# Semantic Version as well as the bundled binary version.
|
|
9
|
+
# "(major).(minor).(teeny).(pre-release).(binary-version)"
|
|
10
|
+
VERSION = '0.1.0'
|
|
11
|
+
end
|
data/lib/yt-dlp/video.rb
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module YtDlp
|
|
4
|
+
# Video model for using and downloading a single video.
|
|
5
|
+
class Video < Runner
|
|
6
|
+
class << self
|
|
7
|
+
# Instantiate a new Video model and download the video
|
|
8
|
+
#
|
|
9
|
+
# YtDlp.download 'https://www.youtube.com/watch?v=KLRDLIIl8bA' # => #<YtDlp::Video:0x00000000000000>
|
|
10
|
+
# YtDlp.get 'https://www.youtube.com/watch?v=ia1diPnNBgU', extract_audio: true, audio_quality: 0
|
|
11
|
+
#
|
|
12
|
+
# @param url [String] URL to use and download
|
|
13
|
+
# @param options [Hash] Options to pass in
|
|
14
|
+
# @return [YtDlp::Video] new Video model
|
|
15
|
+
def download(url, options = {})
|
|
16
|
+
video = new(url, options)
|
|
17
|
+
video.download
|
|
18
|
+
video
|
|
19
|
+
end
|
|
20
|
+
alias get download
|
|
21
|
+
|
|
22
|
+
def information(url, options = {})
|
|
23
|
+
video = new(url, options)
|
|
24
|
+
video.information
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [YtDlp::Options] Download Options for the last download
|
|
29
|
+
attr_reader :download_options
|
|
30
|
+
|
|
31
|
+
# Instantiate new model
|
|
32
|
+
#
|
|
33
|
+
# @param url [String] URL to initialize with
|
|
34
|
+
# @param options [Hash] Options to populate the everything with
|
|
35
|
+
def initialize(url, options = {})
|
|
36
|
+
@url = url
|
|
37
|
+
@options = YtDlp::Options.new(options.merge(default_options))
|
|
38
|
+
@options.banned_keys = banned_keys
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Download the video.
|
|
42
|
+
def download
|
|
43
|
+
raise ArgumentError, 'url cannot be nil' if @url.nil?
|
|
44
|
+
raise ArgumentError, 'url cannot be empty' if @url.empty?
|
|
45
|
+
|
|
46
|
+
set_information_from_json(YtDlp::Runner.new(url, runner_options).run)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
alias get download
|
|
50
|
+
|
|
51
|
+
# Returns the expected filename
|
|
52
|
+
#
|
|
53
|
+
# @return [String] Filename downloaded to
|
|
54
|
+
def filename
|
|
55
|
+
_filename
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Metadata information for the video, gotten from --print-json
|
|
59
|
+
#
|
|
60
|
+
# @return [OpenStruct] information
|
|
61
|
+
def information
|
|
62
|
+
@information || grab_information_without_download
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Redirect methods for information getting
|
|
66
|
+
#
|
|
67
|
+
# @param method [Symbol] method name
|
|
68
|
+
# @param args [Array] method arguments
|
|
69
|
+
# @param block [Proc] explict block
|
|
70
|
+
# @return [Object] The value from @information
|
|
71
|
+
def method_missing(method, *args, &block)
|
|
72
|
+
value =
|
|
73
|
+
if information.is_a?(Array)
|
|
74
|
+
information.first[method]
|
|
75
|
+
else
|
|
76
|
+
information[method]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
if value.nil?
|
|
80
|
+
super
|
|
81
|
+
else
|
|
82
|
+
value
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
# Add in other default options here.
|
|
89
|
+
def default_options
|
|
90
|
+
{
|
|
91
|
+
color: false,
|
|
92
|
+
progress: false,
|
|
93
|
+
print_json: true
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def banned_keys
|
|
98
|
+
%i[
|
|
99
|
+
get_url
|
|
100
|
+
get_title
|
|
101
|
+
get_id
|
|
102
|
+
get_thumbnail
|
|
103
|
+
get_description
|
|
104
|
+
get_duration
|
|
105
|
+
get_filename
|
|
106
|
+
get_format
|
|
107
|
+
]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def runner_options
|
|
111
|
+
YtDlp::Options.new(@options.to_h.merge(default_options))
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def set_information_from_json(json) # :nodoc:
|
|
115
|
+
@information =
|
|
116
|
+
if json.include?("\n")
|
|
117
|
+
json.split("\n").collect do |root_node|
|
|
118
|
+
JSON.parse(root_node, symbolize_names: true)
|
|
119
|
+
end
|
|
120
|
+
else
|
|
121
|
+
JSON.parse(json, symbolize_names: true)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def grab_information_without_download # :nodoc:
|
|
126
|
+
set_information_from_json(YtDlp::Runner.new(url, runner_options.with({ skip_download: true })).run)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
data/lib/yt-dlp.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'terrapin'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'ostruct'
|
|
6
|
+
|
|
7
|
+
require 'yt-dlp/version'
|
|
8
|
+
require 'yt-dlp/support'
|
|
9
|
+
require 'yt-dlp/options'
|
|
10
|
+
require 'yt-dlp/runner'
|
|
11
|
+
require 'yt-dlp/video'
|
|
12
|
+
|
|
13
|
+
# Global YtDlp module. Contains some convenience methods and all of the business classes.
|
|
14
|
+
module YtDlp
|
|
15
|
+
extend self
|
|
16
|
+
extend Support
|
|
17
|
+
|
|
18
|
+
# Downloads given array of URLs with any options passed
|
|
19
|
+
#
|
|
20
|
+
# @param urls [String, Array] URLs to download
|
|
21
|
+
# @param options [Hash] Downloader options
|
|
22
|
+
# @return [YtDlp::Video, Array] Video model or array of Video models
|
|
23
|
+
def download(urls, options = {})
|
|
24
|
+
if urls.is_a? Array
|
|
25
|
+
urls.map { |url| YtDlp::Video.get(url, options) }
|
|
26
|
+
else
|
|
27
|
+
YtDlp::Video.get(urls, options) # Urls should be singular but oh well. url = urls. There. Go cry in a corner.
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alias get download
|
|
32
|
+
|
|
33
|
+
def information(urls, options = {})
|
|
34
|
+
if urls.is_a? Array
|
|
35
|
+
urls.map { |url| YtDlp::Video.information(url, options) }
|
|
36
|
+
else
|
|
37
|
+
YtDlp::Video.information(urls, options) # Urls should be singular but oh well. url = urls. There. Go cry in a corner.
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Lists extractors
|
|
42
|
+
#
|
|
43
|
+
# @return [Array] list of extractors
|
|
44
|
+
def extractors
|
|
45
|
+
@extractors ||= terrapin_line('--list-extractors').run.split("\n")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns yt-dlp's version
|
|
49
|
+
#
|
|
50
|
+
# @return [String] yt-dlp version
|
|
51
|
+
def binary_version
|
|
52
|
+
@binary_version ||= terrapin_line('--version').run.strip
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Returns user agent
|
|
56
|
+
#
|
|
57
|
+
# @return [String] user agent
|
|
58
|
+
def user_agent
|
|
59
|
+
@user_agent ||= terrapin_line('--dump-user-agent').run.strip
|
|
60
|
+
end
|
|
61
|
+
end
|
data/vendor/bin/yt-dlp
ADDED
|
Binary file
|
|
Binary file
|
data/yt-dlp.rb.gemspec
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require 'yt-dlp/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = 'yt-dlp.rb'
|
|
9
|
+
spec.version = YtDlp::VERSION
|
|
10
|
+
spec.authors = %w[andrepcg]
|
|
11
|
+
spec.email = ['andrepcg@gmail.com']
|
|
12
|
+
spec.summary = 'yt-dlp wrapper for Ruby'
|
|
13
|
+
spec.description = 'yt-dlp.rb is a command line wrapper for the python script yt-dlp'
|
|
14
|
+
spec.homepage = 'https://github.com/andrepcg/yt-dlp.rb'
|
|
15
|
+
spec.license = 'MIT'
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
|
+
# spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
20
|
+
spec.require_paths = ['lib']
|
|
21
|
+
spec.required_ruby_version = '>= 2.6'
|
|
22
|
+
|
|
23
|
+
spec.add_dependency 'terrapin', '>=0.6.0'
|
|
24
|
+
|
|
25
|
+
spec.add_development_dependency 'bundler', '>= 1.6'
|
|
26
|
+
spec.add_development_dependency 'codeclimate-test-reporter'
|
|
27
|
+
spec.add_development_dependency 'minitest', '~> 5.14.3'
|
|
28
|
+
spec.add_development_dependency 'purdytest'
|
|
29
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
30
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: yt-dlp.rb
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- andrepcg
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2021-11-08 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: terrapin
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.6.0
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.6.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: bundler
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.6'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.6'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: codeclimate-test-reporter
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: minitest
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 5.14.3
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 5.14.3
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: purdytest
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rake
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '10.0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '10.0'
|
|
97
|
+
description: yt-dlp.rb is a command line wrapper for the python script yt-dlp
|
|
98
|
+
email:
|
|
99
|
+
- andrepcg@gmail.com
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- ".github/workflows/ci.yml"
|
|
105
|
+
- ".gitignore"
|
|
106
|
+
- ".rubocop.yml"
|
|
107
|
+
- ".rubocop_todo.yml"
|
|
108
|
+
- ".ruby-version"
|
|
109
|
+
- 1.0_RELEASE_GOALS.md
|
|
110
|
+
- Gemfile
|
|
111
|
+
- LICENSE.txt
|
|
112
|
+
- README.md
|
|
113
|
+
- Rakefile
|
|
114
|
+
- lib/yt-dlp.rb
|
|
115
|
+
- lib/yt-dlp/options.rb
|
|
116
|
+
- lib/yt-dlp/runner.rb
|
|
117
|
+
- lib/yt-dlp/support.rb
|
|
118
|
+
- lib/yt-dlp/version.rb
|
|
119
|
+
- lib/yt-dlp/video.rb
|
|
120
|
+
- vendor/bin/yt-dlp
|
|
121
|
+
- vendor/bin/yt-dlp.exe
|
|
122
|
+
- yt-dlp.rb.gemspec
|
|
123
|
+
homepage: https://github.com/andrepcg/yt-dlp.rb
|
|
124
|
+
licenses:
|
|
125
|
+
- MIT
|
|
126
|
+
metadata: {}
|
|
127
|
+
post_install_message:
|
|
128
|
+
rdoc_options: []
|
|
129
|
+
require_paths:
|
|
130
|
+
- lib
|
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
|
+
requirements:
|
|
133
|
+
- - ">="
|
|
134
|
+
- !ruby/object:Gem::Version
|
|
135
|
+
version: '2.6'
|
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
|
+
requirements:
|
|
138
|
+
- - ">="
|
|
139
|
+
- !ruby/object:Gem::Version
|
|
140
|
+
version: '0'
|
|
141
|
+
requirements: []
|
|
142
|
+
rubygems_version: 3.1.4
|
|
143
|
+
signing_key:
|
|
144
|
+
specification_version: 4
|
|
145
|
+
summary: yt-dlp wrapper for Ruby
|
|
146
|
+
test_files: []
|