iTunesAmazon 0.0.1
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/History.txt +5 -0
- data/Manifest.txt +7 -0
- data/README.txt +66 -0
- data/Rakefile +13 -0
- data/lib/i_tunes_amazon.rb +148 -0
- data/lib/track.rb +39 -0
- data/test/test_i_tunes_amazon.rb +77 -0
- metadata +72 -0
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
= iTunesAmazon
|
2
|
+
|
3
|
+
|
4
|
+
== DESCRIPTION:
|
5
|
+
|
6
|
+
This is a handy little program that provides super useful stats about your
|
7
|
+
iTunes library, including information about your music from Amazon. The code
|
8
|
+
was written for a Ruby class at UW extension.
|
9
|
+
|
10
|
+
== FEATURES/PROBLEMS:
|
11
|
+
|
12
|
+
Provides an API to show you the following stats about an iTunes library:
|
13
|
+
Total playtime
|
14
|
+
Artist count
|
15
|
+
Album count
|
16
|
+
Track count
|
17
|
+
Genre count
|
18
|
+
Most played album
|
19
|
+
Most played artist
|
20
|
+
Most played genre
|
21
|
+
Random song
|
22
|
+
Top rated Amazon album
|
23
|
+
Total Amazon cost
|
24
|
+
Top Amazon sales rank
|
25
|
+
|
26
|
+
Many of these functions can be extended in interesting ways, for example you
|
27
|
+
could use the random song generator to create playlists.
|
28
|
+
|
29
|
+
== SYNOPSIS:
|
30
|
+
|
31
|
+
parser = ITunesParser.new("iTunes Music Library.xml")
|
32
|
+
top_track = parser.top_played_songs(1)[0]
|
33
|
+
|
34
|
+
== REQUIREMENTS:
|
35
|
+
|
36
|
+
You will need to install ruby-aaws
|
37
|
+
Also, you will need an Amazon Web Services ID. You can obtain one at: http://www.amazon.com/gp/aws/registration/registration-form.html
|
38
|
+
|
39
|
+
== INSTALL:
|
40
|
+
|
41
|
+
sudo gem install
|
42
|
+
|
43
|
+
== LICENSE:
|
44
|
+
|
45
|
+
(The MIT License)
|
46
|
+
|
47
|
+
Copyright (c) 2008 FIX
|
48
|
+
|
49
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
50
|
+
a copy of this software and associated documentation files (the
|
51
|
+
'Software'), to deal in the Software without restriction, including
|
52
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
53
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
54
|
+
permit persons to whom the Software is furnished to do so, subject to
|
55
|
+
the following conditions:
|
56
|
+
|
57
|
+
The above copyright notice and this permission notice shall be
|
58
|
+
included in all copies or substantial portions of the Software.
|
59
|
+
|
60
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
61
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
62
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
63
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
64
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
65
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
66
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/track.rb'
|
6
|
+
require './lib/i_tunes_amazon.rb'
|
7
|
+
|
8
|
+
Hoe.new('iTunesAmazon', ITunesAmazon::VERSION) do |p|
|
9
|
+
p.rubyforge_name = 'uwruby'
|
10
|
+
p.developer('Tracie Hlavka', 'hlavka@gmail.com')
|
11
|
+
end
|
12
|
+
|
13
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,148 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'nokogiri'
|
7
|
+
require 'amazon/aws'
|
8
|
+
require 'amazon/aws/search'
|
9
|
+
require './lib/track.rb'
|
10
|
+
|
11
|
+
include Amazon::AWS
|
12
|
+
include Amazon::AWS::Search
|
13
|
+
|
14
|
+
KEY_ID = '1E3447REXBE9VATGH4R2'
|
15
|
+
|
16
|
+
class ITunesAmazon
|
17
|
+
VERSION = '0.0.1'
|
18
|
+
|
19
|
+
attr_accessor :tracks, :albums, :total_time
|
20
|
+
|
21
|
+
def initialize(file)
|
22
|
+
@tracks = []
|
23
|
+
@albums = {}
|
24
|
+
parse(file)
|
25
|
+
get_amazon_stats
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse(file)
|
29
|
+
xml = Nokogiri::XML.parse(File.read(file))
|
30
|
+
xml.xpath("//dict/dict/dict").each do |song|
|
31
|
+
track = Track.new
|
32
|
+
song.children.each do |attr|
|
33
|
+
case attr.text
|
34
|
+
when 'Artist' then track.artist = attr.next.text
|
35
|
+
when 'Album' then track.album = attr.next.text
|
36
|
+
when 'Name' then track.name = attr.next.text
|
37
|
+
when 'Genre' then track.genre = attr.next.text
|
38
|
+
when 'Size' then track.size = attr.next.text
|
39
|
+
when 'Total Time' then track.time = attr.next.text
|
40
|
+
when 'Play Count' then track.play_count = attr.next.text
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@tracks << track
|
44
|
+
key = "#{track.artist},#{track.album}"
|
45
|
+
unless @albums.has_key?(key)
|
46
|
+
@albums[key] = Album.new(track.album, track.artist, track)
|
47
|
+
else
|
48
|
+
@albums[key].add_track(track)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_amazon_stats
|
54
|
+
@albums.each_value do |album|
|
55
|
+
album.get_amazon_info
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def track_count
|
60
|
+
@tracks.size
|
61
|
+
end
|
62
|
+
|
63
|
+
def count_field name
|
64
|
+
@tracks.map {|track| track.send name}.uniq.size
|
65
|
+
end
|
66
|
+
|
67
|
+
def artist_count
|
68
|
+
count_field "artist"
|
69
|
+
end
|
70
|
+
|
71
|
+
def album_count
|
72
|
+
count_field "album"
|
73
|
+
end
|
74
|
+
|
75
|
+
def total_playtime
|
76
|
+
total_time = 0
|
77
|
+
@tracks.each do |track|
|
78
|
+
unless (track.time == nil && track.time.is_a?(Numeric)) then
|
79
|
+
total_time += track.time.to_i
|
80
|
+
end
|
81
|
+
end
|
82
|
+
total_time
|
83
|
+
end
|
84
|
+
|
85
|
+
def top_played_songs(n)
|
86
|
+
top_tracks = @tracks.sort {|a, b| b.play_count.to_i <=> a.play_count.to_i}
|
87
|
+
top_tracks[0..(n-1)]
|
88
|
+
end
|
89
|
+
|
90
|
+
def random_song(seed = nil)
|
91
|
+
unless seed == nil then srand(seed) end
|
92
|
+
@tracks[rand(@tracks.size)]
|
93
|
+
end
|
94
|
+
|
95
|
+
def genre_count
|
96
|
+
count_field "genre"
|
97
|
+
end
|
98
|
+
|
99
|
+
def most_played_album
|
100
|
+
most_played_field("album")
|
101
|
+
end
|
102
|
+
|
103
|
+
def most_played_artist
|
104
|
+
most_played_field("artist")
|
105
|
+
end
|
106
|
+
|
107
|
+
def most_played_genre
|
108
|
+
most_played_field("genre")
|
109
|
+
end
|
110
|
+
|
111
|
+
def most_played_field(name)
|
112
|
+
fields = {}
|
113
|
+
fields.default = 0
|
114
|
+
@tracks.each do |track|
|
115
|
+
fields[track.send(name)] += track.play_count.to_i
|
116
|
+
end
|
117
|
+
fields.sort {|a, b| b[1] <=> a[1]}[0][0]
|
118
|
+
end
|
119
|
+
|
120
|
+
def top_rated_amazon_albums(n)
|
121
|
+
top_albums = @albums.values.sort {|a, b| b.amazon_average_rating.to_f <=> a.amazon_average_rating.to_f}
|
122
|
+
top_albums[0..(n-1)]
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
def self.run(args)
|
128
|
+
parser = ITunesAmazon.new(args[0])
|
129
|
+
|
130
|
+
album = parser.top_rated_amazon_albums(1)[0]
|
131
|
+
p "Top rated Amazon album: #{album.album} by #{album.artist} rated #{album.amazon_average_rating.to_f}"
|
132
|
+
|
133
|
+
top_track = parser.top_played_songs(1)[0]
|
134
|
+
p "Top song: #{top_track.name} by #{top_track.artist}, played #{top_track.play_count} times"
|
135
|
+
p "Total playtime: #{parser.total_playtime/1000/60} minutes"
|
136
|
+
p "Artist Count: #{parser.artist_count}"
|
137
|
+
p "Album Count: #{parser.album_count}"
|
138
|
+
p "Track Count: #{parser.track_count}"
|
139
|
+
p "Genre Count: #{parser.genre_count}"
|
140
|
+
random_song = parser.random_song()
|
141
|
+
p "Random song: #{random_song.name} by #{random_song.artist}"
|
142
|
+
p "Most playd album: #{parser.most_played_album}"
|
143
|
+
p "Most played artist: #{parser.most_played_artist}"
|
144
|
+
p "Most played genre: #{parser.most_played_genre}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
ITunesAmazon.run(ARGV) if __FILE__ == $0
|
data/lib/track.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
|
3
|
+
class Track
|
4
|
+
attr_accessor :track_id, :name, :artist, :album, :genre, :size, :time, :play_count
|
5
|
+
end
|
6
|
+
|
7
|
+
class Album
|
8
|
+
attr_accessor :tracks, :album, :artist, :amazon_average_rating, :amazon_total_reviews, :amazon_price, :amazon_sales_rank
|
9
|
+
|
10
|
+
def initialize(album, artist, track)
|
11
|
+
@album = album
|
12
|
+
@artist = artist
|
13
|
+
@tracks = []
|
14
|
+
add_track(track)
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_track(track)
|
18
|
+
@tracks << track
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_amazon_info
|
22
|
+
request = Request.new(KEY_ID)
|
23
|
+
unless @artist == nil || @album == nil then
|
24
|
+
is = ItemSearch.new('Music', {'Artist' => @artist, 'Title' => @album, 'MerchantId' => 'Amazon'})
|
25
|
+
rg = ResponseGroup.new('Large')
|
26
|
+
|
27
|
+
begin
|
28
|
+
response = request.search(is, rg)
|
29
|
+
items = response.item_search_response.items.item
|
30
|
+
@amazon_average_rating = items[0].average_rating.to_s
|
31
|
+
@amazon_total_reviews = items[0].total_reviews.to_s
|
32
|
+
@amazon_price = items[0].item_attributes.list_price.amount.to_s
|
33
|
+
@amazon_sales_rank = items[0].sales_rank.to_s
|
34
|
+
rescue Amazon::AWS::Error::NoExactMatches
|
35
|
+
# do nothing?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
|
3
|
+
|
4
|
+
$: << 'lib'
|
5
|
+
|
6
|
+
require "test/unit"
|
7
|
+
require 'i_tunes_amazon.rb'
|
8
|
+
|
9
|
+
class ITunesParserTester < Test::Unit::TestCase
|
10
|
+
@@parse_this = ITunesAmazon.new("../test.itunes.xml")
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@parser = @@parse_this
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_track_count
|
17
|
+
actual = @parser.track_count
|
18
|
+
expected = 19
|
19
|
+
assert_equal expected, actual
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_artist_count
|
23
|
+
actual = @parser.artist_count
|
24
|
+
expected = 2
|
25
|
+
assert_equal expected, actual
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_album_count
|
29
|
+
actual = @parser.album_count
|
30
|
+
expected = 2
|
31
|
+
assert_equal expected, actual
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_total_playtime
|
35
|
+
actual = @parser.total_playtime
|
36
|
+
expected = 4987057
|
37
|
+
assert_equal expected, actual
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_top_song
|
41
|
+
actual = @parser.top_played_songs(1)[0].name
|
42
|
+
expected = "Kick In The Eye"
|
43
|
+
assert_equal expected, actual
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_random_song
|
47
|
+
actual = @parser.random_song(0).name
|
48
|
+
expected = "Lagartija Nick"
|
49
|
+
assert_equal expected, actual
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_genre_count
|
53
|
+
actual = @parser.genre_count
|
54
|
+
expected = 2
|
55
|
+
assert_equal expected, actual
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_most_played_genre
|
59
|
+
actual = @parser.most_played_genre
|
60
|
+
expected = "Goth"
|
61
|
+
assert_equal expected, actual
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_most_played_album
|
65
|
+
actual = @parser.most_played_album
|
66
|
+
expected = "1979-1983 Volume Two"
|
67
|
+
assert_equal expected, actual
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_most_played_artist
|
71
|
+
actual = @parser.most_played_artist
|
72
|
+
expected = "Bauhaus"
|
73
|
+
assert_equal expected, actual
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iTunesAmazon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tracie Hlavka
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-19 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.1
|
24
|
+
version:
|
25
|
+
description: This is a handy little program that provides super useful stats about your iTunes library, including information about your music from Amazon. The code was written for a Ruby class at UW extension.
|
26
|
+
email:
|
27
|
+
- hlavka@gmail.com
|
28
|
+
executables: []
|
29
|
+
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files:
|
33
|
+
- History.txt
|
34
|
+
- Manifest.txt
|
35
|
+
- README.txt
|
36
|
+
files:
|
37
|
+
- History.txt
|
38
|
+
- Manifest.txt
|
39
|
+
- README.txt
|
40
|
+
- Rakefile
|
41
|
+
- lib/i_tunes_amazon.rb
|
42
|
+
- lib/track.rb
|
43
|
+
- test/test_i_tunes_amazon.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage:
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options:
|
48
|
+
- --main
|
49
|
+
- README.txt
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project: uwruby
|
67
|
+
rubygems_version: 1.3.1
|
68
|
+
signing_key:
|
69
|
+
specification_version: 2
|
70
|
+
summary: This is a handy little program that provides super useful stats about your iTunes library, including information about your music from Amazon
|
71
|
+
test_files:
|
72
|
+
- test/test_i_tunes_amazon.rb
|