cultome_player 2.0.0 → 2.0.2

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -79
  3. data/Rakefile +38 -4
  4. data/bin/cultome_player +16 -4
  5. data/config/environment.yml +4 -0
  6. data/cultome_player.gemspec +8 -1
  7. data/lib/cultome_player.rb +45 -19
  8. data/lib/cultome_player/command/language.rb +3 -4
  9. data/lib/cultome_player/command/processor.rb +9 -7
  10. data/lib/cultome_player/command/reader.rb +11 -2
  11. data/lib/cultome_player/environment.rb +21 -13
  12. data/lib/cultome_player/events.rb +7 -7
  13. data/lib/cultome_player/objects/album.rb +9 -2
  14. data/lib/cultome_player/objects/artist.rb +9 -2
  15. data/lib/cultome_player/objects/command.rb +10 -1
  16. data/lib/cultome_player/objects/drive.rb +4 -1
  17. data/lib/cultome_player/objects/genre.rb +4 -1
  18. data/lib/cultome_player/objects/parameter.rb +21 -1
  19. data/lib/cultome_player/objects/response.rb +5 -1
  20. data/lib/cultome_player/objects/song.rb +9 -4
  21. data/lib/cultome_player/player/adapter/mpg123.rb +3 -4
  22. data/lib/cultome_player/player/interactive.rb +67 -11
  23. data/lib/cultome_player/player/interface/basic.rb +13 -9
  24. data/lib/cultome_player/player/interface/extended.rb +26 -12
  25. data/lib/cultome_player/player/interface/helper.rb +73 -9
  26. data/lib/cultome_player/plugins.rb +44 -18
  27. data/lib/cultome_player/plugins/alias.rb +85 -0
  28. data/lib/cultome_player/plugins/gestures.rb +90 -0
  29. data/lib/cultome_player/plugins/help.rb +4 -4
  30. data/lib/cultome_player/plugins/keyboard_special_keys.rb +22 -0
  31. data/lib/cultome_player/plugins/points.rb +51 -0
  32. data/lib/cultome_player/utils.rb +117 -7
  33. data/lib/cultome_player/version.rb +1 -1
  34. data/xbindkeys/xbindkeysrc +12 -0
  35. metadata +37 -89
  36. data/.coveralls.yml +0 -1
  37. data/.gitignore +0 -24
  38. data/.rspec +0 -2
  39. data/.travis.yml +0 -7
  40. data/db/001_create_schema.rb +0 -58
  41. data/spec/config.yml +0 -0
  42. data/spec/cultome_player/command/processor_spec.rb +0 -168
  43. data/spec/cultome_player/command/reader_spec.rb +0 -45
  44. data/spec/cultome_player/cultome_player_spec.rb +0 -17
  45. data/spec/cultome_player/environment_spec.rb +0 -65
  46. data/spec/cultome_player/events_spec.rb +0 -22
  47. data/spec/cultome_player/media_spec.rb +0 -41
  48. data/spec/cultome_player/player/adapter/mpg123_spec.rb +0 -82
  49. data/spec/cultome_player/player/interface/basic_spec.rb +0 -168
  50. data/spec/cultome_player/player/interface/extended/connect_spec.rb +0 -117
  51. data/spec/cultome_player/player/interface/extended/search_spec.rb +0 -90
  52. data/spec/cultome_player/player/interface/extended/show_spec.rb +0 -36
  53. data/spec/cultome_player/player/interface/extended/shuffle_spec.rb +0 -26
  54. data/spec/cultome_player/player/interface/extended_spec.rb +0 -136
  55. data/spec/cultome_player/player/interface/helper_spec.rb +0 -63
  56. data/spec/cultome_player/player/interface_spec.rb +0 -17
  57. data/spec/cultome_player/player/playlist_spec.rb +0 -301
  58. data/spec/cultome_player/plugins/help_spec.rb +0 -21
  59. data/spec/cultome_player/plugins_spec.rb +0 -19
  60. data/spec/cultome_player/utils_spec.rb +0 -15
  61. data/spec/spec_helper.rb +0 -108
  62. data/spec/test/uno/dos/dos.mp3 +0 -0
  63. data/spec/test/uno/dos/tres/tres.mp3 +0 -0
  64. data/spec/test/uno/uno.mp3 +0 -0
  65. data/tasks/console.rake +0 -19
  66. data/tasks/db.rake +0 -19
  67. data/tasks/run.rake +0 -7
