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.
@@ -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
- ARGV.each do |url|
6
- band = BandCamp::Band.new(url)
7
- band.download
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
@@ -1,7 +1,11 @@
1
- require "band_camp/band"
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-_", "_").gsub(/_+/, "_")
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
@@ -1,34 +1,45 @@
1
- require 'net/http'
2
- require 'uri'
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, index = nil)
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
- puts "Saving #{file_name}"
30
- File.open(file_name, "w") do |file|
31
- file.puts res.body
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
@@ -1,4 +1,4 @@
1
1
  module BandCamp
2
2
  # We're doing this because bundler did it this way
3
- VERSION = "0.0.2" unless defined?(::BandCamp::VERSION)
3
+ VERSION = "0.0.4" unless defined?(::BandCamp::VERSION)
4
4
  end
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: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
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-09 00:00:00 +01:00
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/band.rb
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
@@ -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