vuzitruby 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +6 -6
- data/bin/vuzitcl +180 -87
- data/lib/vuzitruby/base.rb +117 -0
- data/lib/vuzitruby/{exception.rb → client_exception.rb} +2 -12
- data/lib/vuzitruby/document.rb +66 -177
- data/lib/vuzitruby/service.rb +22 -23
- data/lib/vuzitruby.rb +2 -1
- metadata +4 -3
data/README
CHANGED
@@ -32,8 +32,8 @@ The client library is a RubyGem called *vuzitruby*. To install, type:
|
|
32
32
|
|
33
33
|
* Download the code - http://github.com/vuzit/vuzitruby/downloads
|
34
34
|
* Sign up for a free Vuzit account - https://ssl.vuzit.com/signup
|
35
|
-
* Code Examples - http://wiki.github.com/vuzit/vuzitruby/
|
36
|
-
* Vuzit API Reference - http://
|
35
|
+
* Code Examples - http://wiki.github.com/vuzit/vuzitruby/code_examples
|
36
|
+
* Vuzit API Reference - http://wiki.github.com/vuzit/vuzitruby/api_reference
|
37
37
|
* VuzitCL Command Line - http://wiki.github.com/vuzit/vuzitruby/vuzitcl
|
38
38
|
|
39
39
|
== EXAMPLES
|
@@ -69,16 +69,16 @@ Upload and View with the JavaScript API Example for a Rails RHTML file:
|
|
69
69
|
|
70
70
|
doc = Vuzit::Document.upload("c:/path/to/document.pdf")
|
71
71
|
timestamp = Time.now
|
72
|
-
sig = Vuzit::Service.
|
72
|
+
sig = Vuzit::Service.signature("show", doc.id, timestamp)
|
73
73
|
%>
|
74
74
|
<html>
|
75
75
|
<head>
|
76
|
-
<link href="http://vuzit.com/stylesheets/Vuzit-2.
|
77
|
-
<script src="http://vuzit.com/javascripts/Vuzit-2.
|
76
|
+
<link href="http://vuzit.com/stylesheets/Vuzit-2.9.css" rel="Stylesheet" type="text/css" />
|
77
|
+
<script src="http://vuzit.com/javascripts/Vuzit-2.9.js" type="text/javascript"></script>
|
78
78
|
<script type="text/javascript">
|
79
79
|
// Called when the page is loaded.
|
80
80
|
function initialize() {
|
81
|
-
vuzit.Base.
|
81
|
+
vuzit.Base.apiKeySet("<%= Vuzit::Service.public_key %>");
|
82
82
|
var options = {signature: '<%= CGI.escape(sig) %>',
|
83
83
|
timestamp: '<%= timestamp %>', ssl: true}
|
84
84
|
var viewer = vuzit.Viewer.fromId("<%= doc.id %>", options);
|
data/bin/vuzitcl
CHANGED
@@ -7,99 +7,95 @@ require 'pp'
|
|
7
7
|
|
8
8
|
require File.dirname(__FILE__) + '/../lib/vuzitruby'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
opts.separator ""
|
29
|
-
opts.separator "Options:"
|
30
|
-
|
31
|
-
opts.on("-k", "--keys [PUB_KEY],[PRIV_KEY]",
|
32
|
-
"Developer API keys - REQUIRED") do |value|
|
33
|
-
options.key = value
|
34
|
-
end
|
35
|
-
|
36
|
-
opts.on("-u", "--upload [PATH]", "File to upload") do |value|
|
37
|
-
options.upload = value
|
38
|
-
end
|
39
|
-
|
40
|
-
opts.on("-p", "--public", "Make uploaded file public") do |value|
|
41
|
-
options.public = true
|
42
|
-
end
|
43
|
-
|
44
|
-
opts.on("-l", "--load [ID]", "Loads the document data") do |value|
|
45
|
-
options.load = value
|
46
|
-
end
|
47
|
-
|
48
|
-
opts.on("-d", "--delete [ID]", "Deletes a document") do |value|
|
49
|
-
options.delete = value
|
50
|
-
end
|
51
|
-
|
52
|
-
opts.on("-s", "--service-url [URL]", "Sets the service URL") do |value|
|
53
|
-
options.service_url = value
|
54
|
-
end
|
55
|
-
|
56
|
-
opts.on("-v", "--verbose", "Prints more messages") do
|
57
|
-
options.verbose = true
|
58
|
-
end
|
59
|
-
|
60
|
-
opts.on_tail("-h", "--help", "Show this message") do
|
61
|
-
puts opts
|
62
|
-
exit
|
63
|
-
end
|
10
|
+
# GENERAL METHODS
|
11
|
+
|
12
|
+
# Prints an error message
|
13
|
+
def error(message)
|
14
|
+
puts ''
|
15
|
+
puts message
|
16
|
+
end
|
17
|
+
|
18
|
+
# Loads the global parameters
|
19
|
+
def global_parameters_load(args)
|
20
|
+
options = OpenStruct.new
|
21
|
+
options.key = nil
|
22
|
+
options.id = nil
|
23
|
+
|
24
|
+
opts = OptionParser.new do |opts|
|
25
|
+
opts.on("-k", "--keys=PUB_KEY,PRIV_KEY",
|
26
|
+
"Developer API keys - REQUIRED") do |value|
|
27
|
+
options.key = value
|
64
28
|
end
|
65
29
|
|
66
|
-
|
67
|
-
|
30
|
+
opts.on("-s", "--service-url=URL", "Sets the service URL") do |value|
|
31
|
+
options.service_url = value
|
68
32
|
end
|
33
|
+
end
|
69
34
|
|
35
|
+
begin
|
70
36
|
opts.parse!(args)
|
71
|
-
|
72
|
-
|
37
|
+
rescue OptionParser::InvalidOption => e
|
38
|
+
e.recover(args)
|
39
|
+
end
|
73
40
|
|
74
|
-
|
41
|
+
if options.key == nil
|
42
|
+
error("Must provide the --keys parameters")
|
43
|
+
return false
|
44
|
+
end
|
75
45
|
|
76
|
-
|
77
|
-
puts ''
|
78
|
-
puts message
|
79
|
-
end
|
46
|
+
keys = options.key.split(',')
|
80
47
|
|
81
|
-
|
82
|
-
|
48
|
+
Vuzit::Service.public_key = keys[0]
|
49
|
+
Vuzit::Service.private_key = keys[1]
|
50
|
+
Vuzit::Service.user_agent = "VuzitCL Ruby 1.1.0"
|
83
51
|
|
84
|
-
if options.
|
85
|
-
|
86
|
-
|
52
|
+
if options.service_url != nil
|
53
|
+
Vuzit::Service.service_url = options.service_url
|
54
|
+
end
|
55
|
+
|
56
|
+
return true
|
87
57
|
end
|
88
58
|
|
89
|
-
|
90
|
-
|
59
|
+
# COMMAND FUNCTIONS
|
60
|
+
|
61
|
+
# Performs the delete command.
|
62
|
+
def delete_command(args)
|
63
|
+
id = args.pop
|
64
|
+
|
65
|
+
return if !global_parameters_load(args)
|
91
66
|
|
92
|
-
|
93
|
-
|
67
|
+
begin
|
68
|
+
doc = Vuzit::Document.destroy(id)
|
69
|
+
puts "DELETED: #{id}"
|
70
|
+
rescue Vuzit::ClientException => ex
|
71
|
+
error "Error occurred: #{ex.code}, #{ex.message}"
|
72
|
+
end
|
94
73
|
end
|
95
74
|
|
96
|
-
|
97
|
-
|
75
|
+
# Handles the help command
|
76
|
+
def help_command(args)
|
77
|
+
command = args.pop
|
78
|
+
|
79
|
+
case command
|
80
|
+
when "load"
|
81
|
+
print_usage_load
|
82
|
+
when "delete"
|
83
|
+
print_usage_delete
|
84
|
+
when "upload"
|
85
|
+
print_usage_upload
|
86
|
+
else
|
87
|
+
error("Unknown option: [#{command}]")
|
88
|
+
end
|
98
89
|
end
|
99
90
|
|
100
|
-
|
91
|
+
# Performs the load command.
|
92
|
+
def load_command(args)
|
93
|
+
id = args.pop
|
94
|
+
|
95
|
+
return if !global_parameters_load(args)
|
96
|
+
|
101
97
|
begin
|
102
|
-
doc = Vuzit::Document.find(
|
98
|
+
doc = Vuzit::Document.find(id)
|
103
99
|
puts "LOADED: #{doc.id}"
|
104
100
|
puts "title: #{doc.title}"
|
105
101
|
puts "subject: #{doc.subject}"
|
@@ -107,24 +103,121 @@ if options.load != nil
|
|
107
103
|
puts "width: #{doc.page_width}"
|
108
104
|
puts "height: #{doc.page_height}"
|
109
105
|
puts "size: #{doc.file_size}"
|
110
|
-
|
106
|
+
puts "status: #{doc.status}"
|
107
|
+
rescue Vuzit::ClientException => ex
|
111
108
|
puts "Error occurred: #{ex.code}, #{ex.message}"
|
112
109
|
end
|
113
|
-
|
110
|
+
end
|
111
|
+
|
112
|
+
# Performs the load command.
|
113
|
+
def upload_command(args)
|
114
|
+
path = args.pop
|
115
|
+
|
116
|
+
return if !global_parameters_load(args)
|
117
|
+
|
118
|
+
list = Hash.new
|
119
|
+
opts = OptionParser.new do |opts|
|
120
|
+
opts.on("-s", "--secure", "") do
|
121
|
+
list[:secure] = true
|
122
|
+
end
|
123
|
+
|
124
|
+
opts.on("-p", "--download-pdf", "") do
|
125
|
+
list[:download_pdf] = true
|
126
|
+
end
|
127
|
+
|
128
|
+
opts.on("-d", "--download-document", "") do
|
129
|
+
list[:download_document] = true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
114
133
|
begin
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
error "Error occurred: #{ex.code}, #{ex.message}"
|
134
|
+
opts.parse!(args)
|
135
|
+
rescue OptionParser::InvalidOption => e
|
136
|
+
e.recover(args)
|
119
137
|
end
|
120
|
-
|
138
|
+
|
121
139
|
begin
|
122
|
-
doc = Vuzit::Document.upload(
|
140
|
+
doc = Vuzit::Document.upload(path, list)
|
123
141
|
puts "UPLOADED: #{doc.id}"
|
124
|
-
rescue Vuzit::
|
142
|
+
rescue Vuzit::ClientException => ex
|
125
143
|
error "Error occurred: #{ex.code}, #{ex.message}"
|
126
144
|
end
|
127
|
-
|
128
|
-
|
145
|
+
end
|
146
|
+
|
147
|
+
# PRINT USAGE METHODS
|
148
|
+
|
149
|
+
# Prints the delete usage.
|
150
|
+
def print_usage_delete
|
151
|
+
puts "delete: Delete a document"
|
152
|
+
puts "usage: delete [OPTIONS] WEB_ID"
|
153
|
+
puts ""
|
154
|
+
puts "Valid options:"
|
155
|
+
puts " none"
|
156
|
+
puts ""
|
157
|
+
print_usage_global
|
158
|
+
end
|
159
|
+
|
160
|
+
# Prints the general usage
|
161
|
+
def print_usage_general
|
162
|
+
puts "VuzitCL - Vuzit Command Line"
|
163
|
+
puts "Usage: vuzitcl COMMAND -k PUBLIC_KEY,PRIVATE_KEY [OPTIONS]"
|
164
|
+
puts ""
|
165
|
+
puts "Type 'vuzitcl help <command>' for help on a specific command."
|
166
|
+
puts ""
|
167
|
+
puts "Available commands:"
|
168
|
+
puts ""
|
169
|
+
puts " upload"
|
170
|
+
puts " delete"
|
171
|
+
puts " load"
|
172
|
+
puts " help"
|
173
|
+
end
|
174
|
+
|
175
|
+
# Prints the global options
|
176
|
+
def print_usage_global
|
177
|
+
puts "Global Options:"
|
178
|
+
puts " -k, --keys=PUB_KEY,PRIV_KEY Developer API keys - REQUIRED"
|
179
|
+
puts " -u, --service-url=URL Sets the service URL (e.g. http://domain.com)"
|
180
|
+
end
|
181
|
+
|
182
|
+
# Prints the load options
|
183
|
+
def print_usage_load
|
184
|
+
puts "load: Loads a document"
|
185
|
+
puts "usage: load [OPTIONS] WEB_ID"
|
186
|
+
puts ""
|
187
|
+
puts "Valid options:"
|
188
|
+
puts " none"
|
189
|
+
puts ""
|
190
|
+
print_usage_global
|
191
|
+
end
|
192
|
+
|
193
|
+
# Prints the upload options
|
194
|
+
def print_usage_upload
|
195
|
+
puts "upload: Upload a file to Vuzit."
|
196
|
+
puts "usage: upload [OPTIONS] PATH"
|
197
|
+
puts ""
|
198
|
+
puts "Valid options:"
|
199
|
+
puts " -s, --secure Make the document secure (not public)"
|
200
|
+
puts " -p, --download-pdf Make the PDF downloadable"
|
201
|
+
puts " -d, --download-document Make the original document downloadable"
|
202
|
+
puts ""
|
203
|
+
print_usage_global
|
204
|
+
end
|
205
|
+
|
206
|
+
# MAIN CODE EXECUTION
|
207
|
+
|
208
|
+
command = ARGV.shift
|
209
|
+
|
210
|
+
case command
|
211
|
+
when "load"
|
212
|
+
load_command(ARGV)
|
213
|
+
when "delete"
|
214
|
+
delete_command(ARGV)
|
215
|
+
when "upload"
|
216
|
+
upload_command(ARGV)
|
217
|
+
when "help"
|
218
|
+
help_command(ARGV)
|
219
|
+
else
|
220
|
+
error("Unknown command: [#{command}]")
|
221
|
+
print_usage_general
|
129
222
|
end
|
130
223
|
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module Vuzit
|
4
|
+
|
5
|
+
# Base web client class for the Vuzit library.
|
6
|
+
class Base
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
# Returns true if a value is a Boolean.
|
11
|
+
def self.bool?(value)
|
12
|
+
return value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns true if the value is empty.
|
16
|
+
def self.empty?(value)
|
17
|
+
return (value == nil) || value.to_s.length < 1
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns an HTTP connection
|
21
|
+
def self.http_connection()
|
22
|
+
uri = URI.parse(Vuzit::Service.service_url)
|
23
|
+
|
24
|
+
result = Net::HTTP.new(uri.host, uri.port)
|
25
|
+
if Vuzit::Service.service_url[0, 8] == "https://"
|
26
|
+
result.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
27
|
+
result.use_ssl = true
|
28
|
+
end
|
29
|
+
|
30
|
+
return result
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a clean version of the parameters hash table.
|
34
|
+
def self.parameters_clean(params)
|
35
|
+
result = Hash.new
|
36
|
+
|
37
|
+
params.each_pair do |key, value|
|
38
|
+
if bool?(value)
|
39
|
+
value = value ? "1" : "0"
|
40
|
+
end
|
41
|
+
|
42
|
+
if !empty?(value)
|
43
|
+
result[key] = value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
return result
|
48
|
+
end
|
49
|
+
|
50
|
+
# Converts a set of parameters to a URL.
|
51
|
+
def self.parameters_to_url(resource, params, id = nil, extension = 'xml')
|
52
|
+
params = parameters_clean(params)
|
53
|
+
|
54
|
+
result = ''
|
55
|
+
result << Vuzit::Service.service_url.to_s << "/" << resource
|
56
|
+
result << ("/" << id) if !id.nil?
|
57
|
+
result << "." << extension << "?"
|
58
|
+
|
59
|
+
params.each_pair do |key, value|
|
60
|
+
result << (key.to_s << "=" << CGI.escape(value.to_s) << "&")
|
61
|
+
end
|
62
|
+
|
63
|
+
return result
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the default HTTP post parameters hash.
|
67
|
+
def self.post_parameters(method, params, id = '')
|
68
|
+
params = Hash.new if params.nil?
|
69
|
+
|
70
|
+
params[:method] = method
|
71
|
+
params[:key] = Vuzit::Service.public_key
|
72
|
+
|
73
|
+
timestamp = Time.now
|
74
|
+
params[:timestamp] = timestamp.to_i # time since epoch
|
75
|
+
|
76
|
+
pages = ''
|
77
|
+
if params.has_key?(:included_pages)
|
78
|
+
pages = params[:included_pages]
|
79
|
+
end
|
80
|
+
label = ''
|
81
|
+
|
82
|
+
signature = Vuzit::Service::signature(method, id, timestamp, pages, label)
|
83
|
+
params[:signature] = signature
|
84
|
+
|
85
|
+
return params
|
86
|
+
end
|
87
|
+
|
88
|
+
# Makes a HTTP POST.
|
89
|
+
def self.send_request(method, fields = {})
|
90
|
+
raise ArgumentError, "Method should be given" if method.nil? || method.empty?
|
91
|
+
|
92
|
+
http = http_connection
|
93
|
+
|
94
|
+
# API methods can be slow.
|
95
|
+
http.read_timeout = 15 * 60
|
96
|
+
request = Net::HTTP::Post.new('/documents', {'User-Agent' => Vuzit::Service.user_agent})
|
97
|
+
request.multipart_params = parameters_clean(fields)
|
98
|
+
|
99
|
+
tries = 3
|
100
|
+
begin
|
101
|
+
tries -= 1
|
102
|
+
res = http.request(request)
|
103
|
+
rescue Exception
|
104
|
+
$stderr.puts "Request encountered error, will retry #{tries} more."
|
105
|
+
if tries > 0
|
106
|
+
# Retrying several times with sleeps is recommended.
|
107
|
+
# This will prevent temporary downtimes
|
108
|
+
sleep(20)
|
109
|
+
retry
|
110
|
+
end
|
111
|
+
raise $!
|
112
|
+
end
|
113
|
+
return res
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
module Vuzit
|
3
3
|
# Vuzit library exception handler class.
|
4
|
-
class
|
4
|
+
class ClientException < StandardError
|
5
5
|
# The web service error message
|
6
6
|
attr_reader :message
|
7
7
|
|
@@ -9,24 +9,14 @@ module Vuzit
|
|
9
9
|
attr_reader :code
|
10
10
|
|
11
11
|
# Constructor for errors.
|
12
|
-
#
|
13
|
-
# Example:
|
14
|
-
#
|
15
|
-
# begin
|
16
|
-
# doc = Vuzit::Document.find("DOCUMENT_ID")
|
17
|
-
# rescue Vuzit::Exception => ex
|
18
|
-
# puts "Error code: #{ex.code}, message: #{ex.message}"
|
19
|
-
# end
|
20
12
|
def initialize(message, code = 0)
|
21
13
|
@message = message
|
22
14
|
@code = code
|
23
15
|
end
|
24
16
|
|
25
17
|
# Returns the string representation of the error in this format:
|
26
|
-
#
|
27
|
-
# Vuzit::Exception: [CODE]: MESSAGE
|
28
18
|
def to_s
|
29
|
-
return "Vuzit::
|
19
|
+
return "Vuzit::ClientException: [#{@code}]: #{@message}";
|
30
20
|
end
|
31
21
|
end
|
32
22
|
end
|
data/lib/vuzitruby/document.rb
CHANGED
@@ -1,75 +1,34 @@
|
|
1
1
|
require 'rexml/document'
|
2
|
-
require 'uri'
|
3
|
-
require 'cgi'
|
4
|
-
|
5
|
-
class Hash #:nodoc:all
|
6
|
-
# Taken from Rails, with appreciation to DHH
|
7
|
-
def stringify_keys
|
8
|
-
inject({}) do |options, (key, value)|
|
9
|
-
options[key.to_s] = value
|
10
|
-
options
|
11
|
-
end
|
12
|
-
end unless method_defined?(:stringify_keys)
|
13
|
-
end
|
14
2
|
|
15
3
|
module Vuzit
|
16
4
|
|
17
5
|
# Class for uploading, loading, and deleting documents using the Vuzit Web
|
18
6
|
# Service API: http://vuzit.com/developer/documents_api
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
# The document subject
|
30
|
-
attr_accessor :subject
|
31
|
-
|
32
|
-
# Number of pages of the document
|
33
|
-
attr_accessor :page_count
|
34
|
-
|
35
|
-
# Page width of the document in pixels
|
36
|
-
attr_accessor :page_width
|
37
|
-
|
38
|
-
# Page height of the document in pixels
|
39
|
-
attr_accessor :page_height
|
40
|
-
|
41
|
-
# File size of the original document bytes
|
42
|
-
attr_accessor :file_size
|
43
|
-
|
44
|
-
TRIES = 3 #:nodoc:
|
7
|
+
class Document < Base
|
8
|
+
attr_reader :id # The document ID
|
9
|
+
attr_reader :title # The document title
|
10
|
+
attr_reader :subject # The document subject
|
11
|
+
attr_reader :page_count # Number of pages of the document
|
12
|
+
attr_reader :page_width # Page width of the document in pixels
|
13
|
+
attr_reader :page_height # Page height of the document in pixels
|
14
|
+
attr_reader :file_size # File size of the original document bytes
|
15
|
+
attr_reader :status # Status of the document
|
45
16
|
|
46
17
|
# Constructor.
|
47
18
|
def initialize #:nodoc:
|
48
19
|
# Set the defaults
|
49
20
|
@id = @title = @subject = nil
|
50
|
-
@page_count = @page_width = @page_height = @file_size = -1
|
21
|
+
@page_count = @page_width = @page_height = @file_size = @status = -1
|
51
22
|
end
|
52
23
|
|
53
24
|
# Deletes a document by the ID. Returns true if it succeeded. It throws
|
54
|
-
# a Vuzit::
|
55
|
-
#
|
56
|
-
# Example:
|
57
|
-
#
|
58
|
-
# Vuzit::Service.public_key = 'YOUR_PUBLIC_API_KEY'
|
59
|
-
# Vuzit::Service.private_key = 'YOUR_PRIVATE_API_KEY'
|
60
|
-
#
|
61
|
-
# result = Vuzit::Document.destroy("DOCUMENT_ID")
|
25
|
+
# a Vuzit::ClientException on failure. It returns _true_ on success.
|
62
26
|
def self.destroy(id)
|
63
|
-
|
64
|
-
|
27
|
+
params = post_parameters("destroy", nil, id)
|
28
|
+
url = parameters_to_url("documents", params, id)
|
29
|
+
http = http_connection
|
65
30
|
|
66
|
-
|
67
|
-
uri = URI.parse(Vuzit::Service.service_url)
|
68
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
69
|
-
|
70
|
-
query = "/documents/#{id}.xml?key=#{Vuzit::Service.public_key}" +
|
71
|
-
"&signature=#{sig}×tamp=#{timestamp.to_i}"
|
72
|
-
request = Net::HTTP::Delete.new(query)
|
31
|
+
request = Net::HTTP::Delete.new(url, {'User-Agent' => Vuzit::Service.user_agent})
|
73
32
|
response = http.start { http.request(request) }
|
74
33
|
|
75
34
|
if response.code.to_i != 200
|
@@ -77,46 +36,38 @@ module Vuzit
|
|
77
36
|
begin
|
78
37
|
doc = REXML::Document.new(response.body)
|
79
38
|
rescue Exception => ex
|
80
|
-
raise Vuzit::
|
39
|
+
raise Vuzit::ClientException.new("XML error: #{ex.message}")
|
81
40
|
end
|
82
41
|
|
83
42
|
if doc.root != nil
|
84
43
|
code = doc.root.elements['code']
|
85
44
|
if code != nil
|
86
|
-
raise Vuzit::
|
45
|
+
raise Vuzit::ClientException.new(doc.root.elements['msg'].text, code.text.to_i);
|
87
46
|
end
|
88
47
|
end
|
89
48
|
|
90
49
|
# At this point we don't know what the error is
|
91
|
-
raise Vuzit::
|
50
|
+
raise Vuzit::ClientException.new("Unknown error occurred #{response.message}", response.code)
|
92
51
|
end
|
93
52
|
|
94
|
-
debug(response.code + " " + response.message + "\n")
|
95
|
-
|
96
53
|
return true
|
97
54
|
end
|
98
55
|
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
#
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
uri = URI.parse(Vuzit::Service.service_url)
|
115
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
116
|
-
|
117
|
-
query = "/documents/#{id}.xml?key=#{Vuzit::Service.public_key}" +
|
118
|
-
"&signature=#{sig}×tamp=#{timestamp.to_i}"
|
119
|
-
request = Net::HTTP::Get.new(query)
|
56
|
+
# Returns a download URL.
|
57
|
+
def self.download_url(id, file_extension)
|
58
|
+
params = post_parameters("show", nil, id)
|
59
|
+
return parameters_to_url("documents", params, id, file_extension)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Finds a document by the ID. It throws a Vuzit::ClientException on failure.
|
63
|
+
def self.find(id, options = {})
|
64
|
+
raise ArgumentError, "Options must be a hash" unless options.kind_of? Hash
|
65
|
+
|
66
|
+
params = post_parameters("show", options, id)
|
67
|
+
url = parameters_to_url("documents", params, id)
|
68
|
+
http = http_connection
|
69
|
+
|
70
|
+
request = Net::HTTP::Get.new(url, {'User-Agent' => Vuzit::Service.user_agent})
|
120
71
|
response = http.start { http.request(request) }
|
121
72
|
|
122
73
|
# TODO: Check if response.code.to_i != 200
|
@@ -124,153 +75,91 @@ module Vuzit
|
|
124
75
|
begin
|
125
76
|
doc = REXML::Document.new(response.body)
|
126
77
|
rescue Exception => ex
|
127
|
-
raise Vuzit::
|
78
|
+
raise Vuzit::ClientException.new("XML error: #{ex.message}")
|
128
79
|
end
|
129
80
|
|
130
81
|
if doc.root == nil
|
131
|
-
raise Vuzit::
|
82
|
+
raise Vuzit::ClientException.new("No response from server");
|
132
83
|
end
|
133
84
|
|
134
|
-
debug(response.code + " " + response.message + "\n" + response.body)
|
135
|
-
|
136
85
|
code = doc.root.elements['code']
|
137
86
|
if code != nil
|
138
|
-
raise Vuzit::
|
87
|
+
raise Vuzit::ClientException.new(doc.root.elements['msg'].text, code.text.to_i);
|
139
88
|
end
|
140
89
|
|
141
90
|
id = doc.root.elements['web_id']
|
142
91
|
if id == nil
|
143
|
-
raise Vuzit::
|
92
|
+
raise Vuzit::ClientException.new("Unknown error occurred");
|
144
93
|
end
|
145
94
|
|
146
95
|
result = Vuzit::Document.new
|
147
|
-
result.
|
148
|
-
result.
|
149
|
-
result.
|
150
|
-
result.
|
151
|
-
result.
|
152
|
-
result.
|
153
|
-
result.
|
96
|
+
result.send(:set_id, id.text)
|
97
|
+
result.send(:set_title, doc.root.elements['title'].text)
|
98
|
+
result.send(:set_subject, doc.root.elements['subject'].text)
|
99
|
+
result.send(:set_page_count, doc.root.elements['page_count'].text.to_i)
|
100
|
+
result.send(:set_page_width, doc.root.elements['width'].text.to_i)
|
101
|
+
result.send(:set_page_height, doc.root.elements['height'].text.to_i)
|
102
|
+
result.send(:set_file_size, doc.root.elements['file_size'].text.to_i)
|
103
|
+
result.send(:set_status, doc.root.elements['status'].text.to_i)
|
154
104
|
|
155
105
|
return result
|
156
106
|
end
|
157
107
|
|
158
|
-
# Uploads a file to Vuzit. It throws a Vuzit::
|
159
|
-
#
|
160
|
-
# Example:
|
161
|
-
#
|
162
|
-
# Vuzit::Service.public_key = 'YOUR_PUBLIC_API_KEY'
|
163
|
-
# Vuzit::Service.private_key = 'YOUR_PRIVATE_API_KEY'
|
164
|
-
#
|
165
|
-
# doc = Vuzit::Document.upload("c:/path/to/document.pdf", :secure => true)
|
166
|
-
# puts doc.id
|
108
|
+
# Uploads a file to Vuzit. It throws a Vuzit::ClientException on failure.
|
167
109
|
def self.upload(file, options = {})
|
168
110
|
raise ArgumentError, "Options must be a hash" unless options.kind_of? Hash
|
169
111
|
|
170
|
-
|
171
|
-
|
172
|
-
# Make a request form
|
173
|
-
fields = Hash.new
|
174
|
-
fields[:format] = 'xml'
|
175
|
-
fields[:key] = Vuzit::Service::public_key
|
176
|
-
|
177
|
-
if options[:secure] != nil
|
178
|
-
fields[:secure] = options[:secure] == true ? '1' : '0'
|
179
|
-
else
|
180
|
-
fields[:secure] = '1'
|
112
|
+
if !File.exists?(file)
|
113
|
+
raise Vuzit::ClientException.new("The file could not be found: #{file}")
|
181
114
|
end
|
182
115
|
|
183
|
-
|
184
|
-
fields[:timestamp] = timestamp.to_i
|
185
|
-
fields[:file_type] = options[:file_type]
|
116
|
+
params = post_parameters("create", options)
|
186
117
|
response = nil
|
187
118
|
|
188
119
|
File.open(file, "rb") do |f|
|
189
|
-
|
190
|
-
response = send_request 'create',
|
120
|
+
params[:upload] = f
|
121
|
+
response = send_request 'create', params
|
191
122
|
end
|
192
123
|
|
193
|
-
debug(response.code + " " + response.message + "\n" + response.body)
|
194
|
-
|
195
124
|
# TODO: check the response.code.to_i to make sure it's 201
|
196
125
|
|
197
126
|
begin
|
198
127
|
doc = REXML::Document.new(response.body)
|
199
128
|
rescue Exception => ex
|
200
|
-
raise Vuzit::
|
129
|
+
raise Vuzit::ClientException.new("XML error: #{ex.message}")
|
201
130
|
end
|
202
131
|
|
203
132
|
if doc.root == nil
|
204
|
-
raise Vuzit::
|
133
|
+
raise Vuzit::ClientException.new("No response from server");
|
205
134
|
end
|
206
135
|
|
207
136
|
code = doc.root.elements['code']
|
208
137
|
if code != nil
|
209
|
-
raise Vuzit::
|
138
|
+
raise Vuzit::ClientException.new(doc.root.elements['msg'].text, code.text.to_i);
|
210
139
|
end
|
211
140
|
|
212
141
|
id = doc.root.elements['web_id']
|
213
142
|
if id == nil
|
214
|
-
raise Vuzit::
|
143
|
+
raise Vuzit::ClientException.new("Unknown error occurred");
|
215
144
|
end
|
216
145
|
|
217
146
|
result = Vuzit::Document.new
|
218
|
-
result.
|
147
|
+
result.send(:set_id, id.text)
|
219
148
|
|
220
149
|
return result
|
221
150
|
end
|
222
151
|
|
223
152
|
private
|
224
153
|
|
225
|
-
#
|
226
|
-
|
227
|
-
|
228
|
-
end
|
229
|
-
|
230
|
-
|
231
|
-
def
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
debug("** Remote method call: #{method}; fields: #{fields.inspect}")
|
236
|
-
|
237
|
-
# replace pesky hashes to prevent accidents
|
238
|
-
fields = fields.stringify_keys
|
239
|
-
|
240
|
-
# Complete fields with the method name
|
241
|
-
fields['method'] = method
|
242
|
-
|
243
|
-
fields.reject! { |k, v| v.nil? }
|
244
|
-
|
245
|
-
debug("** POST parameters: #{fields.inspect}")
|
246
|
-
|
247
|
-
# Create the connection
|
248
|
-
uri = URI.parse(Vuzit::Service.service_url)
|
249
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
250
|
-
|
251
|
-
# API methods can be SLOW. Make sure this is set to something big to prevent spurious timeouts
|
252
|
-
http.read_timeout = 15 * 60
|
253
|
-
|
254
|
-
request = Net::HTTP::Post.new('/documents')
|
255
|
-
request.multipart_params = fields
|
256
|
-
|
257
|
-
tries = TRIES
|
258
|
-
begin
|
259
|
-
tries -= 1
|
260
|
-
res = http.request(request)
|
261
|
-
rescue Exception
|
262
|
-
$stderr.puts "Request encountered error, will retry #{tries} more."
|
263
|
-
if tries > 0
|
264
|
-
# Retrying several times with sleeps is recommended.
|
265
|
-
# This will prevent temporary downtimes at Scribd from breaking API applications
|
266
|
-
sleep(20)
|
267
|
-
retry
|
268
|
-
end
|
269
|
-
raise $!
|
270
|
-
end
|
271
|
-
return res
|
272
|
-
end
|
273
|
-
|
154
|
+
# Private setter methods so that you can set the internal variables but
|
155
|
+
# not allow the setting of the public methods.
|
156
|
+
def set_id(value) @id = value; end
|
157
|
+
def set_subject(value) @subject = value; end
|
158
|
+
def set_title(value) @title = value; end
|
159
|
+
def set_status(value) @status = value; end
|
160
|
+
def set_page_count(value) @page_count = value; end
|
161
|
+
def set_page_width(value) @page_width = value; end
|
162
|
+
def set_page_height(value) @page_height = value; end
|
163
|
+
def set_file_size(value) @file_size = value; end
|
274
164
|
end
|
275
|
-
|
276
165
|
end
|
data/lib/vuzitruby/service.rb
CHANGED
@@ -47,7 +47,8 @@ module Vuzit
|
|
47
47
|
@@public_key = nil
|
48
48
|
@@private_key = nil
|
49
49
|
@@service_url = 'http://vuzit.com'
|
50
|
-
@@
|
50
|
+
@@product_name = 'VuzitRuby Library 1.2.0'
|
51
|
+
@@user_agent = @@product_name
|
51
52
|
|
52
53
|
# TODO: For all of the set variables do not allow nil values
|
53
54
|
|
@@ -75,50 +76,48 @@ module Vuzit
|
|
75
76
|
# you are running Vuzit Enterprise on your own server.
|
76
77
|
# The default value is "http://vuzit.com"
|
77
78
|
def self.service_url=(value)
|
78
|
-
|
79
|
+
url = value.strip
|
80
|
+
if url[-1, 1] == '/'
|
81
|
+
raise Exception.new("Trailing slashes (/) in service URLs are invalid")
|
82
|
+
end
|
83
|
+
|
84
|
+
@@service_url = url
|
79
85
|
end
|
80
86
|
|
81
87
|
# Returns the URL of the Vuzit web service.
|
82
88
|
def self.service_url
|
83
|
-
|
89
|
+
# Return clone so it does not change the orginal value
|
90
|
+
@@service_url.clone
|
84
91
|
end
|
85
92
|
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
@@debug = value
|
93
|
+
# Returns the User-Agent of the library.
|
94
|
+
def self.user_agent
|
95
|
+
@@user_agent
|
90
96
|
end
|
91
97
|
|
92
|
-
#
|
93
|
-
def self.
|
94
|
-
@@
|
98
|
+
# Sets the User-Agent of the library.
|
99
|
+
def self.user_agent=(value)
|
100
|
+
@@user_agent = "#{value} (#{@@product_name})"
|
95
101
|
end
|
96
102
|
|
97
103
|
# Returns The signature string. NOTE: If you are going to use this
|
98
104
|
# with the Vuzit Javascript API then the value must be encoded with the
|
99
|
-
# CGI.escape function. See the Wiki example for more information
|
100
|
-
|
101
|
-
# http://wiki.github.com/vuzit/vuzitruby/code-samples
|
102
|
-
#
|
103
|
-
# Example:
|
104
|
-
#
|
105
|
-
# timestamp = Time.now
|
106
|
-
# sig = Vuzit::Service.get_signature("show", "DOCUMENT_ID", timestamp)
|
107
|
-
def self.get_signature(service, id = '', time = nil)
|
105
|
+
# CGI.escape function. See the Wiki example for more information.
|
106
|
+
def self.signature(service, id = '', time = nil, pages = '', label = '')
|
108
107
|
if Vuzit::Service.public_key == nil || Vuzit::Service.private_key == nil
|
109
|
-
raise Vuzit::
|
108
|
+
raise Vuzit::ClientException.new("The public_key or private_key variables are nil")
|
110
109
|
end
|
111
110
|
time = (time == nil) ? Time.now.to_i : time.to_i
|
112
111
|
|
113
112
|
if @@public_key == nil
|
114
|
-
raise Vuzit::
|
113
|
+
raise Vuzit::ClientException.new("Vuzit::Service.public_key not set")
|
115
114
|
end
|
116
115
|
|
117
116
|
if @@private_key == nil
|
118
|
-
raise Vuzit::
|
117
|
+
raise Vuzit::ClientException.new("Vuzit::Service.private_key not set")
|
119
118
|
end
|
120
119
|
|
121
|
-
msg = "#{service}#{id}#{@@public_key}#{time}"
|
120
|
+
msg = "#{service}#{id}#{@@public_key}#{time}#{pages}#{label}"
|
122
121
|
hmac = hmac_sha1(@@private_key, msg)
|
123
122
|
result = Base64::encode64(hmac).chomp
|
124
123
|
|
data/lib/vuzitruby.rb
CHANGED
@@ -3,7 +3,8 @@ $:.unshift(File.dirname(__FILE__))
|
|
3
3
|
# This prevents the "require 'some_gem'" error
|
4
4
|
require 'rubygems'
|
5
5
|
|
6
|
+
require 'vuzitruby/base'
|
6
7
|
require 'vuzitruby/service'
|
7
8
|
require 'vuzitruby/document'
|
8
|
-
require 'vuzitruby/
|
9
|
+
require 'vuzitruby/client_exception'
|
9
10
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vuzitruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brent Matzelle
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-10-26 00:00:00 -04:00
|
13
13
|
default_executable: vuzitcl
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -25,8 +25,9 @@ files:
|
|
25
25
|
- README
|
26
26
|
- Rakefile
|
27
27
|
- lib/vuzitruby.rb
|
28
|
+
- lib/vuzitruby/base.rb
|
28
29
|
- lib/vuzitruby/document.rb
|
29
|
-
- lib/vuzitruby/
|
30
|
+
- lib/vuzitruby/client_exception.rb
|
30
31
|
- lib/vuzitruby/service.rb
|
31
32
|
has_rdoc: true
|
32
33
|
homepage: http://vuzit.com/
|