cultome_player 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +325 -0
- data/Rakefile +8 -0
- data/bin/cultome_player +39 -0
- data/config/environment.yml +28 -0
- data/cultome_player.gemspec +35 -0
- data/db/001_create_schema.rb +58 -0
- data/lib/cultome_player.rb +107 -0
- data/lib/cultome_player/command.rb +11 -0
- data/lib/cultome_player/command/language.rb +61 -0
- data/lib/cultome_player/command/processor.rb +165 -0
- data/lib/cultome_player/command/reader.rb +86 -0
- data/lib/cultome_player/environment.rb +130 -0
- data/lib/cultome_player/events.rb +29 -0
- data/lib/cultome_player/media.rb +47 -0
- data/lib/cultome_player/objects.rb +15 -0
- data/lib/cultome_player/objects/album.rb +21 -0
- data/lib/cultome_player/objects/artist.rb +18 -0
- data/lib/cultome_player/objects/command.rb +37 -0
- data/lib/cultome_player/objects/drive.rb +26 -0
- data/lib/cultome_player/objects/genre.rb +16 -0
- data/lib/cultome_player/objects/parameter.rb +37 -0
- data/lib/cultome_player/objects/response.rb +42 -0
- data/lib/cultome_player/objects/song.rb +38 -0
- data/lib/cultome_player/player.rb +13 -0
- data/lib/cultome_player/player/adapter.rb +14 -0
- data/lib/cultome_player/player/adapter/mpg123.rb +143 -0
- data/lib/cultome_player/player/interactive.rb +56 -0
- data/lib/cultome_player/player/interface.rb +13 -0
- data/lib/cultome_player/player/interface/basic.rb +96 -0
- data/lib/cultome_player/player/interface/builtin_help.rb +368 -0
- data/lib/cultome_player/player/interface/extended.rb +199 -0
- data/lib/cultome_player/player/interface/helper.rb +300 -0
- data/lib/cultome_player/player/playlist.rb +280 -0
- data/lib/cultome_player/plugins.rb +23 -0
- data/lib/cultome_player/plugins/help.rb +58 -0
- data/lib/cultome_player/state_checker.rb +74 -0
- data/lib/cultome_player/utils.rb +95 -0
- data/lib/cultome_player/version.rb +3 -0
- data/spec/config.yml +0 -0
- data/spec/cultome_player/command/processor_spec.rb +168 -0
- data/spec/cultome_player/command/reader_spec.rb +45 -0
- data/spec/cultome_player/cultome_player_spec.rb +17 -0
- data/spec/cultome_player/environment_spec.rb +65 -0
- data/spec/cultome_player/events_spec.rb +22 -0
- data/spec/cultome_player/media_spec.rb +41 -0
- data/spec/cultome_player/player/adapter/mpg123_spec.rb +82 -0
- data/spec/cultome_player/player/interface/basic_spec.rb +168 -0
- data/spec/cultome_player/player/interface/extended/connect_spec.rb +117 -0
- data/spec/cultome_player/player/interface/extended/search_spec.rb +90 -0
- data/spec/cultome_player/player/interface/extended/show_spec.rb +36 -0
- data/spec/cultome_player/player/interface/extended/shuffle_spec.rb +26 -0
- data/spec/cultome_player/player/interface/extended_spec.rb +136 -0
- data/spec/cultome_player/player/interface/helper_spec.rb +63 -0
- data/spec/cultome_player/player/interface_spec.rb +17 -0
- data/spec/cultome_player/player/playlist_spec.rb +301 -0
- data/spec/cultome_player/plugins/help_spec.rb +21 -0
- data/spec/cultome_player/plugins_spec.rb +19 -0
- data/spec/cultome_player/utils_spec.rb +15 -0
- data/spec/spec_helper.rb +108 -0
- data/spec/test/uno/dos/dos.mp3 +0 -0
- data/spec/test/uno/dos/tres/tres.mp3 +0 -0
- data/spec/test/uno/uno.mp3 +0 -0
- data/tasks/console.rake +19 -0
- data/tasks/db.rake +19 -0
- data/tasks/run.rake +7 -0
- metadata +322 -0
data/spec/config.yml
ADDED
File without changes
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CultomePlayer::Command::Processor do
|
4
|
+
let(:t){ TestClass.new }
|
5
|
+
|
6
|
+
context '#read_command' do
|
7
|
+
end
|
8
|
+
|
9
|
+
context '#get_tokens' do
|
10
|
+
it 'respond to get_tokens method' do
|
11
|
+
t.should respond_to :get_tokens
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'split literals' do
|
15
|
+
t.get_tokens("uno dos").should eq ["uno", "dos"]
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'split strings' do
|
19
|
+
t.get_tokens("'uno dos' 'tres cuatro'").should eq ["uno dos", "tres cuatro"]
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'split numbers' do
|
23
|
+
t.get_tokens("1 2 3").should eq ["1", "2", "3"]
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'split objects' do
|
27
|
+
t.get_tokens("@uno @dos").should eq ["@uno", "@dos"]
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'split paths' do
|
31
|
+
t.get_tokens("/home/mio '/home/tuyo/con espacio'").should eq ["/home/mio", "/home/tuyo/con espacio"]
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'split criteria' do
|
35
|
+
t.get_tokens("uno:dos tres:'cuatro cinco'").should eq ["uno:dos", "tres:cuatro cinco"]
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'raise an error if unclosed string is present' do
|
39
|
+
expect { t.get_tokens("uno 'dos") }.to raise_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context '#identify_tokens' do
|
44
|
+
it 'identify object' do
|
45
|
+
t.identify_tokens(["@uno"]).should eq [{type: :object, value: "uno"}]
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'identify criteria' do
|
49
|
+
t.identify_tokens(["uno:dos"]).should eq [{type: :criteria, criteria: "uno", value: "dos"}]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'identify path' do
|
53
|
+
t.identify_tokens(["/home/mio"]).should eq [{type: :path, value: "/home/mio"}]
|
54
|
+
t.identify_tokens(["~/music"]).should eq [{type: :path, value: "~/music"}]
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'identify number' do
|
58
|
+
t.identify_tokens(["1"]).should eq [{type: :number, value: "1"}]
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'identify literal' do
|
62
|
+
t.identify_tokens(["uno"]).should eq [{type: :literal, value: "uno"}]
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'identify as unknown token that dont recognize' do
|
66
|
+
t.identify_tokens(["@uno dos"]).should eq [{type: :unknown, value: "@uno dos"}]
|
67
|
+
t.identify_tokens(["uno dos:tres"]).should eq [{type: :unknown, value: "uno dos:tres"}]
|
68
|
+
t.identify_tokens(["uno/dos"]).should eq [{type: :unknown, value: "uno/dos"}]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context '#validate_command' do
|
73
|
+
it 'validate a command without parameters' do
|
74
|
+
t.validate_command(:command, [{type: :literal, value: "stop"}]).should be_true
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'validate a command with one parameter' do
|
78
|
+
t.validate_command(:command, [{type: :literal, value: "play"}, {type: :literal, value: "uno"}]).should be_true
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'validate a command with more than one parameter' do
|
82
|
+
t.validate_command(:command, [{type: :literal, value: "play"}, {type: :number, value: "1"}, {type: :object, value: "dos"}, {type: :criteria, criteria: "tres", value: "cuatro"}]).should be_true
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'detect invalid command' do
|
86
|
+
expect{
|
87
|
+
t.validate_command(:command, [{type: :unknown, value: "uno1"}])
|
88
|
+
}.to raise_error("invalid command:invalid command")
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'detect invalid command format' do
|
92
|
+
expect{
|
93
|
+
t.validate_command(:command, [{type: :number, value: "1"}])
|
94
|
+
}.to raise_error("invalid command:invalid command")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'parse user command' do
|
99
|
+
it 'respond to parse method' do
|
100
|
+
t.should respond_to :parse
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns a command object' do
|
104
|
+
t.parse("next").should be_instance_of CultomePlayer::Objects::Command
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'returns a command even when defined as plugin' do
|
108
|
+
t.parse("help").should be_instance_of CultomePlayer::Objects::Command
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'set the action and parameter' do
|
112
|
+
cmd = t.parse("enqueue uno 'dos' tres:cuatro")
|
113
|
+
|
114
|
+
cmd.action.should eq "enqueue"
|
115
|
+
cmd.parameters.should have(3).items
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'basic command' do
|
119
|
+
cmd = t.parse("prev")
|
120
|
+
cmd.action.should eq "prev"
|
121
|
+
cmd.should have(0).parameters
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'with one parameter' do
|
125
|
+
cmd = t.parse("shuffle on")
|
126
|
+
cmd.action.should eq "shuffle"
|
127
|
+
cmd.should have(1).parameters
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'with many parameter' do
|
131
|
+
cmd = t.parse("play uno @dos tes:cuatro")
|
132
|
+
cmd.action.should eq "play"
|
133
|
+
cmd.should have(3).parameters
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'detect parameter type' do
|
137
|
+
it 'type literal' do
|
138
|
+
cmd = t.parse("search uno")
|
139
|
+
cmd.should have(1).parameters
|
140
|
+
cmd.params(:literal).should have(1).item
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'type number' do
|
144
|
+
cmd = t.parse("enqueue 1 2")
|
145
|
+
cmd.should have(2).parameters
|
146
|
+
cmd.params(:number).should have(2).item
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'type object' do
|
150
|
+
cmd = t.parse("show @uno")
|
151
|
+
cmd.should have(1).parameters
|
152
|
+
cmd.params(:object).should have(1).item
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'type path' do
|
156
|
+
cmd = t.parse("connect /home/mio/music => main")
|
157
|
+
cmd.should have(3).parameters
|
158
|
+
cmd.params(:path).should have(1).item
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'type criteria' do
|
162
|
+
cmd = t.parse("play uno:dos")
|
163
|
+
cmd.should have(1).parameters
|
164
|
+
cmd.params(:criteria).should have(1).item
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CultomePlayer::Command::Reader do
|
4
|
+
let(:t){ TestClass.new }
|
5
|
+
|
6
|
+
context 'autocomplete' do
|
7
|
+
it 'actions' do
|
8
|
+
Readline.stub(:line_buffer){ "pl" }
|
9
|
+
t.send(:completion_proc).call("pl").should eq ["play "]
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'path parameters' do
|
13
|
+
Readline.stub(:line_buffer){ "play /hom" }
|
14
|
+
t.send(:completion_proc).call("/hom").should eq ["/home/"]
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'object parameters' do
|
18
|
+
Readline.stub(:line_buffer){ "play @art" }
|
19
|
+
t.send(:completion_proc).call("@art").should eq ["@artist"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'show probable' do
|
24
|
+
it 'actions' do
|
25
|
+
Readline.stub(:line_buffer){ "p" }
|
26
|
+
t.send(:completion_proc).call("p").should eq ["play ", "pause ", "prev "]
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'parameter types' do
|
30
|
+
Readline.stub(:line_buffer){ "play " }
|
31
|
+
t.send(:completion_proc).call("").should eq ["<literal>", "<number>", "<criteria>", "<object>", " "]
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'paths' do
|
35
|
+
Readline.stub(:line_buffer){ "play /home/" }
|
36
|
+
opcs = t.send(:completion_proc).call("/home/")
|
37
|
+
opcs.each{|opc| opc.should start_with "/home/" }
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'objects' do
|
41
|
+
Readline.stub(:line_buffer){ "play @a" }
|
42
|
+
t.send(:completion_proc).call("@a").should eq ["@artist", "@album"]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CultomePlayer do
|
4
|
+
let(:t){ TestClass.new(:rspec) }
|
5
|
+
|
6
|
+
it 'executes built int commands' do
|
7
|
+
t.execute('search way').should_not be_nil
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'executes plugins' do
|
11
|
+
t.execute('help').should_not be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'contains usage instrucctions' do
|
15
|
+
t.should respond_to(:usage_cultome_player)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CultomePlayer::Environment do
|
4
|
+
let(:t){ TestClass.new(nil) }
|
5
|
+
|
6
|
+
it 'prepare environment' do
|
7
|
+
t.prepare_environment(:rspec)
|
8
|
+
t.env_config.should_not be_empty
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'with no environment loaded' do
|
12
|
+
it 'raise exception when using mplayer_pipe' do
|
13
|
+
expect{ t.mplayer_pipe }.to raise_error('environment problem:environment information not loaded')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'raise exception when using db_adapter' do
|
17
|
+
expect{ t.db_adapter }.to raise_error('environment problem:environment information not loaded')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raise exception when using db_file' do
|
21
|
+
expect{ t.db_file }.to raise_error('environment problem:environment information not loaded')
|
22
|
+
end
|
23
|
+
it 'raise exception when using db_log_file' do
|
24
|
+
expect{ t.db_log_file }.to raise_error('environment problem:environment information not loaded')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'raise exception when using file_types' do
|
28
|
+
expect{ t.file_types }.to raise_error('environment problem:environment information not loaded')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'raise exception when using config_file' do
|
32
|
+
expect{ t.config_file }.to raise_error('environment problem:environment information not loaded')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with environment loaded' do
|
37
|
+
before :each do
|
38
|
+
t.prepare_environment(:rspec)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'load the db_adapter' do
|
42
|
+
t.db_adapter.should eq 'sqlite3'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'load the mplayer_pipe' do
|
46
|
+
t.mplayer_pipe.should end_with 'spec/mpctr'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'load the db_file' do
|
50
|
+
t.db_file.should end_with 'spec/db.dat'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'load the db_log_file' do
|
54
|
+
t.db_log_file.should end_with 'spec/db.log'
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'load the file_types' do
|
58
|
+
t.file_types.should eq 'mp3'
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'load the config_file' do
|
62
|
+
t.config_file.should end_with 'spec/config.yml'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CultomePlayer::Events do
|
4
|
+
let(:t){ TestClass.new }
|
5
|
+
let(:l1){ double(:listener1, :on_my_event => "OK 1!" ) }
|
6
|
+
let(:l2){ double(:listener2, :on_my_event => "OK 2!" ) }
|
7
|
+
|
8
|
+
it 'register event listeners' do
|
9
|
+
t.listeners.should be_empty
|
10
|
+
t.register_listener(:my_event, l1)
|
11
|
+
t.listeners.should have(1).item
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'callback listeners on event' do
|
15
|
+
l1.should_receive(:on_my_event).with("DATA")
|
16
|
+
l2.should_receive(:on_my_event).with("DATA")
|
17
|
+
t.register_listener(:my_event, l1)
|
18
|
+
t.register_listener(:my_event, l2)
|
19
|
+
r = t.emit_event(:my_event, "DATA")
|
20
|
+
r.should eq ["OK 1!", "OK 2!"]
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CultomePlayer::Media do
|
4
|
+
let(:t){ TestClass.new }
|
5
|
+
|
6
|
+
describe 'parse mp3 information' do
|
7
|
+
before :each do
|
8
|
+
@info = t.extract_from_mp3("#{test_folder}/uno/uno.mp3")
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'read name' do
|
12
|
+
@info[:name].should_not be_nil
|
13
|
+
@info[:name].should_not be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'read album' do
|
17
|
+
@info[:album].should_not be_nil
|
18
|
+
@info[:album].should_not be_empty
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'read genre' do
|
22
|
+
@info[:genre].should_not be_nil
|
23
|
+
@info[:genre].should_not be_empty
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'read track' do
|
27
|
+
@info[:track].should_not be_nil
|
28
|
+
@info[:track].should > 0
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'read year' do
|
32
|
+
@info[:year].should_not be_nil
|
33
|
+
@info[:year].should > 0
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'read duration' do
|
37
|
+
@info[:duration].should_not be_nil
|
38
|
+
@info[:duration].should > 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CultomePlayer::Player::Adapter::Mpg123 do
|
4
|
+
let(:t){ TestClass.new }
|
5
|
+
let(:song) do
|
6
|
+
s = Song.new
|
7
|
+
s.stub(:path){'/duck/path'}
|
8
|
+
s
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'can check if player is running' do
|
12
|
+
t.should respond_to :player_running?
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'start the player if is not running' do
|
16
|
+
t.should_receive :start_player
|
17
|
+
t.should_not be_player_running
|
18
|
+
t.play_in_player song
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with active playback' do
|
22
|
+
before :each do
|
23
|
+
t.play_in_player song
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'pause a song' do
|
27
|
+
t.should_receive(:send_to_player).with('pause')
|
28
|
+
t.pause_in_player
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'stops a song' do
|
32
|
+
t.should_receive(:send_to_player).with('stop')
|
33
|
+
t.stop_in_player
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'resume a paused song' do
|
37
|
+
t.pause_in_player
|
38
|
+
t.should_receive(:send_to_player).with("pause")
|
39
|
+
t.resume_in_player
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'resume a stopped song' do
|
43
|
+
t.stop_in_player
|
44
|
+
t.should_receive(:start_player)
|
45
|
+
t.play_in_player song
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'running actual mpg123 player', mplayer: true do
|
50
|
+
it 'dont show the initial text from mpg123' do
|
51
|
+
th = Thread.new do
|
52
|
+
class MplayerTest
|
53
|
+
include CultomePlayer
|
54
|
+
end
|
55
|
+
|
56
|
+
song1 = double(:song1, path: "/home/csoria/music/unknown/Torches/02 Pumped Up Kicks.mp3")
|
57
|
+
song2 = double(:song2, path: "/home/csoria/music/unknown/Torches/07 Houdini.mp3")
|
58
|
+
p = MplayerTest.new
|
59
|
+
p.prepare_environment(:rspec)
|
60
|
+
|
61
|
+
puts "Primera cancion..."
|
62
|
+
p.play_in_player(song1)
|
63
|
+
i = 0
|
64
|
+
while i < 3
|
65
|
+
sleep 1
|
66
|
+
i += 1
|
67
|
+
end
|
68
|
+
|
69
|
+
puts "Segunda cancion(running: #{p.player_running?})..."
|
70
|
+
p.play_in_player(song2)
|
71
|
+
i = 0
|
72
|
+
while i < 3
|
73
|
+
sleep 1
|
74
|
+
i += 1
|
75
|
+
end
|
76
|
+
puts "Terminado!"
|
77
|
+
end # Thread
|
78
|
+
|
79
|
+
th.join
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|