rmd 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,52 @@
1
+ require 'mechanize'
2
+
3
+ module RMD
4
+ module Base
5
+ class Playlist
6
+ attr_reader :errors, :link, :songs
7
+
8
+ def initialize(link)
9
+ @link = link
10
+ @errors = []
11
+ @songs = []
12
+ end
13
+
14
+ def success?
15
+ !!songs && songs.count > 0
16
+ end
17
+
18
+ def fetch; end
19
+
20
+ private
21
+
22
+ def agent
23
+ agent ||= Mechanize.new
24
+ end
25
+
26
+ def page
27
+ @page ||= agent.get(link)
28
+ end
29
+
30
+ def song_elements
31
+ @song_element ||= page.search(song_css)
32
+ end
33
+
34
+ def calculate_progress
35
+ if song_elements.count > 0
36
+ progress_bar = ProgressBar.create(
37
+ starting_at: 0,
38
+ total: song_elements.count,
39
+ format: '%c / %C Songs %B %p%%'
40
+ )
41
+
42
+ song_elements.each do |element|
43
+ yield element.attr('href')
44
+ progress_bar.increment
45
+ end
46
+ else
47
+ @errors << 'Can not get song lists from this playlist page.'
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,17 @@
1
+ module RMD
2
+ module Base
3
+ class Song
4
+ attr_reader :errors, :link, :data_link
5
+
6
+ def initialize(link)
7
+ @link = link
8
+ end
9
+
10
+ def fetch; end
11
+
12
+ def success?
13
+ !!data_link && data_link != ''
14
+ end
15
+ end
16
+ end
17
+ end
@@ -44,8 +44,17 @@ module RMD
44
44
  private
45
45
 
46
46
  def file_name
47
+ @file_name ||= uncached_file_name
48
+ end
49
+
50
+ def uncached_file_name
47
51
  uri = URI.parse(link)
48
- File.basename(uri.path)
52
+ name = CGI::parse(uri.query.to_s)['filename'].first
53
+ if name
54
+ name
55
+ else
56
+ File.basename(uri.path)
57
+ end
49
58
  end
50
59
  end
51
60
  end
data/lib/rmd/factory.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'rmd/song_playlist_adapter'
2
2
  require 'rmd/nct/song'
3
3
  require 'rmd/nct/playlist'
4
+ require 'rmd/zing/song'
5
+ require 'rmd/zing/playlist'
4
6
 
5
7
  module RMD
6
8
  class Factory
@@ -19,6 +21,15 @@ module RMD
19
21
  when /playlist/
20
22
  RMD::NCT::Playlist.new(link)
21
23
  end
24
+ when /mp3\.zing\.vn/
25
+ case link
26
+ when /bai-hat/
27
+ RMD::SongPlaylistAdapter.new(RMD::Zing::Song.new(link))
28
+ when /album|playlist/
29
+ RMD::Zing::Playlist.new(link)
30
+ end
31
+ else
32
+ raise 'Your url is not valid. Please check again.'
22
33
  end
23
34
  end
24
35
 
@@ -17,7 +17,7 @@ module RMD
17
17
 
18
18
  def uncached_key
19
19
  page.search('script').each do |element|
20
- if match_data = /NCTNowPlaying.intFlashPlayer\("flashPlayer", "song", "(.+)"\)\;/.match(element.text)
20
+ if match_data = regex.match(element.text)
21
21
  return match_data.to_a.last
22
22
  end
23
23
  end
@@ -44,6 +44,10 @@ module RMD
44
44
  def element
45
45
  @element ||= response.at_xpath('.//tracklist//location')
46
46
  end
47
+
48
+ def regex
49
+ /NCTNowPlaying.intFlashPlayer\("flashPlayer", "song", "(.+)"\)\;/
50
+ end
47
51
  end
48
52
  end
49
53
  end
@@ -1,63 +1,26 @@
1
- require 'mechanize'
1
+ require 'rmd/base/playlist'
2
2
 
3
3
  module RMD
4
4
  module NCT
5
- class Playlist
6
- attr_reader :errors, :link, :songs
7
-
8
- def initialize(link)
9
- @link = link
10
- end
5
+ class Playlist < RMD::Base::Playlist
11
6
 
