Thread overview
Display a random image with vibe.d
Jun 20, 2021
vnr
Jun 20, 2021
pilger
Jun 20, 2021
jfondren
Jun 20, 2021
vnr
Jun 20, 2021
jfondren
Jun 20, 2021
vnr
Jun 21, 2021
Christian Köstlin
June 20, 2021

Hello,
I would like to display a random image each time a page is refreshed. I think my random function works, but the image does not appear on the page. I have this template:

/public
    /images
        /rndimg
            img1.jpg
            img2.jpg
            img3.jpg
/source
    app.d
/views
    index.dt

index.dt:

doctype html

html(lang="en")
    head
        meta(charset="UTF-8")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        meta(http-equiv="X-UA-Compatible", content="ie=edge")
        title Document
    body
        img(src='#{rndimg}')

And the code itself is:

import vibe.vibe;

void main()
{
	auto settings = new HTTPServerSettings;
	settings.port = 8080;
	settings.bindAddresses = ["::1", "127.0.0.1"];
	auto listener = listenHTTP(settings, &index);
	scope (exit)
		listener.stopListening();

	logInfo("Please open http://127.0.0.1:8080/ in your browser.");
	runApplication();
}

/// The index page
void index(HTTPServerRequest req, HTTPServerResponse res)
{
	import std.random;
	import std.format;
	
	auto rnd = Random(unpredictableSeed);
	auto a = uniform(1, 3, rnd);
	const auto rndimg = format("images/rndimg/img%d.jpg", a);

	res.render!("index.dt", req, rndimg);
}

I don't understand why the image doesn't display, when I take an image from the internet and give the url, it works fine though.

Also, is this a good way to randomly display an image or is there a way that is maybe cleaner/efficient?

Thank you.

June 20, 2021

On Sunday, 20 June 2021 at 12:34:33 UTC, vnr wrote:

>

I don't understand why the image doesn't display, when I take an image from the internet and give the url, it works fine though.

maybe this works:
const auto rndimg = format("/images/rndimg/img%d.jpg", a);

>

Also, is this a good way to randomly display an image or is there a way that is maybe cleaner/efficient?

i would use the a/b testing capabilities of the webserver.

June 20, 2021

On Sunday, 20 June 2021 at 12:34:33 UTC, vnr wrote:

>

I don't understand why the image doesn't display, when I take an image from the internet and give the url, it works fine though.

$ curl -s http://127.0.0.1:8080/|grep img
		<img src="images/rndimg/img2.jpg"/>

This is a relative URL, so to satisfy it the browser will tack it onto
the end of the current request, making a request like the following:

$ curl -s http://127.0.0.1:8080/images/rndimg/img2.jpg|grep img
                <img src="images/rndimg/img2.jpg"/>

... which is answered, not with an image, but with the random-image
page. Your webserver needs to serve images if it's going to be asking
visitors to ask it for images. Right now your webserver only tells
visitors to ask it for images.

Your webserver will also always recommend the same image.

June 20, 2021

On Sunday, 20 June 2021 at 13:06:20 UTC, jfondren wrote:

>

On Sunday, 20 June 2021 at 12:34:33 UTC, vnr wrote:

>

I don't understand why the image doesn't display, when I take an image from the internet and give the url, it works fine though.

$ curl -s http://127.0.0.1:8080/|grep img
		<img src="images/rndimg/img2.jpg"/>

This is a relative URL, so to satisfy it the browser will tack it onto
the end of the current request, making a request like the following:

$ curl -s http://127.0.0.1:8080/images/rndimg/img2.jpg|grep img
                <img src="images/rndimg/img2.jpg"/>

... which is answered, not with an image, but with the random-image
page. Your webserver needs to serve images if it's going to be asking
visitors to ask it for images. Right now your webserver only tells
visitors to ask it for images.

Your webserver will also always recommend the same image.

Thanks for the answers, I understand better what is going on.

So, what should I do to make my server respond with a random image, and not the random image page? I'm fairly new to vibe.d, so I don't yet know the intricacies of how to handle this style of thing and I couldn't find how to do it in the documentation.

Thank you.

June 20, 2021

On Sunday, 20 June 2021 at 13:58:22 UTC, vnr wrote:

>

Thanks for the answers, I understand better what is going on.

So, what should I do to make my server respond with a random image, and not the random image page? I'm fairly new to vibe.d, so I don't yet know the intricacies of how to handle this style of thing and I couldn't find how to do it in the documentation.

Thank you.

