infovore-ruminant 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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