stilts 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/stilts.rb CHANGED
@@ -2,6 +2,7 @@ module Stilts
2
2
  require 'net/http'
3
3
  require 'net/https'
4
4
  require 'addressable/uri'
5
+ require 'json'
5
6
  # begin
6
7
  # require 'active_support'
7
8
  # rescue LoadError
@@ -10,8 +11,10 @@ module Stilts
10
11
 
11
12
  require 'stilts/configuration'
12
13
  require 'stilts/sender'
14
+ require 'stilts/receiver'
13
15
  require 'stilts/rack'
14
16
  require 'stilts/image'
17
+ require 'stilts/batch'
15
18
  require 'stilts/railtie' if defined?(Rails)
16
19
 
17
20
  LOG_PREFIX = "[Stilts] "
@@ -19,17 +22,20 @@ module Stilts
19
22
  class << self
20
23
 
21
24
  # The sender object is responsible for delivering formatted data to the server.
22
- # Must respond to #send_to_hoptoad. See Stilts::Sender.
23
25
  attr_accessor :sender
24
26
 
25
27
  # A configuration object. Must act like a hash and return sensible
26
28
  # values for all configuration options. See Stilts::Configuration.
27
29
  attr_accessor :configuration
28
30
 
31
+ # A receiver of requests
32
+ attr_accessor :receiver
33
+
29
34
  def configure(silent = false)
30
35
  self.configuration ||= Configuration.new
31
36
  yield(configuration)
32
37
  self.sender = Sender.new(configuration)
38
+ self.receiver = Receiver.new(configuration)
33
39
  end
34
40
 
35
41
  def logger
@@ -0,0 +1,39 @@
1
+ module Stilts
2
+ class Batch
3
+
4
+ attr_accessor :images
5
+
6
+ # Batch is just an array of images
7
+ def initialize
8
+ self.images = []
9
+ end
10
+
11
+ # Send images to Stilts for transformation, first +screen+ and translate +to_json+
12
+ def deliver
13
+ Stilts.sender.send_image_transform_data(self.to_json)
14
+ end
15
+
16
+ # Ready images for transport across voidy vastness of teh interweb
17
+ def to_json
18
+ JSON.generate(self.images.collect{|i| i.to_hash})
19
+ end
20
+
21
+ # :nodoc:
22
+ def << image
23
+ self.images << image
24
+ end
25
+
26
+ # :nodoc:
27
+ def size
28
+ self.images.size
29
+ end
30
+ alias_method :length, :size
31
+
32
+ # :nodoc:
33
+ def empty?
34
+ return true if self.size == 0
35
+ false
36
+ end
37
+
38
+ end
39
+ end
@@ -3,13 +3,16 @@ module Stilts
3
3
  class Configuration
4
4
 
5
5
  OPTIONS = [:api_key, :host, :http_open_timeout, :http_read_timeout, :project_root,
6
- :port, :protocol, :proxy_host, :secure, :framework].freeze
6
+ :port, :protocol, :secure, :framework].freeze
7
7
 
8
8
  # The API key for your project, found on the project edit form.
9
9
  attr_accessor :api_key
10
10
 
11
11
  # The host to connect to
12
12
  attr_accessor :host
13
+
14
+ # The CDN host to connect to
15
+ attr_accessor :cdn_host
13
16
 
14
17
  # The port on which your server runs (defaults to 443 for secure
15
18
  # connections, 80 for insecure connections).
@@ -21,20 +24,31 @@ module Stilts
21
24
  # The path to the project in which the error occurred, such as the RAILS_ROOT
22
25
  attr_accessor :project_root
23
26
 
24
-
25
27
  # The logger used by
26
28
  attr_accessor :logger
27
29
 
28
30
  # The framework is configured to use
29
31
  attr_accessor :framework
32
+
33
+ # The HTTP open timeout in seconds (defaults to 2).
34
+ attr_accessor :http_open_timeout
35
+
36
+ # The HTTP read timeout in seconds (defaults to 5).
37
+ attr_accessor :http_read_timeout
30
38
 
31
39
  alias_method :secure?, :secure
32
40
 
33
41
  def initialize
34
42
  @secure = false
35
- @host = 'localhost'
43
+ # @host = 'stilts.developmentnow.com'
44
+ # @port = 80
45
+ @host = "localhost"
46
+ @port = 3000
47
+ @cdn_host = 'd15ceu2kbcb932.cloudfront.net'
36
48
  @framework = 'Standalone'
