stratify-itunes 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +92 -0
- data/LICENSE +20 -0
- data/README.md +21 -0
- data/Rakefile +10 -0
- data/app/assets/images/itunes-icon-16.png +0 -0
- data/app/assets/images/itunes-icon-24.png +0 -0
- data/lib/stratify-itunes/activity.rb +37 -0
- data/lib/stratify-itunes/collector.rb +33 -0
- data/lib/stratify-itunes/engine.rb +9 -0
- data/lib/stratify-itunes/presenter.rb +51 -0
- data/lib/stratify-itunes/query.rb +56 -0
- data/lib/stratify-itunes/version.rb +5 -0
- data/lib/stratify-itunes.rb +6 -0
- data/spec/fixtures/iTunes Music Library.xml +2092 -0
- data/spec/mongoid.yml +3 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/stratify-itunes/integration_spec.rb +76 -0
- data/spec/stratify-itunes/presenter_spec.rb +148 -0
- data/stratify-itunes.gemspec +28 -0
- metadata +134 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use ruby-1.9.2-p180@stratify
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
stratify-itunes (0.1.0)
|
5
|
+
itunes-library (~> 0.1.1)
|
6
|
+
railties (~> 3.1.0.rc1)
|
7
|
+
stratify-base (~> 0.1.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actionpack (3.1.0.rc1)
|
13
|
+
activemodel (= 3.1.0.rc1)
|
14
|
+
activesupport (= 3.1.0.rc1)
|
15
|
+
builder (~> 3.0.0)
|
16
|
+
erubis (~> 2.7.0)
|
17
|
+
i18n (~> 0.6.0beta1)
|
18
|
+
rack (~> 1.3.0.beta2)
|
19
|
+
rack-cache (~> 1.0.1)
|
20
|
+
rack-mount (~> 0.8.1)
|
21
|
+
rack-test (~> 0.6.0)
|
22
|
+
sprockets (~> 2.0.0.beta.5)
|
23
|
+
tzinfo (~> 0.3.27)
|
24
|
+
activemodel (3.1.0.rc1)
|
25
|
+
activesupport (= 3.1.0.rc1)
|
26
|
+
bcrypt-ruby (~> 2.1.4)
|
27
|
+
builder (~> 3.0.0)
|
28
|
+
i18n (~> 0.6.0beta1)
|
29
|
+
activesupport (3.1.0.rc1)
|
30
|
+
multi_json (~> 1.0)
|
31
|
+
bcrypt-ruby (2.1.4)
|
32
|
+
bson (1.3.1)
|
33
|
+
bson_ext (1.3.1)
|
34
|
+
builder (3.0.0)
|
35
|
+
database_cleaner (0.6.7)
|
36
|
+
diff-lcs (1.1.2)
|
37
|
+
erubis (2.7.0)
|
38
|
+
hike (1.0.0)
|
39
|
+
i18n (0.6.0)
|
40
|
+
itunes-library (0.1.1)
|
41
|
+
plist
|
42
|
+
mongo (1.3.1)
|
43
|
+
bson (>= 1.3.1)
|
44
|
+
mongoid (2.0.2)
|
45
|
+
activemodel (~> 3.0)
|
46
|
+
mongo (~> 1.3)
|
47
|
+
tzinfo (~> 0.3.22)
|
48
|
+
multi_json (1.0.3)
|
49
|
+
plist (3.1.0)
|
50
|
+
rack (1.3.0)
|
51
|
+
rack-cache (1.0.2)
|
52
|
+
rack (>= 0.4)
|
53
|
+
rack-mount (0.8.1)
|
54
|
+
rack (>= 1.0.0)
|
55
|
+
rack-ssl (1.3.2)
|
56
|
+
rack
|
57
|
+
rack-test (0.6.0)
|
58
|
+
rack (>= 1.0)
|
59
|
+
railties (3.1.0.rc1)
|
60
|
+
actionpack (= 3.1.0.rc1)
|
61
|
+
activesupport (= 3.1.0.rc1)
|
62
|
+
rack-ssl (~> 1.3.2)
|
63
|
+
rake (>= 0.8.7)
|
64
|
+
thor (~> 0.14.6)
|
65
|
+
rake (0.9.2)
|
66
|
+
rspec (2.6.0)
|
67
|
+
rspec-core (~> 2.6.0)
|
68
|
+
rspec-expectations (~> 2.6.0)
|
69
|
+
rspec-mocks (~> 2.6.0)
|
70
|
+
rspec-core (2.6.3)
|
71
|
+
rspec-expectations (2.6.0)
|
72
|
+
diff-lcs (~> 1.1.2)
|
73
|
+
rspec-mocks (2.6.0)
|
74
|
+
sprockets (2.0.0.beta.10)
|
75
|
+
hike (~> 1.0)
|
76
|
+
rack (~> 1.0)
|
77
|
+
tilt (!= 1.3.0, ~> 1.1)
|
78
|
+
stratify-base (0.1.0)
|
79
|
+
bson_ext (~> 1.3.1)
|
80
|
+
mongoid (~> 2.0.2)
|
81
|
+
tilt (~> 1.3.2)
|
82
|
+
thor (0.14.6)
|
83
|
+
tilt (1.3.2)
|
84
|
+
tzinfo (0.3.27)
|
85
|
+
|
86
|
+
PLATFORMS
|
87
|
+
ruby
|
88
|
+
|
89
|
+
DEPENDENCIES
|
90
|
+
database_cleaner (~> 0.6.7)
|
91
|
+
rspec (~> 2.6.0)
|
92
|
+
stratify-itunes!
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Jason Rudolph (http://jasonrudolph.com)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
'Software'), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# stratify-itunes
|
2
|
+
|
3
|
+
## Dependencies
|
4
|
+
|
5
|
+
Stratify is developed and tested with the following dependencies.
|
6
|
+
|
7
|
+
* Ruby 1.9.2 (See `.rvmrc` for the specific version.)
|
8
|
+
* MongoDB 1.8
|
9
|
+
|
10
|
+
## Development
|
11
|
+
|
12
|
+
To get set up for development on stratify-itunes, clone the repo, and ...
|
13
|
+
|
14
|
+
cd stratify/stratify-itunes
|
15
|
+
gem install bundler
|
16
|
+
bundle
|
17
|
+
rake
|
18
|
+
|
19
|
+
## License
|
20
|
+
|
21
|
+
Copyright 2011 Jason Rudolph ([jasonrudolph.com](http://jasonrudolph.com)). Released under the MIT license. See the LICENSE file for further details.
|
data/Rakefile
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'stratify-itunes/presenter'
|
2
|
+
|
3
|
+
module Stratify
|
4
|
+
module ITunes
|
5
|
+
class Activity < Stratify::Activity
|
6
|
+
field :persistent_id, :type => Integer
|
7
|
+
field :album
|
8
|
+
field :artist
|
9
|
+
field :composer
|
10
|
+
field :genre
|
11
|
+
field :movie, :type => Boolean
|
12
|
+
field :name
|
13
|
+
field :podcast, :type => Boolean
|
14
|
+
field :track_number, :type => Integer
|
15
|
+
field :episode_number, :type => Integer
|
16
|
+
field :tv_show, :type => Boolean
|
17
|
+
field :season_number, :type => Integer
|
18
|
+
field :year, :type => Integer
|
19
|
+
|
20
|
+
natural_key :persistent_id, :created_at
|
21
|
+
|
22
|
+
validates_presence_of :persistent_id
|
23
|
+
|
24
|
+
# For TV shows, iTunes stores the show name in the Artist field
|
25
|
+
alias_attribute :show, :artist
|
26
|
+
|
27
|
+
template %q[
|
28
|
+
<p class="summary"><%= summary %></p>
|
29
|
+
<p class="details"><%= details %></p>
|
30
|
+
]
|
31
|
+
|
32
|
+
def presenter
|
33
|
+
Stratify::ITunes::Presenter.new(self)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'stratify-itunes/query'
|
2
|
+
|
3
|
+
module Stratify
|
4
|
+
module ITunes
|
5
|
+
class Collector < Stratify::Collector
|
6
|
+
source "iTunes"
|
7
|
+
|
8
|
+
configuration_fields :library_path => {:type => :string, :label => "Location of 'iTunes Music Library.xml' file"}
|
9
|
+
|
10
|
+
configuration_instructions %q[
|
11
|
+
<p>An iTunes collector pulls in your latest iTunes activity from an "iTunes Music Library.xml" file. On OS X, this file typically resides at <code>~/Music/iTunes/iTunes Music Library.xml</code>. To create an iTunes collector, provide the location of your iTunes XML file.</p>
|
12
|
+
|
13
|
+
<p>To pull in activity from a local iTunes library, just provide the file path, and you're all set. For example:</p>
|
14
|
+
|
15
|
+
<p><code>/Users/johndoe/Music/iTunes/iTunes Music Library.xml</code></p>
|
16
|
+
|
17
|
+
<p>You can also pull in activity from an iTunes XML file at a remote location. To do so, just provide a URL that points to the file. A few examples:</p>
|
18
|
+
|
19
|
+
<p><code>http://dl.dropbox.com/u/1234567/iTunes%20Music%20Library.xml</code></p>
|
20
|
+
|
21
|
+
<p><code>ftp://username:password@LivingRoomMacMini.local/Music/iTunes/iTunes%20Music%20Library.xml</code></p>
|
22
|
+
]
|
23
|
+
|
24
|
+
def activities
|
25
|
+
query.activities
|
26
|
+
end
|
27
|
+
|
28
|
+
def query
|
29
|
+
Stratify::ITunes::Query.new(library_path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Stratify
|
2
|
+
module ITunes
|
3
|
+
class Presenter
|
4
|
+
def initialize(activity)
|
5
|
+
@activity = activity
|
6
|
+
end
|
7
|
+
|
8
|
+
def name
|
9
|
+
@activity.name.blank? ? 'Untitled' : @activity.name
|
10
|
+
end
|
11
|
+
|
12
|
+
def summary
|
13
|
+
return name if movie?
|
14
|
+
join_fields_with_separator name, artist
|
15
|
+
end
|
16
|
+
|
17
|
+
def details
|
18
|
+
if tv_show?
|
19
|
+
join_fields_with_separator season_number, episode_number, year
|
20
|
+
else
|
21
|
+
join_fields_with_separator album, year, genre
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def season_number
|
26
|
+
return unless @activity.season_number
|
27
|
+
"Season #{@activity.season_number}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def episode_number
|
31
|
+
number = @activity.episode_number || @activity.track_number
|
32
|
+
return unless number
|
33
|
+
"Episode #{number}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_missing(*args)
|
37
|
+
@activity.send(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def separator
|
43
|
+
"\u2022"
|
44
|
+
end
|
45
|
+
|
46
|
+
def join_fields_with_separator(*fields)
|
47
|
+
fields.reject(&:blank?).join(" #{separator} ")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'itunes/library'
|
2
|
+
|
3
|
+
module Stratify
|
4
|
+
module ITunes
|
5
|
+
class Query
|
6
|
+
attr_reader :library_path, :limit
|
7
|
+
|
8
|
+
def initialize(library_path, limit = 50)
|
9
|
+
@library_path = library_path
|
10
|
+
@limit = limit
|
11
|
+
end
|
12
|
+
|
13
|
+
def activities
|
14
|
+
recently_played_tracks.map {|track| build_activity_from_raw_data(track)}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def library_xml
|
20
|
+
open(@library_path).read
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_activity_from_raw_data(track)
|
24
|
+
Stratify::ITunes::Activity.new({
|
25
|
+
:album => track.album,
|
26
|
+
:artist => track.artist,
|
27
|
+
:composer => track.composer,
|
28
|
+
:created_at => track.last_played_at.to_time,
|
29
|
+
:episode_number => track.episode_number,
|
30
|
+
:genre => track.genre,
|
31
|
+
:movie => track.movie?,
|
32
|
+
:name => track.name,
|
33
|
+
:persistent_id => track.persistent_id,
|
34
|
+
:podcast => track.podcast?,
|
35
|
+
:season_number => track.season_number,
|
36
|
+
:track_number => track.number,
|
37
|
+
:tv_show => track.tv_show?,
|
38
|
+
:year => track.year,
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
42
|
+
def tracks
|
43
|
+
::ITunes::Library.load(library_xml).tracks
|
44
|
+
end
|
45
|
+
|
46
|
+
def played_tracks
|
47
|
+
tracks.select { |t| t.played? }
|
48
|
+
end
|
49
|
+
|
50
|
+
def recently_played_tracks
|
51
|
+
sorted_tracks = played_tracks.sort_by(&:last_played_at)
|
52
|
+
sorted_tracks.last(limit)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|