Does std.net.curl: download have support for callbacks?

evilrat evilrat666 at gmail.com
Thu Jun 11 07:05:19 UTC 2020


On Thursday, 11 June 2020 at 06:05:09 UTC, adnan338 wrote:
> I would like to set a callback for the `download()` function 
> but I do not seem to find a way to add a callback to the 
> procedure.
>
> Let's say, for example I have a GtkD Widget called "pb" (short 
> for progressBar).
>
> I want to download a file from a url and when done, I want a 
> callback to access pb and increase by a certain number.
>
> The GtkD progress bar API:
> https://api.gtkd.org/gtk.ProgressBar.ProgressBar.setFraction.html
>
> Normally, If it was dependent on a button, I would do something 
> like:
>
>     auto pb = new ProgressBar();
>     auto more = new Button("go-next", GtkIconSize.BUTTON);
>     more.addOnClicked(delegate void(Button _) {
>         if (activityMode.getActive()) // ignore this if 
> condition
>             pb.pulse;
>         else
>             pb.setFraction(pb.getFraction + pb.getPulseStep);
>     });
>
> But how can I do this with `download()`?

 From the docs on download() method it has an optional connection 
reference
https://dlang.org/phobos/std_net_curl.html#.download


And connection has onProgress callback, you can add some global 
variable and update it using this callback.

Now of course another problem left up to you, not thread safe 
means you should expect the worst if you try to use the library 
from multiple threads, this is especially true for UI libraries 
as some OS implies some restrictions on UI interactions as well.

So you need to find relevant mechanism to do a event loop 
scheduling and update progress bar using it by feeding the values 
from somewhere else.

See https://dlang.org/phobos/std_net_curl.html#.HTTP under 
"Tracking progress: " example.
It turns out you might not need to use download() at all.

Pseudocode:

   // some global vars to track it
   size_t bytesTotal;
   size_t bytesReceived;

   // in your downloader thread
   auto http = HTTP();
   http.method = HTTP.Method.get;
   http.url = "http://upload.wikimedia.org/wikipedia/commons/" ~
            "5/53/Wikipedia-logo-en-big.png";
   http.onReceive = (ubyte[] data) { bytesTotal = 0; bytesReceived 
= 0; return data.length; };
   http.onProgress = (size_t dltotal, size_t dlnow,
                    size_t ultotal, size_t ulnow)
   {
     bytesTotal = dltotal;
     bytesReceived = dlnow;
     return 0;
   };

   // somewhere in GTK do something like this, it is up to you to 
find out how to do this
   void check_dl_status()
   {
     // here we are using globals that updates on another thread
     auto progressPct = bytesTotal / bytesReceived;
     progresBar.setPercent (progressPct);

     if (progressPct < 1)
       event.publish (check_dl_status);
   }





More information about the Digitalmars-d-learn mailing list