class WebSandboxConsole::Sandbox
Attributes
code[RW]
exe_tmp_file[RW]
pass_auth[RW]
uuid[RW]
Public Class Methods
new(code = nil, pass_auth = false)
click to toggle source
# File lib/web_sandbox_console/sandbox.rb, line 8 def initialize(code = nil, pass_auth = false) @code = code @uuid = SecureRandom.uuid @pass_auth = pass_auth.presence || false @exe_tmp_file = "#{Rails.root}/tmp/sandbox/#{uuid}.rb" end
Public Instance Methods
add_tmp_file_dir()
click to toggle source
添加临时文件目录
# File lib/web_sandbox_console/sandbox.rb, line 84 def add_tmp_file_dir FileUtils.mkdir_p(tmp_file_dir) unless File.directory?(tmp_file_dir) end
asyn_evalotor()
click to toggle source
异步后台执行
# File lib/web_sandbox_console/sandbox.rb, line 24 def asyn_evalotor evalotor_block do Thread.new {exec_rails_runner} ["已在后台执行,请耐心等待😊"] end end
auto_clean_tmp_file()
click to toggle source
自动删除临时文件
# File lib/web_sandbox_console/sandbox.rb, line 94 def auto_clean_tmp_file FileUtils.rm_rf(Dir["#{tmp_file_dir}/*"]) if tmp_file_need_clean? end
check_syntax()
click to toggle source
检查 语法
# File lib/web_sandbox_console/sandbox.rb, line 112 def check_syntax prepare_check_syntax unless `ruby -c #{self.exe_tmp_file}`.include?('Syntax OK') raise SandboxError, "存在语法错误" end end
evalotor()
click to toggle source
同步执行
# File lib/web_sandbox_console/sandbox.rb, line 16 def evalotor evalotor_block do exec_rails_runner get_result end end
evalotor_block() { || ... }
click to toggle source
执行结构块
# File lib/web_sandbox_console/sandbox.rb, line 32 def evalotor_block begin check_syntax write_exe_tmp_file yield rescue SandboxError => e [e.message] rescue Exception => e ["发生未知错误: #{e.inspect};#{e.backtrace[0..2].join('\r\n')}"] end end
exec_rails_runner()
click to toggle source
运行rails runner
# File lib/web_sandbox_console/sandbox.rb, line 120 def exec_rails_runner @stdout = `RAILS_ENV=#{Rails.env} bundle exec rails runner #{self.exe_tmp_file}` end
get_result()
click to toggle source
最终结果
# File lib/web_sandbox_console/sandbox.rb, line 134 def get_result if @stdout.present? stdout_arr = ['------------ 打印值 ----------'] stdout_arr.concat(@stdout.to_s.split("\n")) stdout_arr << '------------ 返回值 ----------' stdout_arr.concat(return_result_arr) else return_result_arr end end
no_rollback_code()
click to toggle source
不回滚code
# File lib/web_sandbox_console/sandbox.rb, line 72 def no_rollback_code <<-EOF result = eval(#{self.code.inspect}) EOF end
prepare_check_syntax()
click to toggle source
准备检查语法
# File lib/web_sandbox_console/sandbox.rb, line 106 def prepare_check_syntax add_tmp_file_dir File.open(self.exe_tmp_file, 'w'){|f| f << self.code} end
return_result_arr()
click to toggle source
返回结果
# File lib/web_sandbox_console/sandbox.rb, line 125 def return_result_arr last_10_lines = `tail -n 100 #{WebSandboxConsole.log_path} | grep #{self.uuid}` last_10_lines.split("\n").map do |line| line.split("#{self.uuid}:").last.split("|||") end.flatten end
rollback_code()
click to toggle source
回滚code
# File lib/web_sandbox_console/sandbox.rb, line 62 def rollback_code <<-EOF ActiveRecord::Base.transaction(requires_new: true) do result = eval(#{self.code.inspect}) raise ActiveRecord::Rollback end EOF end
runner_code()
click to toggle source
# File lib/web_sandbox_console/sandbox.rb, line 44 def runner_code str =<<-CODE result = nil begin WebSandboxConsole.current_uuid("#{self.uuid}") WebSandboxConsole.init_safe_env WebSandboxConsole.logger_sql #{self.pass_auth ? no_rollback_code : rollback_code} rescue Exception => e WebSandboxConsole.log_p(e) rescue SyntaxError => e WebSandboxConsole.log_p(e) end WebSandboxConsole.log_p(result) CODE end
tmp_file_dir()
click to toggle source
临时文件目录
# File lib/web_sandbox_console/sandbox.rb, line 79 def tmp_file_dir File.dirname(self.exe_tmp_file) end
tmp_file_need_clean?()
click to toggle source
临时文件 需要清理?
# File lib/web_sandbox_console/sandbox.rb, line 89 def tmp_file_need_clean? Dir["#{tmp_file_dir}/*"].count > 6 end
write_exe_tmp_file()
click to toggle source
写入 执行临时文件
# File lib/web_sandbox_console/sandbox.rb, line 99 def write_exe_tmp_file add_tmp_file_dir auto_clean_tmp_file File.open(self.exe_tmp_file, 'w'){|f| f << runner_code} end