This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-25
Channels
- # announcements (16)
- # babashka (110)
- # babashka-sci-dev (11)
- # beginners (50)
- # biff (3)
- # calva (1)
- # clj-commons (19)
- # clj-kondo (1)
- # clojure (17)
- # clojure-art (19)
- # clojure-austin (5)
- # clojure-berlin (2)
- # clojure-denmark (3)
- # clojure-europe (101)
- # clojurescript (84)
- # clr (1)
- # core-async (2)
- # emacs (3)
- # helix (5)
- # honeysql (4)
- # hyperfiddle (8)
- # introduce-yourself (2)
- # jobs (1)
- # lsp (18)
- # membrane (3)
- # reagent (5)
- # releases (3)
- # shadow-cljs (10)
- # tools-deps (24)
I am trying to override clojure.core.async.impl.exec.threadpool
thread-pool-executor
can I just call intern
?
I guess the symbols need to be exposed? From async protols only ReadPort is defined I think
does core.async has a function to set the threadpool executor? clojure itself has this:
user=> (apropos "executor")
(clojure.core/set-agent-send-executor! clojure.core/set-agent-send-off-executor!)
Might be good to request a function for this that explicitly supports this on ask.clojure. It seems it's not well supported currently, barring some hacks changing an impl namespace: https://stackoverflow.com/questions/18779296/clojure-core-async-any-way-to-control-number-of-threads-in-that-go-thread
Doing the intern
in SCI will not have the desired effect since the pre-compiled functions don't see the change
Hmm, we could hack this by adding a watcher on the SCI var that also changes the core var, but even then it might not work (as you can see in the SO answer, the order of loading things matters)
https://ask.clojure.org/index.php/12692/core-async-add-a-function-to-set-thread-executor
https://faster-than-light-memes.xyz/jacking-nbb.html You can now define a cider jack in cmd via .dir-locals.el, or as parameter to a custom function. I was just using this
((nil
(cider-jack-in-cmd . "/tmp/bb nrepl-server")))
so cider-jack-in
starts a dev bb in that dirI am working on a notification tool which is technically a scraper that would fetch HTML pages parse the data with XPath queries and send out notifications. did I get it correctly that currently there is no way to use XPath with Babashka?
@UJSBQNUG6 Dealing with HTML can be done via the bootleg pod:
https://github.com/babashka/pod-registry/blob/master/examples/bootleg.clj
It has a lot of HTML library stuff, e.g. it has enlive
I saw that, but I could not find any XPath support there
I see. If you're open to using Node.js, maybe #C029PTWD3HR is also an option here. I'm sure there are lots of Node libraries that support Xpath
sure, that is a good alternative
I wanted to solve it w/ Babashka since this would be my first project with it
and the experience was flawless so far 🙂
would you go in the hiccup way? or what would give me a similar query like interface?
although I guess, I wouldn’t be able to query the HTML like, I want the <h3>
with this content and all the next siblings until the next <h3>
Perhaps @U1QQJJK89 has an idea?
Warning: converting markup from :html to :hiccup lost 1 form
Cannot read EDN: ...
----- Error --------------------------------------------------------------------
Type: java.lang.RuntimeException
Message: Invalid token: /hirdetmeny?id=1931760
Location: /Users/ikaraszi/_vc/raszi/pnn/src/pnn/scrape.clj:15:3
There is also hickory/select which I've used recently in nbb: https://github.com/babashka/nbb/commit/6feaa7f2e5e0888ccc3a33ea5efbb47041638954
Hmm, @UJSBQNUG6 perhaps you can make a small reproduction of this.
sure, give me a couple of minutes
another option could be to install a look like xidel
which supports xpath:
https://formulae.brew.sh/formula/xidel
and then shell out from bb with (babashka.process/shell "xidel" ...)
So the issue is that the HTML gets transformed into EDN (hiccup) and this EDN is sent back to babashka as a string, but I think there may be some escaping issue
So I might have found a bug?
When I manually paste that string into an .edn file and parse it it's fine...
(clojure.edn/read-string (slurp "/tmp/foo.edn"))
The error is coming from here: https://github.com/babashka/pods/blob/75c2216649bf5caf3ae41e7b8fc202e45b090ea9/src/babashka/pods/impl.clj#L151
I believe the HTML is invalid
<a href="/hirdetmeny?id=1931760" title="„Hejőpapi X.-átmeneti törmelékes nyersanyagok" védnevű bánya bányászati tevékenységére vonatkozó BO/16/7277-22/2016. számú környezetvédelmi engedély módosítása">„Hejőpapi X.-átmeneti törmelékes nyersanyagok" védnevű bánya bányászati tevékenységére vonatkozó BO/16/7277-22/2016. számú környezetvédelmi engedély módosítása</a>
I believe this is the root cause
$ xidel \?SZO\=szeged --silent --extract //h3
Hirdetményét itt tudja beküldeni!
Keresés a hirdetmények között
Találatok
so xidel
could be a working solution, thank you!
It might work with enlive/select
too, not sure:
(prn (enlive/select "<html></html>" #_(slurp "/tmp/foo.html") [:html]))
thank you, I’ll check all 3 options
you can shell out to xidel with:
(shell "xidel" ...)
If you want to get back a string of the output:
(:out (shell {:out :string } "xidel" ...))
etcyes, but then I need to figure how to properly escape the args for xidel
since XPath selectors are quite complex
and I cannot see a good way to do the escaping with babashka.process/shell
like what happens if I have both the quotes (`"` and '
) in the argument?
what would be great to be able to pass a data structure to babashka.process/shell
and that would do the escaping automatically and I would not need to build a string
["cmd", arg0, arg2, arg3]
or something similar
wouldn't you have the same problem when you would call an xpath function in clojure? I don't see how that would be different than shelling out. the string arrives at xidel exactly how you wrote it, barring Java escaping rules
then there are no issues, I just could not find an example like that
or I need to improve myself
this somehow implies it
@U04V15CAJ how could you get enlive
working? for me it throws:
----- Error --------------------------------------------------------------------
Type: java.lang.Exception
Message: Unable to resolve classname: org.xml.sax.ContentHandler
Location: net/cgrand/xml.clj:11:3
----- Context ------------------------------------------------------------------
7: ; You must not remove this notice, or any other, from this software.
8:
9: (ns net.cgrand.xml
10: (:require [clojure.zip :as z])
11: (:import (org.xml.sax ContentHandler Attributes SAXException XMLReader)
^--- Unable to resolve classname: org.xml.sax.ContentHandler
12: (org.xml.sax.ext DefaultHandler2)
13: (javax.xml.parsers SAXParser SAXParserFactory)))
14:
15: (defstruct element :tag :attrs :content)
16:
----- Stack trace --------------------------------------------------------------
net.cgrand.xml - net/cgrand/xml.clj:11:3
net.cgrand.tagsoup - net/cgrand/tagsoup.clj:12:3
net.cgrand.enlive-html - net/cgrand/enlive_html.clj:14:3
pnn.scrape - /Users/ikaraszi/_vc/raszi/pnn/src/pnn/scrape.clj:2:3
pnn.core - /Users/ikaraszi/_vc/raszi/pnn/src/pnn/core.clj:2:3
pnn.main - /Users/ikaraszi/_vc/raszi/pnn/src/pnn/main.clj:2:3
user - <expr>:1:10
okay, I guess I need to use pods, right?
I believe I would simply switch to clojure
nbb
requires too much rewrites
it was a nice experience with Babashka but unfortunately the HTML parsing made it impossible
I would need to run tidy
, or xidel
from shell and that does not sounds too nice 😞
user=> (json/parse-string (:out (babashka.process/shell {:out :string} "xidel" "" "--silent" "--extract" "//h3" "--output-format" "json-wrapped")))
(["Hirdetményét itt tudja beküldeni!" "Keresés a hirdetmények között" "Találatok"])
and with stdin:
user=> (json/parse-string (:out (babashka.process/shell {:in "<body><h3>\nfoo</h3></body></html>" :out :string} "xidel" "--silent" "--data" "-" "--extract" "//h3" "--output-format" "json-wrapped")))
("foo")
takes 25ms on my machine to shell out and get the answer back, not too bad, but it depends on your constraints of course
I added some clarification here to the examples, hope it helps https://github.com/babashka/process/blob/master/API.md#babashka.process/shell
thank you!
Update all your git repos with 49 lines of babashka: https://github.com/teodorlu/bb-scripts/tree/385d310664c676063bdbfcded3ed4f09ff7ddd91/src/teodorlu/bb_scripts/update_repos.clj To try for yourself with #babashka-bbin:
$ bbin install io.github.teodorlu/bb-scripts --latest-sha
$ cd FOLDER_WITH_ALL_MY_GIT_REPOS
$ update-repos
Those 36 lines aren't too special, you could probably have written those yourself. But I think it's quite amazing how much it's possible to get done with a bit of babashka right now. If I were to try to solve that with Bash, I'd get stuck with string manipulation. And now, bbin really solves distribution for babashka scripts.
I'd encourage anyone on the fence with Babashka, shell scripts and bbin to give it a shot!The syntax for shell is (shell ?opts cmd arg1 arg2)
, what you're using now is a legacy syntax that was only supported by process
, and is now deprecated
OK - thanks! Changing to this:
(shell {:out :string
:continue true
:dir path}
'[git symbolic-ref --short HEAD])
The supported syntax is:
(shell {:out :string
:continue true
:dir path}
"git" "symbolic-ref" "--short" "HEAD")
so:
(shell {:out :string
:continue true
:dir path}
"git symbolic-ref --short HEAD")
would also be validIs there some way I can get the watches for an atom? In Clojure, I can do something like (.getWatches my-atom)
but that’s not working in babashka:
Babashka v1.1.173 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.
user=> (.getWatches (atom {}))
java.lang.NoSuchFieldException: getWatches [at <repl>:1:1]
😊 thanks! I’m really looking forward to the Conj. No rush
I guess there is no non-interop way to get the watches from an atom so I'll have to add this to the reflection config.
My https://github.com/adam-james-v/solenoid project uses a registry of controls, each of which has a ‘cursor’ into it. Cursors are implemented using watch fns that update any atoms that are dependent on the atom being currently changed. Control Blocks are auto-updating whenever controls that drive them change. But, you can use the dereferenced value of any control block in the body of other blocks. The mechanism I came up with to track dependent blocks uses watches and watch keys to get details…
Pushed to master. You can test with:
bash <(curl ) --dev-build --dir /tmp
once the CI build has finishedWhoa, thanks! I’ll give it a spin soon.
My talk will feature Solenoid, but is a bit more broad than that. I want to tell my motivations for learning Clojure, and how I used various projects to help me learn. I’ll be talking a bit about making tools to help make ‘things’ (where things are objects, art, machinery, structures, not just code). The idea of interactivity and manipulation is pretty important to making things that actually work (I remember designing things to be welded… not every joint is physically possible, even if you can 3D model it). And solenoid is just one example of interactive tools that can help in other design/build processes. I promise the talk itself will be coherent haha
Babashka v1.1.174-SNAPSHOT REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.
user=> (def a (atom {}))
#'user/a
user=> (add-watch a :my-watch (fn [_ _ _ _] nil))
#object[clojure.lang.Atom 0x3a37bb7 {:status :ready, :val {}}]
user=> (.getWatches a)
{:my-watch #object[sci.impl.fns$fun$arity_4__1176 0x34a5f957 "sci.impl.fns$fun$arity_4__1176@34a5f957"]}
The snapshot works 🙂 Thanks for working on that so quickly, and on the weekend! Really amazing