├── lib ├── tasks │ ├── .gitkeep │ ├── demo-images │ │ ├── men.jpg │ │ └── women.jpg │ ├── screenshots.rake │ └── factory_bot_lint.rake ├── assets │ ├── .gitkeep │ ├── dockerfiles │ │ ├── java-grader.Dockerfile │ │ └── racket-grader.Dockerfile │ └── python-config.json ├── audit.rb ├── array_split.rb ├── fake_upload.rb ├── devise │ └── strategies │ │ └── debug_login.rb └── json_parser.rb ├── public ├── favicon.ico ├── robots.txt └── 422.html ├── .ruby-version ├── app ├── mailers │ ├── .gitkeep │ └── notification_mailer.rb ├── models │ ├── .gitkeep │ ├── team_user.rb │ ├── reg_request_section.rb │ ├── submission_enabled_toggle.rb │ ├── submission_view.rb │ ├── assignments │ │ └── files.rb │ ├── user_submission.rb │ ├── grading_conflict_audit.rb │ ├── registration_section.rb │ ├── used_sub.rb │ ├── grader_allocation.rb │ ├── sandbox.rb │ ├── review_feedback.rb │ ├── application_record.rb │ ├── submissions │ │ └── files_sub.rb │ ├── bucket.rb │ ├── codereview_matching.rb │ ├── individual_extension.rb │ ├── lateness_configs │ │ ├── late_per_hour_config.rb │ │ └── late_per_day_config.rb │ ├── settings.rb │ └── term.rb ├── helpers │ ├── main_helper.rb │ ├── terms_helper.rb │ ├── users_helper.rb │ ├── buckets_helper.rb │ ├── sandboxes_helper.rb │ ├── settings_helper.rb │ ├── reg_requests_helper.rb │ ├── registrations_helper.rb │ ├── courses_helper.rb │ ├── teams_helper.rb │ ├── grader_allocations_helper.rb │ ├── link_to_function_helper.rb │ ├── spinner_helper.rb │ └── exams_schema.yaml ├── assets │ ├── stylesheets │ │ ├── assignment.scss │ │ ├── actions.scss │ │ ├── page-header.scss │ │ ├── sandboxes.scss │ │ ├── bootstrap-treeview.scss │ │ ├── footer.scss │ │ ├── button-file-inputs.scss │ │ ├── questions.scss │ │ └── bootstrap-overrides.scss │ ├── images │ │ ├── c-mark.png │ │ ├── rails.png │ │ ├── dolphin.png │ │ ├── null-mark.png │ │ ├── sad-mark.png │ │ ├── site-icon.png │ │ ├── texture.png │ │ ├── wait-mark.gif │ │ ├── check-mark.png │ │ ├── check-plus.png │ │ ├── cminus-mark.png │ │ ├── crash-mark.png │ │ ├── cross-mark.png │ │ ├── flammarion.png │ │ ├── silhouette.jpg │ │ ├── failure-option.jpg │ │ └── question-mark.png │ └── javascripts │ │ ├── nicEditorIcons.gif │ │ ├── 0startup.js.coffee │ │ ├── sandboxes.coffee │ │ ├── settings.js.coffee │ │ ├── main.js.coffee │ │ ├── terms.js.coffee │ │ ├── reg_requests.js.coffee │ │ ├── submissions.js │ │ ├── grades.js │ │ └── teamsets.js.coffee ├── jobs │ ├── application_job.rb │ └── grade_submission_job.rb ├── views │ ├── teamsets │ │ ├── edit.html.erb │ │ ├── investigate.html.erb │ │ ├── _diff_teamsets.html.erb │ │ └── _table.html.erb │ ├── users │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ └── _form.js.erb │ ├── reg_requests │ │ └── new.html.erb │ ├── courses │ │ ├── edit.html.erb │ │ ├── new.html.erb │ │ ├── public.html.erb │ │ ├── index.html.erb │ │ ├── _grading_due.html.erb │ │ ├── _section.html.erb │ │ └── _table.html.erb │ ├── grades │ │ ├── edit_ExamGrader.html.erb │ │ ├── edit_exam_curved_grades.html.erb │ │ ├── _checker_import_schema.html.erb │ │ ├── _junit_import_schema.html.erb │ │ ├── _tap_style_import_schema.html.erb │ │ ├── _orca_output.js.erb │ │ ├── _grades_file_picker.html.erb │ │ ├── _exam_export_schema.html.erb │ │ ├── _show_xunit_tests.html.erb │ │ └── _exam_import_schema.html.erb │ ├── sandboxes │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ ├── show.html.erb │ │ ├── _form.html.erb │ │ └── index.html.erb │ ├── terms │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ ├── show.html.erb │ │ ├── _table.html.erb │ │ ├── index.html.erb │ │ └── _form.html.erb │ ├── assignments │ │ ├── new.html.erb │ │ ├── show_user_exam.html.erb │ │ ├── edit.html.erb │ │ ├── _interlock.html.erb │ │ ├── _due_date.html.erb │ │ ├── _submission_enabled_toggles.html.erb │ │ ├── show_files.html.erb │ │ ├── show_user_files.html.erb │ │ ├── show_user_questions.html.erb │ │ ├── _assignment_file_picker.html.erb │ │ └── _form.html.erb │ ├── grading_conflicts │ │ └── new.html.erb │ ├── layouts │ │ ├── _flash.html.erb │ │ ├── course.html.erb │ │ ├── _footer.html.erb │ │ ├── _spinner.html.erb │ │ └── errors.html.erb │ ├── main │ │ ├── about.html.erb │ │ └── status.html.erb │ ├── submissions │ │ ├── show_questions.html.erb │ │ ├── show_codereview.html.erb │ │ ├── _enter_answer_text.html.erb │ │ ├── _show_answer_text.html.erb │ │ ├── _show_answer_code.html.erb │ │ ├── _enter_answer_code.html.erb │ │ ├── _enter_answer_numeric.html.erb │ │ ├── details_codereview.html.erb │ │ ├── _show_answer_numeric.html.erb │ │ ├── _enter_answer_true_false.html.erb │ │ ├── _enter_answer_yes_no.html.erb │ │ ├── _show_answer_true_false.html.erb │ │ ├── _show_answer_yes_no.html.erb │ │ ├── _scoring_common.js.erb │ │ ├── _code_tag.html.erb │ │ └── show_files.html.erb │ ├── graders │ │ ├── _ping_orca.js.erb │ │ ├── _manual_grader.html.erb │ │ ├── _junit_grader.js.erb │ │ ├── _schema_grader.js.erb │ │ ├── _java_style_grader.html.erb │ │ ├── _racket_style_grader.html.erb │ │ ├── _python_style_grader.html.erb │ │ ├── build_log.html.erb │ │ └── _grader_file_picker.html.erb │ ├── errors │ │ ├── not_found.html.erb │ │ └── internal_server_error.html.erb │ ├── notification_mailer │ │ └── got_reg_request.text.erb │ ├── grader_allocations │ │ └── stats.html.erb │ ├── registrations │ │ └── index.html.erb │ ├── reviews │ │ └── show.html.erb │ └── teams │ │ └── show.html.erb ├── controllers │ ├── api │ │ ├── users_controller.rb │ │ ├── graders_controller.rb │ │ ├── courses_controller.rb │ │ └── registrations_controller.rb │ ├── settings_controller.rb │ ├── oauth │ │ ├── authorizations_controller.rb │ │ └── applications_controller.rb │ ├── graders_controller.rb │ ├── files_controller.rb │ ├── errors_controller.rb │ └── teams_controller.rb └── javascript │ └── packs │ └── application.js ├── test ├── fixtures │ ├── .gitkeep │ ├── files │ │ ├── image.jpg │ │ ├── PDFs │ │ │ └── sample.pdf │ │ ├── junit-example.zip │ │ ├── Archive-no-perms.zip │ │ ├── HelloWorld │ │ │ ├── HelloWorld.tgz │ │ │ ├── HelloWorld.zip │ │ │ ├── HelloWorld.tar.gz │ │ │ ├── HelloWorld-john.tar.gz │ │ │ ├── HelloWorld-assign.tar.gz │ │ │ └── HelloWorld-grading.tar.gz │ │ ├── students.csv │ │ ├── HelloSingle │ │ │ ├── HelloSingle-grading.tar.gz │ │ │ └── hello.c │ │ ├── TestScript │ │ │ ├── hello.c │ │ │ └── test.pl │ │ ├── test-exam.yaml │ │ ├── fundies-config.json │ │ ├── Exam │ │ │ ├── exam-v2-error-questions.yaml │ │ │ ├── exam.yaml │ │ │ ├── exam-v2-correct.yaml │ │ │ ├── exam-v2-error-weight.yaml │ │ │ └── exam-incorrect-format.yaml │ │ └── Exam-EC │ │ │ └── exam.yaml │ ├── sandboxes.yml │ ├── grader_configs.yml │ └── inline_comments.yml ├── models │ ├── .gitkeep │ ├── helpers │ │ ├── main_helper_test.rb │ │ ├── terms_helper_test.rb │ │ ├── users_helper_test.rb │ │ ├── answers_helper_test.rb │ │ ├── courses_helper_test.rb │ │ ├── lessons_helper_test.rb │ │ ├── assignments_helper_test.rb │ │ ├── reg_requests_helper_test.rb │ │ ├── submissions_helper_test.rb │ │ └── registrations_helper_test.rb │ ├── bucket_test.rb │ ├── reg_request_test.rb │ ├── team_user_test.rb │ ├── grader_config_test.rb │ ├── registration_test.rb │ ├── inline_comment_test.rb │ ├── user_test.rb │ ├── team_test.rb │ └── sandbox_test.rb ├── integration │ ├── .gitkeep │ ├── login_redirect.rb │ ├── sanity_test.rb │ ├── show_hide_username_test.rb │ └── add_user_test.rb ├── jobs │ └── grade_submission_job_test.rb ├── performance │ └── browsing_test.rb └── controllers │ └── settings_controller_test.rb ├── vendor ├── plugins │ └── .gitkeep └── assets │ ├── javascripts │ └── .gitkeep │ └── stylesheets │ └── .gitkeep ├── .browserslistrc ├── bin ├── start.sh ├── rake ├── bundle ├── rails ├── delayed_job ├── webpack ├── webpack-dev-server ├── yarn ├── update └── setup ├── config ├── webpack │ ├── environment.js │ ├── test.js │ ├── production.js │ └── development.js ├── spring.rb ├── orca.yml ├── initializers │ ├── session_store.rb │ ├── action_mailer.rb │ ├── application_controller_renderer.rb │ ├── cookies_serializer.rb │ ├── mime_types.rb │ ├── permissions_policy.rb │ ├── filter_parameter_logging.rb │ ├── assets.rb │ ├── wrap_parameters.rb │ ├── backtrace_silencers.rb │ ├── inflections.rb │ ├── secret_token.rb │ ├── backburner.rb │ └── content_security_policy.rb ├── boot.rb ├── cable.yml ├── environment.rb ├── ldap.yml ├── schedule.rb ├── locales │ └── en.yml ├── secrets.yml └── storage.yml ├── sandbox ├── examples │ ├── demo │ │ ├── hello.tar.gz │ │ ├── demo-grading.tar.gz │ │ ├── hello │ │ │ ├── Makefile │ │ │ ├── hello.c │ │ │ └── test.pl │ │ └── _grading │ │ │ ├── Makefile │ │ │ ├── test.pl │ │ │ └── grade.rb │ ├── extra │ │ ├── hello.tar.gz │ │ ├── extra-grading.tar.gz │ │ ├── hello │ │ │ ├── Makefile │ │ │ ├── hello.c │ │ │ └── test.pl │ │ ├── _grading │ │ │ ├── Makefile │ │ │ └── grade.rb │ │ └── test.pl │ ├── sleep │ │ ├── sleep.tar.gz │ │ └── _grading │ │ │ └── grade.rb │ └── check.rb ├── start-container.sh └── driver.pl.erb ├── Passengerfile.json ├── db ├── migrate │ ├── 20170506003128_rename_sections.rb │ ├── 20170811161131_grader_extra_upload.rb │ ├── 20180609014742_make_terms_unique.rb │ ├── 20170702154328_require_show_in_lists.rb │ ├── 20180924222312_index_used_subs_on_assignment_id.rb │ ├── 20180301224622_index_inline_comments_on_severity.rb │ ├── 20170705045007_require_assignment_grader_order.rb │ ├── 20190303232336_add_index_to_registrations.rb │ ├── 20240725235205_add_orca_status_to_grader.rb │ ├── 20180211180103_index_inline_comments.rb │ ├── 20201026221030_add_user_index_to_inline_comments.rb │ ├── 20170714150844_rename_grader_allocation_grader.rb │ ├── 20170602143559_rename_team_sets.rb │ ├── 20170827140156_index_codereview_matchings_on_assignment_id.rb │ ├── 20171211221349_add_extra_credit_fields.rb │ ├── 20170504141136_auxiliary.rb │ ├── 20170726215845_change_interlock_constraint_type.rb │ ├── 20170726231116_create_submission_views.rb │ ├── 20170727203859_create_codereview_matchings.rb │ ├── 20180302211623_add_bonus_inline_comment_type.rb │ ├── 20181004011746_create_submission_enabled_toggles.rb │ ├── 20201007115016_add_timestamps_to_submission_views.rb │ ├── 20171103172019_create_team_requests.rb │ ├── 20171218170821_create_individual_extensions.rb │ ├── 20170805001646_drop_delayed_jobs.rb │ ├── 20171121152503_make_crns_nonunique.rb │ ├── 20170718000106_create_review_feedbacks.rb │ ├── 20171210143444_make_matchings_unique.rb │ ├── 20180801182418_add_assignment_to_uploads.rb │ ├── 20170710141402_rename_assignment_types.rb │ ├── 20220224011641_create_grading_conflicts.rb │ ├── 20170713123707_rename_submission_types.rb │ ├── 20220426161610_change_primary_key_to_bigint.rb │ ├── 20170531183453_make_teamsets_mandatory.rb │ ├── 20240828125219_change_orca_status_type.rb │ └── 20180608211724_schematize_terms.rb └── simple-data.rb ├── config.ru ├── postcss.config.js ├── script ├── rails ├── getip.pl ├── update-grade-caches ├── parse-test-output ├── regrade-sub ├── clear_jobs ├── mark-find-submissions ├── assign-tarball ├── assignment_grep.rb ├── regrade-whole-assignment ├── resend-auth-links ├── dredge.pl ├── fix-quoted-names ├── dump_comments.rb ├── bulk-user-upload └── cleanup-db ├── package.json └── flake.lock /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.0.2 2 | -------------------------------------------------------------------------------- /app/mailers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /test/integration/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/helpers/main_helper.rb: -------------------------------------------------------------------------------- 1 | module MainHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/terms_helper.rb: -------------------------------------------------------------------------------- 1 | module TermsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/users_helper.rb: -------------------------------------------------------------------------------- 1 | module UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/buckets_helper.rb: -------------------------------------------------------------------------------- 1 | module BucketsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/assets/stylesheets/assignment.scss: -------------------------------------------------------------------------------- 1 | /* assignments.scss */ 2 | -------------------------------------------------------------------------------- /app/helpers/sandboxes_helper.rb: -------------------------------------------------------------------------------- 1 | module SandboxesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/settings_helper.rb: -------------------------------------------------------------------------------- 1 | module SettingsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/reg_requests_helper.rb: -------------------------------------------------------------------------------- 1 | module RegRequestsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/registrations_helper.rb: -------------------------------------------------------------------------------- 1 | module RegistrationsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /bin/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ~/.rvm/bin/rvm-shell -c 'bundle exec rake backburner:work' 3 | -------------------------------------------------------------------------------- /app/views/teamsets/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "Edit teamsets" %> 2 | <%= render 'form' %> 3 | -------------------------------------------------------------------------------- /app/assets/images/c-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/c-mark.png -------------------------------------------------------------------------------- /app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/rails.png -------------------------------------------------------------------------------- /app/views/users/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "Edit User: #{@user.name}" %> 2 | 3 | <%= render 'form' %> 4 | -------------------------------------------------------------------------------- /app/assets/images/dolphin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/dolphin.png -------------------------------------------------------------------------------- /app/assets/images/null-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/null-mark.png -------------------------------------------------------------------------------- /app/assets/images/sad-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/sad-mark.png -------------------------------------------------------------------------------- /app/assets/images/site-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/site-icon.png -------------------------------------------------------------------------------- /app/assets/images/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/texture.png -------------------------------------------------------------------------------- /app/assets/images/wait-mark.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/wait-mark.gif -------------------------------------------------------------------------------- /app/models/team_user.rb: -------------------------------------------------------------------------------- 1 | class TeamUser < ApplicationRecord 2 | belongs_to :user 3 | belongs_to :team 4 | end 5 | -------------------------------------------------------------------------------- /app/views/reg_requests/new.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "New Registration Request" %> 2 | 3 | <%= render 'form' %> 4 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /lib/tasks/demo-images/men.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/lib/tasks/demo-images/men.jpg -------------------------------------------------------------------------------- /lib/tasks/demo-images/women.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/lib/tasks/demo-images/women.jpg -------------------------------------------------------------------------------- /test/fixtures/files/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/test/fixtures/files/image.jpg -------------------------------------------------------------------------------- /app/assets/images/check-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/check-mark.png -------------------------------------------------------------------------------- /app/assets/images/check-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/check-plus.png -------------------------------------------------------------------------------- /app/assets/images/cminus-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/cminus-mark.png -------------------------------------------------------------------------------- /app/assets/images/crash-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/crash-mark.png -------------------------------------------------------------------------------- /app/assets/images/cross-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/cross-mark.png -------------------------------------------------------------------------------- /app/assets/images/flammarion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/flammarion.png -------------------------------------------------------------------------------- /app/assets/images/silhouette.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/silhouette.jpg -------------------------------------------------------------------------------- /app/helpers/courses_helper.rb: -------------------------------------------------------------------------------- 1 | module CoursesHelper 2 | def num_to_col(n) 3 | ("A".."Z").to_a[n] 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/courses/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "#{@course.name} - Edit Course" %> 2 | 3 | <%= render 'form' %> 4 | 5 | -------------------------------------------------------------------------------- /app/views/grades/edit_ExamGrader.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = @grader.display_type %> 2 | 3 | <%= render "exam_form" %> 4 | -------------------------------------------------------------------------------- /config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | module.exports = environment 4 | -------------------------------------------------------------------------------- /app/assets/images/failure-option.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/failure-option.jpg -------------------------------------------------------------------------------- /app/assets/images/question-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/images/question-mark.png -------------------------------------------------------------------------------- /sandbox/examples/demo/hello.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/sandbox/examples/demo/hello.tar.gz -------------------------------------------------------------------------------- /sandbox/examples/extra/hello.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/sandbox/examples/extra/hello.tar.gz -------------------------------------------------------------------------------- /sandbox/examples/sleep/sleep.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/sandbox/examples/sleep/sleep.tar.gz -------------------------------------------------------------------------------- /test/fixtures/files/PDFs/sample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/test/fixtures/files/PDFs/sample.pdf -------------------------------------------------------------------------------- /test/models/helpers/main_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MainHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/models/helpers/terms_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TermsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/models/helpers/users_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UsersHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /Passengerfile.json: -------------------------------------------------------------------------------- 1 | { 2 | "log_file": "log/passenger.log", 3 | "environment": "production", 4 | "min_instances": 2 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/files/junit-example.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/test/fixtures/files/junit-example.zip -------------------------------------------------------------------------------- /test/models/helpers/answers_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class AnswersHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/models/helpers/courses_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CoursesHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/models/helpers/lessons_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LessonsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/javascripts/nicEditorIcons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/app/assets/javascripts/nicEditorIcons.gif -------------------------------------------------------------------------------- /app/assets/stylesheets/actions.scss: -------------------------------------------------------------------------------- 1 | .actions { 2 | display: inline-block; 3 | float: right; 4 | position: relative; 5 | } 6 | -------------------------------------------------------------------------------- /app/views/sandboxes/new.html.erb: -------------------------------------------------------------------------------- 1 |
Create New Assignment
4 | 5 | <%= render 'form' %> 6 | -------------------------------------------------------------------------------- /sandbox/examples/demo/hello/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | hello: 4 | gcc -o hello hello.c 5 | 6 | test: 7 | perl test.pl 8 | 9 | clean: 10 | rm -f hello 11 | -------------------------------------------------------------------------------- /sandbox/examples/extra/hello/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | hello: 4 | gcc -o hello hello.c 5 | 6 | test: 7 | perl test.pl 8 | 9 | clean: 10 | rm -f hello 11 | -------------------------------------------------------------------------------- /test/fixtures/files/HelloWorld/HelloWorld-john.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/test/fixtures/files/HelloWorld/HelloWorld-john.tar.gz -------------------------------------------------------------------------------- /app/helpers/teams_helper.rb: -------------------------------------------------------------------------------- 1 | module TeamsHelper 2 | def names_for_select(users) 3 | options_for_select(users.map {|uu| [uu.name, uu.id] }) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/courses/new.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "New Course" %> 2 | 3 |<%= link_to 'Back to Courses List', courses_path %>
4 | 5 | <%= render 'form' %> 6 | -------------------------------------------------------------------------------- /app/views/grading_conflicts/new.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "New Grading Conflict" %> 2 | <% cur_reg = current_user.registration_for(@course) %> 3 | <%= render 'form' %> -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /sandbox/examples/demo/_grading/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | hello: 4 | gcc -o hello hello.c 5 | 6 | test: 7 | @perl test.pl 8 | 9 | clean: 10 | rm -f hello 11 | -------------------------------------------------------------------------------- /sandbox/examples/extra/_grading/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | hello: 4 | gcc -o hello hello.c 5 | 6 | test: 7 | @perl test.pl 8 | 9 | clean: 10 | rm -f hello 11 | -------------------------------------------------------------------------------- /test/fixtures/files/HelloWorld/HelloWorld-assign.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/test/fixtures/files/HelloWorld/HelloWorld-assign.tar.gz -------------------------------------------------------------------------------- /test/fixtures/files/HelloWorld/HelloWorld-grading.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/test/fixtures/files/HelloWorld/HelloWorld-grading.tar.gz -------------------------------------------------------------------------------- /app/assets/javascripts/0startup.js.coffee: -------------------------------------------------------------------------------- 1 | 2 | window.run_on_page = (name, func) -> 3 | $(() -> 4 | if name == window.current_page_name 5 | func() 6 | ) 7 | -------------------------------------------------------------------------------- /test/fixtures/files/HelloSingle/HelloSingle-grading.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeGrade/bottlenose/HEAD/test/fixtures/files/HelloSingle/HelloSingle-grading.tar.gz -------------------------------------------------------------------------------- /app/views/sandboxes/edit.html.erb: -------------------------------------------------------------------------------- 1 |Bottlenose is a web application to manage assignment submissions and grades 4 | for computer science courses.
5 | 6 | 7 | -------------------------------------------------------------------------------- /config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /app/views/layouts/course.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :content do %> 2 | <%= render "layouts/standard_course_info" %> 3 | <%= yield %> 4 | <% end %> 5 | 6 | <%= render template: "layouts/application" %> 7 | -------------------------------------------------------------------------------- /db/migrate/20170702154328_require_show_in_lists.rb: -------------------------------------------------------------------------------- 1 | class RequireShowInLists < ActiveRecord::Migration[5.1] 2 | def change 3 | change_column_null :registrations, :show_in_lists, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20180924222312_index_used_subs_on_assignment_id.rb: -------------------------------------------------------------------------------- 1 | class IndexUsedSubsOnAssignmentId < ActiveRecord::Migration[5.2] 2 | def change 3 | add_index :used_subs, :assignment_id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /sandbox/examples/extra/test.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use 5.16.0; 3 | 4 | use Test::Simple tests => 1; 5 | 6 | my $hello = `./hello`; 7 | chomp $hello; 8 | ok($hello eq "Hi!", "output correct"); 9 | 10 | -------------------------------------------------------------------------------- /db/migrate/20180301224622_index_inline_comments_on_severity.rb: -------------------------------------------------------------------------------- 1 | class IndexInlineCommentsOnSeverity < ActiveRecord::Migration[5.1] 2 | def change 3 | add_index :inline_comments, [:severity] 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /sandbox/examples/demo/hello/test.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use 5.16.0; 3 | 4 | use Test::Simple tests => 1; 5 | 6 | my $hello = `./hello`; 7 | chomp $hello; 8 | ok($hello eq "Hi!", "output correct"); 9 | 10 | -------------------------------------------------------------------------------- /sandbox/examples/extra/hello/test.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use 5.16.0; 3 | 4 | use Test::Simple tests => 1; 5 | 6 | my $hello = `./hello`; 7 | chomp $hello; 8 | ok($hello eq "Hi!", "output correct"); 9 | 10 | -------------------------------------------------------------------------------- /sandbox/examples/sleep/_grading/grade.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | $stdout.sync = true 4 | $stderr.sync = true 5 | 6 | 0.upto(20) do |ii| 7 | puts "Hello #{ii}" 8 | sleep(5) 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /sandbox/examples/demo/_grading/test.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use 5.16.0; 3 | 4 | use Test::Simple tests => 1; 5 | 6 | my $hello = `./hello`; 7 | chomp $hello; 8 | ok($hello eq "Hi!", "output correct"); 9 | 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/page-header.scss: -------------------------------------------------------------------------------- 1 | .page-header { 2 | margin-top: 0; 3 | 4 | h1 { 5 | display: inline-block; 6 | } 7 | 8 | .actions { 9 | margin-top: 25px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /bin/delayed_job: -------------------------------------------------------------------------------- 1 | #!/home/bottlenose/.rbenv/shims/ruby 2 | 3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) 4 | require 'delayed/command' 5 | Delayed::Command.new(ARGV).daemonize 6 | -------------------------------------------------------------------------------- /db/migrate/20170705045007_require_assignment_grader_order.rb: -------------------------------------------------------------------------------- 1 | class RequireAssignmentGraderOrder < ActiveRecord::Migration[5.1] 2 | def change 3 | change_column_null :assignment_graders, :order, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20190303232336_add_index_to_registrations.rb: -------------------------------------------------------------------------------- 1 | class AddIndexToRegistrations < ActiveRecord::Migration[5.2] 2 | def change 3 | add_index :registrations, [:course_id, :user_id], unique: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sandboxes.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the sandboxes controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /db/migrate/20240725235205_add_orca_status_to_grader.rb: -------------------------------------------------------------------------------- 1 | class AddOrcaStatusToGrader < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :graders, :orca_status, :boolean, default: false, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /config/initializers/action_mailer.rb: -------------------------------------------------------------------------------- 1 | 2 | # Set default hostname for emailed URLs. 3 | unless Rails.env.test? 4 | ActionMailer::Base.default_url_options[:host] = `hostname -f`.chomp 5 | ActionMailer::Base.delivery_method = :sendmail 6 | end 7 | -------------------------------------------------------------------------------- /lib/tasks/screenshots.rake: -------------------------------------------------------------------------------- 1 | desc "Generates screenshots for the manual" 2 | namespace :manual do 3 | task :screenshots => :environment do 4 | exec("ruby", File.expand_path("../screenshots.rb", __FILE__), *ARGV[1..-1]) 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/fixtures/sandboxes.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: MyString 5 | submission_id: 6 | 7 | two: 8 | name: MyString 9 | submission_id: 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/bootstrap-treeview.scss: -------------------------------------------------------------------------------- 1 | .treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed} -------------------------------------------------------------------------------- /db/migrate/20180211180103_index_inline_comments.rb: -------------------------------------------------------------------------------- 1 | class IndexInlineComments < ActiveRecord::Migration[5.1] 2 | def change 3 | add_index "inline_comments", [:grade_id] 4 | add_index "inline_comments", [:submission_id] 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/fixtures/files/test-exam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - weight: 6 3 | - weight: 6 4 | name: "Question 2!" 5 | - parts: 6 | - weight: 3 7 | name: "Problem 3a" 8 | - weight: 5 9 | name: "Problem 3b" 10 | - weight: 3 11 | extra: true 12 | -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: bottlenose_production 11 | -------------------------------------------------------------------------------- /app/assets/javascripts/sandboxes.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/settings.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/models/submission_view.rb: -------------------------------------------------------------------------------- 1 | class SubmissionView < ApplicationRecord 2 | belongs_to :user 3 | belongs_to :assignment 4 | belongs_to :team, optional: true 5 | 6 | validates :user_id, presence: true 7 | validates :assignment_id, presence: true 8 | end 9 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | def fa_icon(name) 5 | %Q{}.html_safe 6 | end 7 | 8 | # Initialize the Rails application. 9 | Rails.application.initialize! 10 | -------------------------------------------------------------------------------- /db/migrate/20201026221030_add_user_index_to_inline_comments.rb: -------------------------------------------------------------------------------- 1 | class AddUserIndexToInlineComments < ActiveRecord::Migration[5.2] 2 | def change 3 | add_index "inline_comments", ["user_id"], name: "index_inline_comments_on_user_id", using: :btree 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/files/fundies-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "OneTopLevelClass": {"category": "ignore"}, 3 | "OuterTypeFilename": {"category": "ignore"}, 4 | "AvoidStarImport": {"category": "ignore"}, 5 | "SummaryJavadoc": {"category": "ignore"} 6 | } 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/main.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /db/migrate/20170714150844_rename_grader_allocation_grader.rb: -------------------------------------------------------------------------------- 1 | class RenameGraderAllocationGrader < ActiveRecord::Migration[5.1] 2 | def change 3 | change_table :grader_allocations do |t| 4 | t.rename :grade_id, :who_grades_id 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/audit.rb: -------------------------------------------------------------------------------- 1 | class Audit 2 | @@log = Logger.new(File.open(Rails.root.join("log", "audit-#{Rails.env}.log"), 3 | File::WRONLY | File::APPEND | File::CREAT)) 4 | def self.log(msg) 5 | @@log.info("#{Time.now}: #{msg}") 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/assets/javascripts/terms.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /app/models/assignments/files.rb: -------------------------------------------------------------------------------- 1 | class Files < Assignment 2 | validates :related_assignment_id, :absence => true 3 | 4 | def questions 5 | nil 6 | end 7 | def flattened_questions 8 | nil 9 | end 10 | def sections 11 | nil 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /test/models/user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UserTest < ActiveSupport::TestCase 4 | test "email addresses are forced to lowercase" do 5 | bob = create(:user, email: "Bob@example.com") 6 | assert_equal(bob.email, bob.email.downcase) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/assets/javascripts/reg_requests.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /test/fixtures/files/Exam/exam-v2-error-questions.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Matrix transpose" 3 | weight: 11 4 | - name: "Duplicator iterator" 5 | weight: 16 6 | - name: "Charm bracelets" 7 | weight: 12 8 | - name: "Equality/hashCode" 9 | weight: 5 10 | extra: true 11 | ... 12 | -------------------------------------------------------------------------------- /db/migrate/20170602143559_rename_team_sets.rb: -------------------------------------------------------------------------------- 1 | class RenameTeamSets < ActiveRecord::Migration[5.1] 2 | def change 3 | rename_table :team_sets, :teamsets 4 | rename_column :teams, :team_set_id, :teamset_id 5 | rename_column :assignments, :team_set_id, :teamset_id 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /db/migrate/20170827140156_index_codereview_matchings_on_assignment_id.rb: -------------------------------------------------------------------------------- 1 | class IndexCodereviewMatchingsOnAssignmentId < ActiveRecord::Migration[5.1] 2 | def change 3 | add_index "codereview_matchings", ["assignment_id"], name: "index_codereview_matchings_on_assignment_id" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('postcss-preset-env')({ 6 | autoprefixer: { 7 | flexbox: 'no-2009' 8 | }, 9 | stage: 3 10 | }) 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /app/models/user_submission.rb: -------------------------------------------------------------------------------- 1 | class UserSubmission < ApplicationRecord 2 | belongs_to :user 3 | belongs_to :submission 4 | 5 | def self.with_user(user) 6 | where(user_id: user) 7 | end 8 | 9 | def self.with_submission(sub) 10 | where(submission_id: sub) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/submissions/show_questions.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "View Submission" %> 2 | <% cur_reg = current_user.registration_for(@course) %> 3 | 4 | <%= render "show_common", cur_reg: cur_reg, kind: "responses", 5 | show_download: false %> 6 | 7 | <%= render "scoring_common", cur_reg: cur_reg %> 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | Mime::Type.register "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :xlsx 6 | -------------------------------------------------------------------------------- /app/views/submissions/show_codereview.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "View Submission" %> 2 | <% cur_reg = current_user.registration_for(@course) %> 3 | 4 | <%= render "show_common", cur_reg: cur_reg, kind: "responses", 5 | show_download: false %> 6 | 7 | <%= render "scoring_common", cur_reg: cur_reg %> 8 | -------------------------------------------------------------------------------- /db/migrate/20171211221349_add_extra_credit_fields.rb: -------------------------------------------------------------------------------- 1 | class AddExtraCreditFields < ActiveRecord::Migration[5.1] 2 | def change 3 | add_column :assignments, :extra_credit, :boolean, null: false, default: false 4 | add_column :graders, :extra_credit, :boolean, null: false, default: false 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/array_split.rb: -------------------------------------------------------------------------------- 1 | 2 | class Array 3 | def split_on(pat) 4 | as = [[]] 5 | ii = 0 6 | 7 | self.each do |xx| 8 | if xx.match(pat) 9 | as << [] 10 | ii += 1 11 | else 12 | as[ii] << xx 13 | end 14 | end 15 | 16 | as 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/fixtures/files/Exam/exam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Matrix transpose" 3 | weight: 11 4 | - name: "Duplicator iterator" 5 | weight: 16 6 | - name: "Visitors" 7 | weight: 11 8 | - name: "Charm bracelets" 9 | weight: 12 10 | - name: "Equality/hashCode" 11 | weight: 7 12 | extra: true 13 | ... 14 | -------------------------------------------------------------------------------- /app/helpers/grader_allocations_helper.rb: -------------------------------------------------------------------------------- 1 | module GraderAllocationsHelper 2 | def names_for_submissions(subs) 3 | options_for_select(subs.map {|sub| [sub.submission_user_names, sub.id] }) 4 | end 5 | def names_for_graders(graders) 6 | options_for_select(graders.map {|g| [g.name, g.id] }) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/fixtures/files/Exam-EC/exam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Matrix transpose" 3 | weight: 11 4 | - name: "Duplicator iterator" 5 | weight: 16 6 | - name: "Visitors" 7 | weight: 11 8 | - name: "Charm bracelets" 9 | weight: 12 10 | - name: "Equality/hashCode" 11 | weight: 7 12 | extra: true 13 | ... 14 | -------------------------------------------------------------------------------- /app/models/grading_conflict_audit.rb: -------------------------------------------------------------------------------- 1 | class GradingConflictAudit < ApplicationRecord 2 | enum status: [:active, :inactive, :pending, :rejected] 3 | belongs_to :user 4 | belongs_to :grading_conflict 5 | 6 | def reason=(value) 7 | super(ActionController::Base.helpers.sanitize(value)) 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /db/migrate/20170504141136_auxiliary.rb: -------------------------------------------------------------------------------- 1 | class Auxiliary < ActiveRecord::Migration[4.2] 2 | def self.up 3 | execute "TRUNCATE schema_migrations;" 4 | execute "INSERT INTO schema_migrations VALUES ('20170502174648');" 5 | end 6 | def self.down 7 | raise ActiveRecord::IrreversibleMigration 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/fixtures/files/Exam/exam-v2-correct.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Matrix transpose" 3 | weight: 11 4 | - name: "Duplicator iterator" 5 | weight: 16 6 | - name: "Visitors" 7 | weight: 11 8 | - name: "Charm bracelets" 9 | weight: 13 10 | - name: "Equality/hashCode" 11 | weight: 7 12 | extra: true 13 | ... 14 | -------------------------------------------------------------------------------- /app/views/layouts/_footer.html.erb: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /test/fixtures/files/Exam/exam-v2-error-weight.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Matrix transpose" 3 | weight: 11 4 | - name: "Duplicator iterator" 5 | weight: 16 6 | - name: "Visitors" 7 | weight: 11 8 | - name: "Charm bracelets" 9 | weight: 1 10 | - name: "Equality/hashCode" 11 | weight: 10 12 | extra: true 13 | ... 14 | -------------------------------------------------------------------------------- /app/views/submissions/_enter_answer_text.html.erb: -------------------------------------------------------------------------------- 1 |<%= notice %>
2 | 3 |4 | Name: 5 | <%= @sandbox.name %> 6 |
7 | 8 |9 | Submission: 10 | <%= @sandbox.submission_id %> 11 |
12 | 13 | <%= link_to 'Edit', edit_sandbox_path(@sandbox) %> | 14 | <%= link_to 'Back', sandboxes_path %> 15 | -------------------------------------------------------------------------------- /script/update-grade-caches: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | APP_PATH = File.expand_path('../../config/application', __FILE__) 4 | require File.expand_path('../../config/boot', __FILE__) 5 | require APP_PATH 6 | Rails.application.require_environment! 7 | 8 | Submission.all.each do |sub| 9 | sub.assignment.update_best_sub_for!(sub.user) 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20170726215845_change_interlock_constraint_type.rb: -------------------------------------------------------------------------------- 1 | class ChangeInterlockConstraintType < ActiveRecord::Migration[5.1] 2 | def up 3 | remove_column :interlocks, :constraint 4 | add_column :interlocks, :constraint, :integer, null: false 5 | end 6 | def down 7 | change_column :interlocks, :constraint, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/submissions.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | function initFiles() { 3 | $(".symlink-jump").click(function(e) { 4 | e.preventDefault(); 5 | e.stopPropagation(); 6 | selectTreeviewFileByHref($(this).data("root"), $(this).attr("href")); 7 | }); 8 | } 9 | 10 | 11 | run_on_page("submissions/details", initFiles); 12 | })(); 13 | -------------------------------------------------------------------------------- /db/migrate/20170726231116_create_submission_views.rb: -------------------------------------------------------------------------------- 1 | class CreateSubmissionViews < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :submission_views do |t| 4 | t.integer :user_id, null: false 5 | t.integer :team_id, null: true # teams might be optional 6 | t.integer :assignment_id, null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/submissions/_show_answer_code.html.erb: -------------------------------------------------------------------------------- 1 |<%= notice %>
4 | 5 |6 | Name: 7 | <%= @term.name %> 8 |
9 | 10 |11 | Archived: 12 | <%= @term.archived? ? "yes" : "no" %> 13 |
14 | 15 | <% if current_user.site_admin? %> 16 | <%= link_to 'Edit', edit_term_path(@term) %> | 17 | <% end %> 18 | <%= link_to 'Back', terms_path %> 19 | -------------------------------------------------------------------------------- /sandbox/examples/extra/_grading/grade.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'steno' 4 | 5 | fs = ['Makefile', 'test.pl'] 6 | 7 | FileUtils.cp("test.pl", "_grading") 8 | 9 | steno = Steno.new 10 | steno.save_grading_hashes(fs) 11 | steno.unpack 12 | steno.shell("make") 13 | steno.check_grading_hashes 14 | fs.each do |name| 15 | FileUtils.cp("_grading/#{name}", ".") 16 | end 17 | steno.run_tests("perl test.pl") 18 | 19 | -------------------------------------------------------------------------------- /test/fixtures/grader_configs.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/fixtures/files/TestScript/test.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use 5.16.0; 3 | use strict; 4 | use warnings FATAL => 'all'; 5 | 6 | use Test::Simple tests => 2; 7 | 8 | system("rm -f hello"); 9 | system("gcc -o hello hello.c"); 10 | my $rv = $? >> 8; 11 | 12 | ok($rv == 0, "Compile OK"); 13 | 14 | my $hello = `./hello`; 15 | chomp $hello; 16 | 17 | ok($hello eq "Hello, World!", "Hello OK"); 18 | 19 | system("rm -f hello"); 20 | 21 | -------------------------------------------------------------------------------- /app/assets/stylesheets/footer.scss: -------------------------------------------------------------------------------- 1 | $footer-height: 40px; 2 | 3 | html { 4 | position: relative; 5 | min-height: 100%; 6 | } 7 | 8 | body { 9 | margin-bottom: $footer-height; 10 | } 11 | 12 | .footer { 13 | background-color: #f5f5f5; 14 | border-top: thin solid gray; 15 | bottom: 0; 16 | height: $footer-height; 17 | padding: 8px; 18 | position: absolute; 19 | text-align: center; 20 | width: 100%; 21 | } 22 | -------------------------------------------------------------------------------- /db/migrate/20170727203859_create_codereview_matchings.rb: -------------------------------------------------------------------------------- 1 | class CreateCodereviewMatchings < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :codereview_matchings do |t| 4 | t.integer :assignment_id, null: false 5 | t.integer :user_id 6 | t.integer :team_id 7 | t.integer :target_user_id 8 | t.integer :target_team_id 9 | t.index [:user_id] 10 | t.index [:team_id] 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | #require 'test_helper' 2 | #require 'rails/performance_test_help' 3 | 4 | #class BrowsingTest < ActionDispatch::PerformanceTest 5 | # Refer to the documentation for all available options 6 | # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] 7 | # :output => 'tmp/performance', :formats => [:flat] } 8 | 9 | # def test_homepage 10 | # get '/' 11 | # end 12 | #end 13 | -------------------------------------------------------------------------------- /app/controllers/settings_controller.rb: -------------------------------------------------------------------------------- 1 | class SettingsController < ApplicationController 2 | before_action :require_site_admin 3 | 4 | def edit 5 | @cfg = Settings.load_json 6 | end 7 | 8 | def update 9 | @cfg = Settings.defaults 10 | 11 | @cfg.each_key do |kk| 12 | @cfg[kk] = params[kk] 13 | end 14 | 15 | Settings.save_json(@cfg) 16 | 17 | redirect_to edit_settings_path, notice: "Settings Saved" 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/views/graders/_ping_orca.js.erb: -------------------------------------------------------------------------------- 1 | function pingOrca(statusID, url) { 2 | if (!$(`#${statusID}`).length || url === '') { 3 | return; 4 | } 5 | $.ajax({ 6 | url, 7 | success: function (statusMessage) { 8 | $(`#${statusID}`).text(statusMessage); 9 | }, 10 | error: function (err) { 11 | $(`#${statusID}`).text(`Could not get status; ${err.status} ${err.statusMessage}`); 12 | }, 13 | dataType: 'json' 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /app/views/terms/_table.html.erb: -------------------------------------------------------------------------------- 1 || Name | 5 |Archived | 6 |
|---|---|
| <%= link_to term.name, term_path(term) %> | 12 |<%= term.archived? ? "archived" : "active" %> | 13 |
An archive containing:
4 |5 | assignment_<%= @assignment.id %>/ 6 | <submissionId>.tap: the updated TAP output for each submission 7 | or the string "DELETE" to erase the grade 8 |9 |
The easiest way to generate TAP files of the appropriate form is 10 | simply to use the tester library.
11 |An archive containing:
4 |5 | assignment_<%= @assignment.id %>/ 6 | <submissionId>.tap: the updated TAP output for each submission 7 | or the string "DELETE" to erase the grade 8 |9 |
The easiest way to generate TAP files of the appropriate form is 10 | simply to use the JUnitTap library.
11 |6 | <%= link_to "Back to submission", 7 | course_assignment_submission_path(@course, @assignment, @submission) %> 8 |
9 | 10 |10 | <%= image_tag "dolphin.png", style: "transform: rotate(20deg);" %> 11 |
An archive (.zip, .tar, .tar.gz or .tgz) containing:
5 | assignment_<%= @assignment.id %>/ 6 | <submissionId>.tap: the updated TAP output for each submission 7 | or the string "DELETE" to erase the grade 8 | OR 9 | <submissionId>.log: the updated error log file if there is no TAP output 10 |11 |
| <%= f.label "avail_score", "Points available:" %> | 7 |<%= f.spinner "avail_score", f.object.avail_score || 50, :min => 0, :delta => 5 %> | 8 |<%= f.check_box :extra_credit, data: {toggle: "toggle", on: "Extra credit", off: "Regular"} %> | 9 |
4 | <%= link_to "Back to Course: #{@course.name}", course_path(@course) %> 5 | <% unless @chapter.nil? %> 6 | | <%= link_to "Back to Chapter: #{@chapter.name}", @chapter %> 7 | <% end %> 8 | | <%= link_to "View Assignment", course_assignment_path(@course, @assignment) %> 9 |
10 | 11 |Edit Existing <%= @assignment.type.titlecase %> Assignment
12 | 13 |Assignment Download: 17 | <%= link_to aa.assignment_file, aa.assignment_file_path %>
18 | <% end %> 19 | 20 | <% end %> 21 | <% end %> 22 | -------------------------------------------------------------------------------- /script/assign-tarball: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require File.expand_path('../../config/boot', __FILE__) 4 | require APP_PATH 5 | Rails.application.require_environment! 6 | 7 | require 'sub_tarball' 8 | 9 | unless ARGV[0] =~ /^\d+$/ 10 | raise Exception.new("Usage: script/assign-tarball ID") 11 | end 12 | 13 | as_id = ARGV[0].to_i 14 | 15 | puts "Generating tarball of submissions for assignment #{as_id}..." 16 | 17 | assign = Assignment.find(as_id) 18 | puts " name = #{assign.name}" 19 | 20 | tb = SubTarball.new(as_id) 21 | tb.update! 22 | 23 | puts tb.path 24 | -------------------------------------------------------------------------------- /app/views/grades/_grades_file_picker.html.erb: -------------------------------------------------------------------------------- 1 |2 | 5 | <%= f.hidden_field :removefile, class: "remove-custom-file", value: '' %> 6 | Current file: nothing 7 | 11 |
12 | -------------------------------------------------------------------------------- /app/controllers/api/graders_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class GradersController < ApiController 3 | skip_before_action :doorkeeper_authorize! 4 | before_action :find_grader 5 | 6 | def orca_response 7 | return head :missing if @grader.nil? 8 | return head :bad_request unless @grader.orca_status 9 | 10 | @grader.handle_image_build_attempt( 11 | params[:logs].map { |l| l.permit!.to_h }, 12 | params[:was_successful] 13 | ) 14 | head :ok 15 | end 16 | 17 | private 18 | 19 | def find_grader 20 | @grader = Grader.find_by_id params[:id] 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /app/views/users/index.html.erb: -------------------------------------------------------------------------------- 1 | <% @page_title = "Manage Users" %> 2 | 3 || Name | 10 |Actions | 12 ||||
|---|---|---|---|---|
| <%= user.name %> | 17 |<%= user.email %> | 18 |<%= link_to 'Show', user_path(user) %> | 19 |<%= link_to 'Edit', edit_user_path(user) %> | 20 |<%= link_to 'Impersonate', impersonate_user_path(user), method: 'post' %> | 21 |
9 | <%= p.name %> 10 | <% if info.nil? %> 11 |
| <%= f.label "avail_score", "Points available:" %> | 7 |<%= f.spinner "avail_score", f.object.avail_score || 50, :min => 0, :delta => 5 %> | 8 |<%= f.check_box :extra_credit, data: {toggle: "toggle", on: "Extra credit", off: "Regular"} %> | 9 |
6 | <%= link_to "< Back to submission", course_assignment_submission_path(@course, @assignment, @submission) %> 7 |
8 |11 | This review of your submission is intended to 12 | be informative, professional and helpful. If 13 | you find something offensive about this review, please email your 14 | professor. 15 |
16 | 17 | <% end %> 18 | 19 | <%= render "submissions/codereview_details", cur_reg: current_user.registration_for(@course) %> 20 | -------------------------------------------------------------------------------- /config/ldap.yml: -------------------------------------------------------------------------------- 1 | development: 2 | host: ldap.ccs.neu.edu 3 | port: 636 4 | attribute: uid 5 | base: ou=people,dc=ccs,dc=neu,dc=edu 6 | ssl: true 7 | 8 | # TODO: The configurations below are untested. 9 | 10 | test: 11 | host: localhost 12 | port: 3389 13 | attribute: uid 14 | base: ou=people,dc=test,dc=com 15 | admin_user: cn=admin,dc=test,dc=com 16 | admin_password: admin_password 17 | ssl: simple_tls 18 | # <<: *AUTHORIZATIONS 19 | 20 | production: 21 | host: ldap.ccs.neu.edu 22 | port: 636 23 | attribute: uid 24 | base: ou=people,dc=ccs,dc=neu,dc=edu 25 | # admin_user: cn=admin,dc=test,dc=com 26 | # admin_password: admin_password 27 | ssl: true 28 | # <<: *AUTHORIZATIONS 29 | -------------------------------------------------------------------------------- /app/views/assignments/_due_date.html.erb: -------------------------------------------------------------------------------- 1 |Assignment should not be submitted after this time. Default: one week from today.
7 |Assignment will not be visible until this time. Default: today.
14 |<%= notice %>
2 | 3 || Name | 9 |Submission | 10 |11 | | ||
|---|---|---|---|---|
| <%= sandbox.name %> | 18 |<%= sandbox.submission_id %> | 19 |<%= link_to 'Show', sandbox %> | 20 |<%= link_to 'Edit', edit_sandbox_path(sandbox) %> | 21 |<%= link_to 'Destroy', sandbox, method: :delete, data: { confirm: 'Are you sure?' } %> | 22 |
Maybe you tried to change something you didn't have access to.
24 || <%= f.label "avail_score", "Points available:" %> | 7 |<%= f.spinner "avail_score", f.object.avail_score || 50, :min => 0, :delta => 5 %> | 8 |<%= f.check_box :extra_credit, data: {toggle: "toggle", on: "Extra credit", off: "Regular"} %> | 9 |
| <%= f.label "line_length", "Maximum line length:" %> | 12 |<%= f.spinner "line_length", f.object.line_length || f.object.default_line_length, :min => 0 %> | 13 |14 | |
Toggle section availability:
3 | <% @toggles.sort_by(&:first).each do |section_type, toggles| %> 4 |By <%= section_type %>
6 | <% toggles.sort_by{|s, _| s.crn}.each do |section, toggle| %> 7 |8 | 9 | <%= check_box_tag "allow-#{toggle.id}", nil, 10 | toggle.submissions_allowed, 11 | data: {toggle: "toggle", on: "Enabled", off: "Disabled", stid: toggle.id}, 12 | class: "submission-enabled-toggle" %> 13 | 14 | <%= section.to_s(show_type: false) %> 15 |
16 | <% end %> 17 |6 | <%= link_to "Show student access", 7 | audit_access_course_assignment_path(@course, @gradesheet.assignment), class: "btn btn-default" %> 8 | <%= link_to "Manage individual extensions", 9 | edit_course_assignment_extensions_path(@course, @gradesheet.assignment), class: "btn btn-default" %> 10 | <%= link_to "Edit Assignment", 11 | edit_course_assignment_path(@course, @gradesheet.assignment), class: "btn btn-default" %> 12 |
13 | <% end %> 14 | 15 | <%= render 'assignment_files_info', gradesheet: @gradesheet %> 16 | <%= render 'admin_subs', type: { noun: "submission", verb: "submit", gerund: "submitting" }, locals: { cur_reg: cur_reg } %> 17 | -------------------------------------------------------------------------------- /script/fix-quoted-names: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # Fixes names that imported poorly. 4 | # Only looks at students in a specific course, specified below. 5 | # Changes the format \"Last,First Mid\" to First Last 6 | 7 | APP_PATH = File.expand_path('../../config/application', __FILE__) 8 | require File.expand_path('../../config/boot', __FILE__) 9 | require APP_PATH 10 | Rails.application.require_environment! 11 | 12 | COURSE_ID = 8 13 | 14 | students = Course.find_by_id(COURSE_ID).students 15 | 16 | students.each do |s| 17 | puts "\n**** " + s.name 18 | if s.name =~ /\".*,.*\"/ 19 | name = s.name[1..-2] 20 | (last, first) = name.split(",") 21 | 22 | newname = first + " " + last 23 | puts newname 24 | s.name = newname 25 | 26 | begin 27 | s.save! 28 | puts "saved" 29 | rescue 30 | puts "NOT SAVED" 31 | end 32 | end 33 | end 34 | 35 | exit(0) 36 | 37 | -------------------------------------------------------------------------------- /app/controllers/oauth/authorizations_controller.rb: -------------------------------------------------------------------------------- 1 | module Oauth 2 | class AuthorizationsController < Doorkeeper::AuthorizationsController 3 | # Note: Does NOT allow impersonating users so that logging into Hourglass (or other OAuth apps) is disjoint from 4 | # Bottlenose's impersonation status 5 | 6 | # NOTE: In Rails 7, redirect_to will throw an error if we don't allow_other_host. 7 | # Unfortunately, Doorkeeper 5.4.0 doesn't supply that option right now, but upgrading 8 | # to new versions seems to be backwards incompatible for some users(?) 9 | # For now, monkey-patch this call of redirect_to to add in the necessary flag. 10 | # Once we successfully upgrade Doorkeeper, we can remove this patch. 11 | def redirect_to(options = {}, response_options = {}) 12 | response_options[:allow_other_host] = true; 13 | super(options, response_options) 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /script/dump_comments.rb: -------------------------------------------------------------------------------- 1 | APP_PATH = File.expand_path('../../config/application', __FILE__) 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require APP_PATH 4 | Rails.application.require_environment! 5 | 6 | require 'active_record' 7 | 8 | InlineComment 9 | .joins(:submission).where("submissions.assignment_id": ARGV[0].to_i) 10 | .joins(:grade).where("grades.grader_id": ARGV[1].to_i) 11 | .group_by(&:submission) 12 | .each do |sub, cs| 13 | if ARGV[2] 14 | match = ARGV[2].downcase 15 | cs = cs.keep_if{|c| c.comment.downcase.include?(match)} 16 | end 17 | next if cs.empty? 18 | print "#{sub.team&.to_s || sub.user.name} -- Sub ##{sub.id}:\n" 19 | cs.each do |c| 20 | print "#{c.filename.gsub(Regexp.new('.*extracted/?'), '')}, #{c.line}: #{c.label}, #{c.severity} [#{c.weight}]: #{c.comment}\n" 21 | end 22 | print "==================================================\n\n" 23 | end 24 | -------------------------------------------------------------------------------- /db/migrate/20171121152503_make_crns_nonunique.rb: -------------------------------------------------------------------------------- 1 | class MakeCrnsNonunique < ActiveRecord::Migration[5.1] 2 | def up 3 | remove_index :sections, [:crn] 4 | add_index :sections, [:crn, :course_id], unique: true 5 | # this migration is safe only because all CRNS > 10000, and all ids < 100 (so far) 6 | Section.all.each do |section| 7 | RegistrationSection.where(section_id: section.crn).update_all(section_id: section.id) 8 | RegRequestSection.where(section_id: section.crn).update_all(section_id: section.id) 9 | end 10 | end 11 | def down 12 | remove_index :sections, [:crn, :course_id] 13 | add_index :sections, [:crn], unique: true 14 | Section.all.each do |section| 15 | RegistrationSection.where(section_id: section.id).update_all(section_id: section.crn) 16 | RegRequestSection.where(section_id: section.id).update_all(section_id: section.crn) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /test/controllers/settings_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SettingsControllerTest < ActionController::TestCase 4 | setup do 5 | @admin = create(:admin_user) 6 | @prof = create(:user) 7 | end 8 | 9 | test "non-admin should not get settings" do 10 | sign_in @prof 11 | get :edit 12 | assert_response :redirect 13 | end 14 | 15 | test "index should show defaults" do 16 | Settings.clear_test! 17 | 18 | sign_in @admin 19 | get :edit 20 | assert_response :success 21 | assert_match "noreply@example.com", @response.body 22 | end 23 | 24 | test "should save_settings" do 25 | sign_in @admin 26 | post :update, params: { site_email: "somebody@example.com", backup_login: "" } 27 | 28 | assert_response :redirect 29 | assert_match "Settings Saved", flash[:notice] 30 | assert_equal "somebody@example.com", Settings['site_email'] 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/javascript/packs/application.js: -------------------------------------------------------------------------------- 1 | /* eslint no-console:0 */ 2 | // This file is automatically compiled by Webpack, along with any other files 3 | // present in this directory. You're encouraged to place your actual application logic in 4 | // a relevant structure within app/javascript and only use these pack files to reference 5 | // that code so it'll be compiled. 6 | // 7 | // To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate 8 | // layout file, like app/views/layouts/application.html.erb 9 | 10 | 11 | // Uncomment to copy all static images under ../images to the output folder and reference 12 | // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) 13 | // or the `imagePath` JavaScript helper below. 14 | // 15 | // const images = require.context('../images', true) 16 | // const imagePath = (name) => images(name, true) 17 | 18 | console.log('Hello World from Webpacker') 19 | -------------------------------------------------------------------------------- /app/views/grades/_exam_export_schema.html.erb: -------------------------------------------------------------------------------- 1 |A CSV file with the following columns:
4 |
5 | NUID | Last name | First name | Status | Action | <%= @assignment.flattened_questions.map{|q| q["name"]}.join(" | ") %> | Curved
6 |
7 | Missing, or Dropped.| <%= f.label "avail_score", "Points available:" %> | 7 |<%= f.spinner "avail_score", f.object.avail_score || 50, :min => 0, :delta => 5 %> | 8 |<%= f.check_box :extra_credit, data: {toggle: "toggle", on: "Extra credit", off: "Regular"} %> | 9 |
| <%= f.label "line_length", "Maximum line length:" %> | 12 |<%= f.spinner "line_length", f.object.line_length || f.object.default_line_length, :min => 0 %> | 13 |14 | |
15 | If you think you've reached this page in error, please report the 16 | URL of the page you were on, the time you visited it, and what you 17 | were trying to do, and we'll look into it. 18 |
19 |20 | You can resume your work by using the Back button, or by selecting 21 | an option from the menubar above. 22 |
23 |<%= log["error"] %>27 |
<%= log["output"] %>31 | <% end %> 32 |
2 | File: 12 | Line number: value="<%= part_ans['line'] %>"<% end %>> 16 |
17 | -------------------------------------------------------------------------------- /app/views/assignments/_assignment_file_picker.html.erb: -------------------------------------------------------------------------------- 1 | <% disabled = false if local_assigns[:disabled].nil? %> 2 |3 | 7 | <%= f.hidden_field :removefile, class: "remove-custom-file", value: '' %> 8 | Current file: 9 | <%= asgn.assignment_file.empty? ? "nothing" : 10 | link_to(asgn.assignment_file, asgn.assignment_upload.path) %> 11 | 17 |
18 | -------------------------------------------------------------------------------- /db/migrate/20220426161610_change_primary_key_to_bigint.rb: -------------------------------------------------------------------------------- 1 | class ChangePrimaryKeyToBigint < ActiveRecord::Migration[5.2] 2 | def change 3 | change_column :assignments, :id, :bigint 4 | change_column :courses, :id, :bigint 5 | change_column :grader_allocations, :id, :bigint 6 | change_column :graders, :id, :bigint 7 | change_column :grades, :id, :bigint 8 | change_column :inline_comments, :id, :bigint 9 | change_column :lateness_configs, :id, :bigint 10 | change_column :reg_requests, :id, :bigint 11 | change_column :registrations, :id, :bigint 12 | change_column :sandboxes, :id, :bigint 13 | change_column :sections, :id, :bigint 14 | change_column :submissions, :id, :bigint 15 | change_column :team_users, :id, :bigint 16 | change_column :teams, :id, :bigint 17 | change_column :teamsets, :id, :bigint 18 | change_column :terms, :id, :bigint 19 | change_column :uploads, :id, :bigint 20 | change_column :used_subs, :id, :bigint 21 | change_column :user_submissions, :id, :bigint 22 | change_column :users, :id, :bigint 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /app/views/assignments/_form.html.erb: -------------------------------------------------------------------------------- 1 |28 | <% end %> 29 | -------------------------------------------------------------------------------- /app/views/teamsets/_diff_teamsets.html.erb: -------------------------------------------------------------------------------- 1 |
| Team 1 | 22 |Student | 23 |Team 2 | 24 |
|---|
| Queue length | 8 |<%= @queue_stats.count %> | 9 |
| Average wait | 12 |<%= @avg_wait_msg %> | 13 |
| Submissions | 16 |
17 | <% if current_user&.site_admin? && (@queue_stats.count >= 50 || @avg_wait > 30 * 60) %>
18 | 19 | <%= link_to "Clear all pending jobs", clear_queue_path, method: "patch", 20 | class: 'btn btn-large btn-danger' %> 21 | 22 | <% end %> 23 | 24 | <% @queue_stats.each do |_, job| %> 25 |Grading <%= job[:grader_type] %> for <%= link_to "#{job[:user_name]}", 26 | course_assignment_submission_path(job[:course], job[:assn], job[:sub]) %> 27 | <% priority = job.dig(:opts, :prio) 28 | if priority %> 29 | with priority <%= priority %> 30 | <% end %> 31 | (<%= job[:wait_s] %>) 32 | 33 | <% end %> 34 | |
35 |
| Name | 5 |6 | | |||
|---|---|---|---|---|
| <%= link_to course.name, course_path(course) %> | 13 | <% if info %> 14 | <% if info[4] %> 15 |Withdrawn | 16 | <% else %> 17 |<%= info[3].titleize %> | 18 | <% end %> 19 | <% elsif current_user.reg_requests.map { |r| r.course }.include?(course) %> 20 |Registration Pending... | 21 | <% else %> 22 |<%= link_to "Request Registration", new_course_reg_request_path(course), class: "btn btn-success btn-xs pull-right" %> | 23 | <% end %> 24 |
6 | <% if cur_reg_staff %> 7 | Weight: <%= t[:info]["weight"] || 1 %> 8 | <% end %> 9 | Passed: <%= t[:comment] %> 10 |
11 |15 | <% if cur_reg_staff %> 16 | Weight: <%= t[:info]["weight"] %> 17 | <% end %> 18 | Failed: <%= t[:info]["header"] %> 19 |
20 | <% unless t[:info]["message"].to_s.empty? %> 21 |Message: <%= t[:info]["message"] %>
Stack:
28 |<%= t[:info]["stack"].join("\n") %>
29 | <% end %>
30 | A CSV file with the following columns:
4 |
5 | NUID | Last name | First name | Status | Action | <%= @assignment.flattened_questions.map{|q| q["name"]}.join(" | ") %> | Curved
6 |
7 | Ignore, Update or Delete:
14 | Ignore will not update the scores for this student.Update will update the scores for this student.Delete will delete the grades for this student.7 | Team starts on 8 | <%= @team.start_date.strftime("%b %d, %Y") %> 9 | <% if @team.end_date %> 10 | and ends the night before 11 | <%= @team.end_date.strftime("%b %d, %Y") %>. 12 | <% else %> 13 | and doesn't end. 14 | <% end %> 15 |
16 | 17 |<%= @team.active? ? "Active" : "Inactive" %>
19 | 20 |None
35 | <% else %> 36 |#{object.name} already exists"
12 | end}
13 |
14 | def self.all_sorted
15 | terms = Term.all
16 | terms.sort_by {|tt| tt.canonical_name }.reverse
17 | end
18 |
19 | def name
20 | "#{semester.humanize} #{year}"
21 | end
22 |
23 | def canonical_name
24 | season = "#{Term.semesters[semester]}_#{semester}"
25 |
26 | arch = archived? ? "a" : "z"
27 |
28 | "#{arch} #{effective_year} #{season} #{name}"
29 | end
30 |
31 | def query_code
32 | # For use with querying university rosters
33 | "#{effective_year}#{Term.semesters[semester]}"
34 | end
35 |
36 | private
37 | def effective_year
38 | # Fall is part of numerically-next *academic* year
39 | year + ((Term.semesters[semester] < Term.semesters[:spring]) ? 1 : 0)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/app/controllers/teams_controller.rb:
--------------------------------------------------------------------------------
1 | class TeamsController < ApplicationController
2 | layout 'course'
3 |
4 | before_action :find_course
5 | before_action :find_teamset
6 | before_action :find_team
7 | before_action :require_registered_user
8 | before_action :require_admin_or_staff, only: [:dissolve]
9 |
10 | # GET /courses/:course_id/teams/:id
11 | def show
12 | if !(current_user_site_admin? || current_user_staff_for?(@course)) && @team.users.exclude?(current_user)
13 | redirect_to(root_path, alert: "You are not a member of that team.")
14 | end
15 | end
16 |
17 | def dissolve
18 | @team.dissolve(DateTime.current)
19 | redirect_back fallback_location: course_teamset_path(@course, @teamset),
20 | notice: "Team was successfully dissolved"
21 | end
22 |
23 | private
24 |
25 | def find_teamset
26 | @teamset = Teamset.find_by(id: params[:teamset_id])
27 | if @teamset.nil?
28 | redirect_back fallback_location: course_teamsets_path(@course),
29 | alert: "No such teamset"
30 | return
31 | end
32 | end
33 | def find_team
34 | @team = Team.find_by(id: params[:id])
35 | if @team.nil? || @team.teamset_id != @teamset.id
36 | redirect_back fallback_location: course_teams_path(@course),
37 | alert: "No such team for this teamset"
38 | return
39 | end
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/script/cleanup-db:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | #
3 | # This script cleans up possible database weirdnesses.
4 | # It should be safe to run at any time.
5 | #
6 |
7 | APP_PATH = File.expand_path('../../config/application', __FILE__)
8 | require File.expand_path('../../config/boot', __FILE__)
9 | require APP_PATH
10 | Rails.application.require_environment!
11 |
12 |
13 | # Make sure all email addresses in the users table are lowercase.
14 |
15 | User.all.each do |user|
16 | if user.email =~ /[A-Z]/ || user.email =~ /\W$/
17 | puts "Fixing user email: #{user.email}"
18 |
19 | unless user.save
20 | user.email = "invalid-user-#{user.id}@example.com"
21 | user.save!
22 | end
23 | end
24 | end
25 |
26 | # Remove users with invalid emails who have no submissions.
27 |
28 | User.all.each do |user|
29 | if user.email =~ /^invalid-user.*@example.com$/
30 | sc = user.submissions.count
31 | if sc == 0
32 | user.registrations.each do |reg|
33 | reg.destroy
34 | end
35 |
36 | unless user.destroy
37 | puts "#{user.id} #{user.name}"
38 | puts user.errors.full_messages
39 | end
40 | end
41 | end
42 | end
43 |
44 | # Remove registration requests from invalid users.
45 |
46 | RegRequest.all.each do |rr|
47 | if rr.user.nil?
48 | rr.destroy
49 | end
50 | end
51 |
--------------------------------------------------------------------------------
/app/views/terms/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_for(@term) do |f| %>
2 | <% if @term.errors.any? %>
3 | | <%= f.select :semester, Term.semesters.map{|name, _| [name.humanize, name]}, 21 | selected: @term.semester %> | 22 |<%= f.spinner :year, @term.year, min: Date.today.year - 10, max: Date.today.year + 10 %> | 23 |