beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
2021-02-12T11:06:08.008600Z

Hi Guys, i'd like to connect clojure with google sheets. https://github.com/SparkFund/google-apps-clj Question is where should i put this in the project.clj ? [google-apps-clj "0.6.1"] is it under dependencies?

(defproject asdf "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "<http://example.com/FIXME>"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "<https://www.eclipse.org/legal/epl-2.0/>"}
  :dependencies [[org.clojure/clojure "1.10.1"]]
  :main ^:skip-aot asdf.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all
                       :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})

2021-02-12T11:18:52.009200Z

ooo thank you @pavlos :D

raicotop 2021-02-12T14:26:40.011400Z

Hi, I'm taking a look at https://github.com/bbatsov/clojure-style-guide#nil-punning

;; good
(defn print-seq [s]
  (when (seq s)
    (prn (first s))
    (recur (rest s))))

;; bad
(defn print-seq [s]
  (when-not (empty? s)
    (prn (first s))
    (recur (rest s))))
I always use empty? because I find it more clear and readable. Would anyone please explain why it's considered bad?

dharrigan 2021-02-12T14:28:02.011800Z

It's not that it's bad or better, it's more idiomatic...

dharrigan 2021-02-12T14:28:18.012Z

user=&gt; (doc empty?)
-------------------------
clojure.core/empty?
([coll])
  Returns true if coll has no items - same as (not (seq coll)).
  Please use the idiom (seq x) rather than (not (empty? x))
nil
user=&gt; 

dharrigan 2021-02-12T14:29:26.012800Z

The thing about seq is that it will return the collection, whereas empty? will simply return true or false

lispyclouds 2021-02-12T14:30:03.013700Z

Also empty? is implemented as (not (seq coll)) so you're kinda doing a double negation.

dharrigan 2021-02-12T14:30:14.013900Z

:thumbsup:

raicotop 2021-02-12T14:38:23.016400Z

Thanks!

2021-02-12T14:39:00.016500Z

@pavlos, ive tried to follow steps : Obtaining OAuth 2 Credentials but stuck at step 6, i've create the google-creds.edn, where should i save this?

lispyclouds 2021-02-12T14:39:46.017700Z

you could use https://clojuredocs.org/clojure.core/not-empty if it helps with the reading, but has the same outputs as seq

2021-02-12T14:39:57.018Z

whenever i called (edn/read-string (slurp "config/google-creds.edn")) , repl error said no such namespace: edn

dharrigan 2021-02-12T14:43:20.019400Z

I would posit too that a clojurist reading clojure code would understand if they saw something like (when-let [foo (seq (get-data))] ... ) would know what's going on 🙂

2021-02-12T14:49:47.020200Z

Hi https://github.com/SparkFund/google-apps-clj i've tried to follow steps : Obtaining OAuth 2 Credentials but stuck at step 6, i've create the google-creds.edn, where should i save this? whenever i called (edn/read-string (slurp "config/google-creds.edn")) , repl error said no such namespace: edn

dharrigan 2021-02-12T14:52:48.020800Z

You need to bring in the edn namespace,

dharrigan 2021-02-12T14:52:49.021Z

i.e.,

dharrigan 2021-02-12T14:53:08.021500Z

