remote-dcl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in remote-dcl.gemspec
4
+ gemspec
@@ -0,0 +1,34 @@
1
+ Remote-DCL is copyrighted free software by Seiya Nishizawa and GFD
2
+ Dennou Club (http://www.gfd-dennou.org/).
3
+
4
+ Copyright 2012 (C) Seiya Nishizawa and GFD Dennou Club
5
+ (http://www.gfd-dennou.org/) All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are
9
+ met:
10
+
11
+ 1. Redistributions of source code must retain the above copyright
12
+ notice, this list of conditions and the following disclaimer.
13
+
14
+ 2. Redistributions in binary form must reproduce the above copyright
15
+ notice, this list of conditions and the following disclaimer in
16
+ the documentation and/or other materials provided with the
17
+ distribution.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY GFD DENNOU CLUB AND CONTRIBUTORS ``AS IS''
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GFD DENNOU CLUB OR
23
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ The views and conclusions contained in the software and documentation
32
+ are those of the authors and should not be interpreted as representing
33
+ official policies, either expressed or implied, of Seiya Nishizawa
34
+ and GFD Dennou Club.
@@ -0,0 +1,67 @@
1
+ = Remote-DCL
2
+ - A tool to execute DCL scripts at a remote server -
3
+
4
+ == What's Remote-DCL
5
+ Remote-DCL is a Ruby script to execute a script at a remote server.
6
+ DCL calles in the script creates PNG images at the remote,
7
+ and send them to local and then display the images.
8
+ It avoid X connection between the local and the remote,
9
+ so could reduce execution time.
10
+
11
+
12
+ == Requires
13
+ * At remote server
14
+ * <a href="http://www.ruby-lang.org/">Ruby</a>
15
+ * Ruby libraries which are required in your script (including DCL)
16
+ * stdbuf command
17
+ * ssh server
18
+ * Xvfb
19
+ xvfb-run command (optional)
20
+ * At local
21
+ * <a href="http://www.ruby-lang.org/">Ruby</a>
22
+ * <a href="http://ruby-gnome2.sourceforge.jp/ja/">Ruby/GTK2,Ruby/GdkPixbuf2</a>
23
+ * ssh client
24
+
25
+
26
+ == Install / Download
27
+ === RubyGems
28
+ % gem install remote-dcl
29
+
30
+ === repository
31
+ You can get from the git repository
32
+ % git clone http://ruby.gfd-dennou.org/products/remote-dcl/remote-dcl.git
33
+ or the repository snapshot, <a href="./remote-dcl-snapshot.tar.gz">remote-dcl-snapshot.tar.gz</a>.
34
+
35
+
36
+ == Documents
37
+ === Usage
38
+ ==== At remote server
39
+ If you do not use xvfb-run command,
40
+ you should lounch Xvfb server before execution of remote-dcl.rb.
41
+ e.g.)
42
+ % Xvfb :99 -screen 0 640x480x8 -nolisten tcp
43
+
44
+ Note: xvfb-run command lounch Xvfb server internally, and the lounching is occuer at every execution of remote-dcl.rb.
45
+ It takes some seconds, so lounching Xvfb server by your self reduces execution time of remote-dcl.rb.
46
+
47
+ ==== At local
48
+ % ruby remote-dcl.rb yourescript.rb server_name [--display=] [--dir=]
49
+ * yourscript.rb:
50
+ script name which is executed at the remote server
51
+ * server_name:
52
+ server name at which the script is execued.
53
+ * display (optional):
54
+ x server number of Xvfb (e.g. --display=:99).
55
+ If this is ommited, xvfb-run comand is used.
56
+ * dir (optional):
57
+ directory name of the remote server at which the script is executed.
58
+ If this is ommited, the script is executed at the home directory.
59
+
60
+ === User Interface
61
+ Actions with key and mouse events are the followings:
62
+ * return key, space key, mouse click:
63
+ go the next frame
64
+ * "s" key:
65
+ skip wait and go the next frame automatically
66
+ * "q" key:
67
+ quit
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new
5
+ task :default => :test
@@ -0,0 +1,274 @@
1
+ def usage(error = false)
2
+ print "Usage: ruby #$0 scriptname host [--display=:99] [--dir=directory]\n"
3
+ print "\n"
4
+ print " Note: If xvfb-run does not exit at remote server,\n"
5
+ print " run Xvfb at the remote server before execution of this script:\n"
6
+ print " e.g.) % Xvfb :99 -screen 0 640x480x8 -nolisten tcp\n"
7
+ exit(error ? 1 : 0)
8
+ end
9
+
10
+ usage if ARGV.index("--help") || ARGV.index("-h")
11
+ opts = {
12
+ "display" => nil,
13
+ "dir" => nil
14
+ }
15
+ opts.keys.each do |name|
16
+ ARGV.dup.each do |opt|
17
+ next unless /\A--#{name}/ =~ opt
18
+ val = $' && $'[1..-1]
19
+ case name
20
+ when "display", "dir"
21
+ opts[name] = val
22
+ end
23
+ ARGV.delete(opt)
24
+ end
25
+ end
26
+
27
+ script = ARGV.shift || usage(true)
28
+ host = ARGV.shift || usage(true)
29
+
30
+
31
+
32
+
33
+ dcl_code = File.read(script)
34
+ remote_code = <<EOC
35
+ pin, pout = IO.pipe
36
+ pid = fork do
37
+ REMOTE_DCL_FNAME = 'remote_dcl'
38
+ pin.close
39
+ # STDOUT.reopen('/dev/null')
40
+ STDOUT.reopen(STDERR)
41
+ require 'numru/dcl'
42
+ require 'base64'
43
+ require 'fileutils'
44
+ pout.sync = true
45
+ POUT = pout
46
+
47
+ module NumRu
48
+ module DCL
49
+ @@page = 0
50
+ @@wait = true
51
+ alias :__gropn :gropn
52
+ def gropn(iws)
53
+ swcset('fname', REMOTE_DCL_FNAME)
54
+ swlset('lwnd', false)
55
+ __gropn(4)
56
+ end
57
+ module_function :__gropn, :gropn
58
+ private_class_method :__gropn
59
+
60
+ alias :__grfrm :grfrm
61
+ def grfrm
62
+ __grfrm
63
+ if @@page > 0
64
+ __send_png(@@page)
65
+ __wait
66
+ end
67
+ @@page += 1
68
+ end
69
+ module_function :__grfrm, :grfrm
70
+ private_class_method :__grfrm
71
+
72
+ alias :__grcls :grcls
73
+ def grcls
74
+ __grcls
75
+ __send_png(@@page)
76
+ end
77
+ module_function :__grcls, :grcls
78
+ private_class_method :__grcls
79
+
80
+ private
81
+ def __send_png(page)
82
+ # STDERR.print "send_png\\n"
83
+ fname = REMOTE_DCL_FNAME+'_%03d'%page+'.png'
84
+ raise('cannot find PNG file') unless File.exist?(fname)
85
+ POUT.print Base64.encode64(File.read(fname)),"\\n"
86
+ POUT.flush
87
+ end
88
+ module_function :__send_png
89
+
90
+ def __wait
91
+ return unless @@wait
92
+ c = gets
93
+ c = c ? c.chop : "q"
94
+ # STDERR.print c,"\\n"
95
+ case c
96
+ when 'n'
97
+ when 's'
98
+ @@wait = false
99
+ when 'q'
100
+ __grcls
101
+ exit(0)
102
+ else
103
+ raise 'received unexpected signal ('+c+')'
104
+ end
105
+ end
106
+ module_function :__wait
107
+
108
+ end # module DCL
109
+ end # module NumRu
110
+
111
+ line = __LINE__ + 1
112
+ begin
113
+ #{dcl_code}
114
+ rescue => error
115
+ backtrace = error.backtrace[0..-3].map do |s|
116
+ a = s.split(':')
117
+ a[0] = 'yourscript.rb' if a[0] == '-e'
118
+ a[1] = a[1].to_i - line
119
+ a.join(':')
120
+ end
121
+ raise error.class, error.message, backtrace
122
+ ensure
123
+ Dir[REMOTE_DCL_FNAME+'_*.png'].each do |fname|
124
+ FileUtils.rm(fname)
125
+ end
126
+ pout.close
127
+ end
128
+ end # fork
129
+ pout.close
130
+ while line = pin.gets
131
+ print line
132
+ end
133
+ Process.wait(pid)
134
+ EOC
135
+
136
+
137
+ def escape(str)
138
+ str.gsub!("\\"){"\\\\"}
139
+ str.gsub!(/"/,'\"')
140
+ end
141
+
142
+ escape remote_code
143
+ #cmd = "ruby -e \"#{remote_code}\""
144
+ cmd = "stdbuf -i0 -o0 -e0 ruby -e \"#{remote_code}\""
145
+
146
+ class Viewer
147
+ def initialize(io)
148
+ @window = Gtk::Window.new
149
+ @window.realize
150
+ @drawable = @window.window
151
+ @gc = Gdk::GC.new(@drawable)
152
+ @pixbuf = nil
153
+ @wait = true
154
+ @window.add_events(Gdk::Event::BUTTON_RELEASE_MASK)
155
+ @window.signal_connect("expose_event") do |w,e|
156
+ expose
157
+ end
158
+ @window.signal_connect("button_release_event") do |w,e|
159
+ next_fig
160
+ true
161
+ end
162
+ @window.signal_connect("key_release_event") do |w,e|
163
+ c = Gdk::Keyval.to_name(e.keyval)
164
+ case c
165
+ when "Return", "space", "n"
166
+ next_fig
167
+ when "s"
168
+ print "skip waiting\n"
169
+ @io.puts c
170
+ when "q"
171
+ quit
172
+ end
173
+ true
174
+ end
175
+ @window.signal_connect("delete_event") do
176
+ quit
177
+ false
178
+ end
179
+ @io = io
180
+ end
181
+ def eof=(boolean)
182
+ @eof = true
183
+ end
184
+ def eof
185
+ return @eof if @eof
186
+ @eof = @io.closed?
187
+ end
188
+ def next_fig
189
+ if eof
190
+ quit
191
+ elsif @wait
192
+ print "next\n"
193
+ @io.puts "n"
194
+ @io.flush
195
+ @wait = false
196
+ end
197
+ end
198
+ def quit
199
+ unless @quit
200
+ print "quit\n"
201
+ begin
202
+ @io.puts("q") unless eof
203
+ @io.flush
204
+ rescue
205
+ end
206
+ Gtk.main_quit
207
+ @quit = true
208
+ end
209
+ end
210
+ def expose
211
+ if @pixbuf
212
+ @drawable.draw_pixbuf(@gc, @pixbuf, 0, 0, 0, 0, -1, -1,
213
+ Gdk::RGB::DITHER_NONE, 0, 0)
214
+ end
215
+ end
216
+ def render(png)
217
+ print "render\n"
218
+ loader = Gdk::PixbufLoader.open("png")
219
+ loader.last_write(png)
220
+ @pixbuf = loader.pixbuf
221
+ expose
222
+ @window.set_size_request(@pixbuf.width, @pixbuf.height)
223
+ # @window.resize(@pixbuf.width, @pixbuf.height)
224
+ @window.show_all
225
+ @wait = true
226
+ end
227
+
228
+ end
229
+
230
+
231
+ escape cmd
232
+ cmd = "cd #{opts["dir"]} ; " + cmd if opts["dir"]
233
+ if opts["display"]
234
+ cmd = "DISPLAY=#{opts["display"]} #{cmd}"
235
+ else
236
+ cmd = "xvfb-run sh -c \"#{cmd} 2> /dev/null\""
237
+ escape cmd
238
+ end
239
+ cmd = "ssh #{host} \"#{cmd}\""
240
+
241
+ IO.popen(cmd, "r+") do |io|
242
+ begin
243
+ require "rubygems"
244
+ rescue LoadError
245
+ end
246
+ require "gtk2"
247
+ require "base64"
248
+ io.sync = true
249
+ str = ""
250
+ Gtk.init
251
+ viewer = Viewer.new(io)
252
+ t = Thread.new {
253
+ Thread.pass
254
+ Gtk.main
255
+ }
256
+ begin
257
+ any = false
258
+ while (c = io.gets)
259
+ any = true
260
+ if c == "\n"
261
+ png = Base64.decode64(str)
262
+ viewer.render(png)
263
+ str = ""
264
+ else
265
+ str << c
266
+ end
267
+ end
268
+ viewer.eof = true
269
+ viewer.quit unless any
270
+ ensure
271
+ io.close
272
+ end
273
+ t.join
274
+ end
@@ -0,0 +1,3 @@
1
+ module RemoteDCL
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "remote-dcl/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "remote-dcl"
7
+ s.version = RemoteDCL::VERSION
8
+ s.authors = ["Seiya Nishizawa"]
9
+ s.email = ["seiya@gfd-dennou.org"]
10
+ s.homepage = "http://ruby.gfd-dennou.org/products/remote-dcl/"
11
+ s.summary = %q{A tool to execute DCL scripts at a remote server}
12
+ s.description = %q{Remote-DCL is a Ruby script to execute a script at a remote server.
13
+ DCL calles in the script creates PNG images at the remote,
14
+ and send them to local and then display the images.
15
+ It avoid X connection between the local and the remote,
16
+ so could reduce execution time.}
17
+
18
+
19
+ s.rubyforge_project = "remote-dcl"
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+ s.bindir = "bin"
26
+ #s.extensions << "ext/extconf.rb"
27
+
28
+ # specify any dependencies here; for example:
29
+ #s.add_development_dependency "rspec"
30
+ s.add_runtime_dependency "gtk2"
31
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remote-dcl
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Seiya Nishizawa
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-01-24 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: gtk2
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: |-
35
+ Remote-DCL is a Ruby script to execute a script at a remote server.
36
+ DCL calles in the script creates PNG images at the remote,
37
+ and send them to local and then display the images.
38
+ It avoid X connection between the local and the remote,
39
+ so could reduce execution time.
40
+ email:
41
+ - seiya@gfd-dennou.org
42
+ executables:
43
+ - remote-dcl
44
+ extensions: []
45
+
46
+ extra_rdoc_files: []
47
+
48
+ files:
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.rdoc
52
+ - Rakefile
53
+ - bin/remote-dcl
54
+ - lib/remote-dcl/version.rb
55
+ - remote-dcl.gemspec
56
+ homepage: http://ruby.gfd-dennou.org/products/remote-dcl/
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options: []
61
+
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ hash: 3
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 3
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ requirements: []
83
+
84
+ rubyforge_project: remote-dcl
85
+ rubygems_version: 1.8.11
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: A tool to execute DCL scripts at a remote server
89
+ test_files: []
90
+