diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000..7616293 --- /dev/null +++ b/Info.plist @@ -0,0 +1,103 @@ + + + + + BuildMachineOSBuild + 12C3006 + CFBundleDevelopmentRegion + en + CFBundleDisplayName + IPyApp + CFBundleDocumentTypes + + + CFBundleTypeIconFile + nw.icns + CFBundleTypeName + node-webkit App + CFBundleTypeRole + Viewer + LSHandlerRank + Owner + LSItemContentTypes + + com.intel.nw.app + + + + CFBundleTypeName + Folder + CFBundleTypeOSTypes + + fold + + CFBundleTypeRole + Viewer + LSHandlerRank + None + + + CFBundleExecutable + node-webkit + CFBundleIconFile + app.nw/app.icns + CFBundleIdentifier + org.ipython.ipyapp + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + IPyApp + CFBundlePackageType + APPL + CFBundleShortVersionString + 32.0.1700.107 + CFBundleVersion + 1700.107 + DTSDKBuild + 11E52 + DTSDKName + macosx10.7 + DTXcode + 0452 + DTXcodeBuild + 4G2008a + LSFileQuarantineEnabled + + LSMinimumSystemVersion + 10.6.0 + NSPrincipalClass + NSApplication + NSSupportsAutomaticGraphicsSwitching + + SCMRevision + 239963 + UTExportedTypeDeclarations + + + UTTypeConformsTo + + com.pkware.zip-archive + + UTTypeDescription + node-webkit App + UTTypeIconFile + nw.icns + UTTypeIdentifier + com.intel.nw.app + UTTypeReferenceURL + https://github.com/rogerwang/node-webkit/wiki/How-to-package-and-distribute-your-apps + UTTypeTagSpecification + + com.apple.ostype + node-webkit + public.filename-extension + + nw + + public.mime-type + application/x-node-webkit-app + + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5c420da --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2014 Preston Holmes + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..94d5873 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# IPyApp + + +This package currently serves as a proof of concept for bundling IPython notebook into a standalone executable application. + +There are basically two components to bundling this. The first is to take Python and IPython and any other python libraries, and bundle them into a platform executable. + +Then wrap this executable in a [node-webkit](https://github.com/rogerwang/node-webkit) app to provide the web UI to the notebook server. + +Current this POC is limited to Mac OS using [Py2App](https://pypi.python.org/pypi/py2app/). + +However node-webkit is cross platform, so as long as an executable can be created (ie py2exe), then this general approach should be cross platform. + +## How to create the bundle + +First, create a virtualenv and install IPython, py2app and any packages you want included. + +Then cd into the py2app directory and build the executable + + rm -r build dist; python setup.py py2app --packages IPython + +Include any additional --packages + +This will create a nb.app executable in the dist folder. Copy this into the app.nw folder. + +Next download the [node-webkit binary](https://github.com/rogerwang/node-webkit#downloads) + +Right click on the node-webkit.app binary that you downloaded and choose "Show Package Contents" + +Copy the provided Info.plist file into the Contents folder of the package, and copy the app.nw folder into the Contents/Resources folder of the package. + +You should now be able to launch the app by double clicking. + +The layout of the app should look something like: + + + + IPyApp.app + └── Contents + ├── Frameworks + │   ├── crash_inspector + │   ├── node-webkit\ Framework.framework + │   │   ├── Libraries + │   │   ├── Resources + │   │   ├── node-webkit\ Framework + │   │   ├── node-webkit\ Framework.TOC + │   │   └── node-webkit\ Framework.tmp + │   ├── node-webkit\ Helper\ EH.app + │   │   └── Contents + │   ├── node-webkit\ Helper\ NP.app + │   │   └── Contents + │   └── node-webkit\ Helper.app + │   └── Contents + ├── Info.plist + ├── MacOS + │   └── node-webkit + ├── PkgInfo + └── Resources + ├── app.nw + │   ├── app.icns + │   ├── IPythonConsole.png + │   ├── nb.app + │   ├── node_modules + │   ├── package.json + │   ├── start.html + │   └── test.js + └── nw.icns + + + +### Similar projects: + +* https://github.com/liyanage/ipython-notebook - A similar project that uses node-webkit, but does not bundle the python environment, but provides an alternative to opening in the browser. +* https://github.com/mangecoeur/ipython-desktop - A project to embed IPython notebook into a native Mac App using OS X only web ui views + + + diff --git a/app.nw/IPythonConsole.png b/app.nw/IPythonConsole.png new file mode 100644 index 0000000..06ea47b Binary files /dev/null and b/app.nw/IPythonConsole.png differ diff --git a/app.nw/app.icns b/app.nw/app.icns new file mode 100644 index 0000000..37db452 Binary files /dev/null and b/app.nw/app.icns differ diff --git a/app.nw/node_modules/sleep/.jshintignore b/app.nw/node_modules/sleep/.jshintignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/app.nw/node_modules/sleep/.jshintignore @@ -0,0 +1 @@ +node_modules diff --git a/app.nw/node_modules/sleep/.jshintrc b/app.nw/node_modules/sleep/.jshintrc new file mode 100644 index 0000000..fde1d96 --- /dev/null +++ b/app.nw/node_modules/sleep/.jshintrc @@ -0,0 +1,33 @@ +{ + "predef": [ + "ve", + + "setImmediate", + + "QUnit" + ], + + "bitwise": true, + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": true, + "newcap": true, + "noarg": true, + "noempty": true, + "nonew": true, + "regexp": false, + "undef": true, + "strict": false, + "trailing": true, + "unused":true, + + "smarttabs": true, + "multistr": true, + + "node": true, + + "nomen": false, + "loopfunc": true + //"onevar": true +} diff --git a/app.nw/node_modules/sleep/.npmignore b/app.nw/node_modules/sleep/.npmignore new file mode 100644 index 0000000..26fefbc --- /dev/null +++ b/app.nw/node_modules/sleep/.npmignore @@ -0,0 +1,4 @@ +.lock-wscript +build +node_modules +lib/binding diff --git a/app.nw/node_modules/sleep/README.md b/app.nw/node_modules/sleep/README.md new file mode 100644 index 0000000..ddaa569 --- /dev/null +++ b/app.nw/node_modules/sleep/README.md @@ -0,0 +1,25 @@ +sleep +===== + +Add `sleep()` and `usleep()` to nodejs. + +This is mainly useful for debugging. + +**Sleep will block execution of all javascript!** +=================================================== + +On windows the module will fall back to a while loop which will use 100% CPU! + +Usage +----- + +`var sleep = require('sleep');` + +* `sleep.sleep(n)`: sleep for n seconds +* `sleep.usleep(n)`: sleep for n microseconds (1 second is 1000000 microseconds) + +Update +------ + +Now bulids properly using node-gyp :) + diff --git a/app.nw/node_modules/sleep/binding.gyp b/app.nw/node_modules/sleep/binding.gyp new file mode 100644 index 0000000..4f61533 --- /dev/null +++ b/app.nw/node_modules/sleep/binding.gyp @@ -0,0 +1,10 @@ +{ + 'targets': [ + { + 'target_name': 'node_sleep', + 'sources': [ + 'sleep.cc', + ], + } + ] +} diff --git a/app.nw/node_modules/sleep/build-util/tools.js b/app.nw/node_modules/sleep/build-util/tools.js new file mode 100644 index 0000000..2e8c79b --- /dev/null +++ b/app.nw/node_modules/sleep/build-util/tools.js @@ -0,0 +1,88 @@ +var http = require('http'); +var url = require('url'); + +function download(from,options,callback) { + options = options || {}; + var uri = url.parse(from); + var req = http.request(uri); + req.on('response', function(res){ + // needed for end to be called + res.resume(); + if (res.statusCode !== 200) { + return callback(new Error('Server returned '+ res.statusCode)); + } + function returnBuffer() { + // todo - use http://nodejs.org/api/buffer.html#buffer_class_method_buffer_concat_list_totallength + for (var length = 0, i = 0; i < out.length; ++i) { + length += out[i].length; + } + var result = new Buffer(length); + for (var pos = 0, j = 0; j < out.length; ++j) { + out[j].copy(result, pos); + pos += out[j].length; + } + return callback(null,result); + } + var out = []; + res.on('data', function(chunk) { + out.push(chunk); + }); + res.on('end', function(){ + returnBuffer(); + }); + res.on('close', function(){ + returnBuffer(); + }); + }); + req.on('error', function(err){ + callback(err); + }); + req.end(); +} + + +function parse_args(_args, opts) { + // first split them like npm returns + var args = [], next_arg; + _args.forEach(function(a) { + var parts = a.split('='); + parts.forEach(function(p) { + args.push(p); + }); + }); + // respect flags passed to npm install + if (process.env.npm_config_argv) { + var argv_obj = JSON.parse(process.env.npm_config_argv); + args = args.concat(argv_obj.cooked.slice(1)); + } + var debug = (args.indexOf('--debug') > -1); + if (debug) { opts.configuration = 'Debug'; } + + opts.stage = (args.indexOf('--stage') > -1); + if (opts.stage) { + opts.force = true; + } else { + var from_source = args.indexOf('--build-from-source'); + if ( from_source > -1) { + // no specific module name passed + next_arg = args[from_source+1]; + if (!next_arg || next_arg.indexOf('--') <= 0) { + opts.force = true; + } else if (next_arg === 'sqlite3'){ + opts.force = true; + } + } + } + var target_arch = args.indexOf('--target_arch'); + if (target_arch > -1) { + next_arg = args[target_arch+1]; + if (next_arg && next_arg.indexOf('--') < 0) { + opts.target_arch = next_arg; + } + } + opts.args = args; + return opts; +} + +module.exports.parse_args = parse_args; +module.exports.download = download; diff --git a/app.nw/node_modules/sleep/build.js b/app.nw/node_modules/sleep/build.js new file mode 100644 index 0000000..b81b116 --- /dev/null +++ b/app.nw/node_modules/sleep/build.js @@ -0,0 +1,113 @@ +// we borrow some build system tooling from node-sqlite3 +var package_json = require('./package.json'); +var Binary = require('./lib/binary_name.js').Binary; +var util = require('./build-util/tools.js'); + +var cp = require('child_process'); +var fs = require('fs'); +var mkdirp = require('mkdirp'); +var path = require('path'); + +var opts = { + name: 'node_sleep', + force: false, + stage: false, + configuration: 'Release', + target_arch: process.arch, + platform: process.platform, + uri: 'http://node-sleep.s3.amazonaws.com/', + tool: 'node-gyp', + paths: {} +}; + +function log(msg) { + console.log('['+package_json.name+']: ' + msg); +} + +// only for dev +function log_debug(msg) { + log(msg); +} + +function done(err) { + if (err) { + log(err); + process.exit(1); + } + process.exit(0); +} + +function build(opts,callback) { + var shell_cmd = opts.tool; + if (opts.tool === 'node-gyp' && process.platform === 'win32') { + shell_cmd = 'node-gyp.cmd'; + } + var shell_args = ['rebuild'].concat(opts.args); + var cmd = cp.spawn(shell_cmd,shell_args, {cwd: undefined, env: process.env, customFds: [ 0, 1, 2]}); + cmd.on('error', function (err) { + if (err) { + return callback(new Error("Failed to execute '" + shell_cmd + ' ' + shell_args.join(' ') + "' (" + err + ")")); + } + }); + // exit not close to support node v0.6.x + cmd.on('exit', function (code) { + if (code !== 0) { + return callback(new Error("Failed to execute '" + shell_cmd + ' ' + shell_args.join(' ') + "' (" + code + ")")); + } + move(opts,callback); + }); +} + +function move(opts,callback) { + try { + fs.statSync(opts.paths.build_module_path); + } catch (ex) { + return callback(new Error('Build succeeded but target not found at ' + opts.paths.build_module_path)); + } + try { + mkdirp.sync(path.dirname(opts.paths.runtime_module_path)); + log('Created: ' + path.dirname(opts.paths.runtime_module_path)); + } catch (err) { + log_debug(err); + } + fs.renameSync(opts.paths.build_module_path,opts.paths.runtime_module_path); + if (opts.stage) { + try { + mkdirp.sync(path.dirname(opts.paths.staged_module_file_name)); + log('Created: ' + path.dirname(opts.paths.staged_module_file_name)); + } catch (err) { + log_debug(err); + } + fs.writeFileSync(opts.paths.staged_module_file_name,fs.readFileSync(opts.paths.runtime_module_path)); + // drop build metadata into build folder + var metapath = path.join(path.dirname(opts.paths.staged_module_file_name),'build-info.json'); + // more build info + opts.date = new Date(); + opts.node_features = process.features; + opts.versions = process.versions; + opts.config = process.config; + opts.execPath = process.execPath; + fs.writeFileSync(metapath,JSON.stringify(opts,null,2)); + //tarball(opts,callback); + return callback(); + } else { + log('Installed in ' + opts.paths.runtime_module_path + ''); + return callback(); + } +} + +function rel(p) { + return path.relative(process.cwd(),p); +} + +// build it! +opts = util.parse_args(process.argv.slice(2), opts); +opts.binary = new Binary(opts); +var versioned = opts.binary.getRequirePath(); +opts.paths.runtime_module_path = rel(path.join(__dirname, 'lib', versioned)); +opts.paths.runtime_folder = rel(path.join(__dirname, 'lib', 'binding',opts.binary.configuration)); +var staged_module_path = path.join(__dirname, 'stage', opts.binary.getModuleAbi(), opts.binary.getBasePath()); +opts.paths.staged_module_file_name = rel(path.join(staged_module_path,opts.binary.filename())); +opts.paths.build_module_path = rel(path.join(__dirname, 'build', opts.binary.configuration, opts.binary.filename())); + +build(opts, done); diff --git a/app.nw/node_modules/sleep/lib/binary_name.js b/app.nw/node_modules/sleep/lib/binary_name.js new file mode 100644 index 0000000..34f1173 --- /dev/null +++ b/app.nw/node_modules/sleep/lib/binary_name.js @@ -0,0 +1,58 @@ + +var path = require('path'); + +var Binary = function(options) { + options = options || {}; + var package_json = options.package_json || require('../package.json'); + this.name = options.name || 'binding'; + this.configuration = options.configuration || 'Release'; + this.uri = options.uri || 'http://'+this.name+'.s3.amazonaws.com/'; + this.module_maj_min = package_json.version.split('.').slice(0,2).join('.'); + this.module_abi = package_json.abi; + this.platform = options.platform || process.platform; + this.target_arch = options.target_arch || process.arch; + if (process.versions.modules) { + // added in >= v0.10.4 and v0.11.7 + // https://github.com/joyent/node/commit/ccabd4a6fa8a6eb79d29bc3bbe9fe2b6531c2d8e + this.node_abi = 'node-v' + (+process.versions.modules); + } else { + this.node_abi = 'v8-' + process.versions.v8.split('.').slice(0,2).join('.'); + } +}; + +Binary.prototype.filename = function() { + return this.name + '.node'; +}; + +Binary.prototype.compression = function() { + return '.tar.gz'; +}; + +Binary.prototype.getBasePath = function() { + return this.node_abi + + '-' + this.platform + + '-' + this.target_arch; +}; + +Binary.prototype.getRequirePath = function(configuration) { + return '../' + path.join('Build', + configuration || this.configuration, + this.filename()); +}; + +Binary.prototype.getModuleAbi = function() { + return this.name + '-v' + this.module_maj_min + '.' + this.module_abi; +}; + +Binary.prototype.getArchivePath = function() { + return this.getModuleAbi() + + '-' + + this.getBasePath() + + this.compression(); +}; + +Binary.prototype.getRemotePath = function() { + return this.uri+this.configuration+'/'+this.getArchivePath(); +}; + +module.exports.Binary = Binary; diff --git a/app.nw/node_modules/sleep/lib/index.js b/app.nw/node_modules/sleep/lib/index.js new file mode 100644 index 0000000..80e7572 --- /dev/null +++ b/app.nw/node_modules/sleep/lib/index.js @@ -0,0 +1,35 @@ +var Binary = require('./binary_name.js').Binary; +var binary = new Binary({name:'node_sleep'}); +var binding; +try { + binding = require(binary.getRequirePath('Debug')); +} catch (err) { /* ignore */ } +if (!binding) { + try { + binding = require(binary.getRequirePath('Release')); + } catch (err) { /* ignore */ } +} +if (!binding) { + console.error("Using busy loop implementation of sleep."); + binding = { + sleep: function(s) { + var e = new Date().getTime() + (s * 1000); + + while (new Date().getTime() <= e) { + /* do nothing, but burn a lot of CPU while doing so */ + /* jshint noempty: false */ + } + }, + + usleep: function(s) { + var e = new Date().getTime() + (s / 1000); + + while (new Date().getTime() <= e) { + /* do nothing, but burn a lot of CPU while doing so */ + /* jshint noempty: false */ + } + } + }; +} + +module.exports = binding; diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/.npmignore b/app.nw/node_modules/sleep/node_modules/mkdirp/.npmignore new file mode 100644 index 0000000..9303c34 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/.travis.yml b/app.nw/node_modules/sleep/node_modules/mkdirp/.travis.yml new file mode 100644 index 0000000..84fd7ca --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.6 + - 0.8 + - 0.9 diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/LICENSE b/app.nw/node_modules/sleep/node_modules/mkdirp/LICENSE new file mode 100644 index 0000000..432d1ae --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/LICENSE @@ -0,0 +1,21 @@ +Copyright 2010 James Halliday (mail@substack.net) + +This project is free software released under the MIT/X11 license: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/examples/pow.js b/app.nw/node_modules/sleep/node_modules/mkdirp/examples/pow.js new file mode 100644 index 0000000..e692421 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/examples/pow.js @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/index.js b/app.nw/node_modules/sleep/node_modules/mkdirp/index.js new file mode 100644 index 0000000..fda6de8 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/index.js @@ -0,0 +1,82 @@ +var path = require('path'); +var fs = require('fs'); + +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, mode, f, made) { + if (typeof mode === 'function' || mode === undefined) { + f = mode; + mode = 0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + if (typeof mode === 'string') mode = parseInt(mode, 8); + p = path.resolve(p); + + fs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), mode, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, mode, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + fs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); +} + +mkdirP.sync = function sync (p, mode, made) { + if (mode === undefined) { + mode = 0777 & (~process.umask()); + } + if (!made) made = null; + + if (typeof mode === 'string') mode = parseInt(mode, 8); + p = path.resolve(p); + + try { + fs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), mode, made); + sync(p, mode, made); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = fs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } + + return made; +}; diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/package.json b/app.nw/node_modules/sleep/node_modules/mkdirp/package.json new file mode 100644 index 0000000..59d66e1 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/package.json @@ -0,0 +1,38 @@ +{ + "name": "mkdirp", + "description": "Recursively mkdir, like `mkdir -p`", + "version": "0.3.5", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "main": "./index", + "keywords": [ + "mkdir", + "directory" + ], + "repository": { + "type": "git", + "url": "http://github.com/substack/node-mkdirp.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "devDependencies": { + "tap": "~0.4.0" + }, + "license": "MIT", + "readme": "# mkdirp\n\nLike `mkdir -p`, but in node.js!\n\n[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)\n\n# example\n\n## pow.js\n\n```js\nvar mkdirp = require('mkdirp');\n \nmkdirp('/tmp/foo/bar/baz', function (err) {\n if (err) console.error(err)\n else console.log('pow!')\n});\n```\n\nOutput\n\n```\npow!\n```\n\nAnd now /tmp/foo/bar/baz exists, huzzah!\n\n# methods\n\n```js\nvar mkdirp = require('mkdirp');\n```\n\n## mkdirp(dir, mode, cb)\n\nCreate a new directory and any necessary subdirectories at `dir` with octal\npermission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\n`cb(err, made)` fires with the error or the first directory `made`\nthat had to be created, if any.\n\n## mkdirp.sync(dir, mode)\n\nSynchronously create a new directory and any necessary subdirectories at `dir`\nwith octal permission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\nReturns the first directory that had to be created, if any.\n\n# install\n\nWith [npm](http://npmjs.org) do:\n\n```\nnpm install mkdirp\n```\n\n# license\n\nMIT\n", + "readmeFilename": "readme.markdown", + "bugs": { + "url": "https://github.com/substack/node-mkdirp/issues" + }, + "homepage": "https://github.com/substack/node-mkdirp", + "_id": "mkdirp@0.3.5", + "dist": { + "shasum": "d7def7349d674800fac371eef2ecaff11c41ccde" + }, + "_from": "mkdirp@~0.3.5", + "_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" +} diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/readme.markdown b/app.nw/node_modules/sleep/node_modules/mkdirp/readme.markdown new file mode 100644 index 0000000..83b0216 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/readme.markdown @@ -0,0 +1,63 @@ +# mkdirp + +Like `mkdir -p`, but in node.js! + +[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp) + +# example + +## pow.js + +```js +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); +``` + +Output + +``` +pow! +``` + +And now /tmp/foo/bar/baz exists, huzzah! + +# methods + +```js +var mkdirp = require('mkdirp'); +``` + +## mkdirp(dir, mode, cb) + +Create a new directory and any necessary subdirectories at `dir` with octal +permission string `mode`. + +If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +`cb(err, made)` fires with the error or the first directory `made` +that had to be created, if any. + +## mkdirp.sync(dir, mode) + +Synchronously create a new directory and any necessary subdirectories at `dir` +with octal permission string `mode`. + +If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +Returns the first directory that had to be created, if any. + +# install + +With [npm](http://npmjs.org) do: + +``` +npm install mkdirp +``` + +# license + +MIT diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/chmod.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/chmod.js new file mode 100644 index 0000000..520dcb8 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/chmod.js @@ -0,0 +1,38 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +test('chmod-pre', function (t) { + var mode = 0744 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.equal(stat && stat.mode & 0777, mode, 'should be 0744'); + t.end(); + }); + }); +}); + +test('chmod', function (t) { + var mode = 0755 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.end(); + }); + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/clobber.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/clobber.js new file mode 100644 index 0000000..0eb7099 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/clobber.js @@ -0,0 +1,37 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +// a file in the way +var itw = ps.slice(0, 3).join('/'); + + +test('clobber-pre', function (t) { + console.error("about to write to "+itw) + fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.'); + + fs.stat(itw, function (er, stat) { + t.ifError(er) + t.ok(stat && stat.isFile(), 'should be file') + t.end() + }) +}) + +test('clobber', function (t) { + t.plan(2); + mkdirp(file, 0755, function (err) { + t.ok(err); + t.equal(err.code, 'ENOTDIR'); + t.end(); + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/mkdirp.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/mkdirp.js new file mode 100644 index 0000000..b07cd70 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/mkdirp.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('woo', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm.js new file mode 100644 index 0000000..23a7abb --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('async perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); + +test('async root perm', function (t) { + mkdirp('/tmp', 0755, function (err) { + if (err) t.fail(err); + t.end(); + }); + t.end(); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm_sync.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm_sync.js new file mode 100644 index 0000000..f685f60 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/perm_sync.js @@ -0,0 +1,39 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json'; + + mkdirp.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); + +test('sync root perm', function (t) { + t.plan(1); + + var file = '/tmp'; + mkdirp.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/race.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/race.js new file mode 100644 index 0000000..96a0447 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/race.js @@ -0,0 +1,41 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('race', function (t) { + t.plan(4); + var ps = [ '', 'tmp' ]; + + for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); + } + var file = ps.join('/'); + + var res = 2; + mk(file, function () { + if (--res === 0) t.end(); + }); + + mk(file, function () { + if (--res === 0) t.end(); + }); + + function mk (file, cb) { + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + if (cb) cb(); + } + }) + }) + }); + } +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/rel.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/rel.js new file mode 100644 index 0000000..7985824 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/rel.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('rel', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var cwd = process.cwd(); + process.chdir('/tmp'); + + var file = [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + process.chdir(cwd); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/return.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/return.js new file mode 100644 index 0000000..bce68e5 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/return.js @@ -0,0 +1,25 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, '/tmp/' + x); + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, null); + }); + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/return_sync.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/return_sync.js new file mode 100644 index 0000000..7c222d3 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/return_sync.js @@ -0,0 +1,24 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + // Note that this will throw on failure, which will fail the test. + var made = mkdirp.sync(file); + t.equal(made, '/tmp/' + x); + + // making the same file again should have no effect. + made = mkdirp.sync(file); + t.equal(made, null); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/root.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/root.js new file mode 100644 index 0000000..97ad7a2 --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/root.js @@ -0,0 +1,18 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('root', function (t) { + // '/' on unix, 'c:/' on windows. + var file = path.resolve('/'); + + mkdirp(file, 0755, function (err) { + if (err) throw err + fs.stat(file, function (er, stat) { + if (er) throw er + t.ok(stat.isDirectory(), 'target is a directory'); + t.end(); + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/sync.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/sync.js new file mode 100644 index 0000000..7530cad --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/sync.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file, 0755); + } catch (err) { + t.fail(err); + return t.end(); + } + + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }); + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask.js new file mode 100644 index 0000000..64ccafe --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('implicit mode from umask', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0777 & (~process.umask())); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask_sync.js b/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask_sync.js new file mode 100644 index 0000000..35bd5cb --- /dev/null +++ b/app.nw/node_modules/sleep/node_modules/mkdirp/test/umask_sync.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('umask sync modes', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file); + } catch (err) { + t.fail(err); + return t.end(); + } + + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, (0777 & (~process.umask()))); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }); + }); +}); diff --git a/app.nw/node_modules/sleep/package.json b/app.nw/node_modules/sleep/package.json new file mode 100644 index 0000000..644c149 --- /dev/null +++ b/app.nw/node_modules/sleep/package.json @@ -0,0 +1,46 @@ +{ + "name": "sleep", + "version": "1.1.4", + "main": "./lib/index.js", + "description": "Add sleep() and usleep() to nodejs", + "homepage": "http://github.com/ErikDubbelboer/node-sleep", + "author": { + "name": "Erik Dubbelboer", + "email": "erik@dubbelboer.com" + }, + "engines": { + "node": ">=0.4.0" + }, + "keywords": [ + "sleep", + "usleep" + ], + "repository": { + "type": "git", + "url": "https://github.com/ErikDubbelboer/node-sleep.git" + }, + "repositories": [ + { + "type": "git", + "url": "https://github.com/ErikDubbelboer/node-sleep.git" + } + ], + "dependencies": { + "mkdirp": "~0.3.5" + }, + "scripts": { + "install": "node build.js || nodejs build.js" + }, + "gypfile": true, + "readme": "sleep\n=====\n\nAdd `sleep()` and `usleep()` to nodejs.\n\nThis is mainly useful for debugging.\n\n**Sleep will block execution of all javascript!**\n===================================================\n\nOn windows the module will fall back to a while loop which will use 100% CPU!\n\nUsage\n-----\n\n`var sleep = require('sleep');`\n\n* `sleep.sleep(n)`: sleep for n seconds\n* `sleep.usleep(n)`: sleep for n microseconds (1 second is 1000000 microseconds)\n\nUpdate\n------\n\nNow bulids properly using node-gyp :)\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/ErikDubbelboer/node-sleep/issues" + }, + "_id": "sleep@1.1.4", + "dist": { + "shasum": "514d79e04ea79ed6e81761f4ca5c4c9aa866f169" + }, + "_from": "sleep@", + "_resolved": "https://registry.npmjs.org/sleep/-/sleep-1.1.4.tgz" +} diff --git a/app.nw/node_modules/sleep/sleep.cc b/app.nw/node_modules/sleep/sleep.cc new file mode 100644 index 0000000..4faaa12 --- /dev/null +++ b/app.nw/node_modules/sleep/sleep.cc @@ -0,0 +1,70 @@ +#ifndef BUILDING_NODE_EXTENSION +#define BUILDING_NODE_EXTENSION +#endif // BUILDING_NODE_EXTENSION + +#include +#include + +#ifdef _WIN32 || _WIN64 +unsigned int sleep(unsigned int seconds) +{ + Sleep(seconds * 1000); + return 0; +} +int usleep(unsigned __int64 usec) +{ + LARGE_INTEGER li; + li.QuadPart = -10 * usec; // negative values for relative time + + HANDLE timer = CreateWaitableTimer(NULL, TRUE, NULL); + if(!timer) return -1; + + SetWaitableTimer(timer, &li, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); + return 0; +} +#else +# include +#endif + + +using namespace v8; +using namespace node; + + +Handle Sleep(const Arguments& args) { + HandleScope scope; + + if (args.Length() < 1 || !args[0]->IsUint32()) { + return ThrowException(Exception::TypeError(String::New("Expected number of seconds"))); + } + + sleep(args[0]->Uint32Value()); + + return scope.Close(Undefined()); +} + +Handle USleep(const Arguments& args) { + HandleScope scope; + + if (args.Length() < 1 || !args[0]->IsUint32()) { + return ThrowException(Exception::TypeError(String::New("Expected number of micro"))); + } + + usleep(args[0]->Uint32Value()); + + return scope.Close(Undefined()); +} + + +extern "C" void init(Handle target) { + NODE_SET_METHOD(target, "sleep", Sleep); + NODE_SET_METHOD(target, "usleep", USleep); +} + + +#ifdef NODE_MODULE +NODE_MODULE(node_sleep, init) +#endif + diff --git a/app.nw/node_modules/sleep/test.js b/app.nw/node_modules/sleep/test.js new file mode 100644 index 0000000..e0735ad --- /dev/null +++ b/app.nw/node_modules/sleep/test.js @@ -0,0 +1,12 @@ + +var sleep = require('./'); + +console.log('sleeping for 1 seconds...'); +sleep.sleep(1); +console.log('done'); + + +console.log('sleeping for 2000000 microseconds (2 seconds)'); +sleep.usleep(2000000); +console.log('done'); + diff --git a/app.nw/package.json b/app.nw/package.json new file mode 100755 index 0000000..e767526 --- /dev/null +++ b/app.nw/package.json @@ -0,0 +1,14 @@ +{ + "name": "ipynb", + "main": "app://whatever/start.html", + "dependencies": + { + "sleep": "" + }, + "window": { + "width": 473, + "height": 340, + "toolbar": false, + "fullscreen": false + } +} diff --git a/app.nw/start.html b/app.nw/start.html new file mode 100755 index 0000000..a78726c --- /dev/null +++ b/app.nw/start.html @@ -0,0 +1,167 @@ + + + + Start + + + + +
+ status: status +
+ + + + diff --git a/app.nw/test.js b/app.nw/test.js new file mode 100644 index 0000000..6667538 --- /dev/null +++ b/app.nw/test.js @@ -0,0 +1,63 @@ +var nbexec = 'nb.app/Contents/MacOS/nb'; +var basedir = '.'; //working dir +var startpage = 'http://127.0.0.1:8888/'; +var pagecheck = 'http://127.0.0.1:8888/tree'; //no side-effect page to check if webserver is running +//************************************************************ +var ipynb_process = null; +var spawn = require("child_process").spawn; +var sleep = require("sleep"); + +function Startipynb() +{ + console.log('start_nb'); + + var child; + child = spawn(nbexec, ['',],{cwd:basedir}); + child.stdout.on("data", function(data) { + return console.log("stdout:" + data); + }); + child.stderr.on("data", function(data) { + return console.log("ERROR: " + data); + }); + + child.on("exit", function(code) { + return console.log("Encoding process exited with code: " + code); + }); + + console.log("start_nb_End"); + + ipynb_process = child; + + function transferComplete(evt) { + console.log("transferComplete"); + } + + function transferFailed(evt) { + console.log("transferFailed"); + console.log("Waiting..."); + sleep.sleep(5); + checkServer(); + } + + function reqListener () { + console.log("Launching..."); + } + + function checkServer() + { + console.log("checking server"); + var oReq = new XMLHttpRequest(); + oReq.addEventListener("load", transferComplete, false); + oReq.addEventListener("error", transferFailed, false); + + oReq.onload = reqListener; + oReq.open("GET", pagecheck, true); + oReq.send(); + } + + console.log("starting..."); + checkServer(); + +} + +Startipynb(); diff --git a/py2app/nb.py b/py2app/nb.py new file mode 100644 index 0000000..bd5e625 --- /dev/null +++ b/py2app/nb.py @@ -0,0 +1,17 @@ +import os + +from IPython.html import notebookapp + +from zmq.eventloop import ioloop +ioloop.install() + +class QuickShutdownNotebookApp(notebookapp.NotebookApp): + def _confirm_exit(self): + self.log.critical("Shutting down") + ioloop.IOLoop.instance().stop() + +NOTEBOOK_STORAGE = os.path.expanduser('~/Library/ipyapp-notebooks/') +if __name__ == '__main__': + if not os.path.exists(NOTEBOOK_STORAGE): + os.makedirs(NOTEBOOK_STORAGE) + QuickShutdownNotebookApp.launch_instance(argv=['--no-browser', '--notebook-dir=%s' % NOTEBOOK_STORAGE]) diff --git a/py2app/setup.py b/py2app/setup.py new file mode 100644 index 0000000..5be1d7d --- /dev/null +++ b/py2app/setup.py @@ -0,0 +1,19 @@ +""" +This is a setup.py script generated by py2applet + +Usage: + python setup.py py2app +""" + +from setuptools import setup + +APP = ['nb.py'] +DATA_FILES = [] +OPTIONS = {'argv_emulation': True} + +setup( + app=APP, + data_files=DATA_FILES, + options={'py2app': OPTIONS}, + setup_requires=['py2app'], +)