(require '[clojure.edn :as edn])

dharrigan 2021-02-12T14:53:24.021800Z

user=&gt; (require '[clojure.edn :as edn])
nil

dharrigan 2021-02-12T14:53:33.022Z

user=&gt; (edn/read-string (slurp "/home/david/foo.edn"))
{:foo [1 2 3]}

2021-02-12T14:55:13.023Z

does clojre.edn , the "clojure" can be changed with my project name? (require '[asdf.edn :as edn])

dharrigan 2021-02-12T14:55:36.023500Z

No, it's a "core" library, part of clojure

dharrigan 2021-02-12T14:55:46.023800Z

it's namespace is clojure.edn

2021-02-12T14:56:19.024200Z

ohh okay noted

dharrigan 2021-02-12T14:56:53.024600Z

it's like, in java doing an import java.time.LocalDate

dharrigan 2021-02-12T14:57:17.024900Z

np

2021-02-12T15:00:09.025500Z

@dharrigan then in step 9 how do i call google-apps-clj.credentials/get-auth-map?

dharrigan 2021-02-12T15:00:56.025900Z

I would imagine, without knowing the api at all, something like this:

dharrigan 2021-02-12T15:02:43.027500Z

Their tests sorta show how it works

dharrigan 2021-02-12T15:02:54.027900Z

.

dharrigan 2021-02-12T15:03:59.028700Z

so instead of calling default-credential you call get-auth-map passing in the slurped data from the edn file

dharrigan 2021-02-12T15:04:30.029400Z

(gauth/get-auth-map (edn/read-string (slurp "/home/adrian/my-credentials.edn")) scope)

dharrigan 2021-02-12T15:06:32.030200Z

with scope set to be "<https://docs.google.com/feeds/>" or one of the other examples

2021-02-12T15:08:54.032Z

I'm lost here... Apologize bcs I'm still newbie here. I'd like to ask when we put this [google-apps-clj "0.6.1"]within dependencies in project.clj then i run lein deps in my cmd. it's kinda installing/downloading, where this library stored?

dharrigan 2021-02-12T15:09:45.032300Z

that's okay, we're all beginners 🙂

dharrigan 2021-02-12T15:10:19.032800Z

Okay, so you are using leiningen, you have a project.clj?

dharrigan 2021-02-12T15:10:28.033100Z

or are you using deps.edn?

2021-02-12T15:11:43.033300Z

i use project.clj

dharrigan 2021-02-12T15:12:53.033600Z

Take for example, the google apis project.clj

dharrigan 2021-02-12T15:13:07.034300Z

you can see that the dependencies are in a block called dependencies

dharrigan 2021-02-12T15:13:21.034700Z

in your project, you would add in the google-aps-clj into your dependencies block

dharrigan 2021-02-12T15:13:27.035Z

make sense?

2021-02-12T15:14:18.035600Z

yes, i've add [google-apps-clj "0.6.1"] in my dependencies block

dharrigan 2021-02-12T15:14:27.035900Z

great

dharrigan 2021-02-12T15:15:22.036600Z

so, now you can do lein repl to bring up a repl for experimentation

2021-02-12T15:16:10.036800Z

yes

dharrigan 2021-02-12T15:16:52.037400Z

great, so now you can require in the various libraries for playing around, such as the google apps library

2021-02-12T15:17:15.037800Z

this

2021-02-12T15:17:28.038200Z

my repl now ready

dharrigan 2021-02-12T15:17:52.038700Z

very good, now you can add in the requires, think of "imports" like you would in java

dharrigan 2021-02-12T15:18:10.039100Z

their tests, which I linked previously, shows how to import their libraries

pavlosmelissinos 2021-02-12T15:19:23.039500Z

there's no namespace called edn

pavlosmelissinos 2021-02-12T15:20:28.039900Z

read-string is a function that exists in clojure.edn : Check out the examples here: https://clojuredocs.org/clojure.edn/read-string

2021-02-12T15:21:27.040700Z

OHHHHHHHHHHHH... like this? since i'm going to use google sheets, i take the require from https://github.com/SparkFund/google-apps-clj/blob/develop/test/google_apps_clj/google_sheets_v4_test.clj

dharrigan 2021-02-12T15:23:11.040900Z

not quite, nealry

dharrigan 2021-02-12T15:23:20.041200Z

you don't ns their stuff

dharrigan 2021-02-12T15:23:26.041400Z

you require it into yours

2021-02-12T15:24:31.041800Z

sorry, this is revised

dharrigan 2021-02-12T15:24:31.041900Z

Let me show you...

dharrigan 2021-02-12T15:24:38.042100Z

yes

dharrigan 2021-02-12T15:24:40.042400Z

that is better

dharrigan 2021-02-12T15:24:50.042700Z

now you have their stuff required into your namespace

dharrigan 2021-02-12T15:25:10.043Z

that should get you going now 🙂

2021-02-12T15:29:31.043800Z

i got an error with the ns from here https://github.com/SparkFund/google-apps-clj/blob/develop/test/google_apps_clj/google_sheets_v4_test.clj i'll try with another

2021-02-12T15:32:07.044100Z

this one works

dharrigan 2021-02-12T15:37:49.044600Z

It's okay, it's a warning

2021-02-12T15:40:16.044900Z

step 9 still is really confusing.

2021-02-12T15:43:31.045300Z

it doesn't result anything in repl.

pavlosmelissinos 2021-02-12T15:56:54.046200Z

You're not using the function step 9 is telling you to call.

2021-02-12T15:59:20.046600Z

I'm sorry, but how to call it?

dharrigan 2021-02-12T16:05:24.047200Z

Is this your first time using Clojure may I ask?

2021-02-12T16:06:04.047800Z

Sadly yes.. I'm learning from braveclojure until ch 9 now

2021-02-12T16:06:32.048700Z

apologize if i really don't understand... i never touch java either

dharrigan 2021-02-12T16:06:40.048900Z

I think, learning to do oauth2 authentication to google, is a big big step

😅 1
dharrigan 2021-02-12T16:07:30.050Z

Could you start with something smaller perhaps? Learn how to invoke functions, passing in arguments?

dharrigan 2021-02-12T16:07:59.050800Z

loading (requiring) in namespaces and working with the functions defined within them?

2021-02-12T16:08:06.051Z

okay noted.

dharrigan 2021-02-12T16:08:29.051700Z

Very happy to help, but it does seem like more basics are required first, until you tackle the beast that is oauth2

dharrigan 2021-02-12T16:08:38.052Z

and trust me, oauth2 sucks

2021-02-12T16:10:18.053Z

allright, i'll re-learn again about the :require once i could do the csv api, but this google things... is very difficult

dharrigan 2021-02-12T16:10:24.053200Z

agreed

dharrigan 2021-02-12T16:10:30.053500Z

🙂

dharrigan 2021-02-12T16:11:08.054300Z

I would also recommend the <https://practicalli.github.io/> courses

dharrigan 2021-02-12T16:11:16.054600Z

they are good too

2021-02-12T16:12:09.055300Z

ahhh okay, thank you so much for the help... step 9 is like last boss... i'll go levelling first

dharrigan 2021-02-12T16:12:14.055500Z

np

Tim Robinson 2021-02-12T17:12:29.060600Z

Hi all. I have 2 namespaces implementing the same functions and I'm trying to dynamically select one based on a configuration entry. I don't really want to get into dependency injection frameworks, interfaces, protocols and all of that stuff unless I have to. I've figured out that this seems to work: (let [namespace (if some-config-flag 'namespace1 'namespace2)] (require [namespace :as implementation])) (implementation/do-something) Is this considered a sensible thing to do, or an abominable hack?

alexmiller 2021-02-12T17:14:53.061500Z

closer to the latter :)

dpsutton 2021-02-12T17:15:13.061900Z

can you just require both? (if (= option :a) (the-a-choice/launch-missles) (tests/launch-console-text-missiles))

alexmiller 2021-02-12T17:15:51.062600Z

using requiring-resolve with a fully-qualified var would be better

dharrigan 2021-02-12T17:16:07.063100Z

I have a use case that I do for this, and yup, Alex beat me to it, (requiring-resolve)

alexmiller 2021-02-12T17:16:11.063300Z

assuming you need the dynaload

Tim Robinson 2021-02-12T17:22:08.064900Z

I have about 20 functions in the implementing namespace, and it's something that is used very heavily in my app (the main persistence module). does requiring-resolve make sense for that or would it have a high runtime overhead?

Tim Robinson 2021-02-12T17:23:16.065700Z

also I don't need to load it dynamically - both implementations will be present in the released package

alexmiller 2021-02-12T17:46:40.066100Z

I mean, from what you describe, I'd probably use a protocol

alexmiller 2021-02-12T17:47:21.066500Z

and just use config to choose what to instantiate

alexmiller 2021-02-12T17:48:26.067200Z

doing the conditional require stuff makes it a lot harder for editors, tools, etc to understand what you're doing (and possibly other developers as well)

Tim Robinson 2021-02-12T18:07:27.068700Z

Thanks - yes I did notice that clj-kondo didn't like what I was doing 🙂 I was put off protocols thinking they were really intended just for java interop, but it looks to me like the best match

ej 2021-02-12T19:31:26.079300Z

I know very little about web application security, but I'm trying to learn more. I know it is normal to protect certain parts of an application, and require the user to be authenticated in order to be authorized to see whatever is protected. But what if I also wanted to encrypt the information going into the system from the client, so that the database administrator or someone who gained entry to the database would not be able to see whatever was stored there. Is this feasible, or common? Can the information be decrypted fast enough for the system to respond like a normal web application, or would that process be very slow? Does anyone know of any good resources for doing things like this in Clojure, or just a general overview of web application security? So far I have found this: https://purelyfunctional.tv/article/clojure-web-security/

dharrigan 2021-02-12T19:37:02.079800Z

in my experience, encryption all the way to the database level is rare

dharrigan 2021-02-12T19:37:30.080400Z

however, saying that, I know that our AWS RDS instances do encrypt the storage underneath

dharrigan 2021-02-12T19:37:58.081100Z

however, that's at the block level, not at the application level, so I can easily psql into a RDS instance and do normal selects etc...

dharrigan 2021-02-12T19:38:51.081900Z

our internal API calls are all TLS (which makes debugging a bit difficult, unless you plug in a MITM on your work machine 🙂 )

dharrigan 2021-02-12T19:39:05.082200Z

however, this is probably better discussed in #off-topic 🙂

👍 1
2021-02-12T19:44:03.082900Z

given a hypothetical database that stores encrypted data, it would need to decrypt it to do all the good things databases do (build indices, enforce constraints, etc). so the database will need to be able to decrypt it, which means if someone has the highest level access to the database (typical of a database admin) that means they can also decrypt it

2021-02-12T19:44:53.083100Z

so no, not feasible

2021-02-12T19:46:39.083300Z

if you aren't interested in a database, and just want a blob key value store, it is feasible. if you aren't familiar, and haven't work with something like a sql database before, you might equate a database with a key value store, but they definitely are not the same thing

ej 2021-02-12T20:09:59.083600Z

Thanks, this has given me something to consider!