resizor 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/README.rdoc +44 -0
- data/Rakefile +9 -0
- data/lib/generators/resizor/USAGE +5 -0
- data/lib/generators/resizor/resizor_generator.rb +31 -0
- data/lib/generators/resizor/templates/resizor_migration.rb.erb +26 -0
- data/lib/resizor/asset.rb +125 -0
- data/lib/resizor/connection.rb +78 -0
- data/lib/resizor/railtie.rb +73 -0
- data/lib/resizor/resizor.rb +19 -0
- data/lib/resizor/version.rb +3 -0
- data/lib/resizor.rb +7 -0
- data/resizor.gemspec +24 -0
- data/test/asset_test.rb +96 -0
- data/test/database.yml +3 -0
- data/test/integration_test.rb +102 -0
- data/test/resizor_test.rb +66 -0
- data/test/test_helper.rb +50 -0
- metadata +133 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
=Resizor
|
2
|
+
|
3
|
+
For use with http://resizor.com
|
4
|
+
|
5
|
+
Inspired by Thoughtbot's Paperclip
|
6
|
+
|
7
|
+
== Usage
|
8
|
+
|
9
|
+
Add resizor to your Gemfile
|
10
|
+
|
11
|
+
gem 'resizor'
|
12
|
+
|
13
|
+
Install resizor gem
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Add a initializer to RAILS_ROOT/config/initializers/resizor.rb
|
18
|
+
|
19
|
+
Resizor.configure do |config|
|
20
|
+
config.api_key = 'my-api-key'
|
21
|
+
end
|
22
|
+
|
23
|
+
Add Resizor fields to your model
|
24
|
+
|
25
|
+
$ rails generate resizor MyModel image
|
26
|
+
|
27
|
+
Add has_resizor_asset to MyModel
|
28
|
+
|
29
|
+
class MyModel < ActiveRecord::Base
|
30
|
+
has_resizor_asset :image
|
31
|
+
|
32
|
+
...
|
33
|
+
end
|
34
|
+
|
35
|
+
Add a file field to the form for MyModel
|
36
|
+
|
37
|
+
<%= f.label :image %>
|
38
|
+
<%= f.file_field :image %>
|
39
|
+
|
40
|
+
Now you can resize your uploaded images on the fly
|
41
|
+
|
42
|
+
<% if my_model.image? %>
|
43
|
+
<img src="<%= my_model.image.url(:size => 'c200x300') %>">
|
44
|
+
<% end %>
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
class ResizorGenerator < ActiveRecord::Generators::Base
|
4
|
+
desc "Create a migration to add resizor-specific fields to your model."
|
5
|
+
|
6
|
+
argument :asset_names, :required => true, :type => :array, :desc => "The names of the asset(s) to add.",
|
7
|
+
:banner => "asset_one asset_two asset_three ..."
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
@source_root ||= File.expand_path('../templates', __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_migration
|
14
|
+
migration_template "resizor_migration.rb.erb", "db/migrate/#{migration_file_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def migration_name
|
20
|
+
"add_resizor_#{asset_names.join("_")}_to_#{name.underscore}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def migration_file_name
|
24
|
+
"#{migration_name}.rb"
|
25
|
+
end
|
26
|
+
|
27
|
+
def migration_class_name
|
28
|
+
migration_name.camelize
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
<% asset_names.each do |asset| -%>
|
4
|
+
add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_resizor_id, :string
|
5
|
+
add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_name, :string
|
6
|
+
|
7
|
+
# Uncomment below for meta data columns
|
8
|
+
# add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_mime_type, :string
|
9
|
+
# add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_size, :integer
|
10
|
+
# add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_width, :integer
|
11
|
+
# add_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_height, :integer
|
12
|
+
<% end -%>
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
<% asset_names.each do |asset| -%>
|
17
|
+
remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_resizor_id
|
18
|
+
remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_name
|
19
|
+
|
20
|
+
# remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_mime_type
|
21
|
+
# remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_size
|
22
|
+
# remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_width
|
23
|
+
# remove_column :<%= name.underscore.camelize.tableize %>, :<%= asset %>_height
|
24
|
+
<% end -%>
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Resizor
|
2
|
+
class Asset
|
3
|
+
attr_accessor :id, :name, :mime_type, :size, :width, :height, :path
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
options.each { |k,v| send "#{k}=".to_sym, v }
|
7
|
+
end
|
8
|
+
|
9
|
+
def url(options={})
|
10
|
+
options = {:size => '200', :format => 'jpg'}.merge(options)
|
11
|
+
"#{Resizor.api_url}/assets/#{id}.#{options[:format]}?size=#{options[:size]}&token=#{resize_token_for(options)}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def resize_token_for(options={})
|
15
|
+
options = {:size => '200', :format => 'jpg'}.merge(options)
|
16
|
+
Digest::SHA1.hexdigest("#{Resizor.api_key}-#{id}-#{options[:size]}-#{options[:format]}")
|
17
|
+
end
|
18
|
+
|
19
|
+
def save_to_resizor
|
20
|
+
if path && File.exists?(path)
|
21
|
+
ret = Resizor.post('/assets.json', :file => File.open(path))
|
22
|
+
if ret.code == 201
|
23
|
+
@id = ret.body['asset']['id']
|
24
|
+
@name = "#{ret.body['asset']['name']}.#{ret.body['asset']['extension']}"
|
25
|
+
@mime_type = ret.body['asset']['mime_type']
|
26
|
+
@size = ret.body['asset']['file_size']
|
27
|
+
@width = ret.body['asset']['width']
|
28
|
+
@height = ret.body['asset']['height']
|
29
|
+
else
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy
|
37
|
+
ret = Resizor.delete("/assets/#{id}.json")
|
38
|
+
if ret.code == 200
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class AttachedAsset < Resizor::Asset
|
45
|
+
|
46
|
+
attr_accessor :attachment_name, :instance, :file
|
47
|
+
|
48
|
+
def initialize(attachment_name, instance, options = {})
|
49
|
+
@attachment_name = attachment_name
|
50
|
+
@instance = instance
|
51
|
+
@options = options
|
52
|
+
@id = instance_read("resizor_id")
|
53
|
+
@name = instance_read("name")
|
54
|
+
@mime_type = instance_read("mime_type")
|
55
|
+
@size = instance_read("size")
|
56
|
+
@width = instance_read("width")
|
57
|
+
@height = instance_read("height")
|
58
|
+
end
|
59
|
+
|
60
|
+
def assign in_file
|
61
|
+
if in_file.is_a?(Resizor::Asset)
|
62
|
+
@id = in_file.id
|
63
|
+
@name = in_file.name
|
64
|
+
@mime_type = in_file.mime_type
|
65
|
+
@size = in_file.size
|
66
|
+
@width = in_file.width
|
67
|
+
@height = in_file.height
|
68
|
+
else
|
69
|
+
@file = in_file
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def save
|
74
|
+
if file
|
75
|
+
@path = File.join(Dir.tmpdir, file.original_filename)
|
76
|
+
if file.is_a?(Tempfile)
|
77
|
+
FileUtils.move(file.local_path, @path)
|
78
|
+
else
|
79
|
+
File.open(@path, 'wb') { |f| f.write(file.read) }
|
80
|
+
end
|
81
|
+
if save_to_resizor
|
82
|
+
File.unlink(@path)
|
83
|
+
else
|
84
|
+
instance.errors[attachment_name.to_sym] << "can't be saved"
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
instance_write(:resizor_id, @id)
|
89
|
+
instance_write(:name, @name)
|
90
|
+
instance_write(:mime_type, @mime_type)
|
91
|
+
instance_write(:size, @size)
|
92
|
+
instance_write(:width, @width)
|
93
|
+
instance_write(:height, @height)
|
94
|
+
return true
|
95
|
+
end
|
96
|
+
|
97
|
+
def delete
|
98
|
+
destroy
|
99
|
+
end
|
100
|
+
|
101
|
+
def destroy
|
102
|
+
if ret = super
|
103
|
+
instance_write(:resizor_id, nil)
|
104
|
+
instance_write(:name, nil)
|
105
|
+
instance_write(:mime_type, nil)
|
106
|
+
instance_write(:size, nil)
|
107
|
+
instance_write(:width, nil)
|
108
|
+
instance_write(:height, nil)
|
109
|
+
end
|
110
|
+
ret
|
111
|
+
end
|
112
|
+
|
113
|
+
protected
|
114
|
+
def instance_write(_attr, value)
|
115
|
+
setter = :"#{attachment_name}_#{_attr}="
|
116
|
+
self.instance_variable_set("@#{_attr.to_s.chop}", value)
|
117
|
+
instance.send(setter, value) if instance.respond_to?(setter)
|
118
|
+
end
|
119
|
+
|
120
|
+
def instance_read(_attr)
|
121
|
+
getter = :"#{attachment_name}_#{_attr}"
|
122
|
+
instance.send(getter) if instance.respond_to?(getter)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
module Resizor
|
3
|
+
class Connection
|
4
|
+
attr_accessor :api_host, :api_port, :api_key
|
5
|
+
|
6
|
+
def initialize(options={})
|
7
|
+
@api_host = options[:api_host] || options['api_host'] || 'http://resizor.com'
|
8
|
+
@api_port = options[:api_port] || options['api_port'] || 80
|
9
|
+
@api_key = options[:api_key] || options['api_key']
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(request_uri, params={}, append_api_key=true)
|
13
|
+
params[:api_key] = @api_key if append_api_key
|
14
|
+
query = make_query(params)
|
15
|
+
do_request do
|
16
|
+
make_response_for resource[request_uri + '?' + query].get
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def post(request_uri, params={}, append_api_key=true)
|
21
|
+
params[:api_key] = @api_key if append_api_key
|
22
|
+
do_request do
|
23
|
+
make_response_for resource[request_uri].post params
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(request_uri, params={}, append_api_key=true)
|
28
|
+
params[:api_key] = @api_key if append_api_key
|
29
|
+
query = make_query(params)
|
30
|
+
do_request do
|
31
|
+
make_response_for resource[request_uri + '?' + query].delete
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def api_url
|
36
|
+
@api_url ||= "http://#{@api_host}:#{@api_port}"
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def resource
|
42
|
+
@resource ||= RestClient::Resource.new(api_url)
|
43
|
+
end
|
44
|
+
|
45
|
+
def make_query(params)
|
46
|
+
params.collect {|key, value| [CGI.escape(key.to_s), CGI.escape(value.to_s)].join("=") }.join("&")
|
47
|
+
end
|
48
|
+
|
49
|
+
def make_response_for(http_response)
|
50
|
+
Resizor::Response.new(http_response.code, http_response.body)
|
51
|
+
end
|
52
|
+
|
53
|
+
def do_request(&block)
|
54
|
+
begin
|
55
|
+
yield
|
56
|
+
rescue RestClient::Exception => e
|
57
|
+
Resizor::Response.new(e.http_code, e.http_body)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Response
|
63
|
+
attr_accessor :code, :body, :format
|
64
|
+
def initialize(_code, _body, _format = 'json')
|
65
|
+
@code = _code
|
66
|
+
@format = _format
|
67
|
+
@body = if @format == 'json'
|
68
|
+
if defined?(ActiveSupport::JSON)
|
69
|
+
ActiveSupport::JSON.decode(_body)
|
70
|
+
else
|
71
|
+
JSON.parse(_body)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
_body
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'resizor.rb'
|
2
|
+
|
3
|
+
module Resizor
|
4
|
+
if defined?(Rails::Railtie)
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
initializer 'resizor.insert_into_active_record' do
|
7
|
+
ActiveSupport.on_load :active_record do
|
8
|
+
Resizor::Railtie.insert
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Railtie
|
15
|
+
def self.insert
|
16
|
+
ActiveRecord::Base.send(:include, Resizor)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def included base
|
22
|
+
base.extend ClassMethods
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def has_resizor_asset name, options = {}
|
28
|
+
include InstanceMethods
|
29
|
+
|
30
|
+
write_inheritable_attribute(:resizor_assets, {}) if resizor_assets.nil?
|
31
|
+
resizor_assets[name] = options
|
32
|
+
|
33
|
+
before_save :save_attached_files_for_resizor
|
34
|
+
before_destroy :delete_attached_files_on_resizor
|
35
|
+
|
36
|
+
define_method name do |*args|
|
37
|
+
asset_for(name)
|
38
|
+
end
|
39
|
+
|
40
|
+
define_method "#{name}=" do |file|
|
41
|
+
asset_for(name).assign(file)
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method "#{name}?" do
|
45
|
+
!asset_for(name).file.nil? || !asset_for(name).id.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def resizor_assets
|
51
|
+
read_inheritable_attribute(:resizor_assets)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module InstanceMethods
|
56
|
+
def asset_for name
|
57
|
+
@resizor_assets ||= {}
|
58
|
+
@resizor_assets[name] ||= Resizor::AttachedAsset.new(name, self, self.class.resizor_assets[name])
|
59
|
+
end
|
60
|
+
|
61
|
+
def save_attached_files_for_resizor
|
62
|
+
self.class.resizor_assets.each do |name, options|
|
63
|
+
asset_for(name).send(:save)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def delete_attached_files_on_resizor
|
68
|
+
self.class.resizor_assets.each do |name, options|
|
69
|
+
asset_for(name).send(:destroy)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'restclient'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'json' unless defined?(ActiveSupport::JSON)
|
4
|
+
|
5
|
+
module Resizor
|
6
|
+
extend self
|
7
|
+
extend Forwardable
|
8
|
+
attr_reader :connection
|
9
|
+
def_delegators :connection, :get, :post, :delete, :api_url, :api_key
|
10
|
+
|
11
|
+
def configure
|
12
|
+
yield @connection = Connection.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def connection
|
16
|
+
raise "Not connected. Please setup Resizor configuration first." unless @connection
|
17
|
+
@connection
|
18
|
+
end
|
19
|
+
end
|
data/lib/resizor.rb
ADDED
data/resizor.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/resizor/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "resizor"
|
6
|
+
s.version = Resizor::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Winston Design"]
|
9
|
+
s.email = ["hello@resizor.com"]
|
10
|
+
s.homepage = "http://github.org/winstondesign/resizor-gem"
|
11
|
+
s.summary = "Client for Resizor.com API"
|
12
|
+
s.description = "Lets you easily interface with Resizor.com's REST API. Includes Rails helpers."
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
|
16
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
17
|
+
|
18
|
+
s.add_dependency(%q<rest-client>, [">= 1.4"])
|
19
|
+
s.add_dependency(%q<json>, [">= 1.2"])
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
23
|
+
s.require_path = 'lib'
|
24
|
+
end
|
data/test/asset_test.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class AssetTest < Test::Unit::TestCase
|
4
|
+
context "A Asset" do
|
5
|
+
setup do
|
6
|
+
setup_resizor
|
7
|
+
@asset = Resizor::Asset.new(:id => 10,
|
8
|
+
:name => 'my_file.jpg',
|
9
|
+
:mime_type => 'image/jpeg',
|
10
|
+
:width => 200,
|
11
|
+
:height => 300,
|
12
|
+
:size => 123456)
|
13
|
+
end
|
14
|
+
should "have assigned attributes" do
|
15
|
+
assert_equal @asset.id, 10
|
16
|
+
assert_equal @asset.name, 'my_file.jpg'
|
17
|
+
assert_equal @asset.mime_type, 'image/jpeg'
|
18
|
+
assert_equal @asset.width, 200
|
19
|
+
assert_equal @asset.height, 300
|
20
|
+
assert_equal @asset.size, 123456
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'generate url for size c200x300' do
|
24
|
+
assert_equal 'http://resizor.test:80/assets/10.jpg?size=c200x300&token=b8bb7c4c7c4fc1006c904f011f32f50f69730e5e', @asset.url(:size => 'c200x300')
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'generate url for size c200x300 format png' do
|
28
|
+
assert_equal 'http://resizor.test:80/assets/10.png?size=c200x300&token=0cf27070e89c44a40aee85decca2cd2d98af1dc2', @asset.url(:size => 'c200x300', :format => 'png')
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'generate resize token for size c200x300 and format jpg' do
|
32
|
+
assert_equal 'b8bb7c4c7c4fc1006c904f011f32f50f69730e5e', @asset.resize_token_for(:size => 'c200x300', :format => 'jpg')
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when saving to resizor' do
|
36
|
+
setup do
|
37
|
+
@jpg_file = Tempfile.new('image.jpg')
|
38
|
+
@asset.path = @jpg_file.path
|
39
|
+
end
|
40
|
+
teardown { @jpg_file.unlink }
|
41
|
+
|
42
|
+
context 'on success' do
|
43
|
+
setup do
|
44
|
+
stub_http_request(:post, "resizor.test/assets.json").
|
45
|
+
with { |request|
|
46
|
+
request.body.include?("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg")
|
47
|
+
}.
|
48
|
+
to_return(:status => 201,
|
49
|
+
:body => '{"asset": { "id":1, "name":"i", "extension":"jpg", "mime_type":"image/jpeg", "height":7, "width":8, "file_size":9, "created_at":"2010-10-23T13:07:25Z"}}')
|
50
|
+
@asset.save_to_resizor
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'make create call to Resizor on save with file' do
|
54
|
+
assert_requested(:post, "resizor.test/assets.json",
|
55
|
+
:times => 1) { |request|
|
56
|
+
request.body.include?("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg")
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
should 'assign data for new assets as attributes' do
|
61
|
+
assert_equal 1, @asset.id
|
62
|
+
assert_equal 'i.jpg', @asset.name
|
63
|
+
assert_equal 'image/jpeg', @asset.mime_type
|
64
|
+
assert_equal 7, @asset.height
|
65
|
+
assert_equal 8, @asset.width
|
66
|
+
assert_equal 9, @asset.size
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'on failure' do
|
71
|
+
should 'return false' do
|
72
|
+
stub_http_request(:post, "resizor.test/assets.json").to_return(:status => 422)
|
73
|
+
assert !@asset.save_to_resizor
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when destroying an asset' do
|
79
|
+
should 'make delete call to Resizor on destroy' do
|
80
|
+
stub_http_request(:delete, "resizor.test/assets/10.json?api_key=test-api-key").to_return(:status => 200)
|
81
|
+
@asset.destroy
|
82
|
+
assert_requested :delete, "resizor.test/assets/10.json?api_key=test-api-key", :times => 1
|
83
|
+
end
|
84
|
+
|
85
|
+
should 'return true on success' do
|
86
|
+
stub_http_request(:delete, "resizor.test/assets/10.json?api_key=test-api-key").to_return(:status => 200)
|
87
|
+
assert @asset.destroy
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'return false on failure' do
|
91
|
+
stub_http_request(:delete, "resizor.test/assets/10.json?api_key=test-api-key").to_return(:status => 404)
|
92
|
+
assert !@asset.destroy
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/test/database.yml
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class IntegrationTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context 'Including Resizor in a Rails project' do
|
6
|
+
setup do
|
7
|
+
setup_resizor
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'add has_resizor_asset to ActiveRecord::Base' do
|
11
|
+
assert ActiveRecord::Base.methods.include?('has_resizor_asset')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'A ActiveRecord model that has_resizor_asset' do
|
16
|
+
setup do
|
17
|
+
build_model
|
18
|
+
@item = Item.new(:name => 'my test item')
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with a file attached' do
|
22
|
+
setup do
|
23
|
+
@image_fixture_path = File.join(File.dirname(__FILE__), 'fixtures', 'image.jpg')
|
24
|
+
File.open(@image_fixture_path, 'w') {|f| f.write('JPEG data') }
|
25
|
+
@file = File.new(@image_fixture_path, 'rb')
|
26
|
+
@item.image = @file
|
27
|
+
stub_http_request(:post, "resizor.test/assets.json").
|
28
|
+
with { |request| request.body.include?("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg") }.
|
29
|
+
to_return(:status => 201, :body => '{"asset": { "id":1, "name":"i", "extension":"jpg", "mime_type":"image/jpeg", "height":7, "width":8, "file_size":9, "created_at":"2010-10-23T13:07:25Z"}}')
|
30
|
+
stub_http_request(:delete, "resizor.test/assets/1.json?api_key=test-api-key").to_return(:status => 200)
|
31
|
+
end
|
32
|
+
|
33
|
+
teardown { File.unlink(@image_fixture_path) }
|
34
|
+
|
35
|
+
should 'save attached asset to Resizor on save' do
|
36
|
+
assert @item.save
|
37
|
+
assert_requested(:post, "resizor.test/assets.json", :times => 1) do |request|
|
38
|
+
request.body.include?("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'set assigned resizor data to asset fields' do
|
43
|
+
@item.save
|
44
|
+
@item.reload
|
45
|
+
assert_equal '1', @item.image_resizor_id
|
46
|
+
assert_equal 'i.jpg', @item.image_name
|
47
|
+
assert_equal 'image/jpeg', @item.image_mime_type
|
48
|
+
assert_equal 9, @item.image_size
|
49
|
+
assert_equal 8, @item.image_width
|
50
|
+
assert_equal 7, @item.image_height
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'copy attributes when another resizor asset is assigned to asset attribute' do
|
54
|
+
@item.save
|
55
|
+
@another_item = Item.create(:name => 'The second item')
|
56
|
+
@another_item.image = @item.image
|
57
|
+
@another_item.save
|
58
|
+
assert_equal @item.image_resizor_id, @another_item.image_resizor_id
|
59
|
+
assert_equal @item.image_name, @another_item.image_name
|
60
|
+
assert_equal @item.image_mime_type, @another_item.image_mime_type
|
61
|
+
assert_equal @item.image_size, @another_item.image_size
|
62
|
+
assert_equal @item.image_width, @another_item.image_width
|
63
|
+
assert_equal @item.image_height, @another_item.image_height
|
64
|
+
end
|
65
|
+
|
66
|
+
should 'return true for #image?' do
|
67
|
+
@item.save
|
68
|
+
assert @item.image?
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
should 'clear asset fields when assets is deleted' do
|
73
|
+
@item.save
|
74
|
+
assert @item.image.destroy
|
75
|
+
[:image_resizor_id, :image_name, :image_mime_type, :image_size, :image_width, :image_height].each do |_attr|
|
76
|
+
assert_nil @item.send(_attr)
|
77
|
+
end
|
78
|
+
assert_requested :delete, "resizor.test/assets/1.json?api_key=test-api-key", :times => 1
|
79
|
+
end
|
80
|
+
|
81
|
+
should 'delete resizor asset when model instance is deleted' do
|
82
|
+
@item.save
|
83
|
+
@item.reload
|
84
|
+
assert @item.destroy
|
85
|
+
assert_requested :delete, "resizor.test/assets/1.json?api_key=test-api-key", :times => 1
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'should work with no attachment set' do
|
91
|
+
assert_nothing_raised do
|
92
|
+
@item.save
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
should 'return false when no attachment is set' do
|
97
|
+
@item.save
|
98
|
+
assert !@item.image?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class ResizorTest < Test::Unit::TestCase
|
4
|
+
context 'When Resizor gem is not setup it' do
|
5
|
+
setup do
|
6
|
+
Resizor.instance_variable_set("@connection", nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
['get', 'post', 'delete'].each do |m|
|
10
|
+
should "raise error for #{m}" do
|
11
|
+
exception = assert_raise(RuntimeError) { Resizor.send(m, nil) }
|
12
|
+
assert_equal 'Not connected. Please setup Resizor configuration first.', exception.message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'When Resizor gem has been setup it' do
|
18
|
+
setup { setup_resizor }
|
19
|
+
should 'return a API url' do
|
20
|
+
assert_equal 'http://resizor.test:80', Resizor.api_url
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'make a GET request to Resizor server with API key' do
|
24
|
+
stub_http_request(:get, "resizor.test:80/assets.json?api_key=test-api-key").to_return(:body => '{"a": "123"}')
|
25
|
+
Resizor.get('/assets.json').tap do |r|
|
26
|
+
assert_equal 200, r.code
|
27
|
+
assert_equal Hash['a', '123'], r.body
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'make a POST request to Resizor server with API key' do
|
32
|
+
stub_http_request(:post, "resizor.test:80/assets.json").with(:body => 'api_key=test-api-key').to_return(:body => '{"a": "123"}', :status => 201)
|
33
|
+
Resizor.post('/assets.json').tap do |r|
|
34
|
+
assert_equal 201, r.code
|
35
|
+
assert_equal Hash['a', '123'], r.body
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'make a DELETE request to Resizor server with API key' do
|
40
|
+
stub_http_request(:delete, "resizor.test:80/assets/1.json?api_key=test-api-key")
|
41
|
+
Resizor.delete('/assets/1.json').tap do |r|
|
42
|
+
assert_equal 200, r.code
|
43
|
+
assert_equal nil, r.body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'add params along with API key when generating GET URL' do
|
48
|
+
stub_http_request(:get, "resizor.test:80/assets.json?api_key=test-api-key&id=1")
|
49
|
+
Resizor.get('/assets.json', :id => 1)
|
50
|
+
assert_requested :get, "resizor.test:80/assets.json?api_key=test-api-key&id=1"
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'add params along with API key when generating POST URL' do
|
54
|
+
stub_http_request(:post, "resizor.test:80/assets.json").with(:body => 'api_key=test-api-key&id=1')
|
55
|
+
Resizor.post('/assets.json', :id => 1)
|
56
|
+
assert_requested :post, "resizor.test:80/assets.json"
|
57
|
+
end
|
58
|
+
|
59
|
+
should 'add params along with API key when generating DELETE URL' do
|
60
|
+
stub_http_request(:delete, "resizor.test:80/assets.json?api_key=test-api-key&id=1")
|
61
|
+
Resizor.delete('/assets.json', :id => 1)
|
62
|
+
assert_requested :delete, "resizor.test:80/assets.json?api_key=test-api-key&id=1"
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'shoulda'
|
7
|
+
require 'resizor'
|
8
|
+
|
9
|
+
gem 'activerecord', '~>3.0.0'
|
10
|
+
require 'active_record'
|
11
|
+
|
12
|
+
require 'webmock/test_unit'
|
13
|
+
include WebMock::API
|
14
|
+
|
15
|
+
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
16
|
+
ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FILE__) + "/debug.log")
|
17
|
+
ActiveRecord::Base.establish_connection(config['test'])
|
18
|
+
|
19
|
+
ActiveRecord::Base.send(:include, Resizor)
|
20
|
+
|
21
|
+
def build_model
|
22
|
+
ActiveRecord::Base.connection.create_table :items, :force => true do |t|
|
23
|
+
t.column :name, :string
|
24
|
+
t.column :image_resizor_id, :string
|
25
|
+
t.column :image_name, :string
|
26
|
+
t.column :image_mime_type, :string
|
27
|
+
t.column :image_size, :integer
|
28
|
+
t.column :image_width, :integer
|
29
|
+
t.column :image_height, :integer
|
30
|
+
end
|
31
|
+
Object.send(:remove_const, "Item") rescue nil
|
32
|
+
Object.const_set("Item", Class.new(ActiveRecord::Base))
|
33
|
+
Item.class_eval do
|
34
|
+
has_resizor_asset :image
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def setup_resizor
|
39
|
+
Resizor.configure do |config|
|
40
|
+
config.api_host = 'resizor.test'
|
41
|
+
config.api_key = 'test-api-key'
|
42
|
+
end
|
43
|
+
Resizor::Railtie.insert
|
44
|
+
end
|
45
|
+
|
46
|
+
class File
|
47
|
+
def original_filename
|
48
|
+
File.basename(self.path)
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resizor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Winston Design
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-16 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: bundler
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 23
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
version: 1.0.0
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rest-client
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 7
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 4
|
49
|
+
version: "1.4"
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: json
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 11
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 2
|
64
|
+
version: "1.2"
|
65
|
+
type: :runtime
|
66
|
+
version_requirements: *id003
|
67
|
+
description: Lets you easily interface with Resizor.com's REST API. Includes Rails helpers.
|
68
|
+
email:
|
69
|
+
- hello@resizor.com
|
70
|
+
executables: []
|
71
|
+
|
72
|
+
extensions: []
|
73
|
+
|
74
|
+
extra_rdoc_files: []
|
75
|
+
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- README.rdoc
|
80
|
+
- Rakefile
|
81
|
+
- lib/generators/resizor/USAGE
|
82
|
+
- lib/generators/resizor/resizor_generator.rb
|
83
|
+
- lib/generators/resizor/templates/resizor_migration.rb.erb
|
84
|
+
- lib/resizor.rb
|
85
|
+
- lib/resizor/asset.rb
|
86
|
+
- lib/resizor/connection.rb
|
87
|
+
- lib/resizor/railtie.rb
|
88
|
+
- lib/resizor/resizor.rb
|
89
|
+
- lib/resizor/version.rb
|
90
|
+
- resizor.gemspec
|
91
|
+
- test/asset_test.rb
|
92
|
+
- test/database.yml
|
93
|
+
- test/integration_test.rb
|
94
|
+
- test/resizor_test.rb
|
95
|
+
- test/test_helper.rb
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: http://github.org/winstondesign/resizor-gem
|
98
|
+
licenses: []
|
99
|
+
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 23
|
120
|
+
segments:
|
121
|
+
- 1
|
122
|
+
- 3
|
123
|
+
- 6
|
124
|
+
version: 1.3.6
|
125
|
+
requirements: []
|
126
|
+
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 1.3.7
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: Client for Resizor.com API
|
132
|
+
test_files: []
|
133
|
+
|