simplificator-rwebthumb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,29 @@
1
+ == rwebthumb
2
+
3
+ = what is it
4
+ A Ruby wrapper for the webthumb API from http://webthumb.bluga.net
5
+
6
+ = dependencies
7
+ - tzinfo:http://tzinfo.rubyforge.org (install: sudo gem install tzinfo)
8
+
9
+ = Usage
10
+ # Creating a Webthumb Object. This is used as your main access point
11
+ wt = Webthumb.new('YOUR API KEY')
12
+
13
+ # Create a new thumbnail job
14
+ job = wt.thumbnail(:url => 'http://simplificator.com')
15
+
16
+ # fetch the thumbnail. this might throw an exception from server side
17
+ # if thumb is not ready yet
18
+ job.fetch(:large)
19
+
20
+ # you can check the status of a job
21
+ job.check_status()
22
+
23
+ # or fetch the thumbnail when it is complete
24
+ job.fetch_when_complete(:large)
25
+
26
+ # once thumbnails are fetched they are cached within the job. so a new fetch will not go to the server again
27
+
28
+ # there is a helper method to write the images to disk
29
+ job.write_file(, '/tmp/test.jpg')
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'rwebthumb'
2
+ puts "****"
data/lib/rwebthumb.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'tzinfo'
2
+ require 'rwebthumb/base'
3
+ require 'rwebthumb/job'
4
+ require 'rwebthumb/webthumb'
@@ -0,0 +1,82 @@
1
+ module Simplificator
2
+ module Webthumb
3
+ #
4
+ #
5
+ #
6
+ #
7
+ class Base
8
+ # Valid output_types for thumbnail requests
9
+ VALID_OUTPUT_TYPES = [:jpg, :png]
10
+ # Valid values for size element in fetch requests
11
+ VALID_SIZES = [:small, :medium, :medium2, :large, :full, :excerpt, :effect, :custom, :zip]
12
+
13
+ # Timezone to convert from MST (Webthumb) to UTC
14
+ MST_TIMEZONE = TZInfo::Timezone.get('MST')
15
+
16
+ attr_reader :api_key
17
+ # Constructor
18
+ # api_key: the Webthumb api key, not nil and not blank
19
+ #
20
+ def initialize(api_key, api_endpoint = 'http://webthumb.bluga.net/api.php')
21
+ raise WebthumbException.new('Need an noot nil and not blank api_key') if api_key == nil || api_key == ''
22
+ @api_key = api_key
23
+ @api_endpoint = api_endpoint
24
+ @api_uri = URI.parse(@api_endpoint)
25
+ end
26
+
27
+ # Parse the datetime string and returns a DateTime object in UTC time
28
+ # Webthumb returns the time in MST (Mountain Standard Time) which is some 7 hours
29
+ # behind UTC
30
+ def self.parse_webthumb_datetime(s)
31
+ MST_TIMEZONE.local_to_utc(DateTime.strptime(s, '%Y-%m-%d %H:%M:%S'))
32
+ end
33
+
34
+ def do_request(xml)
35
+ request = Net::HTTP::Post.new(@api_uri.path)
36
+ request.body = xml.to_s
37
+ response = Net::HTTP.new(@api_uri.host, @api_uri.port).start {|p| p.request(request) }
38
+ case response
39
+ when Net::HTTPOK :
40
+ case response.content_type
41
+ when 'text/xml' : REXML::Document.new(response.body)
42
+ when 'image/jpg'
43
+ when 'image/jpeg'
44
+ when 'image/png'
45
+ response.body
46
+ else
47
+ raise WebthumbException.new("usupported content type #{response.content_type}. Body was: \n#{response.body}")
48
+ end
49
+ else
50
+ raise CommunicationException('Response code was not HTTP OK')
51
+ end
52
+ end
53
+
54
+ # builds the root node for webthumb requtes
55
+ def build_root_node()
56
+ root = REXML::Element.new('webthumb')
57
+ api = root.add_element('apikey')
58
+ api.text = @api_key
59
+ root
60
+ end
61
+
62
+ protected
63
+ #
64
+ # add a XML element if value is present.
65
+ # can be used to create XML for webthumb requests from ruby options hash.
66
+ #
67
+ # root: the root XML element where element is added to
68
+ # options: the hash where value is taken from
69
+ # key: the key to lookup the value in options
70
+ # name: the name of the XML element. defaults to key
71
+ #
72
+ def add_element(root, options, key, name = key.to_s)
73
+ root.add_element(name).add_text(options[key].to_s) if options.has_key?(key)
74
+ end
75
+
76
+ end
77
+ class WebthumbException < RuntimeError
78
+ end
79
+ class CommunicationException < RuntimeError
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,99 @@
1
+ module Simplificator
2
+ module Webthumb
3
+ class Job < Base
4
+
5
+ attr_reader :duration_estimate, :submission_datetime, :cost, :job_id, :url
6
+
7
+ # Constant for the status attribute when job is beeing processed
8
+ STATUS_PROCESSING = 100
9
+ # Constant for the status attribute when job is done
10
+ STATUS_PICKUP = 200
11
+
12
+ # Factory method to build a Job object from a REXML xml element
13
+ def self.from_thumbnail_xml(api_key, xml)
14
+ job_element = REXML::XPath.first(xml, '/webthumb/jobs/job')
15
+ submission_datetime = self.parse_webthumb_datetime(job_element.attributes['time'])
16
+ Job.new(api_key, job_element.text, job_element.attributes['url'], submission_datetime, job_element.attributes['estimate'].to_i, job_element.attributes['cost'].to_i)
17
+ end
18
+
19
+ def self.from_status_xml(api_key, xml)
20
+ status_element = REXML::XPath.first(xml, '/webthumb/jobStatus/status')
21
+ submission_datetime = self.parse_webthumb_datetime(status_element.attributes['submissionTime'])
22
+ job = Job.new(api_key, status_element.attributes['id'], nil, submission_datetime, 5, nil,
23
+ status_element.text == 'Complete' ? STATUS_PICKUP : STATUS_PROCESSING)
24
+ end
25
+
26
+ def initialize(api_key, job_id, url, submission_datetime, duration_estimate, cost, status = STATUS_PROCESSING)
27
+ super(api_key)
28
+ @job_id = job_id
29
+ @url = url
30
+ @submission_datetime = submission_datetime
31
+ @duration_estimate = duration_estimate
32
+ @cost = cost
33
+ @status = status
34
+ @cache = {}
35
+ end
36
+
37
+ def request_status
38
+ response = do_request(build_status_xml())
39
+ @status = REXML::XPath.first(response, '/webthumb/jobStatus/status').text == 'Complete' ? STATUS_PICKUP : STATUS_PROCESSING
40
+ if pickup?
41
+ @completion_time = response.attributes['completionTime']
42
+ @duration = 'not yet... need to convert times first'
43
+ end
44
+ @status
45
+ end
46
+
47
+ def fetch_when_complete(size = :small)
48
+ while not pickup?
49
+ puts "waiting for #{@duration_estimate}"
50
+ sleep @duration_estimate
51
+ request_status
52
+ end
53
+ fetch(size)
54
+ end
55
+
56
+ def fetch(size = :small)
57
+ unless @cache.has_key?(size)
58
+ response = do_request(build_fetch_xml(size))
59
+ @cache[size] = response
60
+ end
61
+ @cache[size]
62
+ end
63
+
64
+ def write_file(data, name)
65
+ File.open(name, 'wb+') do |file|
66
+ file.write(data)
67
+ file.close
68
+ end
69
+ end
70
+
71
+ def pickup?
72
+ @status == STATUS_PICKUP
73
+ end
74
+ def processing?
75
+ @status == STATUS_PROCESSING
76
+ end
77
+
78
+ private
79
+ def build_fetch_xml(size = :small)
80
+ raise WebthumbException.new("size parameter must be one of #{VALID_SIZES.join(', ')} but was #{size}") unless Base::VALID_SIZES.include?(size)
81
+ root = build_root_node()
82
+ fetch = root.add_element('fetch')
83
+ fetch.add_element('job').add_text(@job_id)
84
+ fetch.add_element('size').add_text(size.to_s)
85
+ root
86
+ end
87
+ def build_status_xml()
88
+ root = build_root_node()
89
+ status = root.add_element('status')
90
+ status.add_element('job').add_text(@job_id)
91
+ root
92
+ end
93
+
94
+ def to_s
95
+ "Job: #{@job_id} / Status: #{@status} / Submission Time #{@submission_time} / Duration Estimate #{@duration_estimate}"
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,69 @@
1
+ require 'net/http'
2
+ require 'rexml/document'
3
+ require 'date'
4
+ module Simplificator
5
+ module Webthumb
6
+
7
+
8
+ class Webthumb < Base
9
+ def thumbnail(options = {})
10
+ Job.from_thumbnail_xml(@api_key, do_request(build_thumbnail_xml(options)))
11
+ end
12
+
13
+ def job_status(job_id)
14
+ Job.from_status_xml(@api_key, do_request(build_job_status_xml(job_id)))
15
+ end
16
+
17
+ def credits()
18
+ root = build_root_node()
19
+ root.add_element('credits')
20
+ elements = do_request(root).elements['webthumb'].elements['credits'].elements
21
+ {:reserve => elements['reserve'].text.to_i, :subscription => elements['subscription'].text.to_i}
22
+ end
23
+
24
+ private
25
+ def build_thumbnail_xml(options)
26
+ validate_thumbnail_options(options)
27
+
28
+
29
+ root = build_root_node()
30
+ request = root.add_element('request')
31
+ request.add_element('url').add_text(options[:url])
32
+ add_element(request, options, :output_type, 'outputType')
33
+ [:width, :height, :effect, :delay, :notofy].each {|item| add_element(request, options, item)}
34
+
35
+ if options[:fullthumb] == true
36
+ request.add_element('fullthumb').add_text('1')
37
+ end
38
+ if options.has_key?(:custom_thumbnail)
39
+ request.add_element('customThumbnail',
40
+ 'width' => options[:custom_thumbnail][:width].to_s,
41
+ 'height' => options[:custom_thumbnail][:height].to_s)
42
+
43
+ end
44
+ if options.has_key?(:excerpt)
45
+ excerpt = request.add_element('excerpt')
46
+ [:x, :y, :width, :height].each {|item| add_element(excerpt, options[:excerpt], item)}
47
+ end
48
+ root
49
+ end
50
+
51
+ def build_job_status_xml(job_id)
52
+ root = build_root_node()
53
+ root.add_element('status').add_element('job').add_text(job_id)
54
+ root
55
+ end
56
+
57
+ def validate_thumbnail_options(options)
58
+ raise WebthumbException.new('Need an URL') if options[:url] == nil || options[:url] == ''
59
+ raise WebthumbException.new("output_type is invalid: #{options[:output_type]}") if options.has_key?(:output_type) and (not Base::VALID_OUTPUT_TYPES.include?(options[:output_type]))
60
+
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+
68
+
69
+
data/test/base_test.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+ class BaseTest < Test::Unit::TestCase
3
+ def test_api_key_required
4
+ assert_raises(WebthumbException) { Base.new('') }
5
+ assert_raises(WebthumbException) { Base.new(nil) }
6
+ end
7
+
8
+ def test_parse_webthumb_date
9
+ [['2000-1-1 14:00:00', '2000-1-1 07:00:00'], ['2000-1-1 07:00:00', '2000-1-1 00:00:00'], ['2000-8-1 07:44:2', '2000-8-1 00:44:02']].each do |item|
10
+ utc = DateTime.strptime(item[0], '%Y-%m-%d %H:%M:%S')
11
+ mst = Base.parse_webthumb_datetime(item[1])
12
+ assert_equal(utc, mst)
13
+ end
14
+ end
15
+
16
+ def test_build_root_node()
17
+ root = Base.new('1234').build_root_node()
18
+ assert_not_nil(root)
19
+ assert_not_nil(REXML::XPath.first(root, '/'))
20
+ assert_not_nil(REXML::XPath.first(root, '/apikey'))
21
+ assert_equal('1234', REXML::XPath.first(root, '/apikey').text)
22
+ end
23
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'rwebthumb'
4
+ include Simplificator::Webthumb
data/test/job_test.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'helper'
2
+ class JobTest < Test::Unit::TestCase
3
+ def setup()
4
+ xml = <<-EOF
5
+ <webthumb>
6
+ <jobs>
7
+ <job estimate='20' time='2008-02-27 12:49:48' url='http://blog.joshuaeichorn.com' cost='1'>wt47c5f71c37c3a</job>
8
+ </jobs>
9
+ </webthumb>
10
+ EOF
11
+ job_xml = REXML::Document.new(xml)
12
+ @job = Job.from_thumbnail_xml('1234', job_xml)
13
+ end
14
+ def test_from_thumbnail_xml
15
+
16
+ assert_equal('1234', @job.api_key)
17
+ assert_equal(20, @job.duration_estimate)
18
+ assert_equal(DateTime.strptime('2008-02-27 19:49:48', '%Y-%m-%d %H:%M:%S'), @job.submission_datetime)
19
+ assert_equal('http://blog.joshuaeichorn.com', @job.url)
20
+ assert_equal(1, @job.cost)
21
+ assert_equal('wt47c5f71c37c3a', @job.job_id)
22
+ end
23
+
24
+
25
+ def test_build_fetch()
26
+ xml = @job.send(:build_fetch_xml)
27
+ assert_equal('small', REXML::XPath.first(xml, 'fetch/size').text)
28
+ assert_equal('wt47c5f71c37c3a', REXML::XPath.first(xml, 'fetch/job').text)
29
+ end
30
+
31
+ def test_build_status_xml()
32
+ xml = @job.send(:build_status_xml)
33
+ assert_equal('wt47c5f71c37c3a', REXML::XPath.first(xml, 'status/job').text)
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ require 'helper'
2
+ class WebthumbTest < Test::Unit::TestCase
3
+
4
+
5
+
6
+ def test_build_fetch()
7
+ xml = Webthumb.new('1234').send(:build_thumbnail_xml, :url => 'http://simplificator.com')
8
+ assert_equal('http://simplificator.com', REXML::XPath.first(xml, 'request/url').text)
9
+ end
10
+
11
+ def test_build_job_status_xml()
12
+ xml = Webthumb.new('1234').send(:build_job_status_xml, 'abcd')
13
+ assert_equal('abcd', REXML::XPath.first(xml, 'status/job').text)
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simplificator-rwebthumb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Simplificator GmbH
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-10 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: rwebthumb provides a ruby interface for the webthumb.bluga.net
17
+ email: gems@simplificator.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/rwebthumb.rb
26
+ - lib/rwebthumb/base.rb
27
+ - lib/rwebthumb/job.rb
28
+ - lib/rwebthumb/webthumb.rb
29
+ - test/base_test.rb
30
+ - test/helper.rb
31
+ - test/job_test.rb
32
+ - test/run_test.rb
33
+ - test/webthumb_test.rb
34
+ - README
35
+ - init.rb
36
+ has_rdoc: false
37
+ homepage: http://labs.simplificator.com/
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.2.0
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: rwebthumb provides a ruby interface for the webthumb.bluga.net
62
+ test_files: []
63
+