37
49
  @protocol = protocol
50
+ @http_open_timeout = 2
51
+ @http_read_timeout = 10
38
52
  end
39
53
 
40
54
  # Allows config options to be read like a hash
data/lib/stilts/image.rb CHANGED
@@ -12,17 +12,17 @@ module Stilts
12
12
  ]
13
13
 
14
14
  # The public location of the image
15
- attr_accessor :url, :device_width_ratio
15
+ attr_accessor :source, :device_width_ratio
16
16
 
17
17
  # :nodoc:
18
- def initialize(args)
19
- self.url = args[:url]
20
- self.device_width_ratio = args[:device_width_ratio] || 1
18
+ def initialize(source, options)
19
+ self.source = source
20
+ self.device_width_ratio = options[:device_width_ratio] || 1
21
21
  end
22
22
 
23
23
  # Generates a SHA1 represenation for a particular URL
24
24
  def url_id
25
- Digest::SHA1.hexdigest(self.url)
25
+ Digest::SHA1.hexdigest(self.source)
26
26
  end
27
27
 
28
28
  # Combines resizing parameters into a short, unique slug to be appended to the final image name
@@ -38,18 +38,27 @@ module Stilts
38
38
  end
39
39
 
40
40
  # Location on server that will server this image
41
- def transformed_url
41
+ def cdn_url
42
42
  Stilts.configuration.protocol + "://" +
43
- Stilts.configuration.host +
44
- "/transform/" +
45
- Stilts.configuration.api_key +
46
- "/" + self.name
43
+ Stilts.configuration.cdn_host +
44
+ "/images/" +
45
+ Stilts.configuration.api_key + "/" +
46
+ self.name
47
+ end
48
+
49
+ def deliver
50
+ Stilts.sender.send_image_transform_data("[#{self.to_json}]")
51
+ end
52
+
53
+ # Ready images for transport across voidy vastness of teh interweb
54
+ def to_json
55
+ JSON.generate(self.to_hash)
47
56
  end
48
57
 
49
58
  # A hash representation of the image attributes
50
59
  def to_hash
51
60
  {
52
- :url => self.url,
61
+ :source => self.source,
53
62
  :name => self.name,
54
63
  }
55
64
  end
@@ -2,28 +2,25 @@ module Stilts
2
2
  module Helpers
3
3
  include ActionView::Helpers
4
4
 
5
- def transform(image)
6
- image = Stilts::Image.new(image)
7
- # @response = Stilts.sender.send_to_resizer({:image_source => image_source}.to_json.to_s)
8
- image_tag(image.transformed_url)
5
+ # Take image transform parameters and generate an image tag and stick it into the batch
6
+ def transform_image(source, transform_options = {}, image_options = {})
7
+ image = Stilts::Image.new(source, transform_options).deliver
8
+ # @image_batch << image
9
+ image_tag(image["url"], image_options)
9
10
  end
10
11
 
11
- def stream_resize(image_source)
12
- b = Benchmark.measure do
13
- @params = Addressable::URI.parse(url.to_s) # TODO get URI.parse out of Addressable to remove the dependency
14
- @params.query_values = {:image_source => image_source, :stream => "1"}
15
- end
16
- # logger.debug { "STREAM BENCHMARK :: #{b}" }
17
-
18
- stream_url = url
19
- stream_url.path = "/resize"
20
- stream_url.query = @params.query
21
- stream_url.to_s
22
- end
23
-
24
- def url
25
- Stilts.configuration.url.dup
26
- end
12
+ # def stream_resize(image_source)
13
+ # b = Benchmark.measure do
14
+ # @params = Addressable::URI.parse(url.to_s) # TODO get URI.parse out of Addressable to remove the dependency
15
+ # @params.query_values = {:image_source => image_source, :stream => "1"}
16
+ # end
17
+ # # logger.debug { "STREAM BENCHMARK :: #{b}" }
18
+ #
19
+ # stream_url = url
20
+ # stream_url.path = "/resize"
21
+ # stream_url.query = @params.query
22
+ # stream_url.to_s
23
+ # end
27
24
 
28
25
  def logger
29
26
  Stilts.configuration.logger
@@ -1,16 +1,16 @@
1
1
  module Stilts
