itch 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/itch +29 -16
  2. data/lib/itch.rb +51 -19
  3. metadata +2 -2
data/bin/itch CHANGED
@@ -7,20 +7,33 @@ rescue LoadError
7
7
  require 'itch'
8
8
  end
9
9
 
10
- #Create an iTunes controller.
11
- helper = Itch.new(Itch.create_itunes_interface)
10
+ begin
11
+
12
+ #Create an iTunes controller.
13
+ helper = Itch.new(Itch.create_itunes_interface)
14
+
15
+ #Get program options.
16
+ config = helper.parse_options(ARGV)
17
+ #Set default options.
18
+ config = helper.set_default_options(config)
19
+ #Get playlists that tracks will be selected from.
20
+ playlists = helper.get_playlists(config)
21
+ #Delete requested playlists.
22
+ helper.delete_playlists(config)
23
+ #Get tracks for processing.
24
+ tracks = helper.get_tracks(config, playlists)
25
+ #Process general commands.
26
+ helper.perform_general_operations(config)
27
+ #Process commands for specified tracks.
28
+ helper.perform_track_operations(config, tracks)
12
29
 
13
- #Get program options.
14
- config = helper.parse_options(ARGV)
15
- #Set default options.
16
- config = helper.set_default_options(config)
17
- #Get playlists that tracks will be selected from.
18
- playlists = helper.get_playlists(config)
19
- #Delete requested playlists.
20
- helper.delete_playlists(config)
21
- #Get tracks for processing.
22
- tracks = helper.get_tracks(config, playlists)
23
- #Process general commands.
24
- helper.perform_general_operations(config)
25
- #Process commands for specified tracks.
26
- helper.perform_track_operations(config, tracks)
30
+ rescue => exception
31
+
32
+ #If debug mode requested, print backtrace to STDERR.
33
+ if config and config.has_key?('debug')
34
+ $stderr.puts exception.backtrace
35
+ end
36
+ #Print error to STDERR and exit with an abnormal status.
37
+ abort "Error: " + exception.message
38
+
39
+ end
data/lib/itch.rb CHANGED
@@ -21,7 +21,11 @@ class Itch
21
21
 
22
22
  #Create an OLE/COM link to iTunes.
23
23
  def Itch.create_itunes_interface
24
- WIN32OLE.new('iTunes.Application') or raise "Couldn't take control of iTunes."
24
+ begin
25
+ WIN32OLE.new('iTunes.Application') or raise "Couldn't take control of iTunes."
26
+ rescue WIN32OLERuntimeError => exception
27
+ raise exception.exception("Couldn't take control of iTunes. Could a prior instance be shutting down?")
28
+ end
25
29
  end
26
30
 
27
31
 
@@ -31,13 +35,30 @@ class Itch
31
35
  #Config will hold parsed option values.
32
36
  config = Hash.new
33
37
 
34
- #Define valid options with descriptions.
38
+ #Set up option parser.
35
39
  options = OptionParser.new
40
+ #Modify option parser to wrap descriptions.
41
+ class <<options
42
+ alias old_on on
43
+ def on (*opts, &block)
44
+ opts.map! do |option|
45
+ if option.class == String and option.length > 40
46
+ option = option.scan(/\S.{0,40}\S(?=\s|$)|\S+/)
47
+ end
48
+ option
49
+ end
50
+ old_on(*opts.flatten, &block)
51
+ end
52
+ end
53
+
54
+ #Set up valid options.
55
+
36
56
  options.separator("Program help:")
37
57
  options.on("-h", "--help", TrueClass, "Display program help.") {
38
58
  puts options.help
39
59
  exit
40
60
  }
61
+
41
62
  options.separator("Playback controls:")
42
63
  options.on("-p", "--play-pause", TrueClass, "If currently paused, begin playing. If currently playing, pause playback.") {|value| config['play-pause'] = value}
43
64
  options.on("--pause", TrueClass, "Pause playback.") {|value| config['pause'] = value}
@@ -54,6 +75,7 @@ class Itch
54
75
  options.on("--scan-backwards [seconds]", Integer, "Scan backwards X seconds within the current track (default 10).") {|value| config['scan-backwards'] = value || 10}
55
76
  options.on("--scan-forwards [seconds]", Integer, "Scan forwards X seconds within the current track (default 10).") {|value| config['scan-forwards'] = value || 10}
56
77
  options.on("--play-file name", Object, "Play the specified file or folder.") {|value| config['play-file'] = value}
78
+
57
79
  options.separator("Info on selected tracks:")