12
7
  def fetch
13
- if song_elements.count > 0
14
- @errors = []
15
- progress_bar = ProgressBar.create(
16
- starting_at: 0,
17
- total: song_elements.count,
18
- format: '%c / %C Songs %B %p%%'
19
- )
20
-
21
- @songs = song_elements.inject([]) do |result, element|
22
- link = element.attr('href')
23
- song = RMD::NCT::Song.new(link)
24
- song.fetch
25
- if song.success?
26
- result << song.data_link
27
- else
28
- @errors << song.errors
29
- end
30
-
31
- progress_bar.increment
32
- result
8
+ calculate_progress do |link|
9
+ song = RMD::NCT::Song.new(link)
10
+ song.fetch
11
+ if song.success?
12
+ @songs << song.data_link
13
+ else
14
+ @errors << song.errors
33
15
  end
34
- else
35
- @songs = []
36
- @errors = ['Can not get song lists from this playlist page.']
37
16
  end
38
17
  end
39
18
 
40
- def success?
41
- !!songs && songs.count > 0
42
- end
43
-
44
19
  private
45
20
 
46
21
  def song_css
47
22
  '.item_content .name_song'
48
23
  end
49
-
50
- def song_elements
51
- @song_element ||= page.search(song_css)
52
- end
53
-
54
- def page
55
- @page ||= agent.get(link)
56
- end
57
-
58
- def agent
59
- agent ||= Mechanize.new
60
- end
61
24
  end
62
25
  end
63
26
  end
data/lib/rmd/nct/song.rb CHANGED
@@ -1,14 +1,10 @@
1
+ require 'rmd/base/song'
1
2
  require 'rmd/nct/getter/key_from_page'
2
3
  require 'rmd/nct/getter/key_from_url'
3
4
 
4
5
  module RMD
5
6
  module NCT
6
- class Song
7
- attr_reader :errors, :link, :data_link
8
-
9
- def initialize(link)
10
- @link = link
11
- end
7
+ class Song < RMD::Base::Song
12
8
 
13
9
  def fetch
14
10
  getters.each do |getter|
@@ -19,10 +15,6 @@ module RMD
19
15
  end
20
16
  end
21
17
 
22
- def success?
23
- !!data_link
24
- end
25
-
26
18
  private
27
19
 
28
20
  def getters
data/lib/rmd/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rmd
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,21 @@
1
+ require 'rmd/base/playlist'
2
+ require 'rmd/zing/utils/correct_url'
3
+
4
+ module RMD
5
+ module Zing
6
+ class Playlist < RMD::Base::Playlist
7
+
8
+ def fetch
9
+ calculate_progress do |link|
10
+ @songs << RMD::Zing::Utils::CorrectUrl.correct(link)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def song_css
17
+ '._btnDownload'
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,45 @@
1
+ require 'mechanize'
2
+ require 'rmd/zing/utils/correct_url'
3
+
4
+ module RMD
5
+ module Zing
6
+ class Song < RMD::Base::Song
7
+
8
+ def fetch
9
+ if new_link
10
+ @data_link = RMD::Zing::Utils::CorrectUrl.correct(new_link)
11
+ else
12
+ @errors = 'Can not get song from this link!'
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def agent
19
+ @agent ||= Mechanize.new
20
+ end
21
+
22
+ def page
23
+ @page ||= agent.get(link)
24
+ end
25
+
26
+ def regex
27
+ /http\:\/\/mp3.zing.vn\/download\/song\/\S+\/\w+/
28
+ end
29
+
30
+ def new_link
31
+ @new_link ||= uncached_new_link
32
+ end
33
+
34
+ def uncached_new_link
35
+ page.search('.detail-function script').each do |element|
36
+ if match_data = regex.match(element.text)
37
+ return match_data.to_s
38
+ end
39
+ end
40
+
41
+ nil
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,43 @@
1
+ module RMD
2
+ module Zing
3
+ module Utils
4
+ class CorrectUrl
5
+ attr_reader :url
6
+
7
+ def initialize(url)
8
+ @url = url
9
+ end
10
+
11
+ def correct
12
+ if redirect_location
13
+ URI.escape(redirect_location)
14
+ else
15
+ url
16
+ end
17
+ end
18
+
19
+ def self.correct(url)
20
+ new(url).correct
21
+ end
22
+
23
+ private
24
+
25
+ def uri
26
+ @uri ||= URI.parse(url)
27
+ end
28
+
29
+ def http_client
30
+ @http_client ||= Net::HTTP.start(uri.host)
31
+ end
32
+
33
+ def header_response
34
+ @header_response ||= http_client.head(uri.path)
35
+ end
36
+
37
+ def redirect_location
38
+ header_response['location']
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
data/rmd.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'colorize', '~> 0.7'
25
25
 
