cultome_player 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +24 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +7 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +325 -0
  9. data/Rakefile +8 -0
  10. data/bin/cultome_player +39 -0
  11. data/config/environment.yml +28 -0
  12. data/cultome_player.gemspec +35 -0
  13. data/db/001_create_schema.rb +58 -0
  14. data/lib/cultome_player.rb +107 -0
  15. data/lib/cultome_player/command.rb +11 -0
  16. data/lib/cultome_player/command/language.rb +61 -0
  17. data/lib/cultome_player/command/processor.rb +165 -0
  18. data/lib/cultome_player/command/reader.rb +86 -0
  19. data/lib/cultome_player/environment.rb +130 -0
  20. data/lib/cultome_player/events.rb +29 -0
  21. data/lib/cultome_player/media.rb +47 -0
  22. data/lib/cultome_player/objects.rb +15 -0
  23. data/lib/cultome_player/objects/album.rb +21 -0
  24. data/lib/cultome_player/objects/artist.rb +18 -0
  25. data/lib/cultome_player/objects/command.rb +37 -0
  26. data/lib/cultome_player/objects/drive.rb +26 -0
  27. data/lib/cultome_player/objects/genre.rb +16 -0
  28. data/lib/cultome_player/objects/parameter.rb +37 -0
  29. data/lib/cultome_player/objects/response.rb +42 -0
  30. data/lib/cultome_player/objects/song.rb +38 -0
  31. data/lib/cultome_player/player.rb +13 -0
  32. data/lib/cultome_player/player/adapter.rb +14 -0
  33. data/lib/cultome_player/player/adapter/mpg123.rb +143 -0
  34. data/lib/cultome_player/player/interactive.rb +56 -0
  35. data/lib/cultome_player/player/interface.rb +13 -0
  36. data/lib/cultome_player/player/interface/basic.rb +96 -0
  37. data/lib/cultome_player/player/interface/builtin_help.rb +368 -0
  38. data/lib/cultome_player/player/interface/extended.rb +199 -0
  39. data/lib/cultome_player/player/interface/helper.rb +300 -0
  40. data/lib/cultome_player/player/playlist.rb +280 -0
  41. data/lib/cultome_player/plugins.rb +23 -0
  42. data/lib/cultome_player/plugins/help.rb +58 -0
  43. data/lib/cultome_player/state_checker.rb +74 -0
  44. data/lib/cultome_player/utils.rb +95 -0
  45. data/lib/cultome_player/version.rb +3 -0
  46. data/spec/config.yml +0 -0
  47. data/spec/cultome_player/command/processor_spec.rb +168 -0
  48. data/spec/cultome_player/command/reader_spec.rb +45 -0
  49. data/spec/cultome_player/cultome_player_spec.rb +17 -0
  50. data/spec/cultome_player/environment_spec.rb +65 -0
  51. data/spec/cultome_player/events_spec.rb +22 -0
  52. data/spec/cultome_player/media_spec.rb +41 -0
  53. data/spec/cultome_player/player/adapter/mpg123_spec.rb +82 -0
  54. data/spec/cultome_player/player/interface/basic_spec.rb +168 -0
  55. data/spec/cultome_player/player/interface/extended/connect_spec.rb +117 -0
  56. data/spec/cultome_player/player/interface/extended/search_spec.rb +90 -0
  57. data/spec/cultome_player/player/interface/extended/show_spec.rb +36 -0
  58. data/spec/cultome_player/player/interface/extended/shuffle_spec.rb +26 -0
  59. data/spec/cultome_player/player/interface/extended_spec.rb +136 -0
  60. data/spec/cultome_player/player/interface/helper_spec.rb +63 -0
  61. data/spec/cultome_player/player/interface_spec.rb +17 -0
  62. data/spec/cultome_player/player/playlist_spec.rb +301 -0
  63. data/spec/cultome_player/plugins/help_spec.rb +21 -0
  64. data/spec/cultome_player/plugins_spec.rb +19 -0
  65. data/spec/cultome_player/utils_spec.rb +15 -0
  66. data/spec/spec_helper.rb +108 -0
  67. data/spec/test/uno/dos/dos.mp3 +0 -0
  68. data/spec/test/uno/dos/tres/tres.mp3 +0 -0
  69. data/spec/test/uno/uno.mp3 +0 -0
  70. data/tasks/console.rake +19 -0
  71. data/tasks/db.rake +19 -0
  72. data/tasks/run.rake +7 -0
  73. metadata +322 -0
@@ -0,0 +1,3 @@
1
+ module CultomePlayer
2
+ VERSION = "2.0.0"
3
+ end
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