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;e
zerobin.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 @@
-
+