mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-25 01:03:18 +08:00
Implemented protocol export through Zip::OutputStream [SCI-742]
This commit is contained in:
parent
1abd7fc574
commit
14a6705b55
5 changed files with 221 additions and 660 deletions
|
@ -1,5 +1,4 @@
|
|||
//= require protocols/import_export/import
|
||||
//= require protocols/import_export/export
|
||||
//= require comments
|
||||
//= require datatables
|
||||
|
||||
|
@ -17,7 +16,6 @@ function init() {
|
|||
initLoadFromRepository();
|
||||
initRefreshStatusBar();
|
||||
initImport();
|
||||
initExport();
|
||||
Comments.bindNewElement();
|
||||
Comments.initialize();
|
||||
initTutorial();
|
||||
|
@ -510,11 +508,4 @@ function initImport() {
|
|||
});
|
||||
}
|
||||
|
||||
function initExport() {
|
||||
var exportBtn = $("[data-action='export']");
|
||||
exportBtn.on("click", function() {
|
||||
exportProtocols([ $(this).attr("data-id") ]);
|
||||
});
|
||||
}
|
||||
|
||||
init();
|
||||
|
|
|
@ -1,372 +0,0 @@
|
|||
//= require jszip.min.js
|
||||
|
||||
function exportProtocols(protocol_ids) {
|
||||
/*********************************************/
|
||||
/* INNER FUNCTIONS */
|
||||
/*********************************************/
|
||||
|
||||
// Custom StringBuilder 'object'
|
||||
function StringBuilder() {
|
||||
this.tokens = [];
|
||||
|
||||
this.add = function(token) {
|
||||
this.tokens.push(token);
|
||||
return this;
|
||||
};
|
||||
|
||||
this.nl = function() {
|
||||
this.tokens.push('\n');
|
||||
return this;
|
||||
};
|
||||
|
||||
this.build = function() {
|
||||
var str = this.tokens.join("");
|
||||
this.tokens = null;
|
||||
return str;
|
||||
};
|
||||
}
|
||||
|
||||
function getGuid(id) {
|
||||
var str1 = "00000000-0000-";
|
||||
var str2 = id.toString();
|
||||
for (var i = str2.length; i < 19; i++) {
|
||||
str2 = "0" + str2;
|
||||
}
|
||||
str2 = "4" + str2;
|
||||
var str2n = str2.slice(0, 4) + "-" + str2.slice(4, 8) + "-" + str2.slice(8);
|
||||
return str1 + str2n;
|
||||
}
|
||||
|
||||
// Escape null in String
|
||||
function esn(val) {
|
||||
if (val === null) {
|
||||
return "";
|
||||
} else {
|
||||
return String(val);
|
||||
}
|
||||
}
|
||||
|
||||
function extractFileExtension(fileName) {
|
||||
var tokens = fileName.split(".");
|
||||
if (tokens.length <= 1) {
|
||||
return "";
|
||||
} else {
|
||||
return "." + tokens[tokens.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
function generateEnvelopeXsd() {
|
||||
var sb = new StringBuilder();
|
||||
sb.add('<?xml version="1.0" encoding="UTF-8"?>').nl();
|
||||
sb.add('<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">').nl();
|
||||
sb.add('<xs:element name="envelope">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:sequence>').nl();
|
||||
sb.add('<xs:element name="protocol" maxOccurs="unbounded">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:simpleContent>').nl();
|
||||
sb.add('<xs:extension base="xs:string">').nl();
|
||||
sb.add('<xs:attribute name="id" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="guid" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:extension>').nl();
|
||||
sb.add('</xs:simpleContent>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:sequence>').nl();
|
||||
sb.add('<xs:attribute name="xmlns" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="version" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:schema>');
|
||||
return sb.build();
|
||||
}
|
||||
|
||||
function generateElnXsd() {
|
||||
var sb = new StringBuilder();
|
||||
sb.add('<?xml version="1.0" encoding="UTF-8"?>').nl();
|
||||
sb.add('<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">').nl();
|
||||
sb.add('<xs:element name="eln">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:all>').nl();
|
||||
sb.add('<xs:element name="protocol">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:all>').nl();
|
||||
sb.add('<xs:element name="name" type="xs:string"></xs:element>').nl();
|
||||
sb.add('<xs:element name="authors" type="xs:string" minOccurs="0"></xs:element>').nl();
|
||||
sb.add('<xs:element name="description" type="xs:string" minOccurs="0"></xs:element>').nl();
|
||||
sb.add('<xs:element name="created_at" type="xs:string"></xs:element>').nl();
|
||||
sb.add('<xs:element name="updated_at" type="xs:string"></xs:element>').nl();
|
||||
sb.add('<xs:element name="steps" minOccurs="0">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:sequence>').nl();
|
||||
sb.add('<xs:element name="step" maxOccurs="unbounded">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:all>').nl();
|
||||
sb.add('<xs:element name="name" type="xs:string"></xs:element>').nl();
|
||||
sb.add('<xs:element name="description" type="xs:string" minOccurs="0"></xs:element>').nl();
|
||||
sb.add('<xs:element name="checklists" minOccurs="0">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:sequence>').nl();
|
||||
sb.add('<xs:element name="checklist" maxOccurs="unbounded">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:all>').nl();
|
||||
sb.add('<xs:element name="name" type="xs:string"></xs:element>').nl();
|
||||
sb.add('<xs:element name="items" minOccurs="0">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:sequence>').nl();
|
||||
sb.add('<xs:element name="item" maxOccurs="unbounded">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:all>').nl();
|
||||
sb.add('<xs:element name="text" type="xs:string"></xs:element>').nl();
|
||||
sb.add('</xs:all>').nl();
|
||||
sb.add('<xs:attribute name="id" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="guid" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="position" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:sequence>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:all>').nl();
|
||||
sb.add('<xs:attribute name="id" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="guid" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:sequence>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('<xs:element name="assets" minOccurs="0">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:sequence>').nl();
|
||||
sb.add('<xs:element name="asset" maxOccurs="unbounded">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:all>').nl();
|
||||
sb.add('<xs:element name="fileName" type="xs:string"></xs:element>').nl();
|
||||
sb.add('<xs:element name="fileType" type="xs:string"></xs:element>').nl();
|
||||
sb.add('</xs:all>').nl();
|
||||
sb.add('<xs:attribute name="id" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="guid" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="fileRef" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:sequence>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('<xs:element name="elnTables" minOccurs="0">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:sequence>').nl();
|
||||
sb.add('<xs:element name="elnTable" maxOccurs="unbounded">').nl();
|
||||
sb.add('<xs:complexType>').nl();
|
||||
sb.add('<xs:all>').nl();
|
||||
sb.add('<xs:element name="contents" type="xs:string"></xs:element>').nl();
|
||||
sb.add('</xs:all>').nl();
|
||||
sb.add('<xs:attribute name="id" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="guid" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:sequence>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:all>').nl();
|
||||
sb.add('<xs:attribute name="id" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="guid" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="position" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:sequence>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:all>').nl();
|
||||
sb.add('<xs:attribute name="id" type="xs:int" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="guid" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:all>').nl();
|
||||
sb.add('<xs:attribute name="xmlns" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('<xs:attribute name="version" type="xs:string" use="required"></xs:attribute>').nl();
|
||||
sb.add('</xs:complexType>').nl();
|
||||
sb.add('</xs:element>').nl();
|
||||
sb.add('</xs:schema>');
|
||||
return sb.build();
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* ACTUAL FUNCTION CODE */
|
||||
/*********************************************/
|
||||
|
||||
if (protocol_ids.length > 0) {
|
||||
animateSpinner();
|
||||
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/protocols/export",
|
||||
dataType: "json",
|
||||
data: { protocol_ids: protocol_ids},
|
||||
success: function (data) {
|
||||
var zip = new JSZip();
|
||||
|
||||
// Envelope code
|
||||
var esb = new StringBuilder();
|
||||
esb.add('<envelope xmlns="http://www.scinote.net" version="1.0">').nl();
|
||||
|
||||
_.each(data.protocols, function(protocol) {
|
||||
var protocolGuid = getGuid(protocol.id);
|
||||
|
||||
// Create folder for this protocol
|
||||
var protocolFolder = zip.folder(protocolGuid);
|
||||
|
||||
var protocolXml = [];
|
||||
var psb = new StringBuilder();
|
||||
|
||||
// Header
|
||||
psb.add('<eln xmlns="http://www.scinote.net" version="1.0">').nl();
|
||||
|
||||
// Protocol
|
||||
psb.add('<protocol id="' + protocol.id + '" guid="' + protocolGuid + '">').nl();
|
||||
psb.add('<name>' + esn(protocol.name) + '</name>').nl();
|
||||
psb.add('<authors>' + esn(protocol.authors) + '</authors>').nl();
|
||||
psb.add('<description>' + esn(protocol.description) + '</description>').nl();
|
||||
psb.add('<created_at>' + esn(protocol.created_at) + '</created_at>').nl();
|
||||
psb.add('<updated_at>' + esn(protocol.updated_at) + '</updated_at>').nl();
|
||||
|
||||
// Steps
|
||||
if (protocol.steps.length > 0) {
|
||||
psb.add('<steps>').nl();
|
||||
_.each(protocol.steps, function(step) {
|
||||
var stepGuid = getGuid(step.id);
|
||||
|
||||
var ssb = new StringBuilder();
|
||||
|
||||
ssb.add('<step id="' + step.id + '" guid="' + stepGuid + '" position="' + step.position + '">').nl();
|
||||
ssb.add('<name>' + esn(step.name) + '</name>').nl();
|
||||
ssb.add('<description>' + esn(step.description) + '</description>').nl();
|
||||
|
||||
// Assets
|
||||
if (step.assets.length > 0) {
|
||||
ssb.add('<assets>').nl();
|
||||
_.each(step.assets, function(asset) {
|
||||
var assetGuid = getGuid(asset.id);
|
||||
|
||||
// Generate the asset file inside ZIP
|
||||
var assetFileName = assetGuid + extractFileExtension(asset.fileName);
|
||||
var decodedData = window.atob(asset.bytes);
|
||||
zip.folder(protocolGuid).folder(stepGuid).file(assetFileName, decodedData, { binary: true });
|
||||
|
||||
var asb = new StringBuilder();
|
||||
|
||||
asb.add('<asset id="' + asset.id + '" guid="' + assetGuid + '" fileRef="' + assetFileName + '">').nl();
|
||||
asb.add('<fileName>' + esn(asset.fileName) + '</fileName>').nl();
|
||||
asb.add('<fileType>' + esn(asset.fileType) + '</fileType>').nl();
|
||||
asb.add('</asset>').nl();
|
||||
|
||||
ssb.add(asb.build());
|
||||
});
|
||||
ssb.add('</assets>').nl();
|
||||
}
|
||||
|
||||
// Tables
|
||||
if (step.tables.length > 0) {
|
||||
ssb.add('<elnTables>').nl();
|
||||
_.each(step.tables, function(table) {
|
||||
var tsb = new StringBuilder();
|
||||
|
||||
tsb.add('<elnTable id="' + table.id + '" guid="' + getGuid(table.id) + '">').nl();
|
||||
tsb.add('<name>' + esn(table.name) + '</name>').nl();
|
||||
tsb.add('<contents>' + esn(table.contents) + '</contents>').nl();
|
||||
tsb.add('</elnTable>');
|
||||
|
||||
ssb.add(tsb.build()).nl();
|
||||
});
|
||||
ssb.add('</elnTables>').nl();
|
||||
}
|
||||
|
||||
// Checklists
|
||||
if (step.checklists.length > 0) {
|
||||
ssb.add('<checklists>').nl();
|
||||
_.each(step.checklists, function(checklist) {
|
||||
var csb = new StringBuilder();
|
||||
|
||||
csb.add('<checklist id="' + checklist.id + '" guid="' + getGuid(checklist.id) + '">').nl();
|
||||
csb.add('<name>' + esn(checklist.name) + '</name>').nl();
|
||||
|
||||
if (checklist.items.length > 0) {
|
||||
csb.add('<items>').nl();
|
||||
_.each(checklist.items, function(item) {
|
||||
var isb = new StringBuilder();
|
||||
|
||||
isb.add('<item id="' + item.id + '" guid="' + getGuid(item.id) + '" position="' + item.position + '">').nl();
|
||||
isb.add('<text>' + esn(item.text) + '</text>').nl();
|
||||
isb.add('</item>');
|
||||
|
||||
csb.add(isb.build()).nl();
|
||||
});
|
||||
csb.add('</items>').nl();
|
||||
}
|
||||
csb.add('</checklist>');
|
||||
|
||||
ssb.add(csb.build()).nl();
|
||||
});
|
||||
ssb.add('</checklists>').nl();
|
||||
}
|
||||
|
||||
psb.add(ssb.build());
|
||||
psb.add('</step>').nl();
|
||||
});
|
||||
psb.add('</steps>').nl();
|
||||
}
|
||||
|
||||
psb.add('</protocol>').nl();
|
||||
psb.add('</eln>');
|
||||
|
||||
// Okay, we have a generated XML for
|
||||
// individual protocol, save it to protocol folder
|
||||
protocolFolder.file("eln.xml", psb.build());
|
||||
|
||||
// Add protocol to the envelope
|
||||
esb.add('<protocol id="' + protocol.id + '" guid="' + protocolGuid + '">' + esn(protocol.name) + '</protocol>').nl();
|
||||
});
|
||||
esb.add('</envelope>').nl();
|
||||
|
||||
// Save envelope to root directory in ZIP
|
||||
zip.file("scinote.xml", esb.build());
|
||||
|
||||
// Add the XSD schemes into the ZIP
|
||||
zip.file("scinote.xsd", generateEnvelopeXsd());
|
||||
zip.file("eln.xsd", generateElnXsd());
|
||||
|
||||
// NOW, DOWNLOAD THE ZIP
|
||||
var blob = zip.generate({ type: "blob" });
|
||||
|
||||
var fileName = "protocol.eln";
|
||||
if (data.protocols.length === 1) {
|
||||
// Try to construct an OS-safe file name
|
||||
if (data.protocols[0].name.length && data.protocols[0].name.length > 0) {
|
||||
var escapedName = data.protocols[0].name.replace(/[^0-9a-zA-Z-.,_]/gi, '_').toLowerCase().substring(0, 250);
|
||||
if (escapedName.length > 0) {
|
||||
fileName = escapedName + ".eln";
|
||||
}
|
||||
}
|
||||
} else if (data.protocols.length > 1) {
|
||||
fileName = "protocols.eln";
|
||||
}
|
||||
|
||||
var link = document.createElement("a");
|
||||
if (link.download !== undefined) {
|
||||
// Browsers that support HTML5 download attribute
|
||||
link.setAttribute("href", window.URL.createObjectURL(blob));
|
||||
link.setAttribute("download", fileName);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
} else {
|
||||
alert("Please use latest version of Chrome, Firefox, or Opera browser for the export!");
|
||||
}
|
||||
|
||||
animateSpinner(null, false);
|
||||
},
|
||||
error: function() {
|
||||
alert("Ajax error!");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -560,38 +560,61 @@ class ProtocolsController < ApplicationController
|
|||
end
|
||||
|
||||
def export
|
||||
#respond_to do |format|
|
||||
# format.json {
|
||||
# render json: {
|
||||
# protocols: export_protocols(@protocols)
|
||||
# }, status: :ok
|
||||
# }
|
||||
#end
|
||||
|
||||
# Make a zip output stream and send it to the client
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.zip do
|
||||
Dir.mktmpdir do |tmp_dir|
|
||||
|
||||
|
||||
end
|
||||
|
||||
format.html do
|
||||
z_output_stream = Zip::OutputStream.write_buffer do |ostream|
|
||||
ostream.put_next_entry('eln.xml')
|
||||
ostream.print(protocol_xml)
|
||||
ostream.put_next_entry("#{arch_dir}/scinote.xml")
|
||||
ostream.print(envelope_xml)
|
||||
ostream.put_next_entry("#{arch_dir}/scinote.xsd")
|
||||
ostream.put_next_entry('scinote.xml')
|
||||
ostream.print(generate_envelope_xml(@protocols))
|
||||
ostream.put_next_entry('scinote.xsd')
|
||||
ostream.print(generate_envelope_xsd)
|
||||
ostream.put_next_entry("#{arch_dir}/eln.xsd")
|
||||
ostream.put_next_entry('eln.xsd')
|
||||
ostream.print(generate_eln_xsd)
|
||||
|
||||
# Create folder and xml file for each protocol and populate it
|
||||
@protocols.each do |protocol|
|
||||
protocol_dir = get_guid(protocol.id).to_s
|
||||
ostream.put_next_entry("#{protocol_dir}/eln.xml")
|
||||
ostream.print(generate_protocol_xml(protocol))
|
||||
# Add assets to protocol folder
|
||||
if protocol.steps.count > 0
|
||||
protocol.steps.order(:id).each do |step|
|
||||
step_guid = get_guid(step.id)
|
||||
step_dir = "#{protocol_dir}/#{step_guid}"
|
||||
if step.assets.count > 0
|
||||
step.assets.order(:id).each do |asset|
|
||||
asset_guid = get_guid(asset.id)
|
||||
asset_file_name = asset_guid.to_s +
|
||||
File.extname(asset.file_file_name).to_s
|
||||
ostream.put_next_entry("#{step_dir}/#{asset_file_name}")
|
||||
input_file = asset.open
|
||||
ostream.print(input_file.read)
|
||||
input_file.close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
z_output_stream.rewind
|
||||
send_data compressed_filestream.read, filename: "protocol.eln"
|
||||
end
|
||||
end
|
||||
|
||||
protocol_name = get_protocol_name(@protocols[0])
|
||||
|
||||
# Now generate filename of the archive and send file to user
|
||||
if @protocols.count == 1
|
||||
# Try to construct an OS-safe file name
|
||||
file_name = 'protocol.eln'
|
||||
unless protocol_name.nil?
|
||||
escaped_name = protocol_name.gsub(/[^0-9a-zA-Z-.,_]/i, '_')
|
||||
.downcase[0..250]
|
||||
file_name = escaped_name + '.eln' unless escaped_name.empty?
|
||||
end
|
||||
elsif @protocols.length > 1
|
||||
file_name = 'protocols.eln'
|
||||
end
|
||||
send_data(z_output_stream.read, filename: file_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def unlink_modal
|
||||
|
|
|
@ -1,70 +1,72 @@
|
|||
require 'tmpdir'
|
||||
require 'zip'
|
||||
|
||||
module ProtocolsExporter
|
||||
def export_protocols(protocols)
|
||||
#protocols_json = []
|
||||
#protocols.each do |protocol|
|
||||
# protocols_json << export_protocol(protocol)
|
||||
#end
|
||||
private
|
||||
|
||||
#return protocols_json
|
||||
def get_guid(id)
|
||||
str1 = '00000000-0000-'
|
||||
str2 = id.to_s
|
||||
(19 - str2.size).times do
|
||||
str2 = '0' + str2
|
||||
end
|
||||
str2 = '4' + str2
|
||||
str2n = str2[0..3] + '-' + str2[4..7] + '-' + str2[8..-1]
|
||||
str1 + str2n
|
||||
end
|
||||
|
||||
# create temporary working dir, will be deleted in the end
|
||||
Dir.mktmpdir do |tmp_dir|
|
||||
# create dir for archive
|
||||
arch_dir = "#{tmp_dir}/protocols"
|
||||
Dir.mkdir(arch_dir)
|
||||
# create xml envelope document
|
||||
envelope_xml = "<envelope xmlns=\"http://www.scinote.net\" version=\"1.0\">\n"
|
||||
def get_protocol_name(protocol)
|
||||
## "Inject" module's name
|
||||
if protocol.in_module? && protocol.name.blank?
|
||||
protocol_name = protocol.my_module.name
|
||||
else
|
||||
protocol_name = protocol.name
|
||||
end
|
||||
protocol_name
|
||||
end
|
||||
|
||||
def generate_envelope_xml(protocols)
|
||||
envelope_xml = "<envelope xmlns=\"http://www.scinote.net\" " \
|
||||
"version=\"1.0\">\n"
|
||||
protocols.each do |protocol|
|
||||
protocol_guid = get_guid(protocol.id)
|
||||
# Create a folder for this protocol
|
||||
protocol_dir = "#{arch_dir}/#{protocol_guid}"
|
||||
Dir.mkdir(protocol_dir)
|
||||
# Protocol
|
||||
protocol_name = get_protocol_name(protocol)
|
||||
envelope_xml << "<protocol id=\"#{protocol.id}\" " \
|
||||
"guid=\"#{get_guid(protocol.id)}\">#{protocol_name}" \
|
||||
"</protocol>\n"
|
||||
end
|
||||
envelope_xml << "</envelope>\n"
|
||||
envelope_xml
|
||||
end
|
||||
|
||||
def generate_protocol_xml(protocol)
|
||||
protocol_name = get_protocol_name(protocol)
|
||||
protocol_xml = "<eln xmlns=\"http://www.scinote.net\" version=\"1.0\">\n"
|
||||
protocol_xml << "<protocol id=\"#{protocol.id}\" guid=\"#{protocol_guid}\">\n"
|
||||
protocol_xml << "<name>#{protocol.name}</name>\n"
|
||||
protocol_xml << "<protocol id=\"#{protocol.id}\" " \
|
||||
"guid=\"#{get_guid(protocol.id)}\">\n"
|
||||
protocol_xml << "<name>#{protocol_name}</name>\n"
|
||||
protocol_xml << "<authors>#{protocol.authors}</authors>\n"
|
||||
protocol_xml << "<description>#{protocol.description}</description>\n"
|
||||
protocol_xml << "<created_at>#{protocol.created_at}</created_at>\n"
|
||||
protocol_xml << "<updated_at>#{protocol.updated_at}</updated_at>\n"
|
||||
protocol_xml << "<created_at>#{protocol.created_at.as_json}</created_at>\n"
|
||||
protocol_xml << "<updated_at>#{protocol.updated_at.as_json}</updated_at>\n"
|
||||
|
||||
# Steps
|
||||
if protocol.steps
|
||||
if protocol.steps.count > 0
|
||||
protocol_xml << "<steps>\n"
|
||||
protocol.steps.each do |step|
|
||||
protocol.steps.order(:id).each do |step|
|
||||
step_guid = get_guid(step.id)
|
||||
step_xml = "<step id=\"#{step.id}\" guid=\"#{step_guid}\" position=\"#{step.position}\">\n"
|
||||
step_xml = "<step id=\"#{step.id}\" guid=\"#{step_guid}\" " \
|
||||
"position=\"#{step.position}\">\n"
|
||||
step_xml << "<name>#{step.name}</name>\n"
|
||||
step_xml << "<description>#{step.description}</description>\n"
|
||||
|
||||
# Assets
|
||||
if step.assets
|
||||
p step.id
|
||||
p "assets"
|
||||
step_xml << '<assets>'
|
||||
step.assets.each do |asset|
|
||||
if step.assets.count > 0
|
||||
step_xml << "<assets>\n"
|
||||
step.assets.order(:id).each do |asset|
|
||||
asset_guid = get_guid(asset.id)
|
||||
# create dir in protocol dir for assets
|
||||
step_dir = "#{protocol_dir}/#{step_guid}"
|
||||
p step_dir
|
||||
Dir.mkdir(step_dir)
|
||||
# create file for asset inside step dir
|
||||
asset_file_name = "#{step_dir}/#{asset_guid}#{File.extname(asset.file_file_name)}"
|
||||
output_file = File.open(asset_file_name, 'wb')
|
||||
input_file = asset.open
|
||||
p 'opened'
|
||||
# p input_file
|
||||
# puts `ls -la /tmp`
|
||||
#output_file.write(input_file.read)
|
||||
while buffer = input_file.read(4096)
|
||||
output_file.write(buffer)
|
||||
end
|
||||
input_file.close
|
||||
p output_file.size
|
||||
asset_xml = "<asset id=\"#{asset.id}\" guid=\"#{asset_guid}\" fileRef=\"#{asset_file_name}\">\n"
|
||||
asset_file_name = "#{asset_guid}" \
|
||||
"#{File.extname(asset.file_file_name)}"
|
||||
asset_xml = "<asset id=\"#{asset.id}\" guid=\"#{asset_guid}\" " \
|
||||
"fileRef=\"#{asset_file_name}\">\n"
|
||||
asset_xml << "<fileName>#{asset.file_file_name}</fileName>\n"
|
||||
asset_xml << "<fileType>#{asset.file_content_type}</fileType>\n"
|
||||
asset_xml << "</asset>\n"
|
||||
|
@ -74,11 +76,13 @@ module ProtocolsExporter
|
|||
end
|
||||
|
||||
# Tables
|
||||
if step.tables
|
||||
if step.tables.count > 0
|
||||
step_xml << "<elnTables>\n"
|
||||
step.tables.each do |table|
|
||||
table_xml = "<elnTable id=\"#{table.id}\" guid=\"#{get_guid(table.id)}\">\n"
|
||||
table_xml << "<contents>#{table.contents.unpack('H*')[0]}</contents>\n"
|
||||
step.tables.order(:id).each do |table|
|
||||
table_xml = "<elnTable id=\"#{table.id}\" " \
|
||||
"guid=\"#{get_guid(table.id)}\">\n"
|
||||
table_xml << "<contents>#{table.contents.unpack('H*')[0]}" \
|
||||
"</contents>\n"
|
||||
table_xml << "</elnTable>\n"
|
||||
step_xml << table_xml
|
||||
end
|
||||
|
@ -86,15 +90,18 @@ module ProtocolsExporter
|
|||
end
|
||||
|
||||
# Checklists
|
||||
if step.checklists
|
||||
if step.checklists.count > 0
|
||||
step_xml << "<checklists>\n"
|
||||
step.checklists.each do |checklist|
|
||||
checklist_xml = "<checklist id=\"#{checklist.id}\" guid=\"#{get_guid(checklist.id)}\">\n"
|
||||
step.checklists.order(:id).each do |checklist|
|
||||
checklist_xml = "<checklist id=\"#{checklist.id}\" " \
|
||||
"guid=\"#{get_guid(checklist.id)}\">\n"
|
||||
checklist_xml << "<name>#{checklist.name}</name>\n"
|
||||
if checklist.items
|
||||
checklist_xml << "<items>\n"
|
||||
checklist.items.each do |item|
|
||||
item_xml = "<item id=\"#{item.id}\" guid=\"#{get_guid(item.id)}\" position=\"#{item.position}\">\n"
|
||||
item_xml = "<item id=\"#{item.id}\" " \
|
||||
"guid=\"#{get_guid(item.id)}\" " \
|
||||
"position=\"#{item.position}\">\n"
|
||||
item_xml << "<text>#{item.text}</text>\n"
|
||||
item_xml << "</item>\n"
|
||||
checklist_xml << item_xml
|
||||
|
@ -113,56 +120,14 @@ module ProtocolsExporter
|
|||
end
|
||||
protocol_xml << "</protocol>\n"
|
||||
protocol_xml << '</eln>'
|
||||
p protocol_xml
|
||||
# Okay, we have a generated XML for
|
||||
# individual protocol, save it to protocol folder
|
||||
output_file = File.open("#{protocol_dir}/eln.xml", 'w')
|
||||
output_file.write(protocol_xml)
|
||||
output_file.close
|
||||
# Add protocol to the envelope
|
||||
envelope_xml << "<protocol id=\"#{protocol.id}\" guid=\"#{protocol_guid}\">#{protocol.name}</protocol>\n"
|
||||
end
|
||||
envelope_xml << "</envelope>\n"
|
||||
|
||||
# Save envelope to root directory in archive
|
||||
output_file = File.open("#{arch_dir}/scinote.xml", 'w')
|
||||
output_file.write(envelope_xml)
|
||||
output_file.close
|
||||
output_file = File.open("#{arch_dir}/scinote.xsd", 'w')
|
||||
output_file.write(generate_envelope_xsd)
|
||||
output_file.close
|
||||
output_file = File.open("#{arch_dir}/eln.xsd", 'w')
|
||||
output_file.write(generate_eln_xsd)
|
||||
output_file.close
|
||||
puts `ls -la #{arch_dir}`
|
||||
|
||||
# Now make zip output stream and send it to the client
|
||||
zip_name = "#{tmp_dir}/protocol.eln"
|
||||
Zip::File.open(zip_name, Zip::File::CREATE) do |zipfile|
|
||||
zipfile.add("eln.xsd", "#{arch_dir}/eln.xsd")
|
||||
zipfile.add("eln.xsd", "#{arch_dir}/scinote.xml")
|
||||
zipfile.add("eln.xsd", "#{arch_dir}/scinote.xsd")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_guid(id)
|
||||
str1 = '00000000-0000-'
|
||||
str2 = id.to_s
|
||||
(19 - str2.size).times do
|
||||
str2 = '0' + str2
|
||||
end
|
||||
str2 = '4' + str2
|
||||
str2n = str2[0..3] + '-' + str2[4..7] + '-' + str2[8..-1]
|
||||
str1 + str2n
|
||||
protocol_xml
|
||||
end
|
||||
|
||||
def generate_envelope_xsd
|
||||
envelope_xsd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
envelope_xsd << "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n"
|
||||
envelope_xsd << "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"" \
|
||||
" elementFormDefault=\"qualified\" " \
|
||||
"attributeFormDefault=\"unqualified\">\n"
|
||||
envelope_xsd << "<xs:element name=\"envelope\">\n"
|
||||
envelope_xsd << "<xs:complexType>\n"
|
||||
envelope_xsd << "<xs:sequence>\n"
|
||||
|
@ -170,15 +135,19 @@ module ProtocolsExporter
|
|||
envelope_xsd << "<xs:complexType>\n"
|
||||
envelope_xsd << "<xs:simpleContent>\n"
|
||||
envelope_xsd << "<xs:extension base=\"xs:string\">\n"
|
||||
envelope_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
envelope_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
envelope_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
envelope_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
envelope_xsd << "</xs:extension>\n"
|
||||
envelope_xsd << "</xs:simpleContent>\n"
|
||||
envelope_xsd << "</xs:complexType>\n"
|
||||
envelope_xsd << "</xs:element>\n"
|
||||
envelope_xsd << "</xs:sequence>\n"
|
||||
envelope_xsd << "<xs:attribute name=\"xmlns\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
envelope_xsd << "<xs:attribute name=\"version\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
envelope_xsd << "<xs:attribute name=\"xmlns\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
envelope_xsd << "<xs:attribute name=\"version\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
envelope_xsd << "</xs:complexType>\n"
|
||||
envelope_xsd << "</xs:element>\n"
|
||||
envelope_xsd << "</xs:schema>\n"
|
||||
|
@ -187,7 +156,9 @@ module ProtocolsExporter
|
|||
|
||||
def generate_eln_xsd
|
||||
eln_xsd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
eln_xsd << "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n"
|
||||
eln_xsd << "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" " \
|
||||
"elementFormDefault=\"qualified\" " \
|
||||
"attributeFormDefault=\"unqualified\">\n"
|
||||
eln_xsd << "<xs:element name=\"eln\">\n"
|
||||
eln_xsd << "<xs:complexType>\n"
|
||||
eln_xsd << "<xs:all>\n"
|
||||
|
@ -195,10 +166,14 @@ module ProtocolsExporter
|
|||
eln_xsd << "<xs:complexType>\n"
|
||||
eln_xsd << "<xs:all>\n"
|
||||
eln_xsd << "<xs:element name=\"name\" type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"authors\" type=\"xs:string\" minOccurs=\"0\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"description\" type=\"xs:string\" minOccurs=\"0\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"created_at\" type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"updated_at\" type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"authors\" type=\"xs:string\" " \
|
||||
"minOccurs=\"0\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"description\" type=\"xs:string\" " \
|
||||
"minOccurs=\"0\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"created_at\" " \
|
||||
"type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"updated_at\" " \
|
||||
"type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"steps\" minOccurs=\"0\">\n"
|
||||
eln_xsd << "<xs:complexType>\n"
|
||||
eln_xsd << "<xs:sequence>\n"
|
||||
|
@ -206,7 +181,8 @@ module ProtocolsExporter
|
|||
eln_xsd << "<xs:complexType>\n"
|
||||
eln_xsd << "<xs:all>\n"
|
||||
eln_xsd << "<xs:element name=\"name\" type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"description\" type=\"xs:string\" minOccurs=\"0\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"description\" type=\"xs:string\" " \
|
||||
"minOccurs=\"0\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"checklists\" minOccurs=\"0\">\n"
|
||||
eln_xsd << "<xs:complexType>\n"
|
||||
eln_xsd << "<xs:sequence>\n"
|
||||
|
@ -222,17 +198,22 @@ module ProtocolsExporter
|
|||
eln_xsd << "<xs:all>\n"
|
||||
eln_xsd << "<xs:element name=\"text\" type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "</xs:all>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"position\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" use=\"required\">" \
|
||||
"</xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"position\" type=\"xs:int\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:sequence>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:all>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:sequence>\n"
|
||||
|
@ -244,12 +225,17 @@ module ProtocolsExporter
|
|||
eln_xsd << "<xs:element name=\"asset\" maxOccurs=\"unbounded\">\n"
|
||||
eln_xsd << "<xs:complexType>\n"
|
||||
eln_xsd << "<xs:all>\n"
|
||||
eln_xsd << "<xs:element name=\"fileName\" type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"fileType\" type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"fileName\" " \
|
||||
"type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"fileType\" " \
|
||||
"type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "</xs:all>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"fileRef\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"fileRef\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:sequence>\n"
|
||||
|
@ -261,111 +247,44 @@ module ProtocolsExporter
|
|||
eln_xsd << "<xs:element name=\"elnTable\" maxOccurs=\"unbounded\">\n"
|
||||
eln_xsd << "<xs:complexType>\n"
|
||||
eln_xsd << "<xs:all>\n"
|
||||
eln_xsd << "<xs:element name=\"contents\" type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "<xs:element name=\"contents\" " \
|
||||
"type=\"xs:string\"></xs:element>\n"
|
||||
eln_xsd << "</xs:all>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:sequence>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:all>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"position\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"position\" type=\"xs:int\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:sequence>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:all>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"id\" type=\"xs:int\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"guid\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << "</xs:all>\n"
|
||||
eln_xsd << "<xs:attribute name=\"xmlns\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"version\" type=\"xs:string\" use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"xmlns\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "<xs:attribute name=\"version\" type=\"xs:string\" " \
|
||||
"use=\"required\"></xs:attribute>\n"
|
||||
eln_xsd << "</xs:complexType>\n"
|
||||
eln_xsd << "</xs:element>\n"
|
||||
eln_xsd << '</xs:schema>'
|
||||
end
|
||||
|
||||
def export_protocol(protocol)
|
||||
protocol_json = protocol.as_json(only: [
|
||||
:id,
|
||||
:name,
|
||||
:description,
|
||||
:authors,
|
||||
:created_at,
|
||||
:updated_at
|
||||
])
|
||||
|
||||
# "Inject" module's name
|
||||
if protocol.in_module? && protocol.name.blank?
|
||||
protocol_json["name"] = protocol.my_module.name
|
||||
end
|
||||
|
||||
protocol_json["steps"] = []
|
||||
protocol.steps.find_each do |step|
|
||||
step_json = step.as_json(only: [
|
||||
:id,
|
||||
:name,
|
||||
:description,
|
||||
:position
|
||||
])
|
||||
|
||||
step_json["tables"] = []
|
||||
step.tables.find_each do |table|
|
||||
table_json = table.as_json(only: [:id, :name])
|
||||
table_json["contents"] = table.contents.unpack("H*")[0]
|
||||
|
||||
step_json["tables"] << table_json
|
||||
end
|
||||
|
||||
step_json["assets"] = []
|
||||
step.assets.find_each do |asset|
|
||||
asset_json = asset.as_json(only: [
|
||||
:id,
|
||||
:file_file_name,
|
||||
:file_content_type
|
||||
])
|
||||
asset_json["fileName"] = asset_json.delete("file_file_name")
|
||||
asset_json["fileType"] = asset_json.delete("file_content_type")
|
||||
|
||||
# Retrieve file contents
|
||||
file = asset.open
|
||||
asset_json["bytes"] = Base64.encode64(file.read)
|
||||
file.close
|
||||
|
||||
step_json["assets"] << asset_json
|
||||
end
|
||||
|
||||
step_json["checklists"] = []
|
||||
step.checklists.find_each do |checklist|
|
||||
checklist_json = checklist.as_json(only: [
|
||||
:id,
|
||||
:name
|
||||
])
|
||||
|
||||
checklist_json["items"] = []
|
||||
checklist.checklist_items.find_each do |item|
|
||||
item_json = item.as_json(only: [
|
||||
:id,
|
||||
:text,
|
||||
:position
|
||||
])
|
||||
|
||||
checklist_json["items"] << item_json
|
||||
end
|
||||
|
||||
step_json["checklists"] << checklist_json
|
||||
end
|
||||
|
||||
protocol_json["steps"] << step_json
|
||||
end
|
||||
|
||||
return protocol_json
|
||||
eln_xsd << "</xs:schema>\n"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
<% if can_export_protocol_from_module(@my_module) %>
|
||||
<a href="#" class="btn btn-default" data-action="export" data-id="<%= @protocol.id %>"><span class="glyphicon glyphicon-export"></span><span class="hidden-xs-custom"> <%= t("my_modules.protocols.buttons.export") %></span></a>
|
||||
<%= link_to raw("<span class=\"glyphicon glyphicon-export\"></span><span class=\"hidden-xs-custom\"> " + t('my_modules.protocols.buttons.export') + "</span>"), export_protocols_path(protocol_ids: @protocol.id), class: "btn btn-default" %>
|
||||
<% else %>
|
||||
<a href="#" class="btn btn-default disabled"><span class="glyphicon glyphicon-export"></span><span class="hidden-xs-custom"> <%= t("my_modules.protocols.buttons.export") %></span></a>
|
||||
<% end %>
|
||||
|
|
Loading…
Reference in a new issue