Re: Nimble package, multiple backends

2020-04-17 Thread Hlaaftana
`when` blocks allow for different code based on backends, Nim versions, command 
line options and so on. The [fatal pragma section of the Nim 
manual](https://nim-lang.org/docs/manual.html#pragmas-fatal-pragma) gives an 
example that shows how to error when the user doesn't use the `objc` command to 
compile. If you want to just warn, you can also do that. An example for your 
use case, you put this at the top of your nimble package module:


when defined(macos) or defined(macosx):
  when not defined(objc):
{.warn: "this package is supposed to work with objc on macosx".}
elif not defined(c) or not defined(cpp):
  {.warn: "this package is supposed to work with c/c++ on linux/windows".}


Run

The 
[browsers](https://github.com/nim-lang/Nim/blob/version-1-2/lib/pure/browsers.nim)
 module in the standard library is a short example of how to write OS-specific 
code.


Does Nim have a binary serializer similar to Gos "encoding/gob"?

2020-04-17 Thread Keithcat1
Hi, I'm looking for a binary serializer that will hopefully allow newer 
versions of my program that for example add new fields to a type to still load 
data created by older versions of that same program. Is there anything like 
that? Thanks!


Could Nim use Cmake to invoke the C compiler?

2020-04-17 Thread Keithcat1
I'm curious, would it be hard or beneficial to change the nim compiler so that 
every time you build a project, it generates a cmake_lists.txt file and uses 
Cmake to run the C or C++ compiler to compile the project. This seems to be at 
least one of the things that Cmake was made for. You might also be able to 
include other C code that's built by Cmake. I'm not really suggesting anything 
be changed, but am curious if it would be useful.


Re: Nim version of Flask Web Framework

2020-04-17 Thread federico3
If you want to add auth to existing frameworks: 
[https://github.com/FedericoCeratto/nim-httpauth](https://github.com/FedericoCeratto/nim-httpauth)


Re: generate c++ code from .nim file

2020-04-17 Thread minimisthupper
ok, thanks! 


Nimble package, multiple backends

2020-04-17 Thread rufusroflpunch
What is the best way to distribute a Nimble package that would use Objective-C 
on Mac OS X and C/C++ on Linux/Windows? Is there anything special that needs to 
be done?

Also, if a Nimble package uses a particular backend like Objective-C, do users 
of the that project need to compile their code with the same backend?


Re: Nim Forum build error

2020-04-17 Thread dom96
Yep, it's trying to install karax and that fails for some reason (I think there 
might be a Nimble bug here). Try to install it manually by running nimble 
install karax@#f6bda9a.


Re: AsyncHTTPClient crashes saying invalid http version

2020-04-17 Thread dom96
Stop mixing callbacks and async procs. Your `download` async proc finishes 
before your download operation finishes because you are not awaiting the 
`download` proc. Just do this:


await downloader.downloadFile(node.mediaLink(board, thread), downFileName)


Run


Re: AsyncHTTPClient crashes saying invalid http version

2020-04-17 Thread adnan
> Is this a wrong link? because that doesn't look synchronous.

Ops sorry I had changed the link.

> One important thing to know is that you should never use waitFor in an async 
> procedure, use await.

If I use await, the main thread doesn't stop until all the coroutines I create 
inside the loop finishes


proc download(node: JsonNode; downPath, board, thread: string): 
Future[void] {.async.} =
  var
tim = node["tim"].getInt()
ext = node["ext"].getStr()
downloader = newAsyncHttpClient()
downFileName = fmt"{downPath}/{tim}{ext}"
  echo("Downloading ", node.mediaLink(board, thread), " as ", downFileName, 
"...")
  var downloadFuture = downloader.downloadFile(node.mediaLink(board, 
thread), downFileName)
  downloadFuture.callback=
proc() =
  echo("Downloading ", downFileName, " complete")
  result = downloadFuture

proc main() {.async.} =
  var
boardAndThread = parseBoardAndThread(getRawLink())
downPath = getCurrentDir() & "/" & getRawDownPath()
board = boardAndThread[0]
thread = boardAndThread[1]
  if not downPath.existsDir():
echo("Local path not recognized. Creating directory: ", downPath)
createDir downPath
  var
webClient = newAsyncHttpClient()
link = getAPILink(board, thread)
j: string = await webClient.getContent(link)
  
  var
jsonArray = parseJson(j)["posts"].getElems()
filteredArray = jsonArray.filter(proc(it: JsonNode): bool = it{"tim"} 
!= nil)
downloadSignaledArray = filteredArray.map(proc(it: JsonNode): 
Future[void] = it.download(downPath, board, thread))
  for it in downloadSignaledArray:
await it

waitFor main() # never gets to finish downloading.


Run

For context, this is how the json looks like: 
[https://a.4cdn.org/po/thread/570368.json](https://a.4cdn.org/po/thread/570368.json)

I have to extract `tim` and `ext` from each item in the JArray. Then from the 
program argument I have to parse `po` and build the download link like: 
`https://i.4cdn.org/po/1546293948883.png`. I need to download from any JsonNode 
that has `tim` asynchronously. 


Re: Nim Forum build error

2020-04-17 Thread jjude
` Verifying dependencies for nimforum@2.0.2 Reading official package list 
Checking for jester@#d8a03aa Info: Dependency on jester@#d8a03aa already 
satisfied Verifying dependencies for jester@#d8a03aa Reading official package 
list Checking for httpbeast@>= 0.2.2 Info: Dependency on httpbeast@>= 0.2.2 
already satisfied Verifying dependencies for httpbeast@0.2.2 Reading official 
package list Checking for 
https://github.com/timotheecour/asynctools@#pr_fix_compilation Info: Dependency 
on https://github.com/timotheecour/asynctools@#pr_fix_compilation already 
satisfied Verifying dependencies for asynctools@#pr_fix_compilation Reading 
official package list Checking for 
https://github.com/timotheecour/asynctools@#pr_fix_compilation Info: Dependency 
on https://github.com/timotheecour/asynctools@#pr_fix_compilation already 
satisfied Verifying dependencies for asynctools@#pr_fix_compilation Reading 
official package list Checking for bcrypt@#head Info: Dependency on 
bcrypt@#head already satisfied Verifying dependencies for bcrypt@#head Reading 
official package list Checking for hmac@#9c61ebe2fd134cf97 Info: Dependency on 
hmac@#9c61ebe2fd134cf97 already satisfied Verifying dependencies for 
hmac@#9c61ebe2fd134cf97 Reading official package list Checking for nimSHA2@any 
version Info: Dependency on nimSHA2@any version already satisfied Verifying 
dependencies for nimSHA2@0.1.1 Reading official package list Checking for 
sha1@any version Info: Dependency on sha1@any version already satisfied 
Verifying dependencies for sha1@1.1 Reading official package list Checking for 
recaptcha@#d06488e Info: Dependency on recaptcha@#d06488e already satisfied 
Verifying dependencies for recaptcha@#d06488e Reading official package list 
Checking for sass@#649e0701fa5c Info: Dependency on sass@#649e0701fa5c already 
satisfied Verifying dependencies for sass@#649e0701fa5c Reading official 
package list Checking for karax@#f6bda9a Installing karax@#f6bda9a Reading 
official package list Downloading https://github.com/pragmagic/karax using git 
Executing git clone --recursive https://github.com/pragmagic/karax 
/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a
 Finished with exit code 0 Output Cloning into 
'/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a'...
 Executing git checkout --force f6bda9a Finished with exit code 0 Output Note: 
switching to 'f6bda9a'. ... You are in 'detached HEAD' state. You can look 
around, make experimental ... changes and commit them, and you can discard any 
commits you make in this ... state without impacting any branches by switching 
back to a branch. ... If you want to create a new branch to retain commits you 
create, you may ... do so (now or later) by using -c with the switch command. 
Example: ... git switch -c  ... Or undo this operation with: 
... git switch - ... Turn off this advice by setting config variable 
advice.detachedHead to false ... HEAD is now at f6bda9a Reactive value (#129) 
Executing git submodule update --recursive Finished with exit code 0 Debug: 
Executing nim e --hints:off --verbosity:0 
-p:/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimblecache 
'/private/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims'
 /var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468.out printPkgInfo 
Warning: Not removing temporary path because of debug verbosity: 
/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468.out Warning: Not 
removing temporary path because of debug verbosity: 
/private/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims
 Info 
/private/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims(5,
 22) Warning: imported and not used: 'strutils' [UnusedImport] Debug: Executing 
nim e --hints:off --verbosity:0 
-p:/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimblecache 
'/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims'
 /var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468.out printPkgInfo 
Info 
/private/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468/githubcom_pragmagickarax_#f6bda9a/karax_30468.nims(5,
 22) Warning: imported and not used: 'strutils' [UnusedImport] Verifying 
dependencies for karax@#f6bda9a Installing karax@#f6bda9a Warning: Not removing 
temporary path because of debug verbosity: 
/var/folders/k_/013v486j1w98mvzh31dcwmvmgn/T/nimble_30468 Error: No 
binaries built, did you specify a valid binary name? `

Run


Re: generate c++ code from .nim file

2020-04-17 Thread dom96
You'll need to copy this file beside your .cpp file. This is supposed to be 
copied automatically when using `--genScript` (if you're using 1.0.6 it should 
work), with latest versions of Nim it doesn't get copied (see 
[https://github.com/nim-lang/Nim/issues/13826)](https://github.com/nim-lang/Nim/issues/13826\)).


Re: Nim Forum build error

2020-04-17 Thread dom96
Are you sure you're not getting this error because of a dependency that's being 
installed? Can you paste the full output of `nimble c -r src/buildcss --debug`?


Re: how to get some (partial) type resolution within a macro ?

2020-04-17 Thread Sixte
> Can parseEnum help you with what you want to do?

Thank you for your assistance. At the very end, `{.experimental: 
"dynamicBindSym".}` did the trick for me. I got three different solutions: via 
typedesc, via template (forwarding) and with `bindSym` at compile-time. The 
least mentioned was I was looking for.


import macros
{.experimental: "dynamicBindSym".}

type
  Qa = object
field: int
  Qb   = array[0..23,NimNode]
  Qc   = tuple[tfa : int, tfb : int, tfc : string]

macro helper(a : typed, acomm : string): untyped =
  echo "helper ",acomm," ", treeRepr getImpl a

macro resolve(ta : typedesc, tb : untyped, tc : untyped) : untyped =
  echo "entry ", ta.strVal, tb.strVal, tc.strVal
  var dyn = strVal tc
  echo "typedesc ", treeRepr getImpl ta
  template tpl(v) = helper v, "forwarded"
  let retv = getAst tpl tb
  let NNode = bindsym dyn
  echo "dyn. bind ", treeRepr getImpl NNode
  result = retv

resolve(Qa,Qb,Qc)

# prints type description in order : Qa, Qc, Qb

echo " done. "



Run


Re: AsyncHTTPClient crashes saying invalid http version

2020-04-17 Thread adnan
> To keep multiple connections open at a time you will need a separate 
> HttpClient for each.

Ah that fixes it. Thanks a bunch.


Re: Iterate over fields

2020-04-17 Thread Vindaar
First of all see of course the docs here:

[https://nim-lang.github.io/Nim/macros.html#quote%2Ctyped%2Cstring](https://nim-lang.github.io/Nim/macros.html#quote%2Ctyped%2Cstring)

and the macro tutorial, specifically:

[https://nim-lang.github.io/Nim/tut3.html#introduction-generating-code](https://nim-lang.github.io/Nim/tut3.html#introduction-generating-code)

So the basic idea is that quote do allows you to write exactly the code you 
want to generate. However, in most cases that's not really very helpful, 
because if you can explicitly write your code, you could also just write a 
template / proc. That's where the back ticks come in to perform actual quoting 
of NimNodes defined in the current scope. They will be inserted in those places.

quote do is thus just a nice way to avoid having to build the AST manually (as 
I for instance do in the newVar proc), but keep the ability to insert NimNodes 
you calculate / determine somehow based on what the macro is supposed to 
accomplish.

Another thing to keep in mind when using quote do is about the stuff that's not 
quoted with back ticks. As a rule of thumb (someone please correct me):

  * any procedure / template you use within quote do will be bound in the scope 
where the macro code is injected
  * any variables you introduce will be "gensym'd", that is for each symbol you 
introduce a unique symbol will be created. So if you write var x = 5 within 
quote do, the final code won't have the variable x, but something like x_12345.



The second means that if you want to refer to some variable that will be known 
in the scope in which the macro is used, you have to create the identifier 
manually and quote it. Due to the first point you fortunately don't have to do 
the same for procedures you want to use.


Re: AsyncHTTPClient crashes saying invalid http version

2020-04-17 Thread dom96
> Writing a synchronous downloader script was a breeze: 
> [https://gitlab.com/snippets/1967018](https://gitlab.com/snippets/1967018)

Is this a wrong link? because that doesn't look synchronous.

You're doing a number of things incorrectly here. One important thing to know 
is that you should never use waitFor in an async procedure, use await.

What I believe is the problem though, is that you are reusing the same 
AsyncHttpClient instance for multiple concurrent requests. You need to create 
one AsyncHttpClient instance for each request that you want to be running 
concurrently. I'm going to create an issue on GitHub to show a better error 
message for this case.

The easiest way to make this work would probably be to split up 
parseJson(j)["posts"] into x many lists, then run x async procs on each list 
which create their own AsyncHttpClient and iterate through the list downloading 
each one-by-one (using await instead of storing each future and awaiting them 
all).


Re: AsyncHTTPClient crashes saying invalid http version

2020-04-17 Thread geotre
To keep multiple connections open at a time you will need a separate HttpClient 
for each. Try moving webClient = newAsyncHttpClient() into the for loop so each 
call to webClient.downloadFile has it's own client


Re: generate c++ code from .nim file

2020-04-17 Thread minimisthupper
i get this error every time, when i compile my main file :


@msecond.nim.cpp:9:10: fatal error: 'nimbase.h' file not found
#include "nimbase.h"
 ^~~
1 error generated.


Run


Re: Nim Forum build error

2020-04-17 Thread Yardanico
Check 
[https://github.com/nim-lang/nimforum/blob/master/nimforum.nimble](https://github.com/nim-lang/nimforum/blob/master/nimforum.nimble)
 and you'll find: 


task backend, "Compiles and runs the forum backend":
  exec "nimble c src/forum.nim"
  exec "./src/forum"


Run


task frontend, "Builds the necessary JS frontend (with CSS)":
  exec "nimble c -r src/buildcss"
  exec "nimble js -d:release src/frontend/forum.nim"
  mkDir "public/js"
  cpFile "src/frontend/forum.js", "public/js/forum.js"


Run

so execute "nimble backend" to build backend and "nimble frontend" to build 
frontend (see other tasks too)


Re: Nim Forum build error

2020-04-17 Thread jjude
Tried both (verbose & individual command). Same error: No binaries built, did 
you specify a valid binary name?


Re: Nim Forum build error

2020-04-17 Thread b3liever
Try to run the commands inside nimforum.nimble to find the error messages, 
alternatively look for a nimble verbose option that doesn't hide the build 
commands output


Nim Forum build error

2020-04-17 Thread jjude
I used the latest code from github. Issued 


git submodule update --init --recursive
nimble frontend


Run

I get this error: Error: No binaries built, did you specify a valid binary 
name?.

Nim version: Nim Compiler Version 1.0.6 [MacOSX: amd64]

How to go further?


Re: I think we can really do better...

2020-04-17 Thread miran
@other_mods: Guys, didn't you notice that @brianwil2727 has put one link to 
some Bitcoin stuff to his post? It is a well-masked spam.


Re: Iterate over fields

2020-04-17 Thread b3liever
There is also 
[json.to](https://github.com/nim-lang/Nim/blob/devel/lib/pure/json.nim#L1201) 
as an example.


Re: Compile-time string obfuscation

2020-04-17 Thread Yardanico
https://github.com/Yardanico/nim-strenc


Re: I think we can really do better...

2020-04-17 Thread Pixeye
It's not about claiming to be something revolutionary. It's about the message. 
The fact that I don't know about Modula and Ada says nothing. We live in the 
world of internet. I can read the wiki page of those lang. It doesn't make me 
"knowing Ada/Modula"

Of course, all languages built on each other and if I would like to know who 
influenced Nim I'll read the wiki. This is not the information that can be 
valuable for me as a user in the first place. This is my point :) With all 
respect to Ada, Modula, and other great languages.


Re: Iterate over fields

2020-04-17 Thread Clonk
I didn't about the quote do tricks, that's useful !

Why do you have to use backtick "`" inside quote do ? Is it to interpret macro 
inside a block of code ?


Re: I think we can really do better...

2020-04-17 Thread Stefan_Salewski
Note, my initial suggestion was

"Nim combines successful concepts from mature language like Python, Ada and 
Modula with a few sounding features of latest research."

Unfortunately they discarded the last part, I think to fit it all to one page.

But I have copied all my advertisings to my book:

[http://ssalewski.de/nimprogramming.html](http://ssalewski.de/nimprogramming.html)

Section

[http://ssalewski.de/nimprogramming.html#_nim_has_a_encouraging_future](http://ssalewski.de/nimprogramming.html#_nim_has_a_encouraging_future)

is maybe too much advertising, maybe I will remove that.

The fact that you do not know Modula and Ada is not that great, Modula was an 
important milestone in development of languages, it was the successor of Pascal 
and introduced the module concept around 1980 which current C++ is still 
missing. And Ada, designed by a committee it may be a bit ugly, but it has been 
improved and is still used in critical areas like aircraft.

All languages built on each other in a way, each new languages has learned from 
previous ones and tries to avoid their mistakes.

I guess even V-Lang will not claim to be something revolutionary new?

And Rust -- it is indeed a better C++, and has a large company behind it and 
much hype. 


Re: I think we can really do better...

2020-04-17 Thread Pixeye
just my 5 cents about the theme itself. I think it would be great to understand 
the audience of Nim. I think the topic is not about languages. It's about 
people who stand behind. People are valued. Fresh blood and young programmers 
who are trying to make new stuff. Why?

Because It's hard to convince people that already earn money and have robust 
working toolsets on other langs to drop it in favor of other lang. So the 
audience is not about programmers that came from Python, Ada, Modula, Whatever. 
The audience is people who are

  1. new to programming
  2. have money/will to shift to new tech ( a much smaller group )
  3. hobbyist and who program for fun in a spare time



I want to point on Rust and Nim sites:

  * Rust



A language empowering everyone to build reliable and efficient software.

Obviously I find Rust description sexy, elegant and I understand the mission of 
the language. And I understand why game dev fellas like this description.

  * Nim



Nim is a statically typed compiled systems programming language. It combines 
successful concepts from mature languages like Python, Ada and Modula.

The first part about typed compiled lang is ok and this is why I came here :)

But I know nothing about Ada or Modula. I even never heard of those languages. 
And I think I don't want to. ( Not because I think they are bad of course )

>From my mentality "we take a,b,c,d from there and do better mixing stuff" is 
>not cool. It's like "drink my custom Pepsi, it took best of Cola". Those who 
>are fine with Cola won't look at custom Pepsi, and those who never tasted Cola 
>can't make a decision on drinking custom Pepsi that advertises flavors they 
>never tried.

The Nim language is cool. Period. It doesn't need to compare itself with other 
languages. It's not a selling point. I want a language that helps me solve real 
problems, not a language that solves the problems of other languages.

What problems I have as a game developer?

The first problem is that system languages are great for writing core but often 
too hard for scripting and writing the game itself. Many reasons from syntax to 
more strict rules of how to write code. Maybe core developers fill confident 
but your teammate might have less experience and just want to script.

That's why we have Lua and so on. That's why Unity is on the C++ side and 
scripting is on C# side and they're a lot of silly "optimizations" about 
caching variables and stuff not to make an extra call on the C++ side. That's 
why Unity makes "subsets of C#" to put everything in one scope. A lot of hard, 
dirty work I think.

The second problem is portability. Pc, Mac, Linux, Consoles, Ios, Androids. It 
would be super nice if you can port your game to every device without rewriting 
the game to another language. As Nim compiles to C/C++/JS I can at least hope 
that I will be able to get on every possible platform.

just few examples of what I find like selling points:

  * Write code once, deploy everywhere - selling point
  * You will do more typing less - selling point
  * The language is expressive and versatile, you can write efficiently core 
stuff and game scripts in the same language and scope ( I don't need to mention 
here C++/Lua, it's obvious ) - my personal game dev selling point.



PS, I 'm 30 years old and came to programming accidentally. I developed games 
in C# with Unity for a decade and never identified myself as a programmer. With 
experience, I realized that I don't need an aircraft carrier to make 2d games. 
The safe options are C/C++. The other 3 options were D, Rust, and Nim. And I've 
started looking at Rust. Why? Everyone said that IT'S THE THING for game dev. 
From every corner. No one said to me to use Rust because it's like C++ but 
better. No. I was advertised that I can write safe code and Rust will solve my 
problems. It took me some time to realize that I don't like Rust language ( 
simple as that ). But it hooked me more than Nim at first. 


AsyncHTTPClient crashes saying invalid http version

2020-04-17 Thread adnan
Hi, I'm still trying to figure out async/await. I am writing a script that 
parses a json returned by a forum API and tries to download all the files 
described by the json. Writing a synchronous downloader script was a breeze: 
[https://play.nim-lang.org/#ix=2gcb](https://play.nim-lang.org/#ix=2gcb)

However I have been struggling with making the downloads asynchronous. First of 
all I used the `AsyncHTTPClient` called `webClient`. Then I iterate over the 
json nodes to look for parts that I need to construct file download link. Then 
I created a `seq[Future[void]]` caled `futures` to store all the futures 
returned by `downloadFile()` method. Then I start the loop. Each time I make a 
call to `downloadFile()`, I store the future into `futures` seq.

Lastly when the loop finishes I call `waitFor futures.all()` to wait for the 
future returned by the `all()` function 
([https://nim-lang.org/docs/asyncfutures.html#all%2Cvarargs%5BFuture%5BT%5D%5D](https://nim-lang.org/docs/asyncfutures.html#all%2Cvarargs%5BFuture%5BT%5D%5D))
 to yield.

And at the very last I `waitFor` my main function.


import strutils, os, json, strformat, httpclient, asyncdispatch

proc mediaLink(node: JsonNode; board, thread: string): string =
  let
fileID = node["tim"].getInt()
ext = node["ext"].getStr()
  
  result = fmt"https://i.4cdn.org/{board}/{fileID}{ext};

proc parseBoardAndThread(uri: string): (string, string) =
var
slashCount = 0
board = newStringOfCap(2)
thread = newStringOfCap(8)

for c in uri:
if c == '/':
slashCount += 1
elif slashCount == 3:
board &= c
elif slashCount == 5:
if c >= '0' and c <= '9':
thread &= c
else:
break
return (board, thread)

proc getAPILink(board, thread: string): string =
  fmt"https://a.4cdn.org/{board}/thread/{thread}.json;

proc getRawLink(): string =
  if os.paramCount() < 1:
when not defined release: # debugging purposes so I can just call 
./threadgrabber without any link and dir
  result = "https://boards.4channel.org/wsg/thread/3360760;
else:
  quit("Link required. Usage: $threadgrabber  ")
  else:
result = paramStr(1)

proc getRawDownPath(): string =
  if os.paramCount() < 2:
when not defined release:
  result = "out"
else:
  quit("Download destination required. Usage: $threadgrabber  ")
  else:
result = paramStr(2)

proc main() {.async.} =
  var
boardAndThread = parseBoardAndThread(getRawLink())
downPath = getCurrentDir() & "/" & getRawDownPath()
board = boardAndThread[0]
thread = boardAndThread[1]
  if not downPath.existsDir():
echo("Local path not recognized. Creating directory: ", downPath)
createDir downPath
  var
webClient = newAsyncHttpClient()
link = getAPILink(board, thread)
j: string = await webClient.getContent(link)
futures: seq[Future[void]]
  
  for node in parseJson(j)["posts"]:
if node{"tim"} != nil:
  var
tim = node["tim"].getInt()
ext = node["ext"].getStr()
downFileName = fmt"{downPath}/{tim}{ext}"
  echo("Downloading ", node.mediaLink(board, thread), " as ", 
downFileName, "...")
  var downloadFuture = webClient.downloadFile(node.mediaLink(board, 
thread), downFileName)
  downloadFuture.callback=
proc() =
  echo("Downloading ", tim, ext, " Complete")
  futures &= downloadFuture
  waitFor futures.all()

waitFor main()


Run

The program crashes with vague error messages, complaining that the http 
version is not correct: 
[https://pastebin.com/2jXHKbMV](https://pastebin.com/2jXHKbMV)

I'm compiling with `--d:ssl --threads:on` flag. Any pointers?