2
2
  module Hooks
3
-
3
+
4
4
  def self.included(base)
5
- base.before_filter :clear_resize_batch
6
- base.after_filter :resize_batch
5
+ base.before_filter :image_batch
6
+ base.append_before_filter :deliver_batch
7
7
  end
8
8
 
9
- def clear_resize_batch
10
- @resize_batch = []
9
+ def image_batch
10
+ @image_batch = Stilts::Batch.new
11
11
  end
12
- def resize_batch
13
- @resize_batch
12
+ def deliver_batch
13
+ @image_batch.deliver unless @image_batch.empty?
14
14
  end
15
15
 
16
16
  end
@@ -1,9 +1,29 @@
1
1
  module Stilts
2
2
  class Receiver
3
+
4
+ def initialize(options = {})
5
+ end
3
6
 
7
+ def receive(response)
8
+ case response
9
+ when Net::HTTPSuccess then
10
+ log :info, "Success: #{response.class}", response
11
+
12
+ return JSON.parse(response.body)
13
+ else
14
+ log :error, "Failure: #{response.class}", response
15
+ end
16
+ end
17
+
4
18
  def logger
5
19
  Stilts.configuration.logger
6
20
  end
7
21
 
22
+ def log(level, message, response = nil)
23
+ logger.send level, LOG_PREFIX + message if logger
24
+ Stilts.report_environment_info
25
+ Stilts.report_response_body(response.body) if response && response.respond_to?(:body)
26
+ end
27
+
8
28
  end
9
29
  end
data/lib/stilts/sender.rb CHANGED
@@ -1,16 +1,10 @@
1
1
  module Stilts
2
2
  class Sender
