diff options
author | David Barksdale <amatus@amatus.name> | 2015-07-19 21:21:32 -0500 |
---|---|---|
committer | David Barksdale <amatus@amatus.name> | 2015-07-19 21:21:32 -0500 |
commit | ff57ecf6ce5da72878eeed5838f715c1d6c283e6 (patch) | |
tree | 4b7d534de7f538170e967e8effdbff7eda902445 /src | |
parent | 2cbcdad6fca0556305b7bc046f034586f4de1d95 (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.cljs | 92 | ||||
-rw-r--r-- | src/hl/index.cljs.hl | 45 |
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] |