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