xiami_sauce 0.0.1 → 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ca6f3d6701281dfc430d2fd2f17bdb58dc622c92
4
+ data.tar.gz: 97b99e4e6a7d83017b026415bf0ed1641cf6db5f
5
+ SHA512:
6
+ metadata.gz: 0831a00e09656a48b0d1b5619889c3c1f48e9a5960c994d8a337ee7307aeba267100ee2cabc8ee84b6e051aaeb67ffd6f0237bb1890d985b0903cd5f743f376b
7
+ data.tar.gz: 92ee592a6ecd6256f04d9907d760c5cf1f7f2bef11299467338deaaa4d0da58fde895c79d005dac83ca7d61db6129196f06d1d69094659462f32b2676324f48e
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby
6
+ script: "bundle exec rake spec"
data/Gemfile CHANGED
@@ -1,4 +1,15 @@
1
- source 'https://rubygems.org'
1
+ source 'http://ruby.taobao.org'
2
+ # source 'https://rubygems.org'
2
3
 
3
- # Specify your gem's dependencies in xiami_sauce.gemspec
4
4
  gemspec
5
+
6
+ gem 'guard'
7
+ gem 'guard-bundler'
8
+ gem 'guard-rspec'
9
+
10
+ gem 'rb-fsevent', '>= 0.3.9'
11
+ gem 'rb-inotify', '>= 0.5.1'
12
+
13
+ # Notification System
14
+ gem 'terminal-notifier-guard', require: RUBY_PLATFORM.downcase.include?("darwin") ? 'terminal-notifier-guard' : nil
15
+ gem 'libnotify', require: RUBY_PLATFORM.downcase.include?("linux") ? 'libnotify' : nil
data/Guardfile ADDED
@@ -0,0 +1,13 @@
1
+ RVM_PREFIX = "env -u RUBYOPT rvm 1.8.7,1.9.3-p327,2.0.0 do"
2
+ BUNDLE_CMD = lambda { puts "Bundling gems..."; puts `#{RVM_PREFIX} bundle install` }
3
+
4
+ guard 'bundler' do
5
+ watch(/^.+\.gemspec/, &BUNDLE_CMD)
6
+ watch('Gemfile', &BUNDLE_CMD)
7
+ end
8
+
9
+ guard 'rspec', cli: "--color --format documentation" do
10
+ watch(%r{^spec/.+_spec\.rb$})
11
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
12
+ watch('spec/spec_helper.rb') { "spec" }
13
+ end
data/README.md CHANGED
@@ -1,29 +1,46 @@
1
- # XiamiSauce
1
+ # 虾米酱 - XiamiSauce
2
2
 
