~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to www/media/common/util.js

  • Committer: mattgiuca
  • Date: 2008-04-06 15:04:54 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:725
The database now stores a cache of all the worksheets and what problems
are contained within each, for the purposes of determining marks.

This cache is automatically written to the database when someone visits a
worksheet in the website. If the worksheet file gets updated (touched), then
the database entries will be refreshed (so it is kept up to date).

At this stage, it isn't used to compute anything, it just gets stored in the
DB and updated.

Also added an "assessable" attribute to the worksheet element in the
worksheet XML, and an "optional" attribute to the exercise element, also in
the worksheet XML. (Both of these are optional, so it won't break existing
worksheets). Both default to False, so by default worksheets are not
assessable, and assessable worksheets have all-mandatory exercises.

users.sql: Added worksheet and worksheet_problem tables to the DB.
common/db.py: Added methods get_worksheet_mtime and create_worksheet.
tutorial/__init__.py:
    present_table_of_contents now gathers up details about all the exercises.
    present_worksheet now gets top level details.
    Added function update_db_worksheet, which checks the time stamps and
    updates the database if necessary.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
/* Expects the following variables to have been declared by JavaScript in
26
26
 * the HTML generated by the server:
27
27
 * - root_dir
28
 
 * - public_host
29
28
 * - username
30
29
 */
31
30
 
311
310
    if (("path" in obj) && obj.path != null)
312
311
    {
313
312
        var path = urlencode_path(obj.path.toString());
314
 
        if (url.length > 0 && path.length > 0 && path.charAt(0) != "/")
 
313
        if (url.length > 0 && path.length > 0 && path[0] != "/")
315
314
            path = "/" + path;
316
315
        url += path;
317
316
    }
426
425
    {
427
426
        arg = arguments[i];
428
427
        if (arg.length == 0) continue;
429
 
        if (arg.charAt(0) == '/')
 
428
        if (arg[0] == '/')
430
429
            path = arg;
431
430
        else
432
431
        {
433
 
            if (path.length > 0 && path.charAt(path.length-1) != '/')
 
432
            if (path.length > 0 && path[path.length-1] != '/')
434
433
                path += '/';
435
434
            path += arg;
436
435
        }
491
490
function pathlist_to_path(pathlist)
492
491
{
493
492
    ret = path_join.apply(null, pathlist);
494
 
    if (ret.charAt(ret.length-1) != '/')
 
493
    if (ret[ret.length-1] != '/')
495
494
        ret += '/';
496
495
    return ret;
497
496
}
512
511
    return make_path(path_join.apply(null, arguments));
513
512
}
514
513
 
515
 
/** Generates an absolute URL to a public application
516
 
 */
517
 
function public_app_path(app /*,...*/)
518
 
{
519
 
    return location.protocol + "//" + public_host
520
 
        + make_path(path_join.apply(null, arguments));
521
 
}
522
 
 
523
514
/** Given a path, gets the "basename" (the last path segment).
524
515
 */
525
516
function path_basename(path)
538
529
    return str.substr(str.length - substring.length) == substring;
539
530
}
540
531
 
 
532
/** Equivalent to Python's repr.
 
533
 * Gets the JavaScript string representation.
 
534
 * Actually just calls JSON.stringify.
 
535
 */
 
536
function repr(str)
 
537
{
 
538
    return JSON.stringify(str);
 
539
}
 
540
 
541
541
/** Removes all occurences of a value from an array.
542
542
 */
543
543
Array.prototype.removeall = function(val)
594
594
    }
595
595
}
596
596
 
597
 
/** Creates a random string of length length,
598
 
 * consisting of alphanumeric characters.
599
 
 */
600
 
var rand_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ"
601
 
               + "abcdefghiklmnopqrstuvwxyz";
602
 
function random_string(length)
603
 
{
604
 
    var str = Array(length);
605
 
    var v;
606
 
    for (var i=0; i<length; i++)
607
 
    {
608
 
        v = Math.floor(Math.random() * rand_chars.length);
609
 
        str[i] = rand_chars.charAt(v);
610
 
    }
611
 
    return str.join('');
612
 
}
613
 
 
614
 
