From 09116c1ab91677f950b7e4795d7a31324253be6d Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Mon, 4 Jan 2016 00:02:21 +0900 Subject: 🔪 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++ Gemfile | 8 ++- Gemfile.lock | 34 +++++++-- app/assets/javascripts/application.js | 6 +- app/assets/javascripts/cable.coffee | 11 --- app/assets/javascripts/channels/.keep | 0 app/assets/javascripts/results.es6 | 2 + app/assets/javascripts/snippets.es6 | 53 ++++++++++++++ app/assets/javascripts/snippets.js | 2 - app/assets/stylesheets/application.css | 15 ---- app/assets/stylesheets/application.scss | 4 ++ app/assets/stylesheets/results.scss | 3 + app/assets/stylesheets/scaffold.css | 84 ---------------------- app/assets/stylesheets/snippets.css | 4 -- app/assets/stylesheets/snippets.scss | 4 ++ app/channels/application_cable/channel.rb | 5 -- app/channels/application_cable/connection.rb | 5 -- app/controllers/application_controller.rb | 3 + app/controllers/results_controller.rb | 20 ++++++ app/controllers/snippets_controller.rb | 30 +------- app/helpers/application_helper.rb | 3 + app/helpers/results_helper.rb | 2 + app/jobs/execute_job.rb | 8 ++- app/models/compiler.rb | 58 +++++++++++---- app/models/result.rb | 40 +++++++++++ app/models/snippet.rb | 14 +++- app/views/layouts/application.html.erb | 21 ++++-- app/views/results/_result.html.erb | 16 +++++ app/views/snippets/_form.html.erb | 45 ++++++------ app/views/snippets/edit.html.erb | 6 -- app/views/snippets/index.html.erb | 29 -------- app/views/snippets/new.html.erb | 6 +- app/views/snippets/show.html.erb | 18 ++--- config.ru | 4 -- config/application.rb | 2 +- config/routes.rb | 19 +++-- db/migrate/20160101024323_extend_result.rb | 6 ++ ...20160101060555_add_command_line_to_compilers.rb | 5 ++ .../20160101121151_add_language_to_snippet.rb | 5 ++ db/schema.rb | 14 ++-- db/seeds.rb | 5 -- 41 files changed, 340 insertions(+), 283 deletions(-) delete mode 100644 app/assets/javascripts/cable.coffee delete mode 100644 app/assets/javascripts/channels/.keep create mode 100644 app/assets/javascripts/results.es6 create mode 100644 app/assets/javascripts/snippets.es6 delete mode 100644 app/assets/javascripts/snippets.js delete mode 100644 app/assets/stylesheets/application.css create mode 100644 app/assets/stylesheets/application.scss create mode 100644 app/assets/stylesheets/results.scss delete mode 100644 app/assets/stylesheets/scaffold.css delete mode 100644 app/assets/stylesheets/snippets.css create mode 100644 app/assets/stylesheets/snippets.scss delete mode 100644 app/channels/application_cable/channel.rb delete mode 100644 app/channels/application_cable/connection.rb create mode 100644 app/controllers/results_controller.rb create mode 100644 app/helpers/results_helper.rb create mode 100644 app/views/results/_result.html.erb delete mode 100644 app/views/snippets/edit.html.erb delete mode 100644 app/views/snippets/index.html.erb create mode 100644 db/migrate/20160101024323_extend_result.rb create mode 100644 db/migrate/20160101060555_add_command_line_to_compilers.rb create mode 100644 db/migrate/20160101121151_add_language_to_snippet.rb diff --git a/.gitignore b/.gitignore index 9df4381..59e4c48 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,7 @@ # Vim .*.sw* + +# Playground +playground/base +playground/ruby diff --git a/Gemfile b/Gemfile index 0f4aec0..cd48405 100644 --- a/Gemfile +++ b/Gemfile @@ -6,11 +6,14 @@ gem "sidekiq" gem "sinatra", require: false gem "sprockets" +gem "sass-rails" gem "uglifier", ">= 1.3.0" gem "sprockets-es6" -gem "turbolinks" +gem "jquery-rails" +gem "bootstrap-sass" +gem "codemirror-rails" -gem "puma" +gem "plum" group :development, :test do gem "byebug" @@ -18,4 +21,5 @@ end group :development do gem "web-console", "~> 3.0" + gem "quiet_assets" end diff --git a/Gemfile.lock b/Gemfile.lock index f05b7d5..0e0427f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -46,10 +46,16 @@ GEM minitest (~> 5.1) tzinfo (~> 1.1) arel (7.0.0) + autoprefixer-rails (6.2.3) + execjs + json babel-source (5.8.34) babel-transpiler (0.7.0) babel-source (>= 4.0, < 6) execjs (~> 2.0) + bootstrap-sass (3.3.6) + autoprefixer-rails (>= 5.2.1) + sass (>= 3.3.4) builder (3.2.2) byebug (8.2.1) celluloid (0.17.2) @@ -69,6 +75,8 @@ GEM timers (>= 4.1.1) celluloid-supervision (0.20.5) timers (>= 4.1.1) + codemirror-rails (5.6) + railties (>= 3.0, < 5) coffee-rails (4.1.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.1.x) @@ -93,6 +101,10 @@ GEM hiredis (0.5.2) hitimes (1.2.3) i18n (0.7.0) + jquery-rails (4.0.5) + rails-dom-testing (~> 1.0) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) json (1.8.3) loofah (2.0.3) nokogiri (>= 1.5.9) @@ -105,7 +117,9 @@ GEM mysql2 (0.4.2) nokogiri (1.6.7.1) mini_portile2 (~> 2.0.0.rc2) - puma (2.15.3) + plum (0.2.8) + quiet_assets (1.1.0) + railties (>= 3.1, < 5.0) rack (2.0.0.alpha) json rack-test (0.6.3) @@ -138,6 +152,13 @@ GEM thor (>= 0.18.1, < 2.0) rake (10.4.2) redis (3.2.2) + sass (3.4.20) + sass-rails (5.0.4) + railties (>= 4.0.0, < 5.0) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (>= 1.1, < 3) sidekiq (4.0.1) concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) @@ -158,10 +179,9 @@ GEM sprockets (>= 3.0.0) thor (0.19.1) thread_safe (0.3.5) + tilt (2.0.1) timers (4.1.1) hitimes - turbolinks (2.5.3) - coffee-rails tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (2.7.2) @@ -179,15 +199,19 @@ PLATFORMS ruby DEPENDENCIES + bootstrap-sass byebug + codemirror-rails + jquery-rails mysql2 (>= 0.3.18, < 0.5) - puma + plum + quiet_assets rails (>= 5.0.0.beta1, < 5.1) + sass-rails sidekiq sinatra sprockets sprockets-es6 - turbolinks uglifier (>= 1.3.0) web-console (~> 3.0) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index b12018d..dfb23a2 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,5 +12,9 @@ // //= require jquery //= require jquery_ujs -//= require turbolinks +//= require bootstrap-sprockets +//= require codemirror +//= require codemirror/modes/ruby +//= require codemirror/addons/edit/matchbrackets +//= require codemirror/addons/edit/closebrackets //= require_tree . diff --git a/app/assets/javascripts/cable.coffee b/app/assets/javascripts/cable.coffee deleted file mode 100644 index 49a7cfa..0000000 --- a/app/assets/javascripts/cable.coffee +++ /dev/null @@ -1,11 +0,0 @@ -# Action Cable provides the framework to deal with WebSockets in Rails. -# You can generate new channels where WebSocket features live using the rails generate channel command. -# -# Turn on the cable connection by removing the comments after the require statements (and ensure it's also on in config/routes.rb). -# -#= require action_cable -#= require_self -#= require_tree ./channels -# -# @App ||= {} -# App.cable = ActionCable.createConsumer() diff --git a/app/assets/javascripts/channels/.keep b/app/assets/javascripts/channels/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/app/assets/javascripts/results.es6 b/app/assets/javascripts/results.es6 new file mode 100644 index 0000000..dee720f --- /dev/null +++ b/app/assets/javascripts/results.es6 @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/snippets.es6 b/app/assets/javascripts/snippets.es6 new file mode 100644 index 0000000..d3c3be1 --- /dev/null +++ b/app/assets/javascripts/snippets.es6 @@ -0,0 +1,53 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. + +const codeField = document.querySelector("#code-field"); +if (codeField !== null) { + const origTextarea = codeField.querySelector("textarea[name=\"snippet[code]\"]"); + const codeMirror = CodeMirror.fromTextArea(origTextarea, { + mode: "ruby", + lineNumbers: true, + }); + codeMirror.on("change", cm => cm.save()); +} + +const agg = (elm, n) => { + if (!n) n = 0; + n++; + setTimeout(() => { + $.ajax({ + type: "GET", + url: "/results/" + elm.getAttribute("data-id"), + dataType: "text", + success: (text, st) => { + console.log(text); + elm.outerHTML = text; + if (n < 3) agg(elm, n); + } + }); + }, 1000); +}; + +const refresher = () => { + const runnings = document.querySelectorAll(".result-item[data-status=running]"); + for (var i = 0, len = runnings.length; i < len; i++) { + agg(runnings[i]); + } +}; +refresher(); + +const notrans = document.querySelectorAll(".result-item[data-status=notran]"); +const snippet_id = document.querySelector("#snippet-id").innerHTML; +for (var i = 0, len = notrans.length; i < len; i++) { + const elm = notrans[i]; + $.ajax({ + type: "POST", + url: "/results/run", + dataType: "text", + data: { compiler_id: elm.getAttribute("data-compiler-id"), snippet_id: snippet_id }, + success: (text, st) => { + console.log(text); + elm.outerHTML = text; + } + }); +} diff --git a/app/assets/javascripts/snippets.js b/app/assets/javascripts/snippets.js deleted file mode 100644 index dee720f..0000000 --- a/app/assets/javascripts/snippets.js +++ /dev/null @@ -1,2 +0,0 @@ -// Place all the behaviors and hooks related to the matching controller here. -// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css deleted file mode 100644 index 0ebd7fe..0000000 --- a/app/assets/stylesheets/application.css +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the bottom of the - * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS - * files in this directory. Styles in this file should be added after the last require_* statement. - * It is generally better to create a new file per style scope. - * - *= require_tree . - *= require_self - */ diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss new file mode 100644 index 0000000..37928eb --- /dev/null +++ b/app/assets/stylesheets/application.scss @@ -0,0 +1,4 @@ +@import "bootstrap-sprockets"; +@import "bootstrap"; +@import "codemirror"; +@import "./*"; diff --git a/app/assets/stylesheets/results.scss b/app/assets/stylesheets/results.scss new file mode 100644 index 0000000..07dafa5 --- /dev/null +++ b/app/assets/stylesheets/results.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the results controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/scaffold.css b/app/assets/stylesheets/scaffold.css deleted file mode 100644 index 79f8b7f..0000000 --- a/app/assets/stylesheets/scaffold.css +++ /dev/null @@ -1,84 +0,0 @@ -body { - background-color: #fff; - color: #333; -} - -body, p, ol, ul, td { - font-family: verdana, arial, helvetica, sans-serif; - font-size: 13px; - line-height: 18px; - margin: 33px; -} - -pre { - background-color: #eee; - padding: 10px; - font-size: 11px; -} - -a { - color: #000; -} - -a:visited { - color: #666; -} - -a:hover { - color: #fff; - background-color: #000; -} - -th { - padding-bottom: 5px; -} - -td { - padding-bottom: 7px; - padding-left: 5px; - padding-right: 5px; -} - -div.field, -div.actions { - margin-bottom: 10px; -} - -#notice { - color: green; -} - -.field_with_errors { - padding: 2px; - background-color: red; - display: table; -} - -#error_explanation { - width: 450px; - border: 2px solid red; - padding: 7px; - padding-bottom: 0; - margin-bottom: 20px; - background-color: #f0f0f0; -} - -#error_explanation h2 { - text-align: left; - font-weight: bold; - padding: 5px 5px 5px 15px; - font-size: 12px; - margin: -7px; - margin-bottom: 0; - background-color: #c00; - color: #fff; -} - -#error_explanation ul li { - font-size: 12px; - list-style: square; -} - -label { - display: block; -} diff --git a/app/assets/stylesheets/snippets.css b/app/assets/stylesheets/snippets.css deleted file mode 100644 index afad32d..0000000 --- a/app/assets/stylesheets/snippets.css +++ /dev/null @@ -1,4 +0,0 @@ -/* - Place all the styles related to the matching controller here. - They will automatically be included in application.css. -*/ diff --git a/app/assets/stylesheets/snippets.scss b/app/assets/stylesheets/snippets.scss new file mode 100644 index 0000000..afad32d --- /dev/null +++ b/app/assets/stylesheets/snippets.scss @@ -0,0 +1,4 @@ +/* + Place all the styles related to the matching controller here. + They will automatically be included in application.css. +*/ diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb deleted file mode 100644 index 438c841..0000000 --- a/app/channels/application_cable/channel.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Be sure to restart your server when you modify this file. Action Cable runs in an EventMachine loop that does not support auto reloading. -module ApplicationCable - class Channel < ActionCable::Channel::Base - end -end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb deleted file mode 100644 index 965046f..0000000 --- a/app/channels/application_cable/connection.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Be sure to restart your server when you modify this file. Action Cable runs in an EventMachine loop that does not support auto reloading. -module ApplicationCable - class Connection < ActionCable::Connection::Base - end -end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d83690e..607f101 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,4 +2,7 @@ class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception + + def not_found + end end diff --git a/app/controllers/results_controller.rb b/app/controllers/results_controller.rb new file mode 100644 index 0000000..60ade5a --- /dev/null +++ b/app/controllers/results_controller.rb @@ -0,0 +1,20 @@ +class ResultsController < ApplicationController + before_action :set_result, only: [:show] + + def run + compiler = Compiler.find(params[:compiler_id]) + snippet = Snippet.find(params[:snippet_id]) + @result = compiler.run(snippet) + + show + end + + def show + render text: render_to_string(partial: "results/result", locals: { result: @result, compiler: @result.compiler }), content_type: "text/plain" + end + + private + def set_result + @result = Result.find(params[:id]) + end +end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 7d6f1b3..6fe26b1 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -1,12 +1,6 @@ class SnippetsController < ApplicationController before_action :set_snippet, only: [:show] - # GET /snippets - # TODO - # def index - # @snippets = Snippet.all - # end - # GET /1234 def show end @@ -16,11 +10,6 @@ class SnippetsController < ApplicationController @snippet = Snippet.new end - # GET /snippets/1/edit - # TODO - # def edit - # end - # POST /create def create @snippet = Snippet.new(snippet_params) @@ -32,23 +21,6 @@ class SnippetsController < ApplicationController end end - # PATCH/PUT /snippets/1 - # TODO - # def update - # if @snippet.update(snippet_params) - # redirect_to @snippet, notice: "Snippet was successfully updated." - # else - # render :edit - # end - # end - - # DELETE /snippets/1 - # TODO - # def destroy - # @snippet.destroy - # redirect_to snippets_url, notice: "Snippet was successfully destroyed." - # end - private # Use callbacks to share common setup or constraints between actions. def set_snippet @@ -57,6 +29,6 @@ class SnippetsController < ApplicationController # Only allow a trusted parameter "white list" through. def snippet_params - params.require(:snippet).permit(:title, :code) + params.require(:snippet).permit(:title, :code, :language) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be79..2394f77 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,5 @@ module ApplicationHelper + def application_name + Rails.application.class.to_s.split("::").first + end end diff --git a/app/helpers/results_helper.rb b/app/helpers/results_helper.rb new file mode 100644 index 0000000..c3fd7a5 --- /dev/null +++ b/app/helpers/results_helper.rb @@ -0,0 +1,2 @@ +module ResultsHelper +end diff --git a/app/jobs/execute_job.rb b/app/jobs/execute_job.rb index f5dd436..1d05aba 100644 --- a/app/jobs/execute_job.rb +++ b/app/jobs/execute_job.rb @@ -1,7 +1,11 @@ class ExecuteJob < ApplicationJob queue_as :default - def perform(compiler, snippet) - compiler.run! snippet + def perform(compiler, snippet, result = nil) + if result + compiler.run_body(snippet, result) + else + compiler.run(snippet) + end end end diff --git a/app/models/compiler.rb b/app/models/compiler.rb index 7cf7152..c25bf2e 100644 --- a/app/models/compiler.rb +++ b/app/models/compiler.rb @@ -1,19 +1,51 @@ +require "shellwords" + class Compiler < ApplicationRecord - def _run!(snippet) - raise NotImplementedError + def to_s + "#{language} #{version}" + end + + def run_lazy(snippet) + r = Result.prepare_execution(self, snippet) + ExecuteJob.perform_later(self, snippet, r) + r end - if Rails.env.development? - require "shellwords" - def run!(snippet) - if self.language == "ruby" && self.version == "!!unsafe!!" - out = `ruby -e #{Shellwords.escape(snippet.code)}` - Result.create(snippet: snippet, compiler: self, output: out) - else - _run!(snippet) - end + def run(snippet) + r = Result.prepare_execution(self, snippet) + run_body(snippet, r) + r + end + + private + def run_body(snippet, r) + baseroot = Rails.root.join("playground/base").to_s + env_overlay = Rails.root.join("playground").join(language).join(version).to_s + sf = Tempfile.open + sf.write(snippet.code) + sf.fsync + of = Tempfile.open + pid = spawn("/usr/bin/sudo", Rails.root.join("sandbox/sandbox").to_s, baseroot, env_overlay, sf.path, *Shellwords.split(command_line), + in: :close, # TODO + out: of, + err: STDERR) + _, pst = Process.waitpid2(pid) + if pst.signaled? || pst.exitstatus > 0 + result = :errored + status = -1 + else + result = :success + status = 0 end - else - alias run! _run! + + of.rewind + r.update!(output: of.read, + status: status, + result: result) + rescue + r.update!(status: -1, result: :errored) + ensure + sf.close if sf + of.close if of end end diff --git a/app/models/result.rb b/app/models/result.rb index 8ca10e2..1bbdb29 100644 --- a/app/models/result.rb +++ b/app/models/result.rb @@ -1,4 +1,44 @@ +require "cgi" + class Result < ApplicationRecord belongs_to :snippet belongs_to :compiler + + enum result: [:success, :failed, :errored, :running] + + def finished? + !running? + end + + def parse_output + orig = output.b + ret = [] + while orig.bytesize > 0 + fd, len = orig.slice!(0, 5).unpack("CV") + raise "output is too short" if !len || orig.bytesize < len + ret << [fd, orig.slice!(0, len)] + end + ret + end + + def formatted_output + parse_output.inject("".b) { |s, (fd, c)| + if fd == 1 + s << CGI.escapeHTML(c) + else + s << "" << CGI.escapeHTML(c) << "" + end + }.html_safe + end + + def self.prepare_execution(compiler, snippet) + # kuso + r = Result.find_by(snippet: snippet, compiler: compiler) + if r + r.update(output: "", status: -1, result: :running) + else + r = Result.create!(snippet: snippet, compiler: compiler, output: "", status: -1, result: :running) + end + r + end end diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 5412492..a55b732 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -1,4 +1,14 @@ class Snippet < ApplicationRecord - has_many :result - has_many :compiler + has_many :results + + validates :code, length: { maximum: 65535, tokenizer: :bytes.to_proc } + + def compilers + Compiler.where(language: language) + end + + def results_all + r = results.map { |r| [r.compiler_id, r] }.to_h + compilers.map { |c| [r[c.id], c] } + end end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 5d5a9c0..fd1d40c 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,15 +1,24 @@ - + + + Poe <%= csrf_meta_tags %> - <%= action_cable_meta_tag %> - - <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> - <%= javascript_include_tag "application", "data-turbolinks-track" => true %> + <%= stylesheet_link_tag "application", media: "all" %> - <%= yield %> + +
+ <%= yield %> +
+ <%= javascript_include_tag "application" %> diff --git a/app/views/results/_result.html.erb b/app/views/results/_result.html.erb new file mode 100644 index 0000000..fd59416 --- /dev/null +++ b/app/views/results/_result.html.erb @@ -0,0 +1,16 @@ +<% if result && result.finished? %> +
" data-id="<%= result.id %>"> +
<%= compiler %>
+
+
<%= result.formatted_output %>
+
+
+<% else %> +
" data-id="<%= result&.id %>" data-compiler-id="<%= compiler.id %>"> +
<%= compiler %>
+
+

