diff options
author | Aleš Smodiš <aless@guru.si> | 2015-08-24 19:17:43 +0200 |
---|---|---|
committer | Aleš Smodiš <aless@guru.si> | 2015-08-24 19:17:43 +0200 |
commit | 21d213dcff1367c16dc0c3f6585b8e35d7c2f0c7 (patch) | |
tree | ea7164cde0b4ad7ab42b94b291f690813c22b65b /js/codeq | |
parent | 42ee67384fa52bc3db4716ffb9aff2cd0dda3f5e (diff) |
Introduced the Q promises library, created a basic login page to test prolog examples, and started tying the terminal and editor activity to the REST services.
Diffstat (limited to 'js/codeq')
-rw-r--r-- | js/codeq/comms.js | 64 | ||||
-rw-r--r-- | js/codeq/core.js | 33 | ||||
-rw-r--r-- | js/codeq/login.js | 183 |
3 files changed, 280 insertions, 0 deletions
diff --git a/js/codeq/comms.js b/js/codeq/comms.js new file mode 100644 index 0000000..fb5d348 --- /dev/null +++ b/js/codeq/comms.js @@ -0,0 +1,64 @@ +(function () { + + var activityQueue = []; + + var send = function (service, json) { + return Q.Promise(function (resolve, reject, notify) { + $.ajax({ + 'type': 'POST', + 'url': codeq.urlPrefix + service, + 'accepts': 'application/json', + 'contentType': 'application/json; charset=UTF-8', // type of our request + 'data': json, + 'processData': false, // don't process outgoing data + 'dataType': 'json', // expected type of the response + 'timeout': 60000, // one minute + 'error': function sendErrorHandler(jqXHR, textStatus, errorThrown) { + reject(new Error(errorThrown || textStatus)); + }, + 'success': function sendSuccessHandler(data, textStatus, jqXHR) { + resolve(data); + } + }); + }); + }; + + var sendCount = 0, + sendActivityInternal = function () { + var request; + // send max. 100 activities, do not be excessive + if (activityQueue.length > 100) { + sendCount = 100; + request = '[' + activityQueue.slice(0, 100).join(',') + ']'; + } + else { + sendCount = activityQueue.length; + request = '[' + activityQueue.join(',') + ']'; + } + send('activity', request).then( + function sendActivitySuccess() { + activityQueue.splice(0, sendCount); + if (activityQueue.length > 0) sendActivityInternal(); + }, + function sendActivityFailure() { + Q.delay(500).then(sendActivityInternal).done(); + } + ).done(); + }; + + codeq.comms = { + sendActivity: function commsSendActivity (json) { + var triggerSending = activityQueue.length == 0; + json['sid'] = codeq.sid; + activityQueue.push(codeq.jsonize(json)); + if (triggerSending) { + setTimeout(sendActivityInternal, 0); // async trigger: see if you can collect some more payload + } + }, + + sendQuery: function commsSendQuery (json) { + json['sid'] = codeq.sid; + return send('query', codeq.jsonize(json)); + } + }; +})(); diff --git a/js/codeq/core.js b/js/codeq/core.js new file mode 100644 index 0000000..f13a019 --- /dev/null +++ b/js/codeq/core.js @@ -0,0 +1,33 @@ +window.siteDefinition = { logLevel: 'debug' }; // for debug purposes + +window.codeq = { + /** + * XML namespaces. + */ + ns: { + svg: 'http://www.w3.org/2000/svg' + }, + + noOnlineStatus: !('onLine' in navigator), + + /** + * REST API URL prefix. + */ + urlPrefix: '/codeq/', + + /** + * Returns the number of Unicode code points in the given string. + * + * @param s {string} + * @returns {number} + */ + codePointCount: function (s) { + var n = 0, i, code; + for (i = s.length - 1; i >= 0; i--) { + code = s.charCodeAt(i); + if ((code >= 0xd800) && (code < 0xe000)) i++; + n++; + } + return n; + } +}; diff --git a/js/codeq/login.js b/js/codeq/login.js new file mode 100644 index 0000000..d449835 --- /dev/null +++ b/js/codeq/login.js @@ -0,0 +1,183 @@ +(function(){ + var groups = { + 'family_relations': { + 'name': 'Family relations', + 'problems': [ + {'id': 'ancestor_2', 'name': 'ancestor/2'}, + {'id': 'aunt_2', 'name': 'aunt/2'}, + {'id': 'brother_2', 'name': 'brother/2'}, + {'id': 'connected_3', 'name': 'connected/3'}, + {'id': 'cousin_2', 'name': 'cousin/2'} + ] + }, + 'lists': { + 'name': 'Lists', + 'problems': [ + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''} + ] + }, + 'sorting': { + 'name': 'Sorting', + 'problems': [ + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''} + ] + }, + 'other': { + 'name': 'Other', + 'problems': [ + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''} + ] + }, + 'sets': { + 'name': 'Sets', + 'problems': [ + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''} + ] + }, + 'trees': { + 'name': 'Trees', + 'problems': [ + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''} + ] + }, + 'license_plates': { + 'name': 'License plates', + }, + 'clp_fd': { + 'name': 'CLP(FD', + 'problems': [ + {'id': 'gcd_3', 'name': 'gcd/3'}, + {'id': 'magic_1', 'name': 'magic/1'}, + {'id': 'puzzle_abc_3', 'name': 'puzzle_abc/3'}, + {'id': 'puzzle_beth_1', 'name': 'puzzle_beth/1'}, + {'id': 'puzzle_momson_2', 'name': 'puzzle_momson/2'}, + {'id': 'puzzle_ratio_2', 'name': 'puzzle_ratio/2'}, + {'id': 'tobase_3', 'name': 'tobase/3'} + ] + }, + 'clp_r': { + 'name': 'CLP(R)', + 'problems': [ + {'id': 'bounding_box_3', 'name': 'bounding_box/3'}, + {'id': 'center_3', 'name': 'center/3'}, + {'id': 'linear_opts_3', 'name': 'linear_opts/3'}, + {'id': 'max_sum_2', 'name': 'max_sum/2'}, + {'id': 'megabytes_2', 'name': 'megabytes/2'}, + {'id': 'turkey_3', 'name': 'turkey/3'} + ] + }, + 'dcg': { + 'name': 'DCG', + 'problems': [ + {'id': 'ab_2', 'name': 'ab/2'}, + {'id': 'digit_2', 'name': 'digit/2'}, + {'id': 'expr_2', 'name': 'expr/2'}, + {'id': 'expr_3', 'name': 'expr/3'}, + {'id': 'flower_2', 'name': 'flower/2'} + ] + }, + 'denotational_semantics': { + 'name': 'Denotational semantics', + 'problems': [ + {'id': 'algol_3', 'name': 'algol/3'}, + {'id': 'algol_for_3', 'name': 'algol_for/3'}, + {'id': 'algol_if_3', 'name': 'algol_if/3'}, + {'id': 'prog_8puzzle_2', 'name': 'prog_8puzzle/2'}, + {'id': 'prog_8puzzle_3', 'name': 'prog_8puzzle/3'} + ] + }, + 'old_exams': { + 'name': 'Old exams', + 'problems': [ + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''}, + {'id': '', 'name': ''} + ] + } + }; + + $("#submit").on('click', function () { + var group = $('#problem_group').val(), + problem = $('#problems').val(); + if (!group) alert('Choose a problem group'); + else if (!problem) alert('Choose a problem'); + else { + $.ajax({ + 'type': 'POST', + 'url': '/codeq/login', + 'accepts': 'application/json', + 'contentType': 'application/json; charset=UTF-8', + 'data': JSON.stringify({ + 'username': $('#username').val(), + 'password': $('#password').val() + }), + 'processData': false, + 'dataType': 'json', + 'error': function loginErrorHandler(jqXHR, textStatus, errorThrown) { + alert('Request for login failed: ' + (errorThrown || textStatus)); + }, + 'success': function loginSuccessHandler(data, textStatus, jqXHR) { + if (data && (data.code === 0)) { + window.location = 'prolog.html#sid=' + data.sid + '/grp=' + group + '/prb=' + problem; + } + else { + alert('Login failed: code=' + data.code + ', reason=' + data.message); + } + } + }); + } + }); + + $(document).ready(function () { + var jqGroup = $('#problem_group'), + jqProblems = $('#problems'), + id, g, first_group, html = []; + + for (id in groups) { + g = groups[id]; + html.push('<option value="', id, '">', g.name, '</option>\n'); + } + jqGroup.html(html.join('')); + first_group = html[1]; + html = null; + + jqGroup.on('click', function () { + var g = groups[jqGroup.val()], + html = [], + problems, i, p; + if (g) { + problems = g.problems; + for (i = 0; i < problems.length; i++) { + p = problems[i]; + if (!p.id) continue; + html.push('<option value="', p.id, '">', p.name, '</option>\n') + } + } + jqProblems.html(html.join('')); + }); + + jqGroup.val(first_group); + }); +})();
\ No newline at end of file |