itunes-controller 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.buildpath +5 -0
  2. data/.gitignore +3 -0
  3. data/.project +17 -0
  4. data/.rvmrc +81 -0
  5. data/LICENSE +674 -0
  6. data/README +27 -0
  7. data/Rakefile +27 -0
  8. data/TODO +8 -0
  9. data/bin/addFiles.rb +35 -0
  10. data/bin/dummyiTunesController.rb +109 -0
  11. data/bin/itunesController.rb +78 -0
  12. data/bin/listDeadTracks.rb +45 -0
  13. data/bin/listNewTracks.rb +88 -0
  14. data/bin/recreateTrackCache.rb +31 -0
  15. data/bin/refreshFiles.rb +42 -0
  16. data/bin/removeDeadTracks.rb +31 -0
  17. data/bin/removeFiles.rb +42 -0
  18. data/bin/trackInfo.rb +50 -0
  19. data/itunes-controller.gemspec +24 -0
  20. data/jar-stuff.sh +24 -0
  21. data/lib/itunesController/application.rb +127 -0
  22. data/lib/itunesController/cachedcontroller.rb +188 -0
  23. data/lib/itunesController/config.rb +95 -0
  24. data/lib/itunesController/controller_creator.rb +29 -0
  25. data/lib/itunesController/controllserver.rb +583 -0
  26. data/lib/itunesController/database/backend.rb +41 -0
  27. data/lib/itunesController/database/database.rb +166 -0
  28. data/lib/itunesController/database/sqlite3_backend.rb +67 -0
  29. data/lib/itunesController/debug.rb +124 -0
  30. data/lib/itunesController/dummy_itunes_track.rb +40 -0
  31. data/lib/itunesController/dummy_itunescontroller.rb +142 -0
  32. data/lib/itunesController/itunescontroller.rb +90 -0
  33. data/lib/itunesController/itunescontroller_factory.rb +51 -0
  34. data/lib/itunesController/kinds.rb +138 -0
  35. data/lib/itunesController/logging.rb +119 -0
  36. data/lib/itunesController/macosx_itunescontroller.rb +204 -0
  37. data/lib/itunesController/platform.rb +53 -0
  38. data/lib/itunesController/sqlite_creator.rb +35 -0
  39. data/lib/itunesController/track.rb +39 -0
  40. data/lib/itunesController/version.rb +25 -0
  41. data/lib/itunesController/windows_itunescontroller.rb +145 -0
  42. data/test/base_server_test_case.rb +125 -0
  43. data/test/dummy_client.rb +44 -0
  44. data/test/test_server.rb +312 -0
  45. metadata +185 -0