3
- RESIZER_PATH = "/resize"
4
- RESIZER_HEADERS = {
5
- 'Content-Type' => 'application/json',
6
- 'Accept' => 'application/json'
3
+ TRANSFORM_HEADERS = {
4
+ 'Content-Type' => 'application/json',
5
+ 'Accept' => 'application/json'
7
6
  }
8
7
 
9
- STREAMER_PATH = "/resize"
10
- STREAMER_HEADERS = {
11
- 'Content-Type' => 'image/jpeg',
12
- 'Accept' => 'image/jpeg'
13
- }
14
8
  HTTP_ERRORS = [Timeout::Error,
15
9
  Errno::EINVAL,
16
10
  Errno::ECONNRESET,
@@ -23,64 +17,27 @@ module Stilts
23
17
  attr_accessor :user_agent
24
18
 
25
19
  def initialize(options = {})
26
- [:protocol, :host, :port, :secure].each do |option|
20
+ [:protocol, :host, :port, :secure, :http_open_timeout, :http_read_timeout].each do |option|
27
21
  instance_variable_set("@#{option}", options[option])
28
22
  end
29
- # , :http_open_timeout, :http_read_timeout
30
- end
31
-
32
- def send_to_resizer(data)
33
- http =
34
- Net::HTTP.new(url.host, url.port)
35
-
36
- http.read_timeout = 5
37
- http.open_timeout = 5
38
- http.use_ssl = false
39
- headers = RESIZER_HEADERS.merge({'User-Agent' => user_agent})
40
-
41
- response = begin
42
- logger.debug{"POSTED JSON: #{data} TO: #{url.to_s}" }
43
- http.post(RESIZER_PATH, data, headers)
44
- rescue *HTTP_ERRORS => e
45
- log :error, "Timeout while contacting the server. #{e}"
46
- nil
47
- end
48
-
49
- case response
50
- when Net::HTTPSuccess then
51
- log :info, "Success: #{response.class}", response
52
- return JSON.parse(response.body)
53
- else
54
- log :error, "Failure: #{response.class}", response
55
- end
56
23
  end
57
24
 
58
- def send_to_streamer(data)
59
- http =
60
- Net::HTTP.new(url.host, url.port)
25
+ def send_image_transform_data(data)
26
+ http = Net::HTTP.new(@host, @port)
61
27
 
62
- http.read_timeout = 5
63
- http.open_timeout = 5
28
+ http.read_timeout = @http_read_timeout
29
+ http.open_timeout = @http_open_timeout
64
30
  http.use_ssl = false
31
+ headers = TRANSFORM_HEADERS.merge({'User-Agent' => user_agent})
65
32
 
66
33
  response = begin
67
- http.get(STREAMER_PATH+data, STREAMER_HEADERS)
34
+ http.post("/transform/#{Stilts.configuration.api_key}", data, headers)
68
35
  rescue *HTTP_ERRORS => e
69
36
  log :error, "Timeout while contacting the server. #{e}"
70
37
  nil
71
38
  end
72
39
 
73
- case response
74
- when Net::HTTPSuccess then
75
- log :info, "Success: #{response.class}", response
76
- return response.body
77
- else
78
- log :error, "Failure: #{response.class}", response
79
- end
80
- end
81
-
82
- def url
83
- Stilts.configuration.url.dup
40
+ Stilts.receiver.receive(response)
84
41
  end
85
42
 
86
43
  def log(level, message, response = nil)
@@ -1,3 +1,3 @@
1
1
  module Stilts
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/stilts/batch')
3
+
4
+ describe Stilts::Batch do
5
+ before(:each) do
6
+ @image1, @image2 = random_image, random_image
7
+ @batch = Stilts::Batch.new
8
+ end
9
+
10
+ it "should gather up all the images on a page for resizing" do
11
+ pending "This should really be an integration test"
12
+ end
13
+
14
+ it "should accept new images like an array" do
15
+ @batch << @image1
16
+ @batch.size.should be 1
17
+ end
18
+
19
+ it "should respond to empty?" do
20
+ @batch.empty?.should be true
21
+ @batch << @image1
22
+ @batch.empty?.should be false
23
+ end
24
+
25
+ it "should respond to #to_json" do
26
+ @batch << @image1
27
+ @batch << @image2
28
+ @batch.to_json.should be_a_kind_of(String)
29
+ end
30
+
31
+ describe "#deliver" do
32
+ before(:each) do
33
+ @batch << @image1
34
+ @batch << @image2
35
+ end
36
+
37
+ it "should send a hash of unprocessed images to Stilts" do
38
+ Stilts.sender.user_agent = "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3"
39
+ @batch.deliver
40
+ end
41
+ end
42
+
43
+ # describe "#screen" do
44
+ # it "should check local cache to see if any of the images have already been processed" do
45
+ # pending
46
+ # end
47
+ # it "should skip sending of already processed images to Stilts" do
48
+ # pending
49
+ # # cache fake result, try to resend image
50
+ # end
51
+ # end
52
+
53
+
54
+ end
data/spec/helpers_spec.rb CHANGED
@@ -6,13 +6,14 @@ include Stilts::Helpers
6
6
  describe Stilts::Helpers do
7
7
 
8
8
  before(:each) do
9
+ @image_batch = Stilts::Batch.new
9
10
  @image = test_images[rand(3)]
10
11
  end
11
12
 
12
13
  describe "#transform" do
13
14
  it "should respond with some image tag HTML" do
14
15
 
15
- transform(@image).should =~ /^\<img/
16
+ transform_image("http://bla.com/image.jpg", {}).should =~ /^\<img/
16
17
 
17
18
 
18
19
  end
data/spec/hooks_spec.rb CHANGED
@@ -2,18 +2,5 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
  require File.expand_path(File.dirname(__FILE__) + '/../lib/stilts/rails/hooks')
3
3
 
4
4
  describe Stilts::Hooks do
5
- it "should gather up all the images on a page for resizing" do
6
- pending "This should really be an integration test"
7
- end
8
- it "should check local cache to see if any of the images have already been processed" do
9
- pending
10
- end
11
- it "should send a hash of unprocessed images to Stilts" do
12
- pending
13
- end
14
- it "should skip sending of already processed images to Stilts" do
15
- pending
16
- # cache fake result, try to resend image
17
- end
18
5
 
19
6
  end
data/spec/image_spec.rb CHANGED
@@ -4,7 +4,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../lib/stilts/image')
4
4
  describe Stilts::Image do
5
5
 
6
6
  before(:each) do
7
- @image = Stilts::Image.new(test_images[rand(3)])
7
+ @image = random_image
8
8
  end
9
9
 
10
10
  it "should have some default values assigned" do
@@ -31,9 +31,9 @@ describe Stilts::Image do
31
31
  end
32
32
  end
33
33
 
34
- describe "#transformed_url" do
35
- it "should respond with the full url of a post-transform image" do
36
- @image.transformed_url.should =~ /^http:\/\//
34
+ describe "#s3_url" do
35
+ it "should respond with the full url of a post-transform and distributed image" do
36
+ @image.cdn_url.should =~ /^http:\/\//
37
37
  end
38
38
  end
39
39
 
@@ -43,11 +43,28 @@ describe Stilts::Image do
43
43
  end
44
44
  it "should have some specific keys" do
45
45
  hash = @image.to_hash
46
- hash[:url].should_not be nil
46
+ hash[:source].should_not be nil
47
47
  hash[:name].should_not be nil
48
48
  end
49
49
  end
50
50
 
51
+ describe "#cached?" do
52
+ it "should return true if the image name is in local cache" do
53
+ pending
54
+ end
55
+ it "should return false if the image name is not found in local cache" do
56
+ pending
57
+ end
58
+ end
59
+
60
+ describe "#to_json" do
61
+ it "should respond to to_json" do
62
+ json = @image.to_json
63
+ json.should be_a_kind_of(String)
64
+ JSON.parse(json).should be_a_kind_of(Hash)
65
+ end
66
+ end
67
+
51
68
  def assert_default_value(option, default_value)
52
69
  default_value.should be @image.send(option)
53
70
  end
@@ -6,4 +6,5 @@ describe Stilts::Receiver do
6
6
  it "should log the round-trip time" do
7
7
  pending
8
8
  end
9
+
9
10
  end
data/spec/spec_helper.rb CHANGED
@@ -9,12 +9,20 @@ end
9
9
 
10
10
  def test_images
11
11
  [
12
- { :url => "http://www.crazy-frog.us/donthotlink-crazy-frog-1024x768-1.jpg" },
13
- { :url => "https://totalfright.websitesource.net/mm5/pics/32901.jpg" },
14
- { :url => "http://iamthatmommy.files.wordpress.com/2010/04/unicorn1.jpg"}
12
+ { :source => "http://www.crazy-frog.us/donthotlink-crazy-frog-1024x768-1.jpg",
13
+ :options => {} },
14
+ { :source => "https://totalfright.websitesource.net/mm5/pics/32901.jpg",
15
+ :options => {} },
16
+ { :source => "http://iamthatmommy.files.wordpress.com/2010/04/unicorn1.jpg",
17
+ :options => {} }
15
18
  ]
16
19
  end
17
20
 
21
+ def random_image
22
+ image_number = rand(test_images.size)
23
+ Stilts::Image.new(test_images[image_number][:source], test_images[image_number][:options])
24
+ end
25
+
18
26
  Stilts.configure do |c|
19
27
  c.api_key = "1234123412341234"
20
28
  end
data/stilts.gemspec CHANGED
@@ -20,4 +20,5 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  s.add_dependency('addressable', '~> 2.2.2')
23
+ s.add_dependency('json', '~> 1.4.6')
23
24
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Graham Powrie
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-19 00:00:00 -08:00
17
+ date: 2011-01-21 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,21 @@ dependencies:
32
32
  version: 2.2.2
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 1
45
+ - 4
46
+ - 6
47
+ version: 1.4.6
48
+ type: :runtime
49
+ version_requirements: *id002
35
50
  description: ""
36
51
  email:
37
52
  - graham@developmentnow.com
@@ -47,6 +62,7 @@ files:
47
62
  - README.md
48
63
  - Rakefile
49
64
  - lib/stilts.rb
65
+ - lib/stilts/batch.rb
50
66
  - lib/stilts/configuration.rb
51
67
  - lib/stilts/image.rb
52
68
  - lib/stilts/rack.rb
@@ -57,6 +73,7 @@ files:
57
73
  - lib/stilts/receiver.rb
58
74
  - lib/stilts/sender.rb
59
75
  - lib/stilts/version.rb
76
+ - spec/batch_spec.rb
60
77
  - spec/configuration_spec.rb
61
78
  - spec/helpers_spec.rb
62
79
  - spec/hooks_spec.rb
@@ -98,6 +115,7 @@ signing_key:
98
115
  specification_version: 3
99
116
  summary: On-the-fly image resizing and management for mobile devices
100
117
  test_files:
118
+ - spec/batch_spec.rb
101
119
  - spec/configuration_spec.rb
102
120
  - spec/helpers_spec.rb
103
121
  - spec/hooks_spec.rb