Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit 5d717f9

Browse files
committed
Merge branch 'bookserver' of github.com:RunestoneInteractive/RunestoneComponents into bookserver
2 parents ca83cae + 9b5a74e commit 5d717f9

8 files changed

Lines changed: 67 additions & 39 deletions

File tree

.jshintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"allVisualizers",
88
"console"
99
],
10-
"esversion": 6,
10+
"esversion": 8,
1111
"quotmark": true,
1212
"strict": "implied",
1313
"sub": true,

index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ Runestone Components
33
********************
44
This site documents the working of the Runestone Components. See the `Runestone Interactive Overview <https://runestone.academy/runestone/books/published/overview/overview.html>`_ or the `Runestone instructor's guide <https://runestone.academy/runestone/static/instructorguide/index.html>`_.
55

6+
Demo linking to the Runestone Server docs: :ref:`assignments/grades_report endpoint`.
7+
68

79
Getting started
810
===============

runestone/common/js/bookfuncs.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ function addReadingList() {
105105
});
106106
} else {
107107
l = $("<div />", {
108-
text:
109-
"This page is not part of the last reading assignment you visited.",
108+
text: "This page is not part of the last reading assignment you visited.",
110109
});
111110
}
112111
$("#main-content").append(l);
@@ -206,12 +205,26 @@ class PageProgressBar {
206205

207206
export var pageProgressTracker = {};
208207

209-
function handlePageSetup() {
208+
async function handlePageSetup() {
210209
var mess;
211-
if (eBookConfig.useRunestoneServices) {
212-
jQuery.get(eBookConfig.ajaxURL + "set_tz_offset", {
213-
timezoneoffset: new Date().getTimezoneOffset() / 60,
214-
});
210+
let headers = new Headers({
211+
"Content-type": "application/json; charset=utf-8",
212+
Accept: "application/json",
213+
});
214+
let data = { timezoneoffset: new Date().getTimezoneOffset() / 60 };
215+
let request = new Request("/logger/set_tz_offset", {
216+
method: "POST",
217+
body: JSON.stringify(data),
218+
headers: headers,
219+
});
220+
try {
221+
let response = await fetch(request);
222+
if (!response.ok) {
223+
console.error(`Failed to set timezone! ${response.statusText}`);
224+
}
225+
data = await response.json();
226+
} catch (e) {
227+
console.error(`Error setting timezone ${e}`);
215228
}
216229

217230
if (eBookConfig.isLoggedIn) {

runestone/common/js/runestonebase.js

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import { pageProgressTracker } from "./bookfuncs.js";
2020

2121
export default class RunestoneBase {
2222
constructor(opts) {
23-
this.component_ready_promise = new Promise(resolve => this._component_ready_resolve_fn = resolve)
23+
this.component_ready_promise = new Promise(
24+
(resolve) => (this._component_ready_resolve_fn = resolve)
25+
);
2426
this.optional = false;
2527
if (opts) {
2628
this.sid = opts.sid;
@@ -57,7 +59,7 @@ export default class RunestoneBase {
5759
// is to look for doAssignment in the URL and then grab
5860
// the assignment name from the heading.
5961
if (location.href.indexOf("doAssignment") >= 0) {
60-
this.timedWrapper = $("h1#assignment_name").text()
62+
this.timedWrapper = $("h1#assignment_name").text();
6163
} else {
6264
this.timedWrapper = null;
6365
}
@@ -72,10 +74,8 @@ export default class RunestoneBase {
7274
});
7375
}
7476

75-
// .. _logBookEvent:
76-
//
77-
// logBookEvent
78-
// ------------
77+
// _`logBookEvent`
78+
//----------------
7979
// This function sends the provided ``eventInfo`` to the `hsblog endpoint` of the server. Awaiting this function returns either ``undefined`` (if Runestone services are not available) or the data returned by the server as a JavaScript object (already JSON-decoded).
8080
async logBookEvent(eventInfo) {
8181
if (this.graderactive) {
@@ -97,12 +97,17 @@ export default class RunestoneBase {
9797
try {
9898
let response = await fetch(request);
9999
if (!response.ok) {
100-
throw new Error("Failed to save the log entry");
100+
let detail = await response.json();
101+
console.error(detail);
102+
throw new Error(`Failed to save the log entry ${detail}`);
103+
} else {
104+
post_return = response.json();
101105
}
102-
post_return = response.json();
103106
} catch (e) {
104107
if (this.isTimed) {
105-
alert(`Error: Your action was not saved! The error was ${e}`);
108+
alert(
109+
`Error: Your action was not saved! The error was ${e}`
110+
);
106111
}
107112
console.log(`Error: ${e}`);
108113
}
@@ -120,10 +125,8 @@ export default class RunestoneBase {
120125
return post_return;
121126
}
122127

123-
// .. _logRunEvent:
124-
//
125-
// logRunEvent
126-
// -----------
128+
// -`logRunEvent`
129+
//---------------
127130
// This function sends the provided ``eventInfo`` to the `runlog endpoint`. When awaited, this function returns the data (decoded from JSON) the server sent back.
128131
async logRunEvent(eventInfo) {
129132
let post_promise = "done";
@@ -192,19 +195,23 @@ export default class RunestoneBase {
192195
data.sid = this.sid;
193196
}
194197
if (!eBookConfig.practice_mode && this.assessmentTaken) {
195-
let request = new Request(
196-
"/assessment/results",
197-
{
198-
method: "POST",
199-
body: JSON.stringify(data),
200-
headers: this.jsonHeaders,
201-
}
202-
);
198+
let request = new Request("/assessment/results", {
199+
method: "POST",
200+
body: JSON.stringify(data),
201+
headers: this.jsonHeaders,
202+
});
203203
try {
204204
let response = await fetch(request);
205-
data = await response.json();
206-
this.repopulateFromStorage(data);
207-
this.csresolver("server");
205+
if (response.ok) {
206+
data = await response.json();
207+
data = data.detail;
208+
this.repopulateFromStorage(data);
209+
this.csresolver("server");
210+
} else {
211+
alert(
212+
`HTTP Error getting results: ${response.statusText}`
213+
);
214+
}
208215
} catch (err) {
209216
try {
210217
this.checkLocalStorage();
@@ -252,7 +259,7 @@ export default class RunestoneBase {
252259
*/
253260
repopulateFromStorage(data) {
254261
// decide whether to use the server's answer (if there is one) or to load from storage
255-
if (data !== null && this.shouldUseServer(data)) {
262+
if (data !== null && data !== "no data" && this.shouldUseServer(data)) {
256263
this.restoreAnswers(data);
257264
this.setLocalStorage(data);
258265
} else {

runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/layout.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,9 @@
243243
eBookConfig.username = '{{ user_id}}';
244244
eBookConfig.readings = {{ readings}};
245245
eBookConfig.activities = {{ activity_info }}
246-
eBookConfig.downloadsEnabled = {{downloads_enabled}};
247-
eBookConfig.allow_pairs = {{allow_pairs}}
248-
eBookConfig.enableCompareMe = {{enable_compare_me}};
246+
eBookConfig.downloadsEnabled = {{ downloads_enabled}};
247+
eBookConfig.allow_pairs = {{ allow_pairs}}
248+
eBookConfig.enableCompareMe = {{ enable_compare_me }};
249249
{% endraw %}
250250
{% else %}
251251
eBookConfig.useRunestoneServices = {% if use_services == 'true' -%}true{%- else -%}false{%- endif -%};

runestone/server/componentdb.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ def setup(app):
128128
logger.info("Connecting to DB")
129129
try:
130130
dburl = get_dburl()
131-
engine = create_engine(dburl, client_encoding="utf8", convert_unicode=True)
131+
# SQLite doesn't support ``client_encoding``, while PostgreSQL does.
132+
encoding = dict(client_encoding="utf8") if dburl.startswith("postgresql") else {}
133+
engine = create_engine(dburl, convert_unicode=True, **encoding)
132134
Session = sessionmaker()
133135
engine.connect()
134136
Session.configure(bind=engine)
@@ -339,6 +341,7 @@ def addQuestionToDB(self):
339341
practice=practice,
340342
topic=topics,
341343
from_source=from_source,
344+
review_flag='F',
342345
optional=optional,
343346
description=et,
344347
**meta_opts,
@@ -388,6 +391,7 @@ def addQuestionToDB(self):
388391
question_name=id_,
389392
)
390393
sess.execute(ins)
394+
sess.commit()
391395

392396

393397
def addQNumberToDB(app, node, qnumber):
@@ -585,7 +589,6 @@ def addAssignmentToDB(
585589
return
586590

587591
course_id = getCourseID(course_name)
588-
last_changed = datetime.now()
589592
sel = select([assignments]).where(
590593
and_(assignments.c.name == name, assignments.c.course == course_id)
591594
)
@@ -624,6 +627,7 @@ def addAssignmentToDB(
624627
visible=visible,
625628
time_limit=time_limit,
626629
from_source="T",
630+
released="F",
627631
)
628632
res = sess.execute(ins)
629633
a_id = res.inserted_primary_key[0]

runestone/timed/js/timed.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,8 @@ export default class Timed extends RunestoneBase {
997997
});
998998
localStorage.setItem(this.localStorageKey(), storageObj);
999999
}
1000+
// _`timed exam endpoint parameters`
1001+
//----------------------------------
10001002
logScore() {
10011003
this.logBookEvent({
10021004
event: "timedExam",

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
with open("requirements.txt", "r", encoding="utf-8") as fh:
1111
dependencies = [l.strip() for l in fh]
1212

13-
VERSION = "5.6.1"
13+
VERSION = "6.0.0dev"
1414

1515
# These pre-install hooks are useful to make sure any pre-requisite
1616
# programs that are not pip installable are in place.

0 commit comments

Comments
 (0)