Loading public/javascripts/e393.js +11 −4 Original line number Diff line number Diff line Loading @@ -72,10 +72,12 @@ class E393_Port { // update timestamps update_timestamps(ts){ let self = this; this._data.timestamps = []; // line below breaks references to this._data.timestamps variable: //this._data.timestamps = []; // so, as suggested here: // https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript this._data.timestamps.length = 0; $(ts).children().each(function(){ self._data.timestamps.push({ frame: parseInt($(this).attr("frame")), Loading @@ -83,7 +85,6 @@ class E393_Port { ptr: parseInt($(this).attr("ptr")), }); }); } } Loading @@ -94,6 +95,7 @@ class E393 { constructor(options){ let defaults = { ip: "0.0.0.0", master_port: "N/A", systime: "", systimestamp: 0, Loading @@ -119,6 +121,9 @@ class E393 { this._data = $.extend(defaults,{}); this._data.ip = $(options).find("camera").attr("ip"); // bchn is for multi-cams and imgsrv this._data.bchn = $(options).find("camera").attr("bchn"); this._data.master_port = parseInt($(options).find("master_port").text()); this._data.systime = $(options).find("systime").text(); this._data.systimestamp = $(options).find("systimestamp").text(); Loading @@ -143,6 +148,8 @@ class E393 { this._data = $.extend(defaults,options); } this.ip = this._data.ip; this.bchn = this._data.bchn; this.master_port = this._data.master_port; this.systime = this._data.systime; this.systimestamp = this._data.systimestamp; Loading public/javascripts/index.js +217 −48 Original line number Diff line number Diff line Loading @@ -21,13 +21,34 @@ let Cams = []; async function a_init(){ let res; const url_set_master = parse_url(); if (url_set_master) { await a_deep_init(); console.log("Done"); }else{ console.log("Master node is not selected (in url string). Call 'List master'"); } } // url res = await a_parse_url(); async function a_deep_init(){ // reset everything $("#nodelist").empty(); $("#slavenodes").empty(); appData.slaves = []; appData.ips = []; appData.slaves_selected = []; let res; // get ips res = await a_send_command('ifconfig', appData.slaves); parse_cmd_ifconfig_init(res); // detect // identify res = await a_detect_10393s(); parse_detect_10393s(res); Loading @@ -37,7 +58,6 @@ async function a_init(){ // update interface update_ui(); console.log("Done"); } Loading @@ -60,14 +80,14 @@ function update_ui(){ pars[p] = tmp; // this is an exclusion // TODO: fix and remove later }else if (pars[p]===1){ }else if ((pars[p]===1)&&(p==="trig_period")){ pars[p] = tmp; // after init }else{ // not all are "none" if (!Cams[i].ports[j].sensor.every(v => v === "none")){ // comparing init to others if ((pars[p]!==tmp)&&(tmp!==1)){ if ((pars[p]!==tmp)&&(tmp!==1)&&(p!=="trig_period")){ console.log("Warning! "+p+" is not the same across all cameras/ports"); } } Loading @@ -84,9 +104,32 @@ function update_ui(){ $("#set_quality .input-par").val(quality); $("#set_fps .input-par").val(fps); console.log("White balance is "+pars.wb_en); button_switch($('#toggle_awb') , pars.wb_en); button_switch($('#toggle_aexp'), pars.autoexp_on); // onchange $("#set_format .input-par").change(function(){ let fmt = format_str2num($(this).val()); a_set_params({COLOR: fmt}).then(()=>{ console.log("format set"); }); }); $("#set_quality .input-par").change(function(){ a_set_params({QUALITY: $(this).val()}).then(()=>{ console.log("quality set"); }); }); $("#set_fps .input-par").change(function(){ let period = fps_fps2period($(this).val()); a_set_params({TRIG_PERIOD: period}).then(()=>{ console.log("period set"); }); }); } function init(){ Loading Loading @@ -134,16 +177,8 @@ function init(){ update_master_node($(this).html()); rewrite_url(); a_deep_init(); // reset everything $("#nodelist").empty(); $("#slavenodes").empty(); appData.slaves = []; appData.ips = []; appData.slaves_selected = []; // go straight with ifconfig send_command('ifconfig', appData.slaves, parse_cmd_ifconfig_init); }); } Loading Loading @@ -191,8 +226,6 @@ function init(){ //send_command(cmd, appData.slaves_selected,parse_cmd_testing); mtest(); }); Loading @@ -215,6 +248,24 @@ async function a_read_params(){ } async function a_set_params(pars){ let ps = []; for(let p in pars){ let pname = p.toUpperCase(); ps.push(pname+"="+pars[p]+"&*"+pname+"=0xf"); } let pstr = ps.join("&"); let cmd = wget_rq("parsedit.php?immediate&sensor_port=0&"+pstr); //let cmd = wget_rq("diagnostics.php"); let targets = appData.slaves_selected; let result = await a_send_command(cmd,targets); return result; } async function a_detect_10393s(){ let targets = appData.slaves_selected; Loading Loading @@ -339,6 +390,20 @@ function parse_read_params(res){ $("tr."+name+" .slave_state").html("<b style='color:DarkOrange;'>not 10393</b>"); }else{ if ($(x).find("camera").length==1) { // auto assign bchn (for multi cams for imgsrv), at this point as well let bchn = 0; if (Cams.length!=0){ let c = Cams[Cams.length-1]; bchn = c.bchn; for (let i=0;i<c.ports.length;i++){ if (c.ports[i].sensor[0]!="none"){ bchn++; } } } $(x).find("camera").attr("bchn",bchn); $(x).find("camera").attr("ip",get_ipaddr_by_name(name)); Cams.push(new E393(x)); } } Loading Loading @@ -637,25 +702,9 @@ function get_ipaddr_from_ifconfig(str){ } // url related functions function parse_url(){ let parameters=location.href.replace(/\?/ig,"&").split("&"); for (let i=0;i<parameters.length;i++) parameters[i]=parameters[i].split("="); for (let i=1;i<parameters.length;i++) { switch (parameters[i][0]) { case "master": update_master_node(parameters[i][1]); send_command('ifconfig', appData.slaves, parse_cmd_ifconfig_init); break; } } } async function a_parse_url(){ let res; let res = false; let parameters=location.href.replace(/\?/ig,"&").split("&"); for (let i=0;i<parameters.length;i++) parameters[i]=parameters[i].split("="); Loading @@ -663,15 +712,14 @@ async function a_parse_url(){ switch (parameters[i][0]) { case "master": update_master_node(parameters[i][1]); res = true; //send_command('ifconfig', appData.slaves, parse_cmd_ifconfig_init); res = await a_send_command('ifconfig', appData.slaves); //parse_cmd_ifconfig_init(res); break; } } return res; } function rewrite_url(){ Loading @@ -696,9 +744,105 @@ function init_controls(){ $("#rec_button").on("click",function(){ States.recording = !States.recording; rec_button_switch(States.recording); if(States.recording){ let cmd = wget_rq("camogm_interface.php?cmd=start"); }else{ let cmd = wget_rq("camogm_interface.php?cmd=stop"); } let targets = appData.slaves_selected; a_send_command(cmd,targets).then(()=>{ console.log("Recording: "+States.recording); }); }); $("#snap_button").on("click", async function(){ // should we stop for a moment? let res = await a_read_params(); // update tses $(res).find('response').each(function(){ const name = $(this).find('node').text(); let state = $(this).find('state').text(); const x = state_str2xml(this); if ($(x).find("camera").length==1) { const ip = get_ipaddr_by_name(name); for(let i=0;i<Cams.length;i++){ if (Cams[i].ip===ip){ const y = $(x).find("port"); for(let j=0;j<y.length;j++){ console.log("Processing port "+$(y[j]).attr("index")); Cams[i].ports[j].update_timestamps($(y[j]).find("timestamps")); } break; } } } }); // find a common ts?! or download all common?! decide by checkbox? analyze_timestamps(); // call for download for that ts or tses. console.log("Snap done"); }); } function analyze_timestamps(){ let newest; let oldest; let olds = []; let news = []; for(let i=0;i<Cams.length;i++){ for(let j=0;j<Cams[i].ports.length;j++){ let tmp_cam = Cams[i]; let tmp_port = tmp_cam.ports[j]; let tmp_tses = tmp_port.timestamps; olds.push(tmp_tses[0].ts); news.push(tmp_tses[tmp_tses.length-1].ts); } } newest = Math.min(...news); oldest = Math.max(...olds); console.log("Timestamp range: "+oldest+" - "+newest); // let get the newest for now // need pointers let ptrs = []; for(let i=0;i<Cams.length;i++){ for(let j=0;j<Cams[i].ports.length;j++){ let tmp_cam = Cams[i]; let tmp_port = tmp_cam.ports[j]; let tmp_tses = tmp_port.timestamps; ptrs.push({ cam: i, port: j, ptr: tmp_tses.filter(a => a.ts===newest)[0].ptr }); } } return ptrs; } function rec_button_switch(state){ Loading @@ -722,6 +866,15 @@ function init_awb_toggle(){ wb_en = 1; } let cmd = wget_rq("parsedit.php?immediate&sensor_port=0&WB_EN="+wb_en+"&*WB_EN=0xf"); let targets = appData.slaves_selected; console.log("Hoping to set Auto White Balance to "+wb_en); a_send_command(cmd,targets).then(()=>{ console.log("Auto White Balance: "+wb_en); }); button_switch($(this),wb_en); // will it work without port 0? Loading Loading @@ -783,8 +936,18 @@ function button_switch(btn,state){ } // helper functions function get_ipaddr_by_name(name){ for(let i=0;i<appData.slaves.length;i++){ if (name==appData.slaves[i]){ return appData.ips[i]; } } return ""; } // helper functions function fps_period2fps(period){ // the tick is 10ns, so: Loading @@ -792,13 +955,19 @@ function fps_period2fps(period){ } function fps_fps2period(fps){ return (1e8/fps).toFixed(); } function format_str2num(str){ let num; switch(str){ switch(str.toLowerCase()){ case "jp4" : num = 5; break; case "jpeg": num = 0; break; default: num = -1; default: num = 0; } return num; Loading public/javascripts/snapshot.js 0 → 100644 +141 −0 Original line number Diff line number Diff line var zip_filename = "zip.zip"; var filenames = []; var blobs = []; var snapshot_counter = 0; var zip_counter = 0; var blob_counter = 0; function snapshot_download_all(ptrs){ var ts = snapshot_find_latest_ts(ptrs); if (ts){ zip_filename = ts.replace(/\./ig,"_")+".zip"; snapshot_counter = 0; zip_counter = 0; blob_counter = 0; filenames = []; blobs = []; for(var i=0;i<ptrs.length;i++){ var ip = $(ptrs[i]).find('camera').attr('ip'); var bchn = get_base_channel(ip); //console.log(ip+": base channel = "+base_chn); var buf_pointers = $(ptrs[i]).find('ts[ts=\''+ts+'\']'); for(var j=0;j<cams[i].ports.length;j++){ // everything is ordered var port = cams[i].ports[j].port; var pointer = $(buf_pointers[j]).attr('ptr'); var url = "http://"+ip+":"+port+"/"+pointer+"/timestamp_name/bchn"+bchn+"/bimg"; snapshot_download_single(url); } } } } // from snapshot.js function snapshot_download_single(addr){ snapshot_counter++; // get ze blob var http = new XMLHttpRequest(); http.open("GET", addr, true); http.responseType = "blob"; http.onload = function(e){ if (this.status === 200) { // To access the header, had to add // printf("Access-Control-Expose-Headers: Content-Disposition\r\n"); // to imgsrv var filename = this.getResponseHeader("Content-Disposition"); filename = filename_from_content_disposition(filename); // store in case zip cannot zip filenames.push(filename); blobs.push(http.response); blob_counter++; if (blob_counter==snapshot_counter){ zip_blobs(); } } } http.send(); } function zip_blobs(){ zip.createWriter(new zip.BlobWriter("application/zip"), function(writer) { var f = 0; function nextFile(f) { fblob = blobs[f]; writer.add(filenames[f], new zip.BlobReader(fblob), function() { // callback f++; if (f < filenames.length) { nextFile(f); } else close(); }); } function close() { // close the writer writer.close(function(blob) { // save with FileSaver.js pass_to_file_reader(zip_filename,blob); }); } nextFile(f); }, onerror); } function filename_from_content_disposition(str){ var parameters = str.split(";"); for (var i=0;i<parameters.length;i++) parameters[i]=parameters[i].split("="); for (var i=0;i<parameters.length;i++) { if (parameters[i][0].trim()=="filename"){ str = parameters[i][1].replace(/"/ig,""); str = str.trim(); } } return str; } // from here: // https://diegolamonica.info/multiple-files-download-on-single-link-click/ // http://jsfiddle.net/diegolamonica/ssk8z9pa/ // (helped a lot) https://stackoverflow.com/questions/19327749/javascript-blob-filename-without-link function pass_to_file_reader(filename,fileblob){ var url = window.URL.createObjectURL(fileblob); var a = $('<a>') .attr('href', url) .attr('download',filename) // Firefox does not fire click if the link is outside // the DOM .appendTo('body'); a[0].click(); //a.click(); // delay? setTimeout(function(){ a.remove(); },200); } public/stylesheets/style.css +5 −1 Original line number Diff line number Diff line Loading @@ -121,7 +121,11 @@ input[type="checkbox"], input[type="radio"] { width:80%; height:80%; border-radius:50%; background: rgba(150,150,150,1); background: rgba(210,210,210,1); } .snap_inner:hover{ background: rgb(150,150,150,1); } .snap_inner:active{ Loading Loading
public/javascripts/e393.js +11 −4 Original line number Diff line number Diff line Loading @@ -72,10 +72,12 @@ class E393_Port { // update timestamps update_timestamps(ts){ let self = this; this._data.timestamps = []; // line below breaks references to this._data.timestamps variable: //this._data.timestamps = []; // so, as suggested here: // https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript this._data.timestamps.length = 0; $(ts).children().each(function(){ self._data.timestamps.push({ frame: parseInt($(this).attr("frame")), Loading @@ -83,7 +85,6 @@ class E393_Port { ptr: parseInt($(this).attr("ptr")), }); }); } } Loading @@ -94,6 +95,7 @@ class E393 { constructor(options){ let defaults = { ip: "0.0.0.0", master_port: "N/A", systime: "", systimestamp: 0, Loading @@ -119,6 +121,9 @@ class E393 { this._data = $.extend(defaults,{}); this._data.ip = $(options).find("camera").attr("ip"); // bchn is for multi-cams and imgsrv this._data.bchn = $(options).find("camera").attr("bchn"); this._data.master_port = parseInt($(options).find("master_port").text()); this._data.systime = $(options).find("systime").text(); this._data.systimestamp = $(options).find("systimestamp").text(); Loading @@ -143,6 +148,8 @@ class E393 { this._data = $.extend(defaults,options); } this.ip = this._data.ip; this.bchn = this._data.bchn; this.master_port = this._data.master_port; this.systime = this._data.systime; this.systimestamp = this._data.systimestamp; Loading
public/javascripts/index.js +217 −48 Original line number Diff line number Diff line Loading @@ -21,13 +21,34 @@ let Cams = []; async function a_init(){ let res; const url_set_master = parse_url(); if (url_set_master) { await a_deep_init(); console.log("Done"); }else{ console.log("Master node is not selected (in url string). Call 'List master'"); } } // url res = await a_parse_url(); async function a_deep_init(){ // reset everything $("#nodelist").empty(); $("#slavenodes").empty(); appData.slaves = []; appData.ips = []; appData.slaves_selected = []; let res; // get ips res = await a_send_command('ifconfig', appData.slaves); parse_cmd_ifconfig_init(res); // detect // identify res = await a_detect_10393s(); parse_detect_10393s(res); Loading @@ -37,7 +58,6 @@ async function a_init(){ // update interface update_ui(); console.log("Done"); } Loading @@ -60,14 +80,14 @@ function update_ui(){ pars[p] = tmp; // this is an exclusion // TODO: fix and remove later }else if (pars[p]===1){ }else if ((pars[p]===1)&&(p==="trig_period")){ pars[p] = tmp; // after init }else{ // not all are "none" if (!Cams[i].ports[j].sensor.every(v => v === "none")){ // comparing init to others if ((pars[p]!==tmp)&&(tmp!==1)){ if ((pars[p]!==tmp)&&(tmp!==1)&&(p!=="trig_period")){ console.log("Warning! "+p+" is not the same across all cameras/ports"); } } Loading @@ -84,9 +104,32 @@ function update_ui(){ $("#set_quality .input-par").val(quality); $("#set_fps .input-par").val(fps); console.log("White balance is "+pars.wb_en); button_switch($('#toggle_awb') , pars.wb_en); button_switch($('#toggle_aexp'), pars.autoexp_on); // onchange $("#set_format .input-par").change(function(){ let fmt = format_str2num($(this).val()); a_set_params({COLOR: fmt}).then(()=>{ console.log("format set"); }); }); $("#set_quality .input-par").change(function(){ a_set_params({QUALITY: $(this).val()}).then(()=>{ console.log("quality set"); }); }); $("#set_fps .input-par").change(function(){ let period = fps_fps2period($(this).val()); a_set_params({TRIG_PERIOD: period}).then(()=>{ console.log("period set"); }); }); } function init(){ Loading Loading @@ -134,16 +177,8 @@ function init(){ update_master_node($(this).html()); rewrite_url(); a_deep_init(); // reset everything $("#nodelist").empty(); $("#slavenodes").empty(); appData.slaves = []; appData.ips = []; appData.slaves_selected = []; // go straight with ifconfig send_command('ifconfig', appData.slaves, parse_cmd_ifconfig_init); }); } Loading Loading @@ -191,8 +226,6 @@ function init(){ //send_command(cmd, appData.slaves_selected,parse_cmd_testing); mtest(); }); Loading @@ -215,6 +248,24 @@ async function a_read_params(){ } async function a_set_params(pars){ let ps = []; for(let p in pars){ let pname = p.toUpperCase(); ps.push(pname+"="+pars[p]+"&*"+pname+"=0xf"); } let pstr = ps.join("&"); let cmd = wget_rq("parsedit.php?immediate&sensor_port=0&"+pstr); //let cmd = wget_rq("diagnostics.php"); let targets = appData.slaves_selected; let result = await a_send_command(cmd,targets); return result; } async function a_detect_10393s(){ let targets = appData.slaves_selected; Loading Loading @@ -339,6 +390,20 @@ function parse_read_params(res){ $("tr."+name+" .slave_state").html("<b style='color:DarkOrange;'>not 10393</b>"); }else{ if ($(x).find("camera").length==1) { // auto assign bchn (for multi cams for imgsrv), at this point as well let bchn = 0; if (Cams.length!=0){ let c = Cams[Cams.length-1]; bchn = c.bchn; for (let i=0;i<c.ports.length;i++){ if (c.ports[i].sensor[0]!="none"){ bchn++; } } } $(x).find("camera").attr("bchn",bchn); $(x).find("camera").attr("ip",get_ipaddr_by_name(name)); Cams.push(new E393(x)); } } Loading Loading @@ -637,25 +702,9 @@ function get_ipaddr_from_ifconfig(str){ } // url related functions function parse_url(){ let parameters=location.href.replace(/\?/ig,"&").split("&"); for (let i=0;i<parameters.length;i++) parameters[i]=parameters[i].split("="); for (let i=1;i<parameters.length;i++) { switch (parameters[i][0]) { case "master": update_master_node(parameters[i][1]); send_command('ifconfig', appData.slaves, parse_cmd_ifconfig_init); break; } } } async function a_parse_url(){ let res; let res = false; let parameters=location.href.replace(/\?/ig,"&").split("&"); for (let i=0;i<parameters.length;i++) parameters[i]=parameters[i].split("="); Loading @@ -663,15 +712,14 @@ async function a_parse_url(){ switch (parameters[i][0]) { case "master": update_master_node(parameters[i][1]); res = true; //send_command('ifconfig', appData.slaves, parse_cmd_ifconfig_init); res = await a_send_command('ifconfig', appData.slaves); //parse_cmd_ifconfig_init(res); break; } } return res; } function rewrite_url(){ Loading @@ -696,9 +744,105 @@ function init_controls(){ $("#rec_button").on("click",function(){ States.recording = !States.recording; rec_button_switch(States.recording); if(States.recording){ let cmd = wget_rq("camogm_interface.php?cmd=start"); }else{ let cmd = wget_rq("camogm_interface.php?cmd=stop"); } let targets = appData.slaves_selected; a_send_command(cmd,targets).then(()=>{ console.log("Recording: "+States.recording); }); }); $("#snap_button").on("click", async function(){ // should we stop for a moment? let res = await a_read_params(); // update tses $(res).find('response').each(function(){ const name = $(this).find('node').text(); let state = $(this).find('state').text(); const x = state_str2xml(this); if ($(x).find("camera").length==1) { const ip = get_ipaddr_by_name(name); for(let i=0;i<Cams.length;i++){ if (Cams[i].ip===ip){ const y = $(x).find("port"); for(let j=0;j<y.length;j++){ console.log("Processing port "+$(y[j]).attr("index")); Cams[i].ports[j].update_timestamps($(y[j]).find("timestamps")); } break; } } } }); // find a common ts?! or download all common?! decide by checkbox? analyze_timestamps(); // call for download for that ts or tses. console.log("Snap done"); }); } function analyze_timestamps(){ let newest; let oldest; let olds = []; let news = []; for(let i=0;i<Cams.length;i++){ for(let j=0;j<Cams[i].ports.length;j++){ let tmp_cam = Cams[i]; let tmp_port = tmp_cam.ports[j]; let tmp_tses = tmp_port.timestamps; olds.push(tmp_tses[0].ts); news.push(tmp_tses[tmp_tses.length-1].ts); } } newest = Math.min(...news); oldest = Math.max(...olds); console.log("Timestamp range: "+oldest+" - "+newest); // let get the newest for now // need pointers let ptrs = []; for(let i=0;i<Cams.length;i++){ for(let j=0;j<Cams[i].ports.length;j++){ let tmp_cam = Cams[i]; let tmp_port = tmp_cam.ports[j]; let tmp_tses = tmp_port.timestamps; ptrs.push({ cam: i, port: j, ptr: tmp_tses.filter(a => a.ts===newest)[0].ptr }); } } return ptrs; } function rec_button_switch(state){ Loading @@ -722,6 +866,15 @@ function init_awb_toggle(){ wb_en = 1; } let cmd = wget_rq("parsedit.php?immediate&sensor_port=0&WB_EN="+wb_en+"&*WB_EN=0xf"); let targets = appData.slaves_selected; console.log("Hoping to set Auto White Balance to "+wb_en); a_send_command(cmd,targets).then(()=>{ console.log("Auto White Balance: "+wb_en); }); button_switch($(this),wb_en); // will it work without port 0? Loading Loading @@ -783,8 +936,18 @@ function button_switch(btn,state){ } // helper functions function get_ipaddr_by_name(name){ for(let i=0;i<appData.slaves.length;i++){ if (name==appData.slaves[i]){ return appData.ips[i]; } } return ""; } // helper functions function fps_period2fps(period){ // the tick is 10ns, so: Loading @@ -792,13 +955,19 @@ function fps_period2fps(period){ } function fps_fps2period(fps){ return (1e8/fps).toFixed(); } function format_str2num(str){ let num; switch(str){ switch(str.toLowerCase()){ case "jp4" : num = 5; break; case "jpeg": num = 0; break; default: num = -1; default: num = 0; } return num; Loading
public/javascripts/snapshot.js 0 → 100644 +141 −0 Original line number Diff line number Diff line var zip_filename = "zip.zip"; var filenames = []; var blobs = []; var snapshot_counter = 0; var zip_counter = 0; var blob_counter = 0; function snapshot_download_all(ptrs){ var ts = snapshot_find_latest_ts(ptrs); if (ts){ zip_filename = ts.replace(/\./ig,"_")+".zip"; snapshot_counter = 0; zip_counter = 0; blob_counter = 0; filenames = []; blobs = []; for(var i=0;i<ptrs.length;i++){ var ip = $(ptrs[i]).find('camera').attr('ip'); var bchn = get_base_channel(ip); //console.log(ip+": base channel = "+base_chn); var buf_pointers = $(ptrs[i]).find('ts[ts=\''+ts+'\']'); for(var j=0;j<cams[i].ports.length;j++){ // everything is ordered var port = cams[i].ports[j].port; var pointer = $(buf_pointers[j]).attr('ptr'); var url = "http://"+ip+":"+port+"/"+pointer+"/timestamp_name/bchn"+bchn+"/bimg"; snapshot_download_single(url); } } } } // from snapshot.js function snapshot_download_single(addr){ snapshot_counter++; // get ze blob var http = new XMLHttpRequest(); http.open("GET", addr, true); http.responseType = "blob"; http.onload = function(e){ if (this.status === 200) { // To access the header, had to add // printf("Access-Control-Expose-Headers: Content-Disposition\r\n"); // to imgsrv var filename = this.getResponseHeader("Content-Disposition"); filename = filename_from_content_disposition(filename); // store in case zip cannot zip filenames.push(filename); blobs.push(http.response); blob_counter++; if (blob_counter==snapshot_counter){ zip_blobs(); } } } http.send(); } function zip_blobs(){ zip.createWriter(new zip.BlobWriter("application/zip"), function(writer) { var f = 0; function nextFile(f) { fblob = blobs[f]; writer.add(filenames[f], new zip.BlobReader(fblob), function() { // callback f++; if (f < filenames.length) { nextFile(f); } else close(); }); } function close() { // close the writer writer.close(function(blob) { // save with FileSaver.js pass_to_file_reader(zip_filename,blob); }); } nextFile(f); }, onerror); } function filename_from_content_disposition(str){ var parameters = str.split(";"); for (var i=0;i<parameters.length;i++) parameters[i]=parameters[i].split("="); for (var i=0;i<parameters.length;i++) { if (parameters[i][0].trim()=="filename"){ str = parameters[i][1].replace(/"/ig,""); str = str.trim(); } } return str; } // from here: // https://diegolamonica.info/multiple-files-download-on-single-link-click/ // http://jsfiddle.net/diegolamonica/ssk8z9pa/ // (helped a lot) https://stackoverflow.com/questions/19327749/javascript-blob-filename-without-link function pass_to_file_reader(filename,fileblob){ var url = window.URL.createObjectURL(fileblob); var a = $('<a>') .attr('href', url) .attr('download',filename) // Firefox does not fire click if the link is outside // the DOM .appendTo('body'); a[0].click(); //a.click(); // delay? setTimeout(function(){ a.remove(); },200); }
public/stylesheets/style.css +5 −1 Original line number Diff line number Diff line Loading @@ -121,7 +121,11 @@ input[type="checkbox"], input[type="radio"] { width:80%; height:80%; border-radius:50%; background: rgba(150,150,150,1); background: rgba(210,210,210,1); } .snap_inner:hover{ background: rgb(150,150,150,1); } .snap_inner:active{ Loading