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,28 @@
|
|
1
|
+
user:
|
2
|
+
db_adapter: sqlite3
|
3
|
+
db_file: ~/.cultome/db.dat
|
4
|
+
db_log_file: ~/.cultome/db.log
|
5
|
+
file_types: mp3
|
6
|
+
mplayer_pipe: ~/.cultome/mpctr
|
7
|
+
config_file: ~/.cultome/config.yml
|
8
|
+
memory:
|
9
|
+
db_adapter: sqlite3
|
10
|
+
db_file: /tmp/db.dat
|
11
|
+
db_log_file: /tmp/db.log
|
12
|
+
file_types: mp3
|
13
|
+
mplayer_pipe: /tmp/mpctr
|
14
|
+
config_file: /tmp/config.yml
|
15
|
+
rspec:
|
16
|
+
db_adapter: sqlite3
|
17
|
+
db_file: spec/db.dat
|
18
|
+
db_log_file: spec/db.log
|
19
|
+
file_types: mp3
|
20
|
+
mplayer_pipe: spec/mpctr
|
21
|
+
config_file: spec/config.yml
|
22
|
+
test:
|
23
|
+
db_adapter: sqlite3
|
24
|
+
db_file: ~/tmp/db.dat
|
25
|
+
db_log_file: ~/tmp/db.log
|
26
|
+
file_types: mp3
|
27
|
+
mplayer_pipe: ~/tmp/mpctr
|
28
|
+
config_file: ~/tmp/config.yml
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cultome_player/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "cultome_player"
|
8
|
+
gem.version = CultomePlayer::VERSION
|
9
|
+
gem.summary = "CulToMe Player"
|
10
|
+
gem.description = "A console music library explorer and player"
|
11
|
+
gem.authors = ["Carlos Soria"]
|
12
|
+
gem.email = "cultome@gmail.com"
|
13
|
+
gem.homepage = "https://github.com/cultome/cultome_player"
|
14
|
+
gem.license = "MIT"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.add_runtime_dependency "activerecord"
|
22
|
+
gem.add_runtime_dependency "activesupport"
|
23
|
+
gem.add_runtime_dependency "taglib-ruby"
|
24
|
+
gem.add_runtime_dependency "rb-readline"
|
25
|
+
gem.add_runtime_dependency "sqlite3"
|
26
|
+
gem.add_runtime_dependency "colorize"
|
27
|
+
|
28
|
+
gem.add_development_dependency "rake"
|
29
|
+
gem.add_development_dependency "coveralls"
|
30
|
+
gem.add_development_dependency "rspec"
|
31
|
+
gem.add_development_dependency "bundler"
|
32
|
+
gem.add_development_dependency "database_cleaner"
|
33
|
+
gem.add_development_dependency "pry"
|
34
|
+
gem.add_development_dependency "yard"
|
35
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
class CreateSchema < ActiveRecord::Migration
|
3
|
+
def self.up
|
4
|
+
create_table :songs do |t|
|
5
|
+
t.string :name # If I Had A Gun
|
6
|
+
t.integer :artist_id, default: 0 # Noel Gallagher
|
7
|
+
t.integer :album_id, default: 0 # High Flying Birds
|
8
|
+
t.integer :year # 2011
|
9
|
+
t.integer :track # 3
|
10
|
+
t.integer :duration # 210 sec
|
11
|
+
t.integer :drive_id
|
12
|
+
t.string :relative_path
|
13
|
+
t.integer :points, default: 0
|
14
|
+
t.integer :plays, default: 0
|
15
|
+
t.datetime :last_played_at
|
16
|
+
t.timestamps
|
17
|
+
end
|
18
|
+
|
19
|
+
create_table :albums do |t|
|
20
|
+
t.string :name
|
21
|
+
t.integer :points
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
|
25
|
+
create_table :artists do |t|
|
26
|
+
t.string :name
|
27
|
+
t.integer :points
|
28
|
+
t.timestamps
|
29
|
+
end
|
30
|
+
|
31
|
+
create_table :genres do |t|
|
32
|
+
t.integer :points
|
33
|
+
t.string :name
|
34
|
+
end
|
35
|
+
|
36
|
+
create_table :genres_songs, id: false do |t|
|
37
|
+
t.integer :song_id
|
38
|
+
t.integer :genre_id
|
39
|
+
end
|
40
|
+
|
41
|
+
create_table :drives do |t|
|
42
|
+
t.string :name
|
43
|
+
t.string :path
|
44
|
+
t.boolean :connected, default: true
|
45
|
+
t.timestamps
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.down
|
50
|
+
drop_table :songs
|
51
|
+
drop_table :albums
|
52
|
+
drop_table :artists
|
53
|
+
drop_table :genres
|
54
|
+
drop_table :genres_songs
|
55
|
+
drop_table :drives
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require "cultome_player/version"
|
2
|
+
require "cultome_player/environment"
|
3
|
+
require "cultome_player/objects"
|
4
|
+
require "cultome_player/command"
|
5
|
+
require "cultome_player/player"
|
6
|
+
require "cultome_player/media"
|
7
|
+
require "cultome_player/utils"
|
8
|
+
require "cultome_player/events"
|
9
|
+
require "cultome_player/plugins"
|
10
|
+
require "cultome_player/state_checker"
|
11
|
+
|
12
|
+
module CultomePlayer
|
13
|
+
include Environment
|
14
|
+
include Utils
|
15
|
+
include Objects
|
16
|
+
include Command
|
17
|
+
include Player
|
18
|
+
include Media
|
19
|
+
include Events
|
20
|
+
include Plugins
|
21
|
+
include StateChecker
|
22
|
+
|
23
|
+
# Interpret a user input string as it would be typed in the console.
|
24
|
+
#
|
25
|
+
# @param user_input [String] The user input.
|
26
|
+
# @return [Response] Response object with information about command execution.
|
27
|
+
def execute(user_input)
|
28
|
+
cmd = parse user_input
|
29
|
+
# revisamos si es un built in command o un plugin
|
30
|
+
action = cmd.action
|
31
|
+
plugin_action = "command_#{cmd.action}".to_sym
|
32
|
+
action = plugin_action if respond_to?(plugin_action)
|
33
|
+
|
34
|
+
raise 'invalid command:action unknown' unless respond_to?(action)
|
35
|
+
with_connection do
|
36
|
+
begin
|
37
|
+
send(action, cmd)
|
38
|
+
rescue Exception => e
|
39
|
+
s = e.message.split(":")
|
40
|
+
failure(message: s[0], details: s[1])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Creates a generic response
|
46
|
+
#
|
47
|
+
# @param type [Symbol] The response type.
|
48
|
+
# @param data [Hash] The information that the response will contain.
|
49
|
+
# @return [Response] Response object with information in form of getter methods.
|
50
|
+
def create_response(type, data)
|
51
|
+
data[:response_type] = data.keys.first unless data.has_key?(:response_type)
|
52
|
+
return Response.new(type, data)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Creates a success response. Handy method for #create_response
|
56
|
+
#
|
57
|
+
# @param response [Hash] The information that the response will contain.
|
58
|
+
# @return [Response] Response object with information in form of getter methods.
|
59
|
+
def success(response)
|
60
|
+
create_response(:success, get_response_params(response))
|
61
|
+
end
|
62
|
+
|
63
|
+
# Creates a failure response. Handy method for #create_response
|
64
|
+
#
|
65
|
+
# @param response [Hash] The information that the response will contain.
|
66
|
+
# @return [Response] Response object with information in form of getter methods.
|
67
|
+
def failure(response)
|
68
|
+
create_response(:failure, get_response_params(response))
|
69
|
+
end
|
70
|
+
|
71
|
+
class << self
|
72
|
+
class DefaultPlayer
|
73
|
+
include CultomePlayer
|
74
|
+
|
75
|
+
def initialize(env)
|
76
|
+
prepare_environment(env)
|
77
|
+
playlists.register(:current)
|
78
|
+
playlists.register(:history)
|
79
|
+
playlists.register(:queue)
|
80
|
+
playlists.register(:focus)
|
81
|
+
playlists.register(:search)
|
82
|
+
|
83
|
+
register_listener(:playback_finish, self)
|
84
|
+
end
|
85
|
+
|
86
|
+
def on_playback_finish
|
87
|
+
r = execute("next no_history")
|
88
|
+
display_over("#{r.message}\n#{PROMPT}")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Get an instance of DefaultPlayer
|
93
|
+
#
|
94
|
+
# @param env [Symbol] The environment from which the configirations will be taken.
|
95
|
+
# @return [DefaultPlayer] A Cultome player ready to rock.
|
96
|
+
def get_player(env=:user)
|
97
|
+
DefaultPlayer.new(env)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def get_response_params(response)
|
104
|
+
return {message: response} if response.instance_of?(String)
|
105
|
+
return response
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module CultomePlayer::Command
|
2
|
+
module Language
|
3
|
+
|
4
|
+
# Define the sintaxis of the player language.
|
5
|
+
#
|
6
|
+
# @return [Hash] With the keys :command, :parameters, :actions, :param
|
7
|
+
def sintaxis
|
8
|
+
# <command> : <action> | <action> <parameters>
|
9
|
+
# <action> : literal
|
10
|
+
# <parameters> : <param> | <param> <parameters>
|
11
|
+
# <param> : literal | criteria | number | object | path | bubble
|
12
|
+
{
|
13
|
+
command: ["action", "action parameters"],
|
14
|
+
parameters: ["param", "param parameters"],
|
15
|
+
action: [:literal],
|
16
|
+
param: [:literal, :criteria, :number, :object, :path, :boolean, :bubble],
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the semantics of the builtin commands.
|
21
|
+
#
|
22
|
+
# @note The first literal in regex is the command itself.
|
23
|
+
# @return [Hash<String, Regex>] The key is the command name and the regex its format.
|
24
|
+
def semantics
|
25
|
+
{
|
26
|
+
"play" => /^literal(literal|number|criteria|object|[\s]+)*$/,
|
27
|
+
"show" => /^literal(number|object|[\s]+)*$/,
|
28
|
+
"search" => /^literal(literal|criteria|[\s]+)+$/,
|
29
|
+
"enqueue" => /^literal(literal|number|criteria|object|[\s]+)+$/,
|
30
|
+
"connect" => /^literal ((literal)|(path) bubble (literal))$/,
|
31
|
+
"disconnect" => /^literal (literal)$/,
|
32
|
+
"stop" => /^literal[\s]*$/,
|
33
|
+
"pause" => /^literal (boolean)$/,
|
34
|
+
"prev" => /^literal[\s]*$/,
|
35
|
+
"next" => /^literal[\s]*$/,
|
36
|
+
"quit" => /^literal[\s]*$/,
|
37
|
+
"ff" => /^literal(number|[\s]+)*$/,
|
38
|
+
"fb" => /^literal(number|[\s]+)*$/,
|
39
|
+
"shuffle" => /^literal[\s]+(boolean)$/,
|
40
|
+
"repeat" => /^literal[\s]*$/,
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return the token identities.
|
45
|
+
#
|
46
|
+
# @return [List<Hash>] The has contains the type of the token and their format.
|
47
|
+
def token_identities
|
48
|
+
[
|
49
|
+
{type: :bubble, identity: /^(=>|->)$/},
|
50
|
+
{type: :number, identity: /^([\d]+)$/},
|
51
|
+
{type: :object, identity: /^@([\w\d]+)$/},
|
52
|
+
{type: :path, identity: /^(['"]?(?:\/|~\/)[\/\w\d\s.]+)["']?$/},
|
53
|
+
{type: :criteria, identity: /^([\w]+):([\d\w\s]+)$/, captures: 2, labels: [:criteria, :value]},
|
54
|
+
{type: :boolean, identity: /^(on|off|yes|false|true|si|no|y|n|s|ok)$/},
|
55
|
+
{type: :ip, identity: /^([\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})$/},
|
56
|
+
{type: :literal, identity: /^([\w\d\s]+)$/},
|
57
|
+
]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module CultomePlayer::Command
|
2
|
+
module Processor
|
3
|
+
|
4
|
+
# Parse a user input into a command
|
5
|
+
#
|
6
|
+
# @param user_input [String] The user input to be parsed.
|
7
|
+
# @return [Command] The parsed command.
|
8
|
+
def parse(user_input)
|
9
|
+
tokens = identify_tokens(get_tokens(user_input))
|
10
|
+
validate_command(:command, tokens)
|
11
|
+
return CultomePlayer::Objects::Command.new(tokens.shift, tokens)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Split the user input into tokens.
|
15
|
+
#
|
16
|
+
# @param user_input [String] The user input.
|
17
|
+
# @return [List<String>] The detected tokens.
|
18
|
+
def get_tokens(user_input)
|
19
|
+
tokens = []
|
20
|
+
token = ""
|
21
|
+
capturing_string = false
|
22
|
+
|
23
|
+
user_input.each_char do |char|
|
24
|
+
case char
|
25
|
+
when /[\d\w\/:@]/
|
26
|
+
token << char
|
27
|
+
when /["']/
|
28
|
+
capturing_string = !capturing_string
|
29
|
+
when /[\s]/
|
30
|
+
if capturing_string
|
31
|
+
token << char
|
32
|
+
else
|
33
|
+
tokens << token
|
34
|
+
token = ""
|
35
|
+
end
|
36
|
+
else
|
37
|
+
token << char
|
38
|
+
end # case
|
39
|
+
end # each
|
40
|
+
|
41
|
+
tokens << token unless token.empty?
|
42
|
+
raise "invalid command:unclosed string" if capturing_string
|
43
|
+
|
44
|
+
return tokens
|
45
|
+
end
|
46
|
+
|
47
|
+
# Identify detected tokens.
|
48
|
+
#
|
49
|
+
# @param tokens [List<String>] The detected tokens.
|
50
|
+
# @return [List<Hash>] The hash contains keys :type and :value.
|
51
|
+
def identify_tokens(tokens)
|
52
|
+
tokens.map do |token|
|
53
|
+
id = guess_token_id(token)
|
54
|
+
id.nil? ? {type: :unknown, value: token} : get_token_value(token, id)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Check that a the tokens identifed correspond to a player command.
|
59
|
+
#
|
60
|
+
# @param type [Symbol] The language structure you try to match.
|
61
|
+
# @param tokens [List<Hash>] The list of tokens identified.
|
62
|
+
# @return [Boolean] True if the user command match with a player command format.
|
63
|
+
def validate_command(type, tokens)
|
64
|
+
current_format = get_command_format(type, tokens)
|
65
|
+
# extraemos el primer token, que debe ser el comando
|
66
|
+
cmd = tokens.first[:value]
|
67
|
+
|
68
|
+
valid_format = semantics[cmd]
|
69
|
+
if valid_format.nil?
|
70
|
+
if plugins_respond_to?(cmd)
|
71
|
+
valid_format = plugin_command_sintaxis(cmd)
|
72
|
+
else
|
73
|
+
raise 'invalid command:invalid action'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
return current_format =~ valid_format
|
77
|
+
end
|
78
|
+
|
79
|
+
# Creates a string representation of the command prototype.
|
80
|
+
#
|
81
|
+
# @param type [Symbol] The Language structure you try to match.
|
82
|
+
# @param tokens [List<Hash>] The Language structure you try to match.
|
83
|
+
# @return [String] The string representation of the command prototype.
|
84
|
+
def get_command_format(type, tokens)
|
85
|
+
format = guess_command_format(type, tokens)
|
86
|
+
|
87
|
+
return format if format.class == Symbol
|
88
|
+
|
89
|
+
langs = format.split
|
90
|
+
# partimos el formato y validamos cada pedazo
|
91
|
+
tks = tokens.clone
|
92
|
+
|
93
|
+
cmd_format = ""
|
94
|
+
while !langs.empty? do
|
95
|
+
# extraemos el primer elemento del formato
|
96
|
+
lang = langs.shift
|
97
|
+
|
98
|
+
if langs.empty?
|
99
|
+
# volvemos a validar con el nuevo elemento del lenguaje
|
100
|
+
cmd_format << " " << get_command_format(lang.to_sym, tks).to_s
|
101
|
+
else
|
102
|
+
tk = tks.shift
|
103
|
+
cmd_format << " " << get_command_format(lang.to_sym, tk).to_s
|
104
|
+
end
|
105
|
+
end
|
106
|
+
# limpiamos el formato final
|
107
|
+
return cmd_format.strip.gsub(" ", " ")
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def guess_token_id(token)
|
113
|
+
token_identities.find do |tok_id|
|
114
|
+
token =~ tok_id[:identity]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_token_value(token, id)
|
119
|
+
captures = id[:captures] || 1
|
120
|
+
labels = id[:labels] || [:value]
|
121
|
+
|
122
|
+
token_info = {type: id[:type]}
|
123
|
+
|
124
|
+
token =~ id[:identity]
|
125
|
+
(1..captures).to_a.zip(labels).each do |idx, label|
|
126
|
+
token_info[label] = eval("$#{idx}")
|
127
|
+
end
|
128
|
+
|
129
|
+
return token_info
|
130
|
+
end
|
131
|
+
|
132
|
+
def guess_command_format(type, tokens)
|
133
|
+
# buscamos el formato que tenga mas matches con los parametros
|
134
|
+
format = sintaxis[type].find do |stxs_elem| # ["action", "action parameters"]
|
135
|
+
if stxs_elem.is_a?(String)
|
136
|
+
# checamos si el numero de token en el comando corresponde
|
137
|
+
# con el numer de tokens en la sintaxis
|
138
|
+
stxs_elem.split.size >= tokens.size # ej. "play 1 2" === "action paramters"
|
139
|
+
elsif stxs_elem.is_a?(Symbol)
|
140
|
+
if tokens.is_a?(Hash)
|
141
|
+
tokens[:type] == stxs_elem
|
142
|
+
elsif tokens.is_a?(Array) && tokens.size == 1
|
143
|
+
tokens.first[:type] == stxs_elem
|
144
|
+
else
|
145
|
+
false
|
146
|
+
end
|
147
|
+
else
|
148
|
+
raise 'invalid command:invalid command format'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
if format.nil?
|
153
|
+
max = sintaxis[type].max{|tk| tk.class == String ? tk.split.size: 0}
|
154
|
+
if max.respond_to?(:split) && tokens.size > max.split.size
|
155
|
+
format = max
|
156
|
+
else
|
157
|
+
raise 'invalid command:invalid command'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
return format
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|