Method: RemoteCodeRunner#retrieve

Defined in:
lib/coderunner/remote_code_runner.rb

#retrieve(string) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/coderunner/remote_code_runner.rb', line 144

def retrieve(string)
	#ep '@host', @host, '@remote_cache', @remote_cache
	filename = string.gsub(/[\/:\\\[\]\(\)]/, '.')
	if filename.size > 100
		require 'digest'
		filename = Digest::MD5.hexdigest(filename)
	end
   cachename = self.class.cache_folder(@host, @folder) + '/' + filename
	if @remote_cache == :auto and 	FileTest.exist?(cachename)
		data = eval(File.read(cachename))
     return data if not data.nil?
	end
	string = @libraries.map{|lib| "require #{lib}"}.join(";") + ";" + string

	eputs "Connecting to server using '#{@ssh_command}'..."
	eputs "Loading folder #{@folder}..."
	shell_script = <<EOF
cd #@folder
export ROWS=#{Terminal.terminal_size[0]}
export COLS=#{Terminal.terminal_size[1]}
source /etc/bashrc /etc/profile > /dev/null 2> /dev/null
#{%w{ .bash_login .bash_profile .profile .bashrc .rvm/scripts/rvm}.map{|w| "source $HOME/#{w} > /dev/null 2> /dev/null "}.join(" ; ")}
if [ "$CODE_RUNNER_COMMAND" ]
then
	$CODE_RUNNER_COMMAND runner_eval #{string.inspect} -Z #{@copts.inspect.inspect}
else
	coderunner runner_eval #{string.inspect} -Z #{@copts.inspect.inspect}
fi

EOF

	eputs shell_script if DISPLAY_REMOTE_INVOCATION
	data = %x[#@ssh_command '#{shell_script}']
		#ep data
	eputs "\nDisconnecting from server..."
	eprint "Extracting data..."
	data_arr = []
	in_dump = false
	i = 0
	loop do

		if  i>=80 #data.size
			break

		else  #if data[i-1] == "E" and data[i-2] == "_"
# 				ep data[i...(i + "code_runner_server_dump_start_E".size)], '.....'
# 			ep data[(-"code_runner_server_dump_end_E\n".size-i+1)..-i] if in_dump

# 				string = data[0...i]
# 			p string
			if !in_dump and data[i...(i + "code_runner_server_dump_start_E".size)] == "code_runner_server_dump_start_E" #   =~ /.*Begin Output\n\Z/
# 					ep "IN DUMP"
				data = data[(i + "code_runner_server_dump_start_E".size)..-1]
				in_dump = true
				i = 0
			elsif in_dump and data[(-"code_runner_server_dump_end_E\n".size-i+1)..-i] == "code_runner_server_dump_end_E\n" #
				data_arr.push data[0...(data.size - ("code_runner_server_dump_end_E\n".size+i-1))]
# 					ep "OUT DUMP"
# 				ep data_arr
# 					data = data[0...-(-"code_runner_server_dump_end_E".size-i)]
				in_dump = false
# 					i = 1
				break
			end
		end
		i+=1
	end

	eputs "done"
# 		ep data_arr; exit


	begin
		case data_arr.size
		when 0
			output = nil
		when 1
			output =  Marshal.load(data_arr[0])
		else
			output = data_arr.map{|str| Marshal.load(str)}
		end
	rescue TypeError, ArgumentError => err
		eputs err
		eputs data[0..100] if err.class == TypeError
		raise err unless err.message =~ /undefined class/
		self.class.repair_marshal_run_class_not_found_error(err)
		retry
	end

	if [:refresh, :auto].include? @remote_cache
		eputs "Writing Cache"
		File.open(cachename, 'w'){|file| file.puts(output.inspect)}
	end
	return output

end