Skip to content

Commit

Permalink
Fun and games
Browse files Browse the repository at this point in the history
  • Loading branch information
rlindsgaard committed Feb 14, 2015
1 parent 0ab0f1b commit 0d35a9c
Show file tree
Hide file tree
Showing 4 changed files with 370 additions and 0 deletions.
135 changes: 135 additions & 0 deletions db.js
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);
}
}
}

})();
62 changes: 62 additions & 0 deletions dispatch-worker.js
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;
}
}
41 changes: 41 additions & 0 deletions download-worker.js
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,
});
}
}
132 changes: 132 additions & 0 deletions downloaddispatcher.js
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
});
}
}
}));

0 comments on commit 0d35a9c

Please sign in to comment.