-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0ab0f1b
commit 0d35a9c
Showing
4 changed files
with
370 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
|
||
var database = (function() { | ||
|
||
return function() { | ||
var self = this; | ||
var version = 1; | ||
var request; | ||
var db = undefined; | ||
|
||
self.init = function(success, error) { | ||
request = window.indexedDB.open("hushFiles", version); | ||
|
||
request.onblocked = function(e) { | ||
if(error) error(); | ||
} | ||
|
||
request.onupgradeneeded = function(e) { | ||
var db = request.result; | ||
db.createObjectStore("chunks", {keyPath: "filename"}) | ||
} | ||
|
||
request.onsuccess = function(e){ | ||
db = request.result; | ||
if(success) success(); | ||
} | ||
|
||
request.onerror = function(e) { | ||
if(error) error(); | ||
} | ||
} | ||
|
||
self.saveChunk = function(filename, chunknumber, contents, success, error) { | ||
var trans = db.transaction(["chunks"], "readwrite"); | ||
var store = trans.objectStore("chunks"); | ||
var request = store.put({ | ||
"filename": filename + chunknumber, | ||
"chunknumber": chunknumber, | ||
"contents": contents | ||
}); | ||
|
||
request.onsuccess = function(e) { | ||
if(success) success(e); | ||
} | ||
|
||
request.onerror = function(e) { | ||
console.log(e); | ||
error; | ||
} | ||
} | ||
|
||
self.append = function(fileHandle, contents, success, error) { | ||
lockedFile = fileHandle.open('readwrite'); | ||
console.log("Appending"); | ||
request = lockedFile.append(contents); | ||
|
||
request.onsuccess = function(e) { | ||
console.log("Appended" + contents); | ||
lockedFile.flush(); | ||
if(success) success(); | ||
} | ||
|
||
request.onerror = function(e) { | ||
console.log("verdamt!"); | ||
if(error) error(e); | ||
} | ||
} | ||
|
||
self.readChunk = function(filename, chunknumber, success, errror) { | ||
var store = db.transaction(["chunks"], "readwrite").objectStore("chunks"); | ||
var request = store.get(filename + chunknumber); | ||
|
||
request.onsuccess = function(e) { | ||
var data = request.result; | ||
|
||
if(success) success(data); | ||
} | ||
|
||
request.onerror = function(e) { | ||
if(error) error(e); | ||
} | ||
} | ||
|
||
|
||
// Returns a file to the concatenated file | ||
self.getFile = function(filename, chunks, success, error) { | ||
console.log("Getting entire file"); | ||
console.log(db.mozCreateFileHandle); | ||
var fileRequest = db.mozCreateFileHandle(filename,'text/plain','trololo.txt'); | ||
|
||
var readAndAppend = function(fh, chunknumber) { | ||
self.readChunk(filename, chunknumber, function(data) { | ||
console.log("Chunk read, now appending"); | ||
var fileReader = new FileReader(); | ||
|
||
fileReader.onload = function(e) { | ||
self.append(fh, fileReader.result, function(){ | ||
|
||
if(++chunknumber < chunks) { | ||
console.log("Appended and continuing"); | ||
|
||
readAndAppend(fh, chunknumber); | ||
} else { | ||
request = fh.getFile(); | ||
|
||
request.onsuccess = function(e) { | ||
if(success) success(request.result); | ||
} | ||
|
||
request.onerror = function(e) { | ||
if(error) error(e); | ||
} | ||
} | ||
}, | ||
function(e){ | ||
if(error) error(e); | ||
}); | ||
} | ||
fileReader.readAsArrayBuffer(data.contents); | ||
}, | ||
function(e) { | ||
if(error) error(e); | ||
}); | ||
} | ||
|
||
fileRequest.onsuccess = function(e) { | ||
readAndAppend(fileRequest.result, 0); | ||
} | ||
|
||
fileRequest.onerror = function(e) { | ||
if(error) error(e); | ||
} | ||
} | ||
} | ||
|
||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
var state; | ||
|
||
function range(start, end, step) { | ||
step = step || 1; | ||
r = []; | ||
for(var i = start; i < end; i+=step) { | ||
r.push(i); | ||
} | ||
return r; | ||
} | ||
|
||
onmessage = function(event) { | ||
var message = event.data; | ||
|
||
switch(message.type) { | ||
case 'init': | ||
state = { | ||
'queue': range(0, message.chunks), | ||
'processing': [] | ||
}; | ||
postMessage({ | ||
'type': 'init', | ||
}); | ||
break; | ||
|
||
case 'status': | ||
postMessage({ | ||
'type': 'status', | ||
'status': state, | ||
}); | ||
break; | ||
|
||
case 'next': | ||
next = state['queue'].shift(); | ||
state['processing'].push(next); | ||
postMessage({ | ||
'type': 'next', | ||
'next': next, | ||
}); | ||
break; | ||
|
||
case 'success': | ||
state['processing'] = state['processing'].filter(function(idx) { | ||
return idx != message.index; | ||
}); | ||
if(!state['processing'].length) postMessage({ | ||
'type': 'success', | ||
}); | ||
break; | ||
|
||
case 'enqueue': | ||
state['queue'].push(message.index).sort(); | ||
break; | ||
|
||
default: | ||
postMessage({ | ||
'type': 'error', | ||
'error': new Error('Not implemented in worker: ' + message.type); | ||
}); | ||
break; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
function getApiFile(fileid, chunknumber, progress, success, error) { | ||
var xhr = new XMLHttpRequest(); | ||
|
||
xhr.onload = function(e) { | ||
if(this.status == 200) { | ||
if(success) success(xmr.response); | ||
} else { | ||
if(error) error(e); | ||
} | ||
} | ||
|
||
var url = '/api/file?fileid='+fileid+'&chunknumber='+chunknumber | ||
xhr.open('GET', url); | ||
xhr.responseType = "json"; | ||
xmr.send() | ||
} | ||
|
||
onmessage = function(event) { | ||
var message = event.data; | ||
|
||
switch(message.type) { | ||
case 'init': | ||
getApiFile(message.id, message.index, function(e) { | ||
postMessage({ | ||
'type': 'progress', | ||
'id': message.id, | ||
'index': message.index, | ||
'event': e, | ||
}); | ||
}, function()) | ||
break; | ||
|
||
|
||
default: | ||
var e = new Error('Illegal message type: ' + message.type); | ||
postMessage({ | ||
'type': 'error', | ||
'error': e, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
(function(root, factory) { | ||
if(typeof define === 'function' && define.amd){ | ||
define(['chunkedfile'], factory); | ||
} else if(typeof exports === 'object') { | ||
module.exports = factory(require('chunkedfile.js')); | ||
} else { | ||
root.downloaddispatcher = factory(root.chunkedfile); | ||
} | ||
}(this, function(ChunkedFile) { | ||
|
||
function FileInfo(config) { | ||
var self = this; | ||
|
||
self.id = config.id; | ||
self.chunks = config.chunks; | ||
self.cipher = config.cipher; | ||
|
||
} | ||
|
||
function FileInfo.prototype.fromId(id, success, error) { | ||
|
||
} | ||
|
||
function FileMetadata(config) { | ||
var self = this; | ||
self.id = config.id; | ||
self.name = config.name || 'hushfile.txt'; | ||
self.type = config.type || 'text/plain'; | ||
} | ||
|
||
function Metadata.prototype.fromId(id, success, error) { | ||
|
||
} | ||
|
||
function getApiFile(fileid, chunknumber, progress, success, error) { | ||
var xhr = new XMLHttpRequest(); | ||
xhr.open('GET', '/api/file?fileid='+fileid+'&chunknumber='+chunknumber); | ||
xhr.addEventListener("progress", progress, false); | ||
xhr.onload = function(e) { | ||
if(this.status == 200) { | ||
// decrypt the data | ||
if(success) success(xmr.responseText); | ||
} else { | ||
if(error) error(e); | ||
} | ||
} | ||
xhr.send() | ||
} | ||
|
||
// config: { | ||
// 'chunks': [urls], | ||
// 'metadata': object, | ||
// 'paralel': number, | ||
// 'type': string, | ||
// 'onchunkprogress': function(json), | ||
// 'onchunkerror': function(json), | ||
// 'onchunkwrite': function(json, cb), | ||
// } | ||
function DownloadDispatcher(config) { | ||
var self = this; | ||
|
||
self.info = config.info; | ||
self.metadata = config.metadata; | ||
|
||
self.onprogress = config.onprogress; | ||
self.onerror = config.onerror; | ||
self.onloadend = config.onloadend; | ||
|
||
self.onchunkprogress = config.onpchunkrogress; | ||
self.onchunkerror = config.onchunkerror; | ||
self.onchunkwrite = config.onchunkwrite; | ||
|
||
self.download = function(id, success, error) { | ||
var chunkedFile = new ChunkedFile(config.filename, | ||
{type: config.type}); | ||
var scheduler = new Worker('schedule-worker.js'); | ||
scheduler.onmessage = function(e) { | ||
var message = e.data; | ||
var state = [] | ||
switch(message.type) { | ||
case 'next': | ||
getApiFile(message.id, | ||
message.next, | ||
function(e) { | ||
state[e.id] = e.event; | ||
|
||
if(self.onchunkprogress) { | ||
self.onchunkprogress(event, state); | ||
} | ||
}, | ||
function(event) { | ||
if(self.onchunkwrite) { | ||
self.onchunkwrite(event, function(chunk) { | ||
chunkedFile.addChunk( | ||
self.onchunkwrite(event), | ||
function() { | ||
scheduler.postMessage({ | ||
'type': 'next' | ||
}); | ||
}, onchunkerror); | ||
}); | ||
|
||
} else { | ||
chunkedFile.addChunk(chunk, function() { | ||
scheduler.postMessage({ | ||
'type': 'next' | ||
}); | ||
}, onchunkerror); | ||
} | ||
|
||
}, self.onchunkerror); | ||
|
||
case 'success': | ||
if(success) success(chunkedFile); | ||
break; | ||
|
||
case 'error': | ||
if(error) error(message.error); else throw message.error; | ||
break; | ||
|
||
default: | ||
var e = new Error('Illegel message type: ' + message.type); | ||
if(error) error(e); else throw e; | ||
} | ||
} | ||
scheduler.postMessage({ | ||
'type': 'init', | ||
'chunks': self.info.chunks | ||
}); | ||
} | ||
} | ||
})); |