@@ -41,6 +41,9 @@ var IPython = (function (IPython) {
4141 this . metadata = { } ;
4242 this . _checkpoint_after_save = false ;
4343 this . last_checkpoint = null ;
44+ this . autosave_interval = 0 ;
45+ this . autosave_timer = null ;
46+ this . minimum_autosave_interval = 30000 ;
4447 // single worksheet for now
4548 this . worksheet_metadata = { } ;
4649 this . control_key_active = false ;
@@ -1551,6 +1554,31 @@ var IPython = (function (IPython) {
15511554 return data ;
15521555 } ;
15531556
1557+ /**
1558+ * Start an autosave timer, for periodically saving the notebook.
1559+ *
1560+ * @method autosave_notebook
1561+ * @param {Integer } interval the autosave interval in milliseconds
1562+ */
1563+ Notebook . prototype . autosave_notebook = function ( interval ) {
1564+ var that = this ;
1565+ // clear previous interval, so we don't get simultaneous timers
1566+ if ( this . autosave_timer ) {
1567+ clearInterval ( this . autosave_timer ) ;
1568+ }
1569+
1570+ this . autosave_interval = interval ;
1571+ if ( interval ) {
1572+ this . autosave_timer = setInterval ( function ( ) {
1573+ that . save_notebook ( ) ;
1574+ } , interval ) ;
1575+ $ ( [ IPython . events ] ) . trigger ( "autosave_enabled.Notebook" , interval ) ;
1576+ } else {
1577+ this . autosave_timer = null ;
1578+ $ ( [ IPython . events ] ) . trigger ( "autosave_disabled.Notebook" ) ;
1579+ } ;
1580+ } ;
1581+
15541582 /**
15551583 * Save this notebook on the server.
15561584 *
@@ -1562,15 +1590,19 @@ var IPython = (function (IPython) {
15621590 data . metadata . name = this . notebook_name ;
15631591 data . nbformat = this . nbformat ;
15641592 data . nbformat_minor = this . nbformat_minor ;
1593+
1594+ // time the ajax call for autosave tuning purposes.
1595+ var start = new Date ( ) . getTime ( ) ;
1596+
15651597 // We do the call with settings so we can set cache to false.
15661598 var settings = {
15671599 processData : false ,
15681600 cache : false ,
15691601 type : "PUT" ,
15701602 data : JSON . stringify ( data ) ,
15711603 headers : { 'Content-Type' : 'application/json' } ,
1572- success : $ . proxy ( this . save_notebook_success , this ) ,
1573- error : $ . proxy ( this . save_notebook_error , this )
1604+ success : $ . proxy ( this . save_notebook_success , this , start ) ,
1605+ error : $ . proxy ( this . save_notebook_error , this )
15741606 } ;
15751607 $ ( [ IPython . events ] ) . trigger ( 'notebook_saving.Notebook' ) ;
15761608 var url = this . baseProjectUrl ( ) + 'notebooks/' + this . notebook_id ;
@@ -1581,19 +1613,41 @@ var IPython = (function (IPython) {
15811613 * Success callback for saving a notebook.
15821614 *
15831615 * @method save_notebook_success
1616+ * @param {Integer } start the time when the save request started
15841617 * @param {Object } data JSON representation of a notebook
15851618 * @param {String } status Description of response status
15861619 * @param {jqXHR } xhr jQuery Ajax object
15871620 */
1588- Notebook . prototype . save_notebook_success = function ( data , status , xhr ) {
1621+ Notebook . prototype . save_notebook_success = function ( start , data , status , xhr ) {
15891622 this . dirty = false ;
15901623 $ ( [ IPython . events ] ) . trigger ( 'notebook_saved.Notebook' ) ;
1624+ this . _update_autosave_interval ( start ) ;
15911625 if ( this . _checkpoint_after_save ) {
15921626 this . create_checkpoint ( ) ;
15931627 this . _checkpoint_after_save = false ;
15941628 } ;
15951629 } ;
15961630
1631+ /**
1632+ * update the autosave interval based on how long the last save took
1633+ *
1634+ * @method _update_autosave_interval
1635+ * @param {Integer } timestamp when the save request started
1636+ */
1637+ Notebook . prototype . _update_autosave_interval = function ( start ) {
1638+ var duration = ( new Date ( ) . getTime ( ) - start ) ;
1639+ if ( this . autosave_interval ) {
1640+ // new save interval: higher of 10x save duration or parameter (default 30 seconds)
1641+ var interval = Math . max ( 10 * duration , this . minimum_autosave_interval ) ;
1642+ // round to 10 seconds, otherwise we will be setting a new interval too often
1643+ interval = 10000 * Math . round ( interval / 10000 ) ;
1644+ // set new interval, if it's changed
1645+ if ( interval != this . autosave_interval ) {
1646+ this . autosave_notebook ( interval ) ;
1647+ }
1648+ }
1649+ } ;
1650+
15971651 /**
15981652 * Failure callback for saving a notebook.
15991653 *
0 commit comments