imgshark 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +59 -0
- data/Guardfile +27 -0
- data/README +53 -0
- data/Rakefile +10 -0
- data/imgshark.gemspec +27 -0
- data/lib/imgshark.rb +119 -0
- data/spec/imgshark_spec.rb +40 -0
- data/spec/spec_helper.rb +14 -0
- metadata +145 -0
data/.rspec
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
# These testing gems are specified here rather than in gemspec
|
6
|
+
# because they're for local mac development only
|
7
|
+
group :test do
|
8
|
+
gem 'guard', '~> 0.6.3'
|
9
|
+
gem 'guard-rspec', '~> 0.4.5'
|
10
|
+
gem 'guard-bundler', '~> 0.1.3'
|
11
|
+
gem 'growl_notify', '~> 0.0.3'
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
imgshark (0.0.5)
|
5
|
+
aws-s3 (~> 0.6.2)
|
6
|
+
http (~> 0.0.2)
|
7
|
+
map (~> 4.5.0)
|
8
|
+
redis (~> 2.0)
|
9
|
+
rmagick (~> 2.13.1)
|
10
|
+
yajl-ruby (~> 1.0.0)
|
11
|
+
|
12
|
+
GEM
|
13
|
+
remote: http://rubygems.org/
|
14
|
+
specs:
|
15
|
+
aws-s3 (0.6.2)
|
16
|
+
builder
|
17
|
+
mime-types
|
18
|
+
xml-simple
|
19
|
+
builder (3.0.0)
|
20
|
+
diff-lcs (1.1.3)
|
21
|
+
growl_notify (0.0.3)
|
22
|
+
rb-appscript
|
23
|
+
guard (0.6.3)
|
24
|
+
thor (~> 0.14.6)
|
25
|
+
guard-bundler (0.1.3)
|
26
|
+
bundler (>= 1.0.0)
|
27
|
+
guard (>= 0.2.2)
|
28
|
+
guard-rspec (0.4.5)
|
29
|
+
guard (>= 0.4.0)
|
30
|
+
http (0.0.2)
|
31
|
+
map (4.5.1)
|
32
|
+
mime-types (1.17.2)
|
33
|
+
rb-appscript (0.6.1)
|
34
|
+
redis (2.2.2)
|
35
|
+
rmagick (2.13.1)
|
36
|
+
rspec (2.6.0)
|
37
|
+
rspec-core (~> 2.6.0)
|
38
|
+
rspec-expectations (~> 2.6.0)
|
39
|
+
rspec-mocks (~> 2.6.0)
|
40
|
+
rspec-core (2.6.4)
|
41
|
+
rspec-expectations (2.6.0)
|
42
|
+
diff-lcs (~> 1.1.2)
|
43
|
+
rspec-mocks (2.6.0)
|
44
|
+
thor (0.14.6)
|
45
|
+
vcr (1.3.3)
|
46
|
+
xml-simple (1.1.1)
|
47
|
+
yajl-ruby (1.0.0)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
growl_notify (~> 0.0.3)
|
54
|
+
guard (~> 0.6.3)
|
55
|
+
guard-bundler (~> 0.1.3)
|
56
|
+
guard-rspec (~> 0.4.5)
|
57
|
+
imgshark!
|
58
|
+
rspec (~> 2.6.0)
|
59
|
+
vcr (~> 1.3.3)
|
data/Guardfile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^spec/.+_spec\.rb$})
|
11
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
12
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
13
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
14
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
15
|
+
watch('spec/spec_helper.rb') { "spec" }
|
16
|
+
watch('config/routes.rb') { "spec/routing" }
|
17
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
18
|
+
# Capybara request specs
|
19
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
guard 'bundler' do
|
24
|
+
watch('Gemfile')
|
25
|
+
# Uncomment next line if Gemfile contain `gemspec' command
|
26
|
+
# watch(/^.+\.gemspec/)
|
27
|
+
end
|
data/README
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
ImgShark
|
2
|
+
========
|
3
|
+
Like a shark its, uh, good at resizing and storing images, an images archive.
|
4
|
+
|
5
|
+
Install
|
6
|
+
-------
|
7
|
+
|
8
|
+
gem install imgshark
|
9
|
+
|
10
|
+
Requirements
|
11
|
+
------------
|
12
|
+
- Redis - `brew install redis` or `heroku addons:add redistogo:nano` the gem will pickup the `REDISTOGO_URL` env variable when deployed on heroku.
|
13
|
+
|
14
|
+
- Amazon S3 account. The gem will look for `AMAZON_ACCESS_KEY_ID` and `AMAZON_SECRET_ACCESS_KEY` env varialbes to connect to your account, you can always specify the connection parameters manually (show below).
|
15
|
+
|
16
|
+
Usage
|
17
|
+
-----
|
18
|
+
|
19
|
+
require 'imgshark'
|
20
|
+
|
21
|
+
# You can initialize it manually or use env variables.
|
22
|
+
# The amazon env variables are named the same as the keys below.
|
23
|
+
# The Redis env variable is REDISTOGO_URL so its heroku ready.
|
24
|
+
i = ImgShark.new(amazon_access_key_id: 'somekey',
|
25
|
+
amazon_secret_access_key: 'shhhhh',
|
26
|
+
amazon_bucket: 'bucket_of_awesome',
|
27
|
+
redis_url: 'redis://whereisredis:someport/0')
|
28
|
+
# => #<ImgShark:0x000001025658a8 @redis=#<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.4.2)>, @json=#<Yajl::Parser:0x00000102564e58>, @bucket="bucket_of_awesome">
|
29
|
+
|
30
|
+
i.redis.flushall
|
31
|
+
# => "OK"
|
32
|
+
i.redis.keys
|
33
|
+
# => []
|
34
|
+
|
35
|
+
i.get_url('http://i.imgur.com/onLqO.jpg', 100, 100)
|
36
|
+
# => "http://s3.amazonaws.com/bucket_of_awesome/onLqO_100X100.jpg"
|
37
|
+
|
38
|
+
i.redis.keys
|
39
|
+
# => ["cabf75fecf67c2197e2034aed0e90e36ed899342"]
|
40
|
+
|
41
|
+
i.get_url('http://underwaterschoolbus.com/images/Godzilla.gif', 100, 100)
|
42
|
+
# => "http://s3.amazonaws.com/bucket_of_awesome/images/Godzilla_100X100.gif"
|
43
|
+
|
44
|
+
i.redis.keys
|
45
|
+
# => ["cabf75fecf67c2197e2034aed0e90e36ed899342", "c54cc8e5d37b467b943cb6eed8c632c4d1985a9f"]
|
46
|
+
|
47
|
+
i.get_url('http://underwaterschoolbus.com/images/Godzilla.gif', 400, 400)
|
48
|
+
# => "http://s3.amazonaws.com/bucket_of_awesome/images/Godzilla_400X400.gif"
|
49
|
+
|
50
|
+
i.redis.keys
|
51
|
+
# => ["cabf75fecf67c2197e2034aed0e90e36ed899342", "8a5b2e4b49aeda688a9fdc15764e6edf01e10e81", "c54cc8e5d37b467b943cb6eed8c632c4d1985a9f"]
|
52
|
+
|
53
|
+
|
data/Rakefile
ADDED
data/imgshark.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dickburt/version"
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "imgshark"
|
6
|
+
s.version = Dickburt::VERSION
|
7
|
+
s.authors = ["Tyler Montgomery"]
|
8
|
+
s.email = ["tyler@everlater.com"]
|
9
|
+
s.homepage = "http://github.com/ubermajestix/imgshark"
|
10
|
+
s.summary = %q{Resizes images, stores info in Redis, puts new image on S3}
|
11
|
+
s.description = %q{sharking about}
|
12
|
+
|
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 'redis', '~> 2.0 '
|
19
|
+
s.add_dependency 'aws-s3', '~> 0.6.2'
|
20
|
+
s.add_dependency 'yajl-ruby', '~> 1.0.0'
|
21
|
+
s.add_dependency 'map', '~> 4.5.0'
|
22
|
+
s.add_dependency 'http', '~> 0.0.2'
|
23
|
+
s.add_dependency 'rmagick', '~> 2.13.1'
|
24
|
+
|
25
|
+
s.add_development_dependency 'rspec', '~> 2.6.0'
|
26
|
+
s.add_development_dependency 'vcr', '~> 1.3.3'
|
27
|
+
end
|
data/lib/imgshark.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require "aws/s3"
|
2
|
+
require "redis"
|
3
|
+
require 'digest/sha1'
|
4
|
+
require 'yajl'
|
5
|
+
require 'json'
|
6
|
+
require 'map'
|
7
|
+
require 'http'
|
8
|
+
require 'rmagick'
|
9
|
+
|
10
|
+
class ImgShark
|
11
|
+
|
12
|
+
attr_reader :redis
|
13
|
+
attr_reader :json
|
14
|
+
attr_accessor :bucket
|
15
|
+
|
16
|
+
def initialize(opts = {})
|
17
|
+
AWS::S3::Base.establish_connection!(
|
18
|
+
:access_key_id => opts.delete(:amazon_access_key_id) || ENV['AMAZON_ACCESS_KEY_ID'],
|
19
|
+
:secret_access_key => opts.delete(:amazon_secret_access_key) || ENV['AMAZON_SECRET_ACCESS_KEY']
|
20
|
+
)
|
21
|
+
redis_url = opts.delete(:redis_url) || ENV['REDISTOGO_URL']
|
22
|
+
@redis = redis_url ? Redis.new(redis_url) : Redis.new()
|
23
|
+
@json = Yajl::Parser.new
|
24
|
+
@bucket = opts.delete(:amazon_bucket) || ENV['AMAZON_BUCKET']
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_url(url, height, width)
|
28
|
+
@image = ImgShark::Image.new(self, url: url, h: height, w: width)
|
29
|
+
if @image.exists?
|
30
|
+
find(@image.key).amazon_url
|
31
|
+
else
|
32
|
+
if !@image.on_amazon?
|
33
|
+
@image.resize
|
34
|
+
@image.upload
|
35
|
+
end
|
36
|
+
@image.save
|
37
|
+
@image.amazon_url
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def find(key, response_type = {object: true})
|
42
|
+
response = redis.get(key)
|
43
|
+
if response_type[:object]
|
44
|
+
ImgShark::Image.new(self, json.parse(response)) if response && response.kind_of?(String)
|
45
|
+
elsif response_type[:json]
|
46
|
+
json.parse response
|
47
|
+
else
|
48
|
+
response
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
class ImgShark::Image < Map
|
55
|
+
|
56
|
+
attr_reader :imgshark
|
57
|
+
attr_accessor :blob
|
58
|
+
|
59
|
+
def initialize(imgshark, attributes)
|
60
|
+
@imgshark = imgshark
|
61
|
+
super(attributes)
|
62
|
+
end
|
63
|
+
|
64
|
+
def save
|
65
|
+
response = imgshark.redis.set(key, attributes.to_json)
|
66
|
+
response == 'OK'
|
67
|
+
end
|
68
|
+
|
69
|
+
def exists?
|
70
|
+
!!imgshark.find(key, {})
|
71
|
+
end
|
72
|
+
|
73
|
+
def resize
|
74
|
+
data = Http.get(url) # todo check status
|
75
|
+
data = Magick::Image.from_blob(data).first
|
76
|
+
self.blob = data.resize_to_fill(width, height).to_blob
|
77
|
+
end
|
78
|
+
|
79
|
+
def upload(opts = {:access => :public_read})
|
80
|
+
raise 'no blob' unless blob
|
81
|
+
# TODO upload only if the image isn't there
|
82
|
+
AWS::S3::S3Object.store(filename, blob, imgshark.bucket, opts)
|
83
|
+
end
|
84
|
+
|
85
|
+
def attributes
|
86
|
+
{url: url, h: height, w: width, amazon_url: amazon_url }
|
87
|
+
end
|
88
|
+
|
89
|
+
def filename
|
90
|
+
@filename = url.split('/', 4).last
|
91
|
+
ext = File.extname(@filename)
|
92
|
+
@filename.gsub(ext, "_#{height}X#{width}#{ext}")
|
93
|
+
end
|
94
|
+
|
95
|
+
def height
|
96
|
+
self.h.to_i
|
97
|
+
end
|
98
|
+
|
99
|
+
def width
|
100
|
+
self.w.to_i
|
101
|
+
end
|
102
|
+
|
103
|
+
def amazon_url
|
104
|
+
"http://s3.amazonaws.com/#{amazon_path}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def amazon_path
|
108
|
+
"#{imgshark.bucket}/#{filename}"
|
109
|
+
end
|
110
|
+
|
111
|
+
def on_amazon?
|
112
|
+
Http.head(amazon_url).status == 200
|
113
|
+
end
|
114
|
+
|
115
|
+
def key
|
116
|
+
Digest::SHA1.hexdigest("#{url}#{height}#{width}")
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ImgShark do
|
4
|
+
|
5
|
+
# TODO use vcr
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@img = ImgShark.new(amazon_bucket: 'ubermajestix')
|
9
|
+
@image = ImgShark::Image.new @img, url: 'http://example.com/example.png', h: 1, w: 1
|
10
|
+
redis.set @image.key, @image.attributes.to_json
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should grab an image from the internet, resize it, store it on s3 and give me the new url" do
|
14
|
+
@img.get_url('http://i.imgur.com/onLqO.jpg', 20, 20).should == "http://s3.amazonaws.com/ubermajestix/onLqO_20X20.jpg"
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ImgShark::Image do
|
21
|
+
before :each do
|
22
|
+
@img = ImgShark.new()
|
23
|
+
@image = ImgShark::Image.new(@img, url: 'http://example.com/example.png', h: 1, w: 1)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should respond to height and width" do
|
27
|
+
@image.width.should == 1
|
28
|
+
@image.height.should == 1
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should get a filename with the size init" do
|
32
|
+
@image.filename.should == "example_1X1.png"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should know if something doesn't exist" do
|
36
|
+
@image.should_not exist
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: imgshark
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tyler Montgomery
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-11-30 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: redis
|
16
|
+
requirement: &2157325680 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2157325680
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: aws-s3
|
27
|
+
requirement: &2157325120 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.6.2
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2157325120
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: yajl-ruby
|
38
|
+
requirement: &2157324500 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.0.0
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2157324500
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: map
|
49
|
+
requirement: &2157323980 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.5.0
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2157323980
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: http
|
60
|
+
requirement: &2157323320 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.0.2
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2157323320
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rmagick
|
71
|
+
requirement: &2157322740 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.13.1
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2157322740
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rspec
|
82
|
+
requirement: &2157322120 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 2.6.0
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2157322120
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: vcr
|
93
|
+
requirement: &2157320860 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 1.3.3
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *2157320860
|
102
|
+
description: sharking about
|
103
|
+
email:
|
104
|
+
- tyler@everlater.com
|
105
|
+
executables: []
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- .rspec
|
110
|
+
- Gemfile
|
111
|
+
- Gemfile.lock
|
112
|
+
- Guardfile
|
113
|
+
- README
|
114
|
+
- Rakefile
|
115
|
+
- imgshark.gemspec
|
116
|
+
- lib/imgshark.rb
|
117
|
+
- spec/imgshark_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
119
|
+
homepage: http://github.com/ubermajestix/imgshark
|
120
|
+
licenses: []
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ! '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 1.8.10
|
140
|
+
signing_key:
|
141
|
+
specification_version: 3
|
142
|
+
summary: Resizes images, stores info in Redis, puts new image on S3
|
143
|
+
test_files:
|
144
|
+
- spec/imgshark_spec.rb
|
145
|
+
- spec/spec_helper.rb
|