unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Re: Learning Guile web. Stuck on returning an image. (Martyn Smith)
@ 2015-12-10 19:44 Martyn Smith
  2015-12-11  6:31 ` Nala Ginrut
  0 siblings, 1 reply; 2+ messages in thread
From: Martyn Smith @ 2015-12-10 19:44 UTC (permalink / raw)
  To: guile-user

[-- Attachment #1: Type: text/plain, Size: 11004 bytes --]

Hi all,

Whilst looking around the guile-user area, I noticed an old question I
posted with regards to returning an image in GNU Guile Web. Sadly, I did
not add closure to this query. As this question comes up on google search I
felt I should respond with a solution. I honestly thought I responded to
this. I can only apologies regarding this -- it is unprofessional.
Regardless, a late reply is better than no reply at all.

I ended up moving to GNU Artanis in the end. At the time, I was just happy
playing around with the Web Example section as presented in the Guile
Reference Manual. My code was becoming similar to Artanis in a number of
ways (atleast the get, post, etc, functions). Obviously, with GNU Artanis
being a much more thought-out framework, it made sense to move over. The
great news is that is was very easy to move my code over.

Below is an example code I use to return an image. You should just be able
to copy-paste the below code - as long as you have artanis installed and
ensured it is pointing to a jpg that exists, just open a browser and type -
localhost:1234/image

(use-modules (artanis artanis)
                     (rnrs io ports))

(init-server)

(get "/image"
     (lambda (rc)
       (let* ((port (open-file "s.jpg" "r"))
               (bytes (get-bytevector-all port)))
     (close-port port)
     (response-emit bytes #:headers '((content-type image/jpg))))))

(run #:port 1234)


For my personal website, I pass in an id (ie "/image/{id}") which returns a
record from the database, containing the location of the file in
question... plus other things (tags, uploader, etc)  -- once working I
stick it inside an image tag - job done!

Obviously my example does not cover error handling but you get the idea. :-)

I hope this helps
M





On Mon, May 26, 2014 at 5:00 PM, <guile-user-request@gnu.org> wrote:

> Send guile-user mailing list submissions to
>         guile-user@gnu.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://lists.gnu.org/mailman/listinfo/guile-user
> or, via email, send a message with subject or body 'help' to
>         guile-user-request@gnu.org
>
> You can reach the person managing the list at
>         guile-user-owner@gnu.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of guile-user digest..."
>
>
> Today's Topics:
>
>    1. Learning Guile web. Stuck on returning an image. (Martyn Smith)
>    2. Re: Install Guile 2.0.11 failed on L-Ubuntu 12.04 (Germ?n Arias)
>    3. Re: Learning Guile web. Stuck on returning an image. (Nala Ginrut)
>    4. Re: Learning Guile web. Stuck on returning an image. (Neil Jerram)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Sun, 25 May 2014 23:30:33 +0100
> From: Martyn Smith <martyn.developer@googlemail.com>
> To: guile-user@gnu.org
> Subject: Learning Guile web. Stuck on returning an image.
> Message-ID:
>         <
> CA+dhi3siRAX3bq737RK9nRZcqxKDnaoeKLGn-GiqBMNfzegZcg@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> Hi guys,
>
> I am attempting to create a website as part of a learning experience with
> guile. The code is originally based from ideas in
> https://www.gnu.org/software/guile/manual/html_node/Web-Examples.html. My
> code has progressed since the "Web Examples" page to support a more MVC
> style. So far, so good-ish. :-)
>
> Getting to the point of the email -- I am a bit confused how I would return
> a jpg image. For example: -
> <img src="/load-image?id=1234" />
>
> The "1234" tells me which file to load and return.
>
> Being primarily a .NET developer, I am struggling to understand how to
> achieve such goal in guile. I have tried things like (read-file
> "/location/to/image.jpg" "r") but no luck. Also tried to understand
> converting to bytes in the documentation but again... no luck. Always
> getting a 500 error. Yes, I have included (content-type . (image/jpg)) etc.
>
> Can anyone give me a heads up on how to do such thing? How would I open the
> jpg file? How would it be returned?
>
> I don't think its worth providing any code here. I think the Web-Examples
> page is the best place to review code, and how I would return an image from
> that current codebase, etc.
>
> Thanks for any suggestions.
>
> mart
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <
> http://lists.gnu.org/archive/html/guile-user/attachments/20140525/6759309b/attachment.html
> >
>
> ------------------------------
>
> Message: 2
> Date: Sun, 25 May 2014 17:59:08 -0600
> From: Germ?n Arias <germanandre@gmx.es>
> To: Chris Vine <chris@cvine.freeserve.co.uk>
> Cc: guile-user@gnu.org
> Subject: Re: Install Guile 2.0.11 failed on L-Ubuntu 12.04
> Message-ID: <069c51a1d2a956acc5f8f83512f3230c@german-desktop>
> Content-Type: text/plain; charset="iso-8859-1"
>
> On 2014-05-25 03:10:55 -0600 Chris Vine <chris@cvine.freeserve.co.uk>
> wrote:
>
> [...]
> >
> > Yuck.
>
> This is exactly what one does not expect in a free software list, where is
> supposed the users can share and learn together without being offended.
>
> Germ?n.
>
>
>
>
> ------------------------------
>
> Message: 3
> Date: Mon, 26 May 2014 08:22:58 +0800
> From: Nala Ginrut <nalaginrut@gmail.com>
> To: Martyn Smith <martyn.developer@googlemail.com>
> Cc: Guile User <guile-user@gnu.org>
> Subject: Re: Learning Guile web. Stuck on returning an image.
> Message-ID:
>         <
> CAPjoZodM7m9SXkJRENy3x_PYnBkpKa2AabMV+cuPmqoHNO0dWw@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> Hi Martyn!
>
> 2014?5?26? ??6:30? "Martyn Smith" <martyn.developer@googlemail.com>???
> >
> > Hi guys,
> >
> > I am attempting to create a website as part of a learning experience with
> guile. The code is originally based from ideas in
> https://www.gnu.org/software/guile/manual/html_node/Web-Examples.html. My
> code has progressed since the "Web Examples" page to support a more MVC
> style. So far, so good-ish. :-)
> >
>
> If you want to play web with Guile, I suggest Artanis, which is a web
> framework for it. It's easier than using the lower web api.
>
> www.web-artanis.com
>
> > Getting to the point of the email -- I am a bit confused how I would
> return a jpg image. For example: -
> > <img src="/load-image?id=1234" />
> >
> > The "1234" tells me which file to load and return.
> >
> > Being primarily a .NET developer, I am struggling to understand how to
> achieve such goal in guile. I have tried things like (read-file
> "/location/to/image.jpg" "r") but no luck. Also tried to understand
> converting to bytes in the documentation but again... no luck. Always
> getting a 500 error. Yes, I have included (content-type . (image/jpg)) etc.
> >
>
> Please attache you complete code. But I guess what you need is
> get-bytevector-all which dwells on (rnrs).
> Usually, open file only return a file port, you have to read the content
> then.
>
> > Can anyone give me a heads up on how to do such thing? How would I open
> the jpg file? How would it be returned?
> >
> > I don't think its worth providing any code here. I think the Web-Examples
> page is the best place to review code, and how I would return an image from
> that current codebase, etc.
> >
> > Thanks for any suggestions.
> >
> > mart
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <
> http://lists.gnu.org/archive/html/guile-user/attachments/20140526/f135f4e0/attachment.html
> >
>
> ------------------------------
>
> Message: 4
> Date: Mon, 26 May 2014 10:05:17 +0100
> From: Neil Jerram <neil@ossau.homelinux.net>
> To: Martyn Smith <martyn.developer@googlemail.com>
> Cc: guile-user@gnu.org
> Subject: Re: Learning Guile web. Stuck on returning an image.
> Message-ID: <87k3989agi.fsf@ossau.homelinux.net>
> Content-Type: text/plain; charset=us-ascii
>
> Martyn Smith <martyn.developer@googlemail.com> writes:
>
> > Getting to the point of the email -- I am a bit confused how I would
> return a
> > jpg image. For example: -
> > <img src="/load-image?id=1234" />
> >
> > The "1234" tells me which file to load and return.
> >
> > Being primarily a .NET developer, I am struggling to understand how to
> achieve
> > such goal in guile. I have tried things like (read-file "/location/to/
> > image.jpg" "r") but no luck. Also tried to understand converting to
> bytes in
> > the documentation but again... no luck. Always getting a 500 error. Yes,
> I have
> > included (content-type . (image/jpg)) etc.
> >
> > Can anyone give me a heads up on how to do such thing? How would I open
> the jpg
> > file? How would it be returned?
>
> I recently had the same problem, and eventually decided that it would be
> better to use Guile only for my dynamic content, with a standard web
> server for the static content.  For the latter I chose lighttpd, and I
> can provide more details of my setup if that would be helpful.
>
> But what specifically was the problem?  My handler for an image file
> (and other static content) looked like this:
>
>   (lambda (request request-body uri)
>     (let* ((fn (apply string-append
>                       static-root
>                       (map (lambda (name)
>                              (string-append "/" name))
>                            uri)))
>            (content (with-input-from-file fn read-string))
>            (content-type (cond ((string-match "\\.svg" fn)
>                                 '(image/svg+xml))
>                                ((string-match "\\.html?" fn)
>                                 '(text/html))
>                                ((string-match "\\.jpe?g" fn)
>                                 '(image/jpeg))
>                                ((string-match "\\.png" fn)
>                                 '(image/png))
>                                ((string-match "\\.css" fn)
>                                 '(text/css))
>                                ((string-match "\\.js" fn)
>                                 '(application/javascript))
>                                (else
>                                 '(text/plain)))))
>       (trc 'content-type content-type 'length (string-length content))
>       (values `((content-type . ,content-type))
>               content)))
>
> The problem here that 'content' contains binary data that can't be
> returned as is in an HTTP response.  It needs to be encoded in one of
> the HTTP-supported encodings, and a corresponding Content-Encoding
> header added to the response.
>
> I think I investigated a little whether Guile's (web ...) modules could
> do this, or could easily be enhanced, but decided instead on the
> solution described above.
>
> Regards,
>         Neil
>
>
>
> ------------------------------
>
> _______________________________________________
> guile-user mailing list
> guile-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/guile-user
>
>
> End of guile-user Digest, Vol 138, Issue 9
> ******************************************
>

