[Mpuls-commits] r1911 - in wasko/branches/2.0: . mpulsweb/controllers mpulsweb/lib mpulsweb/model mpulsweb/templates/documents
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Mon Mar 8 16:22:34 CET 2010
Author: torsten
Date: 2010-03-08 16:22:31 +0100 (Mon, 08 Mar 2010)
New Revision: 1911
Modified:
wasko/branches/2.0/ChangeLog
wasko/branches/2.0/mpulsweb/controllers/casedocument.py
wasko/branches/2.0/mpulsweb/controllers/document.py
wasko/branches/2.0/mpulsweb/lib/validators.py
wasko/branches/2.0/mpulsweb/model/document.py
wasko/branches/2.0/mpulsweb/templates/documents/case_new.mako
wasko/branches/2.0/mpulsweb/templates/documents/global_upload.mako
Log:
Fixed wald issue 1288
Modified: wasko/branches/2.0/ChangeLog
===================================================================
--- wasko/branches/2.0/ChangeLog 2010-03-08 12:04:18 UTC (rev 1910)
+++ wasko/branches/2.0/ChangeLog 2010-03-08 15:22:31 UTC (rev 1911)
@@ -11,8 +11,20 @@
* waskaweb/lib/validators.py:Do not import StringTooLong validator
* mpulsweb/lib/validators.py (StringTooLong): Deleted. Not used
anymore.
-
+ Fileuploads
+
+ * mpulsweb/model/document.py,
+ mpulsweb/controllers/casedocument.py,
+ mpulsweb/controllers/document.py,
+ mpulsweb/lib/validators.py,
+ mpulsweb/templates/documents/case_new.mako,
+ mpulsweb/templates/documents/global_upload.mako: Changed upload
+ logic. Now the user can give an optional name for documents. This
+ enables saving files under an alternativ name. Further the user can
+ select if he wants to overwrite any existing files with the same
+ name. For that some new validator logic was written.
+
2010-03-05 Torsten Irländer <torsten.irlaender at intevation.de>
* mpulsweb/lib/validators.py (LoginCheck.validate_python): Fixed mpuls
Modified: wasko/branches/2.0/mpulsweb/controllers/casedocument.py
===================================================================
--- wasko/branches/2.0/mpulsweb/controllers/casedocument.py 2010-03-08 12:04:18 UTC (rev 1910)
+++ wasko/branches/2.0/mpulsweb/controllers/casedocument.py 2010-03-08 15:22:31 UTC (rev 1911)
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import logging
+import formencode
import paste
@@ -7,6 +8,7 @@
from pylons.controllers.util import redirect_to
from mpulsweb.lib.base import BaseController, render
+from mpulsweb.lib.validators import UploadCaseDocumentForm
from mpulsweb.lib.security import checkRole
import mpulsweb.lib.helpers as h
@@ -50,36 +52,30 @@
@checkRole('cm_ka')
def newAction(self):
+ validator = UploadCaseDocumentForm()
try:
- case = int(request.POST['case'])
- except:
- redirect_to(controller="casedocument", action="index")
-
- try:
+ result = validator.to_python(request.params)
doc = Document()
- myfile = None
- try:
- myfile = request.POST.get('file')
- if not myfile is None:
- doc.create(myfile.filename, myfile.file, case)
- c.success_for = SET_ATTACHMENT_SUCCESS_HEADER
- c.success_text = SET_ATTACHMENT_SUCCESS_TEXT
- c.url_ok = h.url_for(controller="/casedocument",
- action="index", id=case)
- return render('/documents/dialogs/success_attachment.mako')
- finally:
- if not myfile is None:
- try:
- myfile.file.close()
- except:
- pass
- except Exception, e:
- log.exception(e)
- c.failed_for = SET_ATTACHMENT_FAILED_HEADER
- c.failed_text = SET_ATTACHMENT_FAILED_TEXT
+ filename = result['file']['filename']
+ content = result['file']['content']
+ case = result['case']
+ if result['name']:
+ filename = result['name']
+ doc.create(filename, content, case)
+ c.dialog_title = SET_ATTACHMENT_SUCCESS_HEADER
+ c.dialog_text = SET_ATTACHMENT_SUCCESS_TEXT
c.url_ok = h.url_for(controller="/casedocument",
- action="new", id=case)
- return render('/documents/dialogs/failed_attachment.mako')
+ action="index", id=case)
+ return render('/documents/dialogs/success_attachment.mako')
+ except formencode.Invalid, error:
+ c.form_result = error.value
+ c.form_errors = error.error_dict or {}
+ log.debug(c.form_result)
+ form = render('/documents/case_new.mako')
+ return formencode.htmlfill.render(unicode(form, 'utf-8'),
+ defaults=c.form_result,
+ auto_insert_errors=False,
+ errors=c.form_errors)
@checkRole(('admin_ka', 'cm_ka'))
def show(self, id):
Modified: wasko/branches/2.0/mpulsweb/controllers/document.py
===================================================================
--- wasko/branches/2.0/mpulsweb/controllers/document.py 2010-03-08 12:04:18 UTC (rev 1910)
+++ wasko/branches/2.0/mpulsweb/controllers/document.py 2010-03-08 15:22:31 UTC (rev 1911)
@@ -28,12 +28,14 @@
# Sascha L. Teichmann <teichmann at intevation.de>
#
import logging
+import formencode
import paste
from pylons import config
from mpulsweb.lib.base import BaseController, c, h, redirect_to, render, request
from mpulsweb.lib.security import checkRole
+from mpulsweb.lib.validators import UploadGlobalDocumentForm
from mpulsweb.model.document import Document, listDocuments, deleteDocument
SET_DOCUMENT_SUCCESS_HEADER = u"""Dokument hinzugefügt!"""
@@ -91,30 +93,29 @@
@checkRole('admin_ka')
def globalUploadAction(self):
+ validator = UploadGlobalDocumentForm()
try:
+ result = validator.to_python(request.params)
doc = Document()
- myfile = None
- try:
- myfile = request.POST.get('file')
- if not myfile is None:
- doc.create(myfile.filename, myfile.file)
- c.dialog_title = SET_DOCUMENT_SUCCESS_HEADER
- c.dialog_text = SET_DOCUMENT_SUCCESS_TEXT
- c.url_ok = h.url_for(controller="document",
- action="globalOverview")
- return render('/documents/dialogs/success_documents.mako')
- finally:
- if not myfile is None:
- try:
- myfile.file.close()
- except Exception, e:
- log.exception(e)
- except Exception, e:
- log.exception(e)
- c.dialog_title = SET_DOCUMENT_FAILED_HEADER
- c.dialog_text = SET_DOCUMENT_FAILED_TEXT
- c.url_ok = h.url_for(controller="document", action="globalUpload")
- return render('/documents/dialogs/failed_document.mako')
+ filename = result['file']['filename']
+ content = result['file']['content']
+ if result['name']:
+ filename = result['name']
+ doc.create(filename, content)
+ c.dialog_title = SET_DOCUMENT_SUCCESS_HEADER
+ c.dialog_text = SET_DOCUMENT_SUCCESS_TEXT
+ c.url_ok = h.url_for(controller="document",
+ action="globalOverview")
+ return render('/documents/dialogs/success_documents.mako')
+ except formencode.Invalid, error:
+ c.form_result = error.value
+ c.form_errors = error.error_dict or {}
+ log.debug(c.form_result)
+ form = render('/documents/global_upload.mako')
+ return formencode.htmlfill.render(unicode(form, 'utf-8'),
+ defaults=c.form_result,
+ auto_insert_errors=False,
+ errors=c.form_errors)
@checkRole(('admin_ka', 'cm_ka'))
def globalShow(self, id):
Modified: wasko/branches/2.0/mpulsweb/lib/validators.py
===================================================================
--- wasko/branches/2.0/mpulsweb/lib/validators.py 2010-03-08 12:04:18 UTC (rev 1910)
+++ wasko/branches/2.0/mpulsweb/lib/validators.py 2010-03-08 15:22:31 UTC (rev 1911)
@@ -2,12 +2,14 @@
import re
import logging
+import cgi
import datetime
import formencode
from formencode import ForEach, All
from formencode.validators import Bool, Int, String, FieldsMatch, StringBoolean, \
- DateConverter, DateValidator, TimeConverter, FormValidator, MaxLength
+ DateConverter, DateValidator, TimeConverter, FormValidator, MaxLength, \
+ FileUploadKeeper, FieldStorageUploadConverter
from pylons import session
from pylons.i18n import _
@@ -34,6 +36,107 @@
allow_extra_fields = True
filter_extra_fields = False
+class FileNotEmptyCheck(formencode.validators.FancyValidator):
+
+ '''Checks if the filename-field of the provided file-dict ist empty. This
+ means that the user has not provided a file. Further check if the file is largger than the max allowed filesize'''
+
+ max_size = 10000000 #10MB = 10000000 bytes
+
+ messages = {
+ 'nofile': (u'Bitte geben Sie eine Datei zum Hochladen an.'),
+ 'toobig': (u'Die Datei ist größer als die maximal zulässige Größe von 10MB.')
+ }
+
+ def _to_python(self, value, state=None):
+ if not value.get('filename'):
+ raise formencode.Invalid(self.message("nofile", state),
+ value, state)
+ if len(value.get('content')) > self.max_size :
+ raise formencode.Invalid(self.message("toobig", state),
+ value, state)
+ return value
+
+class FileExistsChecker(FormValidator):
+ """
+ Checks if a given file (or filename) already exists in the database. If
+ so raise an exception if the user did not want to overwrite it.
+ """
+
+ casedoc_sql = "SELECT id FROM ka_fall_dokumente_tbl_view WHERE name = '%(filename)s'"
+ globaldoc_sql = "SELECT id FROM ka_global_dokumente_tbl_view WHERE name = '%(filename)s'"
+ field_names = None
+ validate_partial_form = True
+ __unpackargs__ = ('*', 'field_names')
+
+ messages = {
+ 'fileexists': _("Es existiert bereits eine Datei mit dem Namen"),
+ 'notDict': _("Fields should be a dictionary"),
+ }
+
+ def __init__(self, *args, **kw):
+ super(FormValidator, self).__init__(*args, **kw)
+ if len(self.field_names) < 2:
+ raise TypeError("FieldsMatch() requires at least two field names")
+
+ def validate_partial(self, field_dict, state):
+ for name in self.field_names:
+ if not field_dict.has_key(name):
+ return
+ self.validate_python(field_dict, state)
+
+ def validate_python(self, field_dict, state):
+ try:
+ ref = field_dict[self.field_names[0]]
+ except TypeError:
+ # Generally because field_dict isn't a dict
+ raise Invalid(self.message('notDict', state), field_dict, state)
+ except KeyError:
+ ref = ''
+
+ file = field_dict[self.field_names[0]]
+ # if user gives a userdefined name for the file take ths to check if
+ # the file is already existent. Else take filename from file
+ name = field_dict[self.field_names[1]]
+ if not name:
+ name = file.get('filename')
+ field_dict[self.field_names[1]] = name
+
+ ow = field_dict[self.field_names[2]]
+ case = field_dict.get(self.field_names[3])
+ if case:
+ sql = self.casedoc_sql
+ else:
+ sql = self.globaldoc_sql
+ errors = {}
+
+ # Only check if there is a file with name in DB, if teh user do not
+ # what do overwrite the files with the same name.
+ if not ow:
+ conn, cur = None, None
+ try:
+ conn = db.getConnection()
+ cur = conn.cursor()
+ fields = {'filename': name}
+ cur.execute(sql % fields)
+ result = cur.fetchone()
+ if result:
+ errors['name'] = self.message('fileexists', state)
+ except Exception, e:
+ log.exception(e)
+ raise
+ finally:
+ db.recycleConnection(conn, cur)
+
+ if errors:
+ error_list = errors.items()
+ error_list.sort()
+ error_message = '<br>\n'.join(
+ ['%s: %s' % (name, value) for name, value in error_list])
+ raise formencode.Invalid(error_message,
+ field_dict, state,
+ error_dict=errors)
+
class DateOrder(FormValidator):
"""
@@ -342,7 +445,22 @@
_from_python = _to_python
+class UploadGlobalDocumentForm(BaseFormValidator):
+ pre_validators = [formencode.variabledecode.NestedVariables()]
+ file = All(FileNotEmptyCheck(not_empty=True), FileUploadKeeper())
+ name = String()
+ overwrite = Bool(if_missing=False)
+ chained_validators = [FileExistsChecker('file', 'name', 'overwrite', 'case')]
+class UploadCaseDocumentForm(BaseFormValidator):
+ pre_validators = [formencode.variabledecode.NestedVariables()]
+ file = All(FileNotEmptyCheck(not_empty=True), FileUploadKeeper())
+ name = String()
+ overwrite = Bool(if_missing=False)
+ case = Int(not_empty=True)
+ chained_validators = [FileExistsChecker('file', 'name', 'overwrite', 'case')]
+
+
class EditSettingsForm(BaseFormValidator):
anon_transfer = formencode.validators.String(if_missing='off')
Modified: wasko/branches/2.0/mpulsweb/model/document.py
===================================================================
--- wasko/branches/2.0/mpulsweb/model/document.py 2010-03-08 12:04:18 UTC (rev 1910)
+++ wasko/branches/2.0/mpulsweb/model/document.py 2010-03-08 15:22:31 UTC (rev 1911)
@@ -186,25 +186,9 @@
case = int(case)
self.case = case
- out = StringIO.StringIO()
- total_size = 0
- while True:
- b = src.read(BLOCK_SIZE)
- l = len(b)
- if l == 0:
- break
- total_size += l
- if total_size > MAX_SIZE:
- raise DocumentException(
- u"Datei ist zu groß. Maximal %sMB sind erlaubt."
- % h.format_number(MAX_SIZE/float(1024*1024)))
- out.write(b)
- bytes = out.getvalue()
- out.close()
- out = None
+ bytes = src
+ self.size = len(bytes) #total_size
- self.size = total_size
-
has_commited = False
con, cur = None, None
try:
@@ -222,7 +206,7 @@
raise DocumentException("Konnte neues Dokument nicht anlegen.")
id = row[0]
- fields = {'bytes': dbapi.Binary(bytes), 'size': total_size,
+ fields = {'bytes': dbapi.Binary(bytes), 'size': self.size,
'name': name, 'mime': mime, 'id': id}
if case is None:
Modified: wasko/branches/2.0/mpulsweb/templates/documents/case_new.mako
===================================================================
--- wasko/branches/2.0/mpulsweb/templates/documents/case_new.mako 2010-03-08 12:04:18 UTC (rev 1910)
+++ wasko/branches/2.0/mpulsweb/templates/documents/case_new.mako 2010-03-08 15:22:31 UTC (rev 1911)
@@ -35,26 +35,68 @@
</div>
</div>
</div>
-
-<div id="document">
- <div id="waska_form" class="import_box">
- <p class="import_p">
- Die Größe einer Anlage darf nicht 10MB überschreiten. Bereits bestehende
- Dateien mit gleichem Namen werden überschrieben!
- </p>
- <div class="import_box_dialog">
- ${h.form(h.url_for(controller="casedocument", action='newAction'),
- multipart=True)}
- <label class="import_label" for="file">
- <strong class="import_number"> 1. </strong>${_('att_form_upload_label_add')}
- </label>
- ${h.file('file')}<br>
- <label class="import_label" for="">
- <strong class="import_number">2. </strong>${_('att_form_upload_label_up')}
- </label>
- ${h.submit("upload", _('doc_form_upload_submit'))}
- ${h.hidden('case', value=session.get('case').id)}
- ${h.end_form()}
- </div>
- </div>
+<p class="import_p">
+ Die Größe eines Dokuments darf nicht 10MB überschreiten.</p>
+${h.form(h.url_for(controller="casedocument", action='newAction'),
+ multipart=True)}
+<div class="widget container">
+ <table class="form">
+ <tr>
+ <td class="label">
+ <label for="name">
+ ${_('File')}
+ </label>
+ </td>
+ <td class="">
+ <input type="file" name="file.upload" id="file">
+ <input type="hidden" name="file.static">
+ </td>
+ <td class=""><span class="error"><form:error name="file"></span></td>
+ </tr>
+ <tr>
+ <td class="label">
+ <label for="name">${_('Filename')}</label></td>
+ <td class="">
+ <input type="text" name="name" id="name"><br>
+ </td>
+ <td class=""><span class="error"><form:error name="name"></span></td>
+ </tr>
+ <tr>
+ <td class="label">
+ <td class="">
+ <p class="note">Sie können optional einen alternativen Namen für
+ die Datei angeben, um so mehrere Versionen eines Dokuments
+ hinterlegen zu können. Wenn Sie keinen Namen angeben, so wird der
+ Dateiname der Datei verwendet, die Sie hochladen. </p>
+ </td>
+ <td class=""></td>
+ </tr>
+ <tr>
+ <td class="label">
+ ${_('Overwrite')}
+ </td>
+ <td class="">
+ <input type="checkbox" name="overwrite" value="1" id="overwrite">
+ <label for="overwrite">
+ ${_('Overwrite files with same name')}
+ </label>
+ </td>
+ <td class=""><span class="error"><form:error name="overwrite"></span></td>
+ </tr>
+ <tr>
+ <td class="label">
+ <td class="">
+ <p class="note">Beachten Sie, dass Sie den Haken bei "Überschreiben" setzen müssen, wenn Sie Daten gleichen Namens überschreiben wollen.</p>
+ </td>
+ <td class=""></td>
+ </tr>
+ <tr>
+ <td class=""></td>
+ <td colspan="2">
+ ${h.hidden('case', value=session.get('case').id)}
+ ${h.submit('upload', _('doc_form_upload_submit'))}
+ </td>
+ </tr>
+ </table>
</div>
+${h.end_form()}
Modified: wasko/branches/2.0/mpulsweb/templates/documents/global_upload.mako
===================================================================
--- wasko/branches/2.0/mpulsweb/templates/documents/global_upload.mako 2010-03-08 12:04:18 UTC (rev 1910)
+++ wasko/branches/2.0/mpulsweb/templates/documents/global_upload.mako 2010-03-08 15:22:31 UTC (rev 1911)
@@ -23,24 +23,67 @@
</div>
</div>
-<div id="document">
- <div id="waska_form" class="import_box">
- <p class="import_p">
- Die Größe eines Dokuments darf nicht 10MB überschreiten. Bereits bestehende
- Dateien mit gleichem Namen werden überschrieben!
- </p>
- <div class="import_box_dialog">
- ${h.form(h.url_for(controller="document", action='globalUploadAction'),
- multipart=True)}
- <label class="import_label" for="file">
- <strong class="import_number">1. </strong>${_('doc_form_upload_label_file')}
- </label>
- ${h.file('file')}<br>
- <label class="import_label" for="">
- <strong class="import_number">2.</strong> Dokument hinzufügen:
- </label>
- ${h.submit('upload', _('doc_form_upload_submit'))}
- ${h.end_form()}
- </div>
- </div>
+<p class="import_p">
+ Die Größe eines Dokuments darf nicht 10MB überschreiten.</p>
+${h.form(h.url_for(controller="document", action='globalUploadAction'),
+ multipart=True)}
+<div class="widget container">
+ <table class="form">
+ <tr>
+ <td class="label">
+ <label for="name">
+ ${_('File')}
+ </label>
+ </td>
+ <td class="">
+ <input type="file" name="file.upload" id="file">
+ <input type="hidden" name="file.static">
+ </td>
+ <td class=""><span class="error"><form:error name="file"></span></td>
+ </tr>
+ <tr>
+ <td class="label">
+ <label for="name">${_('Filename')}</label></td>
+ <td class="">
+ <input type="text" name="name" id="name"><br>
+ </td>
+ <td class=""><span class="error"><form:error name="name"></span></td>
+ </tr>
+ <tr>
+ <td class="label">
+ <td class="">
+ <p class="note">Sie können optional einen alternativen Namen für
+ die Datei angeben, um so mehrere Versionen eines Dokuments
+ hinterlegen zu können. Wenn Sie keinen Namen angeben, so wird der
+ Dateiname der Datei verwendet, die Sie hochladen. </p>
+ </td>
+ <td class=""></td>
+ </tr>
+ <tr>
+ <td class="label">
+ ${_('Overwrite')}
+ </td>
+ <td class="">
+ <input type="checkbox" name="overwrite" value="1" id="overwrite">
+ <label for="overwrite">
+ ${_('Overwrite files with same name')}
+ </label>
+ </td>
+ <td class=""><span class="error"><form:error name="overwrite"></span></td>
+ </tr>
+ <tr>
+ <td class="label">
+ <td class="">
+ <p class="note">Beachten Sie, dass Sie den Haken bei "Überschreiben" setzen müssen, wenn Sie Daten gleichen Namens überschreiben wollen.</p>
+ </td>
+ <td class=""></td>
+ </tr>
+ <tr>
+ <td class=""></td>
+ <td colspan="2">
+ ${h.submit('upload', _('doc_form_upload_submit'))}
+ </td>
+ </tr>
+ </table>
</div>
+${h.end_form()}
More information about the Mpuls-commits
mailing list