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
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'readline'
|
2
|
+
|
3
|
+
module CultomePlayer::Command
|
4
|
+
module Reader
|
5
|
+
|
6
|
+
# Display a prompt and read user input.
|
7
|
+
#
|
8
|
+
# @param prompt [String] The message to display to user for arcking for input.
|
9
|
+
# @return [String] The user input readed.
|
10
|
+
def read_command(prompt)
|
11
|
+
command_reader.readline(prompt, true)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Lazy getter for readline object.
|
15
|
+
#
|
16
|
+
# @return [Readline] The readline object
|
17
|
+
def command_reader
|
18
|
+
return Readline if @command_reader_initialized
|
19
|
+
|
20
|
+
Readline.completion_append_character = ""
|
21
|
+
Readline.basic_word_break_characters = Readline.basic_word_break_characters.delete("@")
|
22
|
+
Readline.completion_proc = completion_proc
|
23
|
+
@command_reader_initialized = true
|
24
|
+
return Readline
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def completion_proc
|
30
|
+
proc do |word|
|
31
|
+
if Readline.line_buffer.empty?
|
32
|
+
# linea en blanco y no sabe los comandos
|
33
|
+
options = semantics.keys #return
|
34
|
+
else
|
35
|
+
tks = Readline.line_buffer.split
|
36
|
+
if tks.length == 1
|
37
|
+
options = complete_action(tks[0], word)
|
38
|
+
elsif tks.length > 1
|
39
|
+
options = complete_parameter(tks[0], word)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
options = [] if options.nil?
|
44
|
+
options << word if options.empty?
|
45
|
+
options << " " if options.all?{|o| o.start_with?("<")}
|
46
|
+
options # final return
|
47
|
+
end # proc
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_command_param_options(cmd, word)
|
51
|
+
if word.empty?
|
52
|
+
# completa! mostramos los parametros disponibles para el comando
|
53
|
+
if semantics.keys.include?(cmd)
|
54
|
+
# mostramos las opciones de parametros IFF acepta parametros
|
55
|
+
params = semantics[cmd].source.gsub(/^\^literal/, '').gsub(/\[\\s\][+*]/, "").gsub(/[()*$]/, '')
|
56
|
+
|
57
|
+
params.split(/[| ]/).collect{|p| "<#{p}>"} unless params.empty?
|
58
|
+
end
|
59
|
+
else
|
60
|
+
yield if block_given?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def complete_parameter(cmd, word)
|
65
|
+
options = get_command_param_options(cmd, word) do
|
66
|
+
# esta acompletando un parametro
|
67
|
+
if word.start_with?("/") || word.start_with?("~/")
|
68
|
+
expanded_path = File.expand_path(word)
|
69
|
+
expanded_path += "/" if File.directory?(expanded_path)
|
70
|
+
Dir[expanded_path + "*"].grep(/^#{Regexp.escape(expanded_path)}/).collect{|d| "#{d}/"}
|
71
|
+
elsif word.start_with?("@")
|
72
|
+
%w{@library @search @playlist @history @queue @song @artist @album @drives}.grep(/^#{word}/)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def complete_action(cmd, word)
|
78
|
+
# escribio una parabra..
|
79
|
+
get_command_param_options(cmd, word) do
|
80
|
+
# incompleta! require acompletar el action actual
|
81
|
+
semantics.keys.grep(/^#{Regexp.escape(Readline.line_buffer)}/).collect{|s| "#{s} "}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
module CultomePlayer
|
5
|
+
module Environment
|
6
|
+
|
7
|
+
# Get the db_adapter environment configuration value.
|
8
|
+
#
|
9
|
+
# @return [String] The db_adapter value for teh selected environment.
|
10
|
+
def db_adapter
|
11
|
+
env_config['db_adapter'] || raise('environment problem:environment information not loaded')
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get the db_file environment configuration value.
|
15
|
+
#
|
16
|
+
# @return [String] The db_file value for teh selected environment.
|
17
|
+
def db_file
|
18
|
+
env_config['db_file'] || raise('environment problem:environment information not loaded')
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get the db_log_file environment configuration value.
|
22
|
+
#
|
23
|
+
# @return [String] The db_log_file value for teh selected environment.
|
24
|
+
def db_log_file
|
25
|
+
env_config['db_log_file'] || raise('environment problem:environment information not loaded')
|
26
|
+
end
|
27
|
+
|
28
|
+
# Get the file_types environment configuration value.
|
29
|
+
#
|
30
|
+
# @return [String] The file_types value for teh selected environment.
|
31
|
+
def file_types
|
32
|
+
env_config['file_types'] || raise('environment problem:environment information not loaded')
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get the config_file environment configuration value.
|
36
|
+
#
|
37
|
+
# @return [String] The config_file value for teh selected environment.
|
38
|
+
def config_file
|
39
|
+
env_config['config_file'] || raise('environment problem:environment information not loaded')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get the mplayer_pipe environment configuration value.
|
43
|
+
#
|
44
|
+
# @return [String] The mplayer_pipe value for teh selected environment.
|
45
|
+
def mplayer_pipe
|
46
|
+
env_config['mplayer_pipe'] || raise('environment problem:environment information not loaded')
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get the stdout (not STDOUT) for the player.
|
50
|
+
#
|
51
|
+
# @return [IO] The stdout for the player.
|
52
|
+
def stdout
|
53
|
+
STDOUT
|
54
|
+
end
|
55
|
+
|
56
|
+
# Gets the player configurations.
|
57
|
+
#
|
58
|
+
# @return [Hash] Player configuration.
|
59
|
+
def player_config
|
60
|
+
@player_config ||= {}
|
61
|
+
end
|
62
|
+
|
63
|
+
# Gets the environment configurations.
|
64
|
+
#
|
65
|
+
# @return [Hash] Environment configuration.
|
66
|
+
def env_config
|
67
|
+
@env_config ||= {}
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get the current environment name.
|
71
|
+
#
|
72
|
+
# @return [Symbol] The current environment name.
|
73
|
+
def current_env
|
74
|
+
@current_env
|
75
|
+
end
|
76
|
+
|
77
|
+
# Extract the configuration for the environment and setup valriables.
|
78
|
+
#
|
79
|
+
# @param env [Symbol] The name of the environment to load.
|
80
|
+
# @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
|
85
|
+
raise 'environment problem:environment not found' if @env_config.nil?
|
86
|
+
expand_paths @env_config
|
87
|
+
create_required_files @env_config
|
88
|
+
load_master_config @env_config['config_file']
|
89
|
+
check_db_schema if check_db
|
90
|
+
end
|
91
|
+
|
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}]") }
|
98
|
+
end
|
99
|
+
|
100
|
+
def load_master_config(config_file)
|
101
|
+
@player_config = YAML.load_file(config_file) || {}
|
102
|
+
@player_config['main'] ||= {}
|
103
|
+
end
|
104
|
+
|
105
|
+
def create_required_files(env_config)
|
106
|
+
env_config.each do |k,v|
|
107
|
+
if k.end_with?('_file')
|
108
|
+
unless File.exist?(v)
|
109
|
+
%x[mkdir -p '#{File.dirname(v)}' && touch '#{v}']
|
110
|
+
raise 'environment problem:cannot create required files' unless $?.success?
|
111
|
+
end
|
112
|
+
elsif k.end_with?('_pipe')
|
113
|
+
unless File.exist?(v)
|
114
|
+
%x[mkfifo '#{v}']
|
115
|
+
raise 'environment problem:cannot create required pipe' unless $?.success?
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def expand_paths(env_config)
|
122
|
+
env_config.each do |k,v|
|
123
|
+
if k.end_with?('_file') || k.end_with?('_pipe')
|
124
|
+
env_config[k] = File.expand_path(v)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module CultomePlayer
|
2
|
+
module Events
|
3
|
+
|
4
|
+
# Lazy getter of registered event listeners.
|
5
|
+
#
|
6
|
+
# @return [Hash] With event names as the keys and values are the listeners registered to that event.
|
7
|
+
def listeners
|
8
|
+
@listeners ||= Hash.new{|h,k| h[k] = [] }
|
9
|
+
end
|
10
|
+
|
11
|
+
# Register a listener to an event.
|
12
|
+
#
|
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
|
19
|
+
end
|
20
|
+
|
21
|
+
# Broadcast an event to all the registered listeners.
|
22
|
+
#
|
23
|
+
# @param event [Symbol] The event name.
|
24
|
+
# @param data [Array] The information sended to the listeners.
|
25
|
+
def emit_event(event, *data)
|
26
|
+
listeners[event].collect{|l| l.send("on_#{event}".to_sym, *data) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'taglib'
|
2
|
+
|
3
|
+
module CultomePlayer
|
4
|
+
module Media
|
5
|
+
|
6
|
+
# Get information from ID3 tags in a mp3.
|
7
|
+
#
|
8
|
+
# @param filepath [String] The absolute path to the mp3 file.
|
9
|
+
# @param opc [Hash] Additional parameters. Actually only :library_path is supported.
|
10
|
+
# @return [Hash] With information extracted from ID3 tags.
|
11
|
+
def extract_from_mp3(filepath, opc={})
|
12
|
+
info = nil
|
13
|
+
TagLib::FileRef.open(filepath) do |mp3|
|
14
|
+
unless mp3.nil?
|
15
|
+
info = {
|
16
|
+
# file information
|
17
|
+
file_path: filepath,
|
18
|
+
library_path: opc[:library_path],
|
19
|
+
# song information
|
20
|
+
album: mp3.tag.album,
|
21
|
+
artist: mp3.tag.artist,
|
22
|
+
genre: mp3.tag.genre,
|
23
|
+
name: mp3.tag.title,
|
24
|
+
track: mp3.tag.track,
|
25
|
+
year: mp3.tag.year,
|
26
|
+
duration: mp3.audio_properties.length,
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
# si no se encontro nombre de la cancion en las etiquestas, usamos el nombre del archivo
|
31
|
+
info[:name] = filepath.split('/').last if info[:name].nil?
|
32
|
+
# limpiamos la informacion un poco
|
33
|
+
return polish_mp3_info(info)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def polish_mp3_info(info)
|
39
|
+
[:genre, :name, :artist, :album].each{|k| info[k] = info[k].downcase.strip.titleize unless info[k].nil? }
|
40
|
+
[:track, :year].each{|k| info[k] = info[k].to_i if info[k] =~ /\A[\d]+\Z/ }
|
41
|
+
info[:duration] = info[:duration].to_i
|
42
|
+
|
43
|
+
return info
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'cultome_player/utils'
|
2
|
+
|
3
|
+
require 'cultome_player/objects/command'
|
4
|
+
require 'cultome_player/objects/parameter'
|
5
|
+
require 'cultome_player/objects/response'
|
6
|
+
require 'cultome_player/objects/song'
|
7
|
+
require 'cultome_player/objects/artist'
|
8
|
+
require 'cultome_player/objects/album'
|
9
|
+
require 'cultome_player/objects/genre'
|
10
|
+
require 'cultome_player/objects/drive'
|
11
|
+
|
12
|
+
module CultomePlayer
|
13
|
+
module Objects
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module CultomePlayer
|
4
|
+
module Objects
|
5
|
+
# The ActiveRecord model for Album objects.
|
6
|
+
class Album < ActiveRecord::Base
|
7
|
+
has_many :songs
|
8
|
+
has_many :artists, through: :songs
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
str = c4(":::: Album: ")
|
12
|
+
str += c13(self.name)
|
13
|
+
str += c4(" \\ Artist: ")
|
14
|
+
unless self.artists.nil? || self.artists.empty?
|
15
|
+
str += c11(self.artists.uniq.collect{|a| a.name}.join(', '))
|
16
|
+
end
|
17
|
+
str += c4(" ::::")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module CultomePlayer
|
4
|
+
module Objects
|
5
|
+
# The ActiveRecord model for Artist objects.
|
6
|
+
class Artist < ActiveRecord::Base
|
7
|
+
has_many :songs
|
8
|
+
has_many :albums, through: :songs
|
9
|
+
has_many :similars, as: :similar
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
str = c4(":::: Artist: ")
|
13
|
+
str += c11(self.name)
|
14
|
+
str += c4(" ::::")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module CultomePlayer
|
2
|
+
module Objects
|
3
|
+
class Command
|
4
|
+
attr_reader :action
|
5
|
+
attr_reader :parameters
|
6
|
+
|
7
|
+
def initialize(action, parameters)
|
8
|
+
@action = action[:value]
|
9
|
+
@parameters = parameters.collect{|p| Parameter.new(p) }
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the parameters, optionally filtered by type
|
13
|
+
#
|
14
|
+
# @param type [Symbol] Parameter type to filter the results
|
15
|
+
# @return [List<Parameter>] The parameters associated with the command, optionally filtered.
|
16
|
+
def params(type=nil)
|
17
|
+
return @parameters if type.nil?
|
18
|
+
@parameters.select{|p| p.type == type}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a map that contains parameter type as key and a list of the parameters of that type as value.
|
22
|
+
#
|
23
|
+
# @return [Hash<Symbol, List<Parameter>>] Parameters grouped by type.
|
24
|
+
def params_groups
|
25
|
+
@parameters.collect{|p| p.type }.each_with_object({}){|type,acc| acc[type] = params(type) }
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns a list with only the parameters values of certain type.
|
29
|
+
#
|
30
|
+
# @param type [Symbol] The type of parameters.
|
31
|
+
# @return [List<Object>] The values of the parameters.
|
32
|
+
def params_values(type)
|
33
|
+
params(type).map{|p| p.value }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module CultomePlayer
|
4
|
+
module Objects
|
5
|
+
# The ActiveRecord model for Drive objects.
|
6
|
+
class Drive < ActiveRecord::Base
|
7
|
+
has_many :songs
|
8
|
+
|
9
|
+
def connected?
|
10
|
+
connected
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
str = c4(":::: Drive: ")
|
15
|
+
str += c14(self.name)
|
16
|
+
str += c4(" => ")
|
17
|
+
str += c14(self.songs.size.to_s)
|
18
|
+
str += c4(" songs => ")
|
19
|
+
str += c14(self.path)
|
20
|
+
str += c4(" => ")
|
21
|
+
str += connected ? c3("Online") : c2("Offline")
|
22
|
+
str += c4(" ::::")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module CultomePlayer
|
4
|
+
module Objects
|
5
|
+
# The ActiveRecord model for Genre objects.
|
6
|
+
class Genre < ActiveRecord::Base
|
7
|
+
has_and_belongs_to_many :songs
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
str = c4(":::: Genre: ")
|
11
|
+
str += c15(self.name)
|
12
|
+
str += c4(" ::::")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module CultomePlayer
|
2
|
+
module Objects
|
3
|
+
class Parameter
|
4
|
+
include CultomePlayer::Utils
|
5
|
+
|
6
|
+
# Initialize a parameter with the data provided.
|
7
|
+
#
|
8
|
+
# @param data [Hash] Contains the keys :criteria, :value, :type
|
9
|
+
def initialize(data)
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
# Get the criteria asocciated with the parameter, if any.
|
14
|
+
def criteria
|
15
|
+
return nil if @data[:criteria].nil?
|
16
|
+
@data[:criteria].to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the value associated with the parameter in its appropiated type.
|
20
|
+
#
|
21
|
+
# @return [Object] The value of the parameter.
|
22
|
+
def value
|
23
|
+
return is_true_value?(@data[:value]) if @data[:type] == :boolean
|
24
|
+
return @data[:value].to_i if @data[:type] == :number
|
25
|
+
return @data[:value].to_sym if @data[:type] == :object
|
26
|
+
@data[:value]
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the type associated with the parameter.
|
30
|
+
#
|
31
|
+
# @return [Symbol] The type of the parameter.
|
32
|
+
def type
|
33
|
+
@data[:type]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|