58
80
  options.on("-i", "--print-info format", Object, "For each track, print information in the given format. If the following strings appear in the given format, they will be replaced with the corresponding track information:",
59
81
  %q#"%a": artist#,
@@ -79,12 +101,14 @@ class Itch
79
101
  %q#"%y": year#,
80
102
  %q#"%%": percent sign#
81
103
  ) {|value| config['print-info'] = value}
104
+
82
105
  options.separator("General iTunes controls:")
83
106
  options.on("-a", "--add-file name", Object, "Add the specified file or folder to the library.") {|value| (config['add-file'] ||= []) << value}
84
107
  options.on("-q", "--quit", TrueClass, "Exit iTunes.") {|value| config['quit'] = value}
85
108
  options.on("--open-url url", Object, "Open the given URL.") {|value| config['open-url'] = value}
86
109
  options.on("--goto-store-home-page", TrueClass, "Go to the Store.") {|value| config['goto-store-home-page'] = value}
87
110
  options.on("--update-ipod", TrueClass, "Update the iPod.") {|value| config['update-ipod'] = value}
111
+
88
112
  options.separator("Playlist selection:")
89
113
  options.on("--library", TrueClass, "Operation will include the entire iTunes library. Used by default unless other libraries are selected.") {|value| config['library'] = value}
90
114
  options.on("--current-playlist", TrueClass, "Operation will include the current playlist.") {|value| config['current-playlist'] = value}
@@ -92,6 +116,7 @@ class Itch
92
116
  options.on("--all-playlists", TrueClass, "Operation will include all playlists.") {|value| config['all-playlists'] = value}
93
117
  options.on("--create-playlist name", Object, "Create a playlist with the specified name and include it in the operation. (This option can occur more than once.)") {|value| (config['create-playlist'] ||= []) << value}
94
118
  options.on("--delete-playlist name", Object, "Delete the playlist with the specified name. (This option can occur more than once.)") {|value| (config['delete-playlist'] ||= []) << value}
119
+
95
120
  options.separator("Track selection:")
96
121
  options.on("-f", "--find string", Object, "Operation will include all tracks in the specified playlist(s) where any field matches the specified string. (This option can occur more than once.)") {|value| (config['find'] ||= []) << value}
97
122
  options.on("-c", "--current-track", TrueClass, "Operation will inclue the current track.") {|value| config['current-track'] = value}
@@ -103,6 +128,7 @@ class Itch
103
128
  options.on("--find-composer string", Object, "Operation will include all tracks in the specified playlist(s) where the composer matches the specified string. (This option can occur more than once.)") {|value| (config['find-composer'] ||= []) << value}
104
129
  options.on("--find-track-name string", Object, "Operation will include all tracks in the specified playlist(s) where the track name matches the specified string. (This option can occur more than once.)") {|value| (config['find-track-name'] ||= []) << value}
105
130
  options.on("-F", "--play-found", TrueClass, "Play the first of the selected tracks.") {|value| config['play-found'] = value}
131
+
106
132
  options.separator("Set track info:")
107
133
  options.on("--set-artist name", Object, "Set the artist for each track.") {|value| config['set-artist'] = value}
108
134
  options.on("--set-album name", Object, "Set the album for each track.") {|value| config['set-album'] = value}
@@ -125,6 +151,9 @@ class Itch
125
151
  options.on("--set-track-volume percent", Integer, "Set the volume adjustment percentage for each track, from -100 to 100. Negative numbers decrease the volume, positive numbers increase it. 0 means no adjustment.") {|value| config['set-track-volume'] = value}
126
152
  options.on("--set-year number", Integer, "Set the year of publication for each track.") {|value| config['set-year'] = value}
127
153
 
154
+ options.separator("Troubleshooting:")
155
+ options.on("--debug", TrueClass, "When an error occurs, show a more detailed message.") {|value| config['debug'] = value}
156
+
128
157
  #Parse the options, printing usage if parsing fails.
129
158
  options.parse(arguments) rescue puts "#{$!}\nType '#{$0} --help' for valid options."
130
159
 
@@ -152,24 +181,24 @@ class Itch
152
181
  def get_playlists (config)
153
182
 
154
183
  playlists = Array.new
155
- playlists.push(@interface.LibraryPlaylist) if config['library']
184
+ playlists << @interface.LibraryPlaylist if config['library']
156
185
  if config['current-playlist']
157
- playlists.push(@interface.CurrentPlaylist) or raise "Can't find current playlist."
186
+ playlists << @interface.CurrentPlaylist or raise "Can't find current playlist."
158
187
  end
159
188
  if config['all-playlists']
160
189
  if library_playlists = @interface.LibrarySource.Playlists
161
- library_playlists.each {|playlist| playlists.push(playlist)}
190
+ library_playlists.each {|playlist| playlists << playlist}
162
191
  else
