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 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
-