file-upload examples?

47 views
Skip to first unread message

mike

unread,
Nov 24, 2009, 6:29:17 AM11/24/09
to weblocks
Hi

Can anyone point me to a recent example of using file-upload?
Searching this list gives examples over a year old which seem to be
before src/views/types/file-upload.lisp was added.

Cheers

Mike

mike

unread,
Nov 24, 2009, 7:21:16 AM11/24/09
to weblocks
To clarify a bit; I can get a file-upload field on a form, as follows:

(modifying examples/weblocks-demo/src/model/company.lisp)

(defclass company ()
...
(file :initform nil
:accessor company-file
:initarg :file)))

;;; Form View
(defview company-form-view (:type form :inherit-from '(:scaffold
company))
(id :hidep t)
(file :present-as (file-upload)
:parse-as (file-upload
:upload-directory (path-rel-to-install "uploads")
:file-name :unique)))


*) This gives me a weblocks error:
"SIMPLE-ERROR: The value of the upload field is incorrect. Please turn
on multipart requests and turn off ajax."

*) I tried with javascript enabled & disabled in the browser, same
result.

*) How can i get this to work?

*) How do i access the uploaded file?
(I see that the method (defmethod parse-view-field-value ((parser file-
upload-parser) value obj...) returns multiple values including the
list of values from the multi-part, and the local file name. I dont
know how these are stored in the 'file' slot in the example above, or
how i would access them).

Cheers
m

mike

unread,
Nov 24, 2009, 9:39:53 AM11/24/09
to weblocks
> *) This gives me a weblocks error:
> "SIMPLE-ERROR: The value of the upload field is incorrect. Please turn
> on multipart requests and turn off ajax."

ok so thats easy, just add these parameters to the defview:

:enctype "multipart/form-data"
:use-ajax-p nil

> *) How do i access the uploaded file?
> (I see that the method (defmethod parse-view-field-value ((parser file-
> upload-parser) value obj...) returns multiple values including the
> list of values from the multi-part, and the local file name. I dont
> know how these are stored in the 'file' slot in the example above, or
> how i would access them).

Ok, parse-view-field-value sets the field to the file name.
I want to make a :unique file name, and access both the :unique name,
as well as the original name sent in the multipart/.

*) How can i get both the new unique name and the multipart file name
into the file slot, maybe as a list of values?

Thanks

Mike.

Leslie P. Polzer

unread,
Nov 26, 2009, 11:44:24 AM11/26/09
to weblocks
Hey Mike,

sorry for the delay.

> Ok, parse-view-field-value sets the field to the file name.
> I want to make a :unique file name, and access both the :unique name,
> as well as the original name sent in the multipart/.

Not sure about the file upload parser right now, but you can access
all data about the uploaded file with Hunchentoot's parameter API.

See hunchentoot:post-parameter in the Hunchentoot documentation.

You'll get a list of three items for a file upload.

Leslie
Message has been deleted

Nandan

unread,
Nov 28, 2009, 8:45:14 AM11/28/09
to weblocks
> > *) How do i access the uploaded file?
> > (I see that the method (defmethod parse-view-field-value ((parser file-
> > upload-parser) value obj...) returns multiple values including the
> > list of values from the multi-part, and the local file name. I dont
> > know how these are stored in the 'file' slot in the example above, or
> > how i would access them).
>
> Ok, parse-view-field-value sets the field to the file name.
> I want to make a :unique file name, and access both the :unique name,
> as well as the original name sent in the multipart/.
>
> *) How can i get both the new unique name and the multipart file name
> into the file slot, maybe as a list of values?
>

If all you want is both a unique name and the original multipart
(browser) name then
http://paste.lisp.org/+1YDA should be sufficient.

In fact, you could even simplify it as in http://paste.lisp.org/+1YDA/1
and probably eliminate the duplicated code too..

Nandan

unread,
Nov 28, 2009, 8:58:20 AM11/28/09
to weblocks

> *) How can i get both the new unique name and the multipart file name
> into the file slot, maybe as a list of values?


Wait.. that code I posted is a bit off. You do need to subclass the
parser, but the both-names slot isn't necessary.

Try this:


(defclass custom-file-upload-parser (file-upload-parser)
()
(:documentation "A parser that returns a plist of the disk file
name, the original browser name, and the mime type"))

(defmethod parse-view-field-value ((parser custom-file-upload-parser)
value obj
(view form-view) (field form-view-field) &rest args)
(declare (ignore args))
(when (null value)
(return-from parse-view-field-value (values t nil)))
(when (stringp value)
(error "The value of the upload field is incorrect. Please turn on
multipart requests and turn off ajax."))
(flet ((octet-string->utf-8 (s)
"Kludge to fix librfc2388 bug."
(hunchentoot::octets-to-string
(map 'vector
(lambda (c)
(let ((x (char-int c)))
(assert (and (not (minusp x))
(< x 256)))
x))
s))))
(let* ((temp-path (first value))
(mime-type (third value))
(browser-name (octet-string->utf-8 (second value)))
(disk-file-name (hunchentoot::create-random-string)))
(copy-file temp-path
(merge-pathnames disk-file-name
(file-upload-parser-upload-directory
parser))
:if-exists :supersede)
(values t value (list :disk-file disk-file-name :original-name
browser-name :mime-type mime-type)))))
Reply all
Reply to author
Forward
0 new messages