carrierwave-aliyun-crud 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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