Navigation Menu

Skip to content

Commit

Permalink
finish the basic rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
phoet committed Jul 13, 2012
1 parent 80a6cc3 commit 129799e
Show file tree
Hide file tree
Showing 23 changed files with 1,266 additions and 1,736 deletions.
25 changes: 23 additions & 2 deletions README.md
Expand Up @@ -19,9 +19,30 @@ or using bundler

## Usage

This is subject to change!
Please have a look at the specs to see all the examples!

Please have a look at the specs to see how it works currently.
# generate a png from a page of a remote pdf
Saaspose::Pdf.convert("remote_pdf_file.pdf", "local_png.png", 1)
# read the number of pages from a remote pdf
Saaspose::Pdf.page_count"remote_pdf_file.pdf"
# => 1

# generate a pdf from a remote ppt
Saaspose::Slides.convert"remote_ppt_file.ppt", "local_pdf.pdf")

# generate a pdf from a remote doc
Saaspose::Words.convert"remote_doc_file.doc", "local_pdf.pdf")

# generate a pdf from a remote xls
Saaspose::Cells.convert("remote_xls_file.xls", "local_pdf.pdf")

# upload a file to the root dir
Saaspose::Storage.upload("example.pdf", "")

# get a list of files from the root dir
files = Saaspose::Storage.files("")
files.first
# => <struct Saaspose::Storage::RemoteFile name="test", folder=true, modified=1969-12-31 14:00:00 +0100, size=0>

## License

Expand Down
4 changes: 2 additions & 2 deletions lib/saaspose/cells.rb
Expand Up @@ -2,8 +2,8 @@ module Saaspose
class Cells
class << self
def convert(name, file, options={:format=>:pdf})
url = "/cells/#{name}"
Utils.call(url, options, file)
url = "cells/#{name}"
Utils.call_and_save(url, options, file)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/saaspose/configuration.rb
Expand Up @@ -6,6 +6,6 @@ class Configuration
include Confiture::Configuration
confiture_allowed_keys(:product_uri, :app_sid, :app_key, :logger)
confiture_mandatory_keys(:product_uri, :app_sid, :app_key)
confiture_defaults(:product_uri => "http://api.saaspose.com/v1.0", :logger => Logger.new(STDERR))
confiture_defaults(:product_uri => "http://api.saaspose.com/v1.0/", :logger => Logger.new(STDERR))
end
end
17 changes: 6 additions & 11 deletions lib/saaspose/pdf.rb
@@ -1,20 +1,15 @@
require "rexml/document"

module Saaspose
class Pdf
class << self
def convert(name, local_file, save_image_format, page_number, height, width)
url_doc = Configuration.product_uri + '/pdf/' + name + '/pages/' + page_number + '?format=' + save_image_format + '&width=' + width + '&height=' + height
signed_url = Utils.sign(url_doc)
response = RestClient.get(signed_url, :accept => 'application/json')
Utils.save_file(response, local_file)
def convert(name, file, page_number, options={:format=>:png, :height=>800, :width=>600})
url = "pdf/#{name}/pages/#{page_number}"
Utils.call_and_save(url, options, file)
end

def page_count(name)
url_page = Configuration.product_uri + '/pdf/' + name + '/pages'
signed_url = Utils.sign(url_page)
response = RestClient.get(signed_url, :accept => 'application/xml')
REXML::Document.new(response.body).elements.size
url = "pdf/#{name}/pages"
result = Utils.call_and_parse(url)
result["Pages"]["Links"].size
end
end
end
Expand Down
8 changes: 3 additions & 5 deletions lib/saaspose/slides.rb
@@ -1,11 +1,9 @@
module Saaspose
class Slides
class << self
def convert(name, local_file, save_format)
url_doc = Configuration.product_uri + '/slides/' + name + '?format=' + save_format
signed_url = Utils.sign(url_doc)
response = RestClient.get(signed_url, :accept => 'application/json')
Utils.save_file(response, local_file)
def convert(name, file, options={:format=>:pdf})
url = "slides/#{name}"
Utils.call_and_save(url, options, file)
end
end
end
Expand Down
23 changes: 11 additions & 12 deletions lib/saaspose/storage.rb
@@ -1,27 +1,26 @@
require "json"
require "rest-client"

module Saaspose
class Storage
File = Struct.new(:name, :folder, :modified, :size)
RemoteFile = Struct.new(:name, :folder, :modified, :size)

class << self
def upload(local_file_path, remote_folder_path)
file_name = ::File.basename(local_file_path)
url_file = "#{Configuration.product_uri}/storage/file/#{remote_folder_path.empty? ? "" : "/#{remote_folder_path}" }#{file_name}"
file_name = File.basename(local_file_path)
url_file = "storage/file/#{remote_folder_path.empty? ? "" : "/#{remote_folder_path}" }#{file_name}"
signed_url = Utils.sign(url_file)
RestClient.put(signed_url, ::File.new(local_file_path, 'rb'))
RestClient.put(signed_url, File.new(local_file_path, 'rb'), :accept => 'application/json')
end

