carrierwave-aliyun-crud 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ uploads
2
+ *.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format nested
data/Changelogs.md ADDED
@@ -0,0 +1,12 @@
1
+ ## 0.1.2
2
+
3
+ * 修正 content_type 的支持,自动用原始文件的 content_type,以免上传 zip 之类的文件以后无法下载.
4
+
5
+ ## 0.1.1
6
+
7
+ * 修改 Aliyun OSS 的请求地址.
8
+ * 加入可选项,使用 Aliyun 内部地址调用上传,以提高内部网络使用的速度.
9
+
10
+ ## 0.1.0
11
+
12
+ * 功能实现.
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://ruby.taobao.org"
2
+ gem "rake"
3
+
4
+ group :test do
5
+ gem 'rails'
6
+ gem 'sqlite3-ruby', :require => 'sqlite3'
7
+ gem 'carrierwave'
8
+ gem 'mini_magick'
9
+ gem 'rest-client'
10
+ gem 'rspec','~> 2.6.0'
11
+ gem 'mocha','0.10.0'
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,114 @@
1
+ GEM
2
+ remote: http://ruby.taobao.org/
3
+ specs:
4
+ actionmailer (3.2.1)
5
+ actionpack (= 3.2.1)
6
+ mail (~> 2.4.0)
7
+ actionpack (3.2.1)
8
+ activemodel (= 3.2.1)
9
+ activesupport (= 3.2.1)
10
+ builder (~> 3.0.0)
11
+ erubis (~> 2.7.0)
12
+ journey (~> 1.0.1)
13
+ rack (~> 1.4.0)
14
+ rack-cache (~> 1.1)
15
+ rack-test (~> 0.6.1)
16
+ sprockets (~> 2.1.2)
17
+ activemodel (3.2.1)
18
+ activesupport (= 3.2.1)
19
+ builder (~> 3.0.0)
20
+ activerecord (3.2.1)
21
+ activemodel (= 3.2.1)
22
+ activesupport (= 3.2.1)
23
+ arel (~> 3.0.0)
24
+ tzinfo (~> 0.3.29)
25
+ activeresource (3.2.1)
26
+ activemodel (= 3.2.1)
27
+ activesupport (= 3.2.1)
28
+ activesupport (3.2.1)
29
+ i18n (~> 0.6)
30
+ multi_json (~> 1.0)
31
+ arel (3.0.0)
32
+ builder (3.0.0)
33
+ carrierwave (0.5.8)
34
+ activesupport (~> 3.0)
35
+ diff-lcs (1.1.3)
36
+ erubis (2.7.0)
37
+ hike (1.2.1)
38
+ i18n (0.6.0)
39
+ journey (1.0.1)
40
+ json (1.6.5)
41
+ mail (2.4.1)
42
+ i18n (>= 0.4.0)
43
+ mime-types (~> 1.16)
44
+ treetop (~> 1.4.8)
45
+ metaclass (0.0.1)
46
+ mime-types (1.17.2)
47
+ mini_magick (3.4)
48
+ subexec (~> 0.2.1)
49
+ mocha (0.10.0)
50
+ metaclass (~> 0.0.1)
51
+ multi_json (1.0.4)
52
+ polyglot (0.3.3)
53
+ rack (1.4.1)
54
+ rack-cache (1.1)
55
+ rack (>= 0.4)
56
+ rack-ssl (1.3.2)
57
+ rack
58
+ rack-test (0.6.1)
59
+ rack (>= 1.0)
60
+ rails (3.2.1)
61
+ actionmailer (= 3.2.1)
62
+ actionpack (= 3.2.1)
63
+ activerecord (= 3.2.1)
64
+ activeresource (= 3.2.1)
65
+ activesupport (= 3.2.1)
66
+ bundler (~> 1.0)
67
+ railties (= 3.2.1)
68
+ railties (3.2.1)
69
+ actionpack (= 3.2.1)
70
+ activesupport (= 3.2.1)
71
+ rack-ssl (~> 1.3.2)
72
+ rake (>= 0.8.7)
73
+ rdoc (~> 3.4)
74
+ thor (~> 0.14.6)
75
+ rake (0.9.2.2)
76
+ rdoc (3.12)
77
+ json (~> 1.4)
78
+ rest-client (1.6.7)
79
+ mime-types (>= 1.16)
80
+ rspec (2.6.0)
81
+ rspec-core (~> 2.6.0)
82
+ rspec-expectations (~> 2.6.0)
83
+ rspec-mocks (~> 2.6.0)
84
+ rspec-core (2.6.4)
85
+ rspec-expectations (2.6.0)
86
+ diff-lcs (~> 1.1.2)
87
+ rspec-mocks (2.6.0)
88
+ sprockets (2.1.2)
89
+ hike (~> 1.2)
90
+ rack (~> 1.0)
91
+ tilt (~> 1.1, != 1.3.0)
92
+ sqlite3 (1.3.5)
93
+ sqlite3-ruby (1.3.3)
94
+ sqlite3 (>= 1.3.3)
95
+ subexec (0.2.1)
96
+ thor (0.14.6)
97
+ tilt (1.3.3)
98
+ treetop (1.4.10)
99
+ polyglot
100
+ polyglot (>= 0.3.1)
101
+ tzinfo (0.3.31)
102
+
103
+ PLATFORMS
104
+ ruby
105
+
106
+ DEPENDENCIES
107
+ carrierwave
108
+ mini_magick
109
+ mocha (= 0.10.0)
110
+ rails
111
+ rake
112
+ rest-client
113
+ rspec (~> 2.6.0)
114
+ sqlite3-ruby
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # CarrierWave for Aliyun OSS
2
+
3
+ This gem forked from carrierwave-aliyun and adds CRUD functionality for [Aliyun OSS](http://oss.aliyun.com) to [CarrierWave](https://github.com/jnicklas/carrierwave/)
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install carrierwave-aliyun-crud
9
+ ```
10
+
11
+ ## Using Bundler
12
+
13
+ ```ruby
14
+ gem 'rest-client'
15
+ gem 'carrierwave-aliyun-crud'
16
+ ```
17
+
18
+ ## Configuration
19
+
20
+ 创建这么个脚本 `config/initializes/carrierwave.rb` 填入下面的代码,并修改对应的配置:
21
+
22
+ ```ruby
23
+ CarrierWave.configure do |config|
24
+ config.storage = :aliyun
25
+ config.aliyun_access_id = "xxxxxx"
26
+ config.aliyun_access_key = 'xxxxxx'
27
+ # 你需要在 Aliyum OSS 上面提前创建一个 Bucket
28
+ config.aliyun_bucket = "simple"
29
+ # 是否使用内部连接,true - 使用 Aliyun 局域网的方式访问 false - 外部网络访问
30
+ config.aliyun_internal = true
31
+ end
32
+ ```
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "carrierwave-aliyun-crud"
6
+ s.version = "0.1.0"
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Jiang Peng"]
9
+ s.email = ["pengj0520@gmail.com"]
10
+ s.homepage = "https://github.com/warmwind/carrierwave-aliyun-crud"
11
+ s.summary = %q{Aliyun OSS support for Carrierwave}
12
+ s.description = %q{Aliyun OSS support for Carrierwave}
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_dependency "carrierwave", [">= 0.5.7"]
19
+ s.add_dependency "rest-client", [">= 1.6.7"]
20
+ end
@@ -0,0 +1,36 @@
1
+ module CarrierWave
2
+ module Aliyun
3
+ module Configuration
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ add_config :aliyun_access_id
7
+ add_config :aliyun_access_key
8
+ add_config :aliyun_bucket
9
+ add_config :aliyun_internal
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def add_config(name)
15
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
16
+ def self.#{name}(value=nil)
17
+ @#{name} = value if value
18
+ return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
19
+ name = superclass.#{name}
20
+ return nil if name.nil? && !instance_variable_defined?("@#{name}")
21
+ @#{name} = name && !name.is_a?(Module) && !name.is_a?(Symbol) && !name.is_a?(Numeric) && !name.is_a?(TrueClass) && !name.is_a?(FalseClass) ? name.dup : name
22
+ end
23
+
24
+ def self.#{name}=(value)
25
+ @#{name} = value
26
+ end
27
+
28
+ def #{name}
29
+ value = self.class.#{name}
30
+ value.instance_of?(Proc) ? value.call : value
31
+ end
32
+ RUBY
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,163 @@
1
+ # encoding: utf-8
2
+ require 'carrierwave'
3
+ require 'digest/hmac'
4
+ require 'digest/md5'
5
+ require 'net/http'
6
+ require "rest-client"
7
+
8
+ module CarrierWave
9
+ module Storage
10
+ class Aliyun < Abstract
11
+
12
+ class Connection
13
+ def initialize(options={})
14
+ @aliyun_access_id = options[:aliyun_access_id]
15
+ @aliyun_access_key = options[:aliyun_access_key]
16
+ @aliyun_bucket = options[:aliyun_bucket]
17
+ @aliyun_host = "oss.aliyuncs.com"
18
+ if options[:aliyun_internal] == true
19
+ @aliyun_host = "oss-internal.aliyuncs.com"
20
+ end
21
+ @http = Net::HTTP.new(@aliyun_host)
22
+ end
23
+
24
+ def put(path, file, options={})
25
+ content_md5 = Digest::MD5.hexdigest(file)
26
+ path = "#{@aliyun_bucket}/#{path}"
27
+ url = "http://#{@aliyun_host}/#{path}"
28
+ headers = generate_header("PUT", path, content_md5, options).merge!({"Content-Length" => file.length})
29
+ RestClient.put url, file, headers
30
+ end
31
+
32
+ def get(path, options={})
33
+ path = "#{@aliyun_bucket}/#{path}"
34
+ url = "http://#{@aliyun_host}/#{path}"
35
+ headers = generate_header "GET", path, "", options
36
+ RestClient.get url, headers
37
+ end
38
+
39
+ def delete path
40
+ path = "#{@aliyun_bucket}/#{path}"
41
+ url = "http://#{@aliyun_host}/#{path}"
42
+ date = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
43
+ headers = {
44
+ "Authorization" => sign("DELETE", path, "", "", date),
45
+ "Date" => date,
46
+ "Host" => @aliyun_host,
47
+ }
48
+ RestClient.delete url, headers
49
+ end
50
+
51
+ private
52
+
53
+ def generate_header verb, path , content_md5, options={}
54
+ content_type = options[:content_type] || "image/jpg"
55
+ date = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
56
+ auth_sign = sign(verb, path, "", content_type, date)
57
+ {
58
+ "Authorization" => auth_sign,
59
+ "Content-Type" => content_type,
60
+ "Date" => date,
61
+ "Host" => @aliyun_host,
62
+ "Expect" => "100-Continue"
63
+ }
64
+ end
65
+
66
+ def sign(verb, path, content_md5 = '', content_type = '', date)
67
+ canonicalized_oss_headers = ''
68
+ canonicalized_resource = "/#{path}"
69
+ string_to_sign = "#{verb}\n\n#{content_type}\n#{date}\n#{canonicalized_oss_headers}#{canonicalized_resource}"
70
+ digest = OpenSSL::Digest::Digest.new('sha1')
71
+ h = OpenSSL::HMAC.digest(digest, @aliyun_access_key, string_to_sign)
72
+ h = Base64.encode64(h)
73
+ "OSS #{@aliyun_access_id}:#{h}"
74
+ end
75
+ end
76
+
77
+ class File
78
+ attr_accessor :content_type
79
+
80
+ def initialize(uploader, base, path)
81
+ @uploader = uploader
82
+ @path = path
83
+ @base = base
84
+ end
85
+
86
+ ##
87
+ # Returns the current path/filename of the file on Cloud Files.
88
+ #
89
+ # === Returns
90
+ #
91
+ # [String] A path
92
+ #
93
+ def path
94
+ @path
95
+ end
96
+
97
+ ##
98
+ # Reads the contents of the file from Cloud Files
99
+ #
100
+ # === Returns
101
+ #
102
+ # [String] contents of the file
103
+ #
104
+ def read
105
+ oss_connection.get(@path)
106
+ end
107
+
108
+ ##
109
+ # Remove the file from Cloud Files
110
+ #
111
+ def delete
112
+ begin
113
+ oss_connection.delete(@path)
114
+ true
115
+ rescue Exception => e
116
+ # If the file's not there, don't panic
117
+ nil
118
+ end
119
+ end
120
+
121
+ def url
122
+ "http://oss.aliyuncs.com/#{@uploader.aliyun_bucket}/#{@path}"
123
+ end
124
+
125
+ def store(data, opts = {})
126
+ oss_connection.put(@path, data, opts)
127
+ end
128
+
129
+ private
130
+
131
+ def headers
132
+ @headers ||= { }
133
+ end
134
+
135
+ def connection
136
+ @base.connection
137
+ end
138
+
139
+ def oss_connection
140
+ return @oss_connection if @oss_connection
141
+
142
+ config = {
143
+ :aliyun_access_id => @uploader.aliyun_access_id,
144
+ :aliyun_access_key => @uploader.aliyun_access_key,
145
+ :aliyun_bucket => @uploader.aliyun_bucket
146
+ }
147
+ @oss_connection ||= CarrierWave::Storage::Aliyun::Connection.new(config)
148
+ end
149
+
150
+ end
151
+
152
+ def store!(file)
153
+ f = CarrierWave::Storage::Aliyun::File.new(uploader, self, uploader.store_path)
154
+ f.store(file.read, :content_type => file.content_type)
155
+ f
156
+ end
157
+
158
+ def retrieve!(identifier)
159
+ CarrierWave::Storage::Aliyun::File.new(uploader, self, uploader.store_path(identifier))
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,9 @@
1
+ require "carrierwave/storage/aliyun"
2
+ require 'carrierwave/processing/mime_types'
3
+ require "carrierwave/aliyun/configuration"
4
+ CarrierWave.configure do |config|
5
+ config.storage_engines.merge!({:aliyun => "CarrierWave::Storage::Aliyun"})
6
+ end
7
+ CarrierWave::Uploader::Base.send(:include, CarrierWave::Aliyun::Configuration)
8
+ CarrierWave::Uploader::Base.send(:include, CarrierWave::MimeTypes)
9
+ CarrierWave::Uploader::Base.send(:process, :set_content_type)
data/spec/foo.gif ADDED
Binary file
data/spec/foo.jpg ADDED
Binary file
data/spec/foo.zip ADDED
Binary file
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'rspec/autorun'
4
+ require 'rails'
5
+ require 'active_record'
6
+ require "carrierwave"
7
+ require 'carrierwave/orm/activerecord'
8
+ require 'carrierwave/processing/mini_magick'
9
+
10
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
11
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12
+
13
+ require "carrierwave-aliyun-crud"
14
+
15
+
16
+ module Rails
17
+ class <<self
18
+ def root
19
+ [File.expand_path(__FILE__).split('/')[0..-3].join('/'),"spec"].join("/")
20
+ end
21
+ end
22
+ end
23
+
24
+ ActiveRecord::Migration.verbose = false
25
+
26
+ # 测试的时候需要修改这个地方
27
+ CarrierWave.configure do |config|
28
+ config.storage = :aliyun
29
+ config.aliyun_access_id = "n4R7XBeTZqd2blQz"
30
+ config.aliyun_access_key = 'WiMTt42rLMT9bPGfGaEaNlzHahG9du'
31
+ config.aliyun_bucket = "carrierwave-jp"
32
+ config.aliyun_internal = false
33
+ end
34
+
35
+ def load_file(fname)
36
+ File.open([Rails.root,fname].join("/"))
37
+ end
@@ -0,0 +1,112 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ require "open-uri"
4
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
5
+
6
+ describe "Upload" do
7
+ def setup_db
8
+ ActiveRecord::Schema.define(:version => 1) do
9
+ create_table :photos do |t|
10
+ t.column :image, :string
11
+ end
12
+
13
+ create_table :attachments do |t|
14
+ t.column :file, :string
15
+ end
16
+ end
17
+ end
18
+
19
+ def drop_db
20
+ ActiveRecord::Base.connection.tables.each do |table|
21
+ ActiveRecord::Base.connection.drop_table(table)
22
+ end
23
+ end
24
+
25
+ class PhotoUploader < CarrierWave::Uploader::Base
26
+ include CarrierWave::MiniMagick
27
+
28
+ version :small do
29
+ process :resize_to_fill => [120, 120]
30
+ end
31
+
32
+ def store_dir
33
+ "photos"
34
+ end
35
+ end
36
+
37
+ class AttachUploader < CarrierWave::Uploader::Base
38
+ include CarrierWave::MiniMagick
39
+
40
+ def store_dir
41
+ "attachs"
42
+ end
43
+ end
44
+
45
+ class Photo < ActiveRecord::Base
46
+ mount_uploader :image, PhotoUploader
47
+ end
48
+
49
+ class Attachment < ActiveRecord::Base
50
+ mount_uploader :file, AttachUploader
51
+ end
52
+
53
+
54
+ before :all do
55
+ setup_db
56
+ end
57
+
58
+ after :all do
59
+ drop_db
60
+ end
61
+
62
+ describe "Upload Image" do
63
+ context "should upload image" do
64
+ before(:all) do
65
+ @file = load_file("foo.jpg")
66
+ @file1 = load_file("foo.gif")
67
+ @photo = Photo.new(:image => @file)
68
+ @photo1 = Photo.new(:image => @file1)
69
+ end
70
+
71
+ it "should upload file" do
72
+ @photo.save.should be_true
73
+ @photo1.save.should be_true
74
+ end
75
+
76
+ it "should get uploaded file" do
77
+ img = open(@photo.image.url)
78
+ img.size.should == @file.size
79
+ img1 = open(@photo1.image.url)
80
+ img1.size.should == @file1.size
81
+ end
82
+
83
+ it "should get small version uploaded file" do
84
+ open(@photo.image.small.url).should_not == nil
85
+ open(@photo1.image.small.url).should_not == nil
86
+ end
87
+
88
+ it "should delete uploaded files" do
89
+ @photo.remove_image!
90
+ @photo.reload
91
+ expect {open(@photo.image.url)}.to raise_error(OpenURI::HTTPError)
92
+ end
93
+ end
94
+
95
+ context "should update zip" do
96
+ before(:all) do
97
+ @file = load_file("foo.zip")
98
+ @attachment = Attachment.new(:file => @file)
99
+ end
100
+
101
+ it "should upload file" do
102
+ @attachment.save.should be_true
103
+ end
104
+
105
+ it "should get uploaded file" do
106
+ attach = open(@attachment.file.url)
107
+ attach.size.should == @file.size
108
+ end
109
+
110
+ end
111
+ end
112
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carrierwave-aliyun-crud
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jiang Peng
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: carrierwave
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.5.7
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.5.7
30
+ - !ruby/object:Gem::Dependency
31
+ name: rest-client
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.6.7
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.6.7
46
+ description: Aliyun OSS support for Carrierwave
47
+ email:
48
+ - pengj0520@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .rspec
55
+ - Changelogs.md
56
+ - Gemfile
57
+ - Gemfile.lock
58
+ - README.md
59
+ - carrierwave-aliyun-crud.gemspec
60
+ - lib/carrierwave-aliyun-crud.rb
61
+ - lib/carrierwave/aliyun/configuration.rb
62
+ - lib/carrierwave/storage/aliyun.rb
63
+ - spec/foo.gif
64
+ - spec/foo.jpg
65
+ - spec/foo.zip
66
+ - spec/spec_helper.rb
67
+ - spec/upload_spec.rb
68
+ homepage: https://github.com/warmwind/carrierwave-aliyun-crud
69
+ licenses: []
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 1.8.24
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Aliyun OSS support for Carrierwave
92
+ test_files:
93
+ - spec/foo.gif
94
+ - spec/foo.jpg
95
+ - spec/foo.zip
96
+ - spec/spec_helper.rb
97
+ - spec/upload_spec.rb