Mercurial > libervia-web
diff src/browser/sat_browser/file_tools.py @ 467:97c72fe4a5f2
browser_side: import fixes:
- moved browser modules in a sat_browser packages, to avoid import conflicts with std lib (e.g. logging), and let pyjsbuild work normaly
- refactored bad import practices: classes are most of time not imported directly, module is imported instead.
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 09 Jun 2014 22:15:26 +0200 |
parents | src/browser/file_tools.py@981ed669d3b3 |
children | bbdc5357dc00 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/browser/sat_browser/file_tools.py Mon Jun 09 22:15:26 2014 +0200 @@ -0,0 +1,148 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Libervia: a Salut à Toi frontend +# Copyright (C) 2011, 2012, 2013, 2014 Jérôme Poisson <goffi@goffi.org> + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from sat.core.log import getLogger +log = getLogger(__name__) +from pyjamas.ui.FileUpload import FileUpload +from pyjamas.ui.FormPanel import FormPanel +from pyjamas import Window +from pyjamas import DOM +from pyjamas.ui.VerticalPanel import VerticalPanel +from pyjamas.ui.HTML import HTML +from pyjamas.ui.HorizontalPanel import HorizontalPanel +from pyjamas.ui.Button import Button +from pyjamas.ui.Label import Label + + +class FilterFileUpload(FileUpload): + + def __init__(self, name, max_size, types=None): + """ + @param name: the input element name and id + @param max_size: maximum file size in MB + @param types: allowed types as a list of couples (x, y, z): + - x: MIME content type e.g. "audio/ogg" + - y: file extension e.g. "*.ogg" + - z: description for the user e.g. "Ogg Vorbis Audio" + If types is None, all file format are accepted + """ + FileUpload.__init__(self) + self.setName(name) + while DOM.getElementById(name): + name = "%s_" % name + self.setID(name) + self._id = name + self.max_size = max_size + self.types = types + + def getFileInfo(self): + from __pyjamas__ import JS + JS("var file = top.document.getElementById(this._id).files[0]; return [file.size, file.type]") + + def check(self): + if self.getFilename() == "": + return False + (size, filetype) = self.getFileInfo() + if self.types and filetype not in [x for (x, y, z) in self.types]: + types = [] + for type_ in ["- %s (%s)" % (z, y) for (x, y, z) in self.types]: + if type_ not in types: + types.append(type_) + Window.alert('This file type is not accepted.\nAccepted file types are:\n\n%s' % "\n".join(types)) + return False + if size > self.max_size * pow(2, 20): + Window.alert('This file is too big!\nMaximum file size: %d MB.' % self.max_size) + return False + return True + + +class FileUploadPanel(FormPanel): + + def __init__(self, action_url, input_id, max_size, texts=None, close_cb=None): + """Build a form panel to upload a file. + @param action_url: the form action URL + @param input_id: the input element name and id + @param max_size: maximum file size in MB + @param texts: a dict to ovewrite the default textual values + @param close_cb: the close button callback method + """ + FormPanel.__init__(self) + self.texts = {'ok_button': 'Upload file', + 'cancel_button': 'Cancel', + 'body': 'Please select a file.', + 'submitting': '<strong>Submitting, please wait...</strong>', + 'errback': "Your file has been rejected...", + 'body_errback': 'Please select another file.', + 'callback': "Your file has been accepted!"} + if isinstance(texts, dict): + self.texts.update(texts) + self.close_cb = close_cb + self.setEncoding(FormPanel.ENCODING_MULTIPART) + self.setMethod(FormPanel.METHOD_POST) + self.setAction(action_url) + self.vPanel = VerticalPanel() + self.message = HTML(self.texts['body']) + self.vPanel.add(self.message) + + hPanel = HorizontalPanel() + hPanel.setSpacing(5) + hPanel.setStyleName('marginAuto') + self.file_upload = FilterFileUpload(input_id, max_size) + self.vPanel.add(self.file_upload) + + self.upload_btn = Button(self.texts['ok_button'], getattr(self, "onSubmitBtnClick")) + hPanel.add(self.upload_btn) + hPanel.add(Button(self.texts['cancel_button'], getattr(self, "onCloseBtnClick"))) + + self.status = Label() + hPanel.add(self.status) + + self.vPanel.add(hPanel) + + self.add(self.vPanel) + self.addFormHandler(self) + + def setCloseCb(self, close_cb): + self.close_cb = close_cb + + def onCloseBtnClick(self): + if self.close_cb: + self.close_cb() + else: + log.warning("no close method defined") + + def onSubmitBtnClick(self): + if not self.file_upload.check(): + return + self.message.setHTML(self.texts['submitting']) + self.upload_btn.setEnabled(False) + self.submit() + + def onSubmit(self, event): + pass + + def onSubmitComplete(self, event): + result = event.getResults() + if result != "OK": + Window.alert(self.texts['errback']) + self.message.setHTML(self.texts['body_errback']) + self.upload_btn.setEnabled(True) + else: + Window.alert(self.texts['callback']) + self.close_cb()