yt_downloader 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 409be4bc22c3acb2663067d21e58eb7195ada02f40bceaa4698ba92283fa491b
4
+ data.tar.gz: 4a0b0c19181defffa2c8ecd21c827f0209ee3ec3af3d3bbf416d8b7c4c9c45c0
5
+ SHA512:
6
+ metadata.gz: 5b02b839bc4f03848f92c8b66a2aabaed9ab8865e1b3a0bbfa6e4d78f84e9be5f659f6b08a6012aae74803b269fb32dc2baf53a62ae6cd6c0ef65cebb3cc94b0
7
+ data.tar.gz: 0ab9cad470141fc49dd2b51d6db413ad6190599567eb155face71057c8a5b2f942f324fa49d1148435d09ba17a0f560066710234a1ed79a11b0c0b1fe73b45b2
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # yt_downloader
2
+
3
+ ## Installation
4
+
5
+ ```shell
6
+ $ gem install yt_downloader
7
+ ```
8
+
9
+ ## Usage
10
+
11
+ ```shell
12
+ $ yt_downloader --help
13
+ Commands:
14
+ yt_downloader download
15
+ ```
16
+
17
+ ```shell
18
+ $ yt_downloader download --help
19
+ Command:
20
+ yt_downloader download
21
+
22
+ Usage:
23
+ yt_downloader download
24
+
25
+ Description:
26
+ Download audio from you tube video
27
+
28
+ Options:
29
+ --source=VALUE # Chrome json path
30
+ --parser=VALUE # Chrome json path: (chrome), default: "chrome"
31
+ --bookmark-tabs=VALUE # Chrome json path, default: "music"
32
+ --destination=VALUE # Download folder, default: "./yt_downloader/audios"
33
+ --logger-path=VALUE # Logger path, default: "./yt_downloader/logs/successful.txt"
34
+ --audio-format=VALUE # Audio format: (mp4/flac), default: "mp3"
35
+ --help, -h # Print this help
36
+
37
+ Examples:
38
+ yt_downloader download --source=/path --parser=chrome --bookmark-tabs=example,example --destination=/path --logger-path=/path audio_format=mp3
39
+ ```
40
+
41
+ ```shell
42
+ $ yt_downloader download
43
+ ```
44
+
45
+ ## Development
46
+
47
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
48
+
49
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
50
+
51
+ ## Contributing
52
+
53
+ Bug reports and pull requests are welcome on GitHub at https://github.com/radicm/yt_downloader.
54
+
55
+ ## Copyright
56
+
57
+ [RadicM](https://github.com/radicm) © 2019 - Released under the MIT License
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: :spec
data/exe/yt_downloader ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require "bundler/setup"
6
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
7
+ end
8
+
9
+ require "yt_downloader"
10
+
11
+ YtDownloader::CLI.new.call
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'hanami/cli'
4
+ require 'pathname'
5
+
6
+ require 'yt_downloader/version'
7
+ require 'yt_downloader/logger'
8
+ require 'yt_downloader/config'
9
+ require 'yt_downloader/converter'
10
+ require 'yt_downloader/parser'
11
+ require 'yt_downloader/downloader'
12
+ require 'yt_downloader/downloader/yt_dl'
13
+ require 'yt_downloader/parser/chrome'
14
+
15
+ module YtDownloader
16
+ class CLI
17
+ def call(*args)
18
+ Hanami::CLI.new(Commands).call(*args)
19
+ end
20
+
21
+ module Commands
22
+ extend Hanami::CLI::Registry
23
+
24
+ class Download < Hanami::CLI::Command
25
+ desc 'Download audio from you tube video'
26
+
27
+ option :source, default: nil, desc: 'Chrome json path'
28
+ option :parser, default: YtDownloader::Parser::CHROME, values: [YtDownloader::Parser::CHROME], desc: 'Chrome json path'
29
+ option :bookmark_tabs, default: 'music', desc: 'Chrome json path'
30
+ option :destination, default: YtDownloader::Config.destination_path, desc: 'Download folder'
31
+ option :logger_path, default: YtDownloader::Config.logger_path, desc: 'Logger path'
32
+ option :audio_format, default: YtDownloader::Config.audio_format, values: %w[mp4 flac], desc: 'Audio format'
33
+
34
+ example [
35
+ '--source=/path --parser=chrome --bookmark-tabs=example,example --destination=/path --logger-path=/path audio_format=mp3 '
36
+ ]
37
+
38
+ def call(**options)
39
+ # make sure dir structure exists
40
+ Pathname(options.fetch(:destination)).dirname.mkpath
41
+ Pathname(options.fetch(:logger_path)).dirname.mkpath
42
+
43
+ bookmark_tabs = options.fetch(:bookmark_tabs).split(',')
44
+ downloader = Downloader.new(Downloader::YTDL, destination: options.fetch(:destination), audio_format: options.fetch(:audio_format))
45
+
46
+ Converter.call(downloader: downloader,
47
+ parser: Parser.new(options.fetch(:parser)),
48
+ source: options.fetch(:source, nil),
49
+ bookmark_tabs: bookmark_tabs,
50
+ logger: Logger.new(options.fetch(:logger_path)))
51
+ end
52
+ end
53
+
54
+ register 'download', Download, aliases: ['d']
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,31 @@
1
+ module YtDownloader
2
+ class Config
3
+ MP3_FORMAT = 'mp3'.freeze
4
+ MP4_FORMAT = 'mp4'.freeze
5
+ FLAC_FORMAT = 'flac'.freeze
6
+
7
+ class << self
8
+ #TODO add support for storing config in .yml
9
+
10
+ # @return [String]
11
+ def destination_path
12
+ './yt_downloader/audios'
13
+ end
14
+
15
+ # @return [String]
16
+ def logger_path
17
+ './yt_downloader/logs/successful.txt'
18
+ end
19
+
20
+ # @return [String]
21
+ def audio_format
22
+ MP3_FORMAT
23
+ end
24
+
25
+ # @return [Array][String]
26
+ def supported_audio_formats
27
+ [MP3_FORMAT, MP4_FORMAT, FLAC_FORMAT]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module YtDownloader
2
+ class Converter
3
+
4
+ # @param [String] audio_format
5
+ # @param [Parser] parser
6
+ # @param [String] source
7
+ # @param [String] destination
8
+ # @param [Array][String] bookmark_tabs
9
+ # @param [Logger] logger
10
+ def self.call(downloader:, parser:, source:, bookmark_tabs:, logger:)
11
+ logger.info('Parsing bookmark urls')
12
+ bookmarks = parser.call(bookmark_tabs, source)
13
+
14
+ bookmarks.each_with_index do |bookmark, i|
15
+ logger.console_log("[#{i + 1}/#{bookmarks.count}] #{bookmark.name} - #{bookmark.url}")
16
+ logger.info("Starting download of #{bookmark.name} - #{bookmark.url}")
17
+
18
+ downloader.call(bookmark.url)
19
+ end
20
+ logger.console_log('Finished!')
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module YtDownloader
2
+ class Downloader
3
+
4
+ # @param [String] downloader
5
+ # @return [Downloader]
6
+ def initialize(downloader, *args)
7
+ @parser = case downloader
8
+ when YtDownloader::Downloader::YTDL
9
+ YtDownloader::Downloader::YtDl.new(*args)
10
+ else
11
+ raise "Unsupported #{downloader} parser!"
12
+ end
13
+ end
14
+
15
+ # @param [String] url
16
+ def call(url)
17
+ @parser.call(url)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module YtDownloader
2
+ class Downloader
3
+ class Base
4
+ def call
5
+ raise('Override this method!')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ require 'yt_downloader/downloader/base'
2
+
3
+ module YtDownloader
4
+ class Downloader
5
+ YTDL = 'ytdl'.freeze
6
+
7
+ class YtDl < Base
8
+ def initialize(**options)
9
+ @destination = options.fetch(:destination)
10
+ @audio_format = options.fetch(:audio_format)
11
+ end
12
+
13
+ def call(url)
14
+ # `youtube-dl -x -o #{destination}/%\\(title\\)s.%\\(ext\\)s --audio-format #{format} -f best #{bookmark.url}`
15
+ `youtube-dl -x -o #{@destination}/%\\(title\\)s.%\\(ext\\)s --audio-format #{@audio_format} -f best --external-downloader aria2c --external-downloader-args '-c -j 3 -x 3 -s 3 -k 1M' #{url}`
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ require 'logger'
2
+
3
+ module YtDownloader
4
+ class Logger
5
+ attr_reader :logger
6
+
7
+ # @param [String] file_path
8
+ # @return [Logger]
9
+ def initialize(file_path)
10
+ @logger = ::Logger.new(file_path, File::APPEND, datetime_format: '%Y-%m-%d %H:%M:%S')
11
+ end
12
+
13
+ # @param [String] message
14
+ def console_log(message)
15
+ puts message
16
+ end
17
+
18
+ # @param [String] message
19
+ def info(message)
20
+ @logger.info(message)
21
+ end
22
+
23
+ # @param [String] message
24
+ def debug(message)
25
+ @logger.debug(message)
26
+ end
27
+
28
+ # @param [String] message
29
+ def warn(message)
30
+ @logger.warn(message)
31
+ end
32
+
33
+ # @param [String] message
34
+ def error(message)
35
+ @logger.error(message)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ module YtDownloader
2
+ class Parser
3
+
4
+ # @param [String] parser
5
+ # @return [Parser]
6
+ def initialize(parser)
7
+ @parser = case parser
8
+ when YtDownloader::Parser::CHROME
9
+ YtDownloader::Parser::Chrome
10
+ else
11
+ raise "Unsupported #{parser} parser!"
12
+ end
13
+ end
14
+
15
+ # @param [Array][String] bookmark_tabs
16
+ # @param [String] source
17
+ def call(bookmark_tabs, source)
18
+ @parser.call(bookmark_tabs, source)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module YtDownloader
2
+ class Parser
3
+ class Base
4
+
5
+ # @param [Array][String] bookmark_tabs
6
+ # @param [String] bookmark_path
7
+ def self.call(bookmark_tabs, bookmark_path)
8
+ raise 'Override this method!'
9
+ end
10
+ end
11
+
12
+ class Bookmark < Struct.new(:url, :name, :tab);
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,75 @@
1
+ require 'yt_downloader/parser/base'
2
+ require 'json'
3
+
4
+ module YtDownloader
5
+ class Parser
6
+
7
+ CHROME = 'chrome'.freeze
8
+
9
+ class Chrome < Base
10
+ MAC_OSX = 'Darwin'.freeze
11
+ LINUX_OS = 'Linux'.freeze
12
+
13
+ # @param [Array][String] bookmark_tabs
14
+ # @param [String] bookmark_path
15
+ def self.call(bookmark_tabs, bookmark_path)
16
+ bookmark_path ||= bookmark_json_path
17
+ bookmark_json = JSON.parse(File.read(bookmark_path), { symbolize_names: true })
18
+ bookmarks = bookmark_json.dig(:roots, :bookmark_bar, :children)
19
+
20
+ extract_urls(bookmarks, bookmark_tabs)
21
+ end
22
+
23
+ private
24
+
25
+ # @param [Array][Hash] bookmarks
26
+ # @param [Array][String] tabs
27
+ def self.extract_urls(bookmarks, tabs)
28
+ bookmarks.inject([]) do |acc, bookmark|
29
+ if tabs.empty?
30
+ acc.concat(aggregate_bookmarks(bookmark))
31
+ else
32
+ tabs.each do |tab|
33
+ acc.concat(aggregate_bookmarks(bookmark)) if bookmark[:name] == tab
34
+ end
35
+ end
36
+
37
+ acc
38
+ end
39
+ end
40
+
41
+ # @return [String]
42
+ def self.bookmark_json_path
43
+ case os
44
+ when LINUX_OS
45
+ "/home/#{whoami}/.config/google-chrome/Default/Bookmarks"
46
+ when MAC_OSX
47
+ "/Users/#{whoami}/Library/Application Support/Google/Chrome/Default/Bookmarks"
48
+ else
49
+ raise "Unsupported #{os} os!"
50
+ end
51
+ end
52
+
53
+ # @param [Hash] bookmark
54
+ # @return [Array][Bookmark]
55
+ def self.aggregate_bookmarks(bookmark)
56
+ return [] if bookmark[:children].nil?
57
+
58
+ bookmark[:children].map { |b| Bookmark.new(*(b.values_at(:url, :name) << bookmark[:name])) }
59
+ end
60
+
61
+ # NOTE: Stub methods for testing
62
+ #
63
+ #
64
+ # @return [String]
65
+ def self.os
66
+ `echo $(uname -s)`.strip
67
+ end
68
+
69
+ # @return [String]
70
+ def self.whoami
71
+ `whoami`.strip
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YtDownloader
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,34 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path("../lib", __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require "yt_downloader/version"
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = "yt_downloader"
10
+ spec.version = YtDownloader::VERSION
11
+ spec.authors = ["RadicM"]
12
+ spec.email = ["milosrt2011@gmail.com"]
13
+
14
+ spec.summary = "You tube audio downloader"
15
+ spec.description = "Gem that helps you easly download audios from you tube"
16
+ # spec.homepage = "https://lucaguidi.com"
17
+ spec.license = "MIT"
18
+
19
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
20
+
21
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
22
+ f.match(%r{^(test|spec|features)/})
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_dependency "hanami-cli"
29
+
30
+ spec.add_development_dependency "bundler"
31
+ spec.add_development_dependency "rake"
32
+ spec.add_development_dependency "rspec"
33
+ spec.add_development_dependency "pry"
34
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yt_downloader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - RadicM
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-06-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hanami-cli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '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'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
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
+ description: Gem that helps you easly download audios from you tube
84
+ email:
85
+ - milosrt2011@gmail.com
86
+ executables:
87
+ - yt_downloader
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - Gemfile
93
+ - README.md
94
+ - Rakefile
95
+ - exe/yt_downloader
96
+ - lib/yt_downloader.rb
97
+ - lib/yt_downloader/config.rb
98
+ - lib/yt_downloader/converter.rb
99
+ - lib/yt_downloader/downloader.rb
100
+ - lib/yt_downloader/downloader/base.rb
101
+ - lib/yt_downloader/downloader/yt_dl.rb
102
+ - lib/yt_downloader/logger.rb
103
+ - lib/yt_downloader/parser.rb
104
+ - lib/yt_downloader/parser/base.rb
105
+ - lib/yt_downloader/parser/chrome.rb
106
+ - lib/yt_downloader/version.rb
107
+ - yt_downloader.gemspec
108
+ homepage:
109
+ licenses:
110
+ - MIT
111
+ metadata:
112
+ allowed_push_host: https://rubygems.org
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.7.6
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: You tube audio downloader
133
+ test_files: []