@@ -0,0 +1,90 @@
1
+ #
2
+ # Copyright (C) 2011-2012 John-Paul.Stanford <dev@stanwood.org.uk>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #
17
+ # Author:: John-Paul Stanford <dev@stanwood.org.uk>
18
+ # Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
19
+ # License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ module ItunesController
23
+
24
+ # This is the base class of all itunes controller.
25
+ # @abstract This class should be overridden to implement the class that talks to iTunes.
26
+ class BaseITunesController
27
+
28
+ # The constructor
29
+ def initialize()
30
+ end
31
+
32
+ # Used to get the iTunes version
33
+ # @abstract Must be overridden
34
+ # @return [String] The itunes version
35
+ def version
36
+ raise "ERROR: Your trying to instantiate an abstract class"
37
+ end
38
+
39
+ # Used to remove tracks from the libaray
40
+ # @abstract Must be overridden
41
+ # @param [Array] tracks A list of tracks to remove from the itunes libaray
42
+ def removeTracksFromLibrary(tracks)
43
+ raise "ERROR: Your trying to instantiate an abstract class"
44
+ end
45
+
46
+ # Used to add a list of files to the itunes library
47
+ # @abstract Must be overridden
48
+ # @param [Array[String]] A list of files to add to the itunes library
49
+ # @return [Array[ItunesController::Track]] List of ids of the new tracks once they are in the database
50
+ def addFilesToLibrary(files)
51
+ raise "ERROR: Your trying to instantiate an abstract class"
52
+ end
53
+
54
+ # Used to tell iTunes to refresh a list of tracks data from the info stored in the files
55
+ # @abstract Must be overridden
56
+ # @param [Array] tracks A list of tracks to fresh
57
+ def refreshTracks(tracks)
58
+ raise "ERROR: Your trying to instantiate an abstract class"
59
+ end
60
+
61
+ # @abstract Must be overridden
62
+ def getTracks(&b)
63
+ raise "ERROR: Your trying to instantiate an abstract class"
64
+ end
65
+
66
+ # Used to search the itunes library
67
+ # @param term The search term
68
+ # @return [Array] a list of iTunes track that match the search term
69
+ # @abstract Must be overridden
70
+ def searchLibrary(term)
71
+ raise "ERROR: Your trying to instantiate an abstract class"
72
+ end
73
+
74
+ # Used to find the number of tracks in the library
75
+ # @abstract Must be overridden
76
+ # @return [Number] The number of tracks
77
+ def getTrackCount()
78
+ raise "ERROR: Your trying to instantiate an abstract class"
79
+ end
80
+
81
+ # Used to get the database of a itunes track
82
+ # @abstract Must be overridden
83
+ # @param track the track
84
+ # @return The database id
85
+ def getTrackDatabaseId(track)
86
+ raise "ERROR: Your trying to instantiate an abstract class"
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,51 @@
1
+ #
2
+ # Copyright (C) 2011-2012 John-Paul.Stanford <dev@stanwood.org.uk>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #
17
+ # Author:: John-Paul Stanford <dev@stanwood.org.uk>
18
+ # Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
19
+ # License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ require 'itunesController/platform'
23
+ if ItunesController::Platform::isWindows()
24
+ require 'itunesController/windows_itunescontroller.rb'
25
+ elsif ItunesController::Platform::isMacOSX()
26
+ require 'itunesController/macosx_itunescontroller.rb'
27
+ else
28
+ raise("Unsupported operating system #{RUBY_PLATFORM}.")
29
+ end
30
+
31
+ require 'itunesController/database/database'
32
+
33
+ module ItunesController
34
+
35
+ # This is a factory class used to create a iTunes controller for the current platform
36
+ class ITunesControllerFactory
37
+
38
+ # Used to create the iTunes controller for different platforms
39
+ # @return [ItunesController::BaseITunesController] The itunes controller
40
+ # @raise If the platform is unsupported
41
+ def self.createController()
42
+ if ItunesController::Platform::isWindows()
43
+ return ItunesController::WindowsITunesController.new()
44
+ elsif ItunesController::Platform::isMacOSX()
45
+ return ItunesController::MacOSXITunesController.new()
46
+ else
47
+ raise("Unsupported operating system #{RUBY_PLATFORM}.")
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,138 @@
1
+ #
2
+ # Copyright (C) 2011-2012 John-Paul.Stanford <dev@stanwood.org.uk>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #
17
+ # Author:: John-Paul Stanford <dev@stanwood.org.uk>
18
+ # Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
19
+ # License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ module ItunesController
23
+
24
+ # A enum of special kinds
25
+ # @attr [Number] kind The Source kind ID
26
+ # @attr [String] String the source display name
27
+ class SpecialKind
28
+ attr_accessor :kind, :displayName
29
+ def initialize(kind,displayName)
30
+ @kind = kind
31
+ @displayName = displayName
32
+ end
33
+
34
+ # The Audio Book kind
35
+ Audiobooks=SpecialKind.new(1800630337,"Audiobooks")
36
+ # The folder kind
37
+ Folder=SpecialKind.new(1800630342,"Folder")
38
+ # The movie kind
39
+ Movies=SpecialKind.new(1800630345,"Movies")
40
+ # The music kind
41
+ Music=SpecialKind.new(1800630362,"Music")
42
+ # The none kind
43
+ None=SpecialKind.new(1800302446,"None")
44
+ # The party shuffle kind
45
+ PartyShuffle=SpecialKind.new(1800630355,"Party Shuffle")
46
+ # The pod cast kind
47
+ Podcasts=SpecialKind.new(1800630352,"Podcasts")
48
+ # The purchased music kind
49
+ PurchasedMusic=SpecialKind.new(1800630349,"Purchased Music")
50
+ # The TV show kind
51
+ TVShows=SpecialKind.new(1800630356,"TV Shows")
52
+ # The video kind
53
+ Videos=SpecialKind.new(1800630358,"Videos")
54
+ # The genius kind
55
+ Genius=SpecialKind.new(1800630343,"Genius")
56
+ # The iTunesU kind
57
+ ITunesU=SpecialKind.new(1800630357,"iTunes U")
58
+ # The library kind
59
+ Library=SpecialKind.new(1800630348,"Library")
60
+ # The unknown kind
61
+ Unknown=SpecialKind.new(-1,"Unknown")
62
+
63
+ @@values=[Audiobooks,Folder,Movies,Music,
64
+ None,PartyShuffle,Podcasts,PurchasedMusic,
65
+ TVShows, Videos,Genius,ITunesU,Library,Unknown]
66
+
67
+ # A class scoped method used to get the kind associated with the kind ID
68
+ # @param kind The kind ID
69
+ # @return [ItunesController::SourceKind] The source kind object
70
+ def self.fromKind(kind)
71
+ @@values.each { | v1 |
72
+ if (v1.kind==kind)
73
+ return v1
74
+ end
75
+ }
76
+ return SpecialKind.new(v1,"Unknown")
77
+ end
78
+
79
+ # Used pretty print the kind to a string
80
+ # @return A string containing the kind display name and ID
81
+ def to_s
82
+ return "#{displayName} (#{kind})"
83
+ end
84
+ end
85
+
86
+ # Enum of source kinds
87
+ # @attr [Number] kind The Source kind ID
88
+ # @attr [String] String the source display name
89
+ class SourceKind
90
+
91
+ attr_accessor :kind, :displayName
92
+
93
+ # The constructor
94
+ # @param [Number] kind The kind ID
95
+ # @param [String] displayName The kind display name
96
+ def initialize(kind,displayName)
97
+ @kind = kind
98
+ @displayName = displayName
99
+ end
100
+
101
+ # The Audio CD Source Kind
102
+ AudioCD=SourceKind.new(1799439172,"Audio CD")
103
+ # The Device Source Kind
104
+ Device=SourceKind.new(1799644534,"Device")
105
+ # The iPod Source Kind
106
+ IPod=SourceKind.new(1800433508,"iPod")
107
+ # The Library Source Kind
108
+ Library=SourceKind.new(1800169826,"Library")
109
+ # The MP3 CD Source Kind
110
+ MP3CD=SourceKind.new(1800225604,"MP3 CD")
111
+ # The Radio Tuner Source Kind
112
+ RadioTuner=SourceKind.new(1800697198,"Radio Tuner")
113
+ # The Shared Libarary Source Kind
114
+ SharedLibrary=SourceKind.new(1800628324,"Shared Library")
115
+ # The Unknown Source Kind
116
+ Unknown=SourceKind.new(1800760938,"Unknown")
117
+
118
+ @@values=[AudioCD,Device,IPod,Library,MP3CD,RadioTuner,SharedLibrary,Unknown]
119
+
120
+ # A class scoped method used to get the kind associated with the kind ID
121
+ # @param kind The kind ID
122
+ # @return [ItunesController::SourceKind] The source kind object
123
+ def self.fromKind(kind)
124
+ @@values.each { | v1 |
125
+ if (v1.kind==kind)
126
+ return v1
127
+ end
128
+ }
129
+ return SourceKind.new(v1,"Unknown")
130
+ end
131
+
132
+ # Used pretty print the kind to a string
133
+ # @return A string containing the kind display name and ID
134
+ def to_s
135
+ return "#{displayName} (#{kind})"
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,119 @@
1
+ #
2
+ # Copyright (C) 2011-2012 John-Paul.Stanford <dev@stanwood.org.uk>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #
17
+ # Author:: John-Paul Stanford <dev@stanwood.org.uk>
18
+ # Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
19
+ # License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ module ItunesController
23
+
24
+ class ItunesControllerLogging
25
+ DEBUG=1
26
+ INFO=2
27
+ WARN=3
28
+ ERROR=4
29
+
30
+ # The log file, if defined then logging opertions will be sent to this file
31
+ @@logFile = nil
32
+ @@logLevel = INFO
33
+
34
+ # Used to set the location of the log file
35
+ # @param [String] file The log file location
36
+ def self.setLogFile(file)
37
+ @@logFile = file
38
+ end
39
+
40
+ # Use to set the loggin level
41
+ # @param [Number] level The logging level
42
+ def self.setLogLevel(level)
43
+ @@logLevel = level
44
+ end
45
+
46
+ def self.setLogLevelFromString(level)
47
+ if (level=="DEBUG")
48
+ @@logLevel = DEBUG
49
+ elsif (level=="INFO")
50
+ @@logLevel = INFO
51
+ elsif (level=="WARN")
52
+ @@logLevel = WARN
53
+ elsif (level=="ERROR")
54
+ @@logLevel = ERROR
55
+ else
56
+ error("Unkown log configuration '#{level}'")
57
+ exit(1)
58
+ end
59
+ end
60
+
61
+ # Used to print logging information at info level
62
+ # @param [String] msg The message to print
63
+ def self.info(msg)
64
+ if @@logLevel <= INFO
65
+ printMsg(msg)
66
+ end
67
+ end
68
+
69
+ # Used to print logging information at warn level
70
+ # @param [String] msg The message to print
71
+ def self.warn(msg)
72
+ if @@logLevel <= WARN
73
+ printMsg(msg)
74
+ end
75
+ end
76
+
77
+ # Used to print logging information at debug level
78
+ # @param [String] msg The message to print
79
+ def self.debug(msg)
80
+ if @@logLevel <= DEBUG
81
+ msg="DEBUG:"+msg
82
+ printMsg(msg)
83
+ end
84
+ end
85
+
86
+ # Used to print logging information at debug level
87
+ # @param [String] msg The message to print
88
+ # @param exception If not nil then this exception detials will be printed
89
+ def self.error(msg,exception=nil)
90
+ if @@logLevel <= ERROR
91
+ msg="ERROR:"+msg
92
+ printMsg(msg,true)
93
+ if (exception!=nil)
94
+ printMsg(" - #{exception.message}",true)
95
+ exception.backtrace.each do | line |
96
+ printMsg(" * #{line}",true)
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def self.printMsg(msg,error=false)
105
+ if (@@logFile!=nil)
106
+ out_file = File.open(@@logFile,"a") do | f |
107
+ f.puts(msg)
108
+ end
109
+ else
110
+ if (error)
111
+ $stderr.puts(msg)
112
+ else
113
+ $stdout.puts(msg)
114
+ end
115
+
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,204 @@
1
+ #
2
+ # Copyright (C) 2011-2012 John-Paul.Stanford <dev@stanwood.org.uk>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #
17
+ # Author:: John-Paul Stanford <dev@stanwood.org.uk>
18
+ # Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
19
+ # License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
20
+ #
21
+
22
+ # References:
23
+ # - http://code.google.com/p/itunes-rem-dupes/source/browse/trunk/itunes_update_library.rb?r=22
24
+ # - http://guides.macrumors.com/Deleting_Songs_From_iTunes
25
+ # - http://macscripter.net/viewtopic.php?id=22726
26
+
27
+ require 'itunesController/itunescontroller'
28
+ require 'itunesController/kinds'
29
+ require 'itunesController/debug'
30
+ require 'itunesController/logging'
31
+ require 'itunesController/track'
32
+ require 'rubygems'
33
+ require 'escape'
34
+ require 'open3'
35
+ require 'osx/cocoa'
36
+
37
+ include OSX
38
+ OSX.require_framework 'ScriptingBridge'
39
+
40
+ module ItunesController
41
+
42
+ # This is a iTunes controller class used to talk to itunes. This runs on macosx and makes
43
+ # use of the OSC ruby bindings. It also uses application "osascript" to execute apple scripts.
44
+ class MacOSXITunesController < ItunesController::BaseITunesController
45
+
46
+ # The constructor
47
+ def initialize()
48
+ @iTunes = SBApplication.applicationWithBundleIdentifier:'com.apple.iTunes'
49
+ library=getSourceLibrary()
50
+ @libraryPlaylists=library.libraryPlaylists
51
+ end
52
+
53
+ # Used to get the iTunes version
54
+ # @return [String] The itunes version
55
+ def version
56
+ return @iTunes.version.to_s+" (Mac OSX)"
57
+ end
58
+
59
+ # Used to tell iTunes to refresh a list of tracks data from the info stored in the files
60
+ # @param [Array] tracks A list of tracks to fresh
61
+ def refreshTracks(tracks)
62
+ ItunesController::ItunesControllerLogging::debug("refreshing tracks...")
63
+ tracks.reverse.each do | track |
64
+ track.refresh
65
+ end
66
+ end
67
+
68
+ # Used to remove tracks from the libaray
69
+ # @param [Array] tracks A list of tracks to remove from the itunes libaray
70
+ def removeTracksFromLibrary(tracks)
71
+ ItunesController::ItunesControllerLogging::debug("removing tracks...")
72
+ tracks.reverse.each do | track |
73
+ track.delete
74
+ end
75
+ end
76
+
77
+ # Used to add a list of files to the itunes library
78
+ # @param [Array[String]] A list of files to add to the itunes library
79
+ # @return [Array[ItunesController::Track]] List of ids of the new tracks once they are in the database
80
+ def addFilesToLibrary(files)
81
+ tracks=[]
82
+ files.each do | file |
83
+ script="tell application \"iTunes\"\n"
84
+ script=script+" set theTrack to (add POSIX file \"#{file}\")\n"
85
+ script=script+" return (database ID of theTrack & name of theTrack)\n"
86
+ script=script+"end tell\n"
87
+ output=executeScript(script)
88
+ if (output =~ /(\d+), (.*)/)
89
+ track=ItunesController::Track.new(file,$1.to_i,$2)
90
+ tracks.push(track)
91
+ else
92
+ ItunesController::ItunesControllerLogging::error("Unable to add file '#{file}': " + output)
93
+ end
94
+ end
95
+
96
+ return tracks;
97
+ end
98
+
99
+ # Used to get the database of a itunes track
100
+ # @param track the track
101
+ # @return The database id
102
+ def getTrackDatabaseId(track)
103
+ return track.databaseID
104
+ end
105
+
106
+ def getTracks(&b)
107
+ ItunesController::ItunesControllerLogging::debug("Retriving track information...")
108
+ playlist=@libraryPlaylists[0]
109
+ fileTracks = playlist.fileTracks
110
+ size = fileTracks.length()
111
+ count = 1
112
+ fileTracks.each do | track |
113
+ location=track.location
114
+ path=nil
115
+ dead=false
116
+ if (location!=nil && location.isFileURL)
117
+ path=location.path
118
+ if (!File.exist?(location.path))
119
+ dead = true
120
+ end
121
+ else
122
+ dead = true
123
+ end
124
+
125
+ if (count % 1000 == 0)
126
+ ItunesController::ItunesControllerLogging::debug("Found tracks #{count} of #{size}")
127
+ end
128
+ if (track.name!=nil)
129
+ b.call(ItunesController::Track.new(path,track.databaseID,track.name),count,size,dead)
130
+ end
131
+ count=count+1
132
+ end
133
+ ItunesController::ItunesControllerLogging::debug("Found tracks #{count-1} of #{size}")
134
+ return size
135
+ end
136
+
137
+ # Used to find the number of tracks in the library
138
+ # @return [Number] The number of tracks
139
+ def getTrackCount()
140
+ playlist=@libraryPlaylists[0]
141
+ return playlist.fileTracks.length()
142
+ end
143
+
144
+ # Used to search the itunes library
145
+ # @param term The search term
146
+ # @return [Array] a list of iTunes track that match the search term
147
+ def searchLibrary(term)
148
+ tracks=[]
149
+ @libraryPlaylists.each do | playlist |
150
+ #foundTracks = playlist.searchFor(term,'kSrS')
151
+ foundTracks = playlist.searchFor_only_(term,1799449708)
152
+ if (foundTracks!=nil)
153
+ foundTracks.each do | t |
154
+ tracks.push(t)
155
+ end
156
+ end
157
+ end
158
+ return tracks
159
+ end
160
+
161
+ private
162
+
163
+ # Used to get the libaray iTunes source
164
+ # @return The iTunes source for the library
165
+ def getSourceLibrary()
166
+ @iTunes.sources.each do |source|
167
+ if (source.kind == SourceKind::Library.kind)
168
+ return source
169
+ end
170
+ end
171
+ return nil
172
+ end
173
+
174
+ # Used to find playlists of a given media kind
175
+ # @param types The types
176
+ # @return [Array] A list of playlists
177
+ def findPlaylists(types)
178
+ playlists=[]
179
+ library=getSourceLibrary()
180
+ if (library==nil)
181
+ raise("Unable to find iTunes library")
182
+ end
183
+
184
+ library.userPlaylists.each do |pl|
185
+ kind=SpecialKind::fromKind(pl.specialKind)
186
+ types.each do |type|
187
+ if (kind.kind == type.kind)
188
+ playlists.push(pl)
189
+ end
190
+ end
191
+ end
192
+
193
+ return playlists
194
+ end
195
+
196
+ # Used to execute a apple script using the system "osascript" command.
197
+ # @private
198
+ # @param script the Script contents
199
+ def executeScript(script)
200
+ stdin, stdout, stderr = Open3.popen3(Escape.shell_command(["osascript","-e",script]))
201
+ return stdout.readlines.join('\n').strip
202
+ end
203
+ end
204
+ end