paperclip-azure 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 71d1e2806cadeb22414cdd7bacba0f7158a1e1c4
4
+ data.tar.gz: c9999f06aff5f07d0df7abfd232ccad3e2a38ab1
5
+ SHA512:
6
+ metadata.gz: 27395952b0f12f5a64ed397f56dbec348a9671081737d4519bc474d8bd0932ac7017b59b67dda19dd0c84add00c48fd2822844c3efa49fec79c54fc7fd2bbbfd
7
+ data.tar.gz: acc6d1af9f93acc8fcb89e7424b0c113d67dbe71ea78951fa61aa91150c4f3651bb630f0f172bc6cb5e92c7d0fbabd3f9b477a933e2a9caa18a1a7c55c0acb6c
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'azure'
4
+ gem 'hashie', require: false
5
+ gem 'addressable', require: false
6
+
7
+ group :development do
8
+ gem "rspec", "~> 2.8.0"
9
+ gem "yard", "~> 0.7"
10
+ gem "rdoc", "~> 3.12"
11
+ gem "bundler", "~> 1.0"
12
+ gem "jeweler", "~> 2.0.1"
13
+ gem "simplecov", ">= 0"
14
+ end
@@ -0,0 +1,90 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.6)
5
+ azure (0.6.4)
6
+ json (~> 1.8)
7
+ mime-types (~> 1.0)
8
+ nokogiri (~> 1.5)
9
+ systemu (~> 2.6)
10
+ uuid (~> 2.0)
11
+ builder (3.2.2)
12
+ descendants_tracker (0.0.4)
13
+ thread_safe (~> 0.3, >= 0.3.1)
14
+ diff-lcs (1.1.3)
15
+ docile (1.1.5)
16
+ faraday (0.9.0)
17
+ multipart-post (>= 1.2, < 3)
18
+ git (1.2.8)
19
+ github_api (0.12.1)
20
+ addressable (~> 2.3)
21
+ descendants_tracker (~> 0.0.4)
22
+ faraday (~> 0.8, < 0.10)
23
+ hashie (>= 3.2)
24
+ multi_json (>= 1.7.5, < 2.0)
25
+ nokogiri (~> 1.6.3)
26
+ oauth2
27
+ hashie (3.3.1)
28
+ highline (1.6.21)
29
+ jeweler (2.0.1)
30
+ builder
31
+ bundler (>= 1.0)
32
+ git (>= 1.2.5)
33
+ github_api
34
+ highline (>= 1.6.15)
35
+ nokogiri (>= 1.5.10)
36
+ rake
37
+ rdoc
38
+ json (1.8.1)
39
+ jwt (1.0.0)
40
+ macaddr (1.7.1)
41
+ systemu (~> 2.6.2)
42
+ mime-types (1.25.1)
43
+ mini_portile (0.6.0)
44
+ multi_json (1.10.1)
45
+ multi_xml (0.5.5)
46
+ multipart-post (2.0.0)
47
+ nokogiri (1.6.3.1)
48
+ mini_portile (= 0.6.0)
49
+ oauth2 (1.0.0)
50
+ faraday (>= 0.8, < 0.10)
51
+ jwt (~> 1.0)
52
+ multi_json (~> 1.3)
53
+ multi_xml (~> 0.5)
54
+ rack (~> 1.2)
55
+ rack (1.5.2)
56
+ rake (10.3.2)
57
+ rdoc (3.12.2)
58
+ json (~> 1.4)
59
+ rspec (2.8.0)
60
+ rspec-core (~> 2.8.0)
61
+ rspec-expectations (~> 2.8.0)
62
+ rspec-mocks (~> 2.8.0)
63
+ rspec-core (2.8.0)
64
+ rspec-expectations (2.8.0)
65
+ diff-lcs (~> 1.1.2)
66
+ rspec-mocks (2.8.0)
67
+ simplecov (0.9.0)
68
+ docile (~> 1.1.0)
69
+ multi_json
70
+ simplecov-html (~> 0.8.0)
71
+ simplecov-html (0.8.0)
72
+ systemu (2.6.4)
73
+ thread_safe (0.3.4)
74
+ uuid (2.3.7)
75
+ macaddr (~> 1.0)
76
+ yard (0.8.7.4)
77
+
78
+ PLATFORMS
79
+ ruby
80
+
81
+ DEPENDENCIES
82
+ addressable
83
+ azure
84
+ bundler (~> 1.0)
85
+ hashie
86
+ jeweler (~> 2.0.1)
87
+ rdoc (~> 3.12)
88
+ rspec (~> 2.8.0)
89
+ simplecov
90
+ yard (~> 0.7)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015 Jordan Yaker
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.
@@ -0,0 +1,19 @@
1
+ = paperclip-azure
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to paperclip-azure
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
+ * Fork the project.
10
+ * Start a feature/bugfix branch.
11
+ * Commit and push until you are happy with your contribution.
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2015 Jordan. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
+ gem.name = "paperclip-azure"
18
+ gem.homepage = "http://github.com/jordanyaker/paperclip-azure"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{An Azure Blob Storage implementation for Paperclip.}
21
+ gem.description = %Q{An Azure Blob Storage implementation for Paperclip.}
22
+ gem.email = "help@supportify.io"
23
+ gem.authors = ["Jordan Yaker"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ desc "Code coverage detail"
35
+ task :simplecov do
36
+ ENV['COVERAGE'] = "true"
37
+ Rake::Task['spec'].execute
38
+ end
39
+
40
+ task :default => :spec
41
+
42
+ require 'yard'
43
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,12 @@
1
+ if defined? Azure::Blob::BlobService
2
+ module Azure
3
+ module Blob
4
+ BlobService.class_eval do
5
+ def initialize(signer=Core::Auth::SharedKey.new, account_name=Azure.config.storage_account_name)
6
+ super(signer, account_name)
7
+ @host = "http://#{account_name}.blob.core.windows.net"
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,84 @@
1
+ # Adapted from the SharedAccessSignature class found in the Azure
2
+ # Extensions project by David Michael located at https://github.com/dmichael/azure-contrib
3
+
4
+ require 'hashie/dash'
5
+ require 'addressable/uri'
6
+
7
+ module Azure
8
+ module Core
9
+ module Auth
10
+ class SharedAccessSignature
11
+ class Version20130815 < Hashie::Dash
12
+ property :resource, default: 'c', required: true
13
+ property :permissions, default: 'r', required: true
14
+ property :start, default: ''
15
+ property :identifier, default: ''
16
+ property :expiry, required: true
17
+ property :canonicalized_resource, required: true
18
+ property :access_key, required: true
19
+ # Do not change this
20
+ property :version, default: '2103-08-15'
21
+ end
22
+
23
+ attr_accessor :uri, :options
24
+
25
+ def initialize(uri, options = {}, account = ENV['AZURE_STORAGE_ACCOUNT'])
26
+ # This is the uri that we are signing
27
+ @uri = Addressable::URI.parse(uri)
28
+
29
+ is_blob = options[:resource] == 'b'
30
+
31
+ # Create the options hash that will be turned into a query string
32
+ @options = Version20130815.new(options.merge(canonicalized_resource: canonicalized_resource(@uri, account, is_blob)))
33
+ end
34
+
35
+ # Create a "canonicalized resource" from the full uri to be signed
36
+ def canonicalized_resource(uri, account = ENV['AZURE_STORAGE_ACCOUNT'], is_blob = false)
37
+ path = uri.path # Addressable::URI
38
+ # There is only really one level deep for containers, the remainder is the BLOB key (that looks like a path)
39
+ path_array = path.split('/').reject {|p| p == ''}
40
+ container = path_array.shift
41
+
42
+ string = if is_blob
43
+ File.join('/', account, container, path_array.join('/'))
44
+ else
45
+ File.join('/', account, container)
46
+ end
47
+
48
+ string
49
+ end
50
+
51
+ # When creating the query string from the options, we only include the no-empty fields
52
+ # - this is opposed to the string that gets signed which includes them as blank.
53
+ def create_query_values(options = Version20130815.new)
54
+ # Parts
55
+ parts = {}
56
+ parts[:st] = URI.unescape(options[:start]) unless options[:start] == ''
57
+ parts[:se] = URI.unescape(options[:expiry])
58
+ parts[:sr] = URI.unescape(options[:resource])
59
+ parts[:sp] = URI.unescape(options[:permissions])
60
+ parts[:si] = URI.unescape(options[:identifier]) unless options[:identifier] == ''
61
+ parts[:sig] = URI.unescape( create_signature(options) )
62
+
63
+ parts
64
+ end
65
+
66
+ def create_signature(options = Version20130815)
67
+ string_to_sign = []
68
+ string_to_sign << options[:permissions]
69
+ string_to_sign << options[:start]
70
+ string_to_sign << options[:expiry]
71
+ string_to_sign << options[:canonicalized_resource]
72
+ string_to_sign << options[:identifier]
73
+
74
+ Azure::Core::Auth::Signer.new(options[:access_key]).sign(string_to_sign.join("\n").force_encoding("UTF-8"))
75
+ end
76
+
77
+ def sign
78
+ @uri.query_values = create_query_values(@options)
79
+ @uri.to_s
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,3 @@
1
+ require 'azure/blob/blob_service'
2
+ require 'azure/core/auth/shared_access_signature'
3
+ require 'paperclip/storage/azure'
@@ -0,0 +1,255 @@
1
+ module Paperclip
2
+ module Storage
3
+ # Azure's container file hosting service is a scalable, easy place to store files for
4
+ # distribution. You can find out more about it at http://azure.microsoft.com/en-us/services/storage/
5
+ #
6
+ # To use Paperclip with Azure, include the +azure+ gem in your Gemfile:
7
+ # gem 'azure'
8
+ # There are a few Azure-specific options for has_attached_file:
9
+ # * +azure_credentials+: Takes a path, a File, a Hash or a Proc. The path (or File) must point
10
+ # to a YAML file containing the +access_key+ and +storage_account+ that azure
11
+ # gives you. You can 'environment-space' this just like you do to your
12
+ # database.yml file, so different environments can use different accounts:
13
+ # development:
14
+ # storage_account_name: foo
15
+ # access_key: 123...
16
+ # test:
17
+ # storage_account_name: foo
18
+ # access_key: abc...
19
+ # production:
20
+ # storage_account_name: foo
21
+ # access_key: 456...
22
+ # This is not required, however, and the file may simply look like this:
23
+ # storage_account_name: foo
24
+ # access_key: 456...
25
+ # In which case, those access keys will be used in all environments. You can also
26
+ # put your container name in this file, instead of adding it to the code directly.
27
+ # This is useful when you want the same account but a different container for
28
+ # development versus production.
29
+ # When using a Proc it provides a single parameter which is the attachment itself. A
30
+ # method #instance is available on the attachment which will take you back to your
31
+ # code. eg.
32
+ # class User
33
+ # has_attached_file :download,
34
+ # :storage => :azure,
35
+ # :azure_credentials => Proc.new{|a| a.instance.azure_credentials }
36
+ #
37
+ # def azure_credentials
38
+ # { :container => "xxx", :storage_account_name => "xxx", :access_key => "xxx" }
39
+ # end
40
+ # end
41
+ #
42
+ # * +container+: This is the name of the Azure container that will store your files. Remember
43
+ # that the container must be unique across the storage account. If the container does not exist
44
+ # Paperclip will attempt to create it. The container name will not be interpolated.
45
+ # You can define the container as a Proc if you want to determine it's name at runtime.
46
+ # Paperclip will call that Proc with attachment as the only argument.
47
+ # * +path+: This is the key under the container in which the file will be stored. The
48
+ # URL will be constructed from the container and the path. This is what you will want
49
+ # to interpolate. Keys should be unique, like filenames, and despite the fact that
50
+ # Azure (strictly speaking) does not support directories, you can still use a / to
51
+ # separate parts of your file name.
52
+
53
+ module Azure
54
+ def self.extended base
55
+ begin
56
+ require 'azure'
57
+ rescue LoadError => e
58
+ e.message << " (You may need to install the azure SDK gem)"
59
+ raise e
60
+ end unless defined?(::Azure::Core)
61
+
62
+ base.instance_eval do
63
+ @azure_options = @options[:azure_options] || {}
64
+ end
65
+
66
+ Paperclip.interpolates(:azure_path_url) do |attachment, style|
67
+ attachment.azure_uri(style)
68
+ end unless Paperclip::Interpolations.respond_to? :azure_path_url
69
+ end
70
+
71
+ def expiring_url(time = 3600, style_name = default_style)
72
+ if path(style_name)
73
+ uri = azure_uri(style_name)
74
+ signer = ::Azure::Core::Auth::SharedAccessSignature.new(uri, {
75
+ resource: 'b',
76
+ permissions: 'r',
77
+ start: 5.minutes.ago.utc.iso8601,
78
+ expiry: time.since.utc.iso8601,
79
+ access_key: azure_credentials[:access_key]
80
+ },
81
+ azure_account_name
82
+ )
83
+ signer.sign
84
+ else
85
+ url(style_name)
86
+ end
87
+ end
88
+
89
+ def azure_credentials
90
+ @azure_credentials ||= parse_credentials(@options[:azure_credentials])
91
+ end
92
+
93
+ def azure_account_name
94
+ account_name = @options[:azure_storage_account_name] || azure_credentials[:storage_account_name]
95
+ account_name = account_name.call(self) if account_name.is_a?(Proc)
96
+
97
+ account_name
98
+ end
99
+
100
+ def container_name
101
+ @container ||= @options[:container] || azure_credentials[:container]
102
+ @container = @container.call(self) if @container.respond_to?(:call)
103
+ @container or raise ArgumentError, "missing required :container option"
104
+ end
105
+
106
+ def azure_interface
107
+ @azure_interface ||= begin
108
+ config = {}
109
+
110
+ [:storage_account_name, :access_key, :container].each do |opt|
111
+ config[opt] = azure_credentials[opt] if azure_credentials[opt]
112
+ end
113
+
114
+ obtain_azure_instance_for(config.merge(@azure_options))
115
+ end
116
+ end
117
+
118
+ def obtain_azure_instance_for(options)
119
+ instances = (Thread.current[:paperclip_azure_instances] ||= {})
120
+
121
+ unless instances[options]
122
+ signer = ::Azure::Core::Auth::SharedKey.new options[:storage_account_name], options[:access_key]
123
+ instances[options] = ::Azure::BlobService.new(signer, options[:storage_account_name])
124
+ end
125
+
126
+ instances[options]
127
+ end
128
+
129
+ def azure_uri(style_name = default_style)
130
+ "#{azure_base_url}/#{container_name}/#{path(style_name).gsub(%r{\A/}, '')}"
131
+ end
132
+
133
+ def azure_base_url
134
+ "https://#{azure_account_name}.blob.core.windows.net"
135
+ end
136
+
137
+ def azure_container
138
+ @azure_container ||= azure_interface.get_container_properties container_name
139
+ end
140
+
141
+ def azure_object(style_name = default_style)
142
+ azure_interface.get_blob_properties container_name, path(style_name).sub(%r{\A/},'')
143
+ end
144
+
145
+ def parse_credentials(creds)
146
+ creds = creds.respond_to?('call') ? creds.call(self) : creds
147
+ creds = find_credentials(creds).stringify_keys
148
+ env = Object.const_defined?(:Rails) ? Rails.env : nil
149
+ (creds[env] || creds).symbolize_keys
150
+ end
151
+
152
+ def exists?(style = default_style)
153
+ if original_filename
154
+ azure_object(style).nil?
155
+ else
156
+ false
157
+ end
158
+ rescue ::Azure::Core::Http::HTTPError => e
159
+ raise unless e.status_code == 404
160
+
161
+ false
162
+ end
163
+
164
+ def create_container
165
+ azure_interface.create_container container_name
166
+ end
167
+
168
+ def flush_writes #:nodoc:
169
+ @queued_for_write.each do |style, file|
170
+ retries = 0
171
+ begin
172
+ log("saving #{path(style)}")
173
+ if azure_container
174
+ save_blob container_name, path(style).sub(%r{\A/},''), file
175
+ end
176
+ rescue ::Azure::Core::Http::HTTPError => e
177
+ if e.status_code == 404
178
+ create_container
179
+ retry
180
+ else
181
+ raise
182
+ end
183
+ ensure
184
+ file.rewind
185
+ end
186
+ end
187
+
188
+ after_flush_writes # allows attachment to clean up temp files
189
+
190
+ @queued_for_write = {}
191
+ end
192
+
193
+ def save_blob(container_name, storage_path, file)
194
+ if file.size < 64.megabytes
195
+ azure_interface.create_block_blob container_name, storage_path, file.read
196
+ else
197
+ blocks = []; count = 0
198
+ while data = file.read(4.megabytes)
199
+ block_id = "block_#{(count += 1).to_s.rjust(5, '0')}"
200
+
201
+ azure_interface.create_blob_block container_name, storage_path, block_id, data
202
+
203
+ blocks << [block_id]
204
+ end
205
+
206
+ azure_interface.commit_blob_blocks container_name, storage_path, blocks
207
+ end
208
+ end
209
+
210
+ def flush_deletes #:nodoc:
211
+ @queued_for_delete.each do |path|
212
+ begin
213
+ log("deleting #{path}")
214
+ azure_interface.delete_blob container_name, path
215
+ rescue ::Azure::Core::Http::HTTPError => e
216
+ raise unless e.status_code == 404
217
+ end
218
+ end
219
+ @queued_for_delete = []
220
+ end
221
+
222
+ def copy_to_local_file(style, local_dest_path)
223
+ log("copying #{path(style)} to local file #{local_dest_path}")
224
+
225
+ blob, content = azure_interface.get_blob(container_name, path(style).sub(%r{\A/},''))
226
+
227
+ ::File.open(local_dest_path, 'wb') do |local_file|
228
+ local_file.write(content)
229
+ end
230
+ rescue ::Azure::Core::Http::HTTPError => e
231
+ raise unless e.status_code == 404
232
+
233
+ warn("#{e} - cannot copy #{path(style)} to local file #{local_dest_path}")
234
+ false
235
+ end
236
+
237
+ private
238
+
239
+ def find_credentials creds
240
+ case creds
241
+ when File
242
+ YAML::load(ERB.new(File.read(creds.path)).result)
243
+ when String, Pathname
244
+ YAML::load(ERB.new(File.read(creds)).result)
245
+ when Hash
246
+ creds
247
+ when NilClass
248
+ {}
249
+ else
250
+ raise ArgumentError, "Credentials given are not a path, file, proc, or hash."
251
+ end
252
+ end
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,77 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "paperclip-azure"
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jordan Yaker"]
12
+ s.date = "2015-01-19"
13
+ s.description = "An Azure Blob Storage implementation for Paperclip."
14
+ s.email = "help@supportify.io"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/azure/blob/blob_service.rb",
29
+ "lib/azure/core/auth/shared_access_signature.rb",
30
+ "lib/paperclip-azure.rb",
31
+ "lib/paperclip/storage/azure.rb",
32
+ "paperclip-azure.gemspec",
33
+ "spec/spec_helper.rb"
34
+ ]
35
+ s.homepage = "http://github.com/jordanyaker/paperclip-azure"
36
+ s.licenses = ["MIT"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = "2.0.6"
39
+ s.summary = "An Azure Blob Storage implementation for Paperclip."
40
+
41
+ if s.respond_to? :specification_version then
42
+ s.specification_version = 4
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<azure>, [">= 0"])
46
+ s.add_runtime_dependency(%q<hashie>, [">= 0"])
47
+ s.add_runtime_dependency(%q<addressable>, [">= 0"])
48
+ s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
49
+ s.add_development_dependency(%q<yard>, ["~> 0.7"])
50
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
51
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
52
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
53
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<azure>, [">= 0"])
56
+ s.add_dependency(%q<hashie>, [">= 0"])
57
+ s.add_dependency(%q<addressable>, [">= 0"])
58
+ s.add_dependency(%q<rspec>, ["~> 2.8.0"])
59
+ s.add_dependency(%q<yard>, ["~> 0.7"])
60
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
61
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
62
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
63
+ s.add_dependency(%q<simplecov>, [">= 0"])
64
+ end
65
+ else
66
+ s.add_dependency(%q<azure>, [">= 0"])
67
+ s.add_dependency(%q<hashie>, [">= 0"])
68
+ s.add_dependency(%q<addressable>, [">= 0"])
69
+ s.add_dependency(%q<rspec>, ["~> 2.8.0"])
70
+ s.add_dependency(%q<yard>, ["~> 0.7"])
71
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
72
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
73
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
74
+ s.add_dependency(%q<simplecov>, [">= 0"])
75
+ end
76
+ end
77
+
@@ -0,0 +1,29 @@
1
+ require 'simplecov'
2
+
3
+ module SimpleCov::Configuration
4
+ def clean_filters
5
+ @filters = []
6
+ end
7
+ end
8
+
9
+ SimpleCov.configure do
10
+ clean_filters
11
+ load_adapter 'test_frameworks'
12
+ end
13
+
14
+ ENV["COVERAGE"] && SimpleCov.start do
15
+ add_filter "/.rvm/"
16
+ end
17
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
19
+
20
+ require 'rspec'
21
+ require 'paperclip-azure'
22
+
23
+ # Requires supporting files with custom matchers and macros, etc,
24
+ # in ./support/ and its subdirectories.
25
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
26
+
27
+ RSpec.configure do |config|
28
+
29
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paperclip-azure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jordan Yaker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: azure
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hashie
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: addressable
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.8.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 2.8.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rdoc
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '3.12'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '3.12'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: jeweler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 2.0.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 2.0.1
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: An Azure Blob Storage implementation for Paperclip.
140
+ email: help@supportify.io
141
+ executables: []
142
+ extensions: []
143
+ extra_rdoc_files:
144
+ - LICENSE.txt
145
+ - README.rdoc
146
+ files:
147
+ - .document
148
+ - .rspec
149
+ - Gemfile
150
+ - Gemfile.lock
151
+ - LICENSE.txt
152
+ - README.rdoc
153
+ - Rakefile
154
+ - VERSION
155
+ - lib/azure/blob/blob_service.rb
156
+ - lib/azure/core/auth/shared_access_signature.rb
157
+ - lib/paperclip-azure.rb
158
+ - lib/paperclip/storage/azure.rb
159
+ - paperclip-azure.gemspec
160
+ - spec/spec_helper.rb
161
+ homepage: http://github.com/jordanyaker/paperclip-azure
162
+ licenses:
163
+ - MIT
164
+ metadata: {}
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 2.0.6
182
+ signing_key:
183
+ specification_version: 4
184
+ summary: An Azure Blob Storage implementation for Paperclip.
185
+ test_files: []