def files(remote_folder_path="")
url_folder = "#{Configuration.product_uri}/storage/folder"
url_folder << "/#{remote_folder_path}" unless remote_folder_path.empty?

signed_url = Utils.sign(url_folder)
response = RestClient.get(signed_url, :accept => 'application/json')
result = JSON.parse(response.body)
uri = "storage/folder"
uri << "/#{remote_folder_path}" unless remote_folder_path.empty?
result = Utils.call_and_parse(uri)

result["Files"].map do |entry|
File.new(entry["Name"], entry["IsFolder"], Utils.parse_date(entry["ModifiedDate"]), entry["Size"])
seconds_since_epoch = entry["ModifiedDate"].scan(/[0-9]+/)[0].to_i
date = Time.at((seconds_since_epoch-(21600000 + 18000000))/1000)
RemoteFile.new(entry["Name"], entry["IsFolder"], date, entry["Size"])
end
end
end
Expand Down
72 changes: 32 additions & 40 deletions lib/saaspose/utils.rb
Expand Up @@ -3,60 +3,52 @@
require 'openssl'
require 'base64'
require 'uri'
require 'json'

module Saaspose
class Utils
DIGEST = OpenSSL::Digest::Digest.new('sha1')
class << self
# Signs a URI with your appSID and Key.
# * :url describes the URL to sign
def sign(url)
url = URI.escape(url)
parsed_url = URI.parse(url)

url_to_sign =''
if parsed_url.query.nil?
url_to_sign = parsed_url.scheme+"://"+ parsed_url.host + parsed_url.path + "?appSID=" + Configuration.app_sid
else
url_to_sign = parsed_url.scheme+"://"+ parsed_url.host + parsed_url.path + '?' + parsed_url.query + "&appSID=" + Configuration.app_sid
end

# create a signature using the private key and the URL
raw_signature = OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), Configuration.app_key, url_to_sign)

#Convert raw to encoded string
signature = Base64.strict_encode64(raw_signature).tr('+/','-_')

#remove invalid character
signature = signature.gsub(/[=_-]/,'=' => '', '_' => '%2f', '-' => '%2b')

#Define expression
pat = /%[0-9a-f]{2}/

#Replace the portion matched to the above pattern to upper case
6.times do
signature = signature.sub(pat, pat.match(signature).to_s.upcase)
end

# prepend the server and append the signature.
url_to_sign + "&signature=#{signature}"
def sign(uri, options=nil)
options = options ? options.dup : {}
options.merge!(:appSID => Configuration.app_sid)
url = "#{Configuration.product_uri}#{uri}"

url << "?" << options.map{|key, value| "#{key}=#{CGI::escape(value.to_s)}"}.join("&")

signature = OpenSSL::HMAC.digest(DIGEST, Configuration.app_key, url)
signature = Base64.strict_encode64(signature).chop
signature = URI::escape(signature, /[^A-z0-9]/)

"#{url}&signature=#{signature}"
end

def parse_date(date_string)
seconds_since_epoch = date_string.scan(/[0-9]+/)[0].to_i
Time.at((seconds_since_epoch-(21600000 + 18000000))/1000)
def call(uri, options=nil)
signed_url = Utils.sign(uri, options)
log(:debug, "calling: #{signed_url}")
RestClient.get(signed_url, :accept => 'application/json')
rescue
log(:error, "error: #{$!.inspect}")
raise
end

def call(uri, options, file)
url = "#{Configuration.product_uri}#{uri}"
url << "?" << options.map{|key, value| "#{key}=#{CGI::escape(value.to_s)}"}.join("&") if options
signed_url = Utils.sign(url)
response = RestClient.get(signed_url, :accept => 'application/json')
def call_and_parse(uri, options=nil)
response = call(uri, options)
JSON.parse(response.body)
end

def call_and_save(uri, options, file)
response = response = call(uri, options)
Utils.save_file(response, file)
end

def save_file(response_stream, local_file)
File.open(local_file, "wb") { |file| file.write(response_stream.body) }
end

def log(severity, message)
Configuration.logger.send(severity, message) if Configuration.logger
end
end
end
end
2 changes: 1 addition & 1 deletion lib/saaspose/version.rb
@@ -1,3 +1,3 @@
module Saaspose
VERSION = "0.0.1"
VERSION = "0.0.2"
end
8 changes: 3 additions & 5 deletions lib/saaspose/words.rb
@@ -1,11 +1,9 @@
module Saaspose
class Words
class << self
def convert(name, local_file, save_format)
urlDoc = Configuration.product_uri + '/words/' + name + '?format=' + save_format
signedURL = Utils.sign(urlDoc)
response = RestClient.get(signedURL, :accept => 'application/json')
Utils.save_file(response, local_file)
def convert(name, file, options={:format=>:pdf})
url = "words/#{name}"
Utils.call_and_save(url, options, file)
end
end
end
Expand Down
18 changes: 18 additions & 0 deletions spec/lib/saaspose/utils_spec.rb
@@ -0,0 +1,18 @@
require "spec_helper"

