jimmy_jukebox 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|