Fork me on GitHub
#babashka
<
2021-07-29
>
crinklywrappr07:07:28

(import '[javax.imageio ImageIO]) in a script is resulting in Unable to resolve classname errors. I have an input stream and need to read it into a BufferedImage. Using this class appears to be the recommended way to do it. Wat do?

borkdude07:07:28

@doubleagent javax.imagio isn't part of bb (yet?).

👍 3
crinklywrappr07:07:18

@borkdude idea was to write a little script to crawl r/wallpapers, and I realized that I could use babashka to query image dimensions in memory w/o saving to disk. http-kit works great, but I'm stuck here. Can you think of a workaround?

borkdude07:07:56

@doubleagent usually people shell out to other tools that can do this kind of stuff. on linux you could e.g. use identify or imagemagick or so

borkdude07:07:39

e.g. Adam has built a wrapper for ffmpeg in this way: https://www.youtube.com/watch?v=0Ch-zNZ67go

🚀 2
borkdude07:07:05

oh I see, the image is not on disk

borkdude07:07:10

I don't know how hard it is to inspect the headers of images manually

borkdude07:07:57

There is a great library for this: https://github.com/helins/binf.cljc But then you would need to parse the headers with it yourself

crinklywrappr07:07:41

I suspect parsing image metadata is going to take longer than an hour, lol. Thanks for the suggestion though. binf looks cool.

borkdude07:07:36

We could consider adding the class to bb, but I suspect that people would then also want java.awt, etc. and this could lead to an considerable increase in binary size. It's worth trying though and just see what happens.

borkdude07:07:53

Feel free to post an issue on the Github Discussions forum about it under "Ideas"

borkdude07:07:05

and you can build bb locally by adding the class, etc.

crinklywrappr07:07:15

If there's a guide for adding modules/classes to bb then I might look into submitting a pr

borkdude07:07:44

yeah, a PR is not the problem, it's more the research around it and gathering feedback from the community if this is really worth adding for everyone

borkdude07:07:56

you can add the class in babashka.impl.classes

borkdude07:07:18

binary size is mostly my concern

borkdude07:07:51

so if you can build locally with and without this/these classes and report the increase in binary size, we have some useful information

crinklywrappr07:07:06

Thanks, you're awesome! I completely respect your concern about binary size.

martinklepsch11:07:27

should shell in bb tasks resolve an env var like $SOME_THNG

borkdude11:07:58

it doesn't. Use (System/getenv "SOME_THING"), bb doesn't support bash syntax

borkdude11:07:58

if you need to set an env var you can use :extra-env or :env in a map as the first argument of shell

martinklepsch11:07:52

Ah, because windows, I guess?

borkdude11:07:07

no, just because shell doesn't invoke bash

martinklepsch11:07:30

I’m trying something like (shell (str "scp -r src root@" (System/getenv "PROD_IP"))) but somehow it’s not happening 😅

martinklepsch11:07:52

nevermind, my bad

borkdude11:07:57

that should work. try hardcoding the IP in doubt

martinklepsch11:07:00

I was missing the colon at the end 🙂

👍 3
martinklepsch11:07:19

is there a better way than string concatenation for this type of thing?

borkdude11:07:24

perhaps format would help a bit, or selmer:

(let [prod-ip (System/getenv "PROD_IP")] (selmer/<< "scp -r root@{{prod-ip}}"))
:)

borkdude12:07:03

(you should require selmer.parser :refer [<<] or selmer.parser :as selmer for this)

borkdude12:07:33

for the life of me I cannot remember the syntax for numbered arguments in format

borkdude12:07:05

$ bb -e '(format "%2$s %1$s" 1 2)'
"2 1"

Max13:07:32

If I have deps specified in bb.edn, how do I get babashka to install them? I vaguely remember that it used to happen automatically but it doesn’t seem to be anymore

borkdude13:07:02

it should happen automatically

borkdude13:07:40

perhaps caching is messing it up, try bb --force

borkdude13:07:52

(if you have the newest)

borkdude13:07:12

else: rm -rf ~/.clojure/.cpcache

Max13:07:16

I’m pretty sure my bb.edn is getting picked up because it’s finding my source files (I’m using the whole src/ structure thing)

borkdude13:07:47

do you mean, you have deps in deps.edn and would like to use them from bb?

borkdude13:07:13

they should be in bb.edn. they were resolved by accident from deps.edn in some previous version but this was never the intent

Max13:07:05

No, I have a :deps keyword in bb.edn

Max13:07:47

yep, --force did it

Max13:07:57

thanks for the help!

jimberlage14:07:55

I'm seeing the same issue - no change if I remove .cpcache

borkdude14:07:38

perhaps you have set BABASHKA_CLASSPATH?

jimberlage14:07:33

Yup, I have that set

jimberlage14:07:59

What should it be set to, in these cases? Or should the project I'm working in be added to the global classpath?

borkdude15:07:14

if you want bb to get deps from bb.edn, you should not use BABASHKA_CLASSPATH at all

borkdude15:07:21

because it overrides it

jimberlage15:07:58

unset BABASHKA_CLASSPATH
did the trick

👍 3
jimberlage15:07:58

unset BABASHKA_CLASSPATH
did the trick

👍 3
Jakub Šťastný15:07:04

Babashka noob question: I use bb for running some processes that take rather long to complete. Hence I want to show time elapsed. So for instance I have (run "yes | unminimize"), that takes a long time, and currently it only prints $ yes | unminimize, but it wouldn't show how long is the thing running. So I want it to print $ yes | unminimize .... 7:02m and of course have the time update itself (shell has the \r sequence which deletes what was already printed, I think that works here). Now I can see there's an example in the bb book about that, but given that I really never have to deal with concurrency (only callbacks/promises in JS), I feel a bit out of the water. Can anyone please tell me which macros/fns should I use?

borkdude16:07:37

@zikajk You could spawn a future that prints in a loop and reads from some atom. While the atom doesn't contain a value, you keep printing in the loop, else you return from the loop. When your long running shell function terminate, you put a value in the atom.

borkdude16:07:43

That's one way to do it.

Jakub Šťastný16:07:03

(defn- current-unix-time [] (quot (System/currentTimeMillis) 1000)) (let [result (atom nil)] (future (Thread/sleep 3000) (reset! result {:stdout []})) (future (let [start-timestamp (current-unix-time)] (loop [] (when-not (deref result) (Thread/sleep 1000) (print (str "\r" (- (current-unix-time) start-timestamp))) (flush) (recur)))))) (Thread/sleep 10000)

Jakub Šťastný16:07:31

OK, this does it ... the last bit I'm not sure how to get rid off is the (Thread/sleep), the very last line. If I don't put it there, it just exits straight away.

Jakub Šťastný16:07:10

How do I do something like Promise.all(future-1 future-2)? As in wait once both futures has finished and then quit?

Jakub Šťastný17:07:36

OK, solved with (run! deref [future-1 future-2])

ambrosebs00:07:01

I used to do this until I learnt about https://clojure.atlassian.net/browse/CLJ-2574 :)

Jakub Šťastný18:07:10

Hmm ... but what's the alternative then @U055XFK8V ?

ambrosebs01:07:49

doseq has similar semantics.

borkdude18:07:45

that's a way to do it. you can also use core.async which is part of babashka as well

👍 3