rmd 0.1.1 → 0.1.2
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/lib/rmd/version.rb +1 -1
- metadata +2 -48
- data/.bundle/config +0 -2
- data/.gitignore +0 -5
- data/.rspec +0 -2
- data/.travis.yml +0 -7
- data/Gemfile +0 -7
- data/LICENSE.txt +0 -22
- data/README.md +0 -63
- data/Rakefile +0 -10
- data/fixtures/vcr_cassettes/nhaccuatui_playlist.yml +0 -124306
- data/fixtures/vcr_cassettes/nhaccuatui_song.yml +0 -32531
- data/fixtures/vcr_cassettes/song_download.yml +0 -186
- data/fixtures/vcr_cassettes/utils_correct_url_correct.yml +0 -40
- data/fixtures/vcr_cassettes/utils_correct_url_redirect.yml +0 -41
- data/fixtures/vcr_cassettes/zing_playlist.yml +0 -69275
- data/fixtures/vcr_cassettes/zing_song.yml +0 -33334
- data/rmd.gemspec +0 -32
- data/spec/acceptants/main_spec.rb +0 -54
- data/spec/rmd/downloader_spec.rb +0 -61
- data/spec/rmd/factory_spec.rb +0 -64
- data/spec/rmd/nct/getter/key_from_page_spec.rb +0 -140
- data/spec/rmd/nct/getter/key_from_url_spec.rb +0 -113
- data/spec/rmd/nct/playlist_spec.rb +0 -46
- data/spec/rmd/nct/song_spec.rb +0 -57
- data/spec/rmd/processor_spec.rb +0 -62
- data/spec/rmd/song_playlist_adapter_spec.rb +0 -35
- data/spec/rmd/zing/playlist_spec.rb +0 -44
- data/spec/rmd/zing/song_spec.rb +0 -92
- data/spec/rmd/zing/utils/correct_url_spec.rb +0 -28
- data/spec/spec_helper.rb +0 -124
- data/spec/support/download_share_examples.rb +0 -9
- data/spec/support/playlist_share_examples.rb +0 -58
data/rmd.gemspec
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'rmd/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "rmd"
|
8
|
-
spec.version = Rmd::VERSION
|
9
|
-
spec.authors = ["Hieu Nguyen"]
|
10
|
-
spec.email = ["hieuk09@gmail.com"]
|
11
|
-
spec.summary = %q{RMD: Ruby Music Dowloader}
|
12
|
-
spec.description = %q{RMD: a music downloader written in pure ruby.}
|
13
|
-
spec.homepage = "https://github.com/hieuk09/rmd"
|
14
|
-
spec.license = "MIT"
|
15
|
-
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.executables = 'rmd'
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = ["lib"]
|
20
|
-
|
21
|
-
spec.add_dependency 'thor', '~> 0.19'
|
22
|
-
spec.add_dependency 'mechanize', '~> 2.7'
|
23
|
-
spec.add_dependency 'ruby-progressbar', '~> 1.7'
|
24
|
-
spec.add_dependency 'colorize', '~> 0.7'
|
25
|
-
|
26
|
-
spec.add_development_dependency "bundler", "~> 1.6"
|
27
|
-
spec.add_development_dependency "rake", "~> 10.1"
|
28
|
-
spec.add_development_dependency "rspec", '~> 3.1'
|
29
|
-
spec.add_development_dependency "webmock", '~> 1.20'
|
30
|
-
spec.add_development_dependency "vcr", '~> 2.9'
|
31
|
-
spec.add_development_dependency "byebug", '~> 3.5'
|
32
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RMD::Main do
|
4
|
-
describe '#download' do
|
5
|
-
let(:options) { {} }
|
6
|
-
let(:run_method) { RMD::Processor.process(link, options) }
|
7
|
-
let(:file_path) { File.expand_path("../../../#{file_name}", __FILE__) }
|
8
|
-
|
9
|
-
context 'when downloads song from nhaccuatui' do
|
10
|
-
let(:link) { 'http://www.nhaccuatui.com/bai-hat/honjitsu-mijukumono-juken-no-kamisama-ost-tv-version-tokio.tFBwsJKDGQX9.html' }
|
11
|
-
let(:file_name) { 'HonjitsuMijukumonoJukenNoKamisamaOSTTVVersion-TOKIO-3164566.mp3' }
|
12
|
-
let(:scenario) { 'nhaccuatui song'}
|
13
|
-
it_behaves_like 'download'
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'when downloads playlist from nhaccuatui' do
|
17
|
-
let(:link) { 'http://www.nhaccuatui.com/playlist/dev-playlist-dang-cap-nhat.jn0g1fg4Z6UO.html' }
|
18
|
-
let(:file_name) { 'BlazeTvSize-KajiuraYuki_35ax5_hq.mp3' }
|
19
|
-
let(:file_path) { File.expand_path("../../../#{file_name}", __FILE__) }
|
20
|
-
let(:scenario) { 'nhaccuatui playlist' }
|
21
|
-
it_behaves_like 'download'
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when downloads song from zing mp3' do
|
25
|
-
let(:link) { 'http://mp3.zing.vn/bai-hat/Bird-TV-Size-Yuya-Matsushita/ZWZCO98B.html' }
|
26
|
-
let(:file_name) { 'Bird TV Size - Yuya Matsushita.mp3' }
|
27
|
-
let(:scenario) { 'zing song' }
|
28
|
-
it_behaves_like 'download'
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'when downloads playlist from zing mp3' do
|
32
|
-
let(:link) { 'http://mp3.zing.vn/playlist/dev-playlist-zid-sincepast/IO0E698Z.html' }
|
33
|
-
let(:file_name) { 'sharp TV Size - Negoto.mp3' }
|
34
|
-
let(:scenario) { 'zing playlist' }
|
35
|
-
it_behaves_like 'download'
|
36
|
-
end
|
37
|
-
|
38
|
-
context 'when downloads song with options' do
|
39
|
-
let(:link) { 'http://mp3.zing.vn/bai-hat/Bird-TV-Size-Yuya-Matsushita/ZWZCO98B.html' }
|
40
|
-
let(:file_name) { 'Bird TV Size - Yuya Matsushita.mp3' }
|
41
|
-
let(:scenario) { 'zing song' }
|
42
|
-
let(:options) { { folder: 'tmp' } }
|
43
|
-
let(:file_path) { File.expand_path("../../../tmp/#{file_name}", __FILE__) }
|
44
|
-
|
45
|
-
it 'downloads and put to correct folder' do
|
46
|
-
VCR.use_cassette(scenario) do
|
47
|
-
capture_io { run_method }
|
48
|
-
expect(File.exists?(file_path)).to eq true
|
49
|
-
end
|
50
|
-
File.delete(file_path)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
data/spec/rmd/downloader_spec.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RMD::Downloader do
|
4
|
-
describe '.download' do
|
5
|
-
let(:link) { 'www.example/xyz/abc.mp3' }
|
6
|
-
let(:downloader) { instance_double('RMD::Downloader') }
|
7
|
-
|
8
|
-
it 'downloads' do
|
9
|
-
expect(described_class).to receive(:new).with(link, {}).and_return(downloader)
|
10
|
-
expect(downloader).to receive(:download)
|
11
|
-
described_class.download(link)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe '#download' do
|
16
|
-
let(:downloader) { described_class.new(link) }
|
17
|
-
let(:run_method) { downloader.download }
|
18
|
-
let(:scenario) { 'song download' }
|
19
|
-
let(:link) { 'http://db.gamefaqs.com/portable/3ds/file/fire_emblem_awakening_shop.txt' }
|
20
|
-
let(:file_name) { 'fire_emblem_awakening_shop.txt' }
|
21
|
-
let(:file_path) { File.expand_path("../../../#{file_name}", __FILE__) }
|
22
|
-
it_behaves_like 'download'
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#file_name' do
|
26
|
-
let(:downloader) { described_class.new(link) }
|
27
|
-
subject { downloader.send(:file_name) }
|
28
|
-
|
29
|
-
context 'when link does not have file name' do
|
30
|
-
let(:link) { 'www.example.com/playlist/abc.mp3' }
|
31
|
-
it { is_expected.to eq 'abc.mp3' }
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'when link have file name' do
|
35
|
-
let(:link) { 'www.example.com/playlist/abc.mp3?filename=abc%20xyz.mp3' }
|
36
|
-
it { is_expected.to eq 'abc xyz.mp3' }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe '#file_path' do
|
41
|
-
let(:link) { 'link' }
|
42
|
-
let(:downloader) { described_class.new(link, options) }
|
43
|
-
let(:options) { { folder: folder } }
|
44
|
-
let(:file_name) { 'file_name' }
|
45
|
-
subject { downloader.send(:file_path) }
|
46
|
-
|
47
|
-
before do
|
48
|
-
expect(downloader).to receive(:file_name).and_return(file_name).at_least(:once)
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'when option folder exists' do
|
52
|
-
let(:folder) { 'folder' }
|
53
|
-
it { is_expected.to eq 'folder/file_name' }
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'when option folder does not exist' do
|
57
|
-
let(:folder) { nil }
|
58
|
-
it { is_expected.to eq file_name }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/spec/rmd/factory_spec.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RMD::Factory do
|
4
|
-
describe '.build' do
|
5
|
-
let(:factory) { double('RMD::Factory') }
|
6
|
-
let(:link) { 'link' }
|
7
|
-
|
8
|
-
it 'builds adapter' do
|
9
|
-
expect(described_class).to receive(:new).with(link).and_return(factory)
|
10
|
-
expect(factory).to receive(:build)
|
11
|
-
described_class.build(link)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe '#build' do
|
16
|
-
let(:factory) { described_class.new(link) }
|
17
|
-
subject(:result) { factory.build }
|
18
|
-
|
19
|
-
context 'when link belongs to nhaccuatui website' do
|
20
|
-
context 'when link is song link' do
|
21
|
-
let(:link) { 'www.nhaccuatui.com/bai-hat/song.mp3' }
|
22
|
-
|
23
|
-
it 'returns an adapter' do
|
24
|
-
expect(result).to be_a RMD::SongPlaylistAdapter
|
25
|
-
expect(result.song).to be_a RMD::NCT::Song
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
context 'when link is playlist link' do
|
30
|
-
let(:link) { 'www.nhaccuatui.com/playlist/bang-kieu' }
|
31
|
-
it { is_expected.to be_a(RMD::NCT::Playlist) }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'when link belongs to zing website' do
|
36
|
-
context 'when link is song link' do
|
37
|
-
let(:link) { 'mp3.zing.vn/bai-hat/song.mp3' }
|
38
|
-
|
39
|
-
it 'returns an adapter' do
|
40
|
-
expect(result).to be_a RMD::SongPlaylistAdapter
|
41
|
-
expect(result.song).to be_a RMD::Zing::Song
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context 'when link is playlist link' do
|
46
|
-
let(:link) { 'mp3.zing.vn/playlist/bang-kieu' }
|
47
|
-
it { is_expected.to be_a(RMD::Zing::Playlist) }
|
48
|
-
end
|
49
|
-
|
50
|
-
context 'when link is playlist link' do
|
51
|
-
let(:link) { 'mp3.zing.vn/album/bang-kieu' }
|
52
|
-
it { is_expected.to be_a(RMD::Zing::Playlist) }
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'otherwise' do
|
57
|
-
let(:link) { '' }
|
58
|
-
|
59
|
-
it 'raises errors' do
|
60
|
-
expect { factory.build }.to raise_error
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,140 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RMD::NCT::Getter::KeyFromPage do
|
4
|
-
let(:url) { 'url' }
|
5
|
-
let(:getter) { described_class.new(url) }
|
6
|
-
|
7
|
-
describe '#fetch' do
|
8
|
-
let(:element) { double('Element', text: data_link) }
|
9
|
-
let(:data_link) { 'data_link' }
|
10
|
-
let(:key) { 'key' }
|
11
|
-
let(:errors) { 'The page does not contain the key.' }
|
12
|
-
|
13
|
-
before do
|
14
|
-
allow(getter).to receive(:key).and_return(key)
|
15
|
-
allow(getter).to receive(:element).and_return(element)
|
16
|
-
getter.fetch
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'when key is not present' do
|
20
|
-
let(:key) { nil }
|
21
|
-
|
22
|
-
it 'returns errors' do
|
23
|
-
expect(getter.data_link).to eq nil
|
24
|
-
expect(getter.errors).to eq errors
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'when element is not present' do
|
29
|
-
let(:element) { nil }
|
30
|
-
|
31
|
-
it 'returns errors' do
|
32
|
-
expect(getter.data_link).to eq nil
|
33
|
-
expect(getter.errors).to eq errors
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
context 'otherwise' do
|
38
|
-
it 'gets data' do
|
39
|
-
expect(getter.data_link).to eq data_link
|
40
|
-
expect(getter.errors).to eq nil
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe '#response' do
|
46
|
-
let(:body) { '<body>abc</body>' }
|
47
|
-
let(:new_page) { double('Page', body: body) }
|
48
|
-
let(:response) { getter.send(:response).child }
|
49
|
-
|
50
|
-
before do
|
51
|
-
expect(getter).to receive(:new_page).and_return(new_page)
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'parse the response from the page' do
|
55
|
-
expect(response.name).to eq 'body'
|
56
|
-
expect(response.text).to eq 'abc'
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe '#key' do
|
61
|
-
let(:page) { double('Page') }
|
62
|
-
let(:elements) { [element] }
|
63
|
-
let(:element) { double('Element', text: text) }
|
64
|
-
subject { getter.send(:key) }
|
65
|
-
|
66
|
-
before do
|
67
|
-
expect(getter).to receive(:page).and_return(page)
|
68
|
-
expect(page).to receive(:search).with('script').and_return(elements)
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'when match data exists' do
|
72
|
-
let(:text) { 'NCTNowPlaying.intFlashPlayer("flashPlayer", "song", "key");' }
|
73
|
-
it { is_expected.to eq 'key' }
|
74
|
-
end
|
75
|
-
|
76
|
-
context 'when match data is not exists' do
|
77
|
-
let(:text) { 'NCTNowPlaying.initFlashPlayer();' }
|
78
|
-
it { is_expected.to eq nil }
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
describe '#element' do
|
83
|
-
let(:response) { Nokogiri::XML(xml) }
|
84
|
-
|
85
|
-
before do
|
86
|
-
expect(getter).to receive(:response).and_return(response)
|
87
|
-
end
|
88
|
-
|
89
|
-
context 'when the path exists' do
|
90
|
-
let(:xml) { '<tracklist><location>abc</location></tracklist>' }
|
91
|
-
let(:subject) { getter.send(:element).text }
|
92
|
-
it { is_expected.to eq 'abc' }
|
93
|
-
end
|
94
|
-
|
95
|
-
context 'when the path is not exists' do
|
96
|
-
let(:xml) { '<location>abc</location>' }
|
97
|
-
subject { getter.send(:element) }
|
98
|
-
it { is_expected.to eq nil }
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
describe '#new_link' do
|
103
|
-
let(:key) { 'key' }
|
104
|
-
subject { getter.send(:new_link) }
|
105
|
-
|
106
|
-
before do
|
107
|
-
expect(getter).to receive(:key).and_return(key)
|
108
|
-
end
|
109
|
-
|
110
|
-
it { is_expected.to eq 'http://www.nhaccuatui.com/flash/xml?key1=key' }
|
111
|
-
end
|
112
|
-
|
113
|
-
describe '#page' do
|
114
|
-
let(:agent) { instance_double('Mechanize') }
|
115
|
-
let(:page) { double('Page') }
|
116
|
-
subject { getter.send(:page) }
|
117
|
-
|
118
|
-
before do
|
119
|
-
expect(getter).to receive(:agent).and_return(agent)
|
120
|
-
expect(agent).to receive(:get).with(url).and_return(page)
|
121
|
-
end
|
122
|
-
|
123
|
-
it { is_expected.to eq page }
|
124
|
-
end
|
125
|
-
|
126
|
-
describe '#new_page' do
|
127
|
-
let(:new_link) { 'new_link' }
|
128
|
-
let(:agent) { instance_double('Mechanize') }
|
129
|
-
let(:page) { double('Page') }
|
130
|
-
subject { getter.send(:new_page) }
|
131
|
-
|
132
|
-
before do
|
133
|
-
expect(getter).to receive(:new_link).and_return(new_link)
|
134
|
-
expect(getter).to receive(:agent).and_return(agent)
|
135
|
-
expect(agent).to receive(:get).with(new_link).and_return(page)
|
136
|
-
end
|
137
|
-
|
138
|
-
it { is_expected.to eq page }
|
139
|
-
end
|
140
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RMD::NCT::Getter::KeyFromUrl do
|
4
|
-
let(:url) { 'url' }
|
5
|
-
let(:getter) { described_class.new(url) }
|
6
|
-
|
7
|
-
describe '#fetch' do
|
8
|
-
before do
|
9
|
-
expect(getter).to receive(:key).and_return(key)
|
10
|
-
end
|
11
|
-
|
12
|
-
context 'when key is present' do
|
13
|
-
let(:key) { 'key' }
|
14
|
-
let(:stream_url) { 'stream_url' }
|
15
|
-
let(:response) { {
|
16
|
-
'error_message' => error_message,
|
17
|
-
'data' => { 'stream_url' => stream_url }
|
18
|
-
} }
|
19
|
-
|
20
|
-
before do
|
21
|
-
allow(getter).to receive(:response).and_return(response)
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when response is success' do
|
25
|
-
let(:error_message) { 'Success' }
|
26
|
-
|
27
|
-
it 'gets the link' do
|
28
|
-
getter.fetch
|
29
|
-
expect(getter.data_link).to eq stream_url
|
30
|
-
expect(getter.errors).to eq nil
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'when response is not success' do
|
35
|
-
let(:error_message) { 'error_message' }
|
36
|
-
let(:new_link) { 'new_link' }
|
37
|
-
|
38
|
-
before do
|
39
|
-
expect(getter).to receive(:new_link).and_return(new_link)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'returns errors' do
|
43
|
-
getter.fetch
|
44
|
-
expect(getter.data_link).to eq nil
|
45
|
-
expect(getter.errors).to eq 'error_message: new_link'
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
context 'when key is not present' do
|
51
|
-
let(:key) { nil }
|
52
|
-
|
53
|
-
it 'returns errors' do
|
54
|
-
getter.fetch
|
55
|
-
expect(getter.data_link).to eq nil
|
56
|
-
expect(getter.errors).to eq 'The url does not contain the key.'
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe '#response' do
|
62
|
-
let(:page) { double('Page', body: body) }
|
63
|
-
let(:body) { "{\"abc\":\"xyz\"}" }
|
64
|
-
let(:response) { { 'abc' => 'xyz' } }
|
65
|
-
subject { getter.send(:response) }
|
66
|
-
|
67
|
-
before do
|
68
|
-
expect(getter).to receive(:page).and_return(page)
|
69
|
-
end
|
70
|
-
|
71
|
-
it { is_expected.to eq response }
|
72
|
-
end
|
73
|
-
|
74
|
-
describe '#key' do
|
75
|
-
subject { getter.send(:key) }
|
76
|
-
|
77
|
-
context 'when there is no match' do
|
78
|
-
let(:url) { 'http://www.nhaccuatui.com/bai-hat/the-clockmaker-vexare.html' }
|
79
|
-
it { is_expected.to eq nil }
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'when there is a match' do
|
83
|
-
let(:url) { 'http://www.nhaccuatui.com/bai-hat/the-clockmaker-vexare.eorOqCpY7k46.html' }
|
84
|
-
it { is_expected.to eq 'eorOqCpY7k46' }
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe '#new_link' do
|
89
|
-
let(:key) { 'key' }
|
90
|
-
subject { getter.send(:new_link) }
|
91
|
-
|
92
|
-
before do
|
93
|
-
expect(getter).to receive(:key).and_return(key)
|
94
|
-
end
|
95
|
-
|
96
|
-
it { is_expected.to eq 'http://www.nhaccuatui.com/download/song/key' }
|
97
|
-
end
|
98
|
-
|
99
|
-
describe '#page' do
|
100
|
-
let(:new_link) { 'new_link' }
|
101
|
-
let(:agent) { instance_double('Mechanize') }
|
102
|
-
let(:page) { double('Page') }
|
103
|
-
subject { getter.send(:page) }
|
104
|
-
|
105
|
-
before do
|
106
|
-
expect(getter).to receive(:new_link).and_return(new_link)
|
107
|
-
expect(getter).to receive(:agent).and_return(agent)
|
108
|
-
expect(agent).to receive(:get).with(new_link).and_return(page)
|
109
|
-
end
|
110
|
-
|
111
|
-
it { is_expected.to eq page }
|
112
|
-
end
|
113
|
-
end
|