describe Saaspose::Utils do
before(:each) do
Saaspose::Configuration.configure do |config|
config.app_sid = "SAASPOSE_APPSID"
config.app_key = "SAASPOSE_APPKEY"
end
end

context "signing" do
let(:signed_url) { "http://api.saaspose.com/v1.0/path?uschi=true&a_param=yes&appSID=SAASPOSE_APPSID&signature=kOJ7Xip6DwLMBOS7ZX9%2FxCkPn1w" }

it "should sign a uri" do
Saaspose::Utils.sign("path", {:uschi => true, :a_param => :yes}).should eql(signed_url)
end
end
end
61 changes: 10 additions & 51 deletions spec/lib/saaspose_spec.rb
@@ -1,15 +1,6 @@
require "spec_helper"

describe "saaspose" do
REMOTE_ROOT_DIR = ""

PNG_PATH = "/tmp/test.png"
PDF_PATH = "/tmp/test.pdf"

TEST_PDF_NAME = "saaspose_test.pdf"
TEST_PPT_NAME = "saaspose_test.ppt"
TEST_DOC_NAME = "saaspose_test.doc"
TEST_XLS_NAME = "saaspose_test.xls"
describe Saaspose do

before(:all) do
configure_client
Expand All @@ -21,8 +12,10 @@
end

context "pdf" do
it "should generate a png from a remote pdf", :vcr => true do
Saaspose::Pdf.convert(TEST_PDF_NAME, PNG_PATH, 'png', '1', '800', '600')
let(:page_number) { 1 }

it "should generate a png from a page of a remote pdf", :vcr => true do
Saaspose::Pdf.convert(TEST_PDF_NAME, PNG_PATH, page_number)
File.exists?(PNG_PATH).should be_true
end

Expand All @@ -33,14 +26,14 @@

context "slides" do
it "should generate a pdf from a remote ppt", :vcr => true do
Saaspose::Slides.convert(TEST_PPT_NAME, PDF_PATH, 'pdf')
Saaspose::Slides.convert(TEST_PPT_NAME, PDF_PATH)
File.exists?(PDF_PATH).should be_true
end
end

context "words" do
it "should generate a pdf from a remote doc", :vcr => true do
Saaspose::Words.convert(TEST_DOC_NAME, PDF_PATH, 'pdf')
Saaspose::Words.convert(TEST_DOC_NAME, PDF_PATH)
File.exists?(PDF_PATH).should be_true
end
end
Expand All @@ -53,52 +46,18 @@
end

context "storage" do
let(:folder) { Saaspose::Storage::File.new("test", true, Time.at(1334562314), 0) }
let(:folder) { Saaspose::Storage::RemoteFile.new("test", true, Time.at(1334562314), 0) }

it "should upload a file to the root dir", :vcr => true do
resp = Saaspose::Storage.upload(fixture_path(TEST_PDF_NAME), REMOTE_ROOT_DIR)
resp.should match("<Status>OK</Status>")
resp.should match("{\"Code\":200,\"Status\":\"OK\"}")
end

it "should get a list of files from the root dir", :vcr => true do
files = Saaspose::Storage.files(REMOTE_ROOT_DIR)
files.first.should be_an_instance_of(Saaspose::Storage::File)
files.first.should be_an_instance_of(Saaspose::Storage::RemoteFile)
files.map(&:name).should include(TEST_PDF_NAME)
files.first.should eql(folder)
end
end

context "utils" do
before(:each) do
Saaspose::Configuration.configure do |config|
config.app_sid = "SAASPOSE_APPSID"
config.app_key = "SAASPOSE_APPKEY"
end
end

let(:url) { "http://example.com/path?uschi=true&a_param=yes" }
it "should sign a uri" do
Saaspose::Utils.sign(url).should eql("http://example.com/path?uschi=true&a_param=yes&appSID=SAASPOSE_APPSID&signature=zl%2BjolbjggyKZ31QgflGVILu%2F0I")
end
end
end

def configure_client
Saaspose::Configuration.configure do |config|
config.app_sid = ENV["SAASPOSE_APPSID"]
config.app_key = ENV["SAASPOSE_APPKEY"]
end
end

def ensure_remote_file(test_file)
VCR.use_cassette("ensure_remote_file #{test_file}", :record => :new_episodes, :match_requests_on => [:host, :path]) do
unless Saaspose::Storage.files.map(&:name).include?(test_file)
puts "uploading #{test_file} for testing purposes"
Saaspose::Storage.upload(fixture_path(test_file), REMOTE_ROOT_DIR)
end
end
end

def fixture_path(name)
File.expand_path("../fixtures/#{name}", File.dirname(__FILE__))
end

0 comments on commit 129799e

Please sign in to comment.