running....

+
+
+<% end %> + diff --git a/app/views/snippets/_form.html.erb b/app/views/snippets/_form.html.erb index 1c37b00..8b21b3d 100644 --- a/app/views/snippets/_form.html.erb +++ b/app/views/snippets/_form.html.erb @@ -1,27 +1,26 @@ -<%= form_for(snippet) do |f| %> - <% if snippet.errors.any? %> -
-

<%= pluralize(snippet.errors.count, "error") %> prohibited this snippet from being saved:

+
+
+ <%= form_for(snippet, url: "/", html: { method: "post" }) do |f| %> + <% if snippet.errors.any? %> + <% end %> - -
- <% end %> -
- <%= f.label :title %> - <%= f.text_field :title %> +
+ <%= f.text_field :title, placeholder: "Untitled", class: "form-control" %> +
+
+ <%= f.text_area :code, style: "display: none" %> +
+ <%= f.hidden_field :language, value: "Ruby" %> + + <% end %>
- -
- <%= f.label :code %> - <%= f.text_area :code %> -
- -
- <%= f.submit %> -
-<% end %> +
diff --git a/app/views/snippets/edit.html.erb b/app/views/snippets/edit.html.erb deleted file mode 100644 index c27040f..0000000 --- a/app/views/snippets/edit.html.erb +++ /dev/null @@ -1,6 +0,0 @@ -

