Implement parsing for image/jpeg responses
This commit is contained in:
parent
8ceb7bce2a
commit
e5e97e14e0
1 changed files with 29 additions and 13 deletions
|
|
@ -14,8 +14,13 @@
|
||||||
(defn fetch-url [url]
|
(defn fetch-url [url]
|
||||||
(future (html/html-snippet (:body (http/get url)))))
|
(future (html/html-snippet (:body (http/get url)))))
|
||||||
|
|
||||||
|
;; here are some hand-picked webcams:
|
||||||
|
;; colorado springs: https://www.insecam.org/en/view/481423/
|
||||||
|
;; salzburg: https://www.insecam.org/en/view/540433/
|
||||||
|
;; not madrid: https://www.insecam.org/en/view/856408/
|
||||||
|
|
||||||
(def some-detail-page
|
(def some-detail-page
|
||||||
@(fetch-url "https://www.insecam.org/en/view/540433/"))
|
@(fetch-url "https://www.insecam.org/en/view/856408/"))
|
||||||
|
|
||||||
(def some-camera-image
|
(def some-camera-image
|
||||||
(->
|
(->
|
||||||
|
|
@ -36,12 +41,7 @@
|
||||||
;; we're only interested in the first chunk of data, so we need to figure out
|
;; we're only interested in the first chunk of data, so we need to figure out
|
||||||
;; how we can close the connection afterwards and discard the other ones.
|
;; how we can close the connection afterwards and discard the other ones.
|
||||||
|
|
||||||
;; TODO: To read the image the following is done
|
;; Our approach is this:
|
||||||
;; - Find the first boundary
|
|
||||||
;; - Load all following bytes into a buffer until the buffer appears the next time
|
|
||||||
;; - Return the buffer
|
|
||||||
|
|
||||||
;; NOTE A more elegant method might be this:
|
|
||||||
;; - Convert the stream into a lazy sequence of bytes
|
;; - Convert the stream into a lazy sequence of bytes
|
||||||
;; - Partition the lazy sequence whenever you find (str "--" boundary)
|
;; - Partition the lazy sequence whenever you find (str "--" boundary)
|
||||||
;; - Select the part of the sequence you want
|
;; - Select the part of the sequence you want
|
||||||
|
|
@ -83,12 +83,9 @@
|
||||||
{:header (apply str (map char (first parsed)))
|
{:header (apply str (map char (first parsed)))
|
||||||
:body (byte-array (apply concat (rest parsed)))}))
|
:body (byte-array (apply concat (rest parsed)))}))
|
||||||
|
|
||||||
(defn parse-multipart [request]
|
(defn parse-mixed-replace [request]
|
||||||
(let [content-type (get-in request [:headers "Content-Type"])
|
(let [content-type (get-in request [:headers "Content-Type"])
|
||||||
boundary (str "--" (second (re-find #"boundary=\"(.*?)\"" content-type)) "\r\n")]
|
boundary (str "--" (second (re-find #"boundary=(?:\")?(.*?)(?:\")?(;|$)" content-type)) "\r\n")]
|
||||||
;; let's throw in an assert because we have no idea how other servers
|
|
||||||
;; implement streaming or wether they implement it at all
|
|
||||||
(assert (some? boundary) "Could not parse multipart/x-mixed-replace boundary")
|
|
||||||
(with-open [input (:body request)]
|
(with-open [input (:body request)]
|
||||||
;; find indices of the bytes between the first and second boundary; the byte
|
;; find indices of the bytes between the first and second boundary; the byte
|
||||||
;; sequence always starts with the boundary, which is why can skip the first
|
;; sequence always starts with the boundary, which is why can skip the first
|
||||||
|
|
@ -99,7 +96,26 @@
|
||||||
;; first (empty) split
|
;; first (empty) split
|
||||||
(parse-multipart-alternative (second (partition-with-seq boundary-seq byte-seq)))))))
|
(parse-multipart-alternative (second (partition-with-seq boundary-seq byte-seq)))))))
|
||||||
|
|
||||||
(def first-multipart-chunk (parse-multipart (http/get some-camera-image {:as :stream})))
|
(defn parse-image [request]
|
||||||
|
(with-open [input (:body request)]
|
||||||
|
(byte-array (input->byte-seq input))))
|
||||||
|
|
||||||
|
(defmulti parse-response-body (fn [req]
|
||||||
|
(second (re-find #"^(.*?)(;|$)" (get-in req [:headers "Content-Type"])))))
|
||||||
|
|
||||||
|
(defmethod parse-response-body "multipart/x-mixed-replace" [req]
|
||||||
|
(:body (parse-mixed-replace req)))
|
||||||
|
|
||||||
|
(defmethod parse-response-body "image/jpeg" [req]
|
||||||
|
(parse-image req))
|
||||||
|
|
||||||
|
#_(ns-unmap *ns* 'parse-response-body)
|
||||||
|
|
||||||
|
(defmethod parse-response-body :default [req]
|
||||||
|
(throw (IllegalArgumentException.
|
||||||
|
(str "No parser defined for content-type " (pr-str (get-in req [:headers "Content-Type"]))))))
|
||||||
|
|
||||||
|
(def webcam-picture (parse-response-body (http/get some-camera-image {:as :stream})))
|
||||||
|
|
||||||
;; we need javax to convert the byte array that is contained in the body of the
|
;; we need javax to convert the byte array that is contained in the body of the
|
||||||
;; first multipart alternative to a `BufferedImage` that we can use
|
;; first multipart alternative to a `BufferedImage` that we can use
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue