odf-converter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .project
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in opendoc-converter.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Daniel Vandersluis
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Opendoc::Converter
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'opendoc-converter'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install opendoc-converter
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ desc "Open an pry session preloaded with this library"
5
+ task :console do
6
+ sh "pry -rubygems -I lib -r odf/converter.rb"
7
+ end
@@ -0,0 +1,3 @@
1
+ require "rubyuno"
2
+ require "odf/converter/version"
3
+ require "odf/converter"
@@ -0,0 +1,108 @@
1
+ require "rubyuno"
2
+ require "odf/converter/version"
3
+ require "odf/converter/families"
4
+ require "odf/converter/filters/base_filter"
5
+ require "odf/converter/filters/import"
6
+ require "odf/converter/filters/export"
7
+ require "odf/converter/hash"
8
+
9
+ module ODF
10
+ PropertyValue = Rubyuno.uno_require "com.sun.star.beans.PropertyValue"
11
+
12
+ class Converter
13
+ class DocumentConversionError < Exception; end
14
+
15
+ attr_reader :ctx, :smgr, :desktop, :document
16
+
17
+ def initialize
18
+ @ctx = Uno::Connector.bootstrap("soffice", "socket", "localhost", 8100)
19
+ @smgr = @ctx.getServiceManager
20
+ @desktop = @smgr.createInstanceWithContext("com.sun.star.frame.Desktop", @ctx)
21
+ end
22
+
23
+ def convert(infile, options = {})
24
+ raise ArgumentError, "to option must be provided." unless options[:to]
25
+
26
+ if options[:to].is_a? Symbol #and Filters::Export[options[:to]]
27
+ outfile = get_output_name(infile, options[:to])
28
+ elsif options[:to].is_a? String
29
+ raise DocumentConversionError, "#{options[:to]} doesn't specify an extension" if File.extname(options[:to]).empty?
30
+ outfile = File.expand_path(options[:to])
31
+ else
32
+ raise DocumentConversionError, "not given a valid destination"
33
+ end
34
+
35
+ perform_conversion(infile, outfile) && outfile
36
+ end
37
+
38
+ def self.convert(*args)
39
+ new.convert(*args)
40
+ end
41
+
42
+ private
43
+ def detect_family(doc)
44
+ return Families::WEB if doc.supportsService("com.sun.star.text.WebDocument")
45
+ return Families::TEXT if doc.supportsService("com.sun.star.text.GenericTextDocument")
46
+ return Families::SPREADSHEET if doc.supportsService("com.sun.star.sheet.SpreadsheetDocument")
47
+ return Families::PRESENTATION if doc.supportsService("com.sun.star.presentation.PresentationDocument")
48
+ return Families::DRAWING if doc.supportsService("com.sun.star.drawing.DrawingDocument")
49
+ raise DocumentConversionError, "unknown document family"
50
+ end
51
+
52
+ def file_url_for(file)
53
+ Rubyuno.system_path_to_file_url File.expand_path(file)
54
+ end
55
+
56
+ def get_output_name(file, ext)
57
+ file = File.expand_path(file)
58
+ File.join(File.dirname(file), File.basename(file, File.extname(file)) + ".#{ext}")
59
+ end
60
+
61
+ def perform_conversion(infile, outfile)
62
+ begin
63
+ load(infile) && store(outfile)
64
+ ensure
65
+ @document.close(true)
66
+ end
67
+ end
68
+
69
+ def load(infile)
70
+ input_url = file_url_for(infile)
71
+ input_ext = File.extname(infile).gsub(/^\./, "")
72
+ props = { Hidden: true }.merge(Filters::Import[input_ext] || {})
73
+
74
+ begin
75
+ @document = desktop.loadComponentFromURL(input_url, "_blank", 0, props.to_uno_properties)
76
+ rescue Rubyuno::Com::Sun::Star::Lang::IllegalArgumentException => e
77
+ raise DocumentConversionError, e.message
78
+ end
79
+
80
+ @document.refresh
81
+ family = detect_family(@document)
82
+
83
+ if family == Families::SPREADSHEET
84
+ page_styles = @document.getStyleFamilies.getByName('PageStyles')
85
+ page_styles.getElementNames.each do |name|
86
+ page_style = pageStyles.getByName(name)
87
+ page_style.setPropertyValue("PageScale", 100)
88
+ page_style.setPropertyValue("PrintGrid", false)
89
+ end
90
+ end
91
+
92
+ true
93
+ end
94
+
95
+ def store(outfile)
96
+ output_url = file_url_for(outfile)
97
+ output_ext = File.extname(outfile).gsub(/^\./, "")
98
+
99
+ family = detect_family(@document)
100
+ props = Filters::Export[output_ext] or raise DocumentConversionError, "unknown output format: #{output_ext}"
101
+ props = props[family] or raise DocumentConversionError, "unsupported conversion: from #{family} to #{output_ext}"
102
+
103
+ @document.storeToURL(output_url, props.to_uno_properties)
104
+
105
+ true
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,11 @@
1
+ module ODF
2
+ class Converter
3
+ module Families
4
+ TEXT = "Text"
5
+ WEB = "Web"
6
+ SPREADSHEET = "Spreadsheet"
7
+ PRESENTATION = "Presentation"
8
+ DRAWING = "Drawing"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module ODF
2
+ class Converter
3
+ module Filters
4
+ module BaseFilter
5
+ def self.included(klass)
6
+ klass.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def [](filter)
11
+ self.const_get(filter.to_s.upcase) rescue nil
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,115 @@
1
+ module ODF
2
+ class Converter
3
+ module Filters
4
+ module Export
5
+ include BaseFilter
6
+
7
+ # see http://wiki.services.openoffice.org/wiki/Framework/Article/Filter
8
+ # most formats are auto-detected; only those requiring options are defined here
9
+ PDF = {
10
+ ODF::Converter::Families::TEXT => {
11
+ FilterName: "writer_pdf_Export"
12
+ },
13
+ ODF::Converter::Families::WEB => {
14
+ FilterName: "writer_web_pdf_Export"
15
+ },
16
+ ODF::Converter::Families::SPREADSHEET => {
17
+ FilterName: "calc_pdf_Export"
18
+ },
19
+ ODF::Converter::Families::PRESENTATION => {
20
+ FilterName: "impress_pdf_Export"
21
+ },
22
+ ODF::Converter::Families::DRAWING => {
23
+ FilterName: "draw_pdf_Export"
24
+ }
25
+ }
26
+
27
+ HTML = {
28
+ ODF::Converter::Families::TEXT => {
29
+ FilterName: "HTML (StarWriter)"
30
+ },
31
+ ODF::Converter::Families::SPREADSHEET => {
32
+ FilterName: "HTML (StarCalc)"
33
+ },
34
+ ODF::Converter::Families::PRESENTATION => {
35
+ FilterName: "impress_html_Export"
36
+ }
37
+ }
38
+
39
+ ODT = {
40
+ ODF::Converter::Families::TEXT => {
41
+ FilterName: "writer8"
42
+ },
43
+ ODF::Converter::Families::WEB => {
44
+ FilterName: "writerweb8_writer"
45
+ }
46
+ }
47
+
48
+ DOC = {
49
+ ODF::Converter::Families::TEXT => {
50
+ FilterName: "MS Word 97"
51
+ }
52
+ }
53
+
54
+ DOCX = {
55
+ ODF::Converter::Families::TEXT => {
56
+ FilterName: "MS Word 2007 XML"
57
+ }
58
+ }
59
+
60
+ RTF = {
61
+ ODF::Converter::Families::TEXT => {
62
+ FilterName: "Rich Text Format"
63
+ }
64
+ }
65
+
66
+ TXT = {
67
+ ODF::Converter::Families::TEXT => {
68
+ FilterName: "Text",
69
+ FilterOptions: "utf8"
70
+ }
71
+ }
72
+
73
+ ODS = {
74
+ ODF::Converter::Families::SPREADSHEET => {
75
+ FilterName: "calc8"
76
+ }
77
+ }
78
+
79
+ XLS = {
80
+ ODF::Converter::Families::SPREADSHEET => {
81
+ FilterName: "MS Excel 97"
82
+ }
83
+ }
84
+
85
+ CSV = {
86
+ ODF::Converter::Families::SPREADSHEET => {
87
+ FilterName: "Text - txt - csv (StarCalc)",
88
+ FilterOptions: "44,34,0"
89
+ }
90
+ }
91
+
92
+ ODP = {
93
+ ODF::Converter::Families::PRESENTATION => {
94
+ FilterName: "impress8"
95
+ }
96
+ }
97
+
98
+ PPT = {
99
+ ODF::Converter::Families::PRESENTATION => {
100
+ FilterName: "MS PowerPoint 97"
101
+ }
102
+ }
103
+
104
+ SWF = {
105
+ ODF::Converter::Families::PRESENTATION => {
106
+ FilterName: "impress_flash_Export"
107
+ },
108
+ ODF::Converter::Families::DRAWING => {
109
+ FilterName: "draw_flash_Export"
110
+ }
111
+ }
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,21 @@
1
+ module ODF
2
+ class Converter
3
+ module Filters
4
+ module Import
5
+ include BaseFilter
6
+
7
+ # see http://wiki.services.openoffice.org/wiki/Framework/Article/Filter
8
+ # most formats are auto-detected; only those requiring options are defined here
9
+ TXT = {
10
+ FilterName: "Text (encoded)",
11
+ FilterOptions: "utf8"
12
+ }
13
+
14
+ CSV = {
15
+ FilterName: "Text - txt - csv (StarCalc)",
16
+ FilterOptions: "44,34,0"
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ class Hash
2
+ def to_uno_properties
3
+ self.inject([]) do |memo, (key, value)|
4
+ property = ODF::PropertyValue.new
5
+ property.Name = key.to_s
6
+ property.Value = value.to_s
7
+ memo << property
8
+ memo
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module ODF
2
+ class Converter
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/odf/converter/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Daniel Vandersluis"]
6
+ gem.email = ["dvandersluis@selfmgmt.com"]
7
+ gem.description = %q{Ruby library for converting ODF files through OO.org}
8
+ gem.summary = %q{Uses a native Ruby-UNO bridge (rubyuno) to connect to OpenOffice.org running as a service and convert ODF documents to a different format.}
9
+ gem.homepage = "https://www.github.com/dvandersluis/odf-converter"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "odf-converter"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = ODF::Converter::VERSION
17
+
18
+ gem.add_dependency "rubyuno"
19
+ gem.add_development_dependency "pry"
20
+ gem.add_development_dependency "pry-editline"
21
+ gem.add_development_dependency "rspec"
22
+ end
@@ -0,0 +1,42 @@
1
+ require 'odf/converter'
2
+
3
+ describe ODF::Converter do
4
+ describe "#new" do
5
+ it "should initialize a connection" do
6
+ end
7
+ end
8
+
9
+ describe "#convert" do
10
+ let(:c) { ODF::Converter.new }
11
+
12
+ describe do
13
+ before { c.stub(:perform_conversion) { true } }
14
+
15
+ it "should raise an error if the to option is not given" do
16
+ expect { c.convert("infile.txt") }.to raise_error ArgumentError
17
+ end
18
+
19
+ it "should raise an error if the to option is a string but doesn't look like a file with extension" do
20
+ expect { c.convert("infile.txt", to: "file") }.to raise_error ODF::Converter::DocumentConversionError
21
+ end
22
+
23
+ it "should raise an error if the to option is not a string or a symbol" do
24
+ expect { c.convert("infile.txt", to: []) }.to raise_error ODF::Converter::DocumentConversionError
25
+ end
26
+
27
+ it "should output to the input file name with the extension changed if to is set to a symbol" do
28
+ FileUtils.cd "/"
29
+
30
+ c.convert("infile.txt", to: :html).should == "/infile.html"
31
+ c.convert("/home/username/infile.txt", to: :html).should == "/home/username/infile.html"
32
+ end
33
+
34
+ it "should output to the given name if it's a valid filename" do
35
+ FileUtils.cd "/"
36
+
37
+ c.convert("infile.txt", to: "outfile.html").should == "/outfile.html"
38
+ c.convert("/home/username/infile.txt", to: "/home/username/outfile.html").should == "/home/username/outfile.html"
39
+ end
40
+ end
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: odf-converter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Daniel Vandersluis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rubyuno
16
+ requirement: &20530940 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *20530940
25
+ - !ruby/object:Gem::Dependency
26
+ name: pry
27
+ requirement: &20530480 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *20530480
36
+ - !ruby/object:Gem::Dependency
37
+ name: pry-editline
38
+ requirement: &20529660 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *20529660
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &20528780 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *20528780
58
+ description: Ruby library for converting ODF files through OO.org
59
+ email:
60
+ - dvandersluis@selfmgmt.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - LICENSE
68
+ - README.md
69
+ - Rakefile
70
+ - lib/odf-converter.rb
71
+ - lib/odf/converter.rb
72
+ - lib/odf/converter/families.rb
73
+ - lib/odf/converter/filters/base_filter.rb
74
+ - lib/odf/converter/filters/export.rb
75
+ - lib/odf/converter/filters/import.rb
76
+ - lib/odf/converter/hash.rb
77
+ - lib/odf/converter/version.rb
78
+ - odf-converter.gemspec
79
+ - spec/odf/converter_spec.rb
80
+ homepage: https://www.github.com/dvandersluis/odf-converter
81
+ licenses: []
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 1.8.12
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Uses a native Ruby-UNO bridge (rubyuno) to connect to OpenOffice.org running
104
+ as a service and convert ODF documents to a different format.
105
+ test_files:
106
+ - spec/odf/converter_spec.rb
107
+ has_rdoc: