itch 1.0.3 → 1.0.4

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.
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