diff --git a/zerobin.py b/zerobin.py index f81277f..386c4d7 100755 --- a/zerobin.py +++ b/zerobin.py @@ -4,4 +4,4 @@ from zerobin.routes import main -main() \ No newline at end of file +main() diff --git a/zerobin/__init__.py b/zerobin/__init__.py index 1dc86df..7d07ffa 100644 --- a/zerobin/__init__.py +++ b/zerobin/__init__.py @@ -4,4 +4,4 @@ from default_settings import VERSION -__version__ = VERSION \ No newline at end of file +__version__ = VERSION diff --git a/zerobin/routes.py b/zerobin/routes.py index 5d4d038..1b033d5 100644 --- a/zerobin/routes.py +++ b/zerobin/routes.py @@ -10,7 +10,7 @@ import os import sys import thread - +import urlparse from datetime import datetime, timedelta # add project dir and libs dir to the PYTHON PATH to ensure they are @@ -48,22 +48,28 @@ def faq(): @app.route('/paste/create', method='POST') def create_paste(): + try: + body = urlparse.parse_qs(request.body.read(int(settings.MAX_SIZE * 1.1))) + except ValueError: + return {'status': 'error', + 'message': u"Wrong data payload."} try: - content = unicode(request.forms.get('content', ''), 'utf8') - except UnicodeDecodeError: + content = unicode(''.join(body['content']), 'utf8') + except (UnicodeDecodeError, KeyError): return {'status': 'error', 'message': u"Encoding error: the paste couldn't be saved."} - if '{"iv":' not in content: # reject silently non encrypted content - return '' + if '{"iv":' not in content: # reject silently non encrypted content + return {'status': 'error', + 'message': u"Wrong data payload."} if content: - # check size of the paste. if more than settings return error without saving paste. - # prevent from unusual use of the system. - # need to be improved + # check size of the paste. if more than settings return error + # without saving paste. prevent from unusual use of the + # system. need to be improved if len(content) < settings.MAX_SIZE: - expiration = request.forms.get('expiration', u'burn_after_reading') + expiration = body.get('expiration', [u'burn_after_reading'])[0] paste = Paste(expiration=expiration, content=content) paste.save() @@ -81,12 +87,12 @@ def create_paste(): GLOBAL_CONTEXT['pastes_count'] = Paste.get_pastes_count() GLOBAL_CONTEXT['refresh_counter'] = now - return {'status': 'ok', 'paste': paste.uuid} return {'status': 'error', - 'message': u"Serveur error: the paste couldn't be saved. Please try later."} + 'message': u"Serveur error: the paste couldn't be saved. " + u"Please try later."} @app.route('/paste/:paste_id') @@ -105,7 +111,8 @@ def display_paste(paste_id): # to the paste that happens during the paste creation try: keep_alive = paste.expiration.split('#')[1] - keep_alive = datetime.strptime(keep_alive, '%Y-%m-%d %H:%M:%S.%f') + keep_alive = datetime.strptime(keep_alive, + '%Y-%m-%d %H:%M:%S.%f') keep_alive = now < keep_alive + timedelta(seconds=10) except IndexError: keep_alive = False @@ -136,8 +143,8 @@ def server_static(filename): def get_app(debug=None, settings_file='', compressed_static=None): """ - Return a tuple (settings, app) configured using passed parameters and/or - a setting file. + Return a tuple (settings, app) configured using passed + parameters and/or a setting file. """ if settings_file: settings.update_with_file(os.path.abspath(settings_file)) @@ -159,8 +166,8 @@ def get_app(debug=None, settings_file='', compressed_static=None): @clize.clize(coerce={'debug': bool, 'compressed_static': bool}) -def runserver(host='', port='', debug=None, user='', - group='', settings_file='', compressed_static=None, version=False): +def runserver(host='', port='', debug=None, user='', group='', + settings_file='', compressed_static=None, version=False): settings, app = get_app(debug, settings_file, compressed_static) @@ -179,7 +186,7 @@ def runserver(host='', port='', debug=None, user='', run(app, host=settings.HOST, port=settings.PORT, reloader=True, server="cherrypy") else: - run(app, host=settings.HOST, port=settings.PORT, server="cherrypy") + run(app, host=settings.HOST, port=settings.PORT, server="cherrypy") def main(): diff --git a/zerobin/static/css/style.css b/zerobin/static/css/style.css index d7575ec..7d19c85 100644 --- a/zerobin/static/css/style.css +++ b/zerobin/static/css/style.css @@ -383,4 +383,8 @@ canvas { -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box; +} + +#content.hover { + background-color: #eee; } \ No newline at end of file diff --git a/zerobin/static/css/style.min.css b/zerobin/static/css/style.min.css index 34a9cd0..64789ed 100644 --- a/zerobin/static/css/style.min.css +++ b/zerobin/static/css/style.min.css @@ -4,4 +4,4 @@ article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display /* Prettify */ .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} /* Custom */ -.brand{font-size:38px!important;padding:0 55px 3px!important;text-shadow:0 1px 0 rgba(255,255,255,.1),0 0 30px rgba(255,255,255,.125);-webkit-transition:all .2s linear;-moz-transition:all .2s linear;-o-transition:all .2s linear;-ms-transition:all .2s linear;transition:all .2s linear}.brand span{font-size:48px;line-height:0}.brand em{display:inline;color:#d40202;font-size:27px}.about{line-height:13px;font-style:italic;text-align:right;padding-top:9px;margin-bottom:0!important}.center{text-align:center}.about span{font-size:10px}body{padding-top:60px;padding-bottom:40px}.sidebar-nav{padding:9px 0}select{width:135px}label{display:inline;margin-left:18px;font-style:italic;font-size:11px;color:#888}ul,ol{padding:0;margin:0}li{margin-left:-9px}p{margin:0 0 20px}.grey{color:#999}.nav-list{padding-right:0!important;font-size:12px}blockquote{width:630px;float:left}h4 p{float:left;font-size:80px;text-shadow:1px 3px 1px #DDD,0 0 4px #333;-webkit-transition:all .2s linear;-o-transition:all .2s linear;-ms-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear;margin-right:7px;margin-top:3px}h4#pixels-total{position:relative;width:166px;float:right;margin:8px 0 0 0;padding:0 0 0 54px;font-size:1.1em;line-height:1.4;font-weight:normal;color:#777;-webkit-border-top-right-radius:6px;-webkit-border-top-left-radius:20px;-moz-border-top-right-radius:6px;-moz-border-top-left-radius:20px;border-top-right-radius:6px;border-top-left-radius:20px}.greetings{clear:both;margin:0 auto;text-align:center;margin-top:40px}.alert .title{display:block}.btn-group{float:left}html.file-upload p.file-upload{float:left;margin:22px 0 0 21px;display:none}html.file-upload p.file-upload{display:inherit}html.no-file-upload p.file-upload{display:none}input.btn-upload{position:relative;left:-6px;width:100px;z-index:1;margin-top:-13px}input.hide-upload{position:relative;left:-110px;-moz-opacity:0;filter:alpha(opacity=0);opacity:0;z-index:2;width:100px;margin-top:-20px;cursor:pointer;cursor:hand;height:49px}#paste-content{background-color:white;padding:1em}#paste-content.linenums{padding-left:0}.submit-form{display:none}.paste-option{float:right}a#clip-button.hover{cursor:pointer;text-decoration:underline}li.L0,li.L1,li.L2,li.L3,li.L4,li.L5,li.L6,li.L7,li.L8,li.L9{list-style-type:decimal;background:inherit}.prettyprint.linenums{-webkit-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;-moz-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0}ol.linenums{margin:0 0 0 55px}ol.linenums li{color:#bebec5;line-height:18px;text-shadow:0 1px 0 #fff}.prettyprint{padding:8px;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,monospace,serif;line-height:21px;font-size:12px}.kwd{color:#66F}.pun,.opn,.clo{color:#0A0}.lit{color:#933}.com{color:#C0C}form{padding-bottom:3em!important;padding-right:17px}form textarea{overflow-y:auto;min-height:250px}button.btn,input[type="submit"].btn{margin-left:5px}.well{padding-bottom:40px;padding-right:17px}.legal{margin:0 auto;width:300px;text-align:center;margin-top:30px}.btn{margin-left:5px}.btn-primary,.btn-danger{position:relative;top:-4px}#alert-template{display:none}.progress{display:none}.progress .bar{width:25%;text-indent:10px;text-align:left}.lnk-option canvas{vertical-align:middle;margin-right:10px}.previous-pastes .item{margin-top:5px;vertical-align:middle;line-height:24px;padding-left:1em}li.item{margin-left:-13px;margin-right:-5px}.previous-pastes canvas{display:block;float:left;margin-right:5px}html.local-storage .no-local-storage{display:none}html.no-local-storage .local-storage{display:none}canvas{border:1px solid white}#wrap-content{display:none}.noscript{text-align:center;color:red;font-weight:bold}#faq dt{margin:2em 0 1em 0}#faq p{margin:1em}#force-coloration{text-decoration:underline}#expiration-tag{float:right;margin:1em;background:grey;color:white;font-size:.8em;padding:0 1ex;opacity:.5;filter:alpha(opacity=50);font-weight:bold;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box} \ No newline at end of file +.brand{font-size:38px!important;padding:0 55px 3px!important;text-shadow:0 1px 0 rgba(255,255,255,.1),0 0 30px rgba(255,255,255,.125);-webkit-transition:all .2s linear;-moz-transition:all .2s linear;-o-transition:all .2s linear;-ms-transition:all .2s linear;transition:all .2s linear}.brand span{font-size:48px;line-height:0}.brand em{display:inline;color:#d40202;font-size:27px}.about{line-height:13px;font-style:italic;text-align:right;padding-top:9px;margin-bottom:0!important}.center{text-align:center}.about span{font-size:10px}body{padding-top:60px;padding-bottom:40px}.sidebar-nav{padding:9px 0}select{width:135px}label{display:inline;margin-left:18px;font-style:italic;font-size:11px;color:#888}ul,ol{padding:0;margin:0}li{margin-left:-9px}p{margin:0 0 20px}.grey{color:#999}.nav-list{padding-right:0!important;font-size:12px}blockquote{width:630px;float:left}h4 p{float:left;font-size:80px;text-shadow:1px 3px 1px #DDD,0 0 4px #333;-webkit-transition:all .2s linear;-o-transition:all .2s linear;-ms-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear;margin-right:7px;margin-top:3px}h4#pixels-total{position:relative;width:166px;float:right;margin:8px 0 0 0;padding:0 0 0 54px;font-size:1.1em;line-height:1.4;font-weight:normal;color:#777;-webkit-border-top-right-radius:6px;-webkit-border-top-left-radius:20px;-moz-border-top-right-radius:6px;-moz-border-top-left-radius:20px;border-top-right-radius:6px;border-top-left-radius:20px}.greetings{clear:both;margin:0 auto;text-align:center;margin-top:40px}.alert .title{display:block}.btn-group{float:left}html.file-upload p.file-upload{float:left;margin:22px 0 0 21px;display:none}html.file-upload p.file-upload{display:inherit}html.no-file-upload p.file-upload{display:none}input.btn-upload{position:relative;left:-6px;width:100px;z-index:1;margin-top:-13px}input.hide-upload{position:relative;left:-110px;-moz-opacity:0;filter:alpha(opacity=0);opacity:0;z-index:2;width:100px;margin-top:-20px;cursor:pointer;cursor:hand;height:49px}#paste-content{background-color:white;padding:1em}#paste-content.linenums{padding-left:0}.submit-form{display:none}.paste-option{float:right}a#clip-button.hover{cursor:pointer;text-decoration:underline}li.L0,li.L1,li.L2,li.L3,li.L4,li.L5,li.L6,li.L7,li.L8,li.L9{list-style-type:decimal;background:inherit}.prettyprint.linenums{-webkit-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;-moz-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0}ol.linenums{margin:0 0 0 55px}ol.linenums li{color:#bebec5;line-height:18px;text-shadow:0 1px 0 #fff}.prettyprint{padding:8px;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,monospace,serif;line-height:21px;font-size:12px}.kwd{color:#66F}.pun,.opn,.clo{color:#0A0}.lit{color:#933}.com{color:#C0C}form{padding-bottom:3em!important;padding-right:17px}form textarea{overflow-y:auto;min-height:250px}button.btn,input[type="submit"].btn{margin-left:5px}.well{padding-bottom:40px;padding-right:17px}.legal{margin:0 auto;width:300px;text-align:center;margin-top:30px}.btn{margin-left:5px}.btn-primary,.btn-danger{position:relative;top:-4px}#alert-template{display:none}.progress{display:none}.progress .bar{width:25%;text-indent:10px;text-align:left}.lnk-option canvas{vertical-align:middle;margin-right:10px}.previous-pastes .item{margin-top:5px;vertical-align:middle;line-height:24px;padding-left:1em}li.item{margin-left:-13px;margin-right:-5px}.previous-pastes canvas{display:block;float:left;margin-right:5px}html.local-storage .no-local-storage{display:none}html.no-local-storage .local-storage{display:none}canvas{border:1px solid white}#wrap-content{display:none}.noscript{text-align:center;color:red;font-weight:bold}#faq dt{margin:2em 0 1em 0}#faq p{margin:1em}#force-coloration{text-decoration:underline}#expiration-tag{float:right;margin:1em;background:grey;color:white;font-size:.8em;padding:0 1ex;opacity:.5;filter:alpha(opacity=50);font-weight:bold;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box}#content.hover{background-color:#eee} \ No newline at end of file diff --git a/zerobin/static/js/behavior.js b/zerobin/static/js/behavior.js index 89d9770..c01a163 100644 --- a/zerobin/static/js/behavior.js +++ b/zerobin/static/js/behavior.js @@ -1,13 +1,16 @@ /*global sjcl:true, jQuery:true, $:true, lzw:true, zerobin:true, ZeroClipboard:true, vizhash:true, prettyPrint:true, confirm:true */ -;(function(){ -"use strict"; +; +(function () { + "use strict"; -/* Start random number generator seeding ASAP */ -sjcl.random.startCollectors(); -/* Ensure jquery use cache for ajax requests */ -$.ajaxSetup({ cache: true }); + /* Start random number generator seeding ASAP */ + sjcl.random.startCollectors(); + /* Ensure jquery use cache for ajax requests */ + $.ajaxSetup({ + cache: true + }); -/** Create a function that create inline callbacks. + /** Create a function that create inline callbacks. We use it to create callbacks for onliners with static arguments E.G: $('stuff').hide(function()(console.log(1, 2, 3))) @@ -15,48 +18,64 @@ $.ajaxSetup({ cache: true }); Becomes: $('stuff').hide(mkcb(console.log, 1, 2, 3)) - */ -function mkcb(func){ - var args = arguments; - return function(){ - return func.apply(func, Array.prototype.slice.call(args, 1)); - }; -} + */ + function mkcb(func) { + var args = arguments; + return function () { + return func.apply(func, Array.prototype.slice.call(args, 1)); + }; + } -/*************************** -**** 0bin utilities *** -****************************/ + /*************************** + **** 0bin utilities *** + ***************************/ -window.zerobin = { + window.zerobin = { /** Base64 + compress + encrypt, with callbacks before each operation, and all of them are executed in a timed continuation to give a change to the UI to respond. */ version: '0.1.1', - encrypt: function(key, content, toBase64Callback, - compressCallback, encryptCallback, doneCallback) { + encrypt: function (key, content, toBase64Callback, + compressCallback, encryptCallback, doneCallback) { - setTimeout (function(){ + setTimeout(function () { content = sjcl.codec.utf8String.toBits(content); - if (toBase64Callback) {toBase64Callback();} + if (toBase64Callback) { + toBase64Callback(); + } - setTimeout(function(){ + setTimeout(function () { content = sjcl.codec.base64.fromBits(content); - if (compressCallback) {compressCallback();} + if (compressCallback) { + compressCallback(); + } - setTimeout(function(){ + setTimeout(function () { - content = lzw.compress(content); - if (encryptCallback) {encryptCallback();} + // content = lzw.compress(content); // Create a bug with JPG + if (encryptCallback) { + encryptCallback(); + } - setTimeout(function(){ - content = sjcl.encrypt(key, content); - if (doneCallback) {doneCallback(content);} + setTimeout(function () { + try { + content = sjcl.encrypt(key, content); + } catch (e) { + $('input, textarea, select, button').prop('disabled', false); + zerobin.progressBar('form.well .progress').container.hide(); + + zerobin.message('error', 'Paste could not be encrypted. Aborting.', + 'Error'); + } + if (doneCallback) { + doneCallback(content); + } }, 250); }, 250); @@ -64,155 +83,169 @@ window.zerobin = { }, 250); }, 250); - }, + }, - /** Base64 decoding + uncompress + decrypt, with callbacks before each operation, + /** Base64 decoding + uncompress + decrypt, with callbacks before each operation, and all of them are executed in a timed continuation to give a change to the UI to respond. This is where using a library to fake synchronicity could start to be useful, this code is starting be difficult to read. If anyone read this and got a suggestion, by all means, speak your mind. - */ - decrypt: function(key, content, errorCallback, uncompressCallback, - fromBase64Callback, toStringCallback, doneCallback) { + */ + decrypt: function (key, content, errorCallback, uncompressCallback, + fromBase64Callback, toStringCallback, doneCallback) { - /* Decrypt */ - setTimeout(function(){ - - try { - - content = sjcl.decrypt(key, content); - if (uncompressCallback) {uncompressCallback();} - - /* Decompress */ - setTimeout(function(){ - - try { - - content = lzw.decompress(content); - if (fromBase64Callback) {fromBase64Callback();} - - /* From base 64 to bits */ - setTimeout(function(){ - - try { - - content = sjcl.codec.base64.toBits(content); - if (toStringCallback) {toStringCallback();} - - /* From bits to string */ - setTimeout(function(){ - - try { - content = sjcl.codec.utf8String.fromBits(content); - if (doneCallback) {doneCallback(content);} - } catch (err) { - errorCallback(err); - } - - }, 250); /* "End of from bits to string" */ - - } catch (err) { - errorCallback(err); - } - - }, 250); /* End of "from base 64 to bits" */ - - } catch (err) { - errorCallback(err); + /* Decrypt */ + setTimeout(function () { + try { + content = sjcl.decrypt(key, content); + if (uncompressCallback) { + uncompressCallback(); } - }, 250); /* End of "decompress" */ + /* Decompress */ + setTimeout(function () { + try { + content = lzw.decompress(content); + if (fromBase64Callback) { + fromBase64Callback(); + } - } catch (err) { - errorCallback(err); - } + /* From base 64 to bits */ + setTimeout(function () { + try { + content = sjcl.codec.base64.toBits(content); + if (toStringCallback) { + toStringCallback(); + } - }, 250); /* End of "decrypt" */ - }, + /* From bits to string */ + setTimeout(function () { + try { + content = sjcl.codec.utf8String.fromBits(content); + if (doneCallback) { + doneCallback(content); + } + } catch (err) { + errorCallback(err); + } - /** Create a random base64 string long enought to be suitable as + }, 250); /* "End of from bits to string" */ + + } catch (err) { + errorCallback(err); + } + + }, 250); /* End of "from base 64 to bits" */ + + } catch (err) { + errorCallback(err); + } + + }, 250); /* End of "decompress" */ + + } catch (err) { + errorCallback(err); + } + + }, 250); /* End of "decrypt" */ + }, + + /** Create a random base64 string long enought to be suitable as an encryption key */ - makeKey: function() { - return sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0); - }, + makeKey: function () { + return sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0); + }, - getFormatedDate: function(date){ - date = date || new Date(); - return ((date.getMonth() +1 ) + '-' + - date.getDate() + '-' + date.getFullYear()); - }, + getFormatedDate: function (date) { + date = date || new Date(); + return ((date.getMonth() + 1) + '-' + date.getDate() + '-' + date.getFullYear()); + }, - getFormatedTime: function(date){ - date = date || new Date(); - var h = date.getHours(), + getFormatedTime: function (date) { + date = date || new Date(); + var h = date.getHours(), m = date.getMinutes(), s = date.getSeconds(); - if (h < 10) {h = "0" + h;} - if (m < 10) {m = "0" + m;} - if (s < 10) {s = "0" + s;} - return h + ":" + m + ":" + s; - }, + if (h < 10) { + h = "0" + h; + } + if (m < 10) { + m = "0" + m; + } + if (s < 10) { + s = "0" + s; + } + return h + ":" + m + ":" + s; + }, - numOrdA: function(a, b){ - return (a-b); - }, + numOrdA: function (a, b) { + return (a - b); + }, - /** Return a reverse sorted list of all the keys in local storage that + /** Return a reverse sorted list of all the keys in local storage that are prefixed with with the passed version (default being this lib version) */ - getLocalStorageKeys: function(){ - var version = 'zerobinV0.1'; - var keys = []; - for (var key in localStorage){ - if (key.indexOf(version) !== -1){ + getLocalStorageKeys: function () { + var version = 'zerobinV0.1'; + var keys = []; + for (var key in localStorage) { + if (key.indexOf(version) !== -1) { keys.push(key); - } - } - keys.sort(); - keys.reverse(); - return keys; - }, + } + } + keys.sort(); + keys.reverse(); + return keys; + }, - /** Get a tinyurl using JSONP */ - getTinyURL: function(longURL, success) { - var api = 'http://is.gd/create.php?format=json&url='; - $.getJSON(api + encodeURIComponent(longURL) + '&callback=?', function(data){ - success(data.shorturl); - }); - }, + /** Get a tinyurl using JSONP */ + getTinyURL: function(longURL, success) { + $.ajax({ + url: 'https://www.googleapis.com/urlshortener/v1/url', + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({ + "longUrl": longURL + }), + processData: false, + dataType: 'json' + }).done(function(data){ + console.log(data); + success(data.id); + }); + }, - /** Check for browser support of the named featured. Store the result + /** Check for browser support of the named featured. Store the result and add a class to the html tag with the result */ - support: { - localStorage: (function(){ - var val = !!(localStorage); - $('html').addClass((val ? '' : 'no-') + 'local-storage'); - return val; - })(), + support: { + localStorage: (function () { + var val = !! (localStorage); + $('html').addClass((val ? '' : 'no-') + 'local-storage'); + return val; + })(), - history: (function(){ - var val = !!(window.history && history.pushState); - $('html').addClass((val ? '' : 'no-') + 'history'); - return val; - })(), + history: (function () { + var val = !! (window.history && history.pushState); + $('html').addClass((val ? '' : 'no-') + 'history'); + return val; + })(), - fileUpload: (function(){ - var w = window; - var val = !!(w.File && w.FileReader && w.FileList && w.Blob); - $('html').addClass((val ? '' : 'no-') + 'file-upload'); - return val; - })() - }, + fileUpload: (function () { + var w = window; + var val = !! (w.File && w.FileReader && w.FileList && w.Blob); + $('html').addClass((val ? '' : 'no-') + 'file-upload'); + return val; + })() + }, - /** Store the paste of a URL in local storate, with a storage format + /** Store the paste of a URL in local storate, with a storage format version prefix and the paste date as the key */ - storePaste: function(url, date){ + storePaste: function (url, date) { date = date || new Date(); - date = (date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + - date.getDate() + ' ' + zerobin.getFormatedTime(date)); + date = (date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + zerobin.getFormatedTime(date)); var keys = zerobin.getLocalStorageKeys(); @@ -221,213 +254,302 @@ window.zerobin = { } localStorage.setItem('zerobinV' + zerobin.version + "#" + date, url); - }, + }, - /** Return a list of the previous paste url with the creation date + /** Return a list of the previous paste url with the creation date If the paste is from today, date format should be "at hh:ss", else it should be "the mm-dd-yyy" */ - getPreviousPastes: function(){ - var pastes = [], + getPreviousPastes: function () { + var pastes = [], keys = zerobin.getLocalStorageKeys(), today = zerobin.getFormatedDate(); - $.each(keys, function(i, key){ - var pasteDateTime = key.replace(/^[^#]+#/, ''); - var displayDate = pasteDateTime.match(/^(\d+)-(\d+)-(\d+)\s/); - displayDate = displayDate[2] + '-' + displayDate[3] + '-' + displayDate[1]; - var prefix = 'the '; - if (displayDate === today){ - displayDate = pasteDateTime.split(' ')[1]; - prefix = 'at '; - } - pastes.push({displayDate: displayDate, prefix: prefix, - link: localStorage.getItem(key)}); - }); + $.each(keys, function (i, key) { + var pasteDateTime = key.replace(/^[^#]+#/, ''); + var displayDate = pasteDateTime.match(/^(\d+)-(\d+)-(\d+)\s/); + displayDate = displayDate[2] + '-' + displayDate[3] + '-' + displayDate[1]; + var prefix = 'the '; + if (displayDate === today) { + displayDate = pasteDateTime.split(' ')[1]; + prefix = 'at '; + } + pastes.push({ + displayDate: displayDate, + prefix: prefix, + link: localStorage.getItem(key) + }); + }); - return pastes; - }, + return pastes; + }, - /** Return an link object with the URL as href so you can extract host, + /** Return an link object with the URL as href so you can extract host, protocol, hash, etc. This function use a closure to store a
parent for the because IE requires the link be processed by it's HTML parser for the URL to be parsed. */ - parseUrl: (function(){ + parseUrl: (function () { - var div = document.createElement('div'); - div.innerHTML = ""; + var div = document.createElement('div'); + div.innerHTML = ""; - return function(url){ - div.firstChild.href = url; - div.innerHTML = div.innerHTML; - return div.firstChild; - }; + return function (url) { + div.firstChild.href = url; + div.innerHTML = div.innerHTML; + return div.firstChild; + }; - })(), + })(), - getPasteId: function(url){ - var loc = url ? zerobin.parseUrl(url) : window.location; - return loc.pathname.replace(/\/|paste/g, ''); - }, + getPasteId: function (url) { + var loc = url ? zerobin.parseUrl(url) : window.location; + return loc.pathname.replace(/\/|paste/g, ''); + }, - getPasteKey: function(url){ - var loc = url ? zerobin.parseUrl(url) : window.location; - return loc.hash.replace('#', '').replace(/(\?|&).*$/, ''); - }, + getPasteKey: function (url) { + var loc = url ? zerobin.parseUrl(url) : window.location; + return loc.hash.replace('#', '').replace(/(\?|&).*$/, ''); + }, - /** Return the paste content stripted from any code coloration */ - getPasteContent: function(){ - var copy = '' ; - $("#paste-content li").each(function(index) { - copy = copy + $(this).text().replace(/[\u00a0]+/g, ' ') + '\n'; - }); - return copy; - }, + /** Return the paste content stripted from any code coloration */ + getPasteContent: function () { + var copy = ''; + $("#paste-content li").each(function (index) { + copy = copy + $(this).text().replace(/[\u00a0]+/g, ' ') + '\n'; + }); + return copy; + }, - /** Return an approximate estimate the number of bytes in a text */ - count: function(text, options) { - // Set option defaults - var crlf = /(\r?\n|\r)/g; - var whitespace = /(\r?\n|\r|\s+)/g; - options = options || {}; - options.lineBreaks = options.lineBreaks || 1; + /** Return an approximate estimate the number of bytes in a text */ + count: function (text, options) { + // Set option defaults + var crlf = /(\r?\n|\r)/g; + var whitespace = /(\r?\n|\r|\s+)/g; + options = options || {}; + options.lineBreaks = options.lineBreaks || 1; - var length = text.length, - nonAscii = length - text.replace(/[\u0100-\uFFFF]/g, '').length, + var length = text.length, + nonAscii = length - text.replace(/[\u0100-\uFFFF]/g, '').length, lineBreaks = length - text.replace(crlf, '').length; return length + nonAscii + Math.max(0, options.lineBreaks * (lineBreaks - 1)); - }, - /** Create a message, style it and insert it in the alert box */ - message: function(type, message, title, flush, callback) { - $(window).scrollTop(0); + }, + /** Create a message, style it and insert it in the alert box */ + message: function (type, message, title, flush, callback) { + $(window).scrollTop(0); - if (flush) {$('.alert-'+type).remove();} + if (flush) { + $('.alert-' + type).remove(); + } - var $message = $('#alert-template').clone().attr('id', null) - .addClass('alert alert-' + type); - $('.message', $message).html(message); + var $message = $('#alert-template').clone().attr('id', null) + .addClass('alert alert-' + type); + $('.message', $message).html(message); - if (title) {$('.title', $message).html(title);} - else {$('.title', $message).remove();} + if (title) { + $('.title', $message).html(title); + } else { + $('.title', $message).remove(); + } - $message.prependTo($('#main')).show('fadeUp', callback); - }, + $message.prependTo($('#main')).show('fadeUp', callback); + }, - /** Return a progress bar object */ - progressBar: function(selector){ - var $container = $(selector); - var bar = {container: $container, elem: $container.find('.bar')}; - bar.set = function(text, rate){bar.elem.text(text).css('width', rate);}; - return bar; - }, + /** Return a progress bar object */ + progressBar: function (selector) { + var $container = $(selector); + var bar = { + container: $container, + elem: $container.find('.bar') + }; + bar.set = function (text, rate) { + bar.elem.text(text).css('width', rate); + }; + return bar; + }, - /** Return an integer ranking the probability this text is any kind of + /** Return an integer ranking the probability this text is any kind of source code. */ - isCode: function(text){ + isCode: function (text) { - var code_chars = /[A-Z]{3}[A-Z]+|\.[a-z]|[=:<>{}\[\]$_'"&]| {2}|\t/g; - var comments = /(:?\/\*|)|(\/\/|#)(.*?)\n/g; - var formating = /[-*=_+]{4,}/; + var code_chars = /[A-Z]{3}[A-Z]+|\.[a-z]|[=:<>{}\[\]$_'"&]| {2}|\t/g; + var comments = /(:?\/\*|)|(\/\/|#)(.*?)\n/g; + var formating = /[-*=_+]{4,}/; - var total = 0; - var size = 0; - var m = text.match(comments); - if (m){ - total += text.match(comments).length; - } - text = text.replace(comments, ''); - text.replace(formating, ''); - text = text.split('\n'); - for (var i = 0; i < text.length; i++) { + var total = 0; + var size = 0; + var m = text.match(comments); + if (m) { + total += text.match(comments).length; + } + text = text.replace(comments, ''); + text.replace(formating, ''); + text = text.split('\n'); + for (var i = 0; i < text.length; i++) { var line = text[i]; size += line.length; var match = line.replace(formating, '').match(code_chars); if (match) { - total += match.length; + total += match.length; } + } + + return total * 1000 / size; + }, + + // prevent defaults + ignoreDrag: function (e) { + e.originalEvent.stopPropagation(); + e.originalEvent.preventDefault(); + }, + + // Handle Drop + handleDrop: function (e) { + e.originalEvent.preventDefault(); + zerobin.upload(e.originalEvent.dataTransfer.files); + $("#content").removeClass('hover'); + }, + + handleDragOver: function (e) { + zerobin.ignoreDrag(e); + $(this).addClass('hover'); + }, + + handleDragLeave: function (e) { + $(this).removeClass('hover'); + }, + + upload: function (files) { + var current_file = files[0]; + var reader = new FileReader(); + if (current_file.type.indexOf('image') == 0) { + reader.onload = function (event) { + var image = new Image(); + image.src = event.target.result; + + image.onload = function() { + var maxWidth = 1024, + maxHeight = 1024, + imageWidth = image.width, + imageHeight = image.height; + + + if (imageWidth > imageHeight) { + if (imageWidth > maxWidth) { + imageHeight *= maxWidth / imageWidth; + imageWidth = maxWidth; + } + } + else { + if (imageHeight > maxHeight) { + imageWidth *= maxHeight / imageHeight; + imageHeight = maxHeight; + } + } + + var canvas = document.createElement('canvas'); + canvas.width = imageWidth; + canvas.height = imageHeight; + image.width = imageWidth; + image.height = imageHeight; + var ctx = canvas.getContext("2d"); + ctx.drawImage(this, 0, 0, imageWidth, imageHeight); + + var paste = canvas.toDataURL(current_file.type); + $('#content').val(paste).trigger('change'); + $('#content').hide(); + $(image).css('max-width', '742px'); + $('#content').after(image); + } + } + reader.readAsDataURL(current_file); + } else { + reader.onload = function (event) { + $('#content').val(event.target.result).trigger('change'); + }; + reader.readAsText(current_file); + } } - - return total * 1000 / size; - } -}; + }; -/*************************** -**** On document ready *** -****************************/ + /*************************** + **** On document ready *** + ****************************/ -$(function(){ + $(function () { -/** + /** On the create paste page: On click on the send button, compress and encrypt data before posting it using ajax. Then redirect to the address of the newly created paste, adding the key in the hash. */ -$('.btn-primary').live("click", function(e){ + $('.btn-primary').live("click", function (e) { - e.preventDefault(); - var paste = $('textarea').val(); + e.preventDefault(); + var paste = $('textarea').val(); - var sizebytes = zerobin.count($('#content').val()); - var oversized = sizebytes > zerobin.max_size; - var readableFsize = Math.round(sizebytes / 1024); - var readableMaxsize = Math.round(zerobin.max_size / 1024); + if (paste.trim()) { - if (oversized){ - zerobin.message('error', - ('Your file is ' + readableFsize + - 'KB. You have reached the maximum size limit of ' + - readableMaxsize + 'KB.'), - 'Warning!', true); - } + var $form = $('input, textarea, select, button').prop('disabled', true); - if (!oversized && paste.trim()) { + // set up progress bar + var bar = zerobin.progressBar('form.well .progress'); + bar.container.show(); + bar.set('Converting paste to bits...', '25%'); - var $form = $('input, textarea, select, button').prop('disabled', true); - - // set up progress bar - var bar = zerobin.progressBar('form.well .progress'); - bar.container.show(); - bar.set('Converting paste to bits...', '25%'); - - /* Encode, compress, encrypt and send the paste then redirect the user + /* Encode, compress, encrypt and send the paste then redirect the user to the new paste. We ensure a loading animation is updated during the process by passing callbacks. */ - try { + try { - var expiration = $('#expiration').val(); - var key = zerobin.makeKey(); + var expiration = $('#expiration').val(); + var key = zerobin.makeKey(); - zerobin.encrypt(key, paste, + zerobin.encrypt(key, paste, - mkcb(bar.set, 'Encoding to base64...', '45%'), - mkcb(bar.set, 'Compressing...', '65%'), - mkcb(bar.set, 'Encrypting...', '85%'), + mkcb(bar.set, 'Encoding to base64...', '45%'), + mkcb(bar.set, 'Compressing...', '65%'), + mkcb(bar.set, 'Encrypting...', '85%'), - /* This block deal with sending the data, redirection or error handling */ - function(content){ + /* This block deal with sending the data, redirection or error handling */ + function (content) { - bar.set('Sending...', '95%'); - var data = {content: content, expiration: expiration}; + bar.set('Sending...', '95%'); + var data = { + content: content, + expiration: expiration + }; + var sizebytes = zerobin.count(JSON.stringify(data)); + var oversized = sizebytes > zerobin.max_size; // 100kb - the others header information + var readableFsize = Math.round(sizebytes / 1024); + var readableMaxsize = Math.round(zerobin.max_size / 1024); - $.post('/paste/create', data) - .error(function(error) { + if (oversized) { + bar.container.hide(); + $form.prop('disabled', false); + zerobin.message('error', ('The encrypted file was ' + readableFsize + + 'KB. You have reached the maximum size limit of ' + readableMaxsize + 'KB.'), + 'Warning!', true); + return; + } + + $.post('/paste/create', data) + .error(function (error) { $form.prop('disabled', false); bar.container.hide(); zerobin.message( 'error', 'Paste could not be saved. Please try again later.', - 'Error' - ); + 'Error'); - }) - .success(function(data) { + }) + .success(function (data) { bar.set('Redirecting to new paste...', '100%'); if (data.status === 'error') { @@ -436,320 +558,341 @@ $('.btn-primary').live("click", function(e){ bar.container.hide(); } else { var paste_url = '/paste/' + data.paste + '#' + key; - if (zerobin.support.localStorage){ + if (zerobin.support.localStorage) { zerobin.storePaste(paste_url); } window.location = (paste_url); } - }); + }); + }); + } catch (err) { + $form.prop('disabled', false); + bar.container.hide(); + zerobin.message('error', 'Paste could not be encrypted. Aborting.', + 'Error'); } - ); - } catch (err) { - $form.prop('disabled', false); - bar.container.hide(); - zerobin.message('error', 'Paste could not be encrypted. Aborting.', - 'Error'); - } - } + } + }); -}); - -/** + /** DECRYPTION: On the display paste page, decrypt and decompress the paste content, add syntax coloration then setup the copy to clipboard button. Also calculate and set the paste visual hash. */ -var content = $('#paste-content').text().trim(); -var key = zerobin.getPasteKey(); -var error = false; + var content = $('#paste-content').text().trim(); + var key = zerobin.getPasteKey(); + var error = false; -if (content && key) { + if (content && key) { - /* Load the lib for visual canvas, create one from the paste id and + /* Load the lib for visual canvas, create one from the paste id and insert it */ - $.getScript("/static/js/vizhash.min.js").done(function(script, textStatus) { - if (vizhash.supportCanvas) { - var vhash = vizhash.canvasHash(zerobin.getPasteId(), 24, 24); - $('').click(function(e){ - e.preventDefault(); - if(confirm("This picture is unique to your paste so you can identify" + - " it quickly. \n\n Do you want to know more about this?")){ - window.open("http://is.gd/IJaMRG", "_blank"); - } - }).prependTo('.lnk-option').append(vhash.canvas); - } - }); - - var $form = $('input, textarea, select, button').prop('disabled', true); - - var bar = zerobin.progressBar('.well form .progress'); - bar.container.show(); - bar.set('Decrypting paste...', '25%'); - - zerobin.decrypt(key, content, - - /* On error*/ - function(){ - bar.container.hide(); - zerobin.message('error', 'Could not decrypt data (Wrong key ?)', 'Error'); - }, - - /* Update progress bar */ - mkcb(bar.set, 'Decompressing...', '45%'), - mkcb(bar.set, 'Base64 decoding...', '65%'), - mkcb(bar.set, 'From bits to string...', '85%'), - - /* When done */ - function(content){ - - /* Decrypted content goes back to initial container*/ - $('#paste-content').text(content); - - bar.set('Code coloration...', '95%'); - - /* Add a continuation to let the UI redraw */ - setTimeout(function(){ - - /* Setup flash clipboard button */ - ZeroClipboard.setMoviePath('/static/js/ZeroClipboard.swf'); - - var clip = new ZeroClipboard.Client(); - - // Callback to reposition the clibpboad flash animation overlay - var reposition = function(){clip.reposition();}; - - clip.addEventListener('mouseup', function(){ - $('#clip-button').text('Copying paste...'); - clip.setText(zerobin.getPasteContent()); - }); - clip.addEventListener('complete', function(){ - $('#clip-button').text('Copy to clipboard'); - zerobin.message('info', 'The paste is now in your clipboard', '', - true, reposition); - }); - clip.glue('clip-button'); - - window.onresize = reposition; - - - /* Setup link to get the paste short url*/ - $('#short-url').click(function(e) { - e.preventDefault(); - $('#short-url').text('Loading short url...'); - zerobin.getTinyURL(window.location.toString(), function(tinyurl){ - clip.setText(tinyurl); - $('#copy-success').hide(); - zerobin.message('success', - '' + tinyurl + '', - 'Short url', true, reposition - ); - $('#short-url').text('Get short url'); - }); - }); - - /* Remap the message close handler to include the clipboard - flash reposition */ - $(".close").die().live('click', function(e){ - e.preventDefault(); - $(this).parent().fadeOut(reposition); - }); - - /** Syntaxic coloration */ - - if (zerobin.isCode(content) > 100){ - $('#paste-content').addClass('linenums'); - prettyPrint(); - } else { - zerobin.message('info', - "The paste did not seem to be code, so it " + - "was not colorized. " + - "Force coloration", - '', false, reposition); - } - - /* Class to switch to paste content style with coloration done */ - $('#paste-content').addClass('done'); - - /* Display result */ - bar.set('Done', '100%'); - bar.container.hide(); - - $form.prop('disabled', false); - content = ''; - - }, 250); - - } - ); - -} /* End of "DECRYPTION" */ - -/* Synchronize expiration select boxes value */ -$('.paste-option select').live('change', function(){ - $('.paste-option select').val($(this).val()); -}); - - -/* Resize Textarea according to content */ -$('#content').elastic(); - - -/* Display bottom paste option buttons when needed */ -$('#content').live('keyup change', function(){ - if($('#content').height() < 400 ){ - $('.paste-option.down').remove(); - } - else { - - if ($('.paste-option').length === 1) { - $('.paste-option').clone().addClass('down').appendTo('form.well'); - } - } - -}); - - -/* Display previous pastes */ -if (zerobin.support.localStorage){ - - var $container = $('.previous-pastes'), - pastes = zerobin.getPreviousPastes(); - - if (pastes.length){ - - $.getScript("/static/js/vizhash.min.js").done(function(script, textStatus) { - - $container.find('.item').remove(); - $.each(zerobin.getPreviousPastes(), function(i, paste){ - - var $li = $('
  • ').appendTo($container); - var $link = $('').attr('href', paste.link) - .text(paste.prefix + paste.displayDate) - .appendTo($li); - + $.getScript("/static/js/vizhash.min.js").done(function (script, textStatus) { if (vizhash.supportCanvas) { - var pasteId = zerobin.getPasteId(paste.link); - var vhash = vizhash.canvasHash(pasteId, 24, 24).canvas; - $link.prepend($(vhash).addClass('vhash')); + var vhash = vizhash.canvasHash(zerobin.getPasteId(), 24, 24); + $('').click(function (e) { + e.preventDefault(); + if (confirm("This picture is unique to your paste so you can identify" + + " it quickly. \n\n Do you want to know more about this?")) { + window.open("http://is.gd/IJaMRG", "_blank"); + } + }).prependTo('.lnk-option').append(vhash.canvas); } + }); + + var $form = $('input, textarea, select, button').prop('disabled', true); + + var bar = zerobin.progressBar('.well form .progress'); + bar.container.show(); + bar.set('Decrypting paste...', '25%'); + + zerobin.decrypt(key, content, + + /* On error*/ + function () { + bar.container.hide(); + zerobin.message('error', 'Could not decrypt data (Wrong key ?)', 'Error'); + }, + + /* Update progress bar */ + mkcb(bar.set, 'Decompressing...', '45%'), + mkcb(bar.set, 'Base64 decoding...', '65%'), + mkcb(bar.set, 'From bits to string...', '85%'), + + /* When done */ + function (content) { + + /* Decrypted content goes back to initial container*/ + $('#paste-content').text(content); + + if (content.indexOf('data:image') == 0) { + // Display Image + $('#paste-content').hide(); + var img = $(''); + $(img).attr('src', content); + $(img).css('max-width', '742px'); + $('#paste-content').after(img); + + // Display Download button + $('.btn-clone').hide(); + + var button = $('').attr('href', content); + $(button).attr('download', '0bin_' + document.location.pathname.split('/').pop()); + $(button).addClass('btn'); + $(button).html(' Download'); + $('.btn-clone').after(button); - // hightlite the current link and make sure clicking the link - // does redirect to the page - if (paste.link.replace(/#[^#]+/, '') === window.location.pathname){ - $li.addClass('active'); - $link.click(function(){ - window.location = $link.attr('href'); - window.location.reload(); - }); } + bar.set('Code coloration...', '95%'); + + /* Add a continuation to let the UI redraw */ + setTimeout(function () { + + /* Setup flash clipboard button */ + ZeroClipboard.setMoviePath('/static/js/ZeroClipboard.swf'); + + var clip = new ZeroClipboard.Client(); + + // Callback to reposition the clibpboad flash animation overlay + var reposition = function () { + clip.reposition(); + }; + + clip.addEventListener('mouseup', function () { + $('#clip-button').text('Copying paste...'); + clip.setText(zerobin.getPasteContent()); + }); + clip.addEventListener('complete', function () { + $('#clip-button').text('Copy to clipboard'); + zerobin.message('info', 'The paste is now in your clipboard', '', + true, reposition); + }); + clip.glue('clip-button'); + + window.onresize = reposition; + + + /* Setup link to get the paste short url*/ + $('#short-url').click(function (e) { + e.preventDefault(); + $('#short-url').text('Loading short url...'); + zerobin.getTinyURL(window.location.toString(), function (tinyurl) { + clip.setText(tinyurl); + $('#copy-success').hide(); + zerobin.message('success', + '' + tinyurl + '', + 'Short url', true, reposition); + $('#short-url').text('Get short url'); + }); + }); + + /* Remap the message close handler to include the clipboard + flash reposition */ + $(".close").die().live('click', function (e) { + e.preventDefault(); + $(this).parent().fadeOut(reposition); + }); + + /** Syntaxic coloration */ + + if (zerobin.isCode(content) > 100) { + $('#paste-content').addClass('linenums'); + prettyPrint(); + } else { + if (content.indexOf('data:image') != 0) { + zerobin.message('info', + "The paste did not seem to be code, so it " + + "was not colorized. " + + "Force coloration", + '', false, reposition); + } + } + + /* Class to switch to paste content style with coloration done */ + $('#paste-content').addClass('done'); + + /* Display result */ + bar.set('Done', '100%'); + bar.container.hide(); + + $form.prop('disabled', false); + content = ''; + + }, 250); }); + } /* End of "DECRYPTION" */ + + /* Synchronize expiration select boxes value */ + $('.paste-option select').live('change', function () { + $('.paste-option select').val($(this).val()); }); - } -} + /* Resize Textarea according to content */ + $('#content').elastic(); -/* Event handler for "clone paste" button */ -$('.btn-clone').click(function(e){ - e.preventDefault(); - $('.submit-form').show(); - $('.paste-form').hide(); - $('#content').val(zerobin.getPasteContent()).trigger('change'); -}); + /* Display bottom paste option buttons when needed */ + $('#content').live('keyup change', function () { + if ($('#content').height() < 400) { + $('.paste-option.down').remove(); + } else { -$('.clone .btn-danger').click(function(e){ - e.preventDefault(); - $('.submit-form').hide(); - $('.paste-form').show(); -}); + if ($('.paste-option').length === 1) { + $('.paste-option').clone().addClass('down').appendTo('form.well'); + } + } + + }); -/* Upload file using HTML5 File API */ -if (zerobin.support.fileUpload) { + /* Display previous pastes */ + if (zerobin.support.localStorage) { - var upload = function(files) { - var reader = new FileReader(); - reader.onload = function(event) { - $('#content').val(event.target.result).trigger('change'); - }; - reader.readAsText(files[0]); - }; + var $container = $('.previous-pastes'), + pastes = zerobin.getPreviousPastes(); - var $buttonOverlay = $('#file-upload'); - var $button = $('.btn-upload'); + if (pastes.length) { - try { - $button.val('Uploading...'); - $button.prop('disabled', true); - $buttonOverlay.change(function(){upload(this.files);}); - } - catch (e) { - zerobin.message('error', 'Could no upload the file', 'Error'); - $button.val('Upload File'); - $button.prop('disabled', false); - } + $.getScript("/static/js/vizhash.min.js").done(function (script, textStatus) { - $button.prop('disabled', false); - $button.val('Upload File'); - $buttonOverlay.mouseover(mkcb($(this).css, 'cursor', 'pointer')); -} + $container.find('.item').remove(); + $.each(zerobin.getPreviousPastes(), function (i, paste) { -/* Alerts */ + var $li = $('
  • ').appendTo($container); + var $link = $('').attr('href', paste.link) + .text(paste.prefix + paste.displayDate) + .appendTo($li); -$(".close").live('click', function(e){ - e.preventDefault(); - $(this).parent().fadeOut(); -}); + if (vizhash.supportCanvas) { + var pasteId = zerobin.getPasteId(paste.link); + var vhash = vizhash.canvasHash(pasteId, 24, 24).canvas; + $link.prepend($(vhash).addClass('vhash')); + } + + // hightlite the current link and make sure clicking the link + // does redirect to the page + if (paste.link.replace(/#[^#]+/, '') === window.location.pathname) { + $li.addClass('active'); + $link.click(function () { + window.location = $link.attr('href'); + window.location.reload(); + }); + } + + }); + + }); + + } + + } -/* Parse obfuscaded emails and make them usable */ -$('.email-link').each(function(i, elem){ - var $obfuscatedEmail = $(this); - var address = $obfuscatedEmail.attr('title').replace('__AT__', '@'); - var text = $obfuscatedEmail.text().replace('__AT__', '@'); - var $plainTextEmail = $(''+ text +''); - $obfuscatedEmail.replaceWith($plainTextEmail); + /* Event handler for "clone paste" button */ + $('.btn-clone').click(function (e) { + e.preventDefault(); + $('.submit-form').show(); + $('.paste-form').hide(); + $('#content').val(zerobin.getPasteContent()).trigger('change'); + }); -}); + $('.clone .btn-danger').click(function (e) { + e.preventDefault(); + $('.submit-form').hide(); + $('.paste-form').show(); + }); -/* Show the page using javascript. Non js enabled browser will see an + + + /* Upload file using HTML5 File API */ + if (zerobin.support.fileUpload) { + + var $buttonOverlay = $('#file-upload'); + var $button = $('.btn-upload'); + + try { + $button.val('Uploading...'); + $button.prop('disabled', true); + $buttonOverlay.change(function () { + zerobin.upload(this.files); + }); + } catch (e) { + zerobin.message('error', 'Could no upload the file', 'Error'); + $button.val('Upload File'); + $button.prop('disabled', false); + } + + $button.prop('disabled', false); + $button.val('Upload File'); + $buttonOverlay.mouseover(mkcb($(this).css, 'cursor', 'pointer')); + + // Implements drag & drop upload + $('#content').bind('drop', zerobin.handleDrop); + $('#content').bind('dragover', zerobin.handleDragOver); + $('#content').bind('dragleave', zerobin.handleDragLeave); + + + } + + /* Alerts */ + + $(".close").live('click', function (e) { + e.preventDefault(); + $(this).parent().fadeOut(); + }); + + + /* Parse obfuscaded emails and make them usable */ + $('.email-link').each(function (i, elem) { + var $obfuscatedEmail = $(this); + var address = $obfuscatedEmail.attr('title').replace('__AT__', '@'); + var text = $obfuscatedEmail.text().replace('__AT__', '@'); + var $plainTextEmail = $('' + text + ''); + $obfuscatedEmail.replaceWith($plainTextEmail); + + }); + + /* Show the page using javascript. Non js enabled browser will see an error message */ -$('#wrap-content').each(function(i, elem){ - $(elem).show(); -}); + $('#wrap-content').each(function (i, elem) { + $(elem).show(); + }); -/* Remove expired pasted from history */ -if (zerobin.support.history && zerobin.paste_not_found){ - var paste_id = zerobin.getPasteId(); - var keys = zerobin.getLocalStorageKeys(); - $.each(keys, function(i, key){ - if (localStorage[key].indexOf(paste_id) !== -1){ - localStorage.removeItem(key); - return false; - } - }); -} + /* Remove expired pasted from history */ + if (zerobin.support.history && zerobin.paste_not_found) { + var paste_id = zerobin.getPasteId(); + var keys = zerobin.getLocalStorageKeys(); + $.each(keys, function (i, key) { + if (localStorage[key].indexOf(paste_id) !== -1) { + localStorage.removeItem(key); + return false; + } + }); + } -/* Force text coloration when clickin on link */ -$("#force-coloration").live("click", function(e) { - e.preventDefault(); - $('#paste-content').addClass('linenums'); - $(this).die(e).text('Applying coloration'); - prettyPrint(); - $(this).remove(); -}); + /* Force text coloration when clickin on link */ + $("#force-coloration").live("click", function (e) { + e.preventDefault(); + $('#paste-content').addClass('linenums'); + $(this).die(e).text('Applying coloration'); + prettyPrint(); + $(this).remove(); + }); -/* Send the paste by email */ -var emailLink = 'mailto:friend@example.com?body=' + window.location; -$('#email-link').attr('href', emailLink); + /* Send the paste by email */ + $('#email-link').click(function() { + zerobin.getTinyURL(window.location.toString(), function(tinyurl) { + window.open('mailto:friend@example.com?body=' + tinyurl); + }); + return false; + }); - -}); /* End of "document ready" jquery callback */ + }); /* End of "document ready" jquery callback */ })(); /* End of self executing function */ diff --git a/zerobin/static/js/main.min.js b/zerobin/static/js/main.min.js index 5ee2d2d..8d779da 100644 --- a/zerobin/static/js/main.min.js +++ b/zerobin/static/js/main.min.js @@ -48,4 +48,4 @@ b[d[2]]=d[3]?parseInt(d[3],10):d[2].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.to undefined)c[b[d]]=a[b[d]];return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.S={};sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.S,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===undefined?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}}; /* custom */ -(function(){sjcl.random.startCollectors();$.ajaxSetup({cache:true});function a(c){var b=arguments;return function(){return c.apply(c,Array.prototype.slice.call(b,1))}}window.zerobin={version:"0.1.1",encrypt:function(f,g,d,b,e,c){setTimeout(function(){g=sjcl.codec.utf8String.toBits(g);if(d){d()}setTimeout(function(){g=sjcl.codec.base64.fromBits(g);if(b){b()}setTimeout(function(){g=lzw.compress(g);if(e){e()}setTimeout(function(){g=sjcl.encrypt(f,g);if(c){c(g)}},250)},250)},250)},250)},decrypt:function(f,g,d,b,e,h,c){setTimeout(function(){try{g=sjcl.decrypt(f,g);if(b){b()}setTimeout(function(){try{g=lzw.decompress(g);if(e){e()}setTimeout(function(){try{g=sjcl.codec.base64.toBits(g);if(h){h()}setTimeout(function(){try{g=sjcl.codec.utf8String.fromBits(g);if(c){c(g)}}catch(l){d(l)}},250)}catch(k){d(k)}},250)}catch(j){d(j)}},250)}catch(i){d(i)}},250)},makeKey:function(){return sjcl.codec.base64.fromBits(sjcl.random.randomWords(8,0),0)},getFormatedDate:function(b){b=b||new Date();return((b.getMonth()+1)+"-"+b.getDate()+"-"+b.getFullYear())},getFormatedTime:function(c){c=c||new Date();var e=c.getHours(),b=c.getMinutes(),d=c.getSeconds();if(e<10){e="0"+e}if(b<10){b="0"+b}if(d<10){d="0"+d}return e+":"+b+":"+d},numOrdA:function(d,c){return(d-c)},getLocalStorageKeys:function(){var b="zerobinV0.1";var d=[];for(var c in localStorage){if(c.indexOf(b)!==-1){d.push(c)}}d.sort();d.reverse();return d},getTinyURL:function(d,c){var b="http://is.gd/create.php?format=json&url=";$.getJSON(b+encodeURIComponent(d)+"&callback=?",function(e){c(e.shorturl)})},support:{localStorage:(function(){var b=!!(localStorage);$("html").addClass((b?"":"no-")+"local-storage");return b})(),history:(function(){var b=!!(window.history&&history.pushState);$("html").addClass((b?"":"no-")+"history");return b})(),fileUpload:(function(){var b=window;var c=!!(b.File&&b.FileReader&&b.FileList&&b.Blob);$("html").addClass((c?"":"no-")+"file-upload");return c})()},storePaste:function(c,b){b=b||new Date();b=(b.getFullYear()+"-"+(b.getMonth()+1)+"-"+b.getDate()+" "+zerobin.getFormatedTime(b));var d=zerobin.getLocalStorageKeys();if(localStorage.length>19){void localStorage.removeItem(d[19])}localStorage.setItem("zerobinV"+zerobin.version+"#"+b,c)},getPreviousPastes:function(){var c=[],d=zerobin.getLocalStorageKeys(),b=zerobin.getFormatedDate();$.each(d,function(g,f){var j=f.replace(/^[^#]+#/,"");var e=j.match(/^(\d+)-(\d+)-(\d+)\s/);e=e[2]+"-"+e[3]+"-"+e[1];var h="the ";if(e===b){e=j.split(" ")[1];h="at "}c.push({displayDate:e,prefix:h,link:localStorage.getItem(f)})});return c},parseUrl:(function(){var b=document.createElement("div");b.innerHTML="";return function(c){b.firstChild.href=c;b.innerHTML=b.innerHTML;return b.firstChild}})(),getPasteId:function(b){var c=b?zerobin.parseUrl(b):window.location;return c.pathname.replace(/\/|paste/g,"")},getPasteKey:function(b){var c=b?zerobin.parseUrl(b):window.location;return c.hash.replace("#","").replace(/(\?|&).*$/,"")},getPasteContent:function(){var b="";$("#paste-content li").each(function(c){b=b+$(this).text().replace(/[\u00a0]+/g," ")+"\n"});return b},count:function(h,d){var g=/(\r?\n|\r)/g;var c=/(\r?\n|\r|\s+)/g;d=d||{};d.lineBreaks=d.lineBreaks||1;var f=h.length,e=f-h.replace(/[\u0100-\uFFFF]/g,"").length,b=f-h.replace(g,"").length;return f+e+Math.max(0,d.lineBreaks*(b-1))},message:function(d,e,f,b,g){$(window).scrollTop(0);if(b){$(".alert-"+d).remove()}var c=$("#alert-template").clone().attr("id",null).addClass("alert alert-"+d);$(".message",c).html(e);if(f){$(".title",c).html(f)}else{$(".title",c).remove()}c.prependTo($("#main")).show("fadeUp",g)},progressBar:function(b){var d=$(b);var c={container:d,elem:d.find(".bar")};c.set=function(f,e){c.elem.text(f).css("width",e)};return c},isCode:function(h){var b=/[A-Z]{3}[A-Z]+|\.[a-z]|[=:<>{}\[\]$_'"&]| {2}|\t/g;var j=/(\/\*|\/\/|#|;).*$/g;var g=0;var f=0;h=h.split("\n");for(var e=0;ezerobin.max_size;var u=Math.round(q/1024);var x=Math.round(zerobin.max_size/1024);if(r){zerobin.message("error",('Your file is '+u+"KB. You have reached the maximum size limit of "+x+"KB."),"Warning!",true)}if(!r&&s.trim()){var A=$("input, textarea, select, button").prop("disabled",true);var w=zerobin.progressBar("form.well .progress");w.container.show();w.set("Converting paste to bits...","25%");try{var z=$("#expiration").val();var y=zerobin.makeKey();zerobin.encrypt(y,s,a(w.set,"Encoding to base64...","45%"),a(w.set,"Compressing...","65%"),a(w.set,"Encrypting...","85%"),function(e){w.set("Sending...","95%");var B={content:e,expiration:z};$.post("/paste/create",B).error(function(C){A.prop("disabled",false);w.container.hide();zerobin.message("error","Paste could not be saved. Please try again later.","Error")}).success(function(D){w.set("Redirecting to new paste...","100%");if(D.status==="error"){zerobin.message("error",D.message,"Error");A.prop("disabled",false);w.container.hide()}else{var C="/paste/"+D.paste+"#"+y;if(zerobin.support.localStorage){zerobin.storePaste(C)}window.location=(C)}})})}catch(t){A.prop("disabled",false);w.container.hide();zerobin.message("error","Paste could not be encrypted. Aborting.","Error")}}});var h=$("#paste-content").text().trim();var k=zerobin.getPasteKey();var j=false;if(h&&k){$.getScript("/static/js/vizhash.min.js").done(function(q,r){if(vizhash.supportCanvas){var e=vizhash.canvasHash(zerobin.getPasteId(),24,24);$('').click(function(s){s.preventDefault();if(confirm("This picture is unique to your paste so you can identify it quickly. \n\n Do you want to know more about this?")){window.open("http://is.gd/IJaMRG","_blank")}}).prependTo(".lnk-option").append(e.canvas)}});var o=$("input, textarea, select, button").prop("disabled",true);var i=zerobin.progressBar(".well form .progress");i.container.show();i.set("Decrypting paste...","25%");zerobin.decrypt(k,h,function(){i.container.hide();zerobin.message("error","Could not decrypt data (Wrong key ?)","Error")},a(i.set,"Decompressing...","45%"),a(i.set,"Base64 decoding...","65%"),a(i.set,"From bits to string...","85%"),function(e){$("#paste-content").text(e);i.set("Code coloration...","95%");setTimeout(function(){ZeroClipboard.setMoviePath("/static/js/ZeroClipboard.swf");var r=new ZeroClipboard.Client();var q=function(){r.reposition()};r.addEventListener("mouseup",function(){$("#clip-button").text("Copying paste...");r.setText(zerobin.getPasteContent())});r.addEventListener("complete",function(){$("#clip-button").text("Copy to clipboard");zerobin.message("info","The paste is now in your clipboard","",true,q)});r.glue("clip-button");window.onresize=q;$("#short-url").click(function(s){s.preventDefault();$("#short-url").text("Loading short url...");zerobin.getTinyURL(window.location.toString(),function(t){r.setText(t);$("#copy-success").hide();zerobin.message("success",''+t+"","Short url",true,q);$("#short-url").text("Get short url")})});$(".close").die().live("click",function(s){s.preventDefault();$(this).parent().fadeOut(q)});if(zerobin.isCode(e)>100){$("#paste-content").addClass("linenums");prettyPrint()}else{zerobin.message("info","The paste did not seem to be code, so it was not colorized. Force coloration","",false,q)}$("#paste-content").addClass("done");i.set("Done","100%");i.container.hide();o.prop("disabled",false);e=""},250)})}$(".paste-option select").live("change",function(){$(".paste-option select").val($(this).val())});$("#content").elastic();$("#content").live("keyup change",function(){if($("#content").height()<400){$(".paste-option.down").remove()}else{if($(".paste-option").length===1){$(".paste-option").clone().addClass("down").appendTo("form.well")}}});if(zerobin.support.localStorage){var m=$(".previous-pastes"),p=zerobin.getPreviousPastes();if(p.length){$.getScript("/static/js/vizhash.min.js").done(function(e,q){m.find(".item").remove();$.each(zerobin.getPreviousPastes(),function(t,v){var w=$('
  • ').appendTo(m);var s=$("").attr("href",v.link).text(v.prefix+v.displayDate).appendTo(w);if(vizhash.supportCanvas){var u=zerobin.getPasteId(v.link);var r=vizhash.canvasHash(u,24,24).canvas;s.prepend($(r).addClass("vhash"))}if(v.link.replace(/#[^#]+/,"")===window.location.pathname){w.addClass("active");s.click(function(){window.location=s.attr("href");window.location.reload()})}})})}}$(".btn-clone").click(function(q){q.preventDefault();$(".submit-form").show();$(".paste-form").hide();$("#content").val(zerobin.getPasteContent()).trigger("change")});$(".clone .btn-danger").click(function(q){q.preventDefault();$(".submit-form").hide();$(".paste-form").show()});if(zerobin.support.fileUpload){var n=function(q){var e=new FileReader();e.onload=function(r){$("#content").val(r.target.result).trigger("change")};e.readAsText(q[0])};var d=$("#file-upload");var b=$(".btn-upload");try{b.val("Uploading...");b.prop("disabled",true);d.change(function(){n(this.files)})}catch(g){zerobin.message("error","Could no upload the file","Error");b.val("Upload File");b.prop("disabled",false)}b.prop("disabled",false);b.val("Upload File");d.mouseover(a($(this).css,"cursor","pointer"))}$(".close").live("click",function(q){q.preventDefault();$(this).parent().fadeOut()});$(".email-link").each(function(r,s){var u=$(this);var e=u.attr("title").replace("__AT__","@");var t=u.text().replace("__AT__","@");var q=$(''+t+"");u.replaceWith(q)});$("#wrap-content").each(function(e,q){$(q).show()});if(zerobin.support.history&&zerobin.paste_not_found){var c=zerobin.getPasteId();var l=zerobin.getLocalStorageKeys();$.each(l,function(q,e){if(localStorage[e].indexOf(c)!==-1){localStorage.removeItem(e);return false}})}$("#force-coloration").live("click",function(q){q.preventDefault();$("#paste-content").addClass("linenums");$(this).die(q).text("Applying coloration");prettyPrint();$(this).remove()});var f="mailto:friend@example.com?body="+window.location;$("#email-link").attr("href",f)})})(); \ No newline at end of file +(function(){sjcl.random.startCollectors();$.ajaxSetup({cache:true});function a(c){var b=arguments;return function(){return c.apply(c,Array.prototype.slice.call(b,1))}}window.zerobin={version:"0.1.1",encrypt:function(f,g,d,b,e,c){setTimeout(function(){g=sjcl.codec.utf8String.toBits(g);if(d){d()}setTimeout(function(){g=sjcl.codec.base64.fromBits(g);if(b){b()}setTimeout(function(){if(e){e()}setTimeout(function(){try{g=sjcl.encrypt(f,g)}catch(h){$("input, textarea, select, button").prop("disabled",false);zerobin.progressBar("form.well .progress").container.hide();zerobin.message("error","Paste could not be encrypted. Aborting.","Error")}if(c){c(g)}},250)},250)},250)},250)},decrypt:function(f,g,d,b,e,h,c){setTimeout(function(){try{g=sjcl.decrypt(f,g);if(b){b()}setTimeout(function(){try{g=lzw.decompress(g);if(e){e()}setTimeout(function(){try{g=sjcl.codec.base64.toBits(g);if(h){h()}setTimeout(function(){try{g=sjcl.codec.utf8String.fromBits(g);if(c){c(g)}}catch(l){d(l)}},250)}catch(k){d(k)}},250)}catch(j){d(j)}},250)}catch(i){d(i)}},250)},makeKey:function(){return sjcl.codec.base64.fromBits(sjcl.random.randomWords(8,0),0)},getFormatedDate:function(b){b=b||new Date();return((b.getMonth()+1)+"-"+b.getDate()+"-"+b.getFullYear())},getFormatedTime:function(c){c=c||new Date();var e=c.getHours(),b=c.getMinutes(),d=c.getSeconds();if(e<10){e="0"+e}if(b<10){b="0"+b}if(d<10){d="0"+d}return e+":"+b+":"+d},numOrdA:function(d,c){return(d-c)},getLocalStorageKeys:function(){var b="zerobinV0.1";var d=[];for(var c in localStorage){if(c.indexOf(b)!==-1){d.push(c)}}d.sort();d.reverse();return d},getTinyURL:function(c,b){$.ajax({url:"https://www.googleapis.com/urlshortener/v1/url",type:"POST",contentType:"application/json",data:JSON.stringify({longUrl:c}),processData:false,dataType:"json"}).done(function(d){console.log(d);b(d.id)})},support:{localStorage:(function(){var b=!!(localStorage);$("html").addClass((b?"":"no-")+"local-storage");return b})(),history:(function(){var b=!!(window.history&&history.pushState);$("html").addClass((b?"":"no-")+"history");return b})(),fileUpload:(function(){var b=window;var c=!!(b.File&&b.FileReader&&b.FileList&&b.Blob);$("html").addClass((c?"":"no-")+"file-upload");return c})()},storePaste:function(c,b){b=b||new Date();b=(b.getFullYear()+"-"+(b.getMonth()+1)+"-"+b.getDate()+" "+zerobin.getFormatedTime(b));var d=zerobin.getLocalStorageKeys();if(localStorage.length>19){void localStorage.removeItem(d[19])}localStorage.setItem("zerobinV"+zerobin.version+"#"+b,c)},getPreviousPastes:function(){var c=[],d=zerobin.getLocalStorageKeys(),b=zerobin.getFormatedDate();$.each(d,function(g,f){var j=f.replace(/^[^#]+#/,"");var e=j.match(/^(\d+)-(\d+)-(\d+)\s/);e=e[2]+"-"+e[3]+"-"+e[1];var h="the ";if(e===b){e=j.split(" ")[1];h="at "}c.push({displayDate:e,prefix:h,link:localStorage.getItem(f)})});return c},parseUrl:(function(){var b=document.createElement("div");b.innerHTML="";return function(c){b.firstChild.href=c;b.innerHTML=b.innerHTML;return b.firstChild}})(),getPasteId:function(b){var c=b?zerobin.parseUrl(b):window.location;return c.pathname.replace(/\/|paste/g,"")},getPasteKey:function(b){var c=b?zerobin.parseUrl(b):window.location;return c.hash.replace("#","").replace(/(\?|&).*$/,"")},getPasteContent:function(){var b="";$("#paste-content li").each(function(c){b=b+$(this).text().replace(/[\u00a0]+/g," ")+"\n"});return b},count:function(h,d){var g=/(\r?\n|\r)/g;var c=/(\r?\n|\r|\s+)/g;d=d||{};d.lineBreaks=d.lineBreaks||1;var f=h.length,e=f-h.replace(/[\u0100-\uFFFF]/g,"").length,b=f-h.replace(g,"").length;return f+e+Math.max(0,d.lineBreaks*(b-1))},message:function(d,e,f,b,g){$(window).scrollTop(0);if(b){$(".alert-"+d).remove()}var c=$("#alert-template").clone().attr("id",null).addClass("alert alert-"+d);$(".message",c).html(e);if(f){$(".title",c).html(f)}else{$(".title",c).remove()}c.prependTo($("#main")).show("fadeUp",g)},progressBar:function(b){var d=$(b);var c={container:d,elem:d.find(".bar")};c.set=function(f,e){c.elem.text(f).css("width",e)};return c},isCode:function(j){var c=/[A-Z]{3}[A-Z]+|\.[a-z]|[=:<>{}\[\]$_'"&]| {2}|\t/g;var f=/(:?\/\*|)|(\/\/|#)(.*?)\n/g;var h=/[-*=_+]{4,}/;var g=0;var l=0;var b=j.match(f);if(b){g+=j.match(f).length}j=j.replace(f,"");j.replace(h,"");j=j.split("\n");for(var d=0;dg){if(i>l){g*=l/i;i=l}}else{if(g>k){i*=k/g;g=k}}var j=document.createElement("canvas");j.width=i;j.height=g;f.width=i;f.height=g;var h=j.getContext("2d");h.drawImage(this,0,0,i,g);var m=j.toDataURL(c.type);$("#content").val(m).trigger("change");$("#content").hide();$(f).css("max-width","742px");$("#content").after(f)}};b.readAsDataURL(c)}else{b.onload=function(e){$("#content").val(e.target.result).trigger("change")};b.readAsText(c)}}};$(function(){$(".btn-primary").live("click",function(u){u.preventDefault();var t=$("textarea").val();if(t.trim()){var p=$("input, textarea, select, button").prop("disabled",true);var s=zerobin.progressBar("form.well .progress");s.container.show();s.set("Converting paste to bits...","25%");try{var o=$("#expiration").val();var q=zerobin.makeKey();zerobin.encrypt(q,t,a(s.set,"Encoding to base64...","45%"),a(s.set,"Compressing...","65%"),a(s.set,"Encrypting...","85%"),function(v){s.set("Sending...","95%");var x={content:v,expiration:o};var z=zerobin.count(JSON.stringify(x));var y=z>zerobin.max_size;var e=Math.round(z/1024);var w=Math.round(zerobin.max_size/1024);if(y){s.container.hide();p.prop("disabled",false);zerobin.message("error",('The encrypted file was '+e+"KB. You have reached the maximum size limit of "+w+"KB."),"Warning!",true);return}$.post("/paste/create",x).error(function(A){p.prop("disabled",false);s.container.hide();zerobin.message("error","Paste could not be saved. Please try again later.","Error")}).success(function(B){s.set("Redirecting to new paste...","100%");if(B.status==="error"){zerobin.message("error",B.message,"Error");p.prop("disabled",false);s.container.hide()}else{var A="/paste/"+B.paste+"#"+q;if(zerobin.support.localStorage){zerobin.storePaste(A)}window.location=(A)}})})}catch(r){p.prop("disabled",false);s.container.hide();zerobin.message("error","Paste could not be encrypted. Aborting.","Error")}}});var g=$("#paste-content").text().trim();var j=zerobin.getPasteKey();var i=false;if(g&&j){$.getScript("/static/js/vizhash.min.js").done(function(o,p){if(vizhash.supportCanvas){var e=vizhash.canvasHash(zerobin.getPasteId(),24,24);$('').click(function(q){q.preventDefault();if(confirm("This picture is unique to your paste so you can identify it quickly. \n\n Do you want to know more about this?")){window.open("http://is.gd/IJaMRG","_blank")}}).prependTo(".lnk-option").append(e.canvas)}});var m=$("input, textarea, select, button").prop("disabled",true);var h=zerobin.progressBar(".well form .progress");h.container.show();h.set("Decrypting paste...","25%");zerobin.decrypt(j,g,function(){h.container.hide();zerobin.message("error","Could not decrypt data (Wrong key ?)","Error")},a(h.set,"Decompressing...","45%"),a(h.set,"Base64 decoding...","65%"),a(h.set,"From bits to string...","85%"),function(p){$("#paste-content").text(p);if(p.indexOf("data:image")==0){$("#paste-content").hide();var e=$("");$(e).attr("src",p);$(e).css("max-width","742px");$("#paste-content").after(e);$(".btn-clone").hide();var o=$("").attr("href",p);$(o).attr("download","0bin_"+document.location.pathname.split("/").pop());$(o).addClass("btn");$(o).html(' Download');$(".btn-clone").after(o)}h.set("Code coloration...","95%");setTimeout(function(){ZeroClipboard.setMoviePath("/static/js/ZeroClipboard.swf");var r=new ZeroClipboard.Client();var q=function(){r.reposition()};r.addEventListener("mouseup",function(){$("#clip-button").text("Copying paste...");r.setText(zerobin.getPasteContent())});r.addEventListener("complete",function(){$("#clip-button").text("Copy to clipboard");zerobin.message("info","The paste is now in your clipboard","",true,q)});r.glue("clip-button");window.onresize=q;$("#short-url").click(function(s){s.preventDefault();$("#short-url").text("Loading short url...");zerobin.getTinyURL(window.location.toString(),function(t){r.setText(t);$("#copy-success").hide();zerobin.message("success",''+t+"","Short url",true,q);$("#short-url").text("Get short url")})});$(".close").die().live("click",function(s){s.preventDefault();$(this).parent().fadeOut(q)});if(zerobin.isCode(p)>100){$("#paste-content").addClass("linenums");prettyPrint()}else{if(p.indexOf("data:image")!=0){zerobin.message("info","The paste did not seem to be code, so it was not colorized. Force coloration","",false,q)}}$("#paste-content").addClass("done");h.set("Done","100%");h.container.hide();m.prop("disabled",false);p=""},250)})}$(".paste-option select").live("change",function(){$(".paste-option select").val($(this).val())});$("#content").elastic();$("#content").live("keyup change",function(){if($("#content").height()<400){$(".paste-option.down").remove()}else{if($(".paste-option").length===1){$(".paste-option").clone().addClass("down").appendTo("form.well")}}});if(zerobin.support.localStorage){var l=$(".previous-pastes"),n=zerobin.getPreviousPastes();if(n.length){$.getScript("/static/js/vizhash.min.js").done(function(e,o){l.find(".item").remove();$.each(zerobin.getPreviousPastes(),function(r,t){var u=$('
  • ').appendTo(l);var q=$("").attr("href",t.link).text(t.prefix+t.displayDate).appendTo(u);if(vizhash.supportCanvas){var s=zerobin.getPasteId(t.link);var p=vizhash.canvasHash(s,24,24).canvas;q.prepend($(p).addClass("vhash"))}if(t.link.replace(/#[^#]+/,"")===window.location.pathname){u.addClass("active");q.click(function(){window.location=q.attr("href");window.location.reload()})}})})}}$(".btn-clone").click(function(o){o.preventDefault();$(".submit-form").show();$(".paste-form").hide();$("#content").val(zerobin.getPasteContent()).trigger("change")});$(".clone .btn-danger").click(function(o){o.preventDefault();$(".submit-form").hide();$(".paste-form").show()});if(zerobin.support.fileUpload){var d=$("#file-upload");var b=$(".btn-upload");try{b.val("Uploading...");b.prop("disabled",true);d.change(function(){zerobin.upload(this.files)})}catch(f){zerobin.message("error","Could no upload the file","Error");b.val("Upload File");b.prop("disabled",false)}b.prop("disabled",false);b.val("Upload File");d.mouseover(a($(this).css,"cursor","pointer"));$("#content").bind("drop",zerobin.handleDrop);$("#content").bind("dragover",zerobin.handleDragOver);$("#content").bind("dragleave",zerobin.handleDragLeave)}$(".close").live("click",function(o){o.preventDefault();$(this).parent().fadeOut()});$(".email-link").each(function(p,q){var s=$(this);var e=s.attr("title").replace("__AT__","@");var r=s.text().replace("__AT__","@");var o=$(''+r+"");s.replaceWith(o)});$("#wrap-content").each(function(e,o){$(o).show()});if(zerobin.support.history&&zerobin.paste_not_found){var c=zerobin.getPasteId();var k=zerobin.getLocalStorageKeys();$.each(k,function(o,e){if(localStorage[e].indexOf(c)!==-1){localStorage.removeItem(e);return false}})}$("#force-coloration").live("click",function(o){o.preventDefault();$("#paste-content").addClass("linenums");$(this).die(o).text("Applying coloration");prettyPrint();$(this).remove()});$("#email-link").click(function(){zerobin.getTinyURL(window.location.toString(),function(e){window.open("mailto:friend@example.com?body="+e)});return false})})})(); \ No newline at end of file diff --git a/zerobin/views/base.tpl b/zerobin/views/base.tpl index c8b01d3..9de5446 100644 --- a/zerobin/views/base.tpl +++ b/zerobin/views/base.tpl @@ -132,7 +132,7 @@ %if settings.DISPLAY_COUNTER:

    ø

    - {{ pastes_count }}
    pastes øbinned + {{ pastes_count }}
    pastes øbinned

    %end diff --git a/zerobin/views/paste.tpl b/zerobin/views/paste.tpl index e7aabe2..be5993d 100644 --- a/zerobin/views/paste.tpl +++ b/zerobin/views/paste.tpl @@ -72,14 +72,14 @@

    -

    +

    -

    +