30 Sep 2013, 13:25
Generic-user-small

craig ferry (12 posts)

In p102 - 103 there is code that handles the upload. The first such one is

(defn handle-upload [file] 
(println file) 
(upload-page
(if (empty? (:filename file)) 
"please select a file to upload" 
"success")))

the filename property of the file map is itself a key in the params map so the code should be either

(defn handle-upload [file] 
(println file) 
(upload-page
(if (empty? (:filename (:file file))) 
"please select a file to upload" 
"success")))

or

(defn handle-upload [params] 
(println file) 
(upload-page
(if (empty? (:filename (:file params))) 
"please select a file to upload" 
"success")))

This error is propogated into the next section of code on p103

30 Sep 2013, 14:25
Generic-user-small

craig ferry (12 posts)

I don’t know how you want code errata reported . Do you want each errata posted in its own thread or similar errata within the code as a single thread?

P103 still on the upload code

(try
(noir.io/upload-file File/separator "img" File/separator file)

the upload file function just expects 2 arguments you need to bracket s-expressions 2-4

(try
(noir.io/upload-file (File/separator "img" File/separator) file)

The code you reference at http://media.pragprog.com/titles/dswdcloj/code/picture-gallery-c/src/picture_gallery/routes/upload.clj is correct in this regard but there is a further problem with the online code.

The online code uses the user-session variable as a subdirectory in the images folder (I am assuming to prevent filename collisions). Although a great idea because the directory doesn’t exist (perhaps we should create on when a user is created) then java bails out with an error that the directory doesn’t exist to save the file upload to. Reading ahead I can see that this is fixed later on (p107) but creates confusion prior to that.

01 Nov 2013, 20:58
Generic-user-small

Erik Backman (7 posts)

I seem to get an extra encoded backslash in my image string.

\picture-gallery\resources\public%5c\img\file.png It’s written out because of an Exception so I might have some issue somewhere else but still it caught my eye.

Any ideas?

02 Nov 2013, 12:59
Profile_pic_pragsmall

Dmitri Sotnikov (42 posts)

Hi Craig,

The code is actually correct. Consider that the “/upload” route already frabs the :file key from the params.

(POST "/upload" [file] (handle-upload file))

The :file key points to the map describing the file that contains the :filename key. Since this is what’s being passed to handle-upload calling (:filename file) is what’s going to get us the filename.

The directory should be created when the user creates an account. Since we expect the user to be logged in to upload files, and the user has to register to login, using the session variable should be safe under normal circumstances.

However, if you have a local db you’re testing with and you’ve already made a user in a previous example, then you can circumvent the registration step. In that case you’ll get the error you’re describing.

Erik,

It looks like you might have an extra “" in the path that’s causing the trouble.

03 Nov 2013, 13:24
Generic-user-small

Erik Backman (7 posts)

Dmitri,

(noir.io/upload-file (str File/separator "img" File/separator) file)

Sorry but I fail to see where the extra character is inserted? I get the same thing when “omitting” the relative path (with “”). To the best of my knowledge %5c is a \ And it comes attached at the end of “public” bit of the path, which I do not specify anywhere?

04 Nov 2013, 03:47
Profile_pic_pragsmall

Dmitri Sotnikov (42 posts)

Hi Erik,

I’m assuming you’re on Windows since you’re using \ for path separators. Could you try omitting the first File/separator to see if that helps:

(noir.io/upload-file (str "img" File/separator) file)

04 Nov 2013, 06:17
Generic-user-small

Erik Backman (7 posts)

Dimitri,

You are right, I’m on windows. And I’ve tried every variant of relative filepath, the thing is, the extra char is before that. It’s an encoded backslash - the only one. And it’s in the upload path - no wonder the system can’t find it to upload, the only place I use encoded is in the img link for the posted image…

Either I’m real stupid, or I have a Windows issue of some sort. Not really sure which of the above is more likely ;)

I’ll - as soon as I get the chance - uberjar and try deploying it somewhere to see if I can get a different result.

edit: Tried the standalone run directly from the very same target directory, and I get this: error uploading file \img\Untitled.png (The system cannot find the path specified) No extra or encoded backslashes there.

Might be a Leiningen on windows issue?

04 Nov 2013, 13:58
Profile_pic_pragsmall

Dmitri Sotnikov (42 posts)

I think a problem might actually be a bug with upload-file. Since you can’t create files inside the jar the approach for saving the images doesn’t actually work with uberjar packaging.

When your working with lein ring server or package it as a war, then the public folder is writeable. However, when it’s packaged in the jar then it’s read-only. I think that’s at least part of the problem here.

05 Nov 2013, 15:45
Generic-user-small

Erik Backman (7 posts)

Dmitri,

Yes not beeing able to actually files with the uberjar makes sense, only compiled it to see if I got something added to the path again. Before that I’ve just been running with lein ring server.

So something with noir.io/upload-file together with lein ring, atleast on windows 8 is the problem then?

06 Nov 2013, 13:35
Profile_pic_pragsmall

Dmitri Sotnikov (42 posts)

I’m not sure I’d blame lein ring just yet. :) All that’s doing is bootstrapping the application.

I’m not sure why the issue surfaces on windows specifically. All that’s happening in noir.io is that it generates the path string relative to the public folder.

The implementation is very simple, you can see what’s happening here.

It grabs the resource URL (io/resource (str "public" File/separator)) and its path, then appends the relative path and the filename:

(java.net.URLDecoder/decode
    (str (resource-path) relative-path File/separator filename)
    "utf-8")

It could be that windows is having a problem with the utf-8 path string.

In the latest version (0.7.5), it’s been updated to simply use the file path supplied without prepending the public folder path. So, that should address the jar problem at least.

I’ve updated the code in the latest draft to work with that. Since the path is now pointing to the filesystem, we need an extra route to read the file from there:

(def galleries "galleries")

(defn serve-file [user-id file-name]
  (file-response (str galleries File/separator user-id File/separator file-name)))

...

(defroutes upload-routes
  (GET "/img/:user-id/:file-name" [user-id file-name]
          (serve-file user-id file-name))
   ...)

If you could try to try and see if this approach works for you, I’d be interested to know.

12 Nov 2013, 14:01
Generic-user-small

Harry Hewat (1 post)

I am having a similar problem with: (str (io/resource-path) “/home.html”) evaluates to “…….resources/public%5c/home.html”

see page 69 using [noir.io :as io] (0.7.5) on windows.

how to work round this?

15 Nov 2013, 01:34
Profile_pic_pragsmall

Dmitri Sotnikov (42 posts)

That’s been changed now and new examples will be available in the next revision.

  You must be logged in to comment