jimmy_jukebox 0.6.0 → 0.6.1
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.
- data/bin/play_jukebox +1 -26
- data/lib/jimmy_jukebox/artists.rb +5 -0
- data/lib/jimmy_jukebox/check_gems.rb +25 -0
- data/lib/jimmy_jukebox/check_io_console.rb +6 -0
- data/lib/jimmy_jukebox/check_jruby.rb +9 -0
- data/lib/jimmy_jukebox/display_options.rb +1 -1
- data/lib/jimmy_jukebox/handle_load_jukebox_input.rb +67 -7
- data/lib/jimmy_jukebox/jukebox.rb +19 -8
- data/lib/jimmy_jukebox/load_jukebox_code.rb +6 -0
- data/lib/jimmy_jukebox/song.rb +13 -11
- data/lib/jimmy_jukebox/song_loader.rb +7 -7
- data/lib/jimmy_jukebox/user_config.rb +18 -6
- data/lib/jimmy_jukebox/user_input_handler.rb +68 -0
- data/lib/jimmy_jukebox/user_interface.rb +5 -56
- data/lib/jimmy_jukebox/version.rb +2 -2
- data/spec/jimmy_jukebox_spec.rb +6 -6
- data/spec/song_loader_spec.rb +7 -7
- data/spec/song_spec.rb +94 -35
- data/spec/user_config_spec.rb +56 -28
- metadata +86 -71
data/bin/play_jukebox
CHANGED
@@ -1,33 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
$running_jruby = defined?(JRUBY_VERSION) || (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby') || RUBY_PLATFORM == 'java'
|
4
|
-
|
5
|
-
if $running_jruby
|
6
|
-
begin
|
7
|
-
require 'spoon'
|
8
|
-
rescue LoadError => e
|
9
|
-
if e.message =~ /spoon/
|
10
|
-
puts "*** You must run 'gem install spoon' before using JimmyJukebox on JRuby ***"
|
11
|
-
exit
|
12
|
-
else
|
13
|
-
raise
|
14
|
-
end
|
15
|
-
end
|
16
|
-
else
|
17
|
-
begin
|
18
|
-
require 'posix/spawn'
|
19
|
-
rescue LoadError => e
|
20
|
-
if e.message =~ /posix/ || e.message =~ /spawn/
|
21
|
-
puts "*** You must run 'gem install posix-spawn' before using JimmyJukebox in Ruby ***"
|
22
|
-
exit
|
23
|
-
else
|
24
|
-
raise
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
3
|
lib = File.expand_path('../lib', File.dirname(__FILE__))
|
30
4
|
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
require 'jimmy_jukebox/check_gems'
|
31
6
|
require 'jimmy_jukebox'
|
32
7
|
include JimmyJukebox
|
33
8
|
|
@@ -85,4 +85,9 @@ module Artists
|
|
85
85
|
name.to_s.split("_").map! { |name_component| name_component.capitalize }.join("") + '.yml'
|
86
86
|
end
|
87
87
|
|
88
|
+
def prettified_artist_name(name)
|
89
|
+
return name.to_s.capitalize unless name.to_s.match(/_/)
|
90
|
+
name.to_s.split("_").map! { |name_component| name_component.capitalize }.join(" ")
|
91
|
+
end
|
92
|
+
|
88
93
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$running_jruby = defined?(JRUBY_VERSION) || (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby') || RUBY_PLATFORM == 'java'
|
2
|
+
|
3
|
+
if $running_jruby
|
4
|
+
begin
|
5
|
+
require 'spoon'
|
6
|
+
rescue LoadError => e
|
7
|
+
if e.message =~ /spoon/
|
8
|
+
puts "*** You must run 'gem install spoon' before using JimmyJukebox on JRuby ***"
|
9
|
+
exit
|
10
|
+
else
|
11
|
+
raise
|
12
|
+
end
|
13
|
+
end
|
14
|
+
else
|
15
|
+
begin
|
16
|
+
require 'posix/spawn'
|
17
|
+
rescue LoadError => e
|
18
|
+
if e.message =~ /posix/ || e.message =~ /spawn/
|
19
|
+
puts "*** You must run 'gem install posix-spawn' before using JimmyJukebox in Ruby ***"
|
20
|
+
exit
|
21
|
+
else
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
begin
|
2
|
+
require 'io/console'
|
3
|
+
rescue LoadError
|
4
|
+
puts "*** JimmyJukebox uses io/console, which is built into Ruby 1.9.3. I recommend running JimmyJukebox on 1.9.3. You could instead install the 'io-console' gem, but the most recent version works only with 1.9.3, so try \"gem install io-console -v '0.3'\" ***"
|
5
|
+
exit
|
6
|
+
end
|
@@ -1,19 +1,49 @@
|
|
1
|
+
require 'jimmy_jukebox/artists'
|
2
|
+
|
1
3
|
module JimmyJukebox
|
2
4
|
|
3
5
|
module HandleLoadJukeboxInput
|
4
6
|
|
5
7
|
def no_argv0
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
display_template {
|
9
|
+
puts " You must select an artist or genre to use 'load_jukebox'.\n\n"
|
10
|
+
puts " Examples:\n\n"
|
11
|
+
puts " load_jukebox at (to download Art Tatum)\n\n"
|
12
|
+
puts " load_jukebox dr (to download Django Reinhardt)\n\n"
|
13
|
+
puts " load_jukebox bluegrass (to download bluegrass)\n\n"
|
14
|
+
puts " load_jukebox classical (to download classical)\n\n"
|
15
|
+
puts " load_jukebox jazz (to download jazz)\n\n"
|
16
|
+
}
|
9
17
|
exit
|
10
18
|
end
|
11
19
|
|
20
|
+
def list_artists
|
21
|
+
display_template {
|
22
|
+
puts " Artist symbol = Artist name (Genre)\n\n"
|
23
|
+
ARTISTS.each do |k,v|
|
24
|
+
puts " " + k.to_s.rjust(5) + ' = ' + prettified_artist_name(v[:name]) + ' (' + v[:genre].capitalize + ')'
|
25
|
+
end
|
26
|
+
puts "\n"
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
12
30
|
def invalid_artist
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
31
|
+
display_template {
|
32
|
+
puts " No action taken in response to your command 'load_jukebox #{ARGV[0]}'.\n\n"
|
33
|
+
puts " JimmyJukebox does not recognize '#{ARGV[0]}'.\n\n"
|
34
|
+
puts " You must select a valid artist or genre.\n\n"
|
35
|
+
puts " Valid genres:\n\n"
|
36
|
+
puts " 'bluegrass'"
|
37
|
+
puts " 'banjo'"
|
38
|
+
puts " 'classical'"
|
39
|
+
puts " 'jazz'"
|
40
|
+
puts " 'rock'\n\n"
|
41
|
+
puts " Valid artists include:\n\n"
|
42
|
+
puts " 'bh' for Billie Holiday"
|
43
|
+
puts " 'cb' for Count Basie"
|
44
|
+
puts " 'lh' for Lionel Hampton.\n\n"
|
45
|
+
puts " Please visit the link below for a complete list of valid artists.\n\n"
|
46
|
+
}
|
17
47
|
exit
|
18
48
|
end
|
19
49
|
|
@@ -35,6 +65,11 @@ module JimmyJukebox
|
|
35
65
|
arg && arg.to_i.is_a?(Integer) && arg.to_i > 0
|
36
66
|
end
|
37
67
|
|
68
|
+
def play_radio
|
69
|
+
require 'jimmy_jukebox/check_gems'
|
70
|
+
require 'jimmy_jukebox/user_interface'
|
71
|
+
end
|
72
|
+
|
38
73
|
def process_artist
|
39
74
|
if valid_integer?(ARGV[1])
|
40
75
|
JimmyJukebox::SongLoader.new.send(artist_name(ARGV[0]), ARGV[1].to_i)
|
@@ -43,6 +78,31 @@ module JimmyJukebox
|
|
43
78
|
end
|
44
79
|
end
|
45
80
|
|
81
|
+
def process_genre
|
82
|
+
if valid_integer?(ARGV[1])
|
83
|
+
JimmyJukebox::SongLoader.new.download_sample_genre(ARGV[1].to_i, ARGV[0].upcase)
|
84
|
+
else
|
85
|
+
display_genre_download_requires_n_message
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def display_template(&msg)
|
90
|
+
puts " ------------------------------------------------------------------------"
|
91
|
+
puts " JimmyJukebox usage help\n\n"
|
92
|
+
msg.call if msg
|
93
|
+
puts " Full instructions: https://github.com/JamesLavin/jimmy_jukebox"
|
94
|
+
puts " ------------------------------------------------------------------------"
|
95
|
+
end
|
96
|
+
|
97
|
+
def display_genre_download_requires_n_message
|
98
|
+
display_template {
|
99
|
+
puts " You requested a sample of #{ARGV[0]} songs without specifying how many.\n\n"
|
100
|
+
puts " Please try again but specify how many songs you wish to download.\n\n"
|
101
|
+
puts " For example, to download 10 #{ARGV[0]} songs, type:\n\n"
|
102
|
+
puts " load_jukebox #{ARGV[0]} 10"
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
46
106
|
def process_sample
|
47
107
|
if ARGV[1].nil?
|
48
108
|
JimmyJukebox::SongLoader.new.download_sample_genre(1)
|
@@ -36,7 +36,7 @@ module JimmyJukebox
|
|
36
36
|
disable_monitor_powerdown if JimmyJukebox::RUNNING_X_WINDOWS
|
37
37
|
self.user_config = new_user_config
|
38
38
|
self.continuous_play = continuous_play
|
39
|
-
raise NoSongsException if
|
39
|
+
raise NoSongsException if downloaded_song_paths.empty?
|
40
40
|
end
|
41
41
|
|
42
42
|
def play_loop
|
@@ -49,10 +49,13 @@ module JimmyJukebox
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
def next_song?
|
53
|
+
@next_song
|
54
|
+
end
|
55
|
+
|
52
56
|
def next_song
|
53
57
|
# reset @next_song each time it's accessed
|
54
|
-
current_next_song
|
55
|
-
@next_song = random_song
|
58
|
+
current_next_song, @next_song = [@next_song || random_song, random_song]
|
56
59
|
current_next_song
|
57
60
|
end
|
58
61
|
|
@@ -62,7 +65,7 @@ module JimmyJukebox
|
|
62
65
|
|
63
66
|
def quit
|
64
67
|
disable_continuous_play
|
65
|
-
terminate_current_song
|
68
|
+
terminate_current_song if current_song
|
66
69
|
end
|
67
70
|
|
68
71
|
def playing?
|
@@ -126,15 +129,23 @@ module JimmyJukebox
|
|
126
129
|
current_song.unpause
|
127
130
|
end
|
128
131
|
|
129
|
-
def
|
130
|
-
user_config.
|
132
|
+
def downloaded_song_paths
|
133
|
+
user_config.song_paths
|
131
134
|
end
|
132
135
|
|
136
|
+
#def undownloaded_songs
|
137
|
+
# user_config.undownloaded_songs
|
138
|
+
#end
|
139
|
+
|
133
140
|
def random_song
|
134
|
-
raise NoNewSongException, "JimmyJukebox can't find any songs to play!" if
|
135
|
-
Song.new(
|
141
|
+
raise NoNewSongException, "JimmyJukebox can't find any songs to play!" if downloaded_song_paths.length == 0
|
142
|
+
Song.new( downloaded_song_paths[rand(downloaded_song_paths.length)] )
|
136
143
|
end
|
137
144
|
|
145
|
+
#def play_random_undownloaded_song
|
146
|
+
# play_song(random_undownloaded_song)
|
147
|
+
#end
|
148
|
+
|
138
149
|
def play_random_song
|
139
150
|
play_song(random_song)
|
140
151
|
end
|
@@ -12,6 +12,12 @@ no_argv0 unless ARGV[0]
|
|
12
12
|
|
13
13
|
if ARGV[0] =~ /sample/i
|
14
14
|
process_sample
|
15
|
+
elsif ARGV[0] =~ /artists/i
|
16
|
+
list_artists
|
17
|
+
elsif ARGV[0] =~ /radio/i
|
18
|
+
play_radio
|
19
|
+
elsif valid_genre?(ARGV[0])
|
20
|
+
process_genre
|
15
21
|
elsif valid_artist?(ARGV[0])
|
16
22
|
process_artist
|
17
23
|
else
|
data/lib/jimmy_jukebox/song.rb
CHANGED
@@ -55,10 +55,12 @@ module JimmyJukebox
|
|
55
55
|
|
56
56
|
def pause
|
57
57
|
self.paused = true
|
58
|
-
if
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
if playing_pid
|
59
|
+
if grandchild_pid
|
60
|
+
`kill -s STOP #{grandchild_pid}`
|
61
|
+
else
|
62
|
+
`kill -s STOP #{playing_pid}`
|
63
|
+
end
|
62
64
|
else
|
63
65
|
raise NoPlayingPidException, "*** Can't pause song because can't find playing_pid #{playing_pid} ***"
|
64
66
|
end
|
@@ -66,21 +68,21 @@ module JimmyJukebox
|
|
66
68
|
|
67
69
|
def unpause
|
68
70
|
self.paused = false
|
69
|
-
if
|
70
|
-
|
71
|
-
|
71
|
+
if playing_pid
|
72
|
+
if grandchild_pid
|
73
|
+
`kill -s CONT #{grandchild_pid}`
|
74
|
+
else playing_pid
|
72
75
|
`kill -s CONT #{playing_pid}`
|
76
|
+
end
|
73
77
|
else
|
74
78
|
raise NoPlayingPidException, "*** Can't unpause song because can't find playing_pid #{playing_pid} ***"
|
75
79
|
end
|
76
80
|
end
|
77
81
|
|
78
82
|
def kill_playing_pid_and_children
|
83
|
+
return nil unless playpid = playing_pid
|
79
84
|
grandpid = grandchild_pid
|
80
|
-
|
81
|
-
if grandpid
|
82
|
-
`kill #{grandpid}`
|
83
|
-
end
|
85
|
+
`kill #{grandpid}` if grandpid
|
84
86
|
`kill #{playpid}`
|
85
87
|
end
|
86
88
|
|
@@ -41,8 +41,8 @@ module JimmyJukebox
|
|
41
41
|
|
42
42
|
attr_reader :user_config
|
43
43
|
|
44
|
-
def initialize
|
45
|
-
@user_config = UserConfig.new
|
44
|
+
def initialize(user_config = nil)
|
45
|
+
@user_config = user_config || UserConfig.new
|
46
46
|
ARTISTS.values.each { |artist| define_artist artist[:name].to_sym }
|
47
47
|
end
|
48
48
|
|
@@ -56,24 +56,24 @@ module JimmyJukebox
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
def
|
60
|
-
|
59
|
+
def all_downloadable_songs(genre = nil) # valid genres: 'JAZZ', 'CLASSICAL', 'BLUEGRASS', 'BANJO', 'ROCK'
|
60
|
+
result = {}
|
61
61
|
ARTISTS.values.each do |artist|
|
62
62
|
next if genre && artist[:genre] != genre
|
63
63
|
fn = File.dirname(__FILE__) + "/songs/#{artist_name_to_yaml_file(artist[:name].to_s)}"
|
64
64
|
if File.exists?(fn)
|
65
65
|
YAML::load_file(fn).each do |song|
|
66
|
-
|
66
|
+
result[song] = artist
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
70
|
+
result
|
71
71
|
end
|
72
72
|
|
73
73
|
def sample_genre(num_songs, genre = nil)
|
74
74
|
# loop through array and download num_songs new songs (or until end of array reached)
|
75
75
|
sample = {}
|
76
|
-
available_songs =
|
76
|
+
available_songs = all_downloadable_songs(genre)
|
77
77
|
num_songs.times do
|
78
78
|
unless available_songs.length == 0
|
79
79
|
k, v = available_songs.rand_pair!
|
@@ -2,8 +2,10 @@ require 'fileutils'
|
|
2
2
|
require 'forwardable'
|
3
3
|
require 'rbconfig'
|
4
4
|
|
5
|
+
require 'jimmy_jukebox/constants'
|
5
6
|
require 'jimmy_jukebox/artists'
|
6
7
|
require 'jimmy_jukebox/song'
|
8
|
+
require 'jimmy_jukebox/song_loader'
|
7
9
|
require 'jimmy_jukebox/music_player_detector'
|
8
10
|
include Artists
|
9
11
|
|
@@ -29,7 +31,7 @@ module JimmyJukebox
|
|
29
31
|
extend Forwardable
|
30
32
|
|
31
33
|
attr_writer :music_directories
|
32
|
-
attr_accessor :
|
34
|
+
attr_accessor :song_paths, :music_player_detector, :argv0
|
33
35
|
def_delegators :@music_player_detector, :ogg_player, :mp3_player, :wav_player, :flac_player
|
34
36
|
|
35
37
|
DEFAULT_PLAYLIST_DIR = File.expand_path(File.join("~",".jimmy_jukebox"))
|
@@ -42,7 +44,7 @@ module JimmyJukebox
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def initialize
|
45
|
-
self.
|
47
|
+
self.song_paths = []
|
46
48
|
self.argv0 = ARGV[0]
|
47
49
|
set_music_players
|
48
50
|
generate_directories_list
|
@@ -195,11 +197,21 @@ module JimmyJukebox
|
|
195
197
|
end
|
196
198
|
files.delete_if { |f| AUDIO_FORMATS.keys.all? { |re| !f.match(re) } }
|
197
199
|
files.map! { |f| File.expand_path(music_dir) + '/' + f }
|
198
|
-
files.each { |f|
|
200
|
+
files.each { |f| song_paths << f }
|
199
201
|
end
|
200
|
-
puts "WARNING: JimmyJukebox could not find any songs" unless
|
201
|
-
#
|
202
|
-
#
|
202
|
+
puts "WARNING: JimmyJukebox could not find any songs" unless song_paths.length > 0
|
203
|
+
#song_paths = ["/home/xxx/Music/Artie_Shaw/Georgia On My Mind 1941.mp3",
|
204
|
+
# "/home/xxx/Music/Jelly_Roll_Morton/High Society 1939.mp3"]
|
205
|
+
end
|
206
|
+
|
207
|
+
def undownloaded_songs
|
208
|
+
result = {}
|
209
|
+
JimmyJukebox::SongLoader.new(self).all_downloadable_songs.each do |url, artist|
|
210
|
+
save_path = root_music_dir + artist_name_to_subdir_name(artist[:name]) + '/' + File.basename(url)
|
211
|
+
next if song_paths.include?(save_path)
|
212
|
+
result[url] = artist
|
213
|
+
end
|
214
|
+
result
|
203
215
|
end
|
204
216
|
|
205
217
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'jimmy_jukebox/check_io_console'
|
2
|
+
require 'jimmy_jukebox/jukebox'
|
3
|
+
require 'jimmy_jukebox/check_jruby'
|
4
|
+
|
5
|
+
module JimmyJukebox
|
6
|
+
|
7
|
+
class UserInputHandler
|
8
|
+
|
9
|
+
class NoPlayLoopThreadException < Exception; end
|
10
|
+
|
11
|
+
attr_accessor :jukebox
|
12
|
+
|
13
|
+
def initialize(jukebox)
|
14
|
+
self.jukebox = jukebox
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_get_char_method
|
18
|
+
@get_char_method = if JimmyJukebox::RUNNING_JRUBY
|
19
|
+
lambda { STDIN.getch }
|
20
|
+
else
|
21
|
+
lambda {
|
22
|
+
begin
|
23
|
+
stty_state = `stty -g`
|
24
|
+
system("stty raw opost -echo -icanon isig")
|
25
|
+
STDIN.getc.chr
|
26
|
+
ensure
|
27
|
+
`stty #{stty_state}`
|
28
|
+
end
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_char
|
34
|
+
@get_char_method.call
|
35
|
+
end
|
36
|
+
|
37
|
+
def repl
|
38
|
+
set_get_char_method
|
39
|
+
loop do
|
40
|
+
case char = get_char
|
41
|
+
when "q", "Q"
|
42
|
+
raise Interrupt
|
43
|
+
when "e", "E"
|
44
|
+
jukebox.erase_song
|
45
|
+
when "p", "P"
|
46
|
+
if jukebox.current_song.paused?
|
47
|
+
jukebox.unpause_current_song
|
48
|
+
else
|
49
|
+
puts "Pausing. To unpause, enter 'p' again"
|
50
|
+
jukebox.pause_current_song
|
51
|
+
end
|
52
|
+
when "r", "R"
|
53
|
+
jukebox.replay_previous_song
|
54
|
+
when "s", "S"
|
55
|
+
jukebox.skip_song
|
56
|
+
else
|
57
|
+
puts "#{char.strip} is not a valid response" if char
|
58
|
+
end
|
59
|
+
end
|
60
|
+
rescue Interrupt, SystemExit => e
|
61
|
+
puts "JimmyJukebox closed by user request. Bye!"
|
62
|
+
jukebox.quit
|
63
|
+
exit
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -1,19 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'io/console'
|
3
|
-
rescue LoadError
|
4
|
-
puts "*** JimmyJukebox uses io/console, which is built into Ruby 1.9.3. I recommend running JimmyJukebox on 1.9.3. You could instead install the 'io-console' gem, but the most recent version works only with 1.9.3, so try \"gem install io-console -v '0.3'\" ***"
|
5
|
-
exit
|
6
|
-
end
|
7
|
-
|
8
|
-
if JimmyJukebox::RUNNING_JRUBY
|
9
|
-
class IO
|
10
|
-
def getch
|
11
|
-
raw do
|
12
|
-
getc
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
1
|
+
require 'jimmy_jukebox/user_input_handler'
|
17
2
|
|
18
3
|
jj = Jukebox.new
|
19
4
|
|
@@ -22,49 +7,13 @@ play_loop_thread = Thread.new do
|
|
22
7
|
jj.play_loop
|
23
8
|
end
|
24
9
|
|
10
|
+
uih = UserInputHandler.new(jj)
|
11
|
+
|
25
12
|
user_input_thread = Thread.new do
|
26
13
|
|
27
|
-
|
14
|
+
raise NoPlayLoopThreadException, "Can't find play_loop_thread" unless play_loop_thread
|
15
|
+
uih.repl
|
28
16
|
|
29
|
-
begin
|
30
|
-
loop do
|
31
|
-
if JimmyJukebox::RUNNING_JRUBY
|
32
|
-
char = STDIN.getch
|
33
|
-
else
|
34
|
-
begin
|
35
|
-
stty_state = `stty -g`
|
36
|
-
system("stty raw opost -echo -icanon isig")
|
37
|
-
char = STDIN.getc.chr
|
38
|
-
ensure
|
39
|
-
`stty #{stty_state}`
|
40
|
-
end
|
41
|
-
end
|
42
|
-
case char
|
43
|
-
when "q", "Q"
|
44
|
-
raise Interrupt
|
45
|
-
when "e", "E"
|
46
|
-
jj.erase_song
|
47
|
-
when "p", "P"
|
48
|
-
raise NoPlayLoopThreadException, "Can't find play_loop_thread" unless play_loop_thread
|
49
|
-
if jj.current_song.paused?
|
50
|
-
jj.unpause_current_song
|
51
|
-
else
|
52
|
-
puts "Pausing. To unpause, enter 'p' again"
|
53
|
-
jj.pause_current_song
|
54
|
-
end
|
55
|
-
when "r", "R"
|
56
|
-
jj.replay_previous_song
|
57
|
-
when "s", "S"
|
58
|
-
jj.skip_song
|
59
|
-
else
|
60
|
-
puts "#{char.strip} is not a valid response" if char
|
61
|
-
end
|
62
|
-
end
|
63
|
-
rescue Interrupt, SystemExit => e
|
64
|
-
puts "JimmyJukebox closed by user request. Bye!"
|
65
|
-
jj.quit
|
66
|
-
exit
|
67
|
-
end
|
68
17
|
end
|
69
18
|
|
70
19
|
play_loop_thread.join
|
data/spec/jimmy_jukebox_spec.rb
CHANGED
@@ -48,6 +48,7 @@ describe Jukebox do
|
|
48
48
|
let(:song2_path) { File.expand_path('~/Music/Rock/Beatles/Sgt_Pepper.mp3') }
|
49
49
|
let(:song3_path) { File.expand_path('~/Music/Rock/Eagles/Hotel_California.ogg') }
|
50
50
|
let(:jb) { Jukebox.new(uc) }
|
51
|
+
let(:downloaded) { jb.downloaded_song_paths }
|
51
52
|
|
52
53
|
before do
|
53
54
|
[song1_path, song2_path, song3_path].each do |song|
|
@@ -59,10 +60,10 @@ describe Jukebox do
|
|
59
60
|
end
|
60
61
|
|
61
62
|
it "generates a non-empty song list" do
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
downloaded.should_not be_nil
|
64
|
+
downloaded.should_not be_empty
|
65
|
+
downloaded.length.should == 3
|
66
|
+
downloaded.grep(/Abbey_Road.mp3/).length.should == 1
|
66
67
|
end
|
67
68
|
|
68
69
|
it "can quit" do
|
@@ -72,9 +73,8 @@ describe Jukebox do
|
|
72
73
|
play_loop_thread = Thread.new do
|
73
74
|
jb.play_loop
|
74
75
|
end
|
75
|
-
sleep 0.
|
76
|
+
sleep 0.1
|
76
77
|
jb.playing?.should be_true
|
77
|
-
p jb.current_song
|
78
78
|
jb.quit
|
79
79
|
end
|
80
80
|
|
data/spec/song_loader_spec.rb
CHANGED
@@ -84,26 +84,26 @@ describe SongLoader do
|
|
84
84
|
|
85
85
|
end
|
86
86
|
|
87
|
-
describe "#
|
87
|
+
describe "#all_downloadable_songs" do
|
88
88
|
|
89
89
|
context "no genre specified" do
|
90
90
|
|
91
|
-
let(:
|
91
|
+
let(:all_downloadable_songs) { SongLoader.new.all_downloadable_songs }
|
92
92
|
|
93
93
|
it "should include songs from artist lists" do
|
94
|
-
|
95
|
-
|
94
|
+
all_downloadable_songs.keys.should include "http://archive.org/download/MozartSinfoniaConcertanteK.364spivakovMintz/02Mozart_SinfoniaConcertanteInEFlatK364-2.Andante.mp3"
|
95
|
+
all_downloadable_songs.keys.should include "http://archive.org/download/WinnerRagtimeBand-TheTurkeyTrot1912/WinnerRagtimeBand-TurkeyTrot1912.mp3"
|
96
96
|
end
|
97
97
|
|
98
98
|
end
|
99
99
|
|
100
100
|
context "genre 'JAZZ' specified" do
|
101
101
|
|
102
|
-
let(:
|
102
|
+
let(:all_downloadable_songs) { SongLoader.new.all_downloadable_songs('JAZZ') }
|
103
103
|
|
104
104
|
it "should include only songs from jazz artist lists" do
|
105
|
-
|
106
|
-
|
105
|
+
all_downloadable_songs.keys.should_not include "http://archive.org/download/MozartSinfoniaConcertanteK.364spivakovMintz/02Mozart_SinfoniaConcertanteInEFlatK364-2.Andante.mp3"
|
106
|
+
all_downloadable_songs.keys.should include "http://archive.org/download/WinnerRagtimeBand-TheTurkeyTrot1912/WinnerRagtimeBand-TurkeyTrot1912.mp3"
|
107
107
|
end
|
108
108
|
|
109
109
|
end
|
data/spec/song_spec.rb
CHANGED
@@ -11,10 +11,12 @@ module JimmyJukebox
|
|
11
11
|
def spawn_method
|
12
12
|
if JimmyJukebox::RUNNING_JRUBY
|
13
13
|
require 'spoon'
|
14
|
-
lambda { |command, arg| Spoon.spawnp('sleep
|
14
|
+
lambda { |command, arg| Spoon.spawnp('sleep 5') }
|
15
15
|
else
|
16
16
|
require 'posix/spawn'
|
17
|
-
|
17
|
+
# no idea why ';boguscommand' works, but tests fail without it
|
18
|
+
#lambda { |command, arg| POSIX::Spawn::spawn('sleep 2; boguscommand') }
|
19
|
+
lambda { |command, arg| POSIX::Spawn::spawn('sleep 5') }
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -28,16 +30,28 @@ describe Song do
|
|
28
30
|
expect {Song.new}.to raise_error
|
29
31
|
end
|
30
32
|
|
31
|
-
it "fails if parameter does not
|
32
|
-
expect {Song.new("
|
33
|
+
it "fails if parameter does not have file extension" do
|
34
|
+
expect {Song.new(File.expand_path("~/music_file"))}.to raise_error
|
33
35
|
end
|
34
36
|
|
35
37
|
it "accepts a parameter ending in .mp3" do
|
36
|
-
Song.new("
|
38
|
+
Song.new(File.expand_path("~/music_file.mp3")).is_a?(Song)
|
37
39
|
end
|
38
40
|
|
39
41
|
it "accepts a parameter ending in .ogg" do
|
40
|
-
Song.new("
|
42
|
+
Song.new(File.expand_path("~/music_file.ogg")).is_a?(Song)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "accepts a parameter ending in .flac" do
|
46
|
+
Song.new(File.expand_path("~/music_file.flac")).is_a?(Song)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "accepts a parameter ending in .wav" do
|
50
|
+
Song.new(File.expand_path("~/music_file.wav")).is_a?(Song)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "handles uppercase file extensions" do
|
54
|
+
Song.new(File.expand_path("~/music_file.WAV")).is_a?(Song)
|
41
55
|
end
|
42
56
|
|
43
57
|
it "sets a music file" do
|
@@ -46,6 +60,12 @@ describe Song do
|
|
46
60
|
song.music_file.should == mf
|
47
61
|
end
|
48
62
|
|
63
|
+
it "sets a music file when passed with ~" do
|
64
|
+
mf = "~/Music/JAZZ/billie_holiday.ogg"
|
65
|
+
song = Song.new(mf)
|
66
|
+
song.music_file.should == File.expand_path(mf)
|
67
|
+
end
|
68
|
+
|
49
69
|
end
|
50
70
|
|
51
71
|
describe "#paused?" do
|
@@ -53,26 +73,41 @@ describe Song do
|
|
53
73
|
before(:each) do
|
54
74
|
@uc = UserConfig.new
|
55
75
|
@jj = Jukebox.new(@uc, false)
|
56
|
-
@song = Song.new("~/Music/JAZZ/art_tatum.mp3")
|
57
76
|
end
|
58
77
|
|
59
78
|
it "is initially not paused" do
|
60
|
-
|
61
|
-
|
79
|
+
Thread.new do
|
80
|
+
song = Song.new("~/Music/JAZZ/art_tatum.mp3")
|
81
|
+
@jj.play_song(song)
|
82
|
+
end
|
83
|
+
sleep 0.1
|
84
|
+
@jj.should be_playing
|
85
|
+
@jj.current_song.paused?.should be_false
|
86
|
+
@jj.quit
|
62
87
|
end
|
63
88
|
|
64
89
|
it "is paused after calling #pause" do
|
65
|
-
|
90
|
+
Thread.new do
|
91
|
+
song = Song.new("~/Music/JAZZ/art_tatum.mp3")
|
92
|
+
@jj.play_song(song)
|
93
|
+
end
|
94
|
+
sleep 0.1
|
66
95
|
@jj.pause_current_song
|
67
|
-
@
|
96
|
+
@jj.current_song.paused?.should be_true
|
97
|
+
@jj.quit
|
68
98
|
end
|
69
99
|
|
70
100
|
it "is unpaused after calling #pause and #unpause" do
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
101
|
+
Thread.new do
|
102
|
+
song = Song.new("~/Music/JAZZ/art_tatum.mp3")
|
103
|
+
@jj.play_song(song)
|
104
|
+
end
|
105
|
+
sleep 0.1
|
106
|
+
@jj.current_song.pause
|
107
|
+
@jj.current_song.paused?.should be_true
|
108
|
+
@jj.current_song.unpause
|
109
|
+
@jj.current_song.paused?.should be_false
|
110
|
+
@jj.quit
|
76
111
|
end
|
77
112
|
|
78
113
|
end
|
@@ -82,37 +117,61 @@ describe Song do
|
|
82
117
|
before(:each) do
|
83
118
|
@uc = UserConfig.new
|
84
119
|
@jj = Jukebox.new(@uc, false)
|
85
|
-
@
|
86
|
-
|
87
|
-
|
88
|
-
it "is initially not paused" do
|
89
|
-
@jj.play_song(@song)
|
90
|
-
@song.playing_pid.should be_kind_of(Integer)
|
91
|
-
@jj.skip_song
|
92
|
-
@song.playing_pid.should be_nil
|
120
|
+
@jj.stub(:downloaded_song_paths).and_return(['~/Music/JAZZ/Duke_Ellington/song1.ogg','~/Music/CLASSICAL/Bach/song2.mp3'])
|
121
|
+
#@song = Song.new("~/Music/JAZZ/art_tatum.mp3")
|
93
122
|
end
|
94
123
|
|
95
124
|
end
|
96
125
|
|
97
|
-
describe "#play_loop" do
|
126
|
+
describe "#play_loop & #skip_song" do
|
98
127
|
|
99
128
|
before(:each) do
|
100
129
|
@uc = UserConfig.new
|
101
|
-
|
102
|
-
@
|
103
|
-
|
104
|
-
|
105
|
-
end
|
106
|
-
|
107
|
-
it "should automatically play the first song" do
|
130
|
+
@song1 = "~/Music/JAZZ/art_tatum.mp3"
|
131
|
+
@song2 = "~/Music/JAZZ/dizzy.mp3"
|
132
|
+
@song3 = "~/Music/JAZZ/earl_hines.mp3"
|
133
|
+
@song4 = "~/Music/CLASSICAL/beethoven.mp3"
|
108
134
|
@jj = Jukebox.new(@uc)
|
109
|
-
|
135
|
+
@jj.stub(:downloaded_song_paths).and_return([@song1, @song2, @song3, @song4])
|
136
|
+
@play_loop_thread = Thread.new do
|
110
137
|
@jj.play_loop
|
111
138
|
end
|
112
139
|
sleep 0.1
|
113
|
-
@jj.playing?.should be_true
|
114
|
-
play_loop_thread.exit
|
115
140
|
end
|
141
|
+
|
142
|
+
describe "#play_loop" do
|
143
|
+
|
144
|
+
it "should automatically play the first song" do
|
145
|
+
@jj.should be_playing
|
146
|
+
@jj.downloaded_song_paths.map { |f| File.expand_path(f) }.should include @jj.current_song.music_file
|
147
|
+
@play_loop_thread.exit
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "#skip_song" do
|
153
|
+
|
154
|
+
it "is initially not paused" do
|
155
|
+
test_thread = Thread.new do
|
156
|
+
@jj.should be_playing
|
157
|
+
puts @jj.current_song.playing_pid
|
158
|
+
puts @jj.current_song.music_file
|
159
|
+
first_song_pid = @jj.current_song.playing_pid
|
160
|
+
sleep 0.5
|
161
|
+
@jj.skip_song
|
162
|
+
puts @jj.current_song.playing_pid
|
163
|
+
puts @jj.current_song.music_file
|
164
|
+
@jj.current_song.playing_pid.should_not == first_song_pid
|
165
|
+
@jj.should be_playing
|
166
|
+
end
|
167
|
+
[@play_loop_thread, test_thread].each do |t|
|
168
|
+
t.join
|
169
|
+
end
|
170
|
+
@play_loop_thread.exit
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
116
175
|
end
|
117
176
|
|
118
177
|
end
|
data/spec/user_config_spec.rb
CHANGED
@@ -128,32 +128,60 @@ describe UserConfig do
|
|
128
128
|
|
129
129
|
end
|
130
130
|
|
131
|
-
describe "#
|
131
|
+
describe "#song_paths and #undownloaded_songs" do
|
132
132
|
let(:user_config) { UserConfig.new }
|
133
|
-
let(:dir1) { '~/Music/
|
134
|
-
let(:dir2) { '~/Music/
|
133
|
+
let(:dir1) { '~/Music/JAZZ/John_Coltrane' }
|
134
|
+
let(:dir2) { '~/Music/CLASSICAL/Vivaldi' }
|
135
135
|
let(:d1) { File.expand_path(dir1) }
|
136
136
|
let(:d2) { File.expand_path(dir2) }
|
137
137
|
|
138
138
|
before(:each) do
|
139
139
|
FileUtils.mkdir_p(d1)
|
140
|
-
FileUtils.mkdir_p(d1 + '/subdir')
|
141
140
|
FileUtils.mkdir_p(d2)
|
142
|
-
FileUtils.touch d1 + '/
|
143
|
-
FileUtils.touch d1 + '/
|
144
|
-
FileUtils.touch d1 + '/
|
145
|
-
FileUtils.touch d2 + '/
|
146
|
-
FileUtils.touch d2 + '/
|
147
|
-
FileUtils.touch d2 + '/
|
141
|
+
FileUtils.touch d1 + '/a_love_supreme.mp3'
|
142
|
+
FileUtils.touch d1 + '/my_funny_valentine.ogg'
|
143
|
+
FileUtils.touch d1 + '/song5.afdsdf'
|
144
|
+
FileUtils.touch d2 + '/four_seasons.flac'
|
145
|
+
FileUtils.touch d2 + '/spring.wav'
|
146
|
+
FileUtils.touch d2 + '/Summer.WAV'
|
148
147
|
end
|
149
148
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
149
|
+
describe "#song_paths" do
|
150
|
+
|
151
|
+
it "generates a complete song list" do
|
152
|
+
user_config.song_paths.should include File.expand_path(d1 + '/a_love_supreme.mp3')
|
153
|
+
user_config.song_paths.should include File.expand_path(d1 + '/my_funny_valentine.ogg')
|
154
|
+
user_config.song_paths.should include File.expand_path(d2 + '/four_seasons.flac')
|
155
|
+
user_config.song_paths.should include File.expand_path(d2 + '/spring.wav')
|
156
|
+
user_config.song_paths.should include File.expand_path(d2 + '/Summer.WAV')
|
157
|
+
user_config.song_paths.length.should == 5
|
158
|
+
end
|
159
|
+
|
160
|
+
it "does not include the invalid-formatted song in the list" do
|
161
|
+
user_config.song_paths.should_not include File.expand_path(d1 + '/song5.afdsdf')
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "#undownloaded_songs" do
|
167
|
+
|
168
|
+
before do
|
169
|
+
@song_hash = {'http://www.mp3.com/a_love_supreme.mp3' => {:genre => 'JAZZ', :name => 'john_coltrane'},
|
170
|
+
'http://www.flac.net/four_seasons.flac' => {:genre => 'CLASSICAL', :name => 'vivaldi'},
|
171
|
+
'http://www.wav.com/winter.wav' => {:genre => 'CLASSICAL', :name => 'vivaldi'},
|
172
|
+
'http://www.ogg.org/maybeline.ogg' => {:genre => 'ROCK', :name => 'chuck_berry'}
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
176
|
+
it "correctly generates the list of undownloaded songs" do
|
177
|
+
JimmyJukebox::SongLoader.any_instance.stub(:all_downloadable_songs).and_return(@song_hash)
|
178
|
+
undownloaded_urls = user_config.undownloaded_songs.keys
|
179
|
+
undownloaded_urls.should include 'http://www.wav.com/winter.wav'
|
180
|
+
undownloaded_urls.should include 'http://www.ogg.org/maybeline.ogg'
|
181
|
+
undownloaded_urls.should_not include 'http://www.flac.net/four_seasons.flac'
|
182
|
+
undownloaded_urls.should_not include 'http://www.mp3.com/a_love_supreme.mp3'
|
183
|
+
end
|
184
|
+
|
157
185
|
end
|
158
186
|
|
159
187
|
end
|
@@ -214,39 +242,39 @@ describe UserConfig do
|
|
214
242
|
|
215
243
|
let(:uc) { UserConfig.new }
|
216
244
|
|
217
|
-
context "with no
|
245
|
+
context "with no song_paths" do
|
218
246
|
|
219
|
-
it "finds no
|
220
|
-
uc.
|
247
|
+
it "finds no song_paths" do
|
248
|
+
uc.song_paths.length.should == 0
|
221
249
|
end
|
222
250
|
|
223
251
|
end
|
224
252
|
|
225
|
-
context "with
|
253
|
+
context "with song_paths in ~/Music" do
|
226
254
|
|
227
255
|
before(:each) do
|
228
256
|
FileUtils.mkdir_p File.expand_path("~/Music")
|
229
257
|
FileUtils.touch File.expand_path("~/Music/Yellow_Submarine.mp3")
|
230
258
|
end
|
231
259
|
|
232
|
-
it "finds
|
233
|
-
uc.
|
234
|
-
uc.
|
260
|
+
it "finds song_paths" do
|
261
|
+
uc.song_paths.should_not be_empty
|
262
|
+
uc.song_paths.length.should == 1
|
235
263
|
end
|
236
264
|
|
237
265
|
end
|
238
266
|
|
239
|
-
context "with
|
267
|
+
context "with song_paths in ~/Music subdirectory" do
|
240
268
|
|
241
269
|
before do
|
242
270
|
FileUtils.mkdir_p File.expand_path("~/Music/ROCK/Beatles")
|
243
271
|
FileUtils.touch File.expand_path("~/Music/ROCK/Beatles/Yellow_Submarine.mp3")
|
244
272
|
end
|
245
273
|
|
246
|
-
it "finds
|
274
|
+
it "finds song_paths" do
|
247
275
|
File.directory?(File.expand_path("~/Music/ROCK/Beatles")).should be_true
|
248
|
-
uc.
|
249
|
-
uc.
|
276
|
+
uc.song_paths.should_not be_empty
|
277
|
+
uc.song_paths.length.should == 1
|
250
278
|
end
|
251
279
|
|
252
280
|
end
|
metadata
CHANGED
@@ -1,114 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jimmy_jukebox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
4
|
+
prerelease:
|
5
|
+
version: 0.6.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- James Lavin
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
|
17
|
-
none: false
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
18
17
|
requirements:
|
19
|
-
- -
|
18
|
+
- - ">="
|
20
19
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
22
|
-
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
version: !binary |-
|
21
|
+
MA==
|
25
22
|
none: false
|
23
|
+
requirement: !ruby/object:Gem::Requirement
|
26
24
|
requirements:
|
27
|
-
- -
|
25
|
+
- - ">="
|
28
26
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
27
|
+
version: !binary |-
|
28
|
+
MA==
|
29
|
+
none: false
|
30
|
+
prerelease: false
|
31
|
+
type: :development
|
30
32
|
- !ruby/object:Gem::Dependency
|
31
33
|
name: rspec-core
|
32
|
-
|
33
|
-
none: false
|
34
|
+
version_requirements: !ruby/object:Gem::Requirement
|
34
35
|
requirements:
|
35
|
-
- -
|
36
|
+
- - ">="
|
36
37
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
38
|
-
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
version: !binary |-
|
39
|
+
MA==
|
41
40
|
none: false
|
41
|
+
requirement: !ruby/object:Gem::Requirement
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: !binary |-
|
46
|
+
MA==
|
47
|
+
none: false
|
48
|
+
prerelease: false
|
49
|
+
type: :development
|
46
50
|
- !ruby/object:Gem::Dependency
|
47
51
|
name: rspec-mocks
|
48
|
-
|
49
|
-
none: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
53
|
requirements:
|
51
|
-
- -
|
54
|
+
- - ">="
|
52
55
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
54
|
-
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
56
|
+
version: !binary |-
|
57
|
+
MA==
|
57
58
|
none: false
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
58
60
|
requirements:
|
59
|
-
- -
|
61
|
+
- - ">="
|
60
62
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
63
|
+
version: !binary |-
|
64
|
+
MA==
|
65
|
+
none: false
|
66
|
+
prerelease: false
|
67
|
+
type: :development
|
62
68
|
- !ruby/object:Gem::Dependency
|
63
69
|
name: rspec-expectations
|
64
|
-
|
65
|
-
none: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
71
|
requirements:
|
67
|
-
- -
|
72
|
+
- - ">="
|
68
73
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
70
|
-
|
71
|
-
prerelease: false
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
version: !binary |-
|
75
|
+
MA==
|
73
76
|
none: false
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
74
78
|
requirements:
|
75
|
-
- -
|
79
|
+
- - ">="
|
76
80
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
81
|
+
version: !binary |-
|
82
|
+
MA==
|
83
|
+
none: false
|
84
|
+
prerelease: false
|
85
|
+
type: :development
|
78
86
|
- !ruby/object:Gem::Dependency
|
79
87
|
name: fakefs
|
80
|
-
|
81
|
-
none: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
89
|
requirements:
|
83
|
-
- -
|
90
|
+
- - ">="
|
84
91
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
86
|
-
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
version: !binary |-
|
93
|
+
MA==
|
89
94
|
none: false
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
90
96
|
requirements:
|
91
|
-
- -
|
97
|
+
- - ">="
|
92
98
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
99
|
+
version: !binary |-
|
100
|
+
MA==
|
101
|
+
none: false
|
102
|
+
prerelease: false
|
103
|
+
type: :development
|
94
104
|
- !ruby/object:Gem::Dependency
|
95
105
|
name: fakeweb
|
96
|
-
|
97
|
-
none: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
98
107
|
requirements:
|
99
|
-
- -
|
108
|
+
- - ">="
|
100
109
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
102
|
-
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
version: !binary |-
|
111
|
+
MA==
|
105
112
|
none: false
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
106
114
|
requirements:
|
107
|
-
- -
|
115
|
+
- - ">="
|
108
116
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
110
|
-
|
111
|
-
|
117
|
+
version: !binary |-
|
118
|
+
MA==
|
119
|
+
none: false
|
120
|
+
prerelease: false
|
121
|
+
type: :development
|
122
|
+
description: jimmy_jukebox downloads great music and plays random MP3 & OGG songs under a directory (or set of directories)
|
112
123
|
email: james@jameslavin.com
|
113
124
|
executables:
|
114
125
|
- play_jukebox
|
@@ -119,11 +130,15 @@ files:
|
|
119
130
|
- roadmap.txt
|
120
131
|
- LICENSE.txt
|
121
132
|
- lib/jimmy_jukebox.rb
|
133
|
+
- lib/jimmy_jukebox/check_jruby.rb
|
122
134
|
- lib/jimmy_jukebox/handle_load_jukebox_input.rb
|
135
|
+
- lib/jimmy_jukebox/check_gems.rb
|
136
|
+
- lib/jimmy_jukebox/user_input_handler.rb
|
123
137
|
- lib/jimmy_jukebox/display_options.rb
|
124
138
|
- lib/jimmy_jukebox/music_player_detector.rb
|
125
139
|
- lib/jimmy_jukebox/load_jukebox_code.rb
|
126
140
|
- lib/jimmy_jukebox/user_interface.rb
|
141
|
+
- lib/jimmy_jukebox/check_io_console.rb
|
127
142
|
- lib/jimmy_jukebox/user_config.rb
|
128
143
|
- lib/jimmy_jukebox/jukebox.rb
|
129
144
|
- lib/jimmy_jukebox/constants.rb
|
@@ -192,27 +207,28 @@ files:
|
|
192
207
|
- bin/load_jukebox
|
193
208
|
homepage: https://github.com/JamesLavin/jimmy_jukebox
|
194
209
|
licenses: []
|
195
|
-
post_install_message: I really hope you enjoy the great jazz, classical, bluegrass,
|
196
|
-
and early rock music downloadable using this gem!
|
210
|
+
post_install_message: I really hope you enjoy the great jazz, classical, bluegrass, and early rock music downloadable using this gem!
|
197
211
|
rdoc_options: []
|
198
212
|
require_paths:
|
199
213
|
- lib
|
200
214
|
required_ruby_version: !ruby/object:Gem::Requirement
|
201
|
-
none: false
|
202
215
|
requirements:
|
203
|
-
- -
|
216
|
+
- - ">="
|
204
217
|
- !ruby/object:Gem::Version
|
205
|
-
version:
|
206
|
-
|
218
|
+
version: !binary |-
|
219
|
+
MA==
|
207
220
|
none: false
|
221
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
222
|
requirements:
|
209
|
-
- -
|
223
|
+
- - ">="
|
210
224
|
- !ruby/object:Gem::Version
|
211
|
-
version:
|
225
|
+
version: !binary |-
|
226
|
+
MA==
|
227
|
+
none: false
|
212
228
|
requirements: []
|
213
229
|
rubyforge_project: jimmy_jukebox
|
214
|
-
rubygems_version: 1.8.
|
215
|
-
signing_key:
|
230
|
+
rubygems_version: 1.8.24
|
231
|
+
signing_key:
|
216
232
|
specification_version: 3
|
217
233
|
summary: plays your MP3 & OGG files and lets you easily download music
|
218
234
|
test_files:
|
@@ -224,4 +240,3 @@ test_files:
|
|
224
240
|
- spec/song_loader_spec.rb
|
225
241
|
- spec/load_jukebox_code_spec.rb
|
226
242
|
- spec/jimmy_jukebox_spec.rb
|
227
|
-
has_rdoc:
|