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.
- checksums.yaml +4 -4
- data/README.md +24 -79
- data/Rakefile +38 -4
- data/bin/cultome_player +16 -4
- data/config/environment.yml +4 -0
- data/cultome_player.gemspec +8 -1
- data/lib/cultome_player.rb +45 -19
- data/lib/cultome_player/command/language.rb +3 -4
- data/lib/cultome_player/command/processor.rb +9 -7
- data/lib/cultome_player/command/reader.rb +11 -2
- data/lib/cultome_player/environment.rb +21 -13
- data/lib/cultome_player/events.rb +7 -7
- data/lib/cultome_player/objects/album.rb +9 -2
- data/lib/cultome_player/objects/artist.rb +9 -2
- data/lib/cultome_player/objects/command.rb +10 -1
- data/lib/cultome_player/objects/drive.rb +4 -1
- data/lib/cultome_player/objects/genre.rb +4 -1
- data/lib/cultome_player/objects/parameter.rb +21 -1
- data/lib/cultome_player/objects/response.rb +5 -1
- data/lib/cultome_player/objects/song.rb +9 -4
- data/lib/cultome_player/player/adapter/mpg123.rb +3 -4
- data/lib/cultome_player/player/interactive.rb +67 -11
- data/lib/cultome_player/player/interface/basic.rb +13 -9
- data/lib/cultome_player/player/interface/extended.rb +26 -12
- data/lib/cultome_player/player/interface/helper.rb +73 -9
- data/lib/cultome_player/plugins.rb +44 -18
- data/lib/cultome_player/plugins/alias.rb +85 -0
- data/lib/cultome_player/plugins/gestures.rb +90 -0
- data/lib/cultome_player/plugins/help.rb +4 -4
- data/lib/cultome_player/plugins/keyboard_special_keys.rb +22 -0
- data/lib/cultome_player/plugins/points.rb +51 -0
- data/lib/cultome_player/utils.rb +117 -7
- data/lib/cultome_player/version.rb +1 -1
- data/xbindkeys/xbindkeysrc +12 -0
- metadata +37 -89
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -24
- data/.rspec +0 -2
- data/.travis.yml +0 -7
- data/db/001_create_schema.rb +0 -58
- data/spec/config.yml +0 -0
- data/spec/cultome_player/command/processor_spec.rb +0 -168
- data/spec/cultome_player/command/reader_spec.rb +0 -45
- data/spec/cultome_player/cultome_player_spec.rb +0 -17
- data/spec/cultome_player/environment_spec.rb +0 -65
- data/spec/cultome_player/events_spec.rb +0 -22
- data/spec/cultome_player/media_spec.rb +0 -41
- data/spec/cultome_player/player/adapter/mpg123_spec.rb +0 -82
- data/spec/cultome_player/player/interface/basic_spec.rb +0 -168
- data/spec/cultome_player/player/interface/extended/connect_spec.rb +0 -117
- data/spec/cultome_player/player/interface/extended/search_spec.rb +0 -90
- data/spec/cultome_player/player/interface/extended/show_spec.rb +0 -36
- data/spec/cultome_player/player/interface/extended/shuffle_spec.rb +0 -26
- data/spec/cultome_player/player/interface/extended_spec.rb +0 -136
- data/spec/cultome_player/player/interface/helper_spec.rb +0 -63
- data/spec/cultome_player/player/interface_spec.rb +0 -17
- data/spec/cultome_player/player/playlist_spec.rb +0 -301
- data/spec/cultome_player/plugins/help_spec.rb +0 -21
- data/spec/cultome_player/plugins_spec.rb +0 -19
- data/spec/cultome_player/utils_spec.rb +0 -15
- data/spec/spec_helper.rb +0 -108
- 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 +0 -19
- data/tasks/db.rake +0 -19
- 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{@
|
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
|
82
|
-
|
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
|
-
|
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
|
11
|
+
# Register a callback to an event.
|
12
12
|
#
|
13
13
|
# @param event [Symbol] The event name.
|
14
|
-
# @param
|
15
|
-
# @return [Object] The registered
|
16
|
-
def register_listener(event,
|
17
|
-
listeners[event] <<
|
18
|
-
return
|
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.
|
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 +=
|
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 +=
|
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.
|
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 +=
|
28
|
+
str += c14(self.name)
|
24
29
|
|
25
30
|
unless self.artist.nil?
|
26
31
|
str += c4(" \\ Artist: ")
|
27
|
-
str +=
|
32
|
+
str += c15(self.artist.name)
|
28
33
|
end
|
29
34
|
|
30
35
|
unless self.album.nil?
|
31
36
|
str += c4(" \\ Album: ")
|
32
|
-
str +=
|
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(:
|
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
|
-
|
14
|
-
|
14
|
+
cmd = read_command(PROMPT)
|
15
|
+
execute_interactively cmd
|
15
16
|
rescue Exception => e
|
16
|
-
|
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
|
-
|
40
|
-
|
41
|
-
end
|
94
|
+
# es una lista
|
95
|
+
display to_display_list(res_obj)
|
42
96
|
elsif res_obj.class == String
|
43
|
-
|
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 "
|
107
|
+
display c3("!!! #{r} !!!")
|
52
108
|
end
|
53
109
|
end
|
54
110
|
|