convertible 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Jens Krämer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,50 @@
1
+ # Overview
2
+
3
+ Simple commandline client written in Ruby for the http://convertible.io/
4
+ online file conversion platform. See the website for more info.
5
+
6
+ # Basic usage
7
+
8
+ Usage: convertible [options] [file1 [file2]]
9
+
10
+ Convert file1 to file2.
11
+
12
+ # Converting files
13
+
14
+ Without any file arguments data will be read from STDIN and written to STDOUT.
15
+ If only one filename (file1) is present, data will be read from STDIN and the result will
16
+ be written to file1. Use the -c switch to invert this behaviour so data is
17
+ read from file1 and written to STDOUT.
18
+
19
+ By default, input and output formats will be guessed from any filenames given. Use -i and -o
20
+ options to override. When using STDIN and/or STDOUT you have to use one or both of these options
21
+ to specify the format of the data. To specify a file format, use the well known file name postfix
22
+ (i.e. pdf for PDF documents) or the official mime type string like application/pdf.
23
+
24
+ convert pdf to plain text:
25
+ convertible document.pdf document.txt
26
+
27
+ convert pdf to plain text reading from STDIN:
28
+ convertible -i pdf document.txt < document.pdf
29
+
30
+ convert pdf to plain text writing to STDOUT:
31
+ convertible -c -o txt document.pdf > document.txt
32
+
33
+ convert pdf to plain text using both STDIN/STDOUT:
34
+ convertible -i pdf -o txt < document.pdf > document.txt
35
+
36
+
37
+ # Querying supported conversions
38
+
39
+ To query supported conversions or to check wether a given conversion is possible, use the
40
+ -s switch together with a given input filename or format (-i) and an optional output filename / format:
41
+
42
+ show all supported conversions:
43
+ convertible -s
44
+
45
+ show supported output formats for OpenOffice text:
46
+ convertible -s -i odt
47
+
48
+ check wether doc can be converted to pdf:
49
+ convertible -s -i doc -o pdf
50
+
File without changes
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env/ruby
2
+
3
+ require 'optparse'
4
+ require 'convertible/cli'
5
+ require 'pp'
6
+
7
+ @options = { :debug => false }
8
+ @max_file_args = 2
9
+
10
+ OptionParser.new do |optparser|
11
+ optparser.banner = <<-HELP
12
+ Usage: convertible [options] [file1 [file2]]
13
+
14
+ Convert file1 to file2.
15
+
16
+ Without any file arguments data will be read from STDIN and written to STDOUT.
17
+ If only one filename (file1) is present, data will be read from STDIN and the result will
18
+ be written to file1. Use the -c switch to invert this behaviour so data is
19
+ read from file1 and written to STDOUT.
20
+
21
+ By default, input and output formats will be guessed from any filenames given. Use -i and -o
22
+ options to override. When using STDIN and/or STDOUT you have to use one or both of these options
23
+ to specify the format of the data. To specify a file format, use the well known file name postfix
24
+ (i.e. pdf for PDF documents) or the official mime type string like application/pdf.
25
+
26
+ convert pdf to plain text:
27
+ convertible document.pdf document.txt
28
+
29
+ convert pdf to plain text reading from STDIN:
30
+ convertible -i pdf document.txt < document.pdf
31
+
32
+ convert pdf to plain text writing to STDOUT:
33
+ convertible -c -o txt document.pdf > document.txt
34
+
35
+ convert pdf to plain text using both STDIN/STDOUT:
36
+ convertible -i pdf -o txt < document.pdf > document.txt
37
+
38
+
39
+ To query supported conversions or to check wether a given conversion is possible, use the
40
+ -s switch together with a given input filename or format (-i) and an optional output filename / format:
41
+
42
+ show all supported conversions:
43
+ convertible -s
44
+
45
+ show supported output formats for OpenOffice text:
46
+ convertible -s -i odt
47
+
48
+ check wether doc can be converted to pdf:
49
+ convertible -s -i doc -o pdf
50
+
51
+ Options are:
52
+ HELP
53
+
54
+ optparser.on('-h', '--help', "This message") do
55
+ puts optparser
56
+ exit
57
+ end
58
+
59
+ optparser.on('-v', '--verbose', "Turn on debug messages") do
60
+ @options[:debug] = true
61
+ end
62
+
63
+ optparser.on('-s', '--supported', "Show supported conversions.") do
64
+ @command = :show
65
+ end
66
+
67
+ optparser.on('-i', '--input-format=MIMETYPE', "Specify input format (derived from input filename by default)") do |arg|
68
+ @options[:input_type] = arg
69
+ end
70
+
71
+ optparser.on('-o', '--output-format=MIMETYPE', "Specify desired output format (derived from output filename by default)") do |arg|
72
+ @options[:output_type] = arg
73
+ end
74
+
75
+ optparser.on('-c', '--stdout', "Read input from file1 and output to STDOUT") do
76
+ @out = 'STDOUT'
77
+ @max_file_args -= 1
78
+ end
79
+
80
+ files = optparser.permute!(ARGV)
81
+ (puts optparser; exit(1)) unless files.size <= @max_file_args
82
+
83
+ @out ||= files.pop || 'STDOUT'
84
+ @in = files.pop || 'STDIN'
85
+ STDERR.puts "#{@in} => #{@out}\n#{@options.inspect}" if @options[:debug]
86
+
87
+ @command ||= :convert
88
+ end
89
+
90
+ begin
91
+ Convertible::Cli.new(@in, @out, @options).send @command
92
+ rescue ArgumentError
93
+ STDERR.puts $!
94
+ exit 1
95
+ end
@@ -0,0 +1,4 @@
1
+ require "convertible/version"
2
+
3
+ module Convertible
4
+ end
@@ -0,0 +1,80 @@
1
+ require 'convertible/client'
2
+ require 'convertible/mime_types'
3
+
4
+ module Convertible
5
+ class Cli
6
+ def initialize(input, output = nil, options = {})
7
+ @input = input
8
+ @output = output
9
+ @options = options
10
+ end
11
+
12
+ def convert
13
+ unless @input == 'STDIN' || File.readable?(@input)
14
+ raise ArgumentError, "cannot open #{@input} for reading"
15
+ end
16
+ check_mimetypes
17
+ $stderr.puts "converting #{@input} to #{@output} with options #{@options.inspect}" if @options[:debug]
18
+ data = @input == 'STDIN' ? $stdin.read : File.read(@input)
19
+ response = client.convert data, @input_type, @output_type, @options
20
+ if @output == 'STDOUT'
21
+ $stdout << response
22
+ else
23
+ (File.open(@output, 'wb') << response).close
24
+ end
25
+ end
26
+
27
+ def show
28
+ check_mimetypes false, false
29
+ if in_t = @input_type
30
+ if out_t = @output_type
31
+ if client.supported?(in_t, out_t)
32
+ puts 'supported'
33
+ else
34
+ puts 'not supported' # no worky
35
+ end
36
+ else
37
+ conversions = client.supported_conversions @input_type
38
+ $stderr.puts "Supported output formats for #{@input_type}:"
39
+ puts conversions.join(', ')
40
+ end
41
+ else
42
+ conversions = client.supported_conversions
43
+ $stderr.puts "Supported conversions:"
44
+ conversions.keys.sort.each do |input|
45
+ puts "#{input} => " << conversions[input].join(', ')
46
+ end
47
+ end
48
+ end
49
+
50
+
51
+ protected
52
+
53
+ def client
54
+ Client.new
55
+ end
56
+
57
+ def check_mimetypes(need_input = true, need_output = true)
58
+ if need_input && @input == 'STDIN' && @options[:input_type].nil?
59
+ raise ArgumentError.new("You need to specify the input mimetype using -i when reading from STDIN!")
60
+ end
61
+ if @input != 'STDIN' || @options[:input_type]
62
+ unless @input_type = MimeTypes::for(@options[:input_type] || @input)
63
+ raise ArgumentError.new "Unsupported input file type"
64
+ end
65
+ end
66
+ if need_output && @output == 'STDOUT' && @options[:output_type].nil?
67
+ raise ArgumentError.new("You need to specify the output mimetype using -o when redirecting to STDOUT!")
68
+ end
69
+ if @output != 'STDOUT' || @options[:output_type]
70
+ unless @output_type = MimeTypes::for(@options[:output_type] || @output)
71
+ raise ArgumentError.new "Unsupported output file type"
72
+ end
73
+ end
74
+ if @options[:debug]
75
+ $stderr.puts "input type: #{@input_type}\noutput type: #{@output_type}"
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,41 @@
1
+ require 'httparty'
2
+ require 'json'
3
+
4
+ module Convertible
5
+ API_ENDPOINT = 'http://api.convertible.io/'
6
+
7
+ class Client
8
+ include HTTParty
9
+ base_uri API_ENDPOINT
10
+
11
+ # content_type and output_content_type must be valid mime types like 'application/pdf' or 'text/plain'
12
+ def convert(data, content_type, output_content_type, options = {})
13
+ response = self.class.post '/convert', :body => data, :headers => { 'Content-Type' => content_type, 'Accept' => output_content_type, 'X-Convert-Options' => option_string(options) }
14
+ if response.code == 200
15
+ return response
16
+ else
17
+ false
18
+ end
19
+ end
20
+
21
+ def supported_conversions(input_type = nil)
22
+ if input_type
23
+ response = self.class.get '/supported', :query => { :in => input_type }, :format => :json
24
+ response['out']
25
+ else
26
+ response = self.class.get '/supported', :format => :json
27
+ response['supported']
28
+ end
29
+ end
30
+
31
+ def supported?(input_type, output_type)
32
+ response = self.class.get '/supported', :query => { :in => input_type, :out => output_type }, :format => :json
33
+ response['supported']
34
+ end
35
+
36
+ private
37
+ def option_string(options = {})
38
+ options.to_a.map{|opt| opt.join('=')}.join(';')
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,83 @@
1
+ module Convertible
2
+ class MimeTypes
3
+ MIME_TYPES = {
4
+ 'text/plain' => %w(txt),
5
+ 'text/html' => %w(html htm xhtml),
6
+ 'text/xml' => %w(xml xsd mxml),
7
+ 'text/yaml' => %w(yml yaml),
8
+ 'text/csv' => %w(csv),
9
+ 'text/rtf' => %w(rtf),
10
+ 'image/gif' => %w(gif),
11
+ 'image/jpeg' => %w(jpg jpeg jpe),
12
+ 'image/png' => %w(png),
13
+ 'image/tiff' => %w(tiff tif),
14
+ 'image/x-ms-bmp' => %w(bmp),
15
+ 'image/x-xpixmap' => %w(xpm),
16
+ 'application/pdf' => %w(pdf),
17
+ 'application/msword' => %w(doc),
18
+ 'application/vnd.ms-excel' => %w(xls),
19
+ 'application/vnd.ms-powerpoint' => %w(ppt pps),
20
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => %w(docx),
21
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => %w(xlsx),
22
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => %w(pptx),
23
+ 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => %w(ppsx),
24
+ 'application/vnd.oasis.opendocument.spreadsheet' => %w(ods),
25
+ 'application/vnd.oasis.opendocument.text' => %w(odt),
26
+ 'application/vnd.oasis.opendocument.presentation' => %w(odp),
27
+ 'application/zip' => %w(zip),
28
+ 'application/x-gzip' => %w(gz)
29
+ }.freeze
30
+
31
+ EXTENSIONS = MIME_TYPES.inject({}) do |map, (type, exts)|
32
+ exts.each {|ext| map[ext] = type}
33
+ map
34
+ end
35
+
36
+ ALIASES = {
37
+ 'application/pdf' => ['application/x-pdf']
38
+ }
39
+
40
+ ALIAS_LOOKUP = ALIASES.inject({}) do |map, (type, aliases)|
41
+ aliases.each {|t| map[t] = type}
42
+ map
43
+ end
44
+
45
+ # input is filename
46
+ def self.of(name)
47
+ if name && m = name.to_s.match(/(^|\.)([^\.]+)$/)
48
+ EXTENSIONS[m[2].downcase]
49
+ end
50
+ end
51
+
52
+ # input is filename or mime type string (which will be returned as is)
53
+ def self.for(mimetype)
54
+ if MIME_TYPES[mimetype]
55
+ mimetype
56
+ elsif t = ALIAS_LOOKUP[mimetype]
57
+ t
58
+ else
59
+ of(mimetype)
60
+ end
61
+ end
62
+
63
+ def self.extension_for(mimetype)
64
+ if exts = MIME_TYPES[self.for(mimetype)]
65
+ exts.first
66
+ end
67
+ end
68
+
69
+ def self.main_mimetype_of(name)
70
+ mimetype = of(name)
71
+ mimetype.split('/').first if mimetype
72
+ end
73
+
74
+ def self.image?(mimetype)
75
+ self.for(mimetype) =~ /^image\/.+/
76
+ end
77
+
78
+ def self.supported?(name_or_mimetype)
79
+ !self.for(name_or_mimetype).blank?
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,3 @@
1
+ module Convertible
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: convertible
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Jens Kraemer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-13 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: httparty
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 0.7.8
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ description: convertible.io is a universal document conversion web service.
28
+ email:
29
+ - jk@jkraemer.net
30
+ executables:
31
+ - convertible
32
+ extensions: []
33
+
34
+ extra_rdoc_files: []
35
+
36
+ files:
37
+ - lib/convertible/cli.rb
38
+ - lib/convertible/client.rb
39
+ - lib/convertible/mime_types.rb
40
+ - lib/convertible/version.rb
41
+ - lib/convertible.rb
42
+ - bin/convertible
43
+ - LICENSE
44
+ - CHANGELOG.md
45
+ - README.md
46
+ - ROADMAP.md
47
+ has_rdoc: true
48
+ homepage: http://github.com/jkraemer/convertible
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 1.3.6
68
+ requirements: []
69
+
70
+ rubyforge_project: convertible
71
+ rubygems_version: 1.6.2
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: client for the convertible.io online service
75
+ test_files: []
76
+