Editing Snippet

- -<%= render 'form', snippet: @snippet %> - -<%= link_to 'Show', @snippet %> | -<%= link_to 'Back', snippets_path %> diff --git a/app/views/snippets/index.html.erb b/app/views/snippets/index.html.erb deleted file mode 100644 index 601ba13..0000000 --- a/app/views/snippets/index.html.erb +++ /dev/null @@ -1,29 +0,0 @@ -

<%= notice %>

- -

Snippets

- - - - - - - - - - - - <% @snippets.each do |snippet| %> - - - - - - - - <% end %> - -
TitleCode
<%= snippet.title %><%= snippet.code %><%= link_to 'Show', snippet %><%= link_to 'Edit', edit_snippet_path(snippet) %><%= link_to 'Destroy', snippet, method: :delete, data: { confirm: 'Are you sure?' } %>
- -
- -<%= link_to 'New Snippet', new_snippet_path %> diff --git a/app/views/snippets/new.html.erb b/app/views/snippets/new.html.erb index 0a9ebaf..2d2567d 100644 --- a/app/views/snippets/new.html.erb +++ b/app/views/snippets/new.html.erb @@ -1,5 +1 @@ -

New Snippet

- -<%= render 'form', snippet: @snippet %> - -<%= link_to 'Back', snippets_path %> +<%= render "form", snippet: @snippet %> diff --git a/app/views/snippets/show.html.erb b/app/views/snippets/show.html.erb index 9e59d7a..e2a1566 100644 --- a/app/views/snippets/show.html.erb +++ b/app/views/snippets/show.html.erb @@ -1,14 +1,6 @@ -

