diff --git a/zerobin/paste.py b/zerobin/paste.py index de9b640..33aecd9 100644 --- a/zerobin/paste.py +++ b/zerobin/paste.py @@ -101,9 +101,9 @@ class Paste(object): expiration = datetime.strptime(expiration, "%Y-%m-%d %H:%M:%S.%f") except StopIteration: - raise TypeError(to_ascii("File %s is malformed" % path)) + raise TypeError("File %s is malformed" % path) except (IOError, OSError): - raise ValueError(to_ascii("Can not open paste from file %s" % path)) + raise ValueError("Can not open paste from file %s" % path) return Paste(uuid=uuid, expiration=expiration, content=content) @@ -228,3 +228,19 @@ class Paste(object): Delete the paste file. """ os.remove(self.path) + + @classmethod + def iter_all(cls, on_error=lambda e: e): + for p in settings.PASTE_FILES_ROOT.rglob("*"): + if p.is_file() and "counter" not in str(p): + try: + yield Paste.load_from_file(p) + except (TypeError, ValueError) as e: + on_error(e) + + @property + def has_expired(self): + try: + return self.expiration < datetime.now() + except TypeError: + return False diff --git a/zerobin/static/css/style.css b/zerobin/static/css/style.css index c5d0ec4..35d7946 100644 --- a/zerobin/static/css/style.css +++ b/zerobin/static/css/style.css @@ -176,7 +176,7 @@ input.hide-upload { filter: alpha(opacity=0); opacity: 0; z-index: 2; - width: 80px; + width: 0; margin-top: -20px; cursor: pointer; cursor: hand; @@ -230,6 +230,7 @@ li.L9 { pre.prettyprint { width: 100%; min-height: 100px; + padding: 5px; } /* Specify class=linenums on a pre to get line numbering */ diff --git a/zerobin/static/js/behavior.js b/zerobin/static/js/behavior.js index 5f43a78..19559a2 100644 --- a/zerobin/static/js/behavior.js +++ b/zerobin/static/js/behavior.js @@ -23,7 +23,6 @@ const app = new Vue({ el: '#app', data: { previousPastes: [], - downloadLink: {}, displayBottomToolBar: false, openPreviousPastesMenu: false, readerMode: false, @@ -32,7 +31,8 @@ const app = new Vue({ ownerKey: '', id: '', type: '', - content: '' + content: '', + downloadLink: {}, }, newPaste: { expiration: '1_day', @@ -45,6 +45,8 @@ const app = new Vue({ clipboard: !!(isSecureContext && navigator.clipboard && navigator.clipboard.writeText), + URLSearchParams: !!window.URLSearchParams, + localStorage: (function () { var val = !!(localStorage); document.querySelector('html').classList.add((val ? '' : 'no-') + 'local-storage'); @@ -69,8 +71,20 @@ const app = new Vue({ methods: { toggleReaderMode: function () { + debugger; if (!this.readerMode) { this.messages = []; + if (this.support.URLSearchParams) { + var searchParams = new URLSearchParams(window.location.search) + searchParams.set('readerMode', 1); + window.location.search = searchParams.toString(); + } + } else { + if (this.support.URLSearchParams) { + var searchParams = new URLSearchParams(window.location.search); + searchParams.delete('readerMode'); + window.location.search = searchParams.toString(); + } } this.readerMode = !this.readerMode; @@ -387,6 +401,7 @@ window.zerobin = { doneCallback(content); } } catch (err) { + debugger; errorCallback(err); } @@ -628,23 +643,31 @@ window.zerobin = { } } - // return total * 250 / size; return total * 1000 / size; }, - // prevent defaults ignoreDrag: function (e) { e.stopPropagation(); e.preventDefault(); }, - // Handle Drop handleDrop: function (e) { e.preventDefault(); zerobin.upload(e.dataTransfer.files); document.getElementById("content").classList.remove("hover"); }, + handlePaste: function (e) { + var items = (event.clipboardData || event.originalEvent.clipboardData).items; + for (var i = 0; i < items.length; i++) { + if (items[i].type.indexOf("image") === 0) { + e.preventDefault() + return zerobin.upload([items[i].getAsFile()]); + } + } + + }, + handleDragOver: function (e) { zerobin.ignoreDrag(e); document.getElementById("content").classList.add('hover'); @@ -656,58 +679,29 @@ window.zerobin = { upload: function (files) { let content = document.getElementById('content'); - var current_file = files[0]; + var currentFile = files[0]; var reader = new FileReader(); - if (current_file.type.indexOf('image') == 0) { + if (currentFile.type.indexOf('image') == 0) { reader.onload = function (event) { var image = new Image(); image.src = event.target.result; + content.value = 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.value = paste; - content.dispatchEvent(new Event('change')); - - image.style.maxWidth = '742px'; - + var imgWrapper = document.createElement('div'); + imgWrapper.classList.add('paste-wrapper'); + imgWrapper.appendChild(image) content.style.display = "none"; - content.after(image); - + content.after(imgWrapper); } } - reader.readAsDataURL(current_file); + reader.readAsDataURL(currentFile); } else { reader.onload = function (event) { content.value = event.target.result content.dispatchEvent(new Event('change')); }; - reader.readAsText(current_file); + reader.readAsText(currentFile); } } }; @@ -755,9 +749,7 @@ if (content && key) { /* When done */ function (content) { - /* Decrypted content goes back to initial container*/ - document.querySelector('#paste-content').innerText = content; - app.currentPaste.content = content + let readerMode = false; if (content.indexOf('data:image') == 0) { // Display Image @@ -770,21 +762,34 @@ if (content && key) { imgWrapper.classList.add('paste-wrapper'); var img = document.createElement('img'); img.src = content; - //img.style.maxWidth = '742px'; pasteContent.after(imgWrapper); imgWrapper.appendChild(img); - // Display Download button document.querySelectorAll('.btn-clone').forEach((node) => node.style.display = "none") - app.downloadLink = { - name: '0bin_' + document.location.pathname.split('/').pop(), + let extension = /data:image\/([^;]+);base64/.exec(content)[1]; + + app.currentPaste.downloadLink = { + name: '0bin_' + document.location.pathname.split('/').pop() + '.' + extension, url: content } } else { app.currentPaste.type = "text" + /* Decrypted content goes back to initial container*/ + document.querySelector('#paste-content').innerText = content; + app.currentPaste.content = content + + app.currentPaste.downloadLink = { + name: '0bin_' + document.location.pathname.split('/').pop() + ".txt", + url: "data:text/html;charset=UTF-8," + content + } + + if (app.support.URLSearchParams) { + readerMode = (new URLSearchParams(window.location.search)).get('readerMode'); + } + } bar.set('Code coloration...', '95%'); @@ -793,7 +798,7 @@ if (content && key) { /** Syntaxic coloration */ - if (zerobin.isCode(content) > 100) { + if (zerobin.isCode(content) > 100 && !readerMode) { document.getElementById('paste-content').classList.add('linenums'); prettyPrint(); } else { @@ -817,6 +822,9 @@ if (content && key) { form.forEach((node) => node.disabled = false); content = ''; + if (readerMode) { + app.toggleReaderMode() + } }, 100); @@ -862,6 +870,7 @@ if (app.support.fileUpload) { // Implements drag & drop upload let content = document.getElementById('content'); content.addEventListener('drop', zerobin.handleDrop); + content.addEventListener('paste', zerobin.handlePaste); content.addEventListener('dragover', zerobin.handleDragOver); content.addEventListener('dragleave', zerobin.handleDragLeave); diff --git a/zerobin/views/base.tpl b/zerobin/views/base.tpl index 9689de9..29df04e 100644 --- a/zerobin/views/base.tpl +++ b/zerobin/views/base.tpl @@ -60,10 +60,10 @@