qcmd 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/TODO.md +0 -3
- data/bin/qcmd +15 -4
- data/lib/qcmd.rb +11 -0
- data/lib/qcmd/cli.rb +71 -17
- data/lib/qcmd/handler.rb +11 -12
- data/lib/qcmd/input_completer.rb +21 -18
- data/lib/qcmd/network.rb +5 -4
- data/lib/qcmd/plaintext.rb +5 -0
- data/lib/qcmd/server.rb +1 -1
- data/lib/qcmd/version.rb +1 -1
- metadata +4 -6
- data/features/hello.feature +0 -13
data/README.md
CHANGED
data/TODO.md
CHANGED
data/bin/qcmd
CHANGED
@@ -13,6 +13,7 @@ opts = Trollop::options do
|
|
13
13
|
opt :machine_passcode, "Use the given machine passcode", :type => :integer
|
14
14
|
opt :workspace, "Automatically try to connect to the workspace with the given name", :type => :string
|
15
15
|
opt :workspace_passcode, "Use the given workspace passcode", :type => :integer
|
16
|
+
opt :command, "Execute a single command and exit", :type => :string
|
16
17
|
end
|
17
18
|
|
18
19
|
if opts[:verbose]
|
@@ -26,10 +27,20 @@ end
|
|
26
27
|
|
27
28
|
# browse local network and check for qlab + qlab workspaces
|
28
29
|
|
29
|
-
|
30
|
-
Qcmd.
|
31
|
-
Qcmd.print
|
30
|
+
if !opts[:machine_given]
|
31
|
+
Qcmd.ascii_qlab
|
32
|
+
Qcmd.print
|
33
|
+
Qcmd.print Qcmd.centered_text(VERSION_STRING)
|
34
|
+
|
35
|
+
Qcmd::Network.browse_and_display opts
|
36
|
+
else
|
37
|
+
Qcmd::Network.browse
|
38
|
+
end
|
39
|
+
|
40
|
+
if options[:command_given] && !(options[:machine_given] && options[:workspace_given])
|
41
|
+
Qcmd.print_wrapped("if you give a command, you must also give a
|
42
|
+
machine name and a workspace name to connect to")
|
43
|
+
end
|
32
44
|
|
33
|
-
Qcmd::Network.browse_and_display opts
|
34
45
|
|
35
46
|
Qcmd::CLI.launch opts
|
data/lib/qcmd.rb
CHANGED
@@ -33,6 +33,17 @@ module Qcmd
|
|
33
33
|
self.log_level = :warning
|
34
34
|
end
|
35
35
|
|
36
|
+
def quiet?
|
37
|
+
self.log_level == :warning
|
38
|
+
end
|
39
|
+
|
40
|
+
def while_quiet
|
41
|
+
previous_level = self.log_level
|
42
|
+
self.log_level = :warning unless previous_level == :debug
|
43
|
+
yield
|
44
|
+
self.log_level = previous_level
|
45
|
+
end
|
46
|
+
|
36
47
|
def debug?
|
37
48
|
!!debug_mode
|
38
49
|
end
|
data/lib/qcmd/cli.rb
CHANGED
@@ -24,9 +24,21 @@ module Qcmd
|
|
24
24
|
|
25
25
|
if options[:machine_given]
|
26
26
|
Qcmd.debug "(autoconnecting to #{ options[:machine] })"
|
27
|
-
|
27
|
+
|
28
|
+
Qcmd.while_quiet do
|
29
|
+
connect_to_machine_by_name options[:machine], options[:machine_passcode]
|
30
|
+
end
|
31
|
+
|
28
32
|
if options[:workspace_given]
|
29
|
-
|
33
|
+
Qcmd.while_quiet do
|
34
|
+
connect_to_workspace_by_name options[:workspace], options[:workspace_passcode]
|
35
|
+
end
|
36
|
+
|
37
|
+
if options[:command_given]
|
38
|
+
handle_message options[:command]
|
39
|
+
puts %[sent command "#{ options[:command] }"]
|
40
|
+
exit 0
|
41
|
+
end
|
30
42
|
end
|
31
43
|
end
|
32
44
|
|
@@ -77,9 +89,12 @@ module Qcmd
|
|
77
89
|
Qcmd.debug %[(connecting to workspace: "#{workspace.name}")]
|
78
90
|
# set workspace in context. Will unset later if there's a problem.
|
79
91
|
Qcmd.context.workspace = workspace
|
80
|
-
self.prompt = "#{ Qcmd.context.machine.name }:#{ workspace.name }> "
|
81
92
|
|
82
93
|
server.connect_to_workspace workspace
|
94
|
+
if Qcmd.context.workspace_connected? && Qcmd.context.workspace.cues
|
95
|
+
print "loaded #{pluralize Qcmd.context.workspace.cues.size, 'cue'}"
|
96
|
+
self.prompt = "#{ Qcmd.context.machine.name }:#{ workspace.name }> "
|
97
|
+
end
|
83
98
|
end
|
84
99
|
|
85
100
|
def reset
|
@@ -107,9 +122,10 @@ module Qcmd
|
|
107
122
|
command = args.shift
|
108
123
|
|
109
124
|
case command
|
110
|
-
when 'exit'
|
125
|
+
when 'exit', 'quit', 'q'
|
111
126
|
print 'exiting...'
|
112
127
|
exit 0
|
128
|
+
|
113
129
|
when 'connect'
|
114
130
|
Qcmd.debug "(connect command received args: #{ args.inspect })"
|
115
131
|
|
@@ -117,9 +133,11 @@ module Qcmd
|
|
117
133
|
passcode = args.shift
|
118
134
|
|
119
135
|
connect_to_machine_by_name machine_name, passcode
|
136
|
+
|
120
137
|
when 'disconnect'
|
121
138
|
reset
|
122
139
|
Qcmd::Network.browse_and_display
|
140
|
+
|
123
141
|
when 'use'
|
124
142
|
Qcmd.debug "(use command received args: #{ args.inspect })"
|
125
143
|
|
@@ -129,18 +147,29 @@ module Qcmd
|
|
129
147
|
Qcmd.debug "(using workspace: #{ workspace_name.inspect })"
|
130
148
|
|
131
149
|
connect_to_workspace_by_name workspace_name, passcode
|
150
|
+
|
132
151
|
when 'cues'
|
133
152
|
if !Qcmd.context.workspace_connected?
|
134
|
-
|
135
|
-
|
136
|
-
print
|
137
|
-
print centered_text(" Cues ", '-')
|
138
|
-
table ['Number', 'Id', 'Name', 'Type'], Qcmd.context.workspace.cues.map {|cue|
|
139
|
-
[cue.number, cue.id, cue.name, cue.type]
|
140
|
-
}
|
141
|
-
print
|
153
|
+
failed_workspace_command message
|
154
|
+
return
|
142
155
|
end
|
143
|
-
|
156
|
+
|
157
|
+
# reload cues
|
158
|
+
server.load_cues
|
159
|
+
|
160
|
+
print
|
161
|
+
print centered_text(" Cues ", '-')
|
162
|
+
table ['Number', 'Id', 'Name', 'Type'], Qcmd.context.workspace.cues.map {|cue|
|
163
|
+
[cue.number, cue.id, cue.name, cue.type]
|
164
|
+
}
|
165
|
+
print
|
166
|
+
|
167
|
+
when 'cue', 'c'
|
168
|
+
if !Qcmd.context.workspace_connected?
|
169
|
+
failed_workspace_command message
|
170
|
+
return
|
171
|
+
end
|
172
|
+
|
144
173
|
# pull off cue number
|
145
174
|
cue_number = args.shift
|
146
175
|
cue_action = args.shift
|
@@ -150,25 +179,50 @@ module Qcmd
|
|
150
179
|
print
|
151
180
|
print " > cue NUMBER COMMAND ARGUMENTS"
|
152
181
|
print
|
153
|
-
|
182
|
+
print_wrapped("available cue commands are: #{Qcmd::InputCompleter::ReservedCueWords.join(', ')}")
|
154
183
|
elsif cue_action.nil?
|
155
|
-
server.send_workspace_command(cue_number)
|
184
|
+
server.send_workspace_command("cue/#{ cue_number }")
|
156
185
|
else
|
157
186
|
server.send_cue_command(cue_number, cue_action, *args)
|
158
187
|
end
|
188
|
+
|
159
189
|
when 'workspace'
|
160
190
|
workspace_command = args.shift
|
161
191
|
|
192
|
+
if !Qcmd.context.workspace_connected?
|
193
|
+
handle_failed_workspace_command message
|
194
|
+
return
|
195
|
+
end
|
196
|
+
|
162
197
|
if workspace_command.nil?
|
163
|
-
|
198
|
+
print_wrapped("no workspace command given. available workspace commands
|
199
|
+
are: #{Qcmd::InputCompleter::ReservedWorkspaceWords.join(', ')}")
|
164
200
|
else
|
165
201
|
server.send_workspace_command(workspace_command, *args)
|
166
202
|
end
|
167
203
|
|
168
204
|
else
|
169
|
-
|
205
|
+
if Qcmd.context.workspace_connected?
|
206
|
+
if Qcmd::InputCompleter::ReservedWorkspaceWords.include?(command)
|
207
|
+
server.send_workspace_command(command, *args)
|
208
|
+
else
|
209
|
+
if %r[/] =~ command
|
210
|
+
# might be legit OSC command, try sending
|
211
|
+
server.send_command(command, *args)
|
212
|
+
else
|
213
|
+
print "unrecognized command: #{ command }"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
else
|
217
|
+
handle_failed_workspace_command message
|
218
|
+
end
|
170
219
|
end
|
171
220
|
end
|
172
221
|
|
222
|
+
def handle_failed_workspace_command command
|
223
|
+
print_wrapped(%[the command, "#{ command }" can't be processed yet. you must
|
224
|
+
first connect to a machine and a workspace
|
225
|
+
before issuing other commands.])
|
226
|
+
end
|
173
227
|
end
|
174
228
|
end
|
data/lib/qcmd/handler.rb
CHANGED
@@ -9,21 +9,22 @@ module Qcmd
|
|
9
9
|
when %r[/workspaces]
|
10
10
|
Qcmd.context.machine.workspaces = reply.data.map {|ws| Qcmd::QLab::Workspace.new(ws)}
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
unless Qcmd.quiet?
|
13
|
+
print centered_text(" Workspaces ", '-')
|
14
|
+
print
|
15
|
+
Qcmd.context.machine.workspaces.each_with_index do |ws, n|
|
16
|
+
print "#{ n + 1 }. #{ ws.name }#{ ws.passcode? ? ' [PROTECTED]' : ''}"
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
print
|
20
|
+
print_wrapped('Type `use "WORKSPACE_NAME" PASSCODE` to load a workspace. Passcode is optional.')
|
21
|
+
print
|
22
|
+
end
|
22
23
|
|
23
24
|
when %r[/workspace/[^/]+/connect]
|
24
25
|
# connecting to a workspace
|
25
26
|
if reply.data == 'badpass'
|
26
|
-
print 'failed to connect to workspace'
|
27
|
+
print 'failed to connect to workspace, bad passcode or no passcode given'
|
27
28
|
Qcmd.context.disconnect_workspace
|
28
29
|
elsif reply.data == 'ok'
|
29
30
|
print 'connected to workspace'
|
@@ -38,8 +39,6 @@ module Qcmd
|
|
38
39
|
cue_list['cues'].map {|cue| Qcmd::QLab::Cue.new(cue)}
|
39
40
|
}.compact.flatten
|
40
41
|
|
41
|
-
print "loaded #{pluralize cues.size, 'cue'}"
|
42
|
-
|
43
42
|
when %r[/(selectedCues|runningCues|runningOrPausedCues)]
|
44
43
|
cues = reply.data.map {|cue|
|
45
44
|
cues = [Qcmd::QLab::Cue.new(cue)]
|
data/lib/qcmd/input_completer.rb
CHANGED
@@ -2,12 +2,14 @@ require 'readline'
|
|
2
2
|
|
3
3
|
module Qcmd
|
4
4
|
module InputCompleter
|
5
|
+
# the commands listed here should represent every possible legal command
|
5
6
|
ReservedWords = %w[
|
6
|
-
connect exit workspace workspaces disconnect
|
7
|
+
connect exit quit workspace workspaces disconnect
|
7
8
|
]
|
8
9
|
|
9
10
|
ReservedWorkspaceWords = %w[
|
10
11
|
cueLists selectedCues runningCues runningOrPausedCues thump
|
12
|
+
go stop pause resume reset panic disconnect
|
11
13
|
]
|
12
14
|
|
13
15
|
ReservedCueWords = %w[
|
@@ -40,14 +42,7 @@ module Qcmd
|
|
40
42
|
names = Qcmd.context.machine.workspace_names
|
41
43
|
quoted_names = names.map {|wn| %["#{wn}"]}
|
42
44
|
workspace_names = (names + quoted_names).grep(matcher)
|
43
|
-
workspace_names = workspace_names
|
44
|
-
if / / =~ wsn && /"/ !~ wsn
|
45
|
-
# if workspace name has a space and is not already quoted
|
46
|
-
%["#{ wsn }"]
|
47
|
-
else
|
48
|
-
wsn
|
49
|
-
end
|
50
|
-
}
|
45
|
+
workspace_names = quote_if_necessary workspace_names
|
51
46
|
commands = commands + workspace_names
|
52
47
|
end
|
53
48
|
else
|
@@ -55,21 +50,29 @@ module Qcmd
|
|
55
50
|
machine_names = Qcmd::Network.names
|
56
51
|
quoted_names = machine_names.map {|mn| %["#{mn}"]}
|
57
52
|
names = (quoted_names + machine_names).grep(matcher)
|
58
|
-
names = names
|
59
|
-
if / / =~ wsn && /"/ !~ wsn
|
60
|
-
# if workspace name has a space and is not already quoted
|
61
|
-
%["#{ wsn }"]
|
62
|
-
else
|
63
|
-
wsn
|
64
|
-
end
|
65
|
-
}
|
66
|
-
|
53
|
+
names = quote_if_necessary(names)
|
67
54
|
# unquote
|
68
55
|
commands = commands + names
|
69
56
|
end
|
70
57
|
|
71
58
|
commands
|
72
59
|
}
|
60
|
+
|
61
|
+
class << self
|
62
|
+
# if the name of a thing has a space in it, it must be surrounded by double
|
63
|
+
# quotes to be properly handled by the parser. so before we pass back
|
64
|
+
# unquoted space-containing results, we must quote them.
|
65
|
+
def quote_if_necessary names
|
66
|
+
names.map do |name|
|
67
|
+
if / / =~ name && /"/ !~ name
|
68
|
+
# if name has a space and is not already quoted
|
69
|
+
%["#{ name }"]
|
70
|
+
else
|
71
|
+
name
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
73
76
|
end
|
74
77
|
end
|
75
78
|
|
data/lib/qcmd/network.rb
CHANGED
@@ -2,11 +2,12 @@ require 'dnssd'
|
|
2
2
|
|
3
3
|
module Qcmd
|
4
4
|
class Network
|
5
|
-
BROWSE_TIMEOUT =
|
5
|
+
BROWSE_TIMEOUT = 8
|
6
6
|
|
7
7
|
class << self
|
8
8
|
attr_accessor :machines, :browse_thread
|
9
9
|
|
10
|
+
# browse can be used alone to populate the machines list
|
10
11
|
def browse
|
11
12
|
self.machines = []
|
12
13
|
self.browse_thread = Thread.start do
|
@@ -21,9 +22,9 @@ module Qcmd
|
|
21
22
|
changed = false
|
22
23
|
previous = 0
|
23
24
|
|
24
|
-
# sleep for
|
25
|
+
# sleep for BROWSE_TIMEOUT loops
|
25
26
|
while naps < BROWSE_TIMEOUT
|
26
|
-
sleep
|
27
|
+
sleep 0.2
|
27
28
|
naps += 1
|
28
29
|
|
29
30
|
if machines.size != previous
|
@@ -56,7 +57,7 @@ module Qcmd
|
|
56
57
|
|
57
58
|
def browse_and_display options={}
|
58
59
|
browse
|
59
|
-
if options[:machine_given] && !find(options[:machine_name]).nil?
|
60
|
+
if !options[:machine_given] || (options[:machine_given] && !find(options[:machine_name]).nil?)
|
60
61
|
display options
|
61
62
|
end
|
62
63
|
end
|
data/lib/qcmd/plaintext.rb
CHANGED
@@ -54,9 +54,14 @@ module Qcmd
|
|
54
54
|
|
55
55
|
# turn line into lines of text of columns length
|
56
56
|
def wrapped_text line
|
57
|
+
line = line.gsub(/\s+/, ' ') # collapse whitespace
|
57
58
|
word_wrap(line, :line_width => columns).split("\n")
|
58
59
|
end
|
59
60
|
|
61
|
+
def print_wrapped line
|
62
|
+
print wrapped_text(line)
|
63
|
+
end
|
64
|
+
|
60
65
|
def right_text line
|
61
66
|
diff = [(columns - line.size), 0].max
|
62
67
|
"%s%s" % [' ' * diff, line]
|
data/lib/qcmd/server.rb
CHANGED
@@ -167,7 +167,7 @@ module Qcmd
|
|
167
167
|
|
168
168
|
def connect_to_workspace workspace
|
169
169
|
if workspace.passcode?
|
170
|
-
send_command "workspace/#{workspace.id}/connect", workspace.passcode
|
170
|
+
send_command "workspace/#{workspace.id}/connect", "%04i" % workspace.passcode
|
171
171
|
else
|
172
172
|
send_command "workspace/#{workspace.id}/connect"
|
173
173
|
end
|
data/lib/qcmd/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qcmd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 5
|
10
|
+
version: 0.1.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Bachman
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-11-
|
18
|
+
date: 2012-11-21 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -161,7 +161,6 @@ files:
|
|
161
161
|
- Rakefile
|
162
162
|
- TODO.md
|
163
163
|
- bin/qcmd
|
164
|
-
- features/hello.feature
|
165
164
|
- features/support/setup.rb
|
166
165
|
- lib/qcmd.rb
|
167
166
|
- lib/qcmd/cli.rb
|
@@ -223,7 +222,6 @@ signing_key:
|
|
223
222
|
specification_version: 3
|
224
223
|
summary: QLab 3 console
|
225
224
|
test_files:
|
226
|
-
- features/hello.feature
|
227
225
|
- features/support/setup.rb
|
228
226
|
- spec/cli_spec.rb
|
229
227
|
- spec/commands_spec.rb
|
data/features/hello.feature
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
Feature: Hello
|
2
|
-
In order to render hello
|
3
|
-
As a CLI
|
4
|
-
I want to do the right thing
|
5
|
-
|
6
|
-
# Scenario: Phrase is default
|
7
|
-
# When I run `qcmd`
|
8
|
-
# Then the output should contain "hello world"
|
9
|
-
|
10
|
-
# Scenario: Phrase is given
|
11
|
-
# When I run `qcmd Tomato`
|
12
|
-
# Then the output should contain "Tomato"
|
13
|
-
|