itunes-controller 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.buildpath +5 -0
- data/.gitignore +3 -0
- data/.project +17 -0
- data/.rvmrc +81 -0
- data/LICENSE +674 -0
- data/README +27 -0
- data/Rakefile +27 -0
- data/TODO +8 -0
- data/bin/addFiles.rb +35 -0
- data/bin/dummyiTunesController.rb +109 -0
- data/bin/itunesController.rb +78 -0
- data/bin/listDeadTracks.rb +45 -0
- data/bin/listNewTracks.rb +88 -0
- data/bin/recreateTrackCache.rb +31 -0
- data/bin/refreshFiles.rb +42 -0
- data/bin/removeDeadTracks.rb +31 -0
- data/bin/removeFiles.rb +42 -0
- data/bin/trackInfo.rb +50 -0
- data/itunes-controller.gemspec +24 -0
- data/jar-stuff.sh +24 -0
- data/lib/itunesController/application.rb +127 -0
- data/lib/itunesController/cachedcontroller.rb +188 -0
- data/lib/itunesController/config.rb +95 -0
- data/lib/itunesController/controller_creator.rb +29 -0
- data/lib/itunesController/controllserver.rb +583 -0
- data/lib/itunesController/database/backend.rb +41 -0
- data/lib/itunesController/database/database.rb +166 -0
- data/lib/itunesController/database/sqlite3_backend.rb +67 -0
- data/lib/itunesController/debug.rb +124 -0
- data/lib/itunesController/dummy_itunes_track.rb +40 -0
- data/lib/itunesController/dummy_itunescontroller.rb +142 -0
- data/lib/itunesController/itunescontroller.rb +90 -0
- data/lib/itunesController/itunescontroller_factory.rb +51 -0
- data/lib/itunesController/kinds.rb +138 -0
- data/lib/itunesController/logging.rb +119 -0
- data/lib/itunesController/macosx_itunescontroller.rb +204 -0
- data/lib/itunesController/platform.rb +53 -0
- data/lib/itunesController/sqlite_creator.rb +35 -0
- data/lib/itunesController/track.rb +39 -0
- data/lib/itunesController/version.rb +25 -0
- data/lib/itunesController/windows_itunescontroller.rb +145 -0
- data/test/base_server_test_case.rb +125 -0
- data/test/dummy_client.rb +44 -0
- data/test/test_server.rb +312 -0
- metadata +185 -0
data/README
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Information
|
2
|
+
-----------
|
3
|
+
|
4
|
+
This is a project to create make it possible to control enable iTunes to be operated
|
5
|
+
on a headless server without the GUI. It provides a TCP server which can be connected
|
6
|
+
to locally or remote by other applications to control iTunes.
|
7
|
+
|
8
|
+
The server only currently runs on Mac OSX It's written in such a way that if someone
|
9
|
+
knows how to script iTunes from ruby on windows, then windows support could be added.
|
10
|
+
|
11
|
+
Requirments
|
12
|
+
-----------
|
13
|
+
|
14
|
+
* iTunes (latest)
|
15
|
+
* MacOS X (tested on snow leopard)
|
16
|
+
* Mac Ruby
|
17
|
+
|
18
|
+
Installation
|
19
|
+
------------
|
20
|
+
|
21
|
+
Building
|
22
|
+
--------
|
23
|
+
|
24
|
+
If you need to rebuild gem and run all the tests, then just change to the project directory and type:
|
25
|
+
|
26
|
+
rake
|
27
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'yard'
|
4
|
+
|
5
|
+
task :default => :all
|
6
|
+
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs << 'test'
|
9
|
+
end
|
10
|
+
|
11
|
+
YARD::Rake::YardocTask.new do |t|
|
12
|
+
# t.files = ['lib/**/*.rb','bin/**/*.rb','LICENSE','README']
|
13
|
+
t.files = ['lib/**/*.rb','bin/**/*.rb']
|
14
|
+
end
|
15
|
+
|
16
|
+
task :gem do
|
17
|
+
sh "gem build itunes-controller.gemspec"
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Execute all the build tasks"
|
21
|
+
task :all do
|
22
|
+
Rake::Task['yard'].invoke
|
23
|
+
Rake::Task['test'].invoke
|
24
|
+
Rake::Task['gem'].invoke
|
25
|
+
end
|
26
|
+
|
27
|
+
|
data/TODO
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
Add support for windows iTunes
|
2
|
+
Speed up removing files
|
3
|
+
- Is their a way of finding the track associated with a file path, without search though the whole library
|
4
|
+
Replace apple script usage with ruby script bridge
|
5
|
+
Add server command to update files in the library with new details in the file
|
6
|
+
- Make sure it keeps the play counts intact
|
7
|
+
|
8
|
+
Add --version command line option
|
data/bin/addFiles.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
#
|
3
|
+
# A command line util used to add tracks to the iTunes library
|
4
|
+
#
|
5
|
+
# Author:: John-Paul Stanford <dev@stanwood.org.uk>
|
6
|
+
# Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
|
7
|
+
# License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'itunesController/cachedcontroller'
|
11
|
+
require 'itunesController/application'
|
12
|
+
require 'itunesController/sqlite_creator'
|
13
|
+
|
14
|
+
class App < ItunesController::Application
|
15
|
+
|
16
|
+
def displayUsage()
|
17
|
+
puts("Usage: "+@appName+" [options] files...")
|
18
|
+
puts("")
|
19
|
+
puts(genericOptionDescription())
|
20
|
+
end
|
21
|
+
|
22
|
+
def createController
|
23
|
+
return ItunesController::SQLLiteControllerCreator.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def execApp(controllerCreator)
|
27
|
+
controller = controllerCreator.createController()
|
28
|
+
ARGV.each do | path |
|
29
|
+
controller.addTrack(path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
app=App.new("addFiles.rb")
|
35
|
+
app.exec()
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 John-Paul.Stanford <dev@stanwood.org.uk>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
# Author:: John-Paul Stanford <dev@stanwood.org.uk>
|
19
|
+
# Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
|
20
|
+
# License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'tempfile'
|
24
|
+
|
25
|
+
require 'itunesController/controller_creator'
|
26
|
+
require 'itunesController/config'
|
27
|
+
require 'itunesController/controllserver'
|
28
|
+
require 'itunesController/dummy_itunescontroller'
|
29
|
+
require 'itunesController/debug'
|
30
|
+
require 'itunesController/logging'
|
31
|
+
require 'itunesController/cachedcontroller'
|
32
|
+
require 'itunesController/application'
|
33
|
+
require 'itunesController/database/sqlite3_backend'
|
34
|
+
|
35
|
+
class DummyControllerCreator < ItunesController::ControllerCreator
|
36
|
+
|
37
|
+
def initialize(controller)
|
38
|
+
@controller = controller
|
39
|
+
end
|
40
|
+
|
41
|
+
def createController()
|
42
|
+
return @controller
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class App < ItunesController::Application
|
47
|
+
|
48
|
+
DEFAULT_PORT=7000
|
49
|
+
|
50
|
+
def initialize(appName,dbPath)
|
51
|
+
super(appName)
|
52
|
+
@dbPath=dbPath
|
53
|
+
end
|
54
|
+
|
55
|
+
# Used to display the command line useage
|
56
|
+
def displayUsage()
|
57
|
+
puts("Usage: "+@appName+" [options]")
|
58
|
+
puts("")
|
59
|
+
puts(genericOptionDescription())
|
60
|
+
puts(" -p, --port PORT The port number to start the server on. Defaults to #{DEFAULT_PORT}")
|
61
|
+
puts(" -c, --config FILE The configuration file")
|
62
|
+
end
|
63
|
+
|
64
|
+
def checkAppOptions()
|
65
|
+
if (@options[:config]==nil)
|
66
|
+
usageError("No config file specified. Use --config option.")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def parseAppOptions(opts)
|
71
|
+
opts.on('-p','--port PORT','The port number to start the server on. Defaults to 7000') do |port|
|
72
|
+
@options[:port] = port;
|
73
|
+
end
|
74
|
+
opts.on('-c','--config FILE','The configuration file') do |value|
|
75
|
+
@options[:config] = value
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def createController()
|
80
|
+
ItunesController::DummyITunesController::resetCommandLog()
|
81
|
+
ItunesController::DummyITunesController::resetTracks()
|
82
|
+
itunes=ItunesController::DummyITunesController.new()
|
83
|
+
dbBackend = ItunesController::SQLite3DatabaseBackend.new(@dbPath)
|
84
|
+
return DummyControllerCreator.new(ItunesController::CachedController.new(itunes,dbBackend))
|
85
|
+
end
|
86
|
+
|
87
|
+
def execApp(controllerCreator)
|
88
|
+
port=DEFAULT_PORT
|
89
|
+
config=ItunesController::ServerConfig.readConfig(@options[:config])
|
90
|
+
if (config.port!=nil)
|
91
|
+
port = config.port
|
92
|
+
end
|
93
|
+
if (@options[:port]!=nil)
|
94
|
+
port = @options[:port]
|
95
|
+
end
|
96
|
+
server=ItunesController::ITunesControlServer.new(config,port,controllerCreator)
|
97
|
+
server.join
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
dbFile = Tempfile.new('dummyDatabase.db')
|
102
|
+
begin
|
103
|
+
ItunesController::ItunesControllerLogging::info("Started dummy itunes controller with db path #{dbFile.path}")
|
104
|
+
app=App.new("itunesController.rb",dbFile.path)
|
105
|
+
app.exec()
|
106
|
+
ensure
|
107
|
+
dbFile.unlink
|
108
|
+
end
|
109
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 John-Paul.Stanford <dev@stanwood.org.uk>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
# Author:: John-Paul Stanford <dev@stanwood.org.uk>
|
19
|
+
# Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
|
20
|
+
# License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'itunesController/config'
|
24
|
+
require 'itunesController/controllserver'
|
25
|
+
require 'itunesController/debug'
|
26
|
+
require 'itunesController/logging'
|
27
|
+
require 'itunesController/cachedcontroller'
|
28
|
+
require 'itunesController/application'
|
29
|
+
require 'itunesController/sqlite_creator'
|
30
|
+
|
31
|
+
class App < ItunesController::Application
|
32
|
+
|
33
|
+
DEFAULT_PORT=7000
|
34
|
+
|
35
|
+
# Used to display the command line useage
|
36
|
+
def displayUsage()
|
37
|
+
puts("Usage: "+@appName+" [options]")
|
38
|
+
puts("")
|
39
|
+
puts(genericOptionDescription())
|
40
|
+
puts(" -p, --port PORT The port number to start the server on. Defaults to #{DEFAULT_PORT}")
|
41
|
+
puts(" -c, --config FILE The configuration file")
|
42
|
+
end
|
43
|
+
|
44
|
+
def checkAppOptions()
|
45
|
+
if (@options[:config]==nil)
|
46
|
+
usageError("No config file specified. Use --config option.")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def parseAppOptions(opts)
|
51
|
+
opts.on('-p','--port PORT','The port number to start the server on. Defaults to 7000') do |port|
|
52
|
+
@options[:port] = port;
|
53
|
+
end
|
54
|
+
opts.on('-c','--config FILE','The configuration file') do |value|
|
55
|
+
@options[:config] = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def createController
|
60
|
+
return ItunesController::SQLLiteControllerCreator.new
|
61
|
+
end
|
62
|
+
|
63
|
+
def execApp(controllerCreator)
|
64
|
+
port=DEFAULT_PORT
|
65
|
+
config=ItunesController::ServerConfig.readConfig(@options[:config])
|
66
|
+
if (config.port!=nil)
|
67
|
+
port = config.port
|
68
|
+
end
|
69
|
+
if (@options[:port]!=nil)
|
70
|
+
port = @options[:port]
|
71
|
+
end
|
72
|
+
server=ItunesController::ITunesControlServer.new(config,port,controllerCreator)
|
73
|
+
server.join
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
app=App.new("itunesController.rb")
|
78
|
+
app.exec()
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
#
|
3
|
+
# A command line util used to list tracks in the iTunes library when their files can't be found.
|
4
|
+
#
|
5
|
+
# Author:: John-Paul Stanford <dev@stanwood.org.uk>
|
6
|
+
# Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
|
7
|
+
# License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'itunesController/cachedcontroller'
|
11
|
+
require 'itunesController/debug'
|
12
|
+
require 'itunesController/logging'
|
13
|
+
require 'itunesController/application'
|
14
|
+
require 'itunesController/sqlite_creator'
|
15
|
+
|
16
|
+
class App < ItunesController::Application
|
17
|
+
|
18
|
+
def createController
|
19
|
+
return ItunesController::SQLLiteControllerCreator.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def execApp(controllerCreator)
|
23
|
+
controller = controllerCreator.createController()
|
24
|
+
deadTracks=controller.findDeadTracks
|
25
|
+
count=0
|
26
|
+
deadTracks.each do | deadTrack |
|
27
|
+
result=[]
|
28
|
+
result.push("Name: "+deadTrack.title)
|
29
|
+
result.push("Database ID: "+deadTrack.databaseId.to_s)
|
30
|
+
if (deadTrack.location==nil)
|
31
|
+
result.push("Location: Unknown")
|
32
|
+
else
|
33
|
+
result.push("Location: "+deadTrack.location)
|
34
|
+
end
|
35
|
+
ItunesController::ItunesControllerLogging::info(result.join("\n"))
|
36
|
+
ItunesController::ItunesControllerLogging::info("")
|
37
|
+
count+=1
|
38
|
+
end
|
39
|
+
ItunesController::ItunesControllerLogging::info("Found #{count} dead tracks")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
app=App.new("listDeadTracks.rb")
|
44
|
+
app.exec()
|
45
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011-2012 John-Paul.Stanford <dev@stanwood.org.uk>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
# Author:: John-Paul Stanford <dev@stanwood.org.uk>
|
19
|
+
# Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
|
20
|
+
# License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'itunesController/application'
|
24
|
+
require 'itunesController/logging'
|
25
|
+
require 'itunesController/sqlite_creator'
|
26
|
+
|
27
|
+
require 'rubygems'
|
28
|
+
require 'fileutils'
|
29
|
+
|
30
|
+
class App < ItunesController::Application
|
31
|
+
|
32
|
+
MEDIA_TYPES = [".m4v","mp3",".mp4"]
|
33
|
+
|
34
|
+
# Used to display the command line useage
|
35
|
+
def displayUsage()
|
36
|
+
puts("Usage: "+@appName+" [options] directories...")
|
37
|
+
puts("")
|
38
|
+
puts(genericOptionDescription())
|
39
|
+
end
|
40
|
+
|
41
|
+
def checkAppOptions()
|
42
|
+
if ARGV.length == 0
|
43
|
+
usageError("No directories given.")
|
44
|
+
end
|
45
|
+
ARGV.each do | path |
|
46
|
+
errors = false
|
47
|
+
if (!File.exists?(path) || !File.directory?(path))
|
48
|
+
ItunesController::ItunesControllerLogging::error("#{path} is not a directory or cannot be found")
|
49
|
+
errors = true
|
50
|
+
end
|
51
|
+
if (errors)
|
52
|
+
exit(1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def processMediaFiles ( controller,dir )
|
58
|
+
(Dir.entries(dir)- %w[ . .. ]).each { |name|
|
59
|
+
file=dir+"/"+name
|
60
|
+
if (!File.directory?(file))
|
61
|
+
ext=File.extname(file)
|
62
|
+
name=File.basename(file)
|
63
|
+
if (MEDIA_TYPES.index(ext)!=nil)
|
64
|
+
if (!controller.trackInLibrary?(file))
|
65
|
+
ItunesController::ItunesControllerLogging::info("#{file}")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
else
|
69
|
+
processMediaFiles(controller,file)
|
70
|
+
end
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def createController
|
75
|
+
return ItunesController::SQLLiteControllerCreator.new
|
76
|
+
end
|
77
|
+
|
78
|
+
def execApp(controllerCreator)
|
79
|
+
controller = controllerCreator.createController()
|
80
|
+
ARGV.each do | path |
|
81
|
+
ItunesController::ItunesControllerLogging::info("Checking for new files in '#{path}'")
|
82
|
+
processMediaFiles(controller,path)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
app=App.new("listNewTracks.rb")
|
88
|
+
app.exec()
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
#
|
3
|
+
# A command line util used to remove tracks to the iTunes library
|
4
|
+
#
|
5
|
+
# Author:: John-Paul Stanford <dev@stanwood.org.uk>
|
6
|
+
# Copyright:: Copyright (C) 2011 John-Paul.Stanford <dev@stanwood.org.uk>
|
7
|
+
# License:: GNU General Public License v3 <http://www.gnu.org/licenses/>
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'itunesController/cachedcontroller'
|
11
|
+
require 'itunesController/sqlite_creator'
|
12
|
+
require 'itunesController/debug'
|
13
|
+
require 'itunesController/logging'
|
14
|
+
require 'itunesController/application'
|
15
|
+
|
16
|
+
class App < ItunesController::Application
|
17
|
+
|
18
|
+
def createController
|
19
|
+
return ItunesController::SQLLiteControllerCreator.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def execApp(controllerCreator)
|
23
|
+
controller = controllerCreator.createController()
|
24
|
+
if (!controller.getCachedTracksOnCreate())
|
25
|
+
controller.cacheTracks(true)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
app=App.new("regenerateTrackCache.rb")
|
31
|
+
app.exec()
|