3
- TODO: Write a gem description
3
+ [![Gem Version](https://badge.fury.io/rb/xiami_sauce.png)](http://badge.fury.io/rb/xiami_sauce)
4
+ [![Build Status](https://travis-ci.org/ranmocy/xiami_sauce.png)](https://travis-ci.org/ranmocy/xiami_sauce)
5
+ [![Dependency Status](https://gemnasium.com/ranmocy/xiami_sauce.png)](https://gemnasium.com/ranmocy/xiami_sauce)
6
+ [![Code Climate](https://codeclimate.com/github/ranmocy/xiami_sauce.png)](https://codeclimate.com/github/ranmocy/xiami_sauce)
4
7
 
5
- ## Installation
8
+ 虾米酱是一个虾米音乐下载器。封装成为一个 Ruby Gem 包。
6
9
 
7
- Add this line to your application's Gemfile:
10
+ XiamiSauce is a downloader of Xiami Music. Writed in Ruby, and presented as a Gem.
8
11
 
9
- gem 'xiami_sauce'
12
+ ## Why
10
13
 
11
- And then execute:
14
+ You know, if you know it.
12
15
 
13
- $ bundle
16
+ ## 依赖 - Dependency
14
17
 
15
- Or install it yourself as:
18
+ 虾米酱在 Ruby 1.9.2, 1.9.3, 2.0.0, jRuby, REE 环境下测试。
19
+ XiamiSauce will be tested under Ruby 1.9.2, 1.9.3, 2.0.0, jRuby, REE.
16
20
 
17
- $ gem install xiami_sauce
21
+ 依赖 Thor, Nokogiri 的 Gem 包。
22
+ Depend on Gems Thor and Nokogiri.
18
23
 
19
- ## Usage
24
+ ## 安装 - Installation
20
25
 
21
- TODO: Write usage instructions here
26
+ 一句话安装 - Install it with one-line code:
22
27
 
23
- ## Contributing
28
+ $ gem install xiami_sauce --no-ri --no-doc
24
29
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
30
+ ## 使用方法 - Usage
31
+
32
+ $ xsauce http://www.xiami.com/artist/64360
33
+ $ xsauce http://www.xiami.com/album/355791
34
+ $ xsauce http://www.xiami.com/song/184616
35
+
36
+ 虾米酱会按照歌曲信息下载到 `[artist]/[album]/[index].[song].mp3`。
37
+
38
+ XiamiSauce will download to `[artist]/[album]/[index].[song].mp3`.
39
+
40
+ ## 参与 - Contributing
41
+
42
+ 1. 派生 - Fork it
43
+ 2. 新建特性分支 - Create your feature branch (`git checkout -b my-new-feature`)
44
+ 3. 提交你的修改 - Commit your changes (`git commit -am 'Add some feature'`)
45
+ 4. 推送特性分支 - Push to the branch (`git push origin my-new-feature`)
46
+ 5. 发起合并请求 - Create new Pull Request
data/Rakefile CHANGED
@@ -1 +1,32 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ # Rspec tasks
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ # Version tasks
8
+ require 'rake/version_task'
9
+ Rake::VersionTask.new
10
+
11
+ # include Rake::DSL if defined?(Rake::DSL)
12
+
13
+ RVM_PREFIX = "rvm 1.8.7,1.9.3-p327,2.0.0 do"
14
+
15
+
16
+ namespace :spec do
17
+ desc "Run on three Rubies"
18
+ task :platforms do
19
+ exit $?.exitstatus unless system "#{RVM_PREFIX} bundle install"
20
+ exit $?.exitstatus unless system "#{RVM_PREFIX} bundle exec rake spec"
21
+ end
22
+ end
23
+
24
+ task default: 'spec:platforms'
25
+
26
+ desc 'Push everywhere!'
27
+ task :publish do
28
+ system %{git push github}
29
+ system %{git push github --tags}
30
+ system %{git push gitcafe}
31
+ system %{git push gitcafe --tags}
32
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
data/bin/xsauce ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require "xiami_sauce"
5
+ rescue
6
+ require "rubygems"
7
+ require "xiami_sauce"
8
+ end
9
+
10
+ XiamiSauce::CLI.start
@@ -0,0 +1,23 @@
1
+ require 'thor'
2
+
3
+ module XiamiSauce
4
+ class CLI < Thor
5
+ default_task :download
6
+
7
+ desc 'download URL', 'download the music from a page url.'
8
+ def download(url=nil)
9
+ unless url
10
+ puts "Target Xiami URL[Song, Album, Artist, ShowCollect]:"
11
+ url = gets.chomp
12
+ end
13
+ puts "Preparing to download #{url}."
14
+
15
+ list = TrackList.new(url).download
16
+ end
17
+
18
+ def method_missing(url, *args)
19
+ download(url)
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,68 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+
4
+ module XiamiSauce
5
+ class Downloader
6
+ RETRY_TIMES = 3
7
+ SLEEP_TIME = 3
8
+
9
+ attr_accessor :url, :file
10
+
11
+ def initialize(url, file)
12
+ @url = url
13
+ @file = file
14
+ end
15
+
16
+ def download
17
+ FileUtils.mkdir_p(@file.parent) unless @file.parent.exist?
18
+
19
+ puts "Downloading #{@file}."
20
+ return puts 'Skip.'.color(:yellow) if @file.exist?
21
+
22
+ retry_count = RETRY_TIMES
23
+ begin
24
+ raise unless(download_file url, @file)
25
+ rescue Exception => e
26
+ if retry_count == 0
27
+ puts 'Failed.'.color(:red)
28
+ else
29
+ puts "Retry remain #{retry_count -= 1} times.".color(:yellow)
30
+ sleep(SLEEP_TIME)
31
+ retry
32
+ end
33
+ end
34
+
35
+ puts 'Done.'.color(:green)
36
+ sleep(SLEEP_TIME)
37
+ end
38
+
39
+ def check_file file_path
40
+ /MPEG/.match(`file -b \"#{file_path}\"`)
41
+ end
42
+
43
+ def check_downloader
44
+ return :curl if system('which curl >/dev/null')
45
+ return :wget if system('which wget >/dev/null')
46
+ raise 'No available downloader, currently support curl and wget.'
47
+ end
48
+
49
+ def download_file url, filename=nil
50
+ puts "[Debug] DownloadFile::Params #{url}, #{filename}" if $DEBUG
51
+
52
+ remote = url && url.to_s.gsub("\"", "\\\\\"")
53
+ local = filename && filename.to_s.gsub("\"", "\\\\\"")
54
+ puts "[Debug] DownloadFile::Prepare #{remote}, #{local}" if $DEBUG
55
+
56
+ case check_downloader
57
+ when :curl
58
+ command = local ? ("curl -\# \"%s\" > \"%s\"" % [remote, local]) : ("curl -O %s" % remote)
59
+ when :wget
60
+ command = local ? ("wget -O \"%s\" \"%s\"" % [local, remote]) : ("wget %s" % remote)
61
+ end
62
+
63
+ puts "[Debug] DownloadFile: #{command}" if $DEBUG
64
+ system(command) && check_file(local)
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,105 @@
1
+ require "cgi"
2
+ require 'net/http'
3
+ require 'nokogiri'
4
+ require_relative 'downloader'
5
+
6
+ module XiamiSauce
7
+ class Track
8
+ attr_accessor :id, :index, :name, :location, :url
9
+ attr_accessor :album_id, :album_cover, :album_name
10
+ attr_accessor :artist_id, :artist_name
11
+ # user_id is who use the widget, could be 0.
12
+ # attr_accessor :user_id, :width, :height, :widgetCode
13
+
14
+ # @todo I wish index could be fetch automatically from somewhere.
15
+ def initialize(song_url, index=nil)
16
+ @id = song_url.match(/song\/([0-9]+)/)[1]
17
+ @index = index.to_s
18
+
19
+ parse_info
20
+ end
21
+
22
+ def download(parent_path=nil)
23
+ file = Pathname('.').join((parent_path || album_name), url.split('/').last)
24
+ @downloader = Downloader.new(url, file)
25
+ @downloader.download
26
+ end
27
+
28
+ def file_name
29
+ index_string = index ? index.to_s.rjust(2, '0') + '.' : ''
30
+ "[#{artist_name}-#{album_name}]#{index_string}#{name}.mp3"
31
+ end
32
+
33
+ def info_src
34
+ @info_src ||= "http://www.xiami.com/widget/xml-single/uid/0/sid/#{id}"
35
+ end
36
+
37
+
38
+ private
39
+
40
+ def parse_info
41
+ url_str = URI.parse(info_src)
42
+ site = Net::HTTP.new(url_str.host, url_str.port)
43
+ xml = site.get2(url_str.path,{'accept'=>'text/html'}).body
44
+ doc = Nokogiri::XML(xml)
45
+
46
+ doc.css('track *').each do |element|
47
+ instance_variable_set("@#{element.name}", element.content)
48
+ end
49
+ @name = @song_name
50
+ @url = sospa(@location)
51
+ end
52
+
53
+ def sospa(location)
54
+ totle = location.to_i
55
+ new_str = location[1..-1]
56
+ chu = (new_str.length.to_f / totle).floor
57
+ yu = new_str.length % totle
58
+ stor = []
59
+
60
+ i = 0
61
+ while i < yu do
62
+ index = (chu+1)*i
63
+ length = chu+1
64
+ stor[i] = new_str[index...index+length]
65
+
66
+ i+=1
67
+ end
68
+
69
+
70
+ i = yu
71
+ while i < totle do
72
+ index = chu*(i-yu)+(chu+1)*yu
73
+ length = chu
74
+
75
+ stor[i] = new_str[index...index+length]
76
+
77
+ i+=1
78
+ end
79
+
80
+ pin_str = ""
81
+ 0.upto(stor[0].length-1) do |ii|
82
+ 0.upto(stor.length-1) do |jj|
83
+ pin_str += stor[jj][ii...ii+1]
84
+ end
85
+ end
86
+
87
+ pin_str = rtan(pin_str)
88
+ return_str = ""
89
+
90
+ 0.upto(pin_str.length-1) do |iii|
91
+ if pin_str[iii...iii+1]=='^'
92
+ return_str<<"0"
93
+ else
94
+ return_str<<pin_str[iii...iii+1]
95
+ end
96
+ end
97
+
98
+ return_str
99
+ end
100
+
101
+ def rtan(str)
102
+ CGI::unescape(str)
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,85 @@
1
+ require 'pathname'
2
+ require_relative 'track'
3
+ require 'nokogiri'
4
+
5
+ module XiamiSauce
6
+ class URLParseError < StandardError; end
7
+ class DocParseError < StandardError; end
8
+ class InvalidURLType < StandardError; end
9
+
10
+ class TrackList
11
+ SONG_SELECTOR = nil
12
+ ALBUM_SELECTOR = "div#track.album_tracks table.track_list tr td.song_name"
13
+ ARTIST_SELECTOR = "div#artist_trends table.track_list td.song_name"
14
+ SHOWCOLLECT_SELECTOR = "div#list_collect div.quote_song_list li span.song_name"
15
+
16
+ attr_accessor :list
17
+
18
+ def initialize(url=nil)
19
+ @list = []
20
+ parse(url) if url
21
+ end
22
+
23
+ def parse(url)
24
+ @uri, @type = parse_url(url)
25
+ @doc = parse_doc(@uri)
26
+ urls = parse_info_from_doc(selector(@type))
27
+ @list += urls.collect { |url| Track.new(url) }
28
+ self
29
+ end
30
+
31
+ def download(target_path=nil)
32
+ path = (target_path && Pathname.new(target_path.to_s).exists?) || Pathname.new("./")
33
+
34
+ puts "Downloading #{@list.size} tracks..."
35
+ count = @list.uniq.inject(0) do |count, track|
36
+ count += 1 if track.download
37
+ end
38
+ puts "Downloaded #{count}/#{@list.size} tracks."
39
+ count
40
+ end
41
+
42
+
43
+ def to_a
44
+ @list
45
+ end
46
+
47
+ def method_missing(method_name, *args)
48
+ @list.send(method_name, *args)
49
+ self
50
+ end
51
+
52
+
53
+ private
54
+
55
+ def parse_url(url)
56
+ uri = URI.parse(url)
57
+ type = uri.path.split('/')[1].to_sym
58
+ [uri, type]
59
+ rescue Exception => e
60
+ raise URLParseError, e.message
61
+ end
62
+
63
+ def parse_doc(uri)
64
+ site = Net::HTTP.new(uri.host, uri.port)
65
+ xml = site.get2(uri.path, {'accept' => 'text/html', 'user-agent' => 'Mozilla/5.0'}).body
66
+ Nokogiri::HTML(xml)
67
+ rescue Exception => e
68
+ raise DocParseError, e.message
69
+ end
70
+
71
+ def parse_info_from_doc(selector)
72
+ return [@uri.to_s] unless selector
73
+ @doc.css(selector).collect { |element| element.css("a").first["href"] }
74
+ end
75
+
76
+ def selector(type)
77
+ selector_name = "#{type.to_s.upcase}_SELECTOR"
78
+ unless self.class.const_defined?(selector_name)
79
+ raise InvalidURLType, "#{type} isn't a supported URL type. Check your URL."
80
+ end
81
+ self.class.const_get(selector_name)
82
+ end
83
+
84
+ end
85
+ end
data/lib/xiami_sauce.rb CHANGED
@@ -1,5 +1,8 @@
1
- require "xiami_sauce/version"
1
+ require 'rainbow'
2
+ require 'xiami_sauce/downloader'
3
+ require 'xiami_sauce/track'
4
+ require 'xiami_sauce/track_list'
5
+ require 'xiami_sauce/cli'
2
6
 
3
7
  module XiamiSauce
4
- # Your code goes here...
5
8
  end
@@ -0,0 +1,7 @@
1
+ require "mocha/api"
2
+
3
+ RSpec.configure do |c|
4
+ c.mock_with :mocha
5
+ end
6
+
7
+ require 'xiami_sauce'
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe XiamiSauce::Downloader do
4
+
5
+ end
@@ -0,0 +1,82 @@
1
+ require "spec_helper"
2
+
3
+ # should define :subject as TrackList
4
+ shared_context "parse to doc" do |url|
5
+ before(:all) do
6
+ track_list = XiamiSauce::TrackList.new
7
+ @uri, @type = track_list.send(:parse_url, url)
8
+ track_list.instance_variable_set("@uri", @uri)
9
+ track_list.instance_variable_set("@type", @type)
10
+ sleep(2)
11
+ @doc = track_list.send(:parse_doc, @uri)
12
+ end
13
+ before(:each) do
14
+ subject { XiamiSauce::TrackList.new }
15
+ subject.instance_variable_set("@doc", @doc)
16
+ # subject.stubs(:parse_doc).returns(@doc)
17
+ end
18
+ end
19
+
20
+ # should define :subject as TrackList
21
+ shared_examples "a right parser" do |type, expected_result|
22
+ let(:selector) { subject.send(:selector, type) }
23
+ let(:parse_result) { subject.send(:parse_info_from_doc, selector) }
24
+ it { expect(parse_result).to be_kind_of Array }
25
+ it { expect(parse_result.first).to be_kind_of String }
26
+ it { expect(parse_result.size).to be == expected_result }
27
+ end
28
+
29
+ describe XiamiSauce::TrackList do
30
+ context "to parse doc" do
31
+ let(:url) { 'http://www.xiami.com/song/1770450682' }
32
+ subject { XiamiSauce::TrackList.new }
33
+
34
+ it "should parse url" do
35
+ uri, type = subject.send(:parse_url, url)
36
+ uri.path.should == '/song/1770450682'
37
+ type.should == :song
38
+ end
39
+
40
+ it "should parse doc" do
41
+ uri, type = subject.send(:parse_url, url)
42
+ subject.instance_variable_set("@uri", uri)
43
+ subject.instance_variable_set("@type", type)
44
+ doc = subject.send(:parse_doc, uri)
45
+ subject.instance_variable_set("@doc", doc)
46
+ subject.instance_variable_get("@doc").should be_kind_of Nokogiri::HTML::Document
47
+ end
48
+ end
49
+
50
+
51
+ context "should support type song" do
52
+ include_context "parse to doc", 'http://www.xiami.com/song/1770450682'
53
+ it_should_behave_like "a right parser", "song", 1
54
+ end
55
+
56
+ context "should support type album" do
57
+ include_context "parse to doc", 'http://www.xiami.com/album/462525'
58
+ it_should_behave_like "a right parser", "album", 7
59
+ end
60
+
61
+ context "should support type artist" do
62
+ include_context "parse to doc", 'http://www.xiami.com/artist/19775'
63
+ it_should_behave_like "a right parser", "artist", 10
64
+ end
65
+
66
+ context "should support type showcollect" do
67
+ include_context "parse to doc", 'http://www.xiami.com/song/showcollect/id/10100776'
68
+ it_should_behave_like "a right parser", "showcollect", 50
69
+ end
70
+
71
+
72
+ context "doing operations" do
73
+ let(:a_url) { 'http://www.xiami.com/album/355791' }
74
+ let(:a_list) { XiamiSauce::TrackList.new(a_url) }
75
+ let(:b_url) { 'http://www.xiami.com/album/362997' }
76
+ let(:b_list) { XiamiSauce::TrackList.new(b_url) }
77
+
78
+ it "should be able to add" do
79
+ (a_list << b_list).list.should be == (a_list.list << b_list.list)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe XiamiSauce::Track do
4
+ let(:song_url) { "http://www.xiami.com/song/1770361274" }
5
+ let(:index) { 9 }
6
+
7
+ subject { XiamiSauce::Track.new(song_url, index) }
8
+
9
+ its('id') { should == '1770361274' }
10
+ its('index') { should == '9' }
11
+ its('name') { should == 'Kids (Unedited Version)' }
12
+ its('url') { should == 'http://f1.xiami.net/11768/454588/02_1770361274_2491919.mp3' }
13
+ its('album_id') { should == '454588' }
14
+ its('album_cover') { should == 'http://img.xiami.com/./images/album/img68/11768/4545881311563810_3.jpg' }
15
+ its('album_name') { should == 'The Way I Am' }
16
+ its('artist_id') { should == '11768' }
17
+ its('artist_name') { should == 'Eminem' }
18
+
19
+ its('file_name') { should == '[Eminem-The Way I Am]09.Kids (Unedited Version).mp3' }
20
+ end
data/xiami_sauce.gemspec CHANGED
@@ -1,16 +1,14 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'xiami_sauce/version'
5
3
 
6
4
  Gem::Specification.new do |spec|
7
5
  spec.name = "xiami_sauce"
8
- spec.version = XiamiSauce::VERSION
6
+ spec.version = File.open('VERSION') { |f| f.read }
9
7
  spec.authors = ["Wanzhang Sheng"]
10
8
  spec.email = ["ranmocy@gmail.com"]
11
9
  spec.description = %q{A Xiami Downloader.}
12
10
  spec.summary = %q{A Xiami Downloader.}
13
- spec.homepage = ""
11
+ spec.homepage = "http://ranmocy.github.com/xiami_sauce"
14
12
  spec.license = "MIT"
15
13
 
16
14
  spec.files = `git ls-files`.split($/)
@@ -18,6 +16,13 @@ Gem::Specification.new do |spec|
18
16
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
17
  spec.require_paths = ["lib"]
20
18
 
19
+ spec.add_dependency 'thor', '~> 0.17.0'
20
+ spec.add_dependency 'nokogiri', '~> 1.5.0'
21
+ spec.add_dependency 'rainbow', '~> 1.1.0'
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.3"
22
24
  spec.add_development_dependency "rake"
25
+ spec.add_development_dependency 'version'
26
+ spec.add_development_dependency 'rspec'
27
+ spec.add_development_dependency 'mocha', '~> 0.13.0'
23
28
  end
metadata CHANGED
@@ -1,92 +1,180 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xiami_sauce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.0.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Wanzhang Sheng
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-03-11 00:00:00.000000000 Z
11
+ date: 2013-03-17 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.17.0
20
+ type: :runtime
15
21
  prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.17.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 1.5.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rainbow
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.1.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.1.0
55
+ - !ruby/object:Gem::Dependency
16
56
  name: bundler
17
57
  requirement: !ruby/object:Gem::Requirement
18
58
  requirements:
19
59
  - - ~>
20
60
  - !ruby/object:Gem::Version
21
61
  version: '1.3'
22
- none: false
23
62
  type: :development
63
+ prerelease: false
24
64
  version_requirements: !ruby/object:Gem::Requirement
25
65
  requirements:
26
66
  - - ~>
27
67
  - !ruby/object:Gem::Version
28
68
  version: '1.3'
29
- none: false
30
69
  - !ruby/object:Gem::Dependency
31
- prerelease: false
32
70
  name: rake
33
71
  requirement: !ruby/object:Gem::Requirement
34
72
  requirements:
35
- - - ! '>='
73
+ - - '>='
36
74
  - !ruby/object:Gem::Version
37
75
  version: '0'
38
- none: false
39
76
  type: :development
77
+ prerelease: false
40
78
  version_requirements: !ruby/object:Gem::Requirement
41
79
  requirements:
42
- - - ! '>='
80
+ - - '>='
43
81
  - !ruby/object:Gem::Version
44
82
  version: '0'
45
- none: false
83
+ - !ruby/object:Gem::Dependency
84
+ name: version
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: mocha
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 0.13.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 0.13.0
46
125
  description: A Xiami Downloader.
47
126
  email:
48
127
  - ranmocy@gmail.com
49
- executables: []
128
+ executables:
129
+ - xsauce
50
130
  extensions: []
51
131
  extra_rdoc_files: []
52
132
  files:
53
133
  - .gitignore
134
+ - .travis.yml
54
135
  - Gemfile
136
+ - Guardfile
55
137
  - LICENSE.txt
56
138
  - README.md
57
139
  - Rakefile
140
+ - VERSION
141
+ - bin/xsauce
58
142
  - lib/xiami_sauce.rb
59
- - lib/xiami_sauce/version.rb
143
+ - lib/xiami_sauce/cli.rb
144
+ - lib/xiami_sauce/downloader.rb
145
+ - lib/xiami_sauce/track.rb
146
+ - lib/xiami_sauce/track_list.rb
147
+ - spec/spec_helper.rb
148
+ - spec/xiami_sauce/downloader_spec.rb
149
+ - spec/xiami_sauce/track_list_spec.rb
150
+ - spec/xiami_sauce/track_spec.rb
60
151
  - xiami_sauce.gemspec
61
- homepage: ''
152
+ homepage: http://ranmocy.github.com/xiami_sauce
62
153
  licenses:
63
154
  - MIT
155
+ metadata: {}
64
156
  post_install_message:
65
157
  rdoc_options: []
66
158
  require_paths:
67
159
  - lib
68
160
  required_ruby_version: !ruby/object:Gem::Requirement
69
161
  requirements:
70
- - - ! '>='
162
+ - - '>='
71
163
  - !ruby/object:Gem::Version
72
- segments:
73
- - 0
74
164
  version: '0'
75
- hash: -3039331413833145677
76
- none: false
77
165
  required_rubygems_version: !ruby/object:Gem::Requirement
78
166
  requirements:
79
- - - ! '>='
167
+ - - '>='
80
168
  - !ruby/object:Gem::Version
81
- segments:
82
- - 0
83
169
  version: '0'
84
- hash: -3039331413833145677
85
- none: false
86
170
  requirements: []
87
171
  rubyforge_project:
88
- rubygems_version: 1.8.25
172
+ rubygems_version: 2.0.0
89
173
  signing_key:
90
- specification_version: 3
174
+ specification_version: 4
91
175
  summary: A Xiami Downloader.
92
- test_files: []
176
+ test_files:
177
+ - spec/spec_helper.rb
178
+ - spec/xiami_sauce/downloader_spec.rb
179
+ - spec/xiami_sauce/track_list_spec.rb
180
+ - spec/xiami_sauce/track_spec.rb
@@ -1,3 +0,0 @@
1
- module XiamiSauce
2
- VERSION = "0.0.1"
3
- end