qcmd 0.1.4 → 0.1.5
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.
- 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
|
-
|