convertible 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +0 -0
- data/LICENSE +20 -0
- data/README.md +50 -0
- data/ROADMAP.md +0 -0
- data/bin/convertible +95 -0
- data/lib/convertible.rb +4 -0
- data/lib/convertible/cli.rb +80 -0
- data/lib/convertible/client.rb +41 -0
- data/lib/convertible/mime_types.rb +83 -0
- data/lib/convertible/version.rb +3 -0
- metadata +76 -0
data/CHANGELOG.md
ADDED
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.
|
data/README.md
ADDED
@@ -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
|
+
|
data/ROADMAP.md
ADDED
File without changes
|
data/bin/convertible
ADDED
@@ -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
|
data/lib/convertible.rb
ADDED
@@ -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
|
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
|
+
|