diff --git a/examples/README.md b/examples/README.md index 4b55b68a..9eb0c0d1 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,5 +1,37 @@ # Examples +- [Examples](#examples) + - [Delete a list of files returned by a Unix command](#delete-a-list-of-files-returned-by-a-unix-command) + - [Calculate aggregate size of directory](#calculate-aggregate-size-of-directory) + - [Shuffle the lines of a file](#shuffle-the-lines-of-a-file) + - [Fetch latest Github release tag](#fetch-latest-github-release-tag) + - [Generate deps.edn entry for a gitlib](#generate-depsedn-entry-for-a-gitlib) + - [View download statistics from Clojars](#view-download-statistics-from-clojars) + - [Portable tree command](#portable-tree-command) + - [List outdated maven dependencies](#list-outdated-maven-dependencies) + - [Convert project.clj to deps.edn](#convert-projectclj-to-depsedn) + - [Print current time in California](#print-current-time-in-california) + - [Tiny http server](#tiny-http-server) + - [Print random docstring](#print-random-docstring) + - [Cryptographic hash](#cryptographic-hash) + - [Package script as Docker image](#package-script-as-docker-image) + - [Extract single file from zip](#extract-single-file-from-zip) + - [Note taking app](#note-taking-app) + - [which](#which) + - [pom.xml version](#pomxml-version) + - [Whatsapp frequencies](#whatsapp-frequencies) + - [Find unused vars](#find-unused-vars) + - [List contents of jar file](#list-contents-of-jar-file) + - [Invoke vim inside a script](#invoke-vim-inside-a-script) + - [Portal](#portal) + - [Image viewer](#image-viewer) + - [File server](#file-server) + - [Torrent viewer](#torrent-viewer) + - [cprop.clj](#cpropclj) + - [fzf](#fzf) + - [digitalocean-ping.clj](#digitalocean-pingclj) + - [download-aliases.clj](#download-aliasesclj) + Here's a gallery of useful examples. Do you have a useful example? PR welcome! ## Delete a list of files returned by a Unix command @@ -161,7 +193,9 @@ See [examples/pst.clj](https://github.com/babashka/babashka/blob/master/examples ## Tiny http server -See [examples/http_server.clj](https://github.com/babashka/babashka/blob/master/examples/http_server.clj) +This implements an http server from scratch. Note that babashka comes with `org.httpkit.server` now, so you don't need to build an http server from scratch anymore. + +See [examples/http_server_from_scratch.clj](https://github.com/babashka/babashka/blob/master/examples/http_server_from_scratch.clj) Original by [@souenzzo](https://gist.github.com/souenzzo/a959a4c5b8c0c90df76fe33bb7dfe201) @@ -330,10 +364,22 @@ Opens browser window and lets user navigate through images of all sub-directorie Example usage: ``` shell -$ examples/image_viewer.clj +$ examples/image-viewer.clj ``` -See [image_viewer.clj](image_viewer.clj). +See [image-viewer.clj](image-viewer.clj). + +## File server + +Opens browser window and lets user navigate through filesystem. + +Example usage: + +``` shell +$ examples/file-server.clj +``` + +See [file-server.clj](file-server.clj). ## Torrent viewer @@ -370,18 +416,6 @@ Example usage: $ cat src/babashka/main.clj | bb examples/fzf.clj ``` -## [rofi](rofi.clj) - -Invoke [rofi](https://github.com/davatorium/rofi), a type-to-filter menu on linux, from babashka. - -See [rofi.clj](rofi.clj) - -Example usage: - -``` shell -$ cat src/babashka/main.clj | bb examples/rofi.clj -``` - ## [digitalocean-ping.clj](digitalocean-ping.clj) The script allows to define which DigitalOcean cloud datacenter (region) has best network performance (ping latency). diff --git a/examples/file-server.clj b/examples/file-server.clj new file mode 100755 index 00000000..65284357 --- /dev/null +++ b/examples/file-server.clj @@ -0,0 +1,82 @@ +#!/usr/bin/env bb +#_" -*- mode: clojure; -*-" +;; Source: https://gist.github.com/holyjak/36c6284c047ffb7573e8a34399de27d8 + +;; Based on https://github.com/babashka/babashka/blob/master/examples/image_viewer.clj +(ns file-server + (:require [babashka.fs :as fs] + [clojure.java.browse :as browse] + [clojure.string :as str] + [clojure.tools.cli :refer [parse-opts]] + [hiccup2.core :as html] + [org.httpkit.server :as server]) + (:import [java.net URLDecoder URLEncoder])) + +(def cli-options [["-p" "--port PORT" "Port for HTTP server" :default 8090 :parse-fn #(Integer/parseInt %)] + ["-d" "--dir DIR" "Directory to serve files from" :default "."] + ["-h" "--help" "Print usage info"]]) + +(def parsed-args (parse-opts *command-line-args* cli-options)) +(def opts (:options parsed-args)) + +(cond + (:help opts) + (do (println "Start a http server for static files in the given dir. Usage:\n" (:summary parsed-args)) + (System/exit 0)) + + (:errors parsed-args) + (do (println "Invalid arguments:\n" (str/join "\n" (:errors parsed-args))) + (System/exit 1)) + + :else + :continue) + + +(def port (:port opts)) +(def dir (fs/path (:dir opts))) + +(assert (fs/directory? dir) (str "The given dir `" dir "` is not a directory.")) + +(defn index [f] + (let [files (map #(str (.relativize dir %)) + (fs/list-dir f))] + {:body (-> [:html + [:head + [:meta {:charset "UTF-8"}] + [:title (str "Index of `" f "`")]] + [:body + [:h1 "Index of " [:code (str f)]] + [:ul + (for [child files] + [:li [:a {:href (URLEncoder/encode (str child))} child + (when (fs/directory? (fs/path dir child)) "/")]])] + [:hr] + [:footer {:style {"text-aling" "center"}} "Served by http-server.clj"]]] + html/html + str)})) + +(defn body [path] + {:body (fs/file path)}) + +(server/run-server + (fn [{:keys [:uri]}] + (let [f (fs/path dir (str/replace-first (URLDecoder/decode uri) #"^/" "")) + index-file (fs/path f "index.html")] + (cond + (and (fs/directory? f) (fs/readable? index-file)) + (body index-file) + + (fs/directory? f) + (index f) + + (fs/readable? f) + (body f) + + :else + {:status 404 :body (str "Not found `" f "` in " dir)}))) + {:port port}) + +(println "Starting http server at " port "for" (str dir)) +(browse/browse-url (format "http://localhost:%s/" port)) + +@(promise) diff --git a/examples/http_server.clj b/examples/http_server_from_scratch.clj similarity index 92% rename from examples/http_server.clj rename to examples/http_server_from_scratch.clj index 213f6d5e..0109f59d 100755 --- a/examples/http_server.clj +++ b/examples/http_server_from_scratch.clj @@ -1,10 +1,13 @@ #!/usr/bin/env bb -;; This example creates a file serving web server +;; This example creates a file serving web server from scratch. ;; It accepts a single connection from a browser and serves content to the connected browser ;; after the connection times out, this script will serve no more. ;; Also see notes.clj for another web app example. +;; Note that babashka comes with org.httpkit.server now, so you don't need to +;; build an http server from scratch anymore. We leave this script here for educational purposes. + (import (java.net ServerSocket)) (require '[clojure.java.io :as io] '[clojure.string :as string]) diff --git a/examples/image_viewer.clj b/examples/image-viewer.clj similarity index 100% rename from examples/image_viewer.clj rename to examples/image-viewer.clj diff --git a/examples/notes.clj b/examples/notes.clj index c23769ef..02e15588 100755 --- a/examples/notes.clj +++ b/examples/notes.clj @@ -1,5 +1,10 @@ #!/usr/bin/env bb +;; Note that babashka comes with org.httpkit.server now, so you don't need to +;; build an http server from scratch anymore like we do here. We should update +;; this script to the built-in webserver. Whoever reads this is welcome to +;; submit a PR. + (import (java.net ServerSocket)) (require '[clojure.java.io :as io] '[clojure.string :as str]) diff --git a/examples/rofi.clj b/examples/rofi.clj deleted file mode 100644 index da7045e6..00000000 --- a/examples/rofi.clj +++ /dev/null @@ -1,12 +0,0 @@ -(require '[babashka.process :as p]) - -(defn rofi [s] - (let [proc (p/process - ["rofi" "-i" "-dmenu" "-mesg" "Select" "-sync" "-p" "*"] - {:in s :err :inherit - :out :string})] - (:out @proc))) - -(rofi (slurp *in*)) - -;; `echo "hi\nthere\nclj" | bb examples/rofi.clj`