comparison browser/sat_browser/file_tools.py @ 1124:28e3eb3bb217

files reorganisation and installation rework: - files have been reorganised to follow other SàT projects and usual Python organisation (no more "/src" directory) - VERSION file is now used, as for other SàT projects - replace the overcomplicated setup.py be a more sane one. Pyjamas part is not compiled anymore by setup.py, it must be done separatly - removed check for data_dir if it's empty - installation tested working in virtual env - libervia launching script is now in bin/libervia
author Goffi <goffi@goffi.org>
date Sat, 25 Aug 2018 17:59:48 +0200
parents src/browser/sat_browser/file_tools.py@f2170536ba23
children 2af117bfe6cc
comparison
equal deleted inserted replaced
1123:63a4b8fe9782 1124:28e3eb3bb217
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # Libervia: a Salut à Toi frontend
5 # Copyright (C) 2011-2018 Jérôme Poisson <goffi@goffi.org>
6
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20 from sat.core.log import getLogger
21 log = getLogger(__name__)
22 from constants import Const as C
23 from sat.core.i18n import _, D_
24 from pyjamas.ui.FileUpload import FileUpload
25 from pyjamas.ui.FormPanel import FormPanel
26 from pyjamas import Window
27 from pyjamas import DOM
28 from pyjamas.ui.VerticalPanel import VerticalPanel
29 from pyjamas.ui.HTML import HTML
30 from pyjamas.ui.HorizontalPanel import HorizontalPanel
31 from pyjamas.ui.Button import Button
32 from pyjamas.ui.Label import Label
33
34
35 class FilterFileUpload(FileUpload):
36
37 def __init__(self, name, max_size, types=None):
38 """
39 @param name: the input element name and id
40 @param max_size: maximum file size in MB
41 @param types: allowed types as a list of couples (x, y, z):
42 - x: MIME content type e.g. "audio/ogg"
43 - y: file extension e.g. "*.ogg"
44 - z: description for the user e.g. "Ogg Vorbis Audio"
45 If types is None, all file format are accepted
46 """
47 FileUpload.__init__(self)
48 self.setName(name)
49 while DOM.getElementById(name):
50 name = "%s_" % name
51 self.setID(name)
52 self._id = name
53 self.max_size = max_size
54 self.types = types
55
56 def getFileInfo(self):
57 from __pyjamas__ import JS
58 JS("var file = top.document.getElementById(this._id).files[0]; return [file.size, file.type]")
59
60 def check(self):
61 if self.getFilename() == "":
62 return False
63 (size, filetype) = self.getFileInfo()
64 if self.types and filetype not in [x for (x, y, z) in self.types]:
65 types = []
66 for type_ in ["- %s (%s)" % (z, y) for (x, y, z) in self.types]:
67 if type_ not in types:
68 types.append(type_)
69 Window.alert('This file type is not accepted.\nAccepted file types are:\n\n%s' % "\n".join(types))
70 return False
71 if size > self.max_size * pow(2, 20):
72 Window.alert('This file is too big!\nMaximum file size: %d MB.' % self.max_size)
73 return False
74 return True
75
76
77 class FileUploadPanel(FormPanel):
78
79 def __init__(self, action_url, input_id, max_size, texts=None, close_cb=None):
80 """Build a form panel to upload a file.
81 @param action_url: the form action URL
82 @param input_id: the input element name and id
83 @param max_size: maximum file size in MB
84 @param texts: a dict to ovewrite the default textual values
85 @param close_cb: the close button callback method
86 """
87 FormPanel.__init__(self)
88 self.texts = {'ok_button': D_('Upload file'),
89 'cancel_button': D_('Cancel'),
90 'body': D_('Please select a file.'),
91 'submitting': D_('<strong>Submitting, please wait...</strong>'),
92 'errback': D_("Your file has been rejected..."),
93 'body_errback': D_('Please select another file.'),
94 'callback': D_("Your file has been accepted!")}
95 if isinstance(texts, dict):
96 self.texts.update(texts)
97 self.close_cb = close_cb
98 self.setEncoding(FormPanel.ENCODING_MULTIPART)
99 self.setMethod(FormPanel.METHOD_POST)
100 self.setAction(action_url)
101 self.vPanel = VerticalPanel()
102 self.message = HTML(self.texts['body'])
103 self.vPanel.add(self.message)
104
105 hPanel = HorizontalPanel()
106 hPanel.setSpacing(5)
107 hPanel.setStyleName('marginAuto')
108 self.file_upload = FilterFileUpload(input_id, max_size)
109 self.vPanel.add(self.file_upload)
110
111 self.upload_btn = Button(self.texts['ok_button'], getattr(self, "onSubmitBtnClick"))
112 hPanel.add(self.upload_btn)
113 hPanel.add(Button(self.texts['cancel_button'], getattr(self, "onCloseBtnClick")))
114
115 self.status = Label()
116 hPanel.add(self.status)
117
118 self.vPanel.add(hPanel)
119
120 self.add(self.vPanel)
121 self.addFormHandler(self)
122
123 def setCloseCb(self, close_cb):
124 self.close_cb = close_cb
125
126 def onCloseBtnClick(self):
127 if self.close_cb:
128 self.close_cb()
129 else:
130 log.warning("no close method defined")
131
132 def onSubmitBtnClick(self):
133 if not self.file_upload.check():
134 return
135 self.message.setHTML(self.texts['submitting'])
136 self.upload_btn.setEnabled(False)
137 self.submit()
138
139 def onSubmit(self, event):
140 pass
141
142 def onSubmitComplete(self, event):
143 result = event.getResults()
144 if result == C.UPLOAD_KO:
145 Window.alert(self.texts['errback'])
146 self.message.setHTML(self.texts['body_errback'])
147 self.upload_btn.setEnabled(True)
148 elif result == C.UPLOAD_OK:
149 Window.alert(self.texts['callback'])
150 self.close_cb()
151 else:
152 Window.alert(_('Submit error: %s' % result))
153 self.upload_btn.setEnabled(True)
154
155
156 class AvatarUpload(FileUploadPanel):
157 def __init__(self):
158 texts = {'ok_button': 'Upload avatar',
159 'body': 'Please select an image to show as your avatar...<br>Your picture must be a square and will be resized to 64x64 pixels if necessary.',
160 'errback': "Can't open image... did you actually submit an image?",
161 'body_errback': 'Please select another image file.',
162 'callback': "Your new profile picture has been set!"}
163 FileUploadPanel.__init__(self, 'upload_avatar', 'avatar_path', 2, texts)