Added example.
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
class DocumentHelper
|
||||
|
||||
@@runtime_cache = {}
|
||||
@@remote_ip = nil
|
||||
@@base_url = nil
|
||||
|
||||
class << self
|
||||
|
||||
def init (ip, url)
|
||||
@@remote_ip = ip
|
||||
@@base_url = url
|
||||
end
|
||||
|
||||
def file_size_max
|
||||
if Rails.configuration.fileSizeMax == nil
|
||||
5 * 1024 * 1024
|
||||
else
|
||||
Rails.configuration.fileSizeMax
|
||||
end
|
||||
end
|
||||
|
||||
def file_exts
|
||||
[].concat(viewed_exts).concat(edited_exts).concat(convert_exts)
|
||||
end
|
||||
|
||||
def viewed_exts
|
||||
if Rails.configuration.viewedDocs.empty?
|
||||
[]
|
||||
else
|
||||
Rails.configuration.viewedDocs.split("|")
|
||||
end
|
||||
end
|
||||
|
||||
def edited_exts
|
||||
if Rails.configuration.editedDocs.empty?
|
||||
[]
|
||||
else
|
||||
Rails.configuration.editedDocs.split("|")
|
||||
end
|
||||
end
|
||||
|
||||
def convert_exts
|
||||
if Rails.configuration.convertDocs.empty?
|
||||
[]
|
||||
else
|
||||
Rails.configuration.convertDocs.split("|")
|
||||
end
|
||||
end
|
||||
|
||||
def cur_user_host_address(user_address)
|
||||
(user_address == nil ? @@remote_ip : user_address).gsub(/[^0-9-.a-zA-Z_=]/, '_');
|
||||
end
|
||||
|
||||
def storage_path(file_name, user_address)
|
||||
directory = Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address))
|
||||
|
||||
unless File.directory?(directory)
|
||||
FileUtils.mkdir_p(directory)
|
||||
end
|
||||
|
||||
directory.join(file_name).to_s
|
||||
end
|
||||
|
||||
def get_correct_name(file_name)
|
||||
ext = File.extname(file_name)
|
||||
base_name = File.basename(file_name, ext)
|
||||
name = base_name + ext
|
||||
index = 1
|
||||
|
||||
while File.exist?(storage_path(name, nil))
|
||||
name = base_name + ' (' + index.to_s + ')' + ext
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
name
|
||||
end
|
||||
|
||||
def create_demo(file_ext)
|
||||
demo_name = 'sample.' + file_ext
|
||||
file_name = get_correct_name demo_name
|
||||
src = Rails.root.join('public', 'samples', demo_name)
|
||||
dest = storage_path file_name, nil
|
||||
|
||||
FileUtils.cp src, dest
|
||||
|
||||
file_name
|
||||
end
|
||||
|
||||
def get_file_uri(file_name)
|
||||
uri = @@base_url + '/' + Rails.configuration.storagePath + '/' + cur_user_host_address(nil) + '/' + URI::encode(file_name)
|
||||
|
||||
if Rails.configuration.haveExternalIp
|
||||
return uri
|
||||
end
|
||||
|
||||
get_external_uri(uri)
|
||||
end
|
||||
|
||||
def get_callback(file_name)
|
||||
|
||||
@@base_url + '/track?type=track&userAddress=' + cur_user_host_address(nil) + '&fileName=' + URI::encode(file_name)
|
||||
|
||||
end
|
||||
|
||||
def get_external_uri(local_uri)
|
||||
|
||||
begin
|
||||
uri = @@runtime_cache[local_uri]
|
||||
|
||||
if uri == nil
|
||||
|
||||
file_name = URI::decode(File.basename(local_uri))
|
||||
file_storage_path = DocumentHelper.storage_path(file_name, nil)
|
||||
data = File.open(file_storage_path, 'rb') {|io| io.read}
|
||||
|
||||
key = ServiceConverter.generate_revision_id(local_uri)
|
||||
uri = ServiceConverter.get_external_uri(data, data.length, nil, key)
|
||||
|
||||
@@runtime_cache[local_uri] = uri
|
||||
|
||||
end
|
||||
|
||||
return uri
|
||||
|
||||
rescue => ex
|
||||
raise ex.message
|
||||
end
|
||||
|
||||
local_uri
|
||||
end
|
||||
|
||||
def get_internal_extension(file_type)
|
||||
|
||||
case file_type
|
||||
when 'text'
|
||||
ext = '.docx'
|
||||
when 'spreadsheet'
|
||||
ext = '.xlsx'
|
||||
when 'presentation'
|
||||
ext = '.pptx'
|
||||
else
|
||||
ext = '.docx'
|
||||
end
|
||||
|
||||
ext
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
class FileModel
|
||||
|
||||
attr_accessor :file_name, :mode, :user_ip
|
||||
|
||||
def initialize(attributes = {})
|
||||
@file_name = attributes[:file_name]
|
||||
@mode = attributes[:mode]
|
||||
@user_ip = attributes[:user_ip]
|
||||
end
|
||||
|
||||
def desktop_type
|
||||
@mode != 'embedded'
|
||||
end
|
||||
|
||||
def file_ext
|
||||
File.extname(@file_name)
|
||||
end
|
||||
|
||||
def file_uri
|
||||
DocumentHelper.get_file_uri(@file_name)
|
||||
end
|
||||
|
||||
def document_type
|
||||
FileUtility.get_file_type(@file_name)
|
||||
end
|
||||
|
||||
def key
|
||||
uri = DocumentHelper.cur_user_host_address(nil) + '/' + @file_name
|
||||
ServiceConverter.generate_revision_id(uri)
|
||||
end
|
||||
|
||||
def validate_key
|
||||
ServiceConverter.generate_validate_key(key, @user_ip)
|
||||
end
|
||||
|
||||
def callback_url
|
||||
DocumentHelper.get_callback(@file_name)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
class FileUtility
|
||||
|
||||
@@exts_document = %w(.docx .doc .odt .rtf .txt .html .htm .mht .pdf .djvu .fb2 .epub .xps)
|
||||
|
||||
@@exts_spreadsheet = %w(.xls .xlsx .ods .csv)
|
||||
|
||||
@@exts_presentation = %w(.ppt .pptx .odp)
|
||||
|
||||
class << self
|
||||
|
||||
def get_file_type(file_name)
|
||||
ext = File.extname(file_name)
|
||||
|
||||
if @@exts_document.include? ext
|
||||
return 'text'
|
||||
end
|
||||
|
||||
if @@exts_spreadsheet.include? ext
|
||||
return 'spreadsheet'
|
||||
end
|
||||
|
||||
if @@exts_presentation.include? ext
|
||||
return 'presentation'
|
||||
end
|
||||
|
||||
'text'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,248 @@
|
||||
class ServiceConverter
|
||||
|
||||
@@convert_timeout = Rails.configuration.timeout
|
||||
@@document_converter_url = Rails.configuration.urlConverter
|
||||
@@document_storage_url = Rails.configuration.urlStorage
|
||||
@@convert_params = '?url=%s&outputtype=%s&filetype=%s&title=%s&key=%s&vkey=%s'
|
||||
@@max_try = 3
|
||||
|
||||
class << self
|
||||
|
||||
def get_converted_uri(document_uri, from_ext, to_ext, document_revision_id, is_async)
|
||||
converted_document_uri = nil
|
||||
responce_from_convert_service = send_request_to_convert_service(document_uri, from_ext, to_ext, document_revision_id, is_async)
|
||||
|
||||
file_result = responce_from_convert_service['FileResult']
|
||||
|
||||
error_element = file_result['Error']
|
||||
if error_element != nil
|
||||
process_convert_service_responce_error(error_element.to_i)
|
||||
end
|
||||
|
||||
is_end_convert = file_result['EndConvert'].downcase == 'true'
|
||||
percent = file_result['Percent'].to_i
|
||||
|
||||
if is_end_convert
|
||||
converted_document_uri = file_result['FileUrl']
|
||||
percent = 100
|
||||
else
|
||||
percent = percent >= 100 ? 99 : percent;
|
||||
end
|
||||
|
||||
return percent, converted_document_uri
|
||||
end
|
||||
|
||||
def get_external_uri(content, content_length, content_type, document_revision_id)
|
||||
|
||||
validate_key = generate_validate_key(document_revision_id, nil)
|
||||
|
||||
url_to_storage = @@document_storage_url + (@@convert_params % ['', '', '', '', document_revision_id, validate_key])
|
||||
|
||||
if content_type == nil
|
||||
content_type = 'application/octet-stream'
|
||||
end
|
||||
|
||||
uri = URI.parse(url_to_storage)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
|
||||
if url_to_storage.start_with?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
end
|
||||
|
||||
req = Net::HTTP::Post.new(uri.request_uri, {'Content-Type' => content_type , 'Content-Length' => content_length.to_s })
|
||||
req.body = content
|
||||
res = http.request(req)
|
||||
data = res.body
|
||||
|
||||
if data == nil
|
||||
raise 'Could not get an answer'
|
||||
end
|
||||
|
||||
document_response = Hash.from_xml(data.gsub('\n', ''))
|
||||
percent, external_uri = get_response_uri(document_response)
|
||||
|
||||
external_uri
|
||||
|
||||
end
|
||||
|
||||
def generate_revision_id(expected_key)
|
||||
|
||||
require 'zlib'
|
||||
|
||||
if expected_key.length > 20
|
||||
expected_key = (Zlib.crc32 expected_key).to_s
|
||||
end
|
||||
|
||||
key = expected_key.gsub(/[^0-9a-zA-Z.=]/, '_')
|
||||
key[(key.length - [key.length, 20].min)..key.length]
|
||||
|
||||
end
|
||||
|
||||
def generate_validate_key(document_revision_id, user_ip)
|
||||
|
||||
if document_revision_id == nil
|
||||
return ''
|
||||
end
|
||||
|
||||
expire = Time.now.to_i * 1000
|
||||
key = generate_revision_id(document_revision_id)
|
||||
key_id = get_key
|
||||
user_count = '0'
|
||||
ip = user_ip != nil ? '' : user_ip
|
||||
|
||||
key = '{"expire": "\/Date(%s)\/", "key" : "%s", "key_id" : "%s", "user_count" : %s, "ip" : "%s"}' %
|
||||
[expire.to_s, key.to_s, key_id.to_s, user_count, ip]
|
||||
|
||||
Signature.create(key, get_skey)
|
||||
|
||||
end
|
||||
|
||||
def get_key
|
||||
|
||||
Rails.configuration.tenantId
|
||||
|
||||
end
|
||||
|
||||
def get_skey
|
||||
|
||||
Rails.configuration.key
|
||||
|
||||
end
|
||||
|
||||
def send_request_to_convert_service(document_uri, from_ext, to_ext, document_revision_id, is_async)
|
||||
|
||||
from_ext = from_ext == nil ? File.extname(document_uri) : from_ext
|
||||
|
||||
title = File.basename(URI.parse(document_uri).path)
|
||||
title = title == nil ? UUID.generate.to_s : title
|
||||
|
||||
document_revision_id = document_revision_id.empty? ? document_uri : document_revision_id
|
||||
document_revision_id = generate_revision_id(document_revision_id)
|
||||
|
||||
validate_key = generate_validate_key(document_revision_id, nil)
|
||||
|
||||
url_to_converter = @@document_converter_url +
|
||||
(@@convert_params % [URI::encode(document_uri), to_ext.delete('.'), from_ext.delete('.'), title, document_revision_id, validate_key])
|
||||
|
||||
if is_async
|
||||
url_to_converter += '&async=true'
|
||||
end
|
||||
|
||||
data = nil
|
||||
count_try = 0
|
||||
|
||||
while count_try < @@max_try
|
||||
begin
|
||||
count_try += 1
|
||||
|
||||
uri = URI.parse(url_to_converter)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
|
||||
if url_to_converter.start_with?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
end
|
||||
|
||||
http.read_timeout = @@convert_timeout
|
||||
req = Net::HTTP::Get.new(uri.request_uri)
|
||||
res = http.request(req)
|
||||
data = res.body
|
||||
|
||||
break
|
||||
rescue TimeoutError
|
||||
#try again
|
||||
rescue => ex
|
||||
raise ex.message
|
||||
end
|
||||
end
|
||||
|
||||
if count_try == @@max_try && data == nil
|
||||
raise 'timeout'
|
||||
end
|
||||
|
||||
Hash.from_xml(data.gsub('\n', ''))
|
||||
|
||||
end
|
||||
|
||||
def process_convert_service_responce_error(error_code)
|
||||
|
||||
error_message = 'unknown error'
|
||||
|
||||
case error_code
|
||||
when -8
|
||||
error_message = 'Error occurred in the ConvertService.ashx: Error document VKey'
|
||||
when -7
|
||||
error_message = 'Error occurred in the ConvertService.ashx: Error document request'
|
||||
when -6
|
||||
error_message = 'Error occurred in the ConvertService.ashx: Error database'
|
||||
when -5
|
||||
error_message = 'Error occurred in the ConvertService.ashx: Error unexpected guid'
|
||||
when -4
|
||||
error_message = 'Error occurred in the ConvertService.ashx: Error download error'
|
||||
when -3
|
||||
error_message = 'Error occurred in the ConvertService.ashx: Error convertation error'
|
||||
when -2
|
||||
error_message = 'Error occurred in the ConvertService.ashx: Error convertation timeout'
|
||||
when -1
|
||||
error_message = 'Error occurred in the ConvertService.ashx: Error convertation unknown'
|
||||
when 0
|
||||
#public const int c_nErrorNo = 0
|
||||
else
|
||||
error_message = 'ErrorCode = ' + error_code.to_s
|
||||
end
|
||||
|
||||
raise error_message
|
||||
|
||||
end
|
||||
|
||||
def get_response_uri(document_response)
|
||||
|
||||
file_result = document_response['FileResult']
|
||||
if file_result == nil
|
||||
raise 'Invalid answer format'
|
||||
end
|
||||
|
||||
error_element = file_result['Error']
|
||||
if error_element != nil
|
||||
process_convert_service_responce_error(error_element.to_i)
|
||||
end
|
||||
|
||||
end_convert_element = file_result['EndConvert']
|
||||
if end_convert_element == nil
|
||||
raise 'Invalid answer format'
|
||||
end
|
||||
is_end_convert = end_convert_element.downcase == 'true'
|
||||
|
||||
result_percent = 0
|
||||
response_uri = ''
|
||||
|
||||
if is_end_convert
|
||||
|
||||
file_url_element = file_result['FileUrl']
|
||||
|
||||
if file_url_element == nil
|
||||
raise 'Invalid answer format'
|
||||
end
|
||||
|
||||
response_uri = file_url_element
|
||||
result_percent = 100
|
||||
|
||||
else
|
||||
|
||||
percent_element = file_result['Percent']
|
||||
|
||||
if percent_element != nil
|
||||
result_percent = percent_element.to_i
|
||||
end
|
||||
|
||||
result_percent = result_percent >= 100 ? 99 : result_percent
|
||||
|
||||
end
|
||||
|
||||
return result_percent, response_uri
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,43 @@
|
||||
class Signature
|
||||
|
||||
class << self
|
||||
|
||||
def create(key, secret)
|
||||
|
||||
#secret = '_ContactUs_'
|
||||
#key = '{"expire":"\/Date(1422449303583)\/","key":"mo.docx1422449303571","key_id":"_ContactUs_","user_count":0}'
|
||||
|
||||
payload = get_hash_base64(key + secret) + '?' + key
|
||||
encode = url_token_encode(payload)
|
||||
|
||||
end
|
||||
|
||||
def get_hash_base64(str)
|
||||
|
||||
utf8 = str.encode('utf-8')
|
||||
sha256 = Digest::SHA256.digest(utf8)
|
||||
base64 = Base64.strict_encode64(sha256)
|
||||
|
||||
end
|
||||
|
||||
def url_token_encode(str)
|
||||
|
||||
utf8 = str.encode('utf-8')
|
||||
base64 = Base64.strict_encode64(utf8)
|
||||
|
||||
cnt = 0
|
||||
base64.each_char {|c|
|
||||
if c == '='
|
||||
cnt += 1
|
||||
end
|
||||
}
|
||||
|
||||
signature = base64.gsub('=', '') + cnt.to_s
|
||||
signature = signature.gsub('+', '-').gsub('/', '_')
|
||||
signature = URI.encode(signature)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user