sp-duh 2.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +661 -0
- data/README.md +2 -0
- data/Rakefile +32 -0
- data/config/i18n/i18n.xlsx +0 -0
- data/config/initializers/active_record/connection_adapters_postgre_sql_adapter.rb +165 -0
- data/config/initializers/active_record/migration_without_transaction.rb +4 -0
- data/config/initializers/active_record/migrator.rb +34 -0
- data/config/initializers/rails/generators.rb +13 -0
- data/config/jsonapi/settings.yml +14 -0
- data/config/locales/pt.yml +15 -0
- data/lib/generators/accounting_migration/accounting_migration_generator.rb +10 -0
- data/lib/generators/accounting_migration/templates/migration.rb +42 -0
- data/lib/generators/accounting_payroll_migration/accounting_payroll_migration_generator.rb +10 -0
- data/lib/generators/accounting_payroll_migration/templates/migration.rb +73 -0
- data/lib/generators/sharded_migration/sharded_migration_generator.rb +10 -0
- data/lib/generators/sharded_migration/templates/migration.rb +45 -0
- data/lib/sp-duh.rb +32 -0
- data/lib/sp/duh.rb +180 -0
- data/lib/sp/duh/adapters/pg/text_decoder/json.rb +15 -0
- data/lib/sp/duh/adapters/pg/text_encoder/json.rb +15 -0
- data/lib/sp/duh/db/transfer/backup.rb +71 -0
- data/lib/sp/duh/db/transfer/restore.rb +89 -0
- data/lib/sp/duh/engine.rb +35 -0
- data/lib/sp/duh/exceptions.rb +70 -0
- data/lib/sp/duh/i18n/excel_loader.rb +26 -0
- data/lib/sp/duh/jsonapi/adapters/base.rb +168 -0
- data/lib/sp/duh/jsonapi/adapters/db.rb +36 -0
- data/lib/sp/duh/jsonapi/adapters/raw_db.rb +77 -0
- data/lib/sp/duh/jsonapi/configuration.rb +167 -0
- data/lib/sp/duh/jsonapi/doc/apidoc_documentation_format_generator.rb +286 -0
- data/lib/sp/duh/jsonapi/doc/generator.rb +32 -0
- data/lib/sp/duh/jsonapi/doc/schema_catalog_helper.rb +97 -0
- data/lib/sp/duh/jsonapi/doc/victor_pinus_metadata_format_parser.rb +374 -0
- data/lib/sp/duh/jsonapi/exceptions.rb +56 -0
- data/lib/sp/duh/jsonapi/model/base.rb +25 -0
- data/lib/sp/duh/jsonapi/model/concerns/attributes.rb +94 -0
- data/lib/sp/duh/jsonapi/model/concerns/model.rb +42 -0
- data/lib/sp/duh/jsonapi/model/concerns/persistence.rb +221 -0
- data/lib/sp/duh/jsonapi/model/concerns/serialization.rb +59 -0
- data/lib/sp/duh/jsonapi/parameters.rb +44 -0
- data/lib/sp/duh/jsonapi/resource_publisher.rb +28 -0
- data/lib/sp/duh/jsonapi/service.rb +110 -0
- data/lib/sp/duh/migrations.rb +47 -0
- data/lib/sp/duh/migrations/migrator.rb +41 -0
- data/lib/sp/duh/repl.rb +193 -0
- data/lib/sp/duh/version.rb +25 -0
- data/lib/tasks/db_utils.rake +98 -0
- data/lib/tasks/doc.rake +27 -0
- data/lib/tasks/i18n.rake +23 -0
- data/lib/tasks/oauth.rake +29 -0
- data/lib/tasks/transfer.rake +48 -0
- data/lib/tasks/xls2jrxml.rake +15 -0
- data/test/jsonapi/server.rb +67 -0
- data/test/tasks/test.rake +10 -0
- metadata +170 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
module SP
|
2
|
+
module Duh
|
3
|
+
module JSONAPI
|
4
|
+
class Parameters
|
5
|
+
attr_reader :user_id, :company_id, :company_schema, :sharded_schema, :default_accounting_schema, :accounting_schema, :accounting_prefix
|
6
|
+
|
7
|
+
def initialize(parameters = {})
|
8
|
+
check_jsonapi_args(parameters)
|
9
|
+
|
10
|
+
@user_id = parameters[:user_id].to_s unless parameters[:user_id].nil?
|
11
|
+
@company_id = parameters[:company_id].to_s unless parameters[:company_id].nil?
|
12
|
+
@company_schema = parameters[:company_schema] unless parameters[:company_schema].nil?
|
13
|
+
@sharded_schema = parameters[:sharded_schema] unless parameters[:sharded_schema].nil?
|
14
|
+
@default_accounting_schema = parameters[:default_accounting_schema] unless parameters[:default_accounting_schema].nil?
|
15
|
+
@accounting_schema = parameters[:accounting_schema] unless parameters[:accounting_schema].nil?
|
16
|
+
@accounting_prefix = parameters[:accounting_prefix] unless parameters[:accounting_prefix].nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_json(options = {})
|
20
|
+
{
|
21
|
+
user_id: self.user_id,
|
22
|
+
company_id: self.company_id,
|
23
|
+
company_schema: self.company_schema,
|
24
|
+
sharded_schema: self.sharded_schema,
|
25
|
+
default_accounting_schema: self.default_accounting_schema,
|
26
|
+
accounting_schema: self.accounting_schema,
|
27
|
+
accounting_prefix: self.accounting_prefix
|
28
|
+
}.to_json
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def check_jsonapi_args(parameters)
|
33
|
+
if parameters.keys.any? && !(parameters.keys - valid_keys).empty?
|
34
|
+
raise SP::Duh::JSONAPI::Exceptions::InvalidJSONAPIKeyError.new(key: (parameters.keys - valid_keys).join(', '))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def valid_keys
|
39
|
+
[ :user_id, :company_id, :company_schema, :sharded_schema, :default_accounting_schema, :accounting_schema, :accounting_prefix ]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Usage (by a module or class belonging to a library or gem that publishes JSONAPI resources):
|
2
|
+
#
|
3
|
+
# In the module or class definition:
|
4
|
+
#
|
5
|
+
# include SP::Duh::JSONAPI::ResourcePublisher
|
6
|
+
# self.jsonapi_resources_root = "<path to the folder where the resources configurations are located>"
|
7
|
+
|
8
|
+
module SP
|
9
|
+
module Duh
|
10
|
+
module JSONAPI
|
11
|
+
|
12
|
+
module ResourcePublisher
|
13
|
+
extend ::ActiveSupport::Concern
|
14
|
+
|
15
|
+
included do
|
16
|
+
SP::Duh::JSONAPI::Configuration.add_publisher self
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
attr_reader :jsonapi_resources_root
|
21
|
+
private
|
22
|
+
attr_writer :jsonapi_resources_root
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module SP
|
2
|
+
module Duh
|
3
|
+
module JSONAPI
|
4
|
+
|
5
|
+
VERSION = '1.0'
|
6
|
+
|
7
|
+
class Status
|
8
|
+
OK = 200
|
9
|
+
ERROR = 500
|
10
|
+
end
|
11
|
+
|
12
|
+
class Service
|
13
|
+
|
14
|
+
def self.protocols ; [ :db, :http ] ; end
|
15
|
+
def connection ; @pg_connection ; end
|
16
|
+
def url ; @url ; end
|
17
|
+
def set_url(value) ; @url = value ; end
|
18
|
+
def configuration ; @configuration ; end
|
19
|
+
def adapter
|
20
|
+
raise Exceptions::ServiceSetupError.new('JSONAPI prefix not specified', nil) if url.blank?
|
21
|
+
@adapter_instance ||= @adapter.new(self)
|
22
|
+
SP::Duh::JSONAPI::Model::Base.adapter ||= @adapter_instance
|
23
|
+
@adapter_instance
|
24
|
+
end
|
25
|
+
|
26
|
+
def protocol ; @protocol ; end
|
27
|
+
def protocol=(value)
|
28
|
+
if !value.to_sym.in?(Service.protocols)
|
29
|
+
raise Exceptions::ServiceProtocolError.new(protocol: value.to_sym, protocols: Service.protocols.join(', '))
|
30
|
+
end
|
31
|
+
@protocol = value.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(pg_connection, url, default_adapter = SP::Duh::JSONAPI::Adapters::Db)
|
35
|
+
@pg_connection = pg_connection
|
36
|
+
@url = url
|
37
|
+
protocol = :db
|
38
|
+
@configuration = Configuration.new(pg_connection, url)
|
39
|
+
@adapter = default_adapter
|
40
|
+
adapter unless url.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def setup
|
44
|
+
begin
|
45
|
+
create_jsonapi_function()
|
46
|
+
rescue StandardError => e
|
47
|
+
raise Exceptions::ServiceSetupError.new(nil, e)
|
48
|
+
end
|
49
|
+
configuration.setup()
|
50
|
+
end
|
51
|
+
|
52
|
+
def close
|
53
|
+
@pg_connection.close if !@pg_connection.nil? && !@pg_connection.finished?
|
54
|
+
@adapter_instance = nil
|
55
|
+
@adapter = nil
|
56
|
+
@url = nil
|
57
|
+
@configuration = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_jsonapi_parameters(parameters = nil) ; @parameters = parameters ; end
|
61
|
+
def clear_jsonapi_args ; @parameters = nil ; end
|
62
|
+
def parameters ; @parameters ; end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def create_jsonapi_function
|
67
|
+
connection.exec %Q[
|
68
|
+
|
69
|
+
CREATE OR REPLACE FUNCTION public.jsonapi (
|
70
|
+
IN method text,
|
71
|
+
IN uri text,
|
72
|
+
IN body text,
|
73
|
+
IN user_id text,
|
74
|
+
IN company_id text,
|
75
|
+
IN company_schema text,
|
76
|
+
IN sharded_schema text,
|
77
|
+
IN accounting_schema text,
|
78
|
+
IN accounting_prefix text,
|
79
|
+
OUT http_status integer,
|
80
|
+
OUT response text
|
81
|
+
) RETURNS record AS '$libdir/pg-jsonapi.so', 'jsonapi' LANGUAGE C;
|
82
|
+
|
83
|
+
CREATE OR REPLACE FUNCTION public.inside_jsonapi (
|
84
|
+
) RETURNS boolean AS '$libdir/pg-jsonapi.so', 'inside_jsonapi' LANGUAGE C;
|
85
|
+
|
86
|
+
CREATE OR REPLACE FUNCTION public.get_jsonapi_user (
|
87
|
+
) RETURNS text AS '$libdir/pg-jsonapi.so', 'get_jsonapi_user' LANGUAGE C;
|
88
|
+
|
89
|
+
CREATE OR REPLACE FUNCTION public.get_jsonapi_company (
|
90
|
+
) RETURNS text AS '$libdir/pg-jsonapi.so', 'get_jsonapi_company' LANGUAGE C;
|
91
|
+
|
92
|
+
CREATE OR REPLACE FUNCTION public.get_jsonapi_company_schema (
|
93
|
+
) RETURNS text AS '$libdir/pg-jsonapi.so', 'get_jsonapi_company_schema' LANGUAGE C;
|
94
|
+
|
95
|
+
CREATE OR REPLACE FUNCTION public.get_jsonapi_sharded_schema (
|
96
|
+
) RETURNS text AS '$libdir/pg-jsonapi.so', 'get_jsonapi_sharded_schema' LANGUAGE C;
|
97
|
+
|
98
|
+
CREATE OR REPLACE FUNCTION public.get_jsonapi_accounting_schema (
|
99
|
+
) RETURNS text AS '$libdir/pg-jsonapi.so', 'get_jsonapi_accounting_schema' LANGUAGE C;
|
100
|
+
|
101
|
+
CREATE OR REPLACE FUNCTION public.get_jsonapi_accounting_prefix (
|
102
|
+
) RETURNS text AS '$libdir/pg-jsonapi.so', 'get_jsonapi_accounting_prefix' LANGUAGE C;
|
103
|
+
|
104
|
+
]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2011-2017 Cloudware S.A. All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is part of sp-duh.
|
5
|
+
#
|
6
|
+
# sp-duh is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# sp-duh is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with sp-duh. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
# encoding: utf-8
|
20
|
+
#
|
21
|
+
module SP
|
22
|
+
module Duh
|
23
|
+
module Migrations
|
24
|
+
extend ::ActiveSupport::Concern
|
25
|
+
|
26
|
+
included do
|
27
|
+
end
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
|
31
|
+
attr_reader :migrations_root
|
32
|
+
|
33
|
+
def migrator(pg_connection)
|
34
|
+
if @migrator.nil? || @migrator.root != migrations_root || @migrator.connection != pg_connection
|
35
|
+
@migrator = Migrator.new(pg_connection, migrations_root)
|
36
|
+
end
|
37
|
+
@migrator
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_writer :migrations_root
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SP
|
2
|
+
module Duh
|
3
|
+
module Migrations
|
4
|
+
|
5
|
+
class Migrator
|
6
|
+
|
7
|
+
attr_reader :root
|
8
|
+
|
9
|
+
def connection ; @pg_connection ; end
|
10
|
+
|
11
|
+
def initialize(pg_connection, migrations_root)
|
12
|
+
@pg_connection = pg_connection
|
13
|
+
@root = migrations_root
|
14
|
+
end
|
15
|
+
|
16
|
+
def up(migration_name) ; migrate(migration_name, :up) ; end
|
17
|
+
def down(migration_name) ; migrate(migration_name, :down) ; end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def migrate(migration_name, direction = :up)
|
22
|
+
_log("Migrating #{direction.to_s} #{migration_name}...", "Migrations::Migrator")
|
23
|
+
run_all_on(File.join(root, migration_name, direction.to_s))
|
24
|
+
_log("[DONE]", "Migrations::Migrator")
|
25
|
+
end
|
26
|
+
|
27
|
+
def run_all_on(folder)
|
28
|
+
connection.transaction do |t|
|
29
|
+
Dir.glob(File.join(folder, '*.sql')).sort.each do |step|
|
30
|
+
name = File.basename(step, '.*')
|
31
|
+
_log(" #{name}", "Migrations::Migrator")
|
32
|
+
t.exec File.read(step)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/sp/duh/repl.rb
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2011-2017 Cloudware S.A. All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is part of sp-duh.
|
5
|
+
#
|
6
|
+
# sp-duh is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# sp-duh is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with sp-duh. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
# encoding: utf-8
|
20
|
+
#
|
21
|
+
module SP
|
22
|
+
module Duh
|
23
|
+
|
24
|
+
class Repl
|
25
|
+
|
26
|
+
@@help = Array.new
|
27
|
+
@@cmds = Array.new
|
28
|
+
|
29
|
+
def initialize (a_pg_conn)
|
30
|
+
@see_calc = false
|
31
|
+
@pg_conn = a_pg_conn
|
32
|
+
@hist_file = ".#{@prompt.split('>')[0].strip}_history"
|
33
|
+
begin
|
34
|
+
File.open(@hist_file).each do |line|
|
35
|
+
Readline::HISTORY << line.strip
|
36
|
+
end
|
37
|
+
rescue
|
38
|
+
# no history file
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.desc (a_msg)
|
44
|
+
@@help << a_msg
|
45
|
+
@@cmds << a_msg.split(' ')[0].strip
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# http://bogojoker.com/readline/
|
50
|
+
# Smarter Readline to prevent empty and dups
|
51
|
+
# 1. Read a line and append to history
|
52
|
+
# 2. Quick Break on nil
|
53
|
+
# 3. Remove from history if empty or dup
|
54
|
+
#
|
55
|
+
def readline_with_hist_management ()
|
56
|
+
line = Readline.readline(@prompt, true)
|
57
|
+
return nil if line.nil?
|
58
|
+
if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line
|
59
|
+
Readline::HISTORY.pop
|
60
|
+
end
|
61
|
+
line
|
62
|
+
end
|
63
|
+
|
64
|
+
def check_db ()
|
65
|
+
raise "can't do that! database connection is not valid" if @pg_conn.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'help -- you are looking at it'
|
69
|
+
def help ()
|
70
|
+
puts @@help
|
71
|
+
end
|
72
|
+
|
73
|
+
def save_history
|
74
|
+
File.open(@hist_file, "w") do |f|
|
75
|
+
Readline::HISTORY.to_a[0..100].each do |line|
|
76
|
+
f.write "#{line}\n"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
desc 'quit -- exit this shell'
|
82
|
+
def quit ()
|
83
|
+
puts "quiting"
|
84
|
+
save_history()
|
85
|
+
exit
|
86
|
+
end
|
87
|
+
|
88
|
+
desc 'initsee -- install pg-see in the database'
|
89
|
+
def initsee (a_recreate = false)
|
90
|
+
SP::Duh.initsee(@pg_conn, a_recreate)
|
91
|
+
end
|
92
|
+
|
93
|
+
desc 'psql -- open sql console'
|
94
|
+
def psql ()
|
95
|
+
system("psql --user=#{@pg_conn.user} --host=#{@pg_conn.host} #{@pg_conn.db}")
|
96
|
+
end
|
97
|
+
|
98
|
+
desc 'open <file> -- open file with system command'
|
99
|
+
def open (a_file)
|
100
|
+
system("open #{File.expand_path(a_file)}")
|
101
|
+
end
|
102
|
+
|
103
|
+
desc 'debug -- enter IRB'
|
104
|
+
def debug
|
105
|
+
byebug
|
106
|
+
end
|
107
|
+
|
108
|
+
desc 'pid -- get pg backend pid'
|
109
|
+
def pid
|
110
|
+
pid = @pg_conn.exec("SELECT pg_backend_pid() AS pid")[0]["pid"]
|
111
|
+
puts "Backend PID: #{pid}"
|
112
|
+
end
|
113
|
+
|
114
|
+
#desc 'reload_jsonapi -- configure JSON API'
|
115
|
+
# @TODO check helpers to reload json and modules with JSM and TD
|
116
|
+
#def reload_jsonapi
|
117
|
+
# JSONAPI.service.setup
|
118
|
+
#end
|
119
|
+
|
120
|
+
def repl ()
|
121
|
+
cmdset = @@cmds.abbrev
|
122
|
+
while buf = readline_with_hist_management
|
123
|
+
begin
|
124
|
+
buf.strip!
|
125
|
+
args = buf.split(' ')
|
126
|
+
command = args[0]
|
127
|
+
args = args[1..-1]
|
128
|
+
unless cmdset.has_key?(command)
|
129
|
+
fallback_command(buf)
|
130
|
+
next
|
131
|
+
end
|
132
|
+
command = cmdset[command]
|
133
|
+
if respond_to?(command)
|
134
|
+
arity = method(command).arity
|
135
|
+
if arity >= 0
|
136
|
+
if arity != args.length
|
137
|
+
puts "command #{command} requires #{arity} arguments (#{args.length} given)"
|
138
|
+
next
|
139
|
+
end
|
140
|
+
elsif arity < 0
|
141
|
+
min_args = -arity - 1
|
142
|
+
if args.length < min_args or args.length > -arity
|
143
|
+
puts "command #{command} takes #{min_args} to #{-arity} arguments (#{args.length} given)"
|
144
|
+
next
|
145
|
+
end
|
146
|
+
end
|
147
|
+
send(command, *args)
|
148
|
+
else
|
149
|
+
fallback_command(buf)
|
150
|
+
end
|
151
|
+
rescue SystemExit
|
152
|
+
save_history()
|
153
|
+
exit
|
154
|
+
rescue Exception => e
|
155
|
+
puts e.message
|
156
|
+
puts e.backtrace
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
def fallback_command (a_command)
|
163
|
+
begin
|
164
|
+
if @see_calc and @pg_conn != nil
|
165
|
+
cmd = a_command.gsub("'", "''")
|
166
|
+
calc = @pg_conn.exec(%Q[
|
167
|
+
SELECT json::json FROM see_evaluate_expression('#{cmd}');
|
168
|
+
])
|
169
|
+
if calc.cmd_tuples != 1
|
170
|
+
puts "unknown error unable to calculate expression"
|
171
|
+
else
|
172
|
+
jresult = JSON.parse(calc[0]['json'])
|
173
|
+
if jresult['error'] != nil
|
174
|
+
if jresult['error']['type'] == 'osal::exception'
|
175
|
+
puts jresult['error']['trace']['why']
|
176
|
+
else
|
177
|
+
puts jresult['error']
|
178
|
+
end
|
179
|
+
else
|
180
|
+
puts jresult['result']
|
181
|
+
end
|
182
|
+
end
|
183
|
+
else
|
184
|
+
puts "#{a_command} is not a valid command"
|
185
|
+
end
|
186
|
+
rescue => e
|
187
|
+
puts e.message
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|