From 5be5848c86e5df725b9ed3ea3452acecd9946eca Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Thu, 15 Jun 2023 20:19:46 +0200 Subject: [PATCH] Remove nbextensions and related code --- .gitignore | 3 - nbgrader/__init__.py | 59 - .../source/contributor_guide/releasing.rst | 12 +- .../assignment_list/assignment_list.css | 103 -- .../assignment_list/assignment_list.js | 677 -------- nbgrader/nbextensions/assignment_list/main.js | 165 -- .../nbextensions/course_list/course_list.css | 67 - .../nbextensions/course_list/course_list.js | 145 -- nbgrader/nbextensions/course_list/main.js | 101 -- .../create_assignment/create_assignment.css | 66 - .../nbextensions/create_assignment/main.js | 626 ------- nbgrader/nbextensions/formgrader/main.js | 21 - .../nbextensions/validate_assignment/main.js | 142 -- .../tests/apps/test_nbgrader_extension.py | 86 - nbgrader/tests/nbextensions/__init__.py | 0 nbgrader/tests/nbextensions/conftest.py | 215 --- nbgrader/tests/nbextensions/files/blank.ipynb | 30 - nbgrader/tests/nbextensions/files/data.txt | 4 - .../tests/nbextensions/files/old-schema.ipynb | 38 - .../files/open_relative_file.ipynb | 37 - .../submitted-answer-cell-type-changed.ipynb | 155 -- .../files/submitted-changed.ipynb | 157 -- .../files/submitted-grade-cell-changed.ipynb | 157 -- .../submitted-grade-cell-type-changed.ipynb | 155 -- .../files/submitted-locked-cell-changed.ipynb | 158 -- .../files/submitted-unchanged.ipynb | 157 -- nbgrader/tests/nbextensions/files/task.ipynb | 20 - .../tests/nbextensions/formgrade_utils.py | 289 ---- .../nbextensions/test_assignment_list.py | 504 ------ .../tests/nbextensions/test_course_list.py | 149 -- .../nbextensions/test_create_assignment.py | 918 ----------- .../tests/nbextensions/test_formgrader.py | 1450 ----------------- .../nbextensions/test_validate_assignment.py | 239 --- pyproject.toml | 10 - tasks.py | 4 +- 35 files changed, 8 insertions(+), 7111 deletions(-) delete mode 100644 nbgrader/nbextensions/assignment_list/assignment_list.css delete mode 100644 nbgrader/nbextensions/assignment_list/assignment_list.js delete mode 100644 nbgrader/nbextensions/assignment_list/main.js delete mode 100644 nbgrader/nbextensions/course_list/course_list.css delete mode 100644 nbgrader/nbextensions/course_list/course_list.js delete mode 100644 nbgrader/nbextensions/course_list/main.js delete mode 100644 nbgrader/nbextensions/create_assignment/create_assignment.css delete mode 100644 nbgrader/nbextensions/create_assignment/main.js delete mode 100644 nbgrader/nbextensions/formgrader/main.js delete mode 100644 nbgrader/nbextensions/validate_assignment/main.js delete mode 100644 nbgrader/tests/apps/test_nbgrader_extension.py delete mode 100644 nbgrader/tests/nbextensions/__init__.py delete mode 100644 nbgrader/tests/nbextensions/conftest.py delete mode 100644 nbgrader/tests/nbextensions/files/blank.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/data.txt delete mode 100644 nbgrader/tests/nbextensions/files/old-schema.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/open_relative_file.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/submitted-answer-cell-type-changed.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/submitted-changed.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/submitted-grade-cell-changed.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/submitted-grade-cell-type-changed.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/submitted-locked-cell-changed.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/submitted-unchanged.ipynb delete mode 100644 nbgrader/tests/nbextensions/files/task.ipynb delete mode 100644 nbgrader/tests/nbextensions/formgrade_utils.py delete mode 100644 nbgrader/tests/nbextensions/test_assignment_list.py delete mode 100644 nbgrader/tests/nbextensions/test_course_list.py delete mode 100644 nbgrader/tests/nbextensions/test_create_assignment.py delete mode 100644 nbgrader/tests/nbextensions/test_formgrader.py delete mode 100644 nbgrader/tests/nbextensions/test_validate_assignment.py diff --git a/.gitignore b/.gitignore index b643661f7..3cecd390f 100644 --- a/.gitignore +++ b/.gitignore @@ -64,9 +64,6 @@ target/ # Coverage files .coverage.* -.selenium.screenshot.png -nbgrader/tests/formgrader/selenium.screenshot.png -nbgrader/tests/nbextensions/selenium.screenshot.png # Autogenerated docs nbgrader/docs/build diff --git a/nbgrader/__init__.py b/nbgrader/__init__.py index 73e99144f..152087966 100644 --- a/nbgrader/__init__.py +++ b/nbgrader/__init__.py @@ -33,65 +33,6 @@ def _jupyter_server_extension_points(): "module": "nbgrader" }] - -# Classic notebook extensions -def _jupyter_nbextension_paths(): - paths = [ - dict( - section="notebook", - src=os.path.join('nbextensions', 'create_assignment'), - dest="create_assignment", - require="create_assignment/main" - ), - dict( - section="tree", - src=os.path.join('nbextensions', 'formgrader'), - dest="formgrader", - require="formgrader/main" - ), - dict( - section="notebook", - src=os.path.join('nbextensions', 'validate_assignment'), - dest="validate_assignment", - require="validate_assignment/main" - ), - ] - - if sys.platform != 'win32': - paths.append( - dict( - section="tree", - src=os.path.join('nbextensions', 'assignment_list'), - dest="assignment_list", - require="assignment_list/main" - ) - ) - paths.append( - dict( - section="tree", - src=os.path.join('nbextensions', 'course_list'), - dest="course_list", - require="course_list/main" - ) - ) - - return paths - - -# Classic notebook server extensions -def _jupyter_server_extension_paths(): - paths = [ - dict(module="nbgrader.server_extensions.formgrader"), - dict(module="nbgrader.server_extensions.validate_assignment") - ] - - if sys.platform != 'win32': - paths.append(dict(module="nbgrader.server_extensions.assignment_list")) - paths.append(dict(module="nbgrader.server_extensions.course_list")) - - return paths - - def _load_jupyter_server_extension(app): load_assignments(app) load_courses(app) diff --git a/nbgrader/docs/source/contributor_guide/releasing.rst b/nbgrader/docs/source/contributor_guide/releasing.rst index fec638699..c3a94f81a 100644 --- a/nbgrader/docs/source/contributor_guide/releasing.rst +++ b/nbgrader/docs/source/contributor_guide/releasing.rst @@ -79,9 +79,9 @@ The version number should have been changed in the following files : - ``pyproject.toml`` - ``package.json`` - ``nbgrader/_version.py`` -- ``nbgrader/nbextensions/assignment_list/main.js`` -- ``nbgrader/nbextensions/course_list/main.js`` -- ``nbgrader/nbextensions/validate_assignment/main.js`` +- ``src/assignment_list/index.ts`` +- ``src/course_list/index.ts`` +- ``src/validate_assignment/index.ts`` Rebuild the documentation ------------------------- @@ -173,6 +173,6 @@ As a reminder, the files concerned are : - ``pyproject.toml`` - ``package.json`` - ``nbgrader/_version.py`` -- ``nbgrader/nbextensions/assignment_list/main.js`` -- ``nbgrader/nbextensions/course_list/main.js`` -- ``nbgrader/nbextensions/validate_assignment/main.js`` +- ``src/assignment_list/index.ts`` +- ``src/course_list/index.ts`` +- ``src/validate_assignment/index.ts`` diff --git a/nbgrader/nbextensions/assignment_list/assignment_list.css b/nbgrader/nbextensions/assignment_list/assignment_list.css deleted file mode 100644 index e92ab3552..000000000 --- a/nbgrader/nbextensions/assignment_list/assignment_list.css +++ /dev/null @@ -1,103 +0,0 @@ -#assignments .panel-group .panel { - margin-top: 3px; - margin-bottom: 1em; -} - -#assignments .panel-group .panel .panel-heading { - background-color: #eee; - padding-top: 4px; - padding-bottom: 4px; - padding-left: 7px; - padding-right: 7px; - line-height: 22px; -} - -#assignments .panel-group .panel .panel-heading a:focus, a:hover { - text-decoration: none; -} - -#assignments .panel-group .panel .panel-body { - padding: 0; -} - -#assignments .panel-group .panel .panel-body .list_container { - margin-top: 0px; - margin-bottom: 0px; - border: 0px; - border-radius: 0px; -} - -#assignments .panel-group .panel .panel-body .list_container .list_item { - border-bottom: 1px solid #ddd; -} - -#assignments .panel-group .panel .panel-body .list_container .list_item:last-child { - border-bottom: 0px; -} - -#assignments .assignment-notebooks .list_item { - background-color: inherit !important; -} - -#assignments .assignment-notebooks .list_item:hover { - background-color: #ddd !important; -} - -#assignments .assignment-notebooks .list_item:first-child:hover { - background-color: inherit !important; -} - -#assignments .list_item { - padding-top: 4px; - padding-bottom: 4px; - padding-left: 7px; - padding-right: 7px; - line-height: 22px; -} - -#assignments .list_item > div { - padding-top: 0; - padding-bottom: 0; - padding-left: 0; - padding-right: 0; -} - -#assignments .item_status { - text-align: right; -} - -#assignments .item_status .btn { - min-width: 13ex; -} - -#assignments .list_placeholder { - display: none; -} - -#assignments .list_error, #assignments .version_error { - display: none; -} - -#submission-message p, -#validation-message p { - margin-bottom: 1em; - padding-top: 1em; -} - -#submission-message pre, -#validation-message pre { - margin-left: 1em; - margin-right: 1em; -} - -#submission-message pre { - white-space: pre; -} - -#assignments .list_placeholder, #assignments .list_loading, #assignments .list_error { - font-weight: bold; - padding-top: 4px; - padding-bottom: 4px; - padding-left: 7px; - padding-right: 7px; -} diff --git a/nbgrader/nbextensions/assignment_list/assignment_list.js b/nbgrader/nbextensions/assignment_list/assignment_list.js deleted file mode 100644 index b35cbb39c..000000000 --- a/nbgrader/nbextensions/assignment_list/assignment_list.js +++ /dev/null @@ -1,677 +0,0 @@ -// Copyright (c) Jupyter Development Team. -// Distributed under the terms of the Modified BSD License. - -define([ - 'base/js/namespace', - 'jquery', - 'base/js/utils', - 'base/js/dialog', -], function(Jupyter, $, utils, dialog) { - "use strict"; - - var ajax = utils.ajax || $.ajax; - // Notebook v4.3.1 enabled xsrf so use notebooks ajax that includes the - // xsrf token in the header data - - var CourseList = function (course_list_selector, default_course_selector, dropdown_selector, refresh_selector, assignment_list, options) { - this.course_list_selector = course_list_selector; - this.default_course_selector = default_course_selector; - this.dropdown_selector = course_list_dropdown; - this.refresh_selector = refresh_selector; - - this.course_list_element = $(course_list_selector); - this.default_course_element = $(default_course_selector); - this.dropdown_element = $(dropdown_selector); - this.refresh_element = $(refresh_selector); - - this.assignment_list = assignment_list; - this.current_course = undefined; - this.bind_events() - - options = options || {}; - this.options = options; - this.base_url = options.base_url || utils.get_body_data("baseUrl"); - - this.data = undefined; - }; - - CourseList.prototype.bind_events = function () { - var that = this; - this.refresh_element.click(function () { - that.load_list(); - }); - }; - - - CourseList.prototype.enable_list = function () { - this.dropdown_element.removeAttr("disabled"); - }; - - - CourseList.prototype.disable_list = function () { - this.dropdown_element.attr("disabled", "disabled"); - }; - - - CourseList.prototype.clear_list = function () { - // remove list items - this.course_list_element.children('li').remove(); - }; - - - CourseList.prototype.load_list = function () { - this.disable_list() - this.clear_list(); - this.assignment_list.clear_list(true); - - var settings = { - processData : false, - cache : false, - type : "GET", - dataType : "json", - success : $.proxy(this.handle_load_list, this), - error : utils.log_ajax_error, - }; - var url = utils.url_path_join(this.base_url, 'courses'); - ajax(url, settings); - }; - - CourseList.prototype.handle_load_list = function (data, status, xhr) { - if (data.success) { - this.load_list_success(data.value); - } else { - this.default_course_element.text("Error fetching courses!"); - this.enable_list(); - this.assignment_list.show_error(data.value); - } - }; - - CourseList.prototype.load_list_success = function (data) { - this.data = data; - this.disable_list() - this.clear_list(); - - if (this.data.length === 0) { - this.default_course_element.text("No courses found."); - this.assignment_list.clear_list(); - this.enable_list() - return; - } - - if ($.inArray(this.current_course, this.data) === -1) { - this.current_course = undefined; - } - - if (this.current_course === undefined) { - this.change_course(this.data[0]); - } else { - // we still want to "change" the course here to update the - // assignment list - this.change_course(this.current_course); - } - }; - - - CourseList.prototype.change_course = function (course) { - this.disable_list(); - if (this.current_course !== undefined) { - this.default_course_element.text(course); - } - this.current_course = course; - this.default_course_element.text(this.current_course); - var success = $.proxy(this.load_assignment_list_success, this); - this.assignment_list.load_list(course, success); - }; - - - CourseList.prototype.load_assignment_list_success = function () { - if (this.data) { - var that = this; - var set_course = function (course) { - return function () { that.change_course(course); }; - } - - for (var i=0; i').append($('').attr("href", "#").text(this.data[i])); - element.click(set_course(this.data[i])); - this.course_list_element.append(element); - } - - this.data = undefined; - } - - this.enable_list(); - }; - - var AssignmentList = function (released_selector, fetched_selector, submitted_selector, options) { - this.released_selector = released_selector; - this.fetched_selector = fetched_selector; - this.submitted_selector = submitted_selector; - - this.released_element = $(released_selector); - this.fetched_element = $(fetched_selector); - this.submitted_element = $(submitted_selector); - - options = options || {}; - this.options = options; - this.base_url = options.base_url || utils.get_body_data("baseUrl"); - - this.callback = undefined; - }; - - - AssignmentList.prototype.load_list = function (course, callback) { - this.callback = callback; - this.clear_list(true); - var settings = { - cache : false, - type : "GET", - dataType : "json", - data : { - course_id: course - }, - success : $.proxy(this.handle_load_list, this), - error : utils.log_ajax_error, - }; - var url = utils.url_path_join(this.base_url, 'assignments'); - ajax(url, settings); - }; - - AssignmentList.prototype.clear_list = function (loading) { - var elems = [this.released_element, this.fetched_element, this.submitted_element]; - var i; - - // remove list items - for (i = 0; i < elems.length; i++) { - elems[i].children('.list_item').remove(); - if (loading) { - // show loading - elems[i].children('.list_loading').show(); - // hide placeholders and errors - elems[i].children('.list_placeholder').hide(); - elems[i].children('.list_error').hide(); - - } else { - // show placeholders - elems[i].children('.list_placeholder').show(); - // hide loading and errors - elems[i].children('.list_loading').hide(); - elems[i].children('.list_error').hide(); - } - } - }; - - AssignmentList.prototype.show_error = function (error) { - var elems = [this.released_element, this.fetched_element, this.submitted_element]; - var i; - - // remove list items - for (i = 0; i < elems.length; i++) { - elems[i].children('.list_item').remove(); - // show errors - elems[i].children('.list_error').show(); - elems[i].children('.list_error').text(error); - // hide loading and placeholding - elems[i].children('.list_loading').hide(); - elems[i].children('.list_placeholder').hide(); - } - }; - - AssignmentList.prototype.handle_load_list = function (data, status, xhr) { - if (data.success) { - this.load_list_success(data.value); - } else { - this.show_error(data.value); - } - }; - - AssignmentList.prototype.load_list_success = function (data) { - this.clear_list(); - - var len = data.length; - for (var i=0; i'); - var item = new Assignment(element, data[i], this.fetched_selector, - $.proxy(this.handle_load_list, this), - this.options); - if (data[i]['status'] === 'released') { - this.released_element.append(element); - this.released_element.children('.list_placeholder').hide(); - } else if (data[i]['status'] === 'fetched') { - this.fetched_element.append(element); - this.fetched_element.children('.list_placeholder').hide(); - } else if (data[i]['status'] === 'submitted') { - this.submitted_element.append(element); - this.submitted_element.children('.list_placeholder').hide(); - } - } - - // Add collapse arrows. - $('.assignment-notebooks-link').each(function(index, el) { - var $link = $(el); - var $icon = $('') - .addClass('fa fa-caret-down') - .css('transform', 'rotate(-90deg)') - .css('borderSpacing', '90') - .css('margin-left', '3px'); - $link.append($icon); - $link.down = false; - $link.click(function () { - if ($link.down) { - $link.down = false; - // jQeury doesn't know how to animate rotations. Abuse - // jQueries animate function by using an unused css attribute - // to do the animation (borderSpacing). - $icon.animate({ borderSpacing: 90 }, { - step: function(now,fx) { - $icon.css('transform','rotate(-' + now + 'deg)'); - } - }, 250); - } else { - $link.down = true; - // See comment above. - $icon.animate({ borderSpacing: 0 }, { - step: function(now,fx) { - $icon.css('transform','rotate(-' + now + 'deg)'); - } - }, 250); - } - }); - }); - - if (this.callback) { - this.callback(); - this.callback = undefined; - } - }; - - - var Assignment = function (element, data, parent, on_refresh, options) { - this.element = $(element); - this.data = data; - this.parent = parent; - this.on_refresh = on_refresh; - this.options = options; - this.base_url = options.base_url || utils.get_body_data("baseUrl"); - this.style(); - this.make_row(); - }; - - Assignment.prototype.style = function () { - this.element.addClass('list_item').addClass("row"); - }; - - Assignment.prototype.escape_id = function () { - // construct the id from the course id and the assignment id, and also - // prepend the id with "nbgrader" (this also ensures that the first - // character is always a letter, as required by HTML 4) - var id = "nbgrader-" + this.data.course_id + "-" + this.data.assignment_id; - - // replace spaces with '_' - id = id.replace(/ /g, "_"); - - // remove any characters that are invalid in HTML div ids - id = id.replace(/[^A-Za-z0-9\-_]/g, ""); - - return id; - }; - - Assignment.prototype.make_row = function () { - var row = $('
').addClass('col-md-12'); - var link = this.make_link(); - row.append(link); - row.append($('').addClass('item_course col-sm-2').text(this.data.course_id)); - - var id, children, element, child; - if (this.data.status === 'submitted') { - id = this.escape_id() + "-submissions"; - children = $('
') - .attr("id", id) - .addClass("panel-collapse list_container assignment-notebooks") - .attr("role", "tabpanel"); - - children.append($('
').addClass('list_item row')); - for (var i=0; i'); - child = new Submission(element, this.data.submissions[i], this.options); - children.append(element); - } - - } else if (this.data.status === 'fetched') { - id = this.escape_id(); - children = $('
') - .attr("id", id) - .addClass("panel-collapse collapse list_container assignment-notebooks") - .attr("role", "tabpanel"); - - children.append($('
').addClass('list_item row')); - for (var i=0; i'); - this.data.notebooks[i].course_id = this.data.course_id; - this.data.notebooks[i].assignment_id = this.data.assignment_id; - child = new Notebook(element, this.data.notebooks[i], this.options); - children.append(element); - } - } - - row.append(this.make_button()); - this.element.empty().append(row).append(children); - }; - - Assignment.prototype.make_link = function () { - var container = $('').addClass('item_name col-sm-6'); - var link; - - if (this.data.status === 'fetched') { - var id = this.escape_id(); - link = $('') - .addClass("collapsed assignment-notebooks-link") - .attr("role", "button") - .attr("data-toggle", "collapse") - .attr("data-parent", this.parent) - .attr("href", "#" + id) - .attr("aria-expanded", "false") - .attr("aria-controls", id) - } else { - link = $(''); - } - - link.text(this.data.assignment_id); - container.append(link); - return container; - }; - - Assignment.prototype.submit_error = function (data) { - var body = $('
').attr('id', 'submission-message'); - - body.append( - $('
').append( - $('

').text('Assignment not submitted:') - ) - ); - body.append( - $('

').text(data.value)
-        );
-
-        dialog.modal({
-            title: "Invalid Submission",
-            body: body,
-            buttons: { OK: { class : "btn-primary" } }
-        });
-    };
-
-    Assignment.prototype.make_button = function () {
-        var that = this;
-        var container = $('').addClass('item_status col-sm-4');
-        var button = $('',
-        '        ',
-        '        ',
-        '      
', - '
', - '
', - ' ', - ' ', - ' ', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - ' Released assignments', - '
', - '
', - '
', - '
', - '
There are no assignments to fetch.
', - '
', - '
', - '
Loading, please wait...
', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - ' Downloaded assignments', - '
', - '
', - '
', - '
', - '
There are no downloaded assignments.
', - '
', - '
', - '
Loading, please wait...
', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - ' Submitted assignments', - '
', - '
', - '
', - '
', - '
There are no submitted assignments.
', - '
', - '
', - '
Loading, please wait...
', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - '
', - '
' - ].join('\n')); - - function checkNbGraderVersion(base_url) { - var settings = { - cache : false, - type : "GET", - dataType : "json", - data : { - version: nbgrader_version - }, - success : function (response) { - if (!response['success']) { - var err = $("#assignments .version_error"); - err.text(response['message']); - err.show(); - } - }, - error : utils.log_ajax_error, - }; - var url = utils.url_path_join(base_url, 'nbgrader_version'); - ajax(url, settings); - } - - function load() { - if (!Jupyter.notebook_list) return; - var base_url = Jupyter.notebook_list.base_url; - $('head').append( - $('') - .attr('rel', 'stylesheet') - .attr('type', 'text/css') - .attr('href', base_url + 'nbextensions/assignment_list/assignment_list.css') - ); - $(".tab-content").append(assignment_html); - $("#tabs").append( - $('
  • ') - .append( - $('') - .attr('href', '#assignments') - .attr('data-toggle', 'tab') - .text('Assignments') - .click(function (e) { - window.history.pushState(null, null, '#assignments'); - course_list.load_list(); - }) - ) - ); - var assignment_list = new AssignmentList.AssignmentList( - '#released_assignments_list', - '#fetched_assignments_list', - '#submitted_assignments_list', - { - base_url: Jupyter.notebook_list.base_url, - notebook_path: Jupyter.notebook_list.notebook_path, - } - ); - var course_list = new AssignmentList.CourseList( - '#course_list', - '#course_list_default', - '#course_list_dropdown', - '#refresh_assignments_list', - assignment_list, - { - base_url: Jupyter.notebook_list.base_url, - } - ); - checkNbGraderVersion(base_url); - } - return { - load_ipython_extension: load - }; -}); diff --git a/nbgrader/nbextensions/course_list/course_list.css b/nbgrader/nbextensions/course_list/course_list.css deleted file mode 100644 index 19e775422..000000000 --- a/nbgrader/nbextensions/course_list/course_list.css +++ /dev/null @@ -1,67 +0,0 @@ -#courses .panel-group .panel { - margin-top: 3px; - margin-bottom: 1em; -} - -#courses .panel-group .panel .panel-heading { - background-color: #eee; - padding-top: 4px; - padding-bottom: 4px; - padding-left: 7px; - padding-right: 7px; - line-height: 22px; -} - -#courses .panel-group .panel .panel-heading a:focus, a:hover { - text-decoration: none; -} - -#courses .panel-group .panel .panel-body { - padding: 0; -} - -#courses .panel-group .panel .panel-body .list_container { - margin-top: 0px; - margin-bottom: 0px; - border: 0px; - border-radius: 0px; -} - -#courses .panel-group .panel .panel-body .list_container .list_item { - border-bottom: 1px solid #ddd; -} - -#courses .panel-group .panel .panel-body .list_container .list_item:last-child { - border-bottom: 0px; -} - -#courses .list_item { - padding-top: 4px; - padding-bottom: 4px; - padding-left: 7px; - padding-right: 7px; - line-height: 22px; -} - -#courses .list_item > div { - padding-top: 0; - padding-bottom: 0; - padding-left: 0; - padding-right: 0; -} - -#courses .list_placeholder { - display: none; -} - -#courses .list_placeholder, #courses .list_loading, #courses .list_error { - font-weight: bold; - padding-top: 4px; - padding-bottom: 4px; - padding-left: 7px; - padding-right: 7px; -} - -#courses .list_error, #courses .version_error { - display: none; -} diff --git a/nbgrader/nbextensions/course_list/course_list.js b/nbgrader/nbextensions/course_list/course_list.js deleted file mode 100644 index 5bd8a044f..000000000 --- a/nbgrader/nbextensions/course_list/course_list.js +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) Jupyter Development Team. -// Distributed under the terms of the Modified BSD License. - -define([ - 'base/js/namespace', - 'jquery', - 'base/js/utils', - 'base/js/dialog', -], function(Jupyter, $, utils, dialog) { - "use strict"; - - var ajax = utils.ajax || $.ajax; - // Notebook v4.3.1 enabled xsrf so use notebooks ajax that includes the - // xsrf token in the header data - - var CourseList = function (course_list_selector, refresh_selector, options) { - this.course_list_selector = course_list_selector; - this.refresh_selector = refresh_selector; - - this.course_list_element = $(course_list_selector); - this.refresh_element = $(refresh_selector); - - this.current_course = undefined; - this.bind_events() - - options = options || {}; - this.options = options; - this.base_url = options.base_url || utils.get_body_data("baseUrl"); - - this.data = undefined; - }; - - CourseList.prototype.bind_events = function () { - var that = this; - this.refresh_element.click(function () { - that.load_list(); - }); - }; - - - CourseList.prototype.clear_list = function (loading) { - this.course_list_element.children('.list_item').remove(); - if (loading) { - // show loading - this.course_list_element.children('.list_loading').show(); - // hide placeholders and errors - this.course_list_element.children('.list_placeholder').hide(); - this.course_list_element.children('.list_error').hide(); - - } else { - // show placeholders - this.course_list_element.children('.list_placeholder').show(); - // hide loading and errors - this.course_list_element.children('.list_loading').hide(); - this.course_list_element.children('.list_error').hide(); - } - }; - - CourseList.prototype.show_error = function (error) { - this.course_list_element.children('.list_item').remove(); - // show errors - this.course_list_element.children('.list_error').show(); - this.course_list_element.children('.list_error').text(error); - // hide loading and placeholding - this.course_list_element.children('.list_loading').hide(); - this.course_list_element.children('.list_placeholder').hide(); - }; - - CourseList.prototype.load_list = function () { - this.clear_list(true); - - var settings = { - processData : false, - cache : false, - type : "GET", - dataType : "json", - success : $.proxy(this.handle_load_list, this), - error : utils.log_ajax_error, - }; - var url = utils.url_path_join(this.base_url, 'formgraders'); - ajax(url, settings); - }; - - CourseList.prototype.handle_load_list = function (data, status, xhr) { - if (data.success) { - this.load_list_success(data.value); - } else { - this.show_error(data.value); - } - }; - - CourseList.prototype.load_list_success = function (data) { - this.clear_list(); - var len = data.length; - for (var i=0; i'); - var item = new Course(element, data[i], this.course_list_selector, $.proxy(this.handle_load_list, this), this.options); - this.course_list_element.append(element); - this.course_list_element.children('.list_placeholder').hide() - } - - if (this.callback) { - this.callback(); - this.callback = undefined; - } - }; - - var Course = function (element, data, parent, on_refresh, options) { - this.element = $(element); - this.course_id = data['course_id']; - this.formgrader_kind = data['kind']; - this.url = data['url']; - this.parent = parent; - this.on_refresh = on_refresh; - this.options = options; - this.style(); - this.make_row(); - }; - - Course.prototype.style = function () { - this.element.addClass('list_item').addClass("row"); - }; - - Course.prototype.make_row = function () { - var row = $('
    ').addClass('col-md-12'); - var course_id = this.course_id; - - if(course_id === '') { - course_id = 'Default formgrader'; - } - - var container = $('').addClass('item_name col-sm-2').append( - $('') - .attr('href', this.url) - .attr('target', '_blank') - .text(course_id)); - row.append(container); - row.append($('').addClass('item_course col-sm-2').text(this.formgrader_kind)); - this.element.empty().append(row); - }; - - return { - 'CourseList': CourseList - }; -}); diff --git a/nbgrader/nbextensions/course_list/main.js b/nbgrader/nbextensions/course_list/main.js deleted file mode 100644 index 424c5ac67..000000000 --- a/nbgrader/nbextensions/course_list/main.js +++ /dev/null @@ -1,101 +0,0 @@ -define([ - 'base/js/namespace', - 'jquery', - 'base/js/utils', - './course_list' -], function(Jupyter, $, utils, CourseList) { - "use strict"; - - var nbgrader_version = "0.8.3"; - - var ajax = utils.ajax || $.ajax; - // Notebook v4.3.1 enabled xsrf so use notebooks ajax that includes the - // xsrf token in the header data - - var course_html = $([ - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - ' Available formgraders', - ' ', - ' ', - ' ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    There are no available formgrader services.
    ', - '
    ', - '
    ', - '
    Loading, please wait...
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ' - ].join('\n')); - - function checkNbGraderVersion(base_url) { - var settings = { - cache : false, - type : "GET", - dataType : "json", - data : { - version: nbgrader_version - }, - success : function (response) { - if (!response['success']) { - var err = $("#courses .version_error"); - err.text(response['message']); - err.show(); - } - }, - error : utils.log_ajax_error, - }; - var url = utils.url_path_join(base_url, 'nbgrader_version'); - ajax(url, settings); - } - - function load() { - if (!Jupyter.notebook_list) return; - var base_url = Jupyter.notebook_list.base_url; - $('head').append( - $('') - .attr('rel', 'stylesheet') - .attr('type', 'text/css') - .attr('href', base_url + 'nbextensions/course_list/course_list.css') - ); - $(".tab-content").append(course_html); - $("#tabs").append( - $('
  • ') - .append( - $('') - .attr('href', '#courses') - .attr('data-toggle', 'tab') - .text('Courses') - .click(function (e) { - window.history.pushState(null, null, '#courses'); - course_list.load_list(); - }) - ) - ); - var course_list = new CourseList.CourseList( - '#formgrader_list', - '#refresh_formgrader_list', - { - base_url: Jupyter.notebook_list.base_url - } - ); - checkNbGraderVersion(base_url); - } - return { - load_ipython_extension: load - }; -}); diff --git a/nbgrader/nbextensions/create_assignment/create_assignment.css b/nbgrader/nbextensions/create_assignment/create_assignment.css deleted file mode 100644 index 6234a00b3..000000000 --- a/nbgrader/nbextensions/create_assignment/create_assignment.css +++ /dev/null @@ -1,66 +0,0 @@ -div.nbgrader-points, div.nbgrader-id { - margin-right: 0.5em; -} - -input.nbgrader-points-input { - width: 3.5em; - height: 22px; - text-align: right; - line-height: 10px; - color: black; -} - -input.nbgrader-id-input { - height: 22px; - text-align: left; - color: black; -} - -#nbgrader-total-points { - width: 3em; - height: 24px; - text-align: right; - line-height: 10px; - margin-left: 0.3em; - margin-right: 0.3em; -} - -div.nbgrader-highlight div.celltoolbar { - color: white; - background-color: #337ab7; - border: 1px solid #337ab7; -} - -div.nbgrader-highlight div.text_cell_render, div.nbgrader-highlight div.input_area { - border: 1px solid #337ab7 !important; -} - -.celltoolbar { - /* safari fix, we cannot use -webkit-flex on hbox - and vbox either or all css get borked - cf https://github.com/jupyter/nbgrader/issues/394. - manual workaround while #370 is not released. */ - display: -webkit-flex; -} - -div.lock-cell-container { - margin-right: auto; - padding-left: 0.5em; - line-height: 25px; - font-size: 1.4em; -} - -.tooltip-inner { - max-width: 300px; -} - -a.lock-button { - color: black -} -div.nbgrader-highlight a.lock-button { - color: white; -} - -a.lock-editable:hover { - cursor: pointer; -} diff --git a/nbgrader/nbextensions/create_assignment/main.js b/nbgrader/nbextensions/create_assignment/main.js deleted file mode 100644 index 00dbd3de4..000000000 --- a/nbgrader/nbextensions/create_assignment/main.js +++ /dev/null @@ -1,626 +0,0 @@ -define([ - 'require', - 'jquery', - 'base/js/namespace', - 'base/js/dialog', - 'notebook/js/celltoolbar', - 'base/js/events' - -], function (require, $, Jupyter, dialog, celltoolbar, events) { - "use strict"; - - var nbgrader_preset_name = "Create Assignment"; - var nbgrader_highlight_cls = "nbgrader-highlight"; - var nbgrader_cls = "nbgrader-cell"; - var nbgrader_schema_version = 3; - var warning; - - var CellToolbar = celltoolbar.CellToolbar; - - // trigger an event when the toolbar is being rebuilt - CellToolbar.prototype._rebuild = CellToolbar.prototype.rebuild; - CellToolbar.prototype.rebuild = function () { - events.trigger('toolbar_rebuild.CellToolbar', this.cell); - this._rebuild(); - }; - - // trigger an event when the toolbar is being (globally) hidden - CellToolbar._global_hide = CellToolbar.global_hide; - CellToolbar.global_hide = function () { - $("#nbgrader-total-points-group").hide(); - - CellToolbar._global_hide(); - for (var i=0; i < CellToolbar._instances.length; i++) { - events.trigger('global_hide.CellToolbar', CellToolbar._instances[i].cell); - } - }; - - // show the total points when the preset is activated - events.on('preset_activated.CellToolbar', function(evt, preset) { - validate_schema_version(); - clear_cell_types(); - - var elem = $("#nbgrader-total-points-group"); - if (preset.name === nbgrader_preset_name) { - if (elem.length == 0) { - elem = $("
    ").attr("id", "nbgrader-total-points-group"); - elem.addClass("btn-group"); - elem.append($("").text("Total points:")); - elem.append($("") - .attr("disabled", "disabled") - .attr("type", "number") - .attr("id", "nbgrader-total-points")); - $("#maintoolbar-container").append(elem); - } - elem.show(); - update_total(); - } else { - elem.hide(); - } - }); - - // remove nbgrader class when the cell is either hidden or rebuilt - events.on("global_hide.CellToolbar toolbar_rebuild.CellToolbar", function (evt, cell) { - if (cell.element && cell.element.hasClass(nbgrader_cls)) { - cell.element.removeClass(nbgrader_cls); - } - if (cell.element && cell.element.hasClass(nbgrader_highlight_cls)) { - cell.element.removeClass(nbgrader_highlight_cls); - } - }); - - // update total points when a cell is deleted - events.on("delete.Cell", function (evt, info) { - update_total(); - }); - - // validate cell ids on save - events.on("before_save.Notebook", function (evt) { - validate_ids(); - }); - - var randomString = function(length) { - var result = ''; - var chars = 'abcdef0123456789'; - var i; - for (i=0; i < length; i++) { - result += chars[Math.floor(Math.random() * chars.length)]; - } - return result; - }; - - var to_float = function(val) { - if (val === undefined || val === "") { - return 0; - } - return parseFloat(val); - }; - - var update_total = function() { - var total_points = 0; - var cells = Jupyter.notebook.get_cells(); - for (var i=0; i < cells.length; i++) { - if (is_graded(cells[i])) { - total_points += to_float(cells[i].metadata.nbgrader.points); - } - } - $("#nbgrader-total-points").attr("value", total_points); - }; - - var validate_ids = function() { - var elems, set, i, label; - - if (warning !== undefined) { - return; - } - - var valid = /^[a-zA-Z0-9_\-]+$/; - var modal_opts = { - notebook: Jupyter.notebook, - keyboard_manager: Jupyter.keyboard_manager, - buttons: { - OK: { - class: "btn-primary", - click: function () { - warning = undefined; - } - } - } - }; - - elems = $(".nbgrader-id-input"); - set = new Object(); - for (i = 0; i < elems.length; i++) { - label = $(elems[i]).val(); - if (!valid.test(label)) { - modal_opts.title = "Invalid nbgrader cell ID"; - modal_opts.body = "At least one cell has an invalid nbgrader ID. Cell IDs must contain at least one character, and may only contain letters, numbers, hyphens, and/or underscores."; - warning = dialog.modal(modal_opts); - break; - } else if (label in set) { - modal_opts.title = "Duplicate nbgrader cell ID"; - modal_opts.body = "The nbgrader ID \"" + label + "\" has been used for more than one cell. Please make sure all grade cells have unique ids."; - warning = dialog.modal(modal_opts); - break; - } else { - set[label] = true; - } - } - }; - - var validate_schema_version = function() { - var i, cells, schema; - - if (warning !== undefined) { - return; - } - - var modal_opts = { - notebook: Jupyter.notebook, - keyboard_manager: Jupyter.keyboard_manager, - buttons: { - OK: { - class: "btn-primary", - click: function () { - warning = undefined; - } - } - } - }; - - cells = Jupyter.notebook.get_cells(); - for (i = 0; i < cells.length; i++) { - schema = get_schema_version(cells[i]); - if (schema !== undefined && schema < nbgrader_schema_version) { - modal_opts.title = "Outdated schema version"; - modal_opts.body = $("

    ").html( - "At least one cell has an old version (" + schema + ") of the " + - "nbgrader metadata. Please back up this notebook and then " + - "update the metadata on the command " + - "line using the following command: nbgrader update " + - Jupyter.notebook.notebook_path + ""); - warning = dialog.modal(modal_opts); - break; - } - } - }; - - var clear_cell_types = function() { - var cells = Jupyter.notebook.get_cells(); - var i; - for (i = 0; i < cells.length; i++) { - if (cells[i].metadata.nbgrader !== undefined && cells[i].metadata.nbgrader.hasOwnProperty("cell_type")) { - delete cells[i].metadata.nbgrader.cell_type; - } - } - }; - - /** - * Remove all nbgrader metadata - */ - var remove_metadata = function (cell) { - if (cell.metadata.hasOwnProperty("nbgrader")) { - delete cell.metadata.nbgrader; - } - }; - - /** - * Set nbgrader schema version - */ - var set_schema_version = function (cell) { - if (cell.metadata.nbgrader === undefined) { - cell.metadata.nbgrader = {}; - } - cell.metadata.nbgrader.schema_version = nbgrader_schema_version; - }; - - /** - * Get nbgrader schema version - */ - var get_schema_version = function (cell) { - if (cell.metadata.nbgrader === undefined) { - return undefined; - } - if (!cell.metadata.nbgrader.hasOwnProperty("schema_version")) { - return 0; - } - return cell.metadata.nbgrader.schema_version; - }; - - /** - * Is the cell a solution cell? - */ - var is_solution = function (cell) { - if (cell.metadata.nbgrader === undefined) { - return false; - } else if (cell.metadata.nbgrader.solution === undefined) { - return false; - } else { - return cell.metadata.nbgrader.solution; - } - }; - - /** - * Set whether this cell is or is not a solution cell. - */ - var set_solution = function (cell, val) { - if (cell.metadata.nbgrader === undefined) { - cell.metadata.nbgrader = {}; - } - cell.metadata.nbgrader.solution = val; - }; - - /** - * Is the cell a grade cell? - */ - var is_grade = function (cell) { - if (cell.metadata.nbgrader === undefined) { - return false; - } else if (cell.metadata.nbgrader.grade === undefined) { - return false; - } else { - return cell.metadata.nbgrader.grade; - } - }; - - /** - * Set whether this cell is or is not a grade cell. - */ - var set_grade = function (cell, val) { - if (cell.metadata.nbgrader === undefined) { - cell.metadata.nbgrader = {}; - } - cell.metadata.nbgrader.grade = val; - if (val === false && cell.metadata.nbgrader.hasOwnProperty("points")) { - delete cell.metadata.nbgrader.points; - } - }; - - /** - * Is the cell a task cell? - */ - var is_task = function (cell) { - if (cell.metadata.nbgrader === undefined) { - return false; - } else if (cell.metadata.nbgrader.task === undefined) { - return false; - } else { - return cell.metadata.nbgrader.task; - } - }; - - /** - * Set whether this cell is or is not a grade cell. - */ - var set_task = function (cell, val) { - if (cell.metadata.nbgrader === undefined) { - cell.metadata.nbgrader = {}; - } - cell.metadata.nbgrader.task = val; - }; - - var is_graded = function (cell) { - return ( is_grade(cell) || is_task(cell) ); - }; - - - var get_points = function (cell) { - if (cell.metadata.nbgrader === undefined) { - return 0; - } else { - return to_float(cell.metadata.nbgrader.points); - } - }; - - var set_points = function (cell, val) { - if (cell.metadata.nbgrader === undefined) { - cell.metadata.nbgrader = {}; - } - var points = to_float(val); - if (points < 0) points = 0; - cell.metadata.nbgrader.points = points; - }; - - var get_grade_id = function (cell) { - if (cell.metadata.nbgrader === undefined) { - return "cell-" + randomString(16); - } else if (cell.metadata.nbgrader.grade_id === undefined) { - return "cell-" + randomString(16); - } else { - return cell.metadata.nbgrader.grade_id; - } - }; - - var set_grade_id = function (cell, val) { - if (cell.metadata.nbgrader === undefined) { - cell.metadata.nbgrader = {}; - } - if (val === undefined) { - cell.metadata.nbgrader.grade_id = ''; - } else { - cell.metadata.nbgrader.grade_id = val; - } - }; - - var is_locked = function (cell) { - if (is_solution(cell)) { - return false; - } else if (is_graded(cell)) { - return true; - } else if (cell.metadata.nbgrader === undefined) { - return false; - } else if (cell.metadata.nbgrader.locked === undefined) { - return false; - } else { - return cell.metadata.nbgrader.locked; - } - }; - - var set_locked = function (cell, val) { - if (cell.metadata.nbgrader === undefined) { - cell.metadata.nbgrader = {}; - } - if (is_solution(cell)) { - cell.metadata.nbgrader.locked = false; - } else if (is_graded(cell)) { - cell.metadata.nbgrader.locked = true; - } else { - cell.metadata.nbgrader.locked = val; - } - }; - - var is_invalid = function (cell) { - if (is_task(cell)) { - return false; - } else if (is_solution(cell) && is_grade(cell)) { - return false; - } else if (is_solution(cell) && cell.cell_type !== "code") { - return true; - } else if (is_grade(cell) && cell.cell_type !== "code") { - return true; - } else { - return false; - } - }; - - /** - * Add a display class to the cell element, depending on the - * nbgrader cell type. - */ - var display_cell = function (cell) { - if (is_graded(cell) || is_solution(cell)) { - if (cell.element && !cell.element.hasClass(nbgrader_highlight_cls)) { - cell.element.addClass(nbgrader_highlight_cls); - } - } - if (is_graded(cell) || is_solution(cell) || is_locked(cell)) { - if (cell.element && !cell.element.hasClass(nbgrader_cls)) { - cell.element.addClass(nbgrader_cls); - } - } - - if (is_task(cell) ){ - if (cell.element && !cell.element.hasClass("nbgrader_task")) { - cell.element.addClass("nbgrader_task"); - } - } else { - if (cell.element && cell.element.hasClass("nbgrader_task")) { - cell.element.removeClass("nbgrader_task"); - } - } - }; - - var create_celltype_select = function (div, cell, celltoolbar) { - // hack -- the DOM element for the celltoolbar is created before the - // cell type is actually set, so we need to wait until the cell type - // has been set before we can actually create the select menu - if (cell.cell_type === null) { - setTimeout(function () { - create_celltype_select(div, cell, celltoolbar); - }, 100); - - } else { - - if (is_invalid(cell)) { - set_schema_version(cell); - set_solution(cell, false); - set_grade(cell, false); - set_locked(cell, false); - set_task(cell, false); - celltoolbar.rebuild(); - return; - } - - var options_list = []; - options_list.push(["-", ""]); - options_list.push(["Manually graded answer", "manual"]); - options_list.push(["Manually graded task", "task"]); - if (cell.cell_type == "code") { - options_list.push(["Autograded answer", "solution"]); - options_list.push(["Autograder tests", "tests"]); - } - options_list.push(["Read-only", "readonly"]); - var setter = function (cell, val) { - if (val === "") { - remove_metadata(cell); - } else if (val === "manual") { - set_schema_version(cell); - set_solution(cell, true); - set_grade(cell, true); - set_locked(cell, false); - set_task(cell, false); - } else if (val === "task") { - set_schema_version(cell); - set_solution(cell, false); - set_grade(cell, false); - set_locked(cell, true); - set_task(cell, true); - if (cell.get_text() === ''){ - cell.set_text('Describe the task here!') - } - } else if (val === "solution") { - set_schema_version(cell); - set_solution(cell, true); - set_grade(cell, false); - set_locked(cell, false); - set_task(cell, false); - } else if (val === "tests") { - set_schema_version(cell); - set_solution(cell, false); - set_grade(cell, true); - set_locked(cell, true); - set_task(cell, false); - } else if (val === "readonly") { - set_schema_version(cell); - set_solution(cell, false); - set_grade(cell, false); - set_locked(cell, true); - set_task(cell, false); - } else { - throw new Error("invalid nbgrader cell type: " + val); - } - }; - - var getter = function (cell) { - if (is_task(cell)) { - return "task"; - } else if (is_solution(cell) && is_grade(cell)) { - return "manual"; - } else if (is_solution(cell) && cell.cell_type === "code") { - return "solution"; - } else if (is_grade(cell) && cell.cell_type === "code") { - return "tests"; - } else if (is_locked(cell)) { - return "readonly"; - } else { - return ""; - } - }; - - var select = $('').attr('type', 'text'); - var lbl = $('

  • ").addClass("fa fa-lock")); - lock.tooltip({ - placement: "right", - title: "Student changes will be overwritten" - }); - } - - $(div).addClass("lock-cell-container").append(lock); - }; - - /** - * Load custom css for the nbgrader toolbar. - */ - var load_css = function () { - var link = document.createElement('link'); - link.type = 'text/css'; - link.rel = 'stylesheet'; - link.href = require.toUrl('./create_assignment.css'); - document.getElementsByTagName('head')[0].appendChild(link); - }; - - /** - * Load the nbgrader toolbar extension. - */ - var load_extension = function () { - load_css(); - CellToolbar.register_callback('create_assignment.grading_options', create_celltype_select); - CellToolbar.register_callback('create_assignment.id_input', create_id_input); - CellToolbar.register_callback('create_assignment.points_input', create_points_input); - CellToolbar.register_callback('create_assignment.lock_cell', create_lock_cell_button); - - var preset = [ - 'create_assignment.lock_cell', - 'create_assignment.points_input', - 'create_assignment.id_input', - 'create_assignment.grading_options', - ]; - CellToolbar.register_preset(nbgrader_preset_name, preset, Jupyter.notebook); - console.log('nbgrader extension for metadata editing loaded.'); - }; - - return { - 'load_ipython_extension': load_extension - }; -}); diff --git a/nbgrader/nbextensions/formgrader/main.js b/nbgrader/nbextensions/formgrader/main.js deleted file mode 100644 index bb85a78b8..000000000 --- a/nbgrader/nbextensions/formgrader/main.js +++ /dev/null @@ -1,21 +0,0 @@ -define(function(require) { - var $ = require('jquery'); - var Jupyter = require('base/js/namespace'); - - function load() { - if (!Jupyter.notebook_list) return; - var base_url = Jupyter.notebook_list.base_url; - $("#tabs").append( - $('
  • ') - .append( - $('') - .attr('href', base_url + 'formgrader') - .attr('target', '_blank') - .text('Formgrader') - ) - ); - } - return { - load_ipython_extension: load - }; -}); diff --git a/nbgrader/nbextensions/validate_assignment/main.js b/nbgrader/nbextensions/validate_assignment/main.js deleted file mode 100644 index a71a59269..000000000 --- a/nbgrader/nbextensions/validate_assignment/main.js +++ /dev/null @@ -1,142 +0,0 @@ -define([ - 'jquery', - 'base/js/namespace', - 'base/js/dialog', - 'base/js/utils' - -], function ($, Jupyter, dialog, utils) { - "use strict"; - - var nbgrader_version = "0.8.3"; - - var ajax = utils.ajax || $.ajax; - // Notebook v4.3.1 enabled xsrf so use notebooks ajax that includes the - // xsrf token in the header data - - var checkNbGraderVersion = function (callback) { - var settings = { - cache : false, - type : "GET", - dataType : "json", - data : { - version: nbgrader_version - }, - success : function (response) { - if (!response['success']) { - var body = $("
    ").text(response['message']); - dialog.modal({ - title: "Version Mismatch", - body: body, - buttons: { OK: { class : "btn-primary" } } - }); - } else { - callback(); - } - }, - error : utils.log_ajax_error, - }; - var url = utils.url_path_join(Jupyter.notebook.base_url, 'nbgrader_version'); - ajax(url, settings); - }; - - var add_button = function () { - var maintoolbar = $("#maintoolbar-container"); - var btn_group = $("
    ").attr("class", "btn-group") - var btn = $("