From 3562aa9103becd216284953f4906e23c9011f7f5 Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Thu, 2 Feb 2017 18:14:33 +0100 Subject: [PATCH 1/8] create remote evaluation --- Gemfile.lock | 3 - app/assets/remote_scripts/client_script.ps1 | 88 +++++++++++++++++++ app/assets/remote_scripts/client_script.sh | 58 ++++++++++++ .../remote_scripts/client_script_osx.sh | 68 ++++++++++++++ .../concerns/remote_evaluation_parameters.rb | 8 ++ .../remote_evaluation_controller.rb | 35 ++++++++ app/controllers/submissions_controller.rb | 40 ++++++++- app/models/remote_evaluation_mapping.rb | 10 +++ app/models/submission.rb | 2 +- config/routes.rb | 2 + ...70437_create_remote_evaluation_mappings.rb | 11 +++ db/schema.rb | 8 ++ 12 files changed, 327 insertions(+), 6 deletions(-) create mode 100644 app/assets/remote_scripts/client_script.ps1 create mode 100644 app/assets/remote_scripts/client_script.sh create mode 100644 app/assets/remote_scripts/client_script_osx.sh create mode 100644 app/controllers/concerns/remote_evaluation_parameters.rb create mode 100644 app/controllers/remote_evaluation_controller.rb create mode 100644 app/models/remote_evaluation_mapping.rb create mode 100644 db/migrate/20170202170437_create_remote_evaluation_mappings.rb diff --git a/Gemfile.lock b/Gemfile.lock index 166109fe..67860f20 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -443,6 +443,3 @@ DEPENDENCIES uglifier (>= 1.3.0) web-console (~> 2.0) will_paginate (~> 3.0) - -BUNDLED WITH - 1.13.6 diff --git a/app/assets/remote_scripts/client_script.ps1 b/app/assets/remote_scripts/client_script.ps1 new file mode 100644 index 00000000..1ef00a57 --- /dev/null +++ b/app/assets/remote_scripts/client_script.ps1 @@ -0,0 +1,88 @@ +# run like this: powershell.exe -noprofile -executionpolicy bypass -file path\to\client_script.ps1 path\to\project_root + +# CodeOcean Remote Client v0.4 + +#file_info format: = (src/frog.java=34) +#file_path format: + +param ( + [string]$project_root +) +if ( !($project_root | select-string -pattern '[/\\]$') ){ + $project_root += '/' +} + + +function post_web_request ($content_type, $data, $url){ + $buffer = [System.Text.Encoding]::UTF8.GetBytes($data) + [System.Net.HttpWebRequest] $web_request = [System.Net.WebRequest]::Create($url) + $web_request.Method = 'POST' + $web_request.ContentType = $content_type + $web_request.ContentLength = $buffer.Length; + + $request_stream = $web_request.GetRequestStream() + $request_stream.Write($buffer, 0, $buffer.Length) + $request_stream.Flush() + $request_stream.Close() + + [System.Net.HttpWebResponse] $web_response = $web_request.GetResponse() + $stream_reader = new-object System.IO.StreamReader($web_response.GetResponseStream()) + $result = $stream_reader.ReadToEnd() + return $result +} + +function find_file ($file_name){ + $search_result = get-childitem -recurse -path $project_root -filter $file_name + if( !$search_result.exists ){ + write-host "Error: $file_name could not be found under $project_root." + exit 1 + }elseif( $search_result.gettype().name -eq 'Object[]' ){ + $search_result = $search_result[0] + } + return $search_result +} + +function get_file ($file_path){ + $path_to_file = $project_root + $path_to_file += ($file_path | select-string -pattern '^.+/').matches.value + $file_name = ($file_path | select-string -pattern '[^/]+$').matches.value + $file = get-childitem -path $path_to_file -filter $file_name + if( !$file.exists ){ + write-host "Warning: $file_name should be in $path_to_file, but it is not. Searching whole project..." + $file = find_file $file_name + write-host 'Using '$file.fullname'.' + } + return $file +} + +function get_escaped_file_content ($file){ + $content = [IO.File]::ReadAllText($file.fullname) + $content = $content -replace "`r`n", '\n' + $content = $content -replace "`n", '\n' + $content = $content.replace('"', '\"') + return $content +} + +function get_file_attributes ($file_info){ + $file = get_file ($file_info | select-string -pattern '^.*(?==)').matches.value + $escaped_file_content = get_escaped_file_content $file + $file_id = ($file_info | select-string -pattern '[^=]+$').matches.value + return "{`"file_id`": $file_id,`"content`": `"$escaped_file_content`"}" +} + +$co_file = get_file '.co' + +$file_array = get-content $co_file.fullname + +$validation_token = $file_array[0] + +$files_attributes = get_file_attributes $file_array[1] + +for ($i = 2; $i -lt $file_array.length; $i++){ + $files_attributes += ', ' + $files_attributes += get_file_attributes $file_array[$i] +} + +$post_data = "{`"remote_evaluation`": {`"validation_token`": `"$validation_token`",`"files_attributes`": [$files_attributes]}}" + +post_web_request 'application/json' $post_data 'http://codeocean.openhpi.de/evaluate' \ No newline at end of file diff --git a/app/assets/remote_scripts/client_script.sh b/app/assets/remote_scripts/client_script.sh new file mode 100644 index 00000000..8bde2fd0 --- /dev/null +++ b/app/assets/remote_scripts/client_script.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# CodeOcean Remote Client v0.4 + +#file_info format: = (src/frog.java=34) +#file_path format: + + +project_root="${1%/}" + +function get_valid_file_path { + file_path="$project_root/$1" + if [ -e "$file_path" ]; then + valid_file_path="$file_path" + else + file_name="${1##*/}" + valid_file_path="$(find "$project_root" -name "$file_name" | head -1)" + if ! [ "$valid_file_path" ]; then + path_to_file="$(echo "$1" | grep -oP '^.+/')" + echo "Error: $file_name is not in $project_root/$path_to_file and could not be found under $project_root." + exit 1 + fi + fi + echo "$valid_file_path" +} + +function get_escaped_file_content { + file_path="$1" + cat "$file_path" | + perl -p -e 's@\r\n@\\n@g' | + perl -p -e 's@\n@\\n@g' | + perl -p -e 's@"@\\"@g' +} + +function get_file_attributes { + file_info="$1" + file_path="$(get_valid_file_path "${file_info%=*}")" + escaped_file_content="$(get_escaped_file_content "$file_path")" + file_id="${file_info##*=}" + echo "{\"file_id\": $file_id,\"content\": \"$escaped_file_content\"}" +} + + +co_file_path="$(get_valid_file_path '.co')" +mapfile -t file_array < "$co_file_path" + +validation_token="${file_array[0]}" + +files_attributes="$(get_file_attributes "${file_array[1]}")" + +for ((i = 2; i < ${#file_array[@]}; i++)); do + files_attributes+=", $(get_file_attributes "${file_array[i]}")" +done + +post_data="{\"remote_evaluation\": {\"validation_token\": \"$validation_token\",\"files_attributes\": [$files_attributes]}}" + +curl -H 'Content-Type: application/json' --data "$post_data" http://codeocean.openhpi.de/evaluate +echo \ No newline at end of file diff --git a/app/assets/remote_scripts/client_script_osx.sh b/app/assets/remote_scripts/client_script_osx.sh new file mode 100644 index 00000000..955b03bd --- /dev/null +++ b/app/assets/remote_scripts/client_script_osx.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# CodeOcean Remote Client v0.4 + +#file_info format: = (src/frog.java=34) +#file_path format: + + +project_root="${1%/}" +declare -a file_array + +function get_valid_file_path { + file_path="$project_root/$1" + if [ -e "$file_path" ]; then + valid_file_path="$file_path" + else + file_name="${1##*/}" + valid_file_path="$(find "$project_root" -name "$file_name" | head -1)" + if ! [ "$valid_file_path" ]; then + path_to_file="$(echo "$1" | pcregrep -o '^.+/')" + echo "Error: $file_name is not in $project_root/$path_to_file and could not be found under $project_root." + exit 1 + fi + fi + echo "$valid_file_path" +} + +function get_escaped_file_content { + file_path="$1" + cat "$file_path" | + perl -p -e 's@\r\n@\\n@g' | + perl -p -e 's@\n@\\n@g' | + perl -p -e 's@"@\\"@g' +} + +function get_file_attributes { + file_info="$1" + file_path="$(get_valid_file_path "${file_info%=*}")" + escaped_file_content="$(get_escaped_file_content "$file_path")" + file_id="${file_info##*=}" + echo "{\"file_id\": $file_id,\"content\": \"$escaped_file_content\"}" +} + +function read_file_to_array { + let i=0 + while IFS=$'\n' read -r line_data; do + file_array[i]="${line_data}" + ((++i)) + done < $1 +} + + +co_file_path="$(get_valid_file_path '.co')" +read_file_to_array $co_file_path + +validation_token="${file_array[0]}" + +files_attributes="$(get_file_attributes "${file_array[1]}")" + +for ((i = 2; i < ${#file_array[@]}; i++)); do + files_attributes+=", $(get_file_attributes "${file_array[i]}")" +done + +post_data="{\"remote_evaluation\": {\"validation_token\": \"$validation_token\",\"files_attributes\": [$files_attributes]}}" + +#echo ${post_data} +curl -H 'Content-Type: application/json' --data "$post_data" http://codeocean.openhpi.de/evaluate +echo \ No newline at end of file diff --git a/app/controllers/concerns/remote_evaluation_parameters.rb b/app/controllers/concerns/remote_evaluation_parameters.rb new file mode 100644 index 00000000..4f0acab2 --- /dev/null +++ b/app/controllers/concerns/remote_evaluation_parameters.rb @@ -0,0 +1,8 @@ +module RemoteEvaluationParameters + include FileParameters + + def remote_evaluation_params + remote_evaluation_params = params[:remote_evaluation].permit(:validation_token, files_attributes: file_attributes) + end + private :remote_evaluation_params +end \ No newline at end of file diff --git a/app/controllers/remote_evaluation_controller.rb b/app/controllers/remote_evaluation_controller.rb new file mode 100644 index 00000000..36d61f73 --- /dev/null +++ b/app/controllers/remote_evaluation_controller.rb @@ -0,0 +1,35 @@ +class RemoteEvaluationController < ApplicationController + include RemoteEvaluationParameters + include SubmissionScoring + + skip_after_action :verify_authorized + skip_before_action :verify_authenticity_token + + # POST /evaluate + # @param validation_token + # @param files_attributes + def evaluate + + validation_token = remote_evaluation_params[:validation_token] + files_attributes = remote_evaluation_params[:files_attributes] || [] + + # todo extra: validiere, ob files wirklich zur Übung gehören (wenn allowNewFiles-flag nicht gesetzt ist) + if (remote_evaluation_mapping = RemoteEvaluationMapping.find_by(:validation_token => validation_token)) + puts remote_evaluation_mapping.exercise_id + puts remote_evaluation_mapping.user_id + + _params = remote_evaluation_params.except(:validation_token) + _params[:exercise_id] = remote_evaluation_mapping.exercise_id + _params[:user_id] = remote_evaluation_mapping.user_id + _params[:cause] = "remoteAssess" + _params[:user_type] = "ExternalUser" + + @submission = Submission.create(_params) + render json: score_submission(@submission) + else + # todo: better output + # todo: check token expired? + render json: "No exercise found for this validation_token! Please keep out!" + end + end +end \ No newline at end of file diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 16fcd697..182c22c4 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -57,12 +57,29 @@ class SubmissionsController < ApplicationController # files = @submission.files.map{ } # zipline( files, 'submission.zip') # send_data(@file.content, filename: @file.name_with_extension) + + id_file = create_remote_evaluation_mapping + require 'zip' stringio = Zip::OutputStream.write_buffer do |zio| @files.each do |file| - zio.put_next_entry(file.name_with_extension) + zio.put_next_entry(file.path.to_s == '' ? file.name_with_extension : File.join(file.path, file.name_with_extension)) zio.write(file.content) end + + # zip .co file + zio.put_next_entry(File.basename id_file) + zio.write(File.read id_file) + File.delete(id_file) if File.exist?(id_file) + + # zip client scripts + scripts_path = 'app/assets/remote_scripts' + Dir.foreach(scripts_path) do |file| + next if file == '.' or file == '..' + zio.put_next_entry(File.join('.scripts', File.basename(file))) + zio.write(File.read File.join(scripts_path, file)) + end + end send_data(stringio.string, filename: @submission.exercise.title.tr(" ", "_") + ".zip") end @@ -316,4 +333,23 @@ class SubmissionsController < ApplicationController server_sent_event.close end private :with_server_sent_events -end + + def create_remote_evaluation_mapping + user_id = @submission.user_id + exercise_id = @submission.exercise_id + + remote_evaluation_mapping = RemoteEvaluationMapping.create(:user_id => user_id, :exercise_id => exercise_id) + + # create id.co file + path = "tmp/.co" + content = "#{remote_evaluation_mapping.validation_token}\n" + @submission.files.each do |file| + file_path = file.path.to_s == '' ? file.name_with_extension : File.join(file.path, file.name_with_extension) + content += "#{file_path}=#{file.id.to_s}\n" + end + File.open(path, "w+") do |f| + f.write(content) + end + path + end +end \ No newline at end of file diff --git a/app/models/remote_evaluation_mapping.rb b/app/models/remote_evaluation_mapping.rb new file mode 100644 index 00000000..be0034b1 --- /dev/null +++ b/app/models/remote_evaluation_mapping.rb @@ -0,0 +1,10 @@ +# todo: reference to lti_param_model +class RemoteEvaluationMapping < ActiveRecord::Base + before_create :generate_token, unless: :validation_token? + belongs_to :exercise + belongs_to :user + + def generate_token + self.validation_token = SecureRandom.urlsafe_base64 + end +end \ No newline at end of file diff --git a/app/models/submission.rb b/app/models/submission.rb index 1abbbb84..6815eb40 100644 --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -2,7 +2,7 @@ class Submission < ActiveRecord::Base include Context include Creation - CAUSES = %w(assess download file render run save submit test autosave requestComments) + CAUSES = %w(assess download file render run save submit test autosave requestComments remoteAssess) FILENAME_URL_PLACEHOLDER = '{filename}' belongs_to :exercise diff --git a/config/routes.rb b/config/routes.rb index b4606f74..6abbe83f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -105,4 +105,6 @@ Rails.application.routes.draw do end end + post "/evaluate", to: 'remote_evaluation#evaluate', via: [:post] + end diff --git a/db/migrate/20170202170437_create_remote_evaluation_mappings.rb b/db/migrate/20170202170437_create_remote_evaluation_mappings.rb new file mode 100644 index 00000000..d102370d --- /dev/null +++ b/db/migrate/20170202170437_create_remote_evaluation_mappings.rb @@ -0,0 +1,11 @@ +class CreateRemoteEvaluationMappings < ActiveRecord::Migration + def change + create_table :remote_evaluation_mappings do |t| + t.integer "user_id", null: false + t.integer "exercise_id", null: false + t.string "validation_token", null: false + t.datetime "created_at" + t.datetime "updated_at" + end + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index 6f5accb0..e53b502f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -191,6 +191,14 @@ ActiveRecord::Schema.define(version: 20161214144837) do t.datetime "updated_at" end + create_table "remote_evaluation_mappings", force: :cascade do |t| + t.integer "user_id", null: false + t.integer "exercise_id", null: false + t.string "validation_token", null: false + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "request_for_comments", force: :cascade do |t| t.integer "user_id", null: false t.integer "exercise_id", null: false From 213ca6c6a147a7508b3307dc086df5cd0bf3e644 Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Thu, 2 Feb 2017 18:24:21 +0100 Subject: [PATCH 2/8] add structure.sql --- db/structure.sql | 154 ++++++++++++++++++++++++++++++----------------- 1 file changed, 98 insertions(+), 56 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index 4b290bdc..09afcb66 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -39,10 +39,9 @@ SET default_with_oids = false; CREATE TABLE code_harbor_links ( id integer NOT NULL, - oauth2token character varying(255), + oauth2token character varying, created_at timestamp without time zone, - updated_at timestamp without time zone, - user_id integer + updated_at timestamp without time zone ); @@ -73,7 +72,7 @@ CREATE TABLE comments ( id integer NOT NULL, user_id integer, file_id integer, - user_type character varying(255), + user_type character varying, "row" integer, "column" integer, text text, @@ -107,11 +106,11 @@ ALTER SEQUENCE comments_id_seq OWNED BY comments.id; CREATE TABLE consumers ( id integer NOT NULL, - name character varying(255), + name character varying, created_at timestamp without time zone, updated_at timestamp without time zone, - oauth_key character varying(255), - oauth_secret character varying(255) + oauth_key character varying, + oauth_secret character varying ); @@ -173,18 +172,18 @@ ALTER SEQUENCE errors_id_seq OWNED BY errors.id; CREATE TABLE execution_environments ( id integer NOT NULL, - docker_image character varying(255), - name character varying(255), + docker_image character varying, + name character varying, created_at timestamp without time zone, updated_at timestamp without time zone, - run_command character varying(255), - test_command character varying(255), - testing_framework character varying(255), + run_command character varying, + test_command character varying, + testing_framework character varying, help text, - exposed_ports character varying(255), + exposed_ports character varying, permitted_execution_time integer, user_id integer, - user_type character varying(255), + user_type character varying, pool_size integer, file_type_id integer, memory_limit integer, @@ -219,14 +218,14 @@ CREATE TABLE exercises ( id integer NOT NULL, description text, execution_environment_id integer, - title character varying(255), + title character varying, created_at timestamp without time zone, updated_at timestamp without time zone, user_id integer, instructions text, public boolean, - user_type character varying(255), - token character varying(255), + user_type character varying, + token character varying, hide_file_tree boolean, allow_file_creation boolean, allow_auto_completion boolean DEFAULT false @@ -259,9 +258,9 @@ ALTER SEQUENCE exercises_id_seq OWNED BY exercises.id; CREATE TABLE external_users ( id integer NOT NULL, consumer_id integer, - email character varying(255), - external_id character varying(255), - name character varying(255), + email character varying, + external_id character varying, + name character varying, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -292,7 +291,7 @@ ALTER SEQUENCE external_users_id_seq OWNED BY external_users.id; CREATE TABLE file_templates ( id integer NOT NULL, - name character varying(255), + name character varying, content text, file_type_id integer, created_at timestamp without time zone, @@ -325,16 +324,16 @@ ALTER SEQUENCE file_templates_id_seq OWNED BY file_templates.id; CREATE TABLE file_types ( id integer NOT NULL, - editor_mode character varying(255), - file_extension character varying(255), + editor_mode character varying, + file_extension character varying, indent_size integer, - name character varying(255), + name character varying, user_id integer, created_at timestamp without time zone, updated_at timestamp without time zone, executable boolean, renderable boolean, - user_type character varying(255), + user_type character varying, "binary" boolean ); @@ -366,20 +365,20 @@ CREATE TABLE files ( id integer NOT NULL, content text, context_id integer, - context_type character varying(255), + context_type character varying, file_id integer, file_type_id integer, hidden boolean, - name character varying(255), + name character varying, read_only boolean, created_at timestamp without time zone, updated_at timestamp without time zone, - native_file character varying(255), - role character varying(255), - hashed_content character varying(255), - feedback_message character varying(255), + native_file character varying, + role character varying, + hashed_content character varying, + feedback_message character varying, weight double precision, - path character varying(255), + path character varying, file_template_id integer ); @@ -410,10 +409,10 @@ ALTER SEQUENCE files_id_seq OWNED BY files.id; CREATE TABLE hints ( id integer NOT NULL, execution_environment_id integer, - locale character varying(255), + locale character varying, message text, - name character varying(255), - regular_expression character varying(255), + name character varying, + regular_expression character varying, created_at timestamp without time zone, updated_at timestamp without time zone ); @@ -445,23 +444,23 @@ ALTER SEQUENCE hints_id_seq OWNED BY hints.id; CREATE TABLE internal_users ( id integer NOT NULL, consumer_id integer, - email character varying(255), - name character varying(255), - role character varying(255), + email character varying, + name character varying, + role character varying, created_at timestamp without time zone, updated_at timestamp without time zone, - crypted_password character varying(255), - salt character varying(255), + crypted_password character varying, + salt character varying, failed_logins_count integer DEFAULT 0, lock_expires_at timestamp without time zone, - unlock_token character varying(255), - remember_me_token character varying(255), + unlock_token character varying, + remember_me_token character varying, remember_me_token_expires_at timestamp without time zone, - reset_password_token character varying(255), + reset_password_token character varying, reset_password_token_expires_at timestamp without time zone, reset_password_email_sent_at timestamp without time zone, - activation_state character varying(255), - activation_token character varying(255), + activation_state character varying, + activation_token character varying, activation_token_expires_at timestamp without time zone ); @@ -519,6 +518,39 @@ CREATE SEQUENCE lti_parameters_id_seq ALTER SEQUENCE lti_parameters_id_seq OWNED BY lti_parameters.id; +-- +-- Name: remote_evaluation_mappings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE remote_evaluation_mappings ( + id integer NOT NULL, + user_id integer NOT NULL, + exercise_id integer NOT NULL, + validation_token character varying NOT NULL, + created_at timestamp without time zone, + updated_at timestamp without time zone +); + + +-- +-- Name: remote_evaluation_mappings_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE remote_evaluation_mappings_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: remote_evaluation_mappings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE remote_evaluation_mappings_id_seq OWNED BY remote_evaluation_mappings.id; + + -- -- Name: request_for_comments; Type: TABLE; Schema: public; Owner: - -- @@ -530,7 +562,7 @@ CREATE TABLE request_for_comments ( file_id integer NOT NULL, created_at timestamp without time zone, updated_at timestamp without time zone, - user_type character varying(255), + user_type character varying, question text, solved boolean, submission_id integer @@ -561,7 +593,7 @@ ALTER SEQUENCE request_for_comments_id_seq OWNED BY request_for_comments.id; -- CREATE TABLE schema_migrations ( - version character varying(255) NOT NULL + version character varying NOT NULL ); @@ -576,8 +608,8 @@ CREATE TABLE submissions ( user_id integer, created_at timestamp without time zone, updated_at timestamp without time zone, - cause character varying(255), - user_type character varying(255) + cause character varying, + user_type character varying ); @@ -725,6 +757,13 @@ ALTER TABLE ONLY internal_users ALTER COLUMN id SET DEFAULT nextval('internal_us ALTER TABLE ONLY lti_parameters ALTER COLUMN id SET DEFAULT nextval('lti_parameters_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY remote_evaluation_mappings ALTER COLUMN id SET DEFAULT nextval('remote_evaluation_mappings_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -850,6 +889,14 @@ ALTER TABLE ONLY lti_parameters ADD CONSTRAINT lti_parameters_pkey PRIMARY KEY (id); +-- +-- Name: remote_evaluation_mappings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY remote_evaluation_mappings + ADD CONSTRAINT remote_evaluation_mappings_pkey PRIMARY KEY (id); + + -- -- Name: request_for_comments_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -874,13 +921,6 @@ ALTER TABLE ONLY testruns ADD CONSTRAINT testruns_pkey PRIMARY KEY (id); --- --- Name: index_code_harbor_links_on_user_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_code_harbor_links_on_user_id ON code_harbor_links USING btree (user_id); - - -- -- Name: index_comments_on_file_id; Type: INDEX; Schema: public; Owner: - -- @@ -1120,3 +1160,5 @@ INSERT INTO schema_migrations (version) VALUES ('20160907123009'); INSERT INTO schema_migrations (version) VALUES ('20170112151637'); +INSERT INTO schema_migrations (version) VALUES ('20170202170437'); + From 4d314317ae03363300aad08043cdadc4d1cc7188 Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Fri, 3 Feb 2017 09:13:59 +0100 Subject: [PATCH 3/8] parse target url to .co file, update remote scripts --- app/assets/remote_scripts/client_script.ps1 | 10 ++++++---- app/assets/remote_scripts/client_script.sh | 12 +++++++----- app/assets/remote_scripts/client_script_osx.sh | 13 +++++++------ app/controllers/submissions_controller.rb | 3 +++ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/app/assets/remote_scripts/client_script.ps1 b/app/assets/remote_scripts/client_script.ps1 index 1ef00a57..3d0ce539 100644 --- a/app/assets/remote_scripts/client_script.ps1 +++ b/app/assets/remote_scripts/client_script.ps1 @@ -1,6 +1,6 @@ # run like this: powershell.exe -noprofile -executionpolicy bypass -file path\to\client_script.ps1 path\to\project_root -# CodeOcean Remote Client v0.4 +# CodeOcean Remote Client v0.5 #file_info format: = (src/frog.java=34) #file_path format: @@ -76,13 +76,15 @@ $file_array = get-content $co_file.fullname $validation_token = $file_array[0] -$files_attributes = get_file_attributes $file_array[1] +$target_url = $file_array[1] -for ($i = 2; $i -lt $file_array.length; $i++){ +$files_attributes = get_file_attributes $file_array[2] + +for ($i = 3; $i -lt $file_array.length; $i++){ $files_attributes += ', ' $files_attributes += get_file_attributes $file_array[$i] } $post_data = "{`"remote_evaluation`": {`"validation_token`": `"$validation_token`",`"files_attributes`": [$files_attributes]}}" -post_web_request 'application/json' $post_data 'http://codeocean.openhpi.de/evaluate' \ No newline at end of file +post_web_request 'application/json' $post_data $target_url diff --git a/app/assets/remote_scripts/client_script.sh b/app/assets/remote_scripts/client_script.sh index 8bde2fd0..8c56f820 100644 --- a/app/assets/remote_scripts/client_script.sh +++ b/app/assets/remote_scripts/client_script.sh @@ -1,6 +1,6 @@ #!/bin/bash -# CodeOcean Remote Client v0.4 +# CodeOcean Remote Client v0.5 #file_info format: = (src/frog.java=34) #file_path format: @@ -46,13 +46,15 @@ mapfile -t file_array < "$co_file_path" validation_token="${file_array[0]}" -files_attributes="$(get_file_attributes "${file_array[1]}")" +target_url="${file_array[1]}" -for ((i = 2; i < ${#file_array[@]}; i++)); do +files_attributes="$(get_file_attributes "${file_array[2]}")" + +for ((i = 3; i < ${#file_array[@]}; i++)); do files_attributes+=", $(get_file_attributes "${file_array[i]}")" done post_data="{\"remote_evaluation\": {\"validation_token\": \"$validation_token\",\"files_attributes\": [$files_attributes]}}" -curl -H 'Content-Type: application/json' --data "$post_data" http://codeocean.openhpi.de/evaluate -echo \ No newline at end of file +curl -H 'Content-Type: application/json' --data "$post_data" "$target_url" +echo diff --git a/app/assets/remote_scripts/client_script_osx.sh b/app/assets/remote_scripts/client_script_osx.sh index 955b03bd..a24fc251 100644 --- a/app/assets/remote_scripts/client_script_osx.sh +++ b/app/assets/remote_scripts/client_script_osx.sh @@ -1,6 +1,6 @@ #!/bin/bash -# CodeOcean Remote Client v0.4 +# CodeOcean Remote Client v0.5 #file_info format: = (src/frog.java=34) #file_path format: @@ -55,14 +55,15 @@ read_file_to_array $co_file_path validation_token="${file_array[0]}" -files_attributes="$(get_file_attributes "${file_array[1]}")" +target_url="${file_array[1]}" -for ((i = 2; i < ${#file_array[@]}; i++)); do +files_attributes="$(get_file_attributes "${file_array[2]}")" + +for ((i = 3; i < ${#file_array[@]}; i++)); do files_attributes+=", $(get_file_attributes "${file_array[i]}")" done post_data="{\"remote_evaluation\": {\"validation_token\": \"$validation_token\",\"files_attributes\": [$files_attributes]}}" -#echo ${post_data} -curl -H 'Content-Type: application/json' --data "$post_data" http://codeocean.openhpi.de/evaluate -echo \ No newline at end of file +curl -H 'Content-Type: application/json' --data "$post_data" "$target_url" +echo diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 182c22c4..d04cfa6f 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -342,7 +342,10 @@ class SubmissionsController < ApplicationController # create id.co file path = "tmp/.co" + # parse validation token content = "#{remote_evaluation_mapping.validation_token}\n" + # parse remote request url + content += "#{request.base_url}/evaluate\n" @submission.files.each do |file| file_path = file.path.to_s == '' ? file.name_with_extension : File.join(file.path, file.name_with_extension) content += "#{file_path}=#{file.id.to_s}\n" From 672303266eb0d68f0f670168e3bb33016b444428 Mon Sep 17 00:00:00 2001 From: Tom Staubitz Date: Mon, 6 Feb 2017 20:30:22 +0100 Subject: [PATCH 4/8] removed relative_url_root for staging environment. The app can be accessed now via port 3000 instead of a subdirectory. --- config/environments/staging.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 7caf841e..745ed57b 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -99,6 +99,5 @@ Rails.application.configure do config.active_record.dump_schema_after_migration = false # Run on subfolder in production environment. - config.relative_url_root = '/co-staging' - + # config.relative_url_root = '/co-staging' end From a50f1ae62ae76f2c35352a2b3bf4a50a26f738bc Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Mon, 27 Feb 2017 13:48:58 +0100 Subject: [PATCH 5/8] rename remote scripts --- app/assets/remote_scripts/{client_script_osx.sh => macos.sh} | 0 app/assets/remote_scripts/{client_script.sh => ubuntu.sh} | 0 app/assets/remote_scripts/{client_script.ps1 => windows.ps1} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename app/assets/remote_scripts/{client_script_osx.sh => macos.sh} (100%) rename app/assets/remote_scripts/{client_script.sh => ubuntu.sh} (100%) rename app/assets/remote_scripts/{client_script.ps1 => windows.ps1} (100%) diff --git a/app/assets/remote_scripts/client_script_osx.sh b/app/assets/remote_scripts/macos.sh similarity index 100% rename from app/assets/remote_scripts/client_script_osx.sh rename to app/assets/remote_scripts/macos.sh diff --git a/app/assets/remote_scripts/client_script.sh b/app/assets/remote_scripts/ubuntu.sh similarity index 100% rename from app/assets/remote_scripts/client_script.sh rename to app/assets/remote_scripts/ubuntu.sh diff --git a/app/assets/remote_scripts/client_script.ps1 b/app/assets/remote_scripts/windows.ps1 similarity index 100% rename from app/assets/remote_scripts/client_script.ps1 rename to app/assets/remote_scripts/windows.ps1 From fb8558f5ab7ff1639bf71921e99cd437c378cb1d Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Mon, 27 Feb 2017 17:31:26 +0100 Subject: [PATCH 6/8] update remote scripts --- app/assets/remote_scripts/macos.sh | 7 ++++++- app/assets/remote_scripts/ubuntu.sh | 7 ++++++- app/assets/remote_scripts/windows.ps1 | 7 +++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/app/assets/remote_scripts/macos.sh b/app/assets/remote_scripts/macos.sh index a24fc251..4632d421 100644 --- a/app/assets/remote_scripts/macos.sh +++ b/app/assets/remote_scripts/macos.sh @@ -1,6 +1,10 @@ #!/bin/bash -# CodeOcean Remote Client v0.5 +# run like this: +# cd path/to/project_root +# .scripts/macos.sh . + +# CodeOcean Remote Client v0.6 #file_info format: = (src/frog.java=34) #file_path format: @@ -28,6 +32,7 @@ function get_valid_file_path { function get_escaped_file_content { file_path="$1" cat "$file_path" | + perl -p -e 's@\\@\\\\@g' | perl -p -e 's@\r\n@\\n@g' | perl -p -e 's@\n@\\n@g' | perl -p -e 's@"@\\"@g' diff --git a/app/assets/remote_scripts/ubuntu.sh b/app/assets/remote_scripts/ubuntu.sh index 8c56f820..db5a970d 100644 --- a/app/assets/remote_scripts/ubuntu.sh +++ b/app/assets/remote_scripts/ubuntu.sh @@ -1,6 +1,10 @@ #!/bin/bash -# CodeOcean Remote Client v0.5 +# run like this: +# cd path/to/project_root +# .scripts/ubuntu.sh . + +# CodeOcean Remote Client v0.6 #file_info format: = (src/frog.java=34) #file_path format: @@ -27,6 +31,7 @@ function get_valid_file_path { function get_escaped_file_content { file_path="$1" cat "$file_path" | + perl -p -e 's@\\@\\\\@g' | perl -p -e 's@\r\n@\\n@g' | perl -p -e 's@\n@\\n@g' | perl -p -e 's@"@\\"@g' diff --git a/app/assets/remote_scripts/windows.ps1 b/app/assets/remote_scripts/windows.ps1 index 3d0ce539..9647d2e5 100644 --- a/app/assets/remote_scripts/windows.ps1 +++ b/app/assets/remote_scripts/windows.ps1 @@ -1,6 +1,8 @@ -# run like this: powershell.exe -noprofile -executionpolicy bypass -file path\to\client_script.ps1 path\to\project_root +# run like this: +# cd path\to\project_root +# powershell.exe -noprofile -executionpolicy bypass -file .scripts\windows.ps1 . -# CodeOcean Remote Client v0.5 +# CodeOcean Remote Client v0.6 #file_info format: = (src/frog.java=34) #file_path format: @@ -57,6 +59,7 @@ function get_file ($file_path){ function get_escaped_file_content ($file){ $content = [IO.File]::ReadAllText($file.fullname) + $content = $content.replace('\', '\\') $content = $content -replace "`r`n", '\n' $content = $content -replace "`n", '\n' $content = $content.replace('"', '\"') From 4fab791e7f0c18de0d256a5c594fb48058ea6b18 Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Mon, 27 Mar 2017 15:52:06 +0200 Subject: [PATCH 7/8] Update submissions_controller.rb --- app/controllers/submissions_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index d04cfa6f..b8c6fd37 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -340,7 +340,7 @@ class SubmissionsController < ApplicationController remote_evaluation_mapping = RemoteEvaluationMapping.create(:user_id => user_id, :exercise_id => exercise_id) - # create id.co file + # create .co file path = "tmp/.co" # parse validation token content = "#{remote_evaluation_mapping.validation_token}\n" @@ -355,4 +355,4 @@ class SubmissionsController < ApplicationController end path end -end \ No newline at end of file +end From 8f81bb728c3f6223aee77d8a3bbf262581139a86 Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Tue, 25 Apr 2017 14:16:29 +0200 Subject: [PATCH 8/8] change tmp-filename of .co-file --- app/controllers/submissions_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 8d84bd7d..9b37fde0 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -72,7 +72,7 @@ class SubmissionsController < ApplicationController end # zip .co file - zio.put_next_entry(File.basename id_file) + zio.put_next_entry(".co") zio.write(File.read id_file) File.delete(id_file) if File.exist?(id_file) @@ -362,7 +362,7 @@ class SubmissionsController < ApplicationController remote_evaluation_mapping = RemoteEvaluationMapping.create(:user_id => user_id, :exercise_id => exercise_id) # create .co file - path = "tmp/.co" + path = "tmp/" + user_id.to_s + ".co" # parse validation token content = "#{remote_evaluation_mapping.validation_token}\n" # parse remote request url