rmd 0.0.1 → 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.
@@ -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