<%= notice %>

+<%= render "form", snippet: @snippet %> + -

- Title: - <%= @snippet.title %> -

- -

- Code: - <%= @snippet.code %> -

- -<%= link_to 'Edit', edit_snippet_path(@snippet) %> | -<%= link_to 'Back', snippets_path %> +<% @snippet.results_all.each do |result, compiler| %> + <%= render partial: "results/result", locals: { result: result, compiler: compiler } %> +<% end %> diff --git a/config.ru b/config.ru index c634fa4..33d9cb1 100644 --- a/config.ru +++ b/config.ru @@ -2,8 +2,4 @@ require ::File.expand_path("../config/environment", __FILE__) -# Action Cable uses EventMachine which requires that all classes are loaded in advance -Rails.application.eager_load! -require "action_cable/process/logging" - run Rails.application diff --git a/config/application.rb b/config/application.rb index 4dc52f9..f41dc96 100644 --- a/config/application.rb +++ b/config/application.rb @@ -8,7 +8,7 @@ require "active_record/railtie" require "action_controller/railtie" # require "action_mailer/railtie" require "action_view/railtie" -require "action_cable/engine" +# require "action_cable/engine" require "sprockets/railtie" # require "rails/test_unit/railtie" diff --git a/config/routes.rb b/config/routes.rb index 19d6a03..b547a66 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,15 +1,22 @@ Rails.application.routes.draw do - resources :snippets - # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + resources :snippets, only: [:new, :create, :update, :show], path: "", path_names: { + new: "", + create: "create", + update: ":id", + show: ":id" + } + + post "results/run" => "results#run" + get "results/:id" => "results#show" # Serve websocket cable requests in-process # mount ActionCable.server => "/cable" - root to: "snippets#new" + #root to: "snippets#new" - post "/create" => "snippets#create" - put "/update" => "snippets#update" - get "/:id" => "snippets#show", constraints: { id: /[1-9][0-9]*/ } + #post "/create" => "snippets#create" + #put "/update" => "snippets#update" + #get "/:id" => "snippets#show", constraints: { id: /[1-9][0-9]*/ } match "*any" => "application#not_found", via: :all end diff --git a/db/migrate/20160101024323_extend_result.rb b/db/migrate/20160101024323_extend_result.rb new file mode 100644 index 0000000..7c04f69 --- /dev/null +++ b/db/migrate/20160101024323_extend_result.rb @@ -0,0 +1,6 @@ +class ExtendResult < ActiveRecord::Migration[5.0] + def change + add_column :results, :result, :integer, null: false + add_column :results, :status, :integer, null: false + end +end diff --git a/db/migrate/20160101060555_add_command_line_to_compilers.rb b/db/migrate/20160101060555_add_command_line_to_compilers.rb new file mode 100644 index 0000000..215855d --- /dev/null +++ b/db/migrate/20160101060555_add_command_line_to_compilers.rb @@ -0,0 +1,5 @@ +class AddCommandLineToCompilers < ActiveRecord::Migration[5.0] + def change + add_column :compilers, :command_line, :string, null: false + end +end diff --git a/db/migrate/20160101121151_add_language_to_snippet.rb b/db/migrate/20160101121151_add_language_to_snippet.rb new file mode 100644 index 0000000..d3fe545 --- /dev/null +++ b/db/migrate/20160101121151_add_language_to_snippet.rb @@ -0,0 +1,5 @@ +class AddLanguageToSnippet < ActiveRecord::Migration[5.0] + def change + add_column :snippets, :language, :string, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 5812893..f60b7ab 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,13 +11,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151226120716) do +ActiveRecord::Schema.define(version: 20160101121151) do create_table "compilers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t| - t.string "language", limit: 64, null: false - t.string "version", limit: 64, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "language", limit: 64, null: false + t.string "version", limit: 64, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "command_line", null: false t.index ["language", "version"], name: "index_compilers_on_language_and_version", unique: true, using: :btree end @@ -26,6 +27,8 @@ ActiveRecord::Schema.define(version: 20151226120716) do t.integer "compiler_id", null: false t.binary "output", limit: 65535, null: false t.datetime "created_at", null: false + t.integer "result", null: false + t.integer "status", null: false t.index ["compiler_id"], name: "index_results_on_compiler_id", using: :btree t.index ["snippet_id", "compiler_id"], name: "index_results_on_snippet_id_and_compiler_id", unique: true, using: :btree t.index ["snippet_id"], name: "index_results_on_snippet_id", using: :btree @@ -35,6 +38,7 @@ ActiveRecord::Schema.define(version: 20151226120716) do t.string "title" t.binary "code", limit: 65535, null: false t.datetime "created_at", null: false + t.string "language", null: false end add_foreign_key "results", "compilers" diff --git a/db/seeds.rb b/db/seeds.rb index f16f4fa..cfadd24 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -5,8 +5,3 @@ # # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) # Character.create(name: 'Luke', movie: movies.first) - -if Rails.env.development? - # just eval - Compiler.create(language: "ruby", version: "!!unsafe!!") -end -- cgit v1.2.3