Skip to content

Commit

Permalink
MicrobeTrace can now import and export zipped versions of its session…
Browse files Browse the repository at this point in the history
… files
  • Loading branch information
AABoyles committed Nov 21, 2018
1 parent 32e71cb commit 637a8d7
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 50 deletions.
28 changes: 18 additions & 10 deletions components/files.html
Original file line number Diff line number Diff line change
Expand Up @@ -203,21 +203,29 @@ <h5 id="alignerControlsModalTitle" class="modal-title">Load Settings</h5>
});

function addFileToTable(file){
session.files.push(file);
var extension = file.name.split('.').pop().toLowerCase();
if(extension === 'microbetrace'){
if(extension === 'zip'){
var new_zip = new JSZip();
new_zip
.loadAsync(file)
.then(function(zip){
zip.forEach(function(relativePath, zipEntry){
extension = zipEntry.name.split('.').pop();
zipEntry.async("string").then(function(c){
app.processJSON(c, extension);
});
});
});
return;
}
if(extension === 'microbetrace' || extension === 'hivtrace'){
var reader = new FileReader();
reader.onloadend = function(out){
session = JSON.parse(out.target.result);
session.meta.startTime = Date.now();
session.style.nodeSymbolMap = function(){ return session.style.nodeSymbols[0]; };
session.style.nodeColorMap = function(){ return session.style.nodeColors[ 0]; };
session.style.linkColorMap = function(){ return session.style.linkColors[ 0]; };
app.finishUp(true);
app.processJSON(out.target.result, extension);
};
reader.readAsText(file);
return;
reader.readAsText(file, 'UTF-8');
}
session.files.push(file);
var isFasta = (extension === 'fasta');
var isXL = (extension === 'xlsx' || extension === 'xls');
var isNode = file.name.toLowerCase().includes('node');
Expand Down
72 changes: 39 additions & 33 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,14 @@ <h5 class="modal-title">Save</h5>
</select>
</div>
</div>
<div class="form-group row">
<div class="col">
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="save-file-compress" checked />
<label class="form-check-label" for="save-file-compress">Compress?</label>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-error" data-dismiss="modal">Cancel</button>
Expand Down Expand Up @@ -413,6 +421,7 @@ <h5 class="modal-title" id="exitModalLabel">Leave MicrobeTrace Session?</h5>
<script src="node_modules/d3-sankey/build/d3-sankey.min.js"></script>
<script src="node_modules/marked/marked.min.js"></script>
<script src="vendor/FileSaver.min.js"></script>
<script src="node_modules/jszip/dist/jszip.min.js"></script>
<script src="vendor/shpwrite.js"></script>
<script src="scripts/common.js"></script>
<script>
Expand Down Expand Up @@ -504,47 +513,44 @@ <h5 class="modal-title" id="exitModalLabel">Leave MicrobeTrace Session?</h5>
} else {
data = JSON.stringify(session);
}
var blob = new Blob([data], {type: 'application/json;charset=utf-8'});
saveAs(blob, name + '.' + format);
if($('#save-file-compress').is(':checked')){
var zip = new JSZip();
zip.file(name + '.' + format, data);
zip.generateAsync({
type:"blob",
compression: "DEFLATE",
compressionOptions: {
level: 9
}}).then(function(content) {
saveAs(content, name + '.zip');
});
} else {
var blob = new Blob([data], {type: 'application/json;charset=utf-8'});
saveAs(blob, name + '.' + format);
}
});