26
26
  spec.add_development_dependency "bundler", "~> 1.6"
27
+ spec.add_development_dependency "rake", "~> 10.1"
27
28
  spec.add_development_dependency "rspec", '~> 3.1'
28
29
  spec.add_development_dependency "webmock", '~> 1.20'
29
30
  spec.add_development_dependency "vcr", '~> 2.9'
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe RMD::Main do
4
+ describe '#download' do
5
+ let(:run_method) { RMD::Processor.process(link) }
6
+ let(:file_path) { File.expand_path("../../../#{file_name}", __FILE__) }
7
+
8
+ context 'when downloads song from nhaccuatui' do
9
+ let(:link) { 'http://www.nhaccuatui.com/bai-hat/honjitsu-mijukumono-juken-no-kamisama-ost-tv-version-tokio.tFBwsJKDGQX9.html' }
10
+ let(:file_name) { 'HonjitsuMijukumonoJukenNoKamisamaOSTTVVersion-TOKIO-3164566.mp3' }
11
+ let(:scenario) { 'nhaccuatui song'}
12
+ it_behaves_like 'download'
13
+ end
14
+
15
+ context 'when downloads playlist from nhaccuatui' do
16
+ let(:link) { 'http://www.nhaccuatui.com/playlist/dev-playlist-dang-cap-nhat.jn0g1fg4Z6UO.html' }
17
+ let(:file_name) { 'BlazeTvSize-KajiuraYuki_35ax5_hq.mp3' }
18
+ let(:file_path) { File.expand_path("../../../#{file_name}", __FILE__) }
19
+ let(:scenario) { 'nhaccuatui playlist' }
20
+ it_behaves_like 'download'
21
+ end
22
+
23
+ context 'when downloads song from zing mp3' do
24
+ let(:link) { 'http://mp3.zing.vn/bai-hat/Bird-TV-Size-Yuya-Matsushita/ZWZCO98B.html' }
25
+ let(:file_name) { 'Bird TV Size - Yuya Matsushita.mp3' }
26
+ let(:scenario) { 'zing song' }
27
+ it_behaves_like 'download'
28
+ end
29
+
30
+ context 'when downloads playlist from zing mp3' do
31
+ let(:link) { 'http://mp3.zing.vn/playlist/dev-playlist-zid-sincepast/IO0E698Z.html' }
32
+ let(:file_name) { 'sharp TV Size - Negoto.mp3' }
33
+ let(:scenario) { 'zing playlist' }
34
+ it_behaves_like 'download'
35
+ end
36
+ end
37
+ end
@@ -14,20 +14,26 @@ describe RMD::Downloader do
14
14
 
15
15
  describe '#download' do
16
16
  let(:downloader) { described_class.new(link) }
17
+ let(:run_method) { downloader.download }
18
+ let(:scenario) { 'song download' }
17
19
  let(:link) { 'http://db.gamefaqs.com/portable/3ds/file/fire_emblem_awakening_shop.txt' }
18
20
  let(:file_name) { 'fire_emblem_awakening_shop.txt' }
19
- let(:content_length) { body.length }
20
21
  let(:file_path) { File.expand_path("../../../#{file_name}", __FILE__) }
21
- let(:result) { File.read(file_path) }
22
+ it_behaves_like 'download'
23
+ end
22
24
 
23
- it 'downloads' do
24
- VCR.use_cassette("song download") do
25
- expect {
26
- downloader.download
27
- }.to output("\e[0;32;49m#{file_name}\e[0m\n").to_stdout
28
- expect(File.exists?(file_path)).to eq true
29
- end
30
- File.delete(file_path)
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' }
31
37
  end
32
38
  end
33
39
  end