filestack 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ task :console do
9
+ exec 'irb -r filestack/filestack -I ./lib'
10
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "filestack/ruby"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ puts lib
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "filestack/ruby/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "filestack"
9
+ spec.version = Filestack::Ruby::VERSION
10
+ spec.authors = ["Filestack"]
11
+ spec.email = ["dev@filestack.com"]
12
+
13
+ spec.summary = %q{Official Ruby SDK for the Filestack API}
14
+ spec.description = %q{This is the official Ruby SDK for Filestack - API and content management system that makes it easy to add powerful file uploading and transformation capabilities to any web or mobile application.}
15
+ spec.homepage = "https://github.com/filestack/filestack-ruby"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features|test-files)/})
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_dependency "unirest", "~> 1.1.2"
26
+ spec.add_dependency "parallel", "~> 1.11.2"
27
+ spec.add_dependency "mimemagic", "~> 0.3.2"
28
+
29
+ spec.add_development_dependency "bundler", "~> 1.15"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ spec.add_development_dependency "rspec", "~> 3.0"
32
+ spec.add_development_dependency "simplecov", "~> 0.14"
33
+ end
@@ -0,0 +1,5 @@
1
+ require 'filestack/models/filelink'
2
+ require 'filestack/models/filestack_client'
3
+ require 'filestack/models/filestack_security'
4
+ require 'filestack/utils/utils'
5
+ require 'filestack/models/filestack_transform'
@@ -0,0 +1,36 @@
1
+ require 'filestack/ruby/version'
2
+
3
+ include Filestack
4
+
5
+ class FilestackConfig
6
+ API_URL = 'https://www.filestackapi.com/api'.freeze
7
+ CDN_URL = 'https://cdn.filestackcontent.com'.freeze
8
+ PROCESS_URL = 'https://process.filestackapi.com'.freeze
9
+
10
+ MULTIPART_START_URL = 'https://upload.filestackapi.com/multipart/start'.freeze
11
+ MULTIPART_UPLOAD_URL = 'https://upload.filestackapi.com/multipart/upload'.freeze
12
+ MULTIPART_COMPLETE_URL = 'https://upload.filestackapi.com/multipart/complete'.freeze
13
+
14
+ MULTIPART_PARAMS = %w[
15
+ store_location store_region store_container
16
+ store_path store_access
17
+ ].freeze
18
+
19
+ DEFAULT_CHUNK_SIZE = 5 * 1024**2
20
+ VERSION = Filestack::Ruby::VERSION
21
+ HEADERS = {
22
+ 'User-Agent' => "filestack-ruby #{VERSION}",
23
+ 'Filestack-Source' => "Ruby-#{VERSION}"
24
+ }.freeze
25
+ end
26
+
27
+ class TransformConfig
28
+ TRANSFORMATIONS = %w[
29
+ resize crop rotate flip flop watermark detect_faces
30
+ crop_faces pixelate_faces round_corners vignette polaroid
31
+ torn_edges shadow circle border sharpen blur monochrome
32
+ blackwhite sepia pixelate oil_paint negative modulate
33
+ partial_pixelate partial_blur collage upscale enhance
34
+ redeye ascii filetype_conversion quality
35
+ ].freeze
36
+ end
@@ -0,0 +1,93 @@
1
+ require 'filestack/config'
2
+ require 'filestack/utils/utils'
3
+ require 'filestack/utils/multipart_upload_utils'
4
+ require 'mimemagic'
5
+
6
+ # Module is mixin for common functionalities that all Filestack
7
+ # objects can call.
8
+ module FilestackCommon
9
+ include UploadUtils
10
+ # Get the contents of a Filestack handle
11
+ #
12
+ # @param [String] file_handle The Filelink handle
13
+ # @param [FilestackSecurity] security Optional Filestack security object
14
+ # if security is enabled
15
+ #
16
+ # @return [Bytes]
17
+ def send_get_content(url, parameters: nil)
18
+ UploadUtils.make_call(url, 'get', parameters: parameters)
19
+ end
20
+
21
+ # Get the content of a filehandle
22
+ #
23
+ # @param [String] filepath Local path of file to be written
24
+ #
25
+ # @return [Int] Size of file written
26
+ def send_download(filepath)
27
+ content = send_get_content(url)
28
+ File.write(filepath, content.body)
29
+ end
30
+
31
+ # Send the delete api request to delete a filelink
32
+ #
33
+ # @param [String] url The url of the Filehandle
34
+ # to be deleted (includes security)
35
+ #
36
+ # @return [unirest::Response]
37
+ def send_delete(handle, apikey, security)
38
+ return 'Delete requires security' if security.nil?
39
+ signature = security.signature
40
+ policy = security.policy
41
+ base = "#{FilestackConfig::API_URL}/file"
42
+ UploadUtils.make_call(
43
+ "#{base}/#{handle}?key=#{apikey}&signature=#{signature}&policy=#{policy}",
44
+ 'delete'
45
+ )
46
+ end
47
+
48
+ # Send the overwrite api request to update a filelink
49
+ #
50
+ # @param [String] filepath Filepath of file to upload
51
+ # @param [String] handle The Filelink handle
52
+ # @param [String] apikey Filestack API Key
53
+ # @param [FilestackSecurity] security Filestack security object
54
+ #
55
+ # @return [Typhoeus::Response]
56
+ def send_overwrite(filepath, handle, apikey, security)
57
+ return 'Overwrite requires security' if security.nil?
58
+
59
+ file = File.open(filepath, 'r')
60
+ mimetype = MimeMagic.by_magic(file)
61
+ content = file.read
62
+
63
+ signature = security.signature
64
+ policy = security.policy
65
+
66
+ headers = { 'Content-Type' => mimetype }
67
+ base = "#{FilestackConfig::API_URL}/file"
68
+
69
+ UploadUtils.make_call(
70
+ "#{base}/#{handle}?key=#{apikey}&signature=#{signature}&policy=#{policy}",
71
+ 'put',
72
+ headers: headers,
73
+ parameters: content
74
+ )
75
+ end
76
+
77
+ # Get tags or sfw content from a filelink
78
+ #
79
+ # @param [String] task 'tags' or 'sfw'
80
+ # @param [String] handle The filehandle
81
+ # @param [Filestack::Security] security Security object
82
+ #
83
+ # @return [Hash]
84
+ def send_tags(task, handle, security)
85
+ raise 'You must use security for tags' if security.nil?
86
+
87
+ policy = security.policy
88
+ signature = security.signature
89
+ url = "#{FilestackConfig::CDN_URL}/#{task}/"\
90
+ "security=signature:#{signature},policy:#{policy}/#{handle}"
91
+ UploadUtils.make_call(url, 'get').body[task]
92
+ end
93
+ end
@@ -0,0 +1,89 @@
1
+ require 'filestack/ruby/version'
2
+ require 'filestack/config'
3
+ require 'filestack/utils/utils'
4
+ require 'filestack/models/filestack_transform'
5
+ require 'filestack/mixins/filestack_common'
6
+
7
+ # This class represents a file stored on your Filestack
8
+ # storage. Once initialized, you may perform transformations, conversions,
9
+ # get metadata, update, or delete it.
10
+ class Filelink
11
+ include FilestackCommon
12
+ include UploadUtils
13
+ attr_reader :handle, :apikey, :security
14
+
15
+ # Initialize Filelink
16
+ #
17
+ # @param [String] file_handle The Filelink handle
18
+ # @param [String] apikey Your Filestack API Key (optional)
19
+ # @param [FilestackSecurity] security Filestack security object, if
20
+ # security is enabled.
21
+ def initialize(handle, apikey: nil, security: nil)
22
+ @handle = handle
23
+ @apikey = apikey
24
+ @security = security
25
+ end
26
+
27
+ # Get content of filelink
28
+ #
29
+ # @return [Bytes]
30
+ def get_content
31
+ send_get_content(url)
32
+ end
33
+
34
+ # Download Filelink
35
+ #
36
+ # @param [String] filepath The local destination of the
37
+ # downloaded filelink
38
+ # @return [Unirest::Response]
39
+ def download(filepath)
40
+ send_download(filepath)
41
+ end
42
+
43
+ # Delete filelink
44
+ #
45
+ # @return [Unirest::Response]
46
+ def delete
47
+ send_delete(handle, apikey, security)
48
+ end
49
+
50
+ # Ovewrite filelink by uploading local file
51
+ #
52
+ # @param [String] filepath filepath of file to upload
53
+ #
54
+ # @return [Unirest::Response]
55
+ def overwrite(filepath)
56
+ send_overwrite(filepath, handle, apikey, security)
57
+ end
58
+
59
+ # Turn the filelink into a transform object to perform
60
+ # transform operations
61
+ #
62
+ # @return [Filestack::Transform]
63
+ def transform
64
+ Transform.new(handle: @handle, apikey: @apikey, security: @security)
65
+ end
66
+
67
+ # Return auto and user tags for the filelink
68
+ #
69
+ # @return [Hash]
70
+ def tags
71
+ send_tags('tags', @handle, @security)
72
+ end
73
+
74
+ # Return true (SFW) or false (NSFW)
75
+ #
76
+ # @return [Bool]
77
+ def sfw
78
+ send_tags('sfw', @handle, @security)
79
+ end
80
+
81
+ # Get the URL of the Filelink
82
+ #
83
+ # @return [String]
84
+ def url
85
+ UploadUtils.get_url(
86
+ FilestackConfig::CDN_URL, handle: handle, security: security
87
+ )
88
+ end
89
+ end
@@ -0,0 +1,32 @@
1
+ require 'filestack/models/filelink'
2
+ require 'filestack/utils/utils'
3
+
4
+ # Class for AV objects -- allows to check status
5
+ # and upgrade to filelink once completed
6
+ class AV
7
+ include UploadUtils
8
+ attr_reader :apikey, :security
9
+
10
+ def initialize(url, apikey: nil, security: nil)
11
+ @url = url
12
+ @apikey = apikey
13
+ @security = security
14
+ end
15
+
16
+ # Turns AV into filelink if video conversion is complete
17
+ #
18
+ # @return [Filestack::Filelink]
19
+ def to_filelink
20
+ return 'Video conversion incomplete' unless status == 'completed'
21
+ response = UploadUtils.make_call(@url, 'get').body
22
+ handle = response['data']['url'].split('/').last
23
+ Filelink.new(handle, apikey: @apikey, security: @security)
24
+ end
25
+
26
+ # Checks the status of the video conversion
27
+ #
28
+ # @return [String]
29
+ def status
30
+ UploadUtils.make_call(@url, 'get').body['status']
31
+ end
32
+ end
@@ -0,0 +1,55 @@
1
+ require 'filestack/utils/multipart_upload_utils'
2
+ require 'filestack/models/filestack_transform'
3
+ require 'filestack/utils/utils'
4
+ require './lib/filestack/'
5
+
6
+ # The Filestack Client class acts as a hub for all
7
+ # Filestack actions that do not require a file handle, including
8
+ # uploading files (both local and external), initiating an external
9
+ # transformation, and other tasks
10
+ class Client
11
+ include MultipartUploadUtils
12
+ include UploadUtils
13
+ attr_reader :apikey, :security
14
+
15
+ # Initialize Client
16
+ #
17
+ # @param [String] apikey Your Filestack API key
18
+ # @param [FilestackSecurity] security A Filestack security object,
19
+ # if security is enabled
20
+ def initialize(apikey, security: nil)
21
+ @apikey = apikey
22
+ @security = security
23
+ end
24
+
25
+ # Upload a local file or external url
26
+ # @param [String] filepath The path of a local file
27
+ # @param [String] external_url An external URL
28
+ # @param [Bool] multipart Switch for miltipart
29
+ # (Default: true)
30
+ # @param [Hash] options User-supplied upload options
31
+ #
32
+ # return [Filestack::Filelink]
33
+ def upload(filepath: nil, external_url: nil, multipart: true, options: nil, storage: 's3')
34
+ if filepath && external_url
35
+ return 'You cannot upload a URL and file at the same time'
36
+ end
37
+ response = if filepath && multipart
38
+ multipart_upload(@apikey, filepath, @security, options)
39
+ else
40
+ send_upload(
41
+ @apikey,
42
+ filepath: filepath,
43
+ external_url: external_url,
44
+ options: options,
45
+ security: @security,
46
+ storage: storage
47
+ )
48
+ end
49
+ Filelink.new(response['handle'], security: @security, apikey: @apikey)
50
+ end
51
+
52
+ def transform_external(external_url)
53
+ Transform.new(external_url: external_url, security: @security, apikey: @apikey)
54
+ end
55
+ end
@@ -0,0 +1,82 @@
1
+ require 'base64'
2
+ require 'json'
3
+ require 'openssl'
4
+
5
+ #
6
+ # This class represents a Filestack Security object that you must passed
7
+ # in with your calls if your account has security enabled. You can manage
8
+ # your Filestack app's security and secret by logging into the Filestack
9
+ # Dev portal.
10
+ #
11
+ class FilestackSecurity
12
+ DEFAULT_EXPIRY = 3600
13
+
14
+ attr_accessor :policy, :signature
15
+
16
+ # Initialize FilestackSecurity object
17
+ #
18
+ # @param [String] secret Your filestack security secret
19
+ # @param [Hash] options Hash of options:
20
+ # call: The calls that you allow this policy to
21
+ # make, e.g convert, exif, pick, read, remove,
22
+ # stat, store, write, writeUrl
23
+ # container: (regex) store must match container
24
+ # that the files will be stored under
25
+ # expiry: (timestamp) epoch_timestamp expire,
26
+ # defaults to 1hr
27
+ # handle: specific file this policy can access
28
+ # maxSize: (number) maximum file size in bytes
29
+ # that can be stored by requests with policy
30
+ # minSize: (number) minimum file size in bytes
31
+ # that can be stored by requests with policy
32
+ # path: (regex) store must match the path that
33
+ # the files will be stored under.
34
+ # url: (regex) subset of external URL domains
35
+ # that are allowed to be image/document
36
+ # sources for processing
37
+ def initialize(secret, options: {})
38
+ generate(secret, options)
39
+ end
40
+
41
+ # Generate the security policy and signature given a string and options
42
+ #
43
+ # @param [String] secret Your filestack security secret
44
+ # @param [Hash] options Hash of options - see constructor
45
+ def generate(secret, options)
46
+ policy_json = create_policy_string(options)
47
+ @policy = Base64.urlsafe_encode64(policy_json)
48
+ @signature = OpenSSL::HMAC.hexdigest('sha256', secret, policy)
49
+ end
50
+
51
+ # Sign the URL by appending policy and signature URL parameters
52
+ #
53
+ # @param [String] url The URL to sign
54
+ #
55
+ # @return [String]
56
+ def sign_url(url)
57
+ format('%s&policy=%s&signature=%s', url, policy, signature)
58
+ end
59
+
60
+ private
61
+
62
+ #
63
+ # Manage options and convert hash to json string
64
+ #
65
+ def create_policy_string(options)
66
+ options[:expiry] = expiry_timestamp(options)
67
+ options.to_json
68
+ end
69
+
70
+ #
71
+ # Get expiration timestamp by adding seconds in option or using default
72
+ #
73
+ def expiry_timestamp(options)
74
+ expiry_time = if options.key?(:expiry)
75
+ options[:expiry]
76
+ else
77
+ FilestackSecurity::DEFAULT_EXPIRY
78
+ end
79
+
80
+ Time.now.to_i + expiry_time
81
+ end
82
+ end