simplificator-rwebthumb 0.0.1

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/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
+