adapt strongbox support to the revised file widget (#1959)

This commit is contained in:
Frédéric Péters 2013-04-05 18:55:55 +02:00
parent 933e8c7fc5
commit c24c0df8c8
6 changed files with 92 additions and 160 deletions

View File

@ -677,3 +677,7 @@ table#strongbox-items tr.even {
table#strongbox-items tr.odd {
background: #eee;
}
p.use-file-from-strongbox span {
cursor: pointer;
}

View File

@ -1,137 +1,14 @@
from quixote.form.widget import ButtonWidget
from qommon.form import *
from qommon import get_cfg, get_logger
from strongbox import StrongboxItem
class FileWithPreviewAndStrongboxWidget(CompositeWidget):
"""Widget that proposes a File Upload widget but that stores the file
ondisk so it has a "readonly" mode where the filename is shown."""
token = None
def __init__(self, name, value=None, **kwargs):
CompositeWidget.__init__(self, name, value, **kwargs)
self.value = value
self.preview = kwargs.get('readonly')
preview = kwargs.get('readonly')
if not preview:
del kwargs['title']
if kwargs.has_key('hint'):
del kwargs['hint']
self.add(FileWidget, 'file', **kwargs)
self.add(HiddenWidget, 'existing-file-token')
self.add(CheckboxWidget, 'orexisting',
title = _('Or use previous file'), value=True)
if get_cfg('misc', {}).get('aq-strongbox') and get_request().user:
self.add(HiddenWidget, 'strongbox');
else:
session = get_session()
self.add(HiddenWidget, 'token')
del kwargs['title']
self.add(StringWidget, 'filename', **kwargs)
if self.value and self.value.orig_filename:
wid = self.get_widget('filename')
get_request().form[wid.name] = self.value.orig_filename
# Is this still mandatory ?
if hasattr(get_request(), 'tempfiles'):
if name in get_request().tempfiles:
token = get_request().tempfiles[name]
wid = self.get_widget('token')
get_request().form[wid.name] = token
def render_content(self):
r = TemplateIO(html=True)
hasvalue = False
if isinstance(self.value, PicklableUpload):
filetype = mimetypes.guess_type(self.value.orig_filename)
hasvalue = True
if filetype and filetype[0] and filetype[0].startswith("image"):
session = get_session()
if session.tempfiles and self.token in session.tempfiles.keys():
session.tempfiles[self.token]['value'] = self.value.fp.read()
r += htmltext('<img alt="%s" src="tempfile?t=%s" />' % \
(self.value.orig_filename,
self.token))
self.value.fp.seek(0)
for widget in self.get_widgets():
if widget is self.get_widget('orexisting'):
if not hasvalue:
continue
widget.title = _('Or use previously uploaded file (%s)') % self.value.orig_filename
widget.value = True
widget.extra_css_class = 'or-existing'
widget.render_br = False
get_response().add_javascript(['jquery.js', 'fileupload.js'])
if widget is self.get_widget('existing-file-token'):
if not hasvalue:
continue
widget.value = get_session().add_tempfile(self.value)
r += widget.render()
return r.getvalue()
class FileWithPreviewAndStrongboxWidget(FileWithPreviewWidget):
def render_hint(self, hint):
t = CompositeWidget.render_hint(self, hint)
if get_cfg('misc', {}).get('aq-strongbox') and get_request().user:
if get_publisher().has_site_option('strongbox') and get_request().user and not self.preview:
get_response().add_javascript(['../../aq/js/strongbox.js'])
root_url = get_publisher().get_root_url()
t += htmltext('''<p class="use-file-from-strongbox"><a
href="%smyspace/strongbox/pick?id=%s"
rel="popup">%s</a></p>''') % (
t += htmltext('''<p class="use-file-from-strongbox"><span
data-url="%smyspace/strongbox/pick?id=%s"
rel="popup">%s</span></p>''') % (
root_url, self.name, _('Use file from strongbox'))
return t
def _parse(self, request):
session = get_session()
if self.get('file') or self.get('orexisting') or self.get('strongbox'):
if self.get('strongbox'):
sffile = StrongboxItem.get(self.get('strongbox'))
if sffile.user_id == get_request().user.id:
self.value = Upload(os.path.basename(sffile.file.orig_filename), sffile.file.content_type)
self.value.fp = file(sffile.file.filename)
token = get_session().add_tempfile(self.value)
if not hasattr(get_request(), 'tempfiles'):
get_request().tempfiles = {}
get_request().tempfiles[self.name] = token
self.value = None
self.get_widget('file').clear_error()
elif self.get('file'):
self.value = self.get('file')
token = get_session().add_tempfile(self.value)
if not hasattr(get_request(), 'tempfiles'):
get_request().tempfiles = {}
get_request().tempfiles[self.name] = token
self.value = None
else:
token = self.get('existing-file-token')
if not hasattr(get_request(), 'tempfiles'):
get_request().tempfiles = {}
get_request().tempfiles[self.name] = token
self.get_widget('file').clear_error()
else:
token = self.get('token')
if session.tempfiles and session.tempfiles.has_key(token):
self.token = token
if not isinstance(self.value, PicklableUpload):
self.value = PicklableUpload(session.tempfiles[token]['orig_filename'],
session.tempfiles[token]['content_type'],
session.tempfiles[token]['charset'])
self.value.fp = tempfile.TemporaryFile()
dirname = os.path.join(get_publisher().app_dir, 'tempfiles')
filename = os.path.join(dirname, token)
if os.path.exists(filename):
self.value.fp.write(open(filename).read())
else:
# looks like the file has been removed from under our
# feets, keep going, the user will have to reupload.
self.value = None
if self.value:
self.value.get_file_pointer().seek(0)
def cleanup(self):
if self.token:
dirname = os.path.join(get_publisher().app_dir, 'tempfiles')
filename = os.path.join(dirname, self.token)
if os.path.exists(filename):
os.unlink(filename)

View File

@ -310,44 +310,51 @@ class StrongboxDirectory(Directory):
sffile.remove_file()
return redirect('.')
def picked_file(self):
get_response().set_content_type('application/json')
sffile = StrongboxItem.get(get_request().form.get('val'))
sffile.file.fp = file(sffile.file.filename)
if sffile.user_id != get_request().user.id:
raise errors.TraversalError()
# XXX: this will copy the file, it would be quite nice if it was
# possible to just make it a symlink to the sffile
token = get_session().add_tempfile(sffile.file)
return json.dumps({'token': token, 'filename': sffile.file.base_filename})
def pick [html] (self):
if get_request().form.get('select') == 'true':
return self.picked_file()
field_id = str(get_request().form.get('id'))
root_url = get_publisher().get_root_url()
sffiles = StrongboxItem.get_with_indexed_value(
str('user_id'), str(get_request().user.id))
'''
<script type="text/javascript">
function pick_file()
{
filewidget = $('input[name=%(id)s$file]');
filewidget.attr('disabled', 'disabled');
value = $('input[name=pick]:checked').val();
$('input[name=%(id)s$strongbox]').val(value);
$.modal.close();
return false;
}
</script>
''' % {'id': field_id}
'<form id="strongbox-pick">'
'<ul>'
for sffile in sffiles:
'<li><input type="radio" name="pick" value="%s"><label for="%s">%s</label>' % (
sffile.id, sffile.id, sffile.get_display_name())
' [<a href="download?id=%s">%s</a>] ' % (sffile.id, _('view'))
'</input>'
'</li>'
'</ul>'
'<p class="popup-buttons">'
'<a class="button" href="#" onclick="return pick_file()">%s</a>' % _('Select')
'<a class="button cancel" href="#">%s</a>' % _('Cancel')
'</p>'
'</form>'
'<h2>%s</h2>' % _('Pick a file')
root_url = get_publisher().get_root_url()
'<p>'
'<a href="%smyspace/strongbox/" target="_blank">%s</a>' % (root_url,
if not sffiles:
'<p>'
_('You do not have any file in your strongbox at the moment.')
'</p>'
'<div class="buttons">'
'<a href="%smyspace/strongbox/" target="_blank">%s</a>' % (root_url,
_('Open Strongbox Management'))
'</p>'
'</div>'
else:
'<form id="strongbox-pick">'
'<ul>'
for sffile in sffiles:
'<li><label><input type="radio" name="file" value="%s"/>%s</label>' % (
sffile.id, sffile.get_display_name())
' [<a href="%smyspace/strongbox/download?id=%s">%s</a>] ' % (
root_url, sffile.id, _('view'))
'</li>'
'</ul>'
'<div class="buttons">'
'<input name="cancel" type="button" value="%s"/>' % _('Cancel')
' '
'<input name="pick" type="button" value="%s"/>' % _('Pick')
'</div>'
'</form>'
class JsonDirectory(Directory):
'''Export of several lists in json, related to the current user or the

View File

@ -725,6 +725,7 @@ class AlternateRootDirectory(OldRootDirectory):
('announces', 'announces_dir'),
'accessibility', 'contact', 'help',
'myspace', 'services', 'agenda',
('tmp-upload', 'tmp_upload'),
'themes', 'pages', 'payment', 'invoices', 'accesscode']
admin = admin.AdminRootDirectory()
@ -794,6 +795,10 @@ class AlternateRootDirectory(OldRootDirectory):
dirname = os.path.join(get_publisher().data_dir, 'qommon')
return StaticDirectory(dirname, follow_symlinks = True)
if component == 'aq':
dirname = os.path.join(get_publisher().data_dir, 'qommon', 'auquotidien')
return StaticDirectory(dirname, follow_symlinks = True)
if component in ('css','images'):
return OldRootDirectory._q_lookup(self, component)

View File

@ -29,5 +29,6 @@ distutils.core.setup(
data_tree('share/wcs/themes/auquotidien', 'theme') +\
data_tree('share/wcs/themes/', 'data/themes/') + \
data_tree('share/auquotidien/apache-errors', 'apache-errors') +\
data_tree('share/wcs/qommon/auquotidien', 'static/')
[('share/wcs/', ('au-quotidien-wcs-settings.xml',))]
)

38
static/js/strongbox.js Normal file
View File

@ -0,0 +1,38 @@
$(function() {
$('p.use-file-from-strongbox span').click(function(e) {
var url = $(this).data('url');
var base_widget = $(this).parents('.file-upload-widget');
$.ajax({
url: url,
beforeSend: function(xhr) {xhr.setRequestHeader('X-Popup', 'true'); },
success: function(html) {
console.log('success');
var title = $(html).find('h2').text();
var dialog = $(html).dialog({
modal: true,
title: title,
width: 'auto'
});
$(dialog).find('h2').remove();
$(dialog).find('.buttons a').click(function() { $(dialog).dialog('destroy'); return true;});
$(dialog).find('input[name=cancel]').click(function() { $(dialog).dialog('destroy'); return false;});
$(dialog).find('input[name=pick]').click(function() {
var json_url = url + '&select=true&val=' + $(dialog).find('input[name=file]:checked').val();
console.log('json url:', json_url);
$.getJSON(json_url, function(data, textStatus, jqXHR) {
console.log('data:', data);
$(base_widget).find('.filename').text(data.filename);
$(base_widget).find('.fileinfo').show();
$(base_widget).find('input[type=hidden]').val(data.token);
$(base_widget).find('input[type=file]').hide();
}
);
$(dialog).dialog('destroy');
return false;
});
return false;
}
});
return false;
});
});