www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Display a random image with vibe.d

reply vnr <cfcr gmail.com> writes:
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

```

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.
Jun 20 2021
next sibling parent pilger <abcd dcba.com> writes:
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.
Jun 20 2021
prev sibling parent reply jfondren <julian.fondren gmail.com> writes:
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.
Jun 20 2021
parent reply vnr <cfcr gmail.com> writes:
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.
Jun 20 2021
parent reply jfondren <julian.fondren gmail.com> writes:
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/
Jun 20 2021
parent reply vnr <cfcr gmail.com> writes:
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); } ```
Jun 20 2021
parent =?UTF-8?Q?Christian_K=c3=b6stlin?= <christian.koestlin gmail.com> writes:
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; } ```
Jun 21 2021