aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amatus.name>2015-07-19 21:21:32 -0500
committerDavid Barksdale <amatus@amatus.name>2015-07-19 21:21:32 -0500
commitff57ecf6ce5da72878eeed5838f715c1d6c283e6 (patch)
tree4b7d534de7f538170e967e8effdbff7eda902445 /src
parent2cbcdad6fca0556305b7bc046f034586f4de1d95 (diff)
Use IndexedDB to store downloaded files
We probably should delete them at some point 0_0
Diffstat (limited to 'src')
-rw-r--r--src/cljs/amatus/filestorage.cljs92
-rw-r--r--src/hl/index.cljs.hl45
2 files changed, 112 insertions, 25 deletions
diff --git a/src/cljs/amatus/filestorage.cljs b/src/cljs/amatus/filestorage.cljs
new file mode 100644
index 0000000..7a1d2e4
--- /dev/null
+++ b/src/cljs/amatus/filestorage.cljs
@@ -0,0 +1,92 @@
+;; filestorage.cljs - functions for organizing data
+;; Copyright (C) 2015 David Barksdale <amatus@amatus.name>
+;;
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+(ns amatus.filestorage
+ (:require [cljs.core.async :refer [chan close!]])
+ (:require-macros [cljs.core.async.macros :refer [go]]))
+
+(def db (atom nil))
+(let [request (js/indexedDB.open "filestorage" 1)]
+ (set! (.-onupgradeneeded request)
+ (fn [e]
+ (.createObjectStore (.-result (.-target e)) "files"
+ (js-obj "autoIncrement" true))))
+ (set! (.-onerror request)
+ (fn [e] (js/console.error "Error creating downloads database" e)))
+ (set! (.-onsuccess request)
+ (fn [e] (reset! db (.-result (.-target e))))))
+
+(defn create
+ [type]
+ (let [transaction (.transaction @db (array "files") "readwrite")
+ store (.objectStore transaction "files")
+ blob (js/Blob. (array) (js-obj "type" type))
+ request (.add store blob)
+ ch (chan 1)]
+ (set! (.-onerror request)
+ (fn [e]
+ (js/console.error "add request failed" e)
+ (close! ch)))
+ (set! (.-onsuccess request)
+ (fn [e]
+ (go (>! ch (.-result (.-target e)))
+ (close! ch))))
+ ch))
+
+(defn delete
+ [handle]
+ (let [transaction (.transaction @db (array "files") "readwrite")
+ store (.objectStore transaction "files")
+ request (.delete store handle)]
+ (set! (.-onerror request)
+ (fn [e] (js/console.error "delete request failed" e)))))
+
+(defn write
+ [handle offset data]
+ (let [transaction (.transaction @db (array "files") "readwrite")
+ store (.objectStore transaction "files")
+ request (.get store handle)]
+ (set! (.-onerror request)
+ (fn [e] (js/console.error "get request failed" e)))
+ (set! (.-onsuccess request)
+ (fn [e]
+ (let [blob (.-result (.-target e))
+ type (.-type blob)
+ header (.slice blob 0 offset)
+ trailer (.slice blob (+ offset (.-length data)))
+ fill (max 0 (- offset (.-size header)))
+ new-blob (js/Blob. (array header
+ (js/Uint8Array. fill)
+ data
+ trailer)
+ (js-obj "type" type))
+ request (.put store new-blob handle)]
+ (set! (.-onerror request)
+ (fn [e] (js/console.error "put request failed" e))))))))
+
+(defn create-object-url
+ [handle]
+ (let [transaction (.transaction @db (array "files") "readwrite")
+ store (.objectStore transaction "files")
+ request (.get store handle)
+ ch (chan 1)]
+ (set! (.-onerror request)
+ (fn [e] (js/console.error "get request failed" e)))
+ (set! (.-onsuccess request)
+ (fn [e]
+ (go (>! ch (js/URL.createObjectURL (.-result (.-target e))))
+ (close! ch))))
+ ch))
diff --git a/src/hl/index.cljs.hl b/src/hl/index.cljs.hl
index ad7bda6..a315c12 100644
--- a/src/hl/index.cljs.hl
+++ b/src/hl/index.cljs.hl
@@ -15,7 +15,8 @@
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
(page "index.html"
- (:require [gnunet-web.core :as core]
+ (:require [amatus.filestorage :as file]
+ [gnunet-web.core :as core]
[gnunet-web.extractor :as extractor]
[gnunet-web.filesharing :as filesharing]
[gnunet-web.hostlist :as hostlist]
@@ -92,30 +93,24 @@
(defn start-download
[uri anonymity state-cell progress-cell object-cell]
(let [download (filesharing/start-download uri anonymity)
- buffer (js/Uint8Array. (:size download))]
- (go-loop
- []
- (when-let [info (<! (:ch download))]
- (when (= :download-start (:status info))
- (reset! state-cell :downloading))
- (when (= :download-completed (:status info))
- (reset! object-cell
- ;; XXX this needs to be revoked when we're finished
- (.createObjectURL
- js/URL
- (js/Blob. (array buffer)
- (js-obj "type" "application/octet-stream"))))
- (reset! state-cell :complete))
- (when (zero? (:depth info))
- (let [offset (:offset info)
- dst (.subarray buffer
- offset
- (+ offset (.-length (:data info))))]
- (.set dst (:data info))))
- (reset! progress-cell (if (zero? (:size info))
- 0
- (/ (:completed info) (:size info))))
- (recur)))))
+ file-ch (file/create "application/octet-stream")]
+ (go
+ (let [file-handle (<! file-ch)]
+ (loop []
+ (when-let [info (<! (:ch download))]
+ (when (= :download-start (:status info))
+ (reset! state-cell :downloading))
+ (when (= :download-completed (:status info))
+ (let [object (<! (file/create-object-url file-handle))]
+ ;; XXX this needs to be revoked when we're finished
+ (reset! object-cell object)
+ (reset! state-cell :complete)))
+ (when (zero? (:depth info))
+ (file/write file-handle (:offset info) (:data info)))
+ (reset! progress-cell (if (zero? (:size info))
+ 0
+ (/ (:completed info) (:size info))))
+ (recur)))))))
(defn start-publish
[keywords metadata file anonymity state-cell progress-cell uri-cell]