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 CHANGED
@@ -12,7 +12,7 @@ IT.**
12
12
 
13
13
  Install this gem to your machine by running the following command:
14
14
 
15
- $ gem install qcmd
15
+ $ sudo gem install qcmd
16
16
 
17
17
  That should do ya.
18
18
 
data/TODO.md CHANGED
@@ -1,3 +0,0 @@
1
- * make sure we can connect to workspaces
2
- * parse arguments with more finesse than String#split
3
- * make sure we can disconnect from workspaces / machines
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
- Qcmd.ascii_qlab
30
- Qcmd.print
31
- Qcmd.print Qcmd.centered_text(VERSION_STRING)
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
- connect_to_machine_by_name options[:machine], options[:machine_passcode]
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
- connect_to_workspace_by_name options[:workspace], options[:workspace_passcode]
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
- print "You must be connected to a workspace before you can view a cue list."
135
- elsif Qcmd.context.workspace.cues
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
- when 'cue'
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
- print wrapped_text("available cue commands are: #{Qcmd::InputCompleter::ReservedCueWords.inspect}")
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
- print wrapped_text("no workspace command given. available workspace commands are: #{Qcmd::InputCompleter::ReservedWorkspaceWords.inspect}")
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
- server.send_command(command, *args)
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
- print centered_text(" Workspaces ", '-')
13
- print
14
- Qcmd.context.machine.workspaces.each_with_index do |ws, n|
15
- print "#{ n + 1 }. #{ ws.name }"
16
- end
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
- print
19
- print wrapped_text('Type `use "WORKSPACE_NAME" PASSCODE` to load a workspace. ' +
20
- 'Only enter a passcode if your workspace uses one')
21
- print
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)]
@@ -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.map {|wsn|
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.map {|wsn|
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 = 2
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 3 seconds
25
+ # sleep for BROWSE_TIMEOUT loops
25
26
  while naps < BROWSE_TIMEOUT
26
- sleep 1
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Qcmd
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
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: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 4
10
- version: 0.1.4
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-16 00:00:00 -05:00
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
@@ -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
-