163
192
  raise "No playlists found."
164
193
  end
165
194
  end
166
195
  with_option_values('playlist', config) do |name|
167
- playlists.push(find_playlist(name)) or raise "Can't find playlist #{name}"
196
+ playlists << find_playlist(name) or raise "Can't find playlist #{name}"
168
197
  end
169
198
 
170
199
  #If creation of playlist(s) requested, create them and add to the collection.
171
200
  with_option_values('create-playlist', config) do |name|
172
- playlists.push(@interface.CreatePlaylist(name)) or raise "Can't create playlist #{name}"
201
+ playlists << @interface.CreatePlaylist(name) or raise "Can't create playlist #{name}"
173
202
  end
174
203
 
175
204
  playlists
@@ -188,34 +217,37 @@ class Itch
188
217
  #Find requested tracks.
189
218
  def get_tracks (config, playlists)
190
219
 
191
- tracks = Array.new
192
-
220
+ tracks = []
221
+
193
222
  #Add current track to list if desired.
194
223
  if config['current-track']
195
- tracks.push(@interface.CurrentTrack) or raise "Can't find current track."
224
+ current_track = @interface.CurrentTrack or raise "No currently active/playing track." #"x << y.CurrentTrack or raise" won't work; nil is false but [nil] is true.
225
+ tracks << current_track
196
226
  end
197
-
227
+
198
228
  #Add highlighted tracks to list if desired.
199
229
  if config['selected-tracks']
200
230
  if selected_tracks = @interface.SelectedTracks
201
- selected_tracks.each {|track| tracks.push(track)}
231
+ selected_tracks.each {|track| tracks << track}
202
232
  else
203
233
  raise "No tracks selected."
204
234
  end
205
235
  end
206
236
 
207
237
  #Find tracks in selected playlists.
208
- for playlist in playlists
238
+ playlists.each do |playlist|
209
239
 
210
240
  #If all tracks are to be processed, select them all.
211
241
  if config['all-tracks']
212
- playlist.Tracks.each {|track| tracks.push(track)}
242
+ playlist.Tracks.each {|track| tracks << track}
213
243
  #Otherwise, see if user wishes to search for tracks.
214
244
  else
215
245
  search_playlist = lambda {|option, field_id|
216
246
  with_option_values(option, config) do |terms|
217
247
  if (results = playlist.Search(terms, field_id))
218
- results.each {|track| tracks.push(track)}
248
+ results.each {|track| tracks << track}
249
+ else
250
+ raise "No tracks found."
219
251
  end
220
252
  end
221
253
  }
@@ -229,7 +261,7 @@ class Itch
229
261
 
230
262
  #Import files to library and add resulting tracks to list.
231
263
  with_option_values('add-file', config) do |path|
232
- tracks.concat(add_file(path, playlist))
264
+ tracks.concat(add_file(File.expand_path(path), playlist))
233
265
  end
234
266
 
235
267
  end
@@ -269,7 +301,7 @@ class Itch
269
301
  def perform_track_operations (config, tracks)
270
302
 
271
303
  #Operate on selected tracks.
272
- for track in tracks
304
+ tracks.each do |track|
273
305
  specified?(config, 'set-artist') {|v| track.Artist = v}
274
306
  specified?(config, 'set-album') {|v| track.Album = v}
275
307
  specified?(config, 'set-bpm') {|v| track.BPM = v}
@@ -328,7 +360,7 @@ class Itch
328
360
  segment.gsub!(/%s/) {track.SkippedCount.to_s}
329
361
  segment.gsub!(/%t/) {track.TrackNumber.to_s}
330
362
  segment.gsub!(/%T/) {track.TrackCount.to_s}
331
- segment.gsub!(/%v/) {track.VolumeAdjustment.to_s}
363
+ segment.gsub!(/%v/) {volume = track.VolumeAdjustment; (1 .. 98).include?(volume) ? volume.next.to_s : volume.to_s}
332
364
  segment.gsub!(/%y/) {track.Year.to_s}
333
365
  segment
334
366
  end
@@ -363,7 +395,7 @@ class Itch
363
395
  sleep 1 while status.InProgress
364
396
  #Return added track(s).
365
397
  tracks = Array.new
366
- status.Tracks.each {|track| tracks.push(track)}
398
+ status.Tracks.each {|track| tracks << track}
367
399
  tracks
368
400
  end
369
401
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: itch
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.3
7
- date: 2007-05-07 00:00:00 -07:00
6
+ version: 1.0.4
7
+ date: 2007-05-08 00:00:00 -07:00
8
8
  summary: Allows control of iTunes for Windows via a command line.
9
9
  require_paths:
10
10
  - lib