bandcamp 0.0.2 → 0.0.4
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.
- 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
|