$('#OpenTab').on('change', function(e){
if(e.target.files.length > 0){
var startTime = Date.now();
var parts = e.target.files[0].name.split('.');
var extension = parts[parts.length - 1].toLowerCase();
var reader = new FileReader();
if(extension === 'microbetrace'){
reader.onloadend = function(out){
try {
session = JSON.parse(out.target.result);
} catch(error) {
alertify.error('File Not Recognized! Are you certain this is a MicrobeTrace Session or HIV-TRACE Output File?');
console.error(error);
return;
}
session.startTime = startTime;
session.style.widgets = Object.assign({}, app.defaultWidgets, session.style.widgets);
$('#node-color-variable').change();
$('#link-color-variable').change();
app.finishUp(true);
};
var extension = e.target.files[0].name.split('.').pop().toLowerCase();
if(extension === 'zip'){
var new_zip = new JSZip();
new_zip.loadAsync(e.target.files[0])
.then(function(zip) {
zip.forEach(function(relativePath, zipEntry){
extension = zipEntry.name.split('.').pop();
zipEntry.async("string").then(function(c){
app.processJSON(c, extension);
});
});
});
} else {
var reader = new FileReader();
reader.onloadend = function(out){
session = app.sessionSkeleton();
session.startTime = startTime;
try {
content = JSON.parse(out.target.result);
} catch(error) {
alertify.error('File Not Recognized! Are you certain this is a MicrobeTrace Session or HIV-TRACE Output File?');
console.error(error);
return;
}
app.parseHIVTrace(content);
app.finishUp();
app.processJSON(out.target.result, extension);
};
reader.readAsText(e.target.files[0], 'UTF-8');
}
reader.readAsText(e.target.files[0], 'UTF-8');
}
});

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"golden-layout": "^1.5.9",
"html2canvas": "^1.0.0-alpha.12",
"jquery": "^3.3.1",
"jszip": "^3.1.5",
"leaflet": "^1.3.3",
"marked": "^0.5.1",
"moment": "^2.22.2",
Expand Down
62 changes: 61 additions & 1 deletion scripts/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,25 @@ app.addLink = function(newLink, check){
return 1;
};

app.parseHIVTrace = function(hivtrace){
app.processJSON = function(json, extension){
var data;
try {
data = JSON.parse(json);
} catch(error) {
alertify.error('File Not Recognized! Are you certain this is a MicrobeTrace Session or HIV-TRACE Output File?');
console.error(error);
return;
}
if(extension === 'microbetrace'){
app.applySession(data);
} else {
app.applyHIVTrace(data);
}
};

app.applyHIVTrace = function(hivtrace){
session = app.sessionSkeleton();
session.meta.startTime = Date.now();
hivtrace['trace_results']['Nodes'].forEach(function(node){
var newNode = JSON.parse(JSON.stringify(node.patient_attributes));
newNode.id = node.id;
Expand All @@ -206,6 +224,7 @@ app.parseHIVTrace = function(hivtrace){
'visible': true
}, false);
}
app.finishUp();
};

app.parseFASTA = function(text){
Expand Down Expand Up @@ -590,6 +609,7 @@ app.createLinkColorMap = function(){

app.applyStyle = function(style){
session.style = style;
session.style.widgets = Object.assign({}, app.defaultWidgets, session.style.widgets);
app.createLinkColorMap();
app.createNodeColorMap();
for(var id in session.style.widgets){
Expand All @@ -604,6 +624,14 @@ app.applyStyle = function(style){
}
};

app.applySession = function(data, startTime){
session = data;
if(!startTime) startTime = Date.now();
session.meta.startTime = startTime;
app.applyStyle(session.style);
app.finishUp(true);
};

app.reset = function(){
$('#network-statistics-hide, #color-table-hide').parent().trigger('click');
window.session = app.sessionSkeleton();
Expand Down Expand Up @@ -845,6 +873,38 @@ app.getHelp = function(filename, callback){
});
};

app.ab2str = function(buf){
return String.fromCharCode.apply(null, new Uint8Array(buf));
};

app.str2ab = function(str){
var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
var bufView = new Uint8Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
};

app.encrypt = async (plainText, password) => {
const ptUtf8 = new TextEncoder().encode(plainText);
const pwUtf8 = new TextEncoder().encode(password);
const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8);
const iv = crypto.getRandomValues(new Uint8Array(12));
const alg = { name: 'AES-GCM', iv: iv };
const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['encrypt']);
return { iv, encBuffer: await crypto.subtle.encrypt(alg, key, ptUtf8) };
};

app.decrypt = async (ctBuffer, iv, password) => {
const pwUtf8 = new TextEncoder().encode(password);
const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8);
const alg = { name: 'AES-GCM', iv: iv };
const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['decrypt']);
const ptBuffer = await crypto.subtle.decrypt(alg, key, ctBuffer);
return new TextDecoder().decode(ptBuffer);
};