/** Makes an XMLHttpRequest call to the server.
 
597
/** Makes an asynchronous XMLHttpRequest call to the server.
615
598
 * Sends the XMLHttpRequest object containing the completed response to a
616
599
 * specified callback function.
617
600
 *
618
601
 * \param callback A callback function. Will be called when the response is
619
602
 *      complete. Passed 1 parameter, an XMLHttpRequest object containing the
620
 
 *      completed response. If callback is null this is a syncronous request 
621
 
 *      otherwise this is an asynchronous request.
 
603
 *      completed response.
622
604
 * \param app IVLE app to call (such as "fileservice").
623
605
 * \param path URL path to make the request to, within the application.
624
606
 * \param args Argument object, as described in parse_url and friends.
625
 
 * \param method String; "GET", "POST", "PUT", or "PATCH"
626
 
 * \param content_type String, optional.
 
607
 * \param method String; "GET" or "POST"
 
608
 * \param content_type String, optional. Only applies if method is "POST".
 
609
 *      May be "application/x-www-form-urlencoded" or "multipart/form-data".
627
610
 *      Defaults to "application/x-www-form-urlencoded".
628
611
 */
629
612
function ajax_call(callback, app, path, args, method, content_type)
630
613
{
631
 
    if (!content_type)
 
614
    if (content_type != "multipart/form-data")
632
615
        content_type = "application/x-www-form-urlencoded";
633
616
    path = app_path(app, path);
634
617
    var url;
635
618
    /* A random string, for multipart/form-data
636
619
     * (This is not checked against anywhere else, it is solely defined and
637
620
     * used within this function) */
638
 
    var boundary = random_string(20);
 
621
    var boundary = "48234n334nu7n4n2ynonjn234t683jyh80j";
639
622
    var xhr = new_xmlhttprequest();
640
 
    var asyncronous = callback != null;
641
 
    if (asyncronous)
642
 
    {
643
 
        xhr.onreadystatechange = function()
 
623
    xhr.onreadystatechange = function()
 
624
        {
 
625
            if (xhr.readyState == 4)
644
626
            {
645
 
                if (xhr.readyState == 4)
646
 
                {
647
 
                    callback(xhr);
648
 
                }
 
627
                callback(xhr);
649
628
            }
650
 
    }
 
629
        }
651
630
    if (method == "GET")
652
631
    {
653
632
        /* GET sends the args in the URL */
654
633
        url = build_url({"path": path, "args": args});
655
634
        /* open's 3rd argument = true -> asynchronous */
656
 
        xhr.open(method, url, asyncronous);
 
635
        xhr.open(method, url, true);
657
636
        xhr.send(null);
658
637
    }
659
638
    else
660
639
    {
661
 
        /* POST & PUT & PATCH sends the args in the request body */
 
640
        /* POST sends the args in application/x-www-form-urlencoded */
662
641
        url = encodeURI(path);
663
 
        xhr.open(method, url, asyncronous);
 
642
        xhr.open(method, url, true);
664
643
        var message;
665
644
        if (content_type == "multipart/form-data")
666
645
        {
667
646
            xhr.setRequestHeader("Content-Type",
668
 
                "multipart/form-data; boundary=" + boundary);
 
647
                "multipart/form-data, boundary=" + boundary);
669
648
            message = make_multipart_formdata(args, boundary);
670
649
        }
671
 
        else if (content_type == "application/x-www-form-urlencoded")
 
650
        else
672
651
        {
673
652
            xhr.setRequestHeader("Content-Type", content_type);
674
653
            message = make_query_string(args);
675
654
        }
676
 
        else if (content_type == "application/json")
677
 
        {
678
 
            xhr.setRequestHeader("Content-Type", content_type);
679
 
            message = JSON.stringify(args);
680
 
        }
681
 
        else
682
 
        {
683
 
            xhr.setRequestHeader("Content-Type", content_type);
684
 
            message = args;
685
 
        }
 
655
        xhr.setRequestHeader("Content-Length", message.length);
686
656
        xhr.send(message);
687
657
    }
688
 
    /* Only return the XHR for syncronous requests */
689
 
    if (!asyncronous)
690
 
    { 
691
 
        return xhr;
692
 
    }
693
658
}
694
659
 
695
 
/** Attempts to JSON decodes a response object
696
 
 * If a non-200 response or the JSON decode fails then returns null
697
 
 */
698
 
function decode_response(response)
699
 
{
700
 
    if (response.status == 200)
701
 
    {
702
 
        try
703
 
        {
704
 
            var responseText = response.responseText;
705
 
            return JSON.parse(responseText);
706
 
        }
707
 
        catch (e)
708
 
        {
709
 
            // Pass
710
 
        }
711
 
     }
712
 
    
713
 
     return null;
714
 
}