remote-dcl 0.1.0

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