Responding with a random image is an option, but what you have is
a good start, you just need to also serve images on request.

I'm very distracted right now or I would've included more in my
earlier post, but Vibe's online documentation has what you need.

Try, especially, https://vibed.org/docs#http-routing

You want a route for the random-image page, and you want to serve
static files under images/

June 20, 2021

On Sunday, 20 June 2021 at 14:28:26 UTC, jfondren wrote:

>

On Sunday, 20 June 2021 at 13:58:22 UTC, vnr wrote:

>

Thanks for the answers, I understand better what is going on.

So, what should I do to make my server respond with a random image, and not the random image page? I'm fairly new to vibe.d, so I don't yet know the intricacies of how to handle this style of thing and I couldn't find how to do it in the documentation.

Thank you.

Responding with a random image is an option, but what you have is
a good start, you just need to also serve images on request.

I'm very distracted right now or I would've included more in my
earlier post, but Vibe's online documentation has what you need.

Try, especially, https://vibed.org/docs#http-routing

You want a route for the random-image page, and you want to serve
static files under images/

Great, thanks a lot, it works as expected! Here is the code used (app.d), for those who are interested:

import vibe.vibe;

void main()
{

    	auto router = new URLRouter;
    	router.get("/", &index);
    	router.get("*", serveStaticFiles("public"));

    	auto settings = new HTTPServerSettings;
    	settings.bindAddresses = ["::1", "127.0.0.1"];
    	settings.port = 8080;

    	auto listener = listenHTTP(settings, router);
    	scope (exit) listener.stopListening();

    	logInfo("Please open http://127.0.0.1:8080/ in your browser.");
    	runApplication();
    }

    /// The index page
    void index(HTTPServerRequest req, HTTPServerResponse res)
    {
    	import std.random;
    	import std.format;

    	auto rnd = Random(unpredictableSeed);
    	const auto rndimg = format("/images/rndimg/img%d.jpg", uniform(1, 27, rnd));

    	res.render!("index.dt", req, rndimg);
    }
    ```
June 22, 2021

On 2021-06-20 17:14, vnr wrote:

>

On Sunday, 20 June 2021 at 14:28:26 UTC, jfondren wrote:

>

On Sunday, 20 June 2021 at 13:58:22 UTC, vnr wrote:

>

Thanks for the answers, I understand better what is going on.

So, what should I do to make my server respond with a random image, and not the random image page? I'm fairly new to vibe.d, so I don't yet know the intricacies of how to handle this style of thing and I couldn't find how to do it in the documentation.

Thank you.

Responding with a random image is an option, but what you have is
a good start, you just need to also serve images on request.

I'm very distracted right now or I would've included more in my
earlier post, but Vibe's online documentation has what you need.

Try, especially, https://vibed.org/docs#http-routing

You want a route for the random-image page, and you want to serve
static files under images/

Great, thanks a lot, it works as expected! Here is the code used (app.d), for those who are interested:

import vibe.vibe;

void main()
{

         auto router = new URLRouter;
         router.get("/", &index);
         router.get("*", serveStaticFiles("public"));

         auto settings = new HTTPServerSettings;
         settings.bindAddresses = ["::1", "127.0.0.1"];
         settings.port = 8080;

         auto listener = listenHTTP(settings, router);
         scope (exit) listener.stopListening();

         logInfo("Please open http://127.0.0.1:8080/ in your browser.");
         runApplication();
     }

     /// The index page
     void index(HTTPServerRequest req, HTTPServerResponse res)
     {
         import std.random;
         import std.format;

         auto rnd = Random(unpredictableSeed);
         const auto rndimg = format("/images/rndimg/img%d.jpg", uniform(1, 27, rnd));

         res.render!("index.dt", req, rndimg);
     }
     ```

The Random object should only be created once, but here its created for every request.

  1. It is relatively slow to reinitialize it
  2. If you really want to have uniform distribution its probably better to not throw the UniformRandomNumberGenerator generator away.

You can simplify that by using just uniform(1, 27) (it should fallback to the default rndGen that is initialized per thread (https://dlang.org/library/std/random/rnd_gen.html).

here a benchmark of both functions:

import std;
import std.datetime.stopwatch;

auto onlyUniform() {
  return uniform(1, 27);
}
auto withNewRandom() {
    auto rnd = Random(unpredictableSeed);
    return uniform(1, 27, rnd);
}
void main() {
  100_000.benchmark!(onlyUniform, withNewRandom).writeln;
}