Commit 084184dd authored by hh1966's avatar hh1966
Browse files

Add multiple export options and zip file creation to research plan export

parent 270ab676
......@@ -158,7 +158,7 @@ module Chemotion
params do
requires :id, type: Integer, desc: "Research plan id"
requires :html, type: String, desc: "Client side rendered html"
optional :export_format, type: Symbol, desc: "Export format", values: [:html, :docx, :latex]
optional :export_format, type: Symbol, desc: "Export format", values: [:docx, :odt, :html, :markdown, :latex]
end
route_param :id do
before do
......@@ -167,21 +167,26 @@ module Chemotion
post :export do
research_plan = ResearchPlan.find(params[:id])
file_name = "#{research_plan.name}.#{params[:export_format]}"
if params[:export_format]
# make src in html relative
params[:html].gsub! 'src="/images/', 'src="images/'
# return the response "as is"
env['api.format'] = :binary
# convert using pandoc and stream as file
if params[:export_format]
# return a file
content_type "application/octet-stream"
header['Content-Disposition'] = "attachment; filename=\"#{file_name}\""
env['api.format'] = :binary
present PandocRuby.convert(params[:html], :from => :html, :to => params[:export_format], :resource_path => Rails.public_path)
# init the export object
export = Export::ExportResearchPlan.new params[:html], params[:export_format]
if [:html, :markdown, :latex].include? params[:export_format]
header['Content-Disposition'] = "attachment; filename=\"#{research_plan.name}.zip\""
present export.to_zip
else
header['Content-Disposition'] = "attachment; filename=\"#{research_plan.name}.#{params[:export_format]}\""
present export.to_file
end
else
# return plain html
env['api.format'] = :binary
present params[:html]
end
end
......
import React, { Component } from 'react';
import ReactDOM from "react-dom"
import PropTypes from 'prop-types';
import { Panel, ListGroup, ListGroupItem, ButtonToolbar, Button, Tooltip, OverlayTrigger, Row, Col, Tabs, Tab } from 'react-bootstrap';
import { Panel, ListGroup, ListGroupItem, ButtonToolbar, Button, Tooltip, OverlayTrigger, Row, Col, Tabs, Tab, Dropdown, MenuItem } from 'react-bootstrap';
import SVG from 'react-inlinesvg';
import { includes, last, findKey, values } from 'lodash';
import ElementCollectionLabels from '../ElementCollectionLabels';
......@@ -179,7 +179,7 @@ export default class ResearchPlanDetails extends Component {
this.forceUpdate();
}
handleExport() {
handleExport(exportFormat) {
const { research_plan } = this.state;
const bodyElements = ReactDOM.findDOMNode(this.ref.current).getElementsByClassName('field')
......@@ -193,7 +193,7 @@ export default class ResearchPlanDetails extends Component {
}
})
ResearchPlansFetcher.export(research_plan, html, 'docx')
ResearchPlansFetcher.export(research_plan, html, exportFormat)
}
// render functions
......@@ -210,24 +210,46 @@ export default class ResearchPlanDetails extends Component {
)
}
renderPropertiesTab(research_plan) {
const { name, body, attachments } = research_plan
const { update, edit } = this.state
const submitLabel = research_plan.isNew ? "Create" : "Save"
let exportButton
renderExportButton(edit) {
if (!edit) {
exportButton = (
return (
<div className="pull-right">
<Button bsStyle="default" onClick={this.handleExport.bind(this)}>Export</Button>
<Dropdown id="research-plan-export-dropdown">
<Dropdown.Toggle>
Export
</Dropdown.Toggle>
<Dropdown.Menu>
<MenuItem onSelect={() => this.handleExport('docx')}>
as .docx
</MenuItem>
<MenuItem onSelect={() => this.handleExport('odt')}>
as .odt
</MenuItem>
<MenuItem onSelect={() => this.handleExport('html')}>
as HTML
</MenuItem>
<MenuItem onSelect={() => this.handleExport('markdown')}>
as Markdown
</MenuItem>
<MenuItem onSelect={() => this.handleExport('latex')}>
as LaTeX
</MenuItem>
</Dropdown.Menu>
</Dropdown>
</div>
)
}
}
renderPropertiesTab(research_plan) {
const { name, body, attachments } = research_plan
const { update, edit } = this.state
const submitLabel = research_plan.isNew ? "Create" : "Save"
return (
<ListGroup fill="true">
<ListGroupItem >
{exportButton}
{this.renderExportButton()}
<ResearchPlanDetailsName value={name}
disabled={research_plan.isMethodDisabled('name')}
......
require 'tempfile'
module Export
class ExportResearchPlan
def initialize(html, export_format)
# make src in html relative
@html = html
@html.gsub! 'src="/images/', 'src="images/'
@export_format = export_format
end
def to_file
PandocRuby.convert(@html, :from => :html, :to => @export_format, :resource_path => Rails.public_path)
end
def to_zip
Dir.mktmpdir('chemotion') do |tmpdir|
# convert the html string using pandoc and save the images in tmpdir
document = PandocRuby.convert(@html, :from => :html, :to => @export_format, :resource_path => Rails.public_path, :extract_media => tmpdir)
# substitute tmp dir with images in the document
document.gsub! tmpdir, 'images'
# create a zipfile with the document and an image directory
zip = Zip::OutputStream.write_buffer do |zip|
zip.put_next_entry "document.#{@export_format}"
zip.write document
Dir.children(tmpdir).each do |tmpfile|
zip.put_next_entry "images/#{tmpfile}"
zip.write File.read(File.join(tmpdir, tmpfile))
end
end
zip.rewind
zip.read
end
end
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment