|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
define([ |
|
"jquery", |
|
"base/js/namespace", |
|
"require", |
|
], function ($, Jupyter, requirejs) { |
|
"use strict"; |
|
|
|
var params = { |
|
sticky: false, |
|
play_sound: false |
|
}; |
|
var audio_file = "./notify.mp3"; |
|
|
|
var current_time = function() { |
|
return new Date().getTime() / 1000; |
|
}; |
|
|
|
var start_time = current_time(); |
|
var min_time = 0; |
|
var enabled = false; |
|
var first_start = true; |
|
var busy_kernel = true; |
|
|
|
var add_permissions_list = function () { |
|
var ipython_toolbar = $('#maintoolbar-container'); |
|
var label = $('<span/>').addClass("navbar-text permissions-list").text('Notify:'); |
|
var select = $('<select/>') |
|
.attr('id', 'permissions-select') |
|
.attr('class', 'permissions-list form-control select-xs') |
|
.append($('<option/>') |
|
.attr('value', 'Disabled') |
|
.text('Disabled')); |
|
ipython_toolbar.append(label).append(select); |
|
select.change(function() { |
|
var val = $(this).val(); |
|
if (val == 'Disabled') { |
|
enabled = false; |
|
} else { |
|
enabled = true; |
|
min_time = val; |
|
} |
|
save_state(); |
|
}); |
|
|
|
|
|
var presets = [0, 5, 10, 30]; |
|
for (var i=0; i<presets.length; i++) { |
|
var name = presets[i]; |
|
select.append($('<option/>').attr('value', name).text(name)); |
|
} |
|
|
|
restore_state(); |
|
}; |
|
|
|
var add_permissions_button = function () { |
|
if ($("#permissions-button").length === 0) { |
|
$(Jupyter.toolbar.add_buttons_group([ |
|
Jupyter.keyboard_manager.actions.register ({ |
|
'help' : 'Grant Notification Permissions', |
|
'icon' : 'fa-check', |
|
'handler': ask_permission, |
|
},'grant-notifications-permission', 'notify') |
|
])).find('.btn').attr('id', 'permissions-button'); |
|
} |
|
}; |
|
|
|
var ensure_permission = function () { |
|
ask_permission(); |
|
|
|
if (Notification && Notification.permission !== "granted") { |
|
add_permissions_button(); |
|
add_permissions_list(); |
|
$(".permissions-list").hide(); |
|
} else if (Notification && Notification.permission === "granted") { |
|
add_permissions_list(); |
|
} |
|
}; |
|
|
|
var ask_permission = function () { |
|
if (Notification && Notification.permission !== "granted") { |
|
Notification.requestPermission(function (status) { |
|
if (Notification.permission !== status) { |
|
Notification.permission = status; |
|
} |
|
|
|
if (Notification && Notification.permission === "granted" && $("#permissions-button").length > 0) { |
|
$("#permissions-button").remove(); |
|
$(".permissions-list").show(); |
|
} |
|
}); |
|
} |
|
}; |
|
|
|
var play_notification_sound = function(opts) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
var audio = new Audio(requirejs.toUrl(audio_file)); |
|
audio.play(); |
|
} catch(e) { |
|
console.log('HTML5 Audio not supported in browser.'); |
|
} |
|
}; |
|
|
|
var notify = function () { |
|
var elapsed_time = current_time() - start_time; |
|
if (enabled && !first_start && !busy_kernel && elapsed_time >= min_time) { |
|
var opts = { |
|
body: "Kernel is now idle\n(ran for " + Math.round(elapsed_time) + " secs)", |
|
icon: Jupyter.notebook.base_url + "static/base/images/favicon.ico", |
|
requireInteraction: params.sticky |
|
}; |
|
if (params.play_sound) { |
|
play_notification_sound(opts); |
|
} |
|
var n = new Notification(Jupyter.notebook.notebook_name, opts); |
|
n.onclick = function(event){ window.focus(); } |
|
} |
|
if (first_start) { |
|
first_start = false; |
|
} |
|
}; |
|
|
|
var load_state = function () { |
|
if (!Jupyter.notebook) return; |
|
|
|
if ("notify_time" in Jupyter.notebook.metadata) { |
|
min_time = Jupyter.notebook.metadata.notify_time; |
|
enabled = true; |
|
} |
|
}; |
|
|
|
var save_state = function () { |
|
if (enabled) { |
|
if (Jupyter.notebook.metadata.notify_time !== min_time) { |
|
Jupyter.notebook.metadata.notify_time = min_time; |
|
Jupyter.notebook.set_dirty(); |
|
} |
|
} else { |
|
if (Jupyter.notebook.metadata.hasOwnProperty('notify_time')) { |
|
delete Jupyter.notebook.metadata.notify_time; |
|
Jupyter.notebook.set_dirty(); |
|
} |
|
} |
|
}; |
|
|
|
var restore_state = function () { |
|
load_state(); |
|
|
|
if ($("#permissions-select").length > 0) { |
|
if (!enabled) { |
|
$("#permissions-select").val("Disabled"); |
|
} else { |
|
$("#permissions-select").val(min_time); |
|
} |
|
} |
|
}; |
|
|
|
var setup_notifier = function () { |
|
$([Jupyter.events]).on('kernel_starting.Kernel',function () { |
|
first_start = true; |
|
}); |
|
|
|
$([Jupyter.events]).on('kernel_busy.Kernel',function () { |
|
busy_kernel = true; |
|
start_time = current_time(); |
|
}); |
|
|
|
$([Jupyter.events]).on('kernel_idle.Kernel',function () { |
|
busy_kernel = false; |
|
setTimeout(notify, 500); |
|
}); |
|
}; |
|
|
|
var load_ipython_extension = function () { |
|
return Jupyter.notebook.config.loaded.then(function() { |
|
$.extend(true, params, Jupyter.notebook.config.data.notify); |
|
ensure_permission(); |
|
setup_notifier(); |
|
}); |
|
}; |
|
|
|
return { |
|
load_ipython_extension : load_ipython_extension |
|
}; |
|
|
|
}); |
|
|