[-- Attachment #2: Type: text/html, Size: 15501 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Learning Guile web. Stuck on returning an image. (Martyn Smith)
  2015-12-10 19:44 Learning Guile web. Stuck on returning an image. (Martyn Smith) Martyn Smith
@ 2015-12-11  6:31 ` Nala Ginrut
  0 siblings, 0 replies; 2+ messages in thread
From: Nala Ginrut @ 2015-12-11  6:31 UTC (permalink / raw)
  To: Martyn Smith; +Cc: guile-user

Hi Martyn!
I'm very glad to see a new user of Artanis!

On Thu, 2015-12-10 at 19:44 +0000, Martyn Smith wrote:
> (use-modules (artanis artanis)
>                      (rnrs io ports))
> 
> (init-server)
> 
> (get "/image"
>      (lambda (rc)
>        (let* ((port (open-file "s.jpg" "r"))
>                (bytes (get-bytevector-all port)))
>      (close-port port)
>      (response-emit bytes #:headers '((content-type image/jpg))))))
> 
> (run #:port 1234)
> 

In this case, you have three more alternatives to try. It is not
recommended to handle static files manually. Such work is treated as
low-level in Artanis.

1. Static files handling
This would be done by (init-server #:statics '(jpg)) or add more static
files ext-filename as you wish.
In this way, you don't have to write rules & handlers, say, you don't
need (get ...). Artanis will handle jpg files and detect correct MIME
for you, and proper cache expires according to your config file.

2. Use emit-response-with-file
http://www.gnu.org/software/artanis/manual/manual.html#sec-6-4

Sometimes, you don't want to reveal the jpg filename, say,
(get "/image"
  (lambda (rc) (emit-response-with-file "s.jpg")))

Of course, you don't have to specify MIME, but no cache option (ETag)
specified too. Unless you specify it explicitly. This method is used for
MVC to emit HTML template of Views automatically. Because sometimes we
don't want Artanis to add caching for us cleverly.

3. Take advantage of #:cache shortcut
For static files, we often want to emit it with caching.
(get "/image" #:cache '(public "s.jpg" #:maxage 3600)
  (lambda (rc) 
    (:cache rc)))


Happy hacking!




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-12-11  6:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-10 19:44 Learning Guile web. Stuck on returning an image. (Martyn Smith) Martyn Smith
2015-12-11  6:31 ` Nala Ginrut

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).