app.exportHIVTRACE = function(){
var links = session.data.links.filter(function(l){ return l.visible });
var geneticLinks = links.filter(function(l){ return l.origin.includes('Genetic Distance'); });
Expand Down
3 changes: 2 additions & 1 deletion sw.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var CACHE = 'MicrobeTraceD2018-11-20';
var CACHE = 'MicrobeTraceD2018-11-21';

self.addEventListener('install', function(event) {
event.waitUntil(
Expand Down Expand Up @@ -56,6 +56,7 @@ self.addEventListener('install', function(event) {
'node_modules/alignment-viewer/dist/alignment-viewer.min.js',
'node_modules/d3-sankey/build/d3-sankey.min.js',
'node_modules/marked/marked.min.js',
'node_modules/jszip/dist/jszip.min.js',
'node_modules/bioseq/dist/bioseq.min.js',
'vendor/bootstrap-filestyle.min.js',
'vendor/d3.v3.min.js',
Expand Down
60 changes: 55 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,11 @@ cookie@0.3.1:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=

core-js@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65"
integrity sha1-+rg/uwstjchfpjbEudNMdUIMbWU=

core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
Expand Down Expand Up @@ -1314,6 +1319,11 @@ es6-promise@^3.0.2:
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613"
integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=

es6-promise@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6"
integrity sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=

es6-symbol@^3.1.1, es6-symbol@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
Expand Down Expand Up @@ -2308,6 +2318,11 @@ ieee754@^1.1.6:
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b"
integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==

immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=

incremental-convex-hull@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/incremental-convex-hull/-/incremental-convex-hull-1.0.1.tgz#51428c14cb9d9a6144bfe69b2851fb377334be1e"
Expand Down Expand Up @@ -2460,6 +2475,17 @@ jsesc@~0.5.0:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=

jszip@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37"
integrity sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==
dependencies:
core-js "~2.3.0"
es6-promise "~3.0.2"
lie "~3.1.0"
pako "~1.0.2"
readable-stream "~2.0.6"

kapsule@^1.9.2:
version "1.9.2"
resolved "https://registry.yarnpkg.com/kapsule/-/kapsule-1.9.2.tgz#424df7b6ace3633cfbc8a8210a2ba6d52e49c055"
Expand Down Expand Up @@ -2512,16 +2538,18 @@ levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"

lie@~3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=
dependencies:
immediate "~3.0.5"

longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=

lz-string@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=

magic-string@^0.22.4:
version "0.22.5"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e"
Expand Down Expand Up @@ -3085,6 +3113,11 @@ pad-left@^1.0.2:
dependencies:
repeat-string "^1.3.0"

pako@~1.0.2:
version "1.0.6"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==

papaparse@^4.4.0:
version "4.6.2"
resolved "https://registry.yarnpkg.com/papaparse/-/papaparse-4.6.2.tgz#5b2df0296f505f1c9d4c2261f903d3b44866a28d"
Expand Down Expand Up @@ -3322,6 +3355,11 @@ printj@~1.1.0, printj@~1.1.2:
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==

process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=

process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
Expand Down Expand Up @@ -3436,6 +3474,18 @@ readable-stream@~1.1.0, readable-stream@~1.1.9:
isarray "0.0.1"
string_decoder "~0.10.x"

readable-stream@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
integrity sha1-j5A0HmilPMySh4jaz80Rs265t44=
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
string_decoder "~0.10.x"
util-deprecate "~1.0.1"

redeyed@~0.4.0:
version "0.4.4"
resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-0.4.4.tgz#37e990a6f2b21b2a11c2e6a48fd4135698cba97f"
Expand Down

0 comments on commit 637a8d7

Please sign in to comment.