diff --git a/usability/chrome_clipboard.js b/usability/chrome_clipboard.js
index 78ad42a..7eb3a75 100644
--- a/usability/chrome_clipboard.js
+++ b/usability/chrome_clipboard.js
@@ -2,137 +2,126 @@
// works with images and notebook cells (MIME-type 'notebook-cell/json')
"using strict";
+define( function () {
+ var load_ipython_extension = function () {
+ if (window.chrome == undefined) return;
-chrome_clipboard = function() {
+ /* http://stackoverflow.com/questions/3231459/create-unique-id-with-javascript */
+ function uniqueid(){
+ // always start with a letter (for DOM friendlyness)
+ var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65));
+ do {
+ // between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
+ var ascicode=Math.floor((Math.random()*42)+48);
+ if (ascicode<58 || ascicode>64){
+ // exclude all chars between : (58) and @ (64)
+ idstr+=String.fromCharCode(ascicode);
+ }
+ } while (idstr.length<32);
- if (window.chrome == undefined) return;
-
- /* http://stackoverflow.com/questions/3231459/create-unique-id-with-javascript */
- function uniqueid(){
- // always start with a letter (for DOM friendlyness)
- var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65));
- do {
- // between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
- var ascicode=Math.floor((Math.random()*42)+48);
- if (ascicode<58 || ascicode>64){
- // exclude all chars between : (58) and @ (64)
- idstr+=String.fromCharCode(ascicode);
- }
- } while (idstr.length<32);
-
- return (idstr);
- }
-
- /* receive url of graphics from websocket */
- dragdrop_event = function(evt){
- console.log("Websock-Event:", evt);
- var obj = $.parseJSON(evt.data);
- if (obj.status == "OK") {
- var new_cell = IPython.notebook.insert_cell_below('markdown');
- var filename = obj.name;
- var str = '
';
- new_cell.set_text(str);
- new_cell.rendered = false;
- new_cell.render();
+ return (idstr);
}
- }
-
- /*
- * override clipboard 'paste' and insert new cell from json data in clipboard
- */
- window.addEventListener('paste', function(event){
- var cell = IPython.notebook.get_selected_cell();
- if (cell.mode == "command" ) {
- event.preventDefault();
- var items = event.clipboardData.items;
- for (var i = 0; i < items.length; i++) {
- console.log("items:", items[i].type);
- if (items[i].type == 'notebook-cell/json') {
- /* json data adds a new notebook cell */
- var data = event.clipboardData.getData('notebook-cell/json');
- var new_cell_data = JSON.parse(data);
- var new_cell = IPython.notebook.insert_cell_below(new_cell_data.cell_type);
- new_cell.fromJSON(new_cell_data);
- } else if (items[i].type.indexOf('image/') !== -1) {
- /* images are transferred to the server as file and linked to */
- var blob = items[i].getAsFile();
- var reader = new FileReader();
- reader.onload = ( function(evt) {
- var filename = uniqueid();
- var msg = JSON.stringify({"type":"file",
- "name":filename,
- "path":IPython.notebook.notebook_path,
- "url" : "",
- "data": evt.target.result});
- IPython.notebook.ws_dragdrop.send(msg);
- event.preventDefault();
- } );
- reader.readAsDataURL(blob);
+
+ send_to_server = function(name,path,msg) {
+ if (name == '') {
+ name = uniqueid() + '.' + msg.match(/data:image\/(\S+);/)[1];
+ }
+ var url = 'http://' + location.host + '/api/contents/' + path + '/' + name;
+ var img = msg.replace(/(^\S+,)/, ''); // strip header
+// console.log("send_to_server:", url, msg);
+ data = {'name': name, 'format':'base64', 'content': img, 'type': 'file'}
+ var settings = {
+ processData : false,
+ cache : false,
+ type : "PUT",
+ dataType : "json",
+ data : JSON.stringify(data),
+ headers : {'Content-Type': 'text/plain'},
+ async : false,
+ success : function (data, status, xhr) {
+ var new_cell = IPython.notebook.insert_cell_below('markdown');
+ var str = '
';
+ new_cell.set_text(str);
+ new_cell.execute();
+ //new_cell.select();
+ },
+ error : function() {console.log('fail'); },
+ };
+ $.ajax(url, settings);
+ }
+ /*
+ * override clipboard 'paste' and insert new cell from json data in clipboard
+ */
+ window.addEventListener('paste', function(event){
+ var cell = IPython.notebook.get_selected_cell();
+ if (cell.mode == "command" ) {
+ event.preventDefault();
+ var items = event.clipboardData.items;
+ for (var i = 0; i < items.length; i++) {
+ console.log("items:", items[i].type);
+ if (items[i].type == 'notebook-cell/json') {
+ /* json data adds a new notebook cell */
+ var data = event.clipboardData.getData('notebook-cell/json');
+ var new_cell_data = JSON.parse(data);
+ var new_cell = IPython.notebook.insert_cell_below(new_cell_data.cell_type);
+ new_cell.fromJSON(new_cell_data);
+ } else if (items[i].type.indexOf('image/') !== -1) {
+ /* images are transferred to the server as file and linked to */
+ var blob = items[i].getAsFile();
+ var reader = new FileReader();
+ reader.onload = ( function(evt) {
+ var filename = '';
+ send_to_server(filename, IPython.notebook.notebook_path, evt.target.result);
+ event.preventDefault();
+ } );
+ reader.readAsDataURL(blob);
+ }
}
}
- }
- });
+ });
- /*
- * override clipboard 'copy' and copy current cell as json and text to clipboard
- */
- window.addEventListener('copy', function(event){
-
- var cell = IPython.notebook.get_selected_cell();
- if (cell.mode == "command") {
- var sel = window.getSelection();
- if (sel.type == "Range") return; /* default: copy marked text */
- event.preventDefault();
- var j = cell.toJSON();
- var json = JSON.stringify(j);
- var text = cell.code_mirror.getValue();
- /* copy cell as json and cell contents as text */
- event.clipboardData.setData('notebook-cell/json',json);
- event.clipboardData.setData("Text", text);
- }
- });
+ /*
+ * override clipboard 'copy' and copy current cell as json and text to clipboard
+ */
+ window.addEventListener('copy', function(event){
+
+ var cell = IPython.notebook.get_selected_cell();
+ if (cell.mode == "command") {
+ var sel = window.getSelection();
+ if (sel.type == "Range") return; /* default: copy marked text */
+ event.preventDefault();
+ var j = cell.toJSON();
+ var json = JSON.stringify(j);
+ var text = cell.code_mirror.getValue();
+ /* copy cell as json and cell contents as text */
+ event.clipboardData.setData('notebook-cell/json',json);
+ event.clipboardData.setData("Text", text);
+ }
+ });
- /*
- * override clipboard 'cut' and copy current cell as json and text to clipboard
- */
- window.addEventListener('cut', function(event){
-
- var cell = IPython.notebook.get_selected_cell();
- if (cell.mode == "command" ) {
- var sel = window.getSelection();
- if (sel.type == "Range") return; /* default: cut marked text */
- event.preventDefault();
- var j = cell.toJSON();
- var json = JSON.stringify(j);
- var text = cell.code_mirror.getValue();
- /* copy cell as json and cell contents as text */
- event.clipboardData.setData('notebook-cell/json',json);
- event.clipboardData.setData("Text", text);
- IPython.notebook.delete_cell(IPython.notebook.find_cell_index(cell));
- }
- });
+ /*
+ * override clipboard 'cut' and copy current cell as json and text to clipboard
+ */
+ window.addEventListener('cut', function(event){
+
+ var cell = IPython.notebook.get_selected_cell();
+ if (cell.mode == "command" ) {
+ var sel = window.getSelection();
+ if (sel.type == "Range") return; /* default: cut marked text */
+ event.preventDefault();
+ var j = cell.toJSON();
+ var json = JSON.stringify(j);
+ var text = cell.code_mirror.getValue();
+ /* copy cell as json and cell contents as text */
+ event.clipboardData.setData('notebook-cell/json',json);
+ event.clipboardData.setData("Text", text);
+ IPython.notebook.delete_cell(IPython.notebook.find_cell_index(cell));
+ }
+ });
+ };
- function callback(out_data)
- {
- var ul = out_data.content.data;
- var webport = eval(ul['text/plain'])
- console.log("webport:",webport);
- var wsUri = "ws://" + document.domain + ":" + webport + "/"+ "websocket";
- var ws_dragdrop = new WebSocket(wsUri);
- IPython.notebook.ws_dragdrop = ws_dragdrop;
- ws_dragdrop.onmessage = dragdrop_event;
- }
+ return {
+ load_ipython_extension : load_ipython_extension,
+ };
+});
- function getport()
- {
- var code = 'drag_and_drop_webport';
- var callbacks = { iopub : { output: callback } };
-
- IPython.notebook.kernel.execute(code, callbacks, {silent: false});
- }
-
-
- $([IPython.events]).on('create.Cell',create_cell);
- $([IPython.events]).on('status_started.Kernel',function() { getport();});
-
-}();
diff --git a/usability/dragdrop/50-start-drag-and-drop.ipy b/usability/dragdrop/50-start-drag-and-drop.ipy
deleted file mode 100644
index 7125f6b..0000000
--- a/usability/dragdrop/50-start-drag-and-drop.ipy
+++ /dev/null
@@ -1,14 +0,0 @@
-# start websocket server for drag-and-drop extension
-
-drag_and_drop_webport = get_ipython().config['DragDrop']['port']
-
-def start_drag_and_drop():
- c = get_ipython()
- nb_dir = get_ipython().config['FileNotebookManager']['notebook_dir']
- newpath = os.path.normpath(c.config['NotebookApp']['extra_static_paths'][0]+'/custom/dragdrop/')
- sys.path.insert(0, newpath)
-
- import drag_and_drop
- drag_and_drop.start_server(drag_and_drop_webport, nb_dir)
-
-start_drag_and_drop()
diff --git a/usability/dragdrop/drag-and-drop.js b/usability/dragdrop/drag-and-drop.js
index 2a64487..70a0dbc 100644
--- a/usability/dragdrop/drag-and-drop.js
+++ b/usability/dragdrop/drag-and-drop.js
@@ -1,80 +1,108 @@
-// add drag&drop functionality
+// Allow drag&drop of images into a notebook
// Tested with Firefox and Chrome
-
"using strict";
+define( function () {
+ var load_ipython_extension = function () {
-drag_and_drop = function() {
-
-
- /* http://stackoverflow.com/questions/3231459/create-unique-id-with-javascript */
- function uniqueid(){
- // always start with a letter (for DOM friendlyness)
- var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65));
- do {
- // between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
- var ascicode=Math.floor((Math.random()*42)+48);
- if (ascicode<58 || ascicode>64){
- // exclude all chars between : (58) and @ (64)
- idstr+=String.fromCharCode(ascicode);
- }
- } while (idstr.length<32);
+ /* http://stackoverflow.com/questions/3231459/create-unique-id-with-javascript */
+ function uniqueid(){
+ // always start with a letter (for DOM friendlyness)
+ var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65));
+ do {
+ // between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
+ var ascicode=Math.floor((Math.random()*42)+48);
+ if (ascicode<58 || ascicode>64){
+ // exclude all chars between : (58) and @ (64)
+ idstr+=String.fromCharCode(ascicode);
+ }
+ } while (idstr.length<32);
- return (idstr);
- }
-
- /* receive url of graphics from websocket */
- dragdrop_event = function(evt){
- console.log("Websock-Event:", evt);
- var obj = $.parseJSON(evt.data);
- if (obj.status == "OK") {
- var new_cell = IPython.notebook.insert_cell_below('markdown');
- var filename = obj.name;
- var str = '
';
- new_cell.set_text(str);
- new_cell.rendered = false;
- new_cell.render();
+ return (idstr);
}
- }
-
- /* the dragover event needs to be canceled to allow firing the drop event */
- window.addEventListener('dragover', function(event){
- if (event.preventDefault) { event.preventDefault(); };
- });
-
- /* allow dropping an image in notebook */
- window.addEventListener('drop', function(event){
- if (IPython.notebook.mode === "edit") return;
-// console.log("drop event x:",event);
- var cell = IPython.notebook.get_selected_cell();
- event.preventDefault();
- if(event.stopPropagation) {event.stopPropagation();}
- if (event.dataTransfer.items != undefined) {
- /* Chrome here */
- var items = event.dataTransfer.items;
- for (var i = 0; i < items.length; i++) {
- /* data coming from local file system, must be an image to allow dropping*/
- if (items[i].kind == 'file' && items[i].type.indexOf('image/') !== -1) {
- var blob = items[i].getAsFile();
- var filename = blob.name;
- var reader = new FileReader();
- reader.onload = ( function(evt) {
- console.log("name:",filename)
- var msg = JSON.stringify({"type":"file",
- "name":filename,
- "path":IPython.notebook.notebook_path,
- "url" : "",
- "data": evt.target.result});
- IPython.notebook.ws_dragdrop.send(msg);
- event.preventDefault();
+
+ send_to_server = function(name,path,msg) {
+ if (name == '') {
+ name = uniqueid() + '.' + msg.match(/data:image\/(\S+);/)[1];
+ }
+ var url = 'http://' + location.host + '/api/contents/' + path + '/' + name;
+ var img = msg.replace(/(^\S+,)/, ''); // strip header
+ //console.log("send_to_server:", url, img);
+ data = {'name': name, 'format':'base64', 'content': img, 'type': 'file'}
+ var settings = {
+ processData : false,
+ cache : false,
+ type : "PUT",
+ dataType : "json",
+ data : JSON.stringify(data),
+ headers : {'Content-Type': 'text/plain'},
+ async : false,
+ success : function (data, status, xhr) {
+ var new_cell = IPython.notebook.insert_cell_below('markdown');
+ var str = '
';
+ new_cell.set_text(str);
+ new_cell.execute();
+ //new_cell.select();
+ },
+ error : function() {console.log('fail'); },
+ };
+ $.ajax(url, settings);
+ }
+
+ /* the dragover event needs to be canceled to allow firing the drop event */
+ window.addEventListener('dragover', function(event){
+ if (event.preventDefault) { event.preventDefault(); };
+ });
+
+ /* allow dropping an image in notebook */
+ window.addEventListener('drop', function(event){
+ // console.log("drop event x:",event);
+ var cell = IPython.notebook.get_selected_cell();
+ event.preventDefault();
+ if(event.stopPropagation) {event.stopPropagation();}
+ if (event.dataTransfer.items != undefined) {
+ /* Chrome here */
+ var items = event.dataTransfer.items;
+ for (var i = 0; i < items.length; i++) {
+ /* data coming from local file system, must be an image to allow dropping*/
+ if (items[i].kind == 'file' && items[i].type.indexOf('image/') !== -1) {
+ var blob = items[i].getAsFile();
+ var filename = blob.name;
+ var reader = new FileReader();
+ reader.onload = ( function(evt) {
+ send_to_server(filename, IPython.notebook.notebook_path, evt.target.result);
+ event.preventDefault();
} );
- reader.readAsDataURL(blob);
- } else if (items[i].kind == 'string') {
- /* data coming from browser */
+ reader.readAsDataURL(blob);
+ } else if (items[i].kind == 'string') {
+ /* data coming from browser */
+ var data = event.dataTransfer.getData('text/plain');
+ if (data[0] == 'd') {
+ url = "";
+ filename = '';
+ } else {
+ url = data;
+ data = "";
+ }
+ /* data coming from browser:
+ * url - image is given as an url
+ * data - image is a base64 blob
+ */
+ //console.log("file"," name:", filename," path:", IPython.notebook.notebook_path," url:", url);
+ send_to_server(filename, IPython.notebook.notebook_path, data);
+ event.preventDefault();
+ return;
+ }
+ }
+ } else {
+ /* Firefox here */
+ var files = event.dataTransfer.files;
+ if (files.length == 0) {
+ var filename = event.dataTransfer.getData('application/x-moz-file-promise-dest-filename');
var data = event.dataTransfer.getData('text/plain');
- if (data[0] == 'd') {
+ if (filename.length == 0) {
url = "";
- filename = uniqueid();
+ filename = '';
} else {
url = data;
data = "";
@@ -83,116 +111,66 @@ drag_and_drop = function() {
* url - image is given as an url
* data - image is a base64 blob
*/
- var msg = JSON.stringify({"type":"url",
- "name":filename,
- "path":IPython.notebook.notebook_path,
- "url" : url,
- "data": data});
- IPython.notebook.ws_dragdrop.send(msg);
+ //console.log("type:",url," name:", filename," path:", IPython.notebook.notebook_path," url:", url);
+ send_to_server(filename, IPython.notebook.notebook_path, data);
event.preventDefault();
return;
- }
- }
- } else {
- /* Firefox here */
- var files = event.dataTransfer.files;
- if (files.length == 0) {
- var filename = event.dataTransfer.getData('application/x-moz-file-promise-dest-filename');
- var data = event.dataTransfer.getData('text/plain');
- if (filename.length == 0) {
- url = "";
- filename = uniqueid();
- } else {
- url = data;
- data = "";
+ }
+ /* data coming from local file system, must be an image to allow dropping*/
+ for (var i=0; i < files.length; i++) {
+ var blob = event.dataTransfer.files[0];
+ if (blob.type.indexOf('image/') !== -1) {
+ var filename = blob.name;
+ var url = event.view.location.origin;
+ var reader = new FileReader();
+ reader.onload = ( function(evt) {
+ //console.log("file"," name:", filename," path:", IPython.notebook.notebook_path," url:", url);
+ send_to_server(filename, IPython.notebook.notebook_path, evt.target.result);
+ event.preventDefault();
+ } );
+ reader.readAsDataURL(blob);
+ }
}
- /* data coming from browser:
- * url - image is given as an url
- * data - image is a base64 blob
- */
- console.log("type:",url," name:", filename," path:", IPython.notebook.notebook_path," url:", url);
- var msg = JSON.stringify({"type":"url",
- "name":filename,
- "path":IPython.notebook.notebook_path,
- "url" : url,
- "data": data});
- IPython.notebook.ws_dragdrop.send(msg);
- event.preventDefault();
- return;
- }
- /* data coming from local file system, must be an image to allow dropping*/
- for (var i=0; i < files.length; i++) {
- var blob = event.dataTransfer.files[0];
- if (blob.type.indexOf('image/') !== -1) {
- var filename = blob.name;
- var url = event.view.location.origin;
- var reader = new FileReader();
- reader.onload = ( function(evt) {
- console.log("file"," name:", filename," path:", IPython.notebook.notebook_path," url:", url);
- var msg = JSON.stringify({"type":"file",
- "name":filename,
- "path":IPython.notebook.notebook_path,
- "url" : url,
- "data": evt.target.result});
- IPython.notebook.ws_dragdrop.send(msg);
- event.preventDefault();
- } );
- reader.readAsDataURL(blob);
- }
- }
- }
- });
-
- /*
- * make sure we do not drop images into a codemirror text field
- */
- checktype = function(cm,event) {
- if (event.dataTransfer.items != undefined)
- {
- evt.codemirrorIgnore = true;
}
- var blob = evt.dataTransfer.files[0];
-
- if (blob.type.indexOf('image/') !== -1) {
- evt.codemirrorIgnore = true;
+ });
+
+ /*
+ * make sure we do not drop images into a codemirror text field
+ */
+ checktype = function(cm,event) {
+ if (event.dataTransfer.items != undefined)
+ {
+ evt.codemirrorIgnore = true;
+ }
+ var blob = evt.dataTransfer.files[0];
+
+ if (blob.type.indexOf('image/') !== -1) {
+ evt.codemirrorIgnore = true;
+ }
+ }
+
+ create_cell = function (event,nbcell,nbindex) {
+ var cell = nbcell.cell;
+ if ((cell instanceof IPython.CodeCell)) {
+ cell.code_mirror.on('drop', checktype);
}
- }
-
- create_cell = function (event,nbcell,nbindex) {
- var cell = nbcell.cell;
- if ((cell instanceof IPython.CodeCell)) {
- cell.code_mirror.on('drop', checktype);
- }
- };
-
- var cells = IPython.notebook.get_cells();
- for(var i in cells){
- var cell = cells[i];
- if ((cell instanceof IPython.CodeCell)) {
- cell.code_mirror.on('drop', checktype);
- }
- };
-
- function callback(out_data)
- {
- var ul = out_data.content.data;
- var webport = eval(ul['text/plain'])
- console.log("Graphics webport:",webport);
- var wsUri = "ws://" + document.domain + ":" + webport + "/"+ "websocket";
- var ws_dragdrop = new WebSocket(wsUri);
- IPython.notebook.ws_dragdrop = ws_dragdrop;
- ws_dragdrop.onmessage = dragdrop_event;
- }
-
- function getport()
- {
- var code = 'drag_and_drop_webport';
- var callbacks = { iopub : { output: callback } };
-
- IPython.notebook.kernel.execute(code, callbacks, {silent: false});
- }
-
+ };
- $([IPython.events]).on('create.Cell',create_cell);
- $([IPython.events]).on('status_started.Kernel',function() { getport();});
-}();
+ var cells = IPython.notebook.get_cells();
+ for(var i in cells){
+ var cell = cells[i];
+ if ((cell instanceof IPython.CodeCell)) {
+ cell.code_mirror.on('drop', checktype);
+ }
+ };
+
+ $([IPython.events]).on('create.Cell',create_cell);
+ };
+
+ return {
+ load_ipython_extension : load_ipython_extension,
+ };
+});
+
+
+
diff --git a/usability/dragdrop/drag-and-drop.py b/usability/dragdrop/drag-and-drop.py
deleted file mode 100644
index 7eaa2fb..0000000
--- a/usability/dragdrop/drag-and-drop.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-# Copyright (C) 2013
-
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-
-@author: juhasch
-"""
-
-"""
-Tornado web server to
- push value received from Pyzmq pull messages
- to web browser using a webscocket connection
-
- Configuration in ipython_notebook_config.py:
- c.DragDrop.port = 8901
-
-"""
-
-import time
-import os.path
-import sys, getopt
-
-import numpy as np
-
-import tornado.web
-import tornado.websocket
-import tornado.ioloop
-
-import random
-import json
-import base64
-import hashlib
-
-from zmq.eventloop import ioloop, zmqstream
-
-webport = 0
-nb_dir = ''
-
-GLOBALS={
- 'sockets': []
-}
-
-# http://stackoverflow.com/questions/273192/check-if-a-directory-exists-and-create-it-if-necessary
-def ensure_dir(f):
- d = os.path.dirname(f)
- if not os.path.exists(d):
- os.makedirs(d)
-
-def md5sum(fname, block_size=2**20):
- f = open(fname, 'rb')
- md5 = hashlib.md5()
- while True:
- data = f.read(block_size)
- if not data:
- break
- md5.update(data)
- f.close()
- return md5.hexdigest()
-
-class WebSocketHandler(tornado.websocket.WebSocketHandler):
- def open(self):
- print "open socket"
- GLOBALS['sockets'].append(self)
-
- def on_close(self):
- print "on_close"
- GLOBALS['sockets'].remove(self)
-
- def on_message(self, message):
- x=json.loads(message)
- print "Data received"
- url = x['url']
- if len(url) == 0:
- print "Base64"
- filename = x['name']
- print "Filename: %s" % filename
-
- path = nb_dir + u'\\' + x['path'] + u'\\images\\'
- print "Path: %s" %path
-
- ensure_dir(path)
- png_b64 = x['data']
- data = png_b64.split(',') # [0] is header, [1] b64 data
- png = base64.b64decode(data[1])
- print "Filename: %s" % filename
- # check if file exists
- if os.path.exists(path+filename):
- print('File %s already exists')
- # compare md5sum
- md5_file = md5sum(path+filename)
-# print('md5sum of file is %s' % md5_file)
- d = hashlib.md5()
- d.update(png)
- md5_websocket = d.hexdigest()
-# print('md5sum of dropped image is is %s' % md5_websocket)
- if md5_file != md5_websocket:
- i = 0
- while True:
-
- if not os.path.exists('%s%0d_%s' % (path, i, filename)):
- break
- filename = '%0d_%s' % (i, filename)
- f = open(path+filename, 'wb')
- f.write(png)
- f.close()
- else:
- f = open(path+filename, 'wb')
- f.write(png)
- f.close()
- status = "OK"
- reply = {"status": status, "name": 'images/' + filename }
- self.write_message(reply)
- else:
- status = "OK"
- reply = {"status": status, "name": url }
- self.write_message(reply)
-
-application = tornado.web.Application([
- (r"/websocket", WebSocketHandler),
-])
-
-
-def main(argv):
- global webport, nb_dir
- #try:
- opts, args = getopt.getopt(argv,"hp:d:",["port=","directory="])
- if opts == []:
- print 'drag-and-drop.py -p -d '
- sys.exit(2)
-
- for opt, arg in opts:
- if opt == '-h':
- print 'drag-and-drop.py -p -d '
- sys.exit()
- elif opt in ("-p", "--port"):
- webport = int(arg)
- elif opt in ("-d", "--directory"):
- nb_dir = arg
-
-
- print 'webport is "', webport
- print 'notebook directory is "', nb_dir
-
- if webport < 1000 or webport > 65535:
- print('Illegal webport adress %d' % webport)
- sys.exit(2)
-
- if not os.path.exists(nb_dir):
- print('Directory %s does not exist' % nb_dir)
- sys.exit(2)
-
- ioloop.install()
- try:
- application.listen(webport)
- except:
- print('Port %d already in use!' % webport)
- exit()
- main_loop = tornado.ioloop.IOLoop.instance()
- main_loop.start()
-
-if __name__ == "__main__":
- main(sys.argv[1:])
diff --git a/usability/dragdrop/drag_and_drop.py b/usability/dragdrop/drag_and_drop.py
deleted file mode 100644
index c06d146..0000000
--- a/usability/dragdrop/drag_and_drop.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-# Copyright (C) 2014
-# Distributed under the terms of the BSD License.
-"""
-
-"""
-Tornado websocket server to save images received from web browser and reply
-with URL of stored image.
-This is required for drag&drop of images in the IPython notebook
-
-The websocket port can be configured in ipython_notebook_config.py:
- c.DragDrop.port = 8901
-
-"""
-
-import time
-import os.path
-import sys, getopt
-
-import numpy as np
-
-import tornado.web
-import tornado.websocket
-import tornado.ioloop
-
-import random
-import json
-import base64
-import hashlib
-from multiprocessing import Process
-from zmq.eventloop import ioloop, zmqstream
-
-webport = 0
-nb_dir = ''
-
-GLOBALS={
- 'sockets': []
-}
-
-# http://stackoverflow.com/questions/273192/check-if-a-directory-exists-and-create-it-if-necessary
-def ensure_dir(f):
- d = os.path.dirname(f)
- if not os.path.exists(d):
- os.makedirs(d)
-
-def md5sum(fname, block_size=2**20):
- f = open(fname, 'rb')
- md5 = hashlib.md5()
- while True:
- data = f.read(block_size)
- if not data:
- break
- md5.update(data)
- f.close()
- return md5.hexdigest()
-
-class WebSocketHandler(tornado.websocket.WebSocketHandler):
- """ Handle websocket connections from web browser
- """
- def open(self):
- GLOBALS['sockets'].append(self)
-
- def on_close(self):
- GLOBALS['sockets'].remove(self)
-
- def on_message(self, message):
- """ Receive image from web browser
- Save it to the local 'images' directory under it's name.
- If filename already exists, md5-check if identical, otherwise rename.
- If no filename is given, create unique ID.
- """
- x=json.loads(message)
- url = x['url']
- eventtype = x['type']
-
- if eventtype == 'file':
- filename = x['name']
- path = nb_dir + u'\\' + x['path'] + u'\\images\\'
- ensure_dir(path)
- data = x['data'].split(',') # [0] is header, [1] b64 data
- png = base64.b64decode(data[1])
- # check if file exists: skip if identical, rename if new
- if os.path.exists(path+filename):
-# print('File %s already exists' % filename)
- # compare md5sum
- md5_file = md5sum(path+filename)
- d = hashlib.md5()
- d.update(png)
- md5_websocket = d.hexdigest()
- if md5_file != md5_websocket:
- i = 0
- while True:
- if not os.path.exists('%s%0d_%s' % (path, i, filename)):
- break
- filename = '%0d_%s' % (i, filename)
- f = open(path+filename, 'wb')
- f.write(png)
- f.close()
- else:
- f = open(path+filename, 'wb')
- f.write(png)
- f.close()
- status = "OK"
- #reply = {"status": status, "name": 'images/' + filename }
- # send url instead of file path, otherwise it won't work for nbconvert
- url_path = url + '/notebooks' + x['path'] + '/images/' + filename
- reply = {"status": status, "name": url_path}
- self.write_message(reply)
- else:
- # just reply already existing url
- status = "OK"
- reply = {"status": status, "name": url }
- self.write_message(reply)
-
-application = tornado.web.Application([
- (r"/websocket", WebSocketHandler),
-])
-
-
-def websocket_server(webport, nbdir):
- global nb_dir
- nb_dir = nbdir
- ioloop.install()
- try:
- application.listen(webport)
- except:
-# print('Port %d already in use!' % webport)
- sys.exit(2)
- main_loop = tornado.ioloop.IOLoop.instance()
- main_loop.start()
-
-
-def start_server(webport,nb_dir):
- print('webport is %s' % webport)
- print('notebook directory is %s' % nb_dir)
-
- if webport < 1000 or webport > 65535:
- print('Illegal webport adress %d' % webport)
- sys.exit(2)
-
- if not os.path.exists(nb_dir):
- print('Directory %s does not exist' % nb_dir)
- sys.exit(2)
-
- p = Process(target=websocket_server, args=(webport,nb_dir))
- p.start()