bandcamp 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/band_camp_download +18 -3
- data/lib/band_camp.rb +6 -2
- data/lib/band_camp/cli/options.rb +25 -0
- data/lib/band_camp/downloader.rb +22 -0
- data/lib/band_camp/page.rb +87 -0
- data/lib/band_camp/song.rb +25 -14
- data/lib/band_camp/version.rb +1 -1
- metadata +35 -5
- data/lib/band_camp/band.rb +0 -49
data/bin/band_camp_download
CHANGED
@@ -1,8 +1,23 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
lib_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
$:.unshift(lib_dir) unless
|
5
|
+
$:.include?(lib_dir) || $:.include?(File.expand_path(lib_dir))
|
6
|
+
|
3
7
|
require 'band_camp'
|
4
8
|
|
5
|
-
|
6
|
-
|
7
|
-
|
9
|
+
options = BandCamp::Cli::Options.extract_from_argv
|
10
|
+
|
11
|
+
if ARGV.size > 0
|
12
|
+
ARGV.each do |url|
|
13
|
+
page = BandCamp::Page.new(url, options)
|
14
|
+
page.download
|
15
|
+
end
|
16
|
+
else
|
17
|
+
usage = <<EOT
|
18
|
+
Usage: #{$0} http://example.bandcamp.com [http://otherexample.bandcamp.com/]*
|
19
|
+
This script finds all the songs shown on the bandcamp page and downloads them to
|
20
|
+
./download/band_name/0x-track_name.mp3
|
21
|
+
EOT
|
22
|
+
STDERR.puts usage
|
8
23
|
end
|
data/lib/band_camp.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
require "band_camp/
|
1
|
+
require "band_camp/page"
|
2
|
+
require "band_camp/cli/options"
|
3
|
+
if Gem.available?("ruby-debug")
|
4
|
+
require "ruby-debug"
|
5
|
+
end
|
2
6
|
|
3
7
|
module BandCamp
|
4
8
|
def self.file_safe_string(string)
|
5
|
-
string.tr("^a-zA-Z0-9-
|
9
|
+
string.gsub("&", " and ").tr("^a-zA-Z0-9-", "_").gsub(/_+/, "_")
|
6
10
|
end
|
7
11
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module BandCamp
|
2
|
+
module Cli
|
3
|
+
module Options
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
def self.extract_from_argv
|
7
|
+
options = {}
|
8
|
+
options[:debug] = true
|
9
|
+
|
10
|
+
OptionParser.new do |opts|
|
11
|
+
opts.banner = "Usage: example.rb [options]"
|
12
|
+
|
13
|
+
opts.on("-t", "--true", "Do not download any mp3 files") do |v|
|
14
|
+
options[:try] = v
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on("-d", "--[no-]debug", "Output debug information") do |v|
|
18
|
+
options[:debug] = v
|
19
|
+
end
|
20
|
+
end.parse!
|
21
|
+
options
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module BandCamp
|
5
|
+
class Downloader
|
6
|
+
def self.download(options)
|
7
|
+
url = options[:url] || raise(ArgumentError, "No url provided")
|
8
|
+
file_name = options[:file_name] || raise(ArgumentError, "No file_name provided")
|
9
|
+
|
10
|
+
puts "Saving #{file_name}" if options[:debug]
|
11
|
+
|
12
|
+
parsed_url = URI.parse(url)
|
13
|
+
res = Net::HTTP.start(parsed_url.host, parsed_url.port) {|http|
|
14
|
+
http.get("#{parsed_url.path}?#{parsed_url.query}")
|
15
|
+
}
|
16
|
+
|
17
|
+
File.open(file_name, "w") do |file|
|
18
|
+
file.puts res.body
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "band_camp/song"
|
2
|
+
require "band_camp/downloader"
|
3
|
+
require "harmony"
|
4
|
+
require "hpricot"
|
5
|
+
|
6
|
+
module BandCamp
|
7
|
+
class Page
|
8
|
+
def initialize(url, options = {})
|
9
|
+
@options = options
|
10
|
+
@url = url
|
11
|
+
end
|
12
|
+
|
13
|
+
def page_html
|
14
|
+
unless @page_html
|
15
|
+
puts "Getting content of \"#{@url}\"" if @options[:debug]
|
16
|
+
@page_html = Net::HTTP.get(URI.parse(@url))
|
17
|
+
end
|
18
|
+
@page_html
|
19
|
+
end
|
20
|
+
|
21
|
+
def harmony_page
|
22
|
+
unless @harmony_page
|
23
|
+
# Assigning to a variable first to make the puts statements make sense
|
24
|
+
html = page_html
|
25
|
+
puts "Initializing headless browser" if @options[:debug]
|
26
|
+
@harmony_page = Harmony::Page.new(html)
|
27
|
+
end
|
28
|
+
@harmony_page
|
29
|
+
end
|
30
|
+
|
31
|
+
def songs
|
32
|
+
@songs ||= harmony_page.execute_js("TralbumData.trackinfo").map do |song_object|
|
33
|
+
Song.new(song_object.title.to_s, song_object.title_link.to_s, song_object.file.to_s, @options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def band_name
|
38
|
+
@band_name ||= harmony_page.execute_js("BandData.name")
|
39
|
+
end
|
40
|
+
|
41
|
+
def album_name
|
42
|
+
@album_name ||= harmony_page.execute_js("TralbumData.current.title")
|
43
|
+
end
|
44
|
+
|
45
|
+
def download
|
46
|
+
dir = path_for_download
|
47
|
+
unless @options[:try]
|
48
|
+
`mkdir -p #{dir}`
|
49
|
+
end
|
50
|
+
|
51
|
+
number_of_tracks = songs.size
|
52
|
+
|
53
|
+
songs.each_with_index { |song, index|
|
54
|
+
song.download(dir,
|
55
|
+
:index => index,
|
56
|
+
:number_of_tracks => number_of_tracks,
|
57
|
+
:band_name => band_name,
|
58
|
+
:album_name => album_name)
|
59
|
+
}
|
60
|
+
|
61
|
+
download_album_art
|
62
|
+
end
|
63
|
+
|
64
|
+
def path_for_download
|
65
|
+
File.join("download",
|
66
|
+
BandCamp::file_safe_string(band_name),
|
67
|
+
BandCamp::file_safe_string(album_name))
|
68
|
+
end
|
69
|
+
|
70
|
+
def hpricot
|
71
|
+
@hpricot ||= Hpricot.parse(page_html)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def download_album_art
|
77
|
+
# Assumes the directory where the album is downloaded already exists
|
78
|
+
url = hpricot.search("#tralbumArt img").first.attributes["src"]
|
79
|
+
file_name = File.join(path_for_download, "album.jpg")
|
80
|
+
if @options[:try]
|
81
|
+
puts "[try] Saving #{file_name}"
|
82
|
+
else
|
83
|
+
Downloader.download(:url => url, :file_name => file_name, :debug => @options[:debug])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/band_camp/song.rb
CHANGED
@@ -1,34 +1,45 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "band_camp/downloader"
|
2
|
+
require "id3lib"
|
3
3
|
|
4
4
|
module BandCamp
|
5
5
|
class Song
|
6
6
|
attr_reader :title, :title_link, :url
|
7
7
|
|
8
|
-
def initialize(title, title_link, url)
|
8
|
+
def initialize(title, title_link, url, options = {})
|
9
9
|
@title = title
|
10
10
|
@title_link = title_link
|
11
11
|
@url = url
|
12
|
+
@options = options
|
12
13
|
end
|
13
14
|
|
14
15
|
def to_s
|
15
16
|
"title: #{title}"
|
16
17
|
end
|
17
18
|
|
18
|
-
def download(band_path,
|
19
|
-
song_url = URI.parse(url)
|
20
|
-
res = Net::HTTP.start(song_url.host, song_url.port) {|http|
|
21
|
-
http.get("#{song_url.path}?#{song_url.query}")
|
22
|
-
}
|
23
|
-
|
19
|
+
def download(band_path, options = {})
|
24
20
|
song_name = BandCamp::file_safe_string(title)
|
25
|
-
if index
|
26
|
-
song_name = "%02d-%s" % [index + 1, song_name]
|
21
|
+
if options[:index]
|
22
|
+
song_name = "%02d-%s" % [options[:index] + 1, song_name]
|
27
23
|
end
|
28
24
|
file_name = File.join(band_path, song_name + ".mp3")
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
|
26
|
+
if @options[:try]
|
27
|
+
puts "[try] Saving #{file_name}"
|
28
|
+
else
|
29
|
+
Downloader.download(:url => url, :file_name => file_name, :debug => @options[:debug])
|
30
|
+
|
31
|
+
id3_tag = ID3Lib::Tag.new(file_name)
|
32
|
+
id3_tag.title = title
|
33
|
+
id3_tag.artist = options[:band_name] if options[:band_name]
|
34
|
+
id3_tag.album = options[:album_name] if options[:album_name]
|
35
|
+
if options[:index]
|
36
|
+
track = (options[:index] + 1).to_s
|
37
|
+
if options[:number_of_tracks]
|
38
|
+
track += "/%d" % options[:number_of_tracks]
|
39
|
+
end
|
40
|
+
id3_tag.track = track
|
41
|
+
end
|
42
|
+
id3_tag.update!
|
32
43
|
end
|
33
44
|
end
|
34
45
|
end
|
data/lib/band_camp/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bandcamp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tom ten Thij
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-10 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -32,6 +32,34 @@ dependencies:
|
|
32
32
|
version: "0"
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hpricot
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: id3lib-ruby
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
35
63
|
description: A utility to download the low quality mp3 files for a band on bandcamp.com
|
36
64
|
email:
|
37
65
|
- ruby@tomtenthij.nl
|
@@ -43,7 +71,9 @@ extra_rdoc_files: []
|
|
43
71
|
|
44
72
|
files:
|
45
73
|
- bin/band_camp_download
|
46
|
-
- lib/band_camp/
|
74
|
+
- lib/band_camp/cli/options.rb
|
75
|
+
- lib/band_camp/downloader.rb
|
76
|
+
- lib/band_camp/page.rb
|
47
77
|
- lib/band_camp/song.rb
|
48
78
|
- lib/band_camp/version.rb
|
49
79
|
- lib/band_camp.rb
|
data/lib/band_camp/band.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
require "band_camp/song"
|
2
|
-
require 'net/http'
|
3
|
-
require 'uri'
|
4
|
-
require 'harmony'
|
5
|
-
|
6
|
-
module BandCamp
|
7
|
-
class Band
|
8
|
-
def initialize(url)
|
9
|
-
@url = url
|
10
|
-
end
|
11
|
-
|
12
|
-
def page_html
|
13
|
-
unless @page_html
|
14
|
-
puts "Getting content of \"#{@url}\""
|
15
|
-
@page_html = Net::HTTP.get(URI.parse(@url))
|
16
|
-
end
|
17
|
-
@page_html
|
18
|
-
end
|
19
|
-
|
20
|
-
def harmony_page
|
21
|
-
unless @harmony_page
|
22
|
-
html = page_html
|
23
|
-
puts "Initializing headless browser"
|
24
|
-
@harmony_page = Harmony::Page.new(html)
|
25
|
-
end
|
26
|
-
@harmony_page
|
27
|
-
end
|
28
|
-
|
29
|
-
def songs
|
30
|
-
@songs ||= harmony_page.execute_js("TralbumData.trackinfo").map do |song_object|
|
31
|
-
Song.new(song_object.title.to_s, song_object.title_link.to_s, song_object.file.to_s)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def name
|
36
|
-
harmony_page.execute_js("BandData.name")
|
37
|
-
end
|
38
|
-
|
39
|
-
def download
|
40
|
-
dir = path_for_download
|
41
|
-
`mkdir -p #{dir}`
|
42
|
-
songs.each_with_index { |song, index| song.download(dir, index) }
|
43
|
-
end
|
44
|
-
|
45
|
-
def path_for_download
|
46
|
-
File.join("download", BandCamp::file_safe_string(name))
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|