Hey all,

I wrote a clojure version of the simplest functionality of wget. I
basically translated the java version into clojure code, but I'm not
quite happy with the wget-binary function because I use a loop, and I
feel like someone else has a more idiomatic solution to iterating
through a java-array. Also, I don't know if my way of handling the no
filename case is best. Please tell me how to improve my code,
especially in the interop sections.

(ns dj
  (:import [java.io File FileOutputStream BufferedInputStream
BufferedReader InputStreamReader])
  (:import [java.net URL])
  (:require [clojure.contrib [duck-streams :as duck-streams]]))

(defn blank?
  "True if s is nil, empty, or contains only whitespace."
  [#^String s]
  (every? (fn [#^Character c] (Character/isWhitespace c)) s))

(defn- extract-url-filename [url]
  (let [filename (.getFile url)]
    (if (blank? filename)
      "index.html"
      (subs filename 1))))

(defn- wget-binary [con content-length]
  (with-open [stream (BufferedInputStream. (.getInputStream con))]
    (let [data (make-array Byte/TYPE content-length)]
      (loop [offset 0]
        (if (< offset content-length)
          (let [bytesRead (.read stream
                                 data
                                 offset
                                 (- content-length
                                    offset))]
            (if (= bytesRead -1)
              data
              (recur (+ offset bytesRead))))
          data)))))

(defn- wget-text [url-obj]
  (with-open [buf (-> url-obj
                      (.openStream)
                      (InputStreamReader.)
                      (BufferedReader.))]
    (apply str (line-seq buf))))

(defn wget [url-address]
  (let [url (URL. url-address)
        filename (extract-url-filename url)
        con (.openConnection url)
        content-length (.getContentLength con)]
    (if (or (= -1 content-length)
            (.startsWith (.getContentType con) "text/"))
      (duck-streams/spit filename (wget-text url))
      (with-open [out-file (FileOutputStream. filename)]
        (.write out-file (wget-binary con content-length))))))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to