infovore-ruminant 0.9.4

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,70 @@
1
+ Ruminant
2
+ ========
3
+
4
+ Aiming to make the moo API almost as easy to use for developers as the moo.com site itself.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ If you've never installed a gem from github before - enter the following and you will eternally be graced by a thousand minds:
10
+ gem sources -a http://gems.github.com
11
+
12
+ Then you can install this like any other gem:
13
+ gem install james-ruminant
14
+
15
+
16
+ Usage
17
+ -----
18
+
19
+ All parameters are done in an ActiveRecord attributes style, i.e. they can be passed into new() as a hash, and are all attr-accessors
20
+
21
+ Making an order:
22
+ require 'rubygems'
23
+ require 'moo'
24
+ order = Moo::Order.new(:api_key => "your api key")
25
+
26
+ Adding a product:
27
+ moocard = Moo::MiniCard.new(:url => "http://farm...")
28
+ order.designs << moocard
29
+
30
+ Adding text
31
+ moocard.text = "This is line 1 \n This is line 2"
32
+ moocard.line(1) #=> This is line 1
33
+ moocard.line(1).bold = true
34
+ moocard.line(1).align = "right"
35
+ moocard.line(1).font = "modern"
36
+ moocard.line(1).colour = "#444444"
37
+ moocard.bold = true # sets bold=true on all lines
38
+
39
+ Submitting to moo:
40
+ order.to_xml # Gives you the generated xml if you want to manually submit it
41
+ order.submit
42
+ if order.error?
43
+ order.error_string
44
+ else
45
+ order.start_url
46
+ end
47
+
48
+ Current Limitations
49
+ -------------------
50
+
51
+ Currently I only support MiniCards, but have made it incredibly easy to add the other supported products.
52
+ I haven't yet, as I do not have a personal need, so don't feel I can test it. If you have such a need, do let me know, as we can add it.
53
+
54
+ Manual Cropping is not currently supported for the same reason.
55
+
56
+ Please please please do feel to give feedback and/or submit patches. I want this library to be as helpful as possible, but can only do that if I know what you want.
57
+
58
+ Contributors thus far
59
+ ---------------------
60
+ Xenia Kingsley - Naming powers
61
+ Chris Mear - Fixing stuff, and provides the wine
62
+ Dan Webb - Wisdom
63
+
64
+
65
+ (__)
66
+ (oo)
67
+ /-------\/
68
+ / | ||
69
+ * ||----||
70
+ ~~ ~~
@@ -0,0 +1,20 @@
1
+ module OptionsStruct
2
+ def self.create(*accessors)
3
+ Class.new do
4
+ attr_accessor *accessors
5
+ include Methods
6
+ end
7
+ end
8
+
9
+ module Methods
10
+ def default_options
11
+ {}
12
+ end
13
+
14
+ def initialize(options={})
15
+ default_options.merge(options).each do |name, value|
16
+ self.send("#{name}=",value)
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/design.rb ADDED
@@ -0,0 +1,98 @@
1
+ require 'text_line'
2
+ module Moo
3
+ class Design < OptionsStruct.create(:url, :type, :crop, :lines, :font_size)
4
+ def default_options
5
+ {
6
+ :lines => [],
7
+ :crop => 'auto',
8
+ :type => 'variable'
9
+ }
10
+ end
11
+
12
+ def text=(content)
13
+ content.split("\n").each{|line| lines << TextLine.new(:string => line, :design => self) }
14
+ end
15
+
16
+ def line(n)
17
+ lines[n-1]
18
+ end
19
+
20
+ [:design, :string, :font_size, :bold, :italic, :align, :font, :colour].each do |text_attribute|
21
+ class_eval %{
22
+ # Sets #{text_attribute} attribute on all text lines
23
+ def #{text_attribute}=(value)
24
+ set_attribute_on_all_lines(:#{text_attribute}, value)
25
+ end
26
+ }
27
+ end
28
+
29
+ def self.disable_attributes(attributes=[])
30
+ attributes.each do |attribute|
31
+ class_eval %{
32
+ def #{attribute}=(*args)
33
+ raise DisabledAttributeError
34
+ end
35
+ }
36
+ end
37
+ end
38
+
39
+ def to_xml(xml=Builder::XmlMarkup.new)
40
+ xml.design {
41
+ xml.image {
42
+ xml.url self.url
43
+ xml.type self.type
44
+ xml.crop {
45
+ xml.auto true
46
+ }
47
+ }
48
+ if !product_type.eql?("sticker")
49
+ xml.text_collection {
50
+ xml.tag! product_type {
51
+ xml.minicard {
52
+ lines.each_with_index do |line, index|
53
+ xml.text_line {
54
+ xml.id index+1
55
+ xml.string line.string
56
+ xml.bold line.bold
57
+ xml.align line.align
58
+ xml.font line.font
59
+ xml.colour line.colour
60
+ }
61
+ end
62
+ }
63
+ end
64
+ }
65
+ }
66
+ end
67
+
68
+ private
69
+
70
+ def set_attribute_on_all_lines(attribute, value)
71
+ @lines.each{|line| line.send("#{attribute}=",value)}
72
+ end
73
+
74
+ end
75
+
76
+ class MiniCard < Design
77
+ disable_attributes [:font_size, :italic]
78
+
79
+ def product_type
80
+ "minicard"
81
+ end
82
+ end
83
+
84
+ class Sticker < Design
85
+
86
+ disable_attributes [:font, :font_size, :colour, :align, :bold, :string, :italic]
87
+
88
+ def product_type
89
+ "sticker"
90
+ end
91
+
92
+ undef :text=
93
+ undef :line
94
+ end
95
+
96
+ class DisabledAttributeError < StandardError
97
+ end
98
+ end
data/lib/moo.rb ADDED
@@ -0,0 +1,58 @@
1
+ require 'core_ext/options_struct'
2
+ require 'rubygems'
3
+ require 'builder'
4
+ require 'design'
5
+
6
+ require 'net/http'
7
+ require 'uri'
8
+ require 'hpricot'
9
+
10
+ module Moo
11
+ class Order < OptionsStruct.create(:api_key, :designs)
12
+ def api_version
13
+ 0.7
14
+ end
15
+
16
+ def default_options
17
+ {
18
+ :designs => [],
19
+ :api_key => 0
20
+ }
21
+ end
22
+
23
+ def product_type
24
+ @designs.first.product_type if @designs.first
25
+ end
26
+
27
+ def to_xml(xml=nil)
28
+ xml = Builder::XmlMarkup.new(:target => (@xml_string = "")) unless xml
29
+ eval File.open(File.expand_path(File.dirname(__FILE__) + "/template.xml.builder")).read
30
+ xml.target!
31
+ end
32
+
33
+ attr_accessor :raw_response, :error_string, :error_code, :session_id, :start_url
34
+ def submit
35
+ res = Net::HTTP.post_form(URI.parse('http://www.moo.com/api/api.php'),
36
+ {'xml'=>self.to_xml, 'method'=>'direct'})
37
+ @raw_response = res.body
38
+ process_response
39
+ !error?
40
+ end
41
+
42
+ def process_response
43
+ @response = Hpricot(raw_response)
44
+ if error?
45
+ @error_string = @response.search('error_string').inner_html
46
+ @error_code = @response.search('error_code').inner_html
47
+ else
48
+ @session_id = @response.search('session_id').inner_html
49
+ @start_url = @response.search('start_url').inner_html
50
+ end
51
+ end
52
+
53
+ def error?
54
+ @error ||= (@response.search('error').inner_html == "true")
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,20 @@
1
+ xml.instruct!
2
+ xml.moo("xsi:noNamespaceSchemaLocation" => "http://www.moo.com/xsd/api_0.7.xsd", "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance") {
3
+ xml.request {
4
+ xml.version self.api_version
5
+ xml.api_key self.api_key
6
+ xml.call "build"
7
+ }
8
+ xml.payload{
9
+ xml.products {
10
+ xml.product {
11
+ xml.product_type self.product_type
12
+ xml.designs {
13
+ self.designs.each { |design|
14
+ design.to_xml(xml)
15
+ }
16
+ }
17
+ }
18
+ }
19
+ }
20
+ }
data/lib/text_line.rb ADDED
@@ -0,0 +1,12 @@
1
+ module Moo
2
+ class TextLine < OptionsStruct.create(:design, :string, :font_size, :bold, :italic, :align, :font, :colour)
3
+ def default_options
4
+ {
5
+ :bold => false,
6
+ :align => 'left',
7
+ :font => 'modern',
8
+ :colour => '#000000'
9
+ }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,65 @@
1
+ require File.join(File.dirname(__FILE__), *%w[spec_helper])
2
+
3
+ describe "a minicard" do
4
+ before :each do
5
+ @design = Moo::MiniCard.new(:url => "http://farm3.static.flickr.com/2300/2179038972_23d2a1ff40_o.jpg")
6
+ end
7
+
8
+ it "should have minicard as the type" do
9
+ @design.product_type.should == "minicard"
10
+ end
11
+
12
+ it "should not support size" do
13
+ lambda{@design.font_size = 0.5}.should raise_error(Moo::DisabledAttributeError)
14
+ end
15
+
16
+ it "should not support italic" do
17
+ lambda{@design.italic = true}.should raise_error(Moo::DisabledAttributeError)
18
+ end
19
+ end
20
+
21
+ describe "a sticker" do
22
+ before(:each) do
23
+ @design = Moo::Sticker.new(:url => "")
24
+ end
25
+
26
+ it "should have sticker as the type" do
27
+ @design.product_type.should == "sticker"
28
+ end
29
+
30
+ it "should not support font size" do
31
+ lambda{@design.font_size = 0.5}.should raise_error(Moo::DisabledAttributeError)
32
+ end
33
+
34
+ it "should not support italic" do
35
+ lambda{@design.italic = true}.should raise_error(Moo::DisabledAttributeError)
36
+ end
37
+
38
+ it "should not support string" do
39
+ lambda{@design.string = "foo"}.should raise_error(Moo::DisabledAttributeError)
40
+ end
41
+
42
+ it "should not support bold" do
43
+ lambda{@design.bold = true}.should raise_error(Moo::DisabledAttributeError)
44
+ end
45
+
46
+ it "should not support align" do
47
+ lambda{@design.align = "centre"}.should raise_error(Moo::DisabledAttributeError)
48
+ end
49
+
50
+ it "should not support font" do
51
+ lambda{@design.font = "Normal"}.should raise_error(Moo::DisabledAttributeError)
52
+ end
53
+
54
+ it "should not support colour" do
55
+ lambda{@design.colour = "#ccc"}.should raise_error(Moo::DisabledAttributeError)
56
+ end
57
+
58
+ it "should not support any text" do
59
+ lambda{@design.text = "testing!"}.should raise_error(NoMethodError)
60
+ end
61
+
62
+ it "should not support lines" do
63
+ lambda{@design.line(1)}.should raise_error(NoMethodError)
64
+ end
65
+ end
data/spec/moo_spec.rb ADDED
@@ -0,0 +1,85 @@
1
+ require File.join(File.dirname(__FILE__), *%w[spec_helper])
2
+
3
+ describe "an empty moo order" do
4
+ before :each do
5
+ @moo = Moo::Order.new :api_key => "TESTAPIKEY"
6
+ end
7
+
8
+ it "should have the appropiate header" do
9
+ @moo.to_xml.should include('<?xml version="1.0" encoding="UTF-8"?><moo xsi:noNamespaceSchemaLocation="http://www.moo.com/xsd/api_0.7.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">')
10
+ end
11
+
12
+ it "should user MOO API version 0.7" do
13
+ @moo.to_xml.should include("<version>0.7</version>")
14
+ end
15
+
16
+ it "should include the API key" do
17
+ @moo.to_xml.should include("<api_key>TESTAPIKEY</api_key>")
18
+ end
19
+
20
+ it "should call build" do
21
+ @moo.to_xml.should include("<call>build</call>")
22
+ end
23
+
24
+ it "should not contain to_s" do
25
+ @moo.to_xml.should_not include("to_s")
26
+ end
27
+ end
28
+
29
+ describe "a moo order with a minicard" do
30
+ before :each do
31
+ @moo = Moo::Order.new :api_key => "TESTAPIKEY"
32
+ @minicard = Moo::MiniCard.new(:url => "http://farm3.static.flickr.com/2300/2179038972_23d2a1ff40_o.jpg")
33
+ @moo.designs << @minicard
34
+ end
35
+
36
+ it "should have product type of 'minicard'" do
37
+ @moo.product_type.should == 'minicard'
38
+ @moo.to_xml.should include('<product_type>minicard</product_type>')
39
+ end
40
+
41
+ it "should include the xml for the minicard" do
42
+ @moo.to_xml.should include(@minicard.to_xml)
43
+ end
44
+ end
45
+
46
+ describe "processing an XML response for failure" do
47
+ before :each do
48
+ @moo = Moo::Order.new :api_key => "TESTAPIKEY"
49
+ @moo.stub!(:raw_response).and_return('<?xml version="1.0" encoding="UTF-8"?> <moo> <response> <call>build</call> <error>true</error> </response> <payload> <error_code>1</error_code> <error_string>Error importing XML document</error_string> </payload> </moo>')
50
+ @moo.process_response
51
+ end
52
+
53
+ it "should set error? as true" do
54
+ @moo.error?.should be_true
55
+ end
56
+
57
+ it "should set error_string correctly" do
58
+ @moo.error_string.should == "Error importing XML document"
59
+ end
60
+
61
+ it "should set error_code correctly" do
62
+ @moo.error_code.should == "1"
63
+ end
64
+ end
65
+
66
+
67
+ describe "processing an XML response for success" do
68
+ before :each do
69
+ @moo = Moo::Order.new :api_key => "TESTAPIKEY"
70
+ @moo.stub!(:raw_response).and_return('<?xml version="1.0" encoding="UTF-8"?> <moo> <response> <call>build</call> <api_key>3ddbe3c0-17ac-c0a802d2-47bafd19-2473</api_key> </response> <payload> <session_id>d4c7a6d179fca910d67221a57a1bf966</session_id> <start_url>http://www.moo.com/make/designback.php?bid=1&pid=115&SID=d4c7a6d179fca910d67221a57a1bf966</start_url> </payload> </moo>')
71
+ @moo.process_response
72
+ end
73
+
74
+ it "should set error? as false" do
75
+ @moo.error?.should be_false
76
+ end
77
+
78
+ it "should set start_url correctly" do
79
+ @moo.start_url.should == "http://www.moo.com/make/designback.php?bid=1&pid=115&SID=d4c7a6d179fca910d67221a57a1bf966"
80
+ end
81
+
82
+ it "should set session_id correctly" do
83
+ @moo.session_id.should == "d4c7a6d179fca910d67221a57a1bf966"
84
+ end
85
+ end
@@ -0,0 +1,29 @@
1
+ require File.join(File.dirname(__FILE__), *%w[spec_helper])
2
+
3
+ describe "The Design base class" do
4
+ before :each do
5
+ @design = Moo::Design.new(:url => "http://farm3.static.flickr.com/2300/2179038972_23d2a1ff40_o.jpg")
6
+ @design.stub!(:product_type).and_return("minicard")
7
+
8
+ @design.text = "This is Line 1\nAnd this is the second line"
9
+ end
10
+
11
+ it "should include the design's photo url" do
12
+ @design.to_xml.should include("<url>http://farm3.static.flickr.com/2300/2179038972_23d2a1ff40_o.jpg</url>")
13
+ end
14
+
15
+ it "should store the text into multiple TextLines" do
16
+ @design.line(1).class.should == Moo::TextLine
17
+ @design.line(1).string.should == "This is Line 1"
18
+ @design.line(2).class.should == Moo::TextLine
19
+ @design.line(2).string.should == "And this is the second line"
20
+ end
21
+
22
+ it "should be able to set an attribute on all lines" do
23
+ @design.line(1).bold.should == false
24
+ @design.line(2).bold.should == false
25
+ @design.bold = true
26
+ @design.line(1).bold.should == true
27
+ @design.line(2).bold.should == true
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
2
+
3
+ require 'rubygems'
4
+ require 'spec'
5
+
6
+ require 'moo.rb'
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: infovore-ruminant
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.4
5
+ platform: ruby
6
+ authors:
7
+ - James Darling
8
+ - Tom Armitage
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ date: 2008-09-15 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hpricot
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: builder
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ description: A ruby library to regurgitate MOO products
34
+ email: james@abscond.org tom@infovore.org
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - lib/moo.rb
43
+ - lib/design.rb
44
+ - lib/template.xml.builder
45
+ - lib/text_line.rb
46
+ - lib/core_ext/options_struct.rb
47
+ - README
48
+ has_rdoc: false
49
+ homepage: http://github.com/infovore/ruminant/tree/master
50
+ post_install_message:
51
+ rdoc_options: []
52
+
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">"
58
+ - !ruby/object:Gem::Version
59
+ version: 0.0.0
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.2.0
71
+ signing_key:
72
+ specification_version: 2
73
+ summary: A ruby library to regurgitate MOO products
74
+ test_files:
75
+ - spec/design_spec.rb
76
+ - spec/moo_spec.rb
77
+ - spec/product_spec.rb
78
+ - spec/spec_helper.rb