@@ -8,7 +8,16 @@ module CultomePlayer::Command
8
8
  # @param prompt [String] The message to display to user for arcking for input.
9
9
  # @return [String] The user input readed.
10
10
  def read_command(prompt)
11
- command_reader.readline(prompt, true)
11
+ input = command_reader.readline(c5(prompt), true)
12
+
13
+ # evitamos que comando consecutivos repetidos o vacios queden en el historial
14
+ if input.empty?
15
+ command_reader::HISTORY.pop
16
+ elsif command_reader::HISTORY.to_a.reverse[1] == input
17
+ command_reader::HISTORY.pop
18
+ end
19
+
20
+ return input
12
21
  end
13
22
 
14
23
  # Lazy getter for readline object.
@@ -69,7 +78,7 @@ module CultomePlayer::Command
69
78
  expanded_path += "/" if File.directory?(expanded_path)
70
79
  Dir[expanded_path + "*"].grep(/^#{Regexp.escape(expanded_path)}/).collect{|d| "#{d}/"}
71
80
  elsif word.start_with?("@")
72
- %w{@library @search @playlist @history @queue @song @artist @album @drives}.grep(/^#{word}/)
81
+ %w{@playlist @current @history @queue @search @song @artist @album @drives @artists @albums @genres @library @recently_added @recently_played @most_played @less_played @populars}.grep(/^#{word}/)
73
82
  end
74
83
  end
75
84
  end
@@ -1,5 +1,4 @@
1
1
  require 'yaml'
2
- require 'rake'
3
2
 
4
3
  module CultomePlayer
5
4
  module Environment
@@ -39,6 +38,13 @@ module CultomePlayer
39
38
  env_config['config_file'] || raise('environment problem:environment information not loaded')
40
39
  end
41
40
 
41
+ # Get the command_pipe environment configuration value.
42
+ #
43
+ # @return [String] The command_pipe value for teh selected environment.
44
+ def command_pipe
45
+ env_config['command_pipe'] || raise('environment problem:environment information not loaded')
46
+ end
47
+
42
48
  # Get the mplayer_pipe environment configuration value.
43
49
  #
44
50
  # @return [String] The mplayer_pipe value for teh selected environment.
@@ -74,29 +80,31 @@ module CultomePlayer
74
80
  @current_env
75
81
  end
76
82
 
83
+ def load_environment_properties(env)
84
+ env_config = YAML.load_file File.expand_path('config/environment.yml', File.join(File.dirname(__FILE__), "../.."))
85
+ @env_config = env_config[env.to_s]
86
+ expand_paths @env_config
87
+ @current_env = env.to_sym
88
+ return @env_config
89
+ end
90
+
77
91
  # Extract the configuration for the environment and setup valriables.
78
92
  #
79
93
  # @param env [Symbol] The name of the environment to load.
80
94
  # @param check_db [Boolean] Flag to decide if the database schema should be checked.
81
- def prepare_environment(env, check_db=true)
82
- env_config = YAML.load_file File.expand_path('config/environment.yml')
83
- @env_config = env_config[env.to_s]
84
- @current_env = env.to_sym
95
+ def prepare_environment(env)
96
+ load_environment_properties(env)
85
97
  raise 'environment problem:environment not found' if @env_config.nil?
86
- expand_paths @env_config
87
98
  create_required_files @env_config
88
99
  load_master_config @env_config['config_file']
89
- check_db_schema if check_db
90
100
  end
91
101
 
92
- private
93
-
94
- def check_db_schema
95
- Rake.load_rakefile 'Rakefile'
96
- Rake.application.load_imports
97
- swallow_stdout{ Rake.application.invoke_task("db:create[#{current_env}]") }
102
+ def save_player_configurations
103
+ open(config_file, 'w'){|f| f.write player_config.to_yaml }
98
104
  end
99
105
 
106
+ private
107
+
100
108
  def load_master_config(config_file)
101
109
  @player_config = YAML.load_file(config_file) || {}
102
110
  @player_config['main'] ||= {}
@@ -8,14 +8,14 @@ module CultomePlayer
8
8
  @listeners ||= Hash.new{|h,k| h[k] = [] }
9
9
  end
10
10
 
11
- # Register a listener to an event.
11
+ # Register a callback to an event.
12
12
  #
13
13
  # @param event [Symbol] The event name.
14
- # @param listener [Object] Implements a callback with the name on_<event name>.
15
- # @return [Object] The registered listener.
16
- def register_listener(event, listener)
17
- listeners[event] << listener
18
- return listener
14
+ # @param callback [Object] Implements a callback with the name on_<event name>.
15
+ # @return [Object] The registered callback.
16
+ def register_listener(event, &callback)
17
+ listeners[event] << callback
18
+ return callback
19
19
  end
20
20
 
21
21
  # Broadcast an event to all the registered listeners.
@@ -23,7 +23,7 @@ module CultomePlayer
23
23
  # @param event [Symbol] The event name.
24
24
  # @param data [Array] The information sended to the listeners.
25
25
  def emit_event(event, *data)
26
- listeners[event].collect{|l| l.send("on_#{event}".to_sym, *data) }
26
+ listeners[event].collect{|l| l.call(*data) }
27
27
  end
28
28
  end
29
29
  end
@@ -4,18 +4,25 @@ module CultomePlayer
4
4
  module Objects
5
5
  # The ActiveRecord model for Album objects.
6
6
  class Album < ActiveRecord::Base
7
+
8
+ include CultomePlayer::Utils
9
+
7
10
  has_many :songs
8
11
  has_many :artists, through: :songs
9
12
 
10
13
  def to_s
11
14
  str = c4(":::: Album: ")
12
- str += c13(self.name)
15
+ str += c16(self.name)
13
16
  str += c4(" \\ Artist: ")
14
17
  unless self.artists.nil? || self.artists.empty?
15
18
  str += c11(self.artists.uniq.collect{|a| a.name}.join(', '))
16
19
  end
17
20
  str += c4(" ::::")
18
21
  end
22
+
23
+ def readonly?
24
+ false
25
+ end
19
26
  end
20
27
  end
21
- end
28
+ end
@@ -4,15 +4,22 @@ module CultomePlayer
4
4
  module Objects
5
5
  # The ActiveRecord model for Artist objects.
6
6
  class Artist < ActiveRecord::Base
7
+
8
+ include CultomePlayer::Utils
9
+
7
10
  has_many :songs
8
11
  has_many :albums, through: :songs
9
12
  has_many :similars, as: :similar
10
13
 
11
14
  def to_s
12
15
  str = c4(":::: Artist: ")
13
- str += c11(self.name)
16
+ str += c15(self.name)
14
17
  str += c4(" ::::")
15
18
  end
19
+
20
+ def readonly?
21
+ false
22
+ end
16
23
  end
17
24
  end
18
- end
25
+ end
@@ -7,6 +7,11 @@ module CultomePlayer
7
7
  def initialize(action, parameters)
8
8
  @action = action[:value]
9
9
  @parameters = parameters.collect{|p| Parameter.new(p) }
10
+ @no_history = params(:literal).any?{|p| p.value == 'no_history'}
11
+ end
12
+
13
+ def history?
14
+ !@no_history
10
15
  end
11
16
 
12
17
  # Returns the parameters, optionally filtered by type
@@ -32,6 +37,10 @@ module CultomePlayer
32
37
  def params_values(type)
33
38
  params(type).map{|p| p.value }
34
39
  end
40
+
41
+ def to_s
42
+ "#{action} #{@parameters.join(" ")}"
43
+ end
35
44
  end
36
45
  end
37
- end
46
+ end
@@ -4,6 +4,9 @@ module CultomePlayer
4
4
  module Objects
5
5
  # The ActiveRecord model for Drive objects.
6
6
  class Drive < ActiveRecord::Base
7
+
8
+ include CultomePlayer::Utils
9
+
7
10
  has_many :songs
8
11
 
9
12
  def connected?
@@ -23,4 +26,4 @@ module CultomePlayer
23
26
  end
24
27
  end
25
28
  end
26
- end
29
+ end
@@ -4,6 +4,9 @@ module CultomePlayer
4
4
  module Objects
5
5
  # The ActiveRecord model for Genre objects.
6
6
  class Genre < ActiveRecord::Base
7
+
8
+ include CultomePlayer::Utils
9
+
7
10
  has_and_belongs_to_many :songs
8
11
 
9
12
  def to_s
@@ -13,4 +16,4 @@ module CultomePlayer
13
16
  end
14
17
  end
15
18
  end
16
- end
19
+ end
@@ -23,6 +23,13 @@ module CultomePlayer
23
23
  return is_true_value?(@data[:value]) if @data[:type] == :boolean
24
24
  return @data[:value].to_i if @data[:type] == :number
25
25
  return @data[:value].to_sym if @data[:type] == :object
26
+ return raw_value
27
+ end
28
+
29
+ # Return the value as the user input typed (no conversions).
30
+ #
31
+ # @return [String] The values of the parameter as the user typed.
32
+ def raw_value
26
33
  @data[:value]
27
34
  end
28
35
 
@@ -32,6 +39,19 @@ module CultomePlayer
32
39
  def type
33
40
  @data[:type]
34
41
  end
42
+
43
+ def to_s
44
+ return case @data[:type]
45
+ when :literal then @data[:value]
46
+ when :criteria then "#{@data[:criteria]}:#{@data[:value]}"
47
+ when :number then @data[:value]
48
+ when :object then "@#{@data[:value]}"
49
+ when :boolean then @data[:value]
50
+ when :path then @data[:value]
51
+ when :bubble then @data[:value]
52
+ else value
53
+ end
54
+ end
35
55
  end
36
56
  end
37
- end
57
+ end
@@ -8,7 +8,7 @@ module CultomePlayer
8
8
  @data = data
9
9
 
10
10
  @data.each do |k,v|
11
- self.class.send(:define_method, k) do
11
+ self.singleton_class.send(:define_method, k) do
12
12
  v
13
13
  end
14
14
  end
@@ -37,6 +37,10 @@ module CultomePlayer
37
37
  data = @data.merge response.data
38
38
  return Response.new(type, data)
39
39
  end
40
+
41
+ def to_s
42
+ "Response #{success? ? 'successful' : 'failed'} => #{@data}"
43
+ end
40
44
  end
41
45
  end
42
46
  end
@@ -2,8 +2,12 @@ require 'active_record'
2
2
 
3
3
  module CultomePlayer
4
4
  module Objects
5
+
5
6
  # The ActiveRecord model for Song objects.
6
7
  class Song < ActiveRecord::Base
8
+
9
+ include CultomePlayer::Utils
10
+
7
11
  belongs_to :artist
8
12
  belongs_to :album
9
13
  has_and_belongs_to_many :genres
@@ -11,6 +15,7 @@ module CultomePlayer
11
15
  has_many :similars, as: :similar
12
16
 
13
17
  scope :connected, -> {joins(:drive).where('drives.connected' => true)}
18
+
14
19
  # Get the full path to the song file.
15
20
  #
16
21
  # @return [String] The full path to the song file.
@@ -20,19 +25,19 @@ module CultomePlayer
20
25
 
21
26
  def to_s
22
27
  str = c4(":::: Song: ")
23
- str += c10(self.name)
28
+ str += c14(self.name)
24
29
 
25
30
  unless self.artist.nil?
26
31
  str += c4(" \\ Artist: ")
27
- str += c11(self.artist.name)
32
+ str += c15(self.artist.name)
28
33
  end
29
34
 
30
35
  unless self.album.nil?
31
36
  str += c4(" \\ Album: ")
32
- str += c13(self.album.name)
37
+ str += c16(self.album.name)
33
38
  end
34
39
  str += c4(" ::::")
35
40
  end
36
41
  end
37
42
  end
38
- end
43
+ end
@@ -109,16 +109,15 @@ module CultomePlayer::Player::Adapter
109
109
  when 0 # stopped
110
110
  @playing = @paused = false
111
111
  @stopped = true
112
- emit_event(:playback_finish) unless @user_stopped
113
- @user_stopped = false
112
+ @user_stopped ? emit_event(:playback_stopped, current_song) : emit_event(:playback_finish, current_song)
114
113
  when 1 # paused
115
114
  @stopped = @playing = false
116
115
  @paused = true
117
- emit_event(:playback_paused)
116
+ emit_event(:playback_paused, current_song)
118
117
  when 2 # unpaused
119
118
  @playing = true
120
119
  @paused = @stopped = false
121
- emit_event(:playback_resumed)
120
+ emit_event(:playback_resumed, current_song)
122
121
  end
123
122
  when /^@F ([\d]+) ([\d]+) ([\d.]+) ([\d.]+)$/
124
123
  @playback_time_position = $3.to_f
@@ -6,18 +6,49 @@ module CultomePlayer::Player
6
6
  # Begin a REP loop inside player.
7
7
  def begin_session
8
8
  @in_session = true
9
- display "Cultome Player v#{CultomePlayer::VERSION}"
9
+ display c5("Cultome Player v#{CultomePlayer::VERSION}")
10
+ emit_event(:interactive_session_started)
10
11
 
11
12
  while in_session?
12
13
  begin
13
- r = execute read_command(PROMPT)
14
- show_response(r)
14
+ cmd = read_command(PROMPT)
15
+ execute_interactively cmd
15
16
  rescue Exception => e
16
- display e.message
17
+ show_error(e.message)
18
+ e.backtrace.each{|b| display c3(b) } if current_env == :test
17
19
  end
18
20
  end
19
21
  end
20
22
 
23
+ def execute_interactively(cmd)
24
+ begin
25
+ if cmd.empty?
26
+ # tomamos en ultimo comando
27
+ cmd = last_command
28
+
29
+ else
30
+ # agregamos el comando al historia de la session_history
31
+ session_history << cmd
32
+ # seteamos el ultimo comando ejecutado
33
+ # # seteamos el ultimo comando ejecutado
34
+ set_last_command(cmd)
35
+ end
36
+
37
+ return false if cmd.nil?
38
+
39
+ r = execute cmd
40
+
41
+ if r.size > 1
42
+ display c1("#{r.size} commands were executed, Showing result of the last one.")
43
+ end
44
+
45
+ show_response(r.last)
46
+ rescue Exception => e
47
+ emit_event(:interactive_exception, e)
48
+ raise e
49
+ end
50
+ end
51
+
21
52
  # Check if there is an interactive session in progress.
22
53
  #
23
54
  # @return [Boolean] True if session in progress. False otherwise.
@@ -28,27 +59,52 @@ module CultomePlayer::Player
28
59
  # Terminates a interactive session.
29
60
  def terminate_session
30
61
  @in_session = false
62
+ save_player_configurations
63
+ emit_event(:interactive_session_ended)
64
+ end
65
+
66
+ # Command history of this session
67
+ #
68
+ # @return [Array<Command>] The history of commands of this session.
69
+ def session_history
70
+ @session_history ||= []
71
+ end
72
+
73
+ def set_last_command(cmd)
74
+ @last_command = cmd
75
+ end
76
+
77
+ def last_command
78
+ @last_command
31
79
  end
32
80
 
33
81
  private
34
82
 
83
+ def show_error(msg)
84
+ type, message = msg.split(":")
85
+ display c3("[#{type}] #{message}")
86
+ end
87
+
35
88
  def show_response(r)
89
+ return if r.respond_to?(:no_response)
90
+
36
91
  if r.respond_to?(:response_type)
37
92
  res_obj = r.send(r.response_type)
38
93
  if res_obj.respond_to?(:each)
39
- res_obj.each.with_index do |elem, idx|
40
- display "#{(idx + 1).to_s.ljust(3)} | #{elem.to_s}"
41
- end
94
+ # es una lista
95
+ display to_display_list(res_obj)
42
96
  elsif res_obj.class == String
43
- display res_obj.to_s
97
+ # es un mensaje
98
+ display r.success? ? res_obj : c3(res_obj.to_s)
44
99
  else
45
- display "(((#{res_obj.to_s})))"
100
+ display c3("(((#{res_obj.to_s})))")
46
101
  end
47
102
 
103
+ # Dont has response_type, eg has a message
48
104
  elsif r.respond_to?(:message)
49
- display r.message
105
+ display r.success? ? c15(r.message) : c3(r.message)
50
106
  else
51
- display "!!!#{r}!!!"
107
+ display c3("!!! #{r} !!!")
52
108
  end
53
109
  end
54
110