From ddca2198c57eb7f53c8480e45531e6a64eaa2ef1 Mon Sep 17 00:00:00 2001 From: niten Date: Wed, 15 Mar 2023 10:02:46 -0700 Subject: [PATCH] Initial checkin --- deps-lock.json | 301 ++++++++++++++++++++++++++++++++ deps.edn | 8 + flake.lock | 212 ++++++++++++++++++++++ flake.nix | 36 ++++ src/objectifier_client/cli.clj | 61 +++++++ src/objectifier_client/core.clj | 60 +++++++ 6 files changed, 678 insertions(+) create mode 100644 deps-lock.json create mode 100644 deps.edn create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 src/objectifier_client/cli.clj create mode 100644 src/objectifier_client/core.clj diff --git a/deps-lock.json b/deps-lock.json new file mode 100644 index 0000000..8cee345 --- /dev/null +++ b/deps-lock.json @@ -0,0 +1,301 @@ +{ + "lock-version": 3, + "git-deps": [], + "mvn-deps": [ + { + "mvn-path": "clj-http/clj-http/3.12.3/clj-http-3.12.3.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-OJ0pdhKo6KzGbF0NZKbJO99lDe1iXG9q4Wk7kzaKkaU=" + }, + { + "mvn-path": "clj-http/clj-http/3.12.3/clj-http-3.12.3.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-Jx0VRYS9iV/S4w9jEVAE8ce4xySq6tLLKpl8XFWEBfA=" + }, + { + "mvn-path": "clj-tuple/clj-tuple/0.2.2/clj-tuple-0.2.2.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-WNv3Pai8403EmN5sNH+HLvmPMBo6KdyVeX1k+A5ra0c=" + }, + { + "mvn-path": "clj-tuple/clj-tuple/0.2.2/clj-tuple-0.2.2.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-ahZELYfCkwwDImtKo9KYkVfVi5TtPnyNZ2aLDrZYOJs=" + }, + { + "mvn-path": "commons-codec/commons-codec/1.15/commons-codec-1.15.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-s+n21jp5AQm/DQVmEfvtHPaQVYJt7+uYlKcTadJG7WM=" + }, + { + "mvn-path": "commons-codec/commons-codec/1.15/commons-codec-1.15.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-yG7hmKNaNxVIeGD0Gcv2Qufk2ehxR3eUfb5qTjogq1g=" + }, + { + "mvn-path": "commons-io/commons-io/2.8.0/commons-io-2.8.0.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-AvKR5dEkPcFDSW48u7QKHO1Hqljy1jPT44eAzQaNUHQ=" + }, + { + "mvn-path": "commons-io/commons-io/2.8.0/commons-io-2.8.0.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-18hkGjfW5282+56B/BQg4moJ1j+jLwD3R2TeBnyoNH0=" + }, + { + "mvn-path": "commons-logging/commons-logging/1.2/commons-logging-1.2.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-2t3qHqC+D1aXirMAa4rJKDSv7vvZt+TmMW/KV98PpjY=" + }, + { + "mvn-path": "commons-logging/commons-logging/1.2/commons-logging-1.2.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-yRq1qlcNhvb9B8wVjsa8LFAIBAKXLukXn+JBAHOfuyA=" + }, + { + "mvn-path": "org/apache/apache/13/apache-13.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-/1E9sDYf1BI3vvR4SWi8FarkeNTsCpSW+BEHLMrzhB0=" + }, + { + "mvn-path": "org/apache/apache/18/apache-18.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-eDEwcoX9R1u8NrIK4454gvEcMVOx1ZMPhS1E7ajzPBc=" + }, + { + "mvn-path": "org/apache/apache/21/apache-21.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-rxDBCNoBTxfK+se1KytLWjocGCZfoq+XoyXZFDU3s4A=" + }, + { + "mvn-path": "org/apache/apache/23/apache-23.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-vBBiTgYj82V3+sVjnKKTbTJA7RUvttjVM6tNJwVDSRw=" + }, + { + "mvn-path": "org/apache/commons/commons-parent/34/commons-parent-34.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-Oi5p0G1kHR87KTEm3J4uTqZWO/jDbIfgq2+kKS0Et5w=" + }, + { + "mvn-path": "org/apache/commons/commons-parent/52/commons-parent-52.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-ddvo806Y5MP/QtquSi+etMvNO18QR9VEYKzpBtu0UC4=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpasyncclient/4.1.4/httpasyncclient-4.1.4.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-UOmBqOVnoW69rRBGBbFWVAqGNFn6EnuLpkfzEN/IPvg=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpasyncclient/4.1.4/httpasyncclient-4.1.4.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-NPJO+Ya4nVG4CgkDh6o9DIJNQPCHrlzPrUf/PCYsLkc=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpclient-cache/4.5.13/httpclient-cache-4.5.13.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-Zs797nR1mFJWr2gL86581dfULo/euTmmJ3ki4b3u1Do=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpclient-cache/4.5.13/httpclient-cache-4.5.13.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-o1h75UcWw7gKMonBHfhlqWK8cr5HiRReQgxpSL9FpKQ=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-b+kCalZsalABYIzz/DIZZkH2weXhmG0QN8zb1fMe90M=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-eOua2nSSn81j0HrcT0kjaEGkXMKdX4F79FgB9RP9fmw=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcomponents-asyncclient/4.1.4/httpcomponents-asyncclient-4.1.4.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-6WXrNprx2LWmi31LeGHVOlJhaugD4TFi6N+EImFwAYA=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcomponents-client/4.5.13/httpcomponents-client-4.5.13.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-nLpZTAjbcnHQwg6YRdYiuznmlYORC0Xn1d+C9gWNTdk=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcomponents-core/4.4.10/httpcomponents-core-4.4.10.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-YelCfUvjJsMHp/FrqCjRyzsUcTybBPyLqZKljzdsMTY=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcomponents-core/4.4.14/httpcomponents-core-4.4.14.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-IJ7ZMctXmYJS3+AnyqnAOtpiBhNkIylnkTEWX4scutE=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcomponents-parent/10/httpcomponents-parent-10.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-yq+WfZSvshdT82CCxghiBr0fSIJf9ZaTLM66crZdOfo=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcomponents-parent/11/httpcomponents-parent-11.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-qQH4exFcVQcMfuQ+//Y+IOewLTCvJEOuKSvx9OUy06o=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcore-nio/4.4.10/httpcore-nio-4.4.10.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-3r7n6VcsAqFs4Mqk9WWp7OsSkNM816HjKXCHvUZ9r/Q=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcore-nio/4.4.10/httpcore-nio-4.4.10.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-pMmVtzjRBLdcyLEWTbYAUzFWwEfsy0yO5dknshoX7HM=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcore/4.4.14/httpcore-4.4.14.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-+VYgnkUMsdDFF3bfvSPlPp3Y25oSmO1itwvwlEumOyg=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpcore/4.4.14/httpcore-4.4.14.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-VXFjmKl48QID+eJciu/AWA2vfwkHxu0K6tgexftrf9g=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpmime/4.5.13/httpmime-4.5.13.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-BudU2ZJFuY3MKGDctD0g5zfWUNor8gd6EF9orMvVxcw=" + }, + { + "mvn-path": "org/apache/httpcomponents/httpmime/4.5.13/httpmime-4.5.13.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-k0GN8hCu7VBQJUjbzysXwPHZFEMDDnL+++7RZSscKN0=" + }, + { + "mvn-path": "org/apache/httpcomponents/project/7/project-7.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-PW66QoVVpVjeBGtddurMH1pUtPXyC4TWNu16/xiqSMM=" + }, + { + "mvn-path": "org/clojure/clojure/1.10.3/clojure-1.10.3.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-fxJHLa7Y9rUXSYqqKrE6ViR1w+31FHjkWBzHYemJeaM=" + }, + { + "mvn-path": "org/clojure/clojure/1.10.3/clojure-1.10.3.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-GJwAxDNAdJai+7DsyzeQjJSVXZHq0b5IFWdE7MGBbZQ=" + }, + { + "mvn-path": "org/clojure/clojure/1.11.0/clojure-1.11.0.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-PiH6daB+yd278bK1A1bPGAcQ0DmN6qT0TpHNYwRVWUc=" + }, + { + "mvn-path": "org/clojure/clojure/1.11.0/clojure-1.11.0.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-SQjMS0yeYsmoFJb5PLWsb2lBd8xkXc87jOXkkavOHro=" + }, + { + "mvn-path": "org/clojure/clojure/1.11.1/clojure-1.11.1.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-I4G26UI6tGUVFFWUSQPROlYkPWAGuRlK/Bv0+HEMtN4=" + }, + { + "mvn-path": "org/clojure/clojure/1.11.1/clojure-1.11.1.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-IMRaGr7b2L4grvk2BQrjGgjBZ0CzL4dAuIOM3pb/y4o=" + }, + { + "mvn-path": "org/clojure/core.specs.alpha/0.2.56/core.specs.alpha-0.2.56.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-/PRCveArBKhj8vzFjuaiowxM8Mlw99q4VjTwq3ERZrY=" + }, + { + "mvn-path": "org/clojure/core.specs.alpha/0.2.56/core.specs.alpha-0.2.56.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-AarxdIP/HHSCySoHKV1+e8bjszIt9EsptXONAg/wB0A=" + }, + { + "mvn-path": "org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-Bu6owHC75FwVhWfkQ0OWgbyMRukSNBT4G/oyukLWy8g=" + }, + { + "mvn-path": "org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-F3i70Ti9GFkLgFS+nZGdG+toCfhbduXGKFtn1Ad9MA4=" + }, + { + "mvn-path": "org/clojure/data.json/2.4.0/data.json-2.4.0.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-7D8vmU4e7dQgMTxFK6VRjF9cl75RUt/tVlC8ZhFIat8=" + }, + { + "mvn-path": "org/clojure/data.json/2.4.0/data.json-2.4.0.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-pC6nDxe1F2Zq2EkqG/qRfeXe+se0fFFvbQ1NicJ4DPQ=" + }, + { + "mvn-path": "org/clojure/pom.contrib/0.3.0/pom.contrib-0.3.0.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-fxgrOypUPgV0YL+T/8XpzvasUn3xoTdqfZki6+ee8Rk=" + }, + { + "mvn-path": "org/clojure/pom.contrib/1.1.0/pom.contrib-1.1.0.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-EOzku1+YKQENwWVh9C67g7ry9HYFtR+RBbkvPKoIlxU=" + }, + { + "mvn-path": "org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-z2iZ+YUpjGSxPqEplGrZAo3uja3w6rmuGORVAn04JJw=" + }, + { + "mvn-path": "org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-WhHw4eizwFLmUcSYxpRbRNs1Nb8sGHGf3PZd8fiLE+Y=" + }, + { + "mvn-path": "org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-Z+yJjrVcZqlXpVJ53YXRN2u5lL2HZosrDeHrO5foquA=" + }, + { + "mvn-path": "org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-bY3hTDrIdXYMX/kJVi/5hzB3AxxquTnxyxOeFp/pB1g=" + }, + { + "mvn-path": "potemkin/potemkin/0.4.5/potemkin-0.4.5.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-KzZsg02Hy26mMbpoaXvDdNDRr4H23rQsKECUTaMgvZk=" + }, + { + "mvn-path": "potemkin/potemkin/0.4.5/potemkin-0.4.5.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-3tL5YlDzDlqPmI60YeMvKzDzbBy0Qz+6qHu82kJRTDo=" + }, + { + "mvn-path": "riddley/riddley/0.1.12/riddley-0.1.12.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-OY9h+kgluPhskWrlgMfhM7fEd9C3Kn07KY04EDJ0C64=" + }, + { + "mvn-path": "riddley/riddley/0.1.12/riddley-0.1.12.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-At+3ryDvgcJTZQVfYCjoscwpBdCyaLuJzEKM2nIwo2U=" + }, + { + "mvn-path": "slingshot/slingshot/0.12.2/slingshot-0.12.2.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-porCK/LqPNVM4023D9aYRNYx71SfZFDCeMMOb3nfY/M=" + }, + { + "mvn-path": "slingshot/slingshot/0.12.2/slingshot-0.12.2.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-SrxOK5ppxzvTc+gy0/AOWQZ4Q/+DUe/V7rsfOCTbnFE=" + } + ] +} diff --git a/deps.edn b/deps.edn new file mode 100644 index 0000000..fbfdb6a --- /dev/null +++ b/deps.edn @@ -0,0 +1,8 @@ +{ + :paths ["src"] + :deps { + org.clojure/clojure { :mvn/version "1.11.1" } + org.clojure/data.json { :mvn/version "2.4.0" } + clj-http/clj-http { :mvn/version "3.12.3" } + } + } diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..6c33276 --- /dev/null +++ b/flake.lock @@ -0,0 +1,212 @@ +{ + "nodes": { + "clj-nix": { + "inputs": { + "devshell": "devshell", + "flake-utils": "flake-utils", + "nixpkgs": [ + "helpers", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1677342613, + "narHash": "sha256-BqhKj7jQahSVThEwLHt164kJHGx9LXzBARFZaFNLPW8=", + "owner": "jlesquembre", + "repo": "clj-nix", + "rev": "7d9e244ea96988524ba3bd6c2bbafdf0a5340b96", + "type": "github" + }, + "original": { + "owner": "jlesquembre", + "repo": "clj-nix", + "type": "github" + } + }, + "clj2nix": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": "nixpkgs", + "utils": "utils" + }, + "locked": { + "lastModified": 1673786922, + "narHash": "sha256-MrwSNEXpq20/AvMxW49MRbuqf8C2M4Vei3jtZeXYjJk=", + "owner": "hlolli", + "repo": "clj2nix", + "rev": "04b0dfbfc69c6316b8613d061e3fe4619d79cd9f", + "type": "github" + }, + "original": { + "owner": "hlolli", + "repo": "clj2nix", + "type": "github" + } + }, + "devshell": { + "inputs": { + "flake-utils": [ + "helpers", + "clj-nix", + "flake-utils" + ], + "nixpkgs": [ + "helpers", + "clj-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1658746384, + "narHash": "sha256-CCJcoMOcXyZFrV1ag4XMTpAPjLWb4Anbv+ktXFI1ry0=", + "owner": "numtide", + "repo": "devshell", + "rev": "0ffc7937bb5e8141af03d462b468bd071eb18e1b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1668681692, + "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "009399224d5e398d03b22badca40a37ac85412a1", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1656928814, + "narHash": "sha256-RIFfgBuKz6Hp89yRr7+NR5tzIAbn52h8vT6vXkYjZoM=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "7e2a3b3dfd9af950a856d66b0a7d01e3c18aa249", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "helpers": { + "inputs": { + "clj-nix": "clj-nix", + "clj2nix": "clj2nix", + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils_2" + }, + "locked": { + "lastModified": 1677792046, + "narHash": "sha256-GU7czTodGN+6ijrz5MuREJMyfPo9aDsXRjaZA+nl+ys=", + "ref": "refs/heads/master", + "rev": "d54fa928c37e7f260c2b99bc733634347e83d9fd", + "revCount": 32, + "type": "git", + "url": "https://git.fudo.org/fudo-public/nix-helpers.git" + }, + "original": { + "type": "git", + "url": "https://git.fudo.org/fudo-public/nix-helpers.git" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1673785507, + "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1678761643, + "narHash": "sha256-tapXZvg6Kg5Fm7Fm6i+7cRC5Exp2lX7cgMrqsfrGhuc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c4aec3c021620d98861639946123214207e98344", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-22.11", + "type": "indirect" + } + }, + "root": { + "inputs": { + "helpers": "helpers", + "nixpkgs": "nixpkgs_2", + "utils": "utils_3" + } + }, + "utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "utils_2": { + "locked": { + "lastModified": 1676283394, + "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "utils_3": { + "locked": { + "lastModified": 1676283394, + "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a68afc8 --- /dev/null +++ b/flake.nix @@ -0,0 +1,36 @@ +{ + description = "Objectifier Client"; + + inputs = { + nixpkgs.url = "nixpkgs/nixos-22.11"; + helpers = { + url = "git+https://git.fudo.org/fudo-public/nix-helpers.git"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, helpers, utils, ... }: + utils.lib.eachDefaultSystem (system: { + packages = rec { + default = objectifier-client; + objectifier-client = helpers.packages."${system}".mkClojureBin { + name = "org.fudo/objectifier-client"; + primary-namespace = "objectifier-client.cli"; + src = ./.; + }; + }; + + devShells = let pkgs = import nixpkgs { inherit system; }; + in rec { + default = update-deps; + objectifier-client = pkgs.mkShell { + buildInputs = [ self.packages."${system}".objectifier-client ]; + }; + update-deps = pkgs.mkShell { + buildInputs = with helpers.packages."${system}"; + [ updateClojureDeps ]; + }; + }; + }); +} diff --git a/src/objectifier_client/cli.clj b/src/objectifier_client/cli.clj new file mode 100644 index 0000000..add0f60 --- /dev/null +++ b/src/objectifier_client/cli.clj @@ -0,0 +1,61 @@ +(ns objectifier-client.cli + (:require [objectifier-client.core :as obj] + [clojure.java.io :as io] + [clojure.tools.cli :as cli] + [clojure.string :as str])) + +(defn- read-file-bytes [filename] + (with-open [in (java.io.FileInputStream. filename) + out (java.io.ByteArrayOutputStream.)] + (io/copy in out) + (.toByteArray out))) + +(def cli-opts + [["-s" "--server SERVER" "Hostname of the Objectifier server."] + ["-p" "--port PORT" "Port on which the Objectifier server is listening." + :default 80 + :parse-fn #(Integer/parseInt %)] + ["-l" "--labels" "Only print detected labels."] + ["-h" "--help" "Print this message."] + ["-v" "--verbose" "Provide verbose output."]]) + +(defn- msg-quit [status msg] + (println msg) + (System/exit status)) + +(defn- usage + ([summary] (usage summary [])) + ([summary errors] (->> (concat errors + ["usage: objectifier-client [opts] " + "" + "Options:" + summary]) + (str/join \newline)))) + +(defn- display-probabilities [client filename] + (let [probabilities (obj/get-probabilities! client (read-file-bytes filename))] + (println (str filename ":")) + (doseq [[lbl prob] probabilities] + (println (format " %s - %.2f" + (name lbl) + prob))))) + +(defn- display-labels [client filenames] + (distinct + (mapcat (fn [filename] + (obj/get-labels! client (read-file-bytes filename))) + filenames))) + +(defn -main [& args] + (let [{:keys [options arguments summary errors]}] + (when (seq errors) + (msg-quit 1 (usage summary errors))) + (when (:help options) + (msg-quit 0 (usage summary))) + (when (empty? (arguments)) + (msg-quit 0 (usage summary ["No files provided to scan."]))) + (let [client (obj/define-connection "http" (:server options) (:port options))] + (if (:labels options) + (display-labels client arguments) + (doseq [file arguments] + (display-probabilities client file)))))) diff --git a/src/objectifier_client/core.clj b/src/objectifier_client/core.clj new file mode 100644 index 0000000..f101a8c --- /dev/null +++ b/src/objectifier_client/core.clj @@ -0,0 +1,60 @@ +(ns objectifier-client.core + (:require [clj-http.client :as client] + [clojure.data.json :as json] + [slingshot.slingshot :refer [throw+]]) + (:import java.net.URL + java.io.ByteArrayInputStream)) + +(defprotocol IObjectifierClient + (get! [_ image-data]) + (get-labels! [_ image-data]) + (get-detections! [_ image-data]) + (get-highlights! [_ image-data]) + (get-probabilites! [_ image-data])) + +(defn- url->string [url] (.toExternalForm url)) + +(defn- build-url [{:keys [scheme host port]}] + (url->string (URL. scheme host port "/images"))) + +(defn- send-image! [url image-bytes] + (let [input-stream (ByteArrayInputStream. image-bytes)] + (client/post url + {:multipart [{:name "image" + :content input-stream}]}))) + +(defn- process-response [resp] + (if (<= 200 (:status resp) 299) + (-> resp :body (json/read-str :key-fn keyword)) + (throw+ {:type ::http-error + :status (:status resp) + :reason (:reason-phrase resp) + :response resp}))) + +(defrecord ObjectifierClient [scheme host port] + IObjectifierClient + (get! [self image-data] + (process-response (send-image! (build-url self) image-data))) + + (get-labels! [self image-data] + (-> (get! self image-data) + :labels)) + + (get-detections! [self image-data] + (-> (get! self image-data) + :detections)) + + (get-highlights! [self image-data] + (-> (get! self image-data) + :output)) + + (get-probabilites! [self image-data] + (into {} + (map (juxt (comp keyword :label) :confidence)) + (get-detections! self image-data)))) + +(defn define-connection + [{:keys [scheme host port] + :or {scheme "http" + port 80}}] + (->ObjectifierClient scheme host port))