oas 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ .redcar
4
+ .rvmrc
5
+ Gemfile.lock
6
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ruby-oas.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Realmedia LatinAmerica
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,69 @@
1
+ OAS API Ruby Gem
2
+ ====================
3
+ A Ruby wrapper for OAS 7.4 API
4
+
5
+ Installation
6
+ ------------
7
+ gem install oas
8
+
9
+ Usage Examples
10
+ --------------
11
+ require "rubygems"
12
+ require "oas"
13
+
14
+ # All methods require authentication.
15
+ Oas.configure do |config|
16
+ config.endpoint = WSDL_URI
17
+ config.account = YOUR_OAS_ACCOUNT
18
+ config.username = YOUR_USERNAME
19
+ config.password = YOUR_PASSWORD
20
+ end
21
+
22
+ # Read an advertiser
23
+ puts Oas.advertiser("advertiser_id")
24
+
25
+ # Read an agency
26
+ puts Oas.agency("agency_id")
27
+
28
+ # Read a campaign
29
+ puts Oas.campaign("campaign_id")
30
+
31
+ # Read a campaign group
32
+ puts Oas.campaign_group("campaign_group_id")
33
+
34
+ # Read a creative
35
+ puts Oas.creative("campaign_id", "creative_id")
36
+
37
+ # Read a keyname
38
+ puts Oas.keyname("keyname")
39
+
40
+ # Read a keyword
41
+ puts Oas.keyword("keyword_id")
42
+
43
+ # Read a notification
44
+ puts Oas.notification("campaign_id", "event_name")
45
+
46
+ # Read a page
47
+ puts Oas.page("page_url")
48
+
49
+ # Read a section
50
+ puts Oas.section("section_id")
51
+
52
+ # Read a site
53
+ puts Oas.site("site_id")
54
+
55
+ # Read a site group
56
+ puts Oas.site_group("site_group_id")
57
+
58
+ TODO
59
+ ------------
60
+
61
+ * Create and update support on Campaign and Database sections.
62
+ * Listings
63
+ * Reports
64
+ * Inventory
65
+
66
+ Copyright
67
+ ---------
68
+ Copyright (c) 2011 Realmedia LatinAmerica.
69
+ See [LICENSE](https://github.com/realmedia/ruby-oas/blob/master/LICENSE) for details.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ task :test => :spec
8
+ task :default => :spec
data/lib/oas/api.rb ADDED
@@ -0,0 +1,56 @@
1
+ require 'nokogiri'
2
+ require 'httpclient'
3
+ require 'savon'
4
+
5
+ module Oas
6
+ class Api
7
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
8
+
9
+ def initialize(options={})
10
+ options = Oas.options.merge(options)
11
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
12
+ send("#{key}=", options[key])
13
+ end
14
+ end
15
+
16
+ def request(request_type, &block)
17
+ xml = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
18
+ xml.AdXML {
19
+ xml.Request(:type => request_type) {
20
+ yield(xml) if block_given?
21
+ }
22
+ }
23
+ end
24
+ response = webservice.request :n1, :oas_xml_request, :"xmlns:n1" => "http://api.oas.tfsm.com/" do
25
+ soap.body = {
26
+ "String_1" => account.to_s,
27
+ "String_2" => username.to_s,
28
+ "String_3" => password.to_s,
29
+ "String_4" => xml.to_xml
30
+ }
31
+ end
32
+ response = Hash.from_xml(response.to_hash[:oas_xml_request_response][:result])[:AdXML][:Response]
33
+ verify_errors(request_type, response)
34
+ response
35
+ end
36
+
37
+ private
38
+ def verify_errors(request_type, response)
39
+ return if (e = response[:Exception]).nil? && (e = response[request_type.to_sym][:Exception]).nil?
40
+ error_code = e[:errorCode]
41
+ error_msg = e[:content]
42
+ case error_code
43
+ when 550
44
+ raise Oas::InvalidSite.new(error_msg, error_code)
45
+ when 551
46
+ raise Oas::InvalidPage.new(error_msg, error_code)
47
+ else
48
+ raise Oas::Error.new(error_msg, error_code)
49
+ end
50
+ end
51
+
52
+ def webservice
53
+ @webservice ||= Savon::Client.new(endpoint)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,16 @@
1
+ module Oas
2
+ class Client
3
+ # Defines methods related to oas campaigns
4
+ module Campaign
5
+ def campaign(id)
6
+ request("Campaign") do |xml|
7
+ xml.Campaign(:action => "read") {
8
+ xml.Overview {
9
+ xml.Id id
10
+ }
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Oas
2
+ class Client
3
+ # Defines methods related to oas campaign creatives
4
+ module Creative
5
+ def creative(campaign_id, id)
6
+ request("Creative") do |xml|
7
+ xml.Creative(:action => "read") {
8
+ xml.CampaignId campaign_id
9
+ xml.Id id
10
+ }
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,96 @@
1
+ module Oas
2
+ class Client
3
+ # Defines methods related to oas database section
4
+ module Database
5
+ def advertiser(id)
6
+ request("Advertiser") do |xml|
7
+ xml.Database(:action => "read") {
8
+ xml.Advertiser {
9
+ xml.Id id
10
+ }
11
+ }
12
+ end
13
+ end
14
+
15
+ def agency(id)
16
+ request("Agency") do |xml|
17
+ xml.Database(:action => "read") {
18
+ xml.Agency {
19
+ xml.Id id
20
+ }
21
+ }
22
+ end
23
+ end
24
+
25
+ def campaign_group(id)
26
+ request("CampaignGroup") do |xml|
27
+ xml.Database(:action => "read") {
28
+ xml.CampaignGroup {
29
+ xml.Id id
30
+ }
31
+ }
32
+ end
33
+ end
34
+
35
+ def keyname(name)
36
+ request("Keyname") do |xml|
37
+ xml.Database(:action => "read") {
38
+ xml.Keyname {
39
+ xml.Name name
40
+ }
41
+ }
42
+ end
43
+ end
44
+
45
+ def keyword(id)
46
+ request("Keyword") do |xml|
47
+ xml.Database(:action => "read") {
48
+ xml.Keyword {
49
+ xml.Id id
50
+ }
51
+ }
52
+ end
53
+ end
54
+
55
+ def page(url)
56
+ request("Page") do |xml|
57
+ xml.Database(:action => "read") {
58
+ xml.Page {
59
+ xml.Url url
60
+ }
61
+ }
62
+ end
63
+ end
64
+
65
+ def section(id)
66
+ request("Section") do |xml|
67
+ xml.Database(:action => "read") {
68
+ xml.Section {
69
+ xml.Id id
70
+ }
71
+ }
72
+ end
73
+ end
74
+
75
+ def site(id)
76
+ request("Site") do |xml|
77
+ xml.Database(:action => "read") {
78
+ xml.Site {
79
+ xml.Id id
80
+ }
81
+ }
82
+ end
83
+ end
84
+
85
+ def site_group(id)
86
+ request("SiteGroup") do |xml|
87
+ xml.Database(:action => "read") {
88
+ xml.SiteGroup {
89
+ xml.Id id
90
+ }
91
+ }
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,15 @@
1
+ module Oas
2
+ class Client
3
+ # Defines methods related to oas campaigns
4
+ module Notification
5
+ def notification(campaign_id, event_name)
6
+ request("Notification") do |xml|
7
+ xml.Notification(:action => "read") {
8
+ xml.CampaignId campaign_id
9
+ xml.EventName event_name
10
+ }
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Oas
2
+ class Client
3
+ module Utils
4
+ private
5
+ def build_attributes(xml, attributes = {})
6
+ attributes.each do |key,value|
7
+ if value.is_a?(Hash)
8
+ build_attributes(xml, value)
9
+ else
10
+ xml.send(key.to_sym, value)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/oas/client.rb ADDED
@@ -0,0 +1,15 @@
1
+ module Oas
2
+ class Client < Api
3
+ require 'oas/client/utils'
4
+ require 'oas/client/campaign'
5
+ require 'oas/client/creative'
6
+ require 'oas/client/database'
7
+ require 'oas/client/notification'
8
+
9
+ include Oas::Client::Utils
10
+ include Oas::Client::Campaign
11
+ include Oas::Client::Creative
12
+ include Oas::Client::Database
13
+ include Oas::Client::Notification
14
+ end
15
+ end
@@ -0,0 +1,45 @@
1
+ module Oas
2
+ module Configuration
3
+ # An array of valid keys in the options hash when configuring a {Twitter::Client}
4
+ VALID_OPTIONS_KEYS = [
5
+ :endpoint,
6
+ :account,
7
+ :username,
8
+ :password].freeze
9
+
10
+ # The endpoint that will be used to connect if none is set
11
+ DEFAULT_ENDPOINT = "https://oas.realmedianetwork.net/oasapi/OaxApi?wsdl".freeze
12
+
13
+ # The account that will be used to connect if none is set
14
+ DEFAULT_ACCOUNT = "OasDefault"
15
+
16
+ # By default, don't set a username
17
+ DEFAULT_USERNAME = nil
18
+
19
+ # By default, don't set a password
20
+ DEFAULT_PASSWORD = nil
21
+
22
+ attr_accessor *VALID_OPTIONS_KEYS
23
+
24
+ def self.extended(base)
25
+ base.reset
26
+ end
27
+
28
+ def configure
29
+ yield self if block_given?
30
+ end
31
+
32
+ def options
33
+ options = {}
34
+ VALID_OPTIONS_KEYS.each{|k| options[k] = send(k) }
35
+ options
36
+ end
37
+
38
+ def reset
39
+ self.endpoint = DEFAULT_ENDPOINT
40
+ self.account = DEFAULT_ACCOUNT
41
+ self.username = DEFAULT_USERNAME
42
+ self.password = DEFAULT_PASSWORD
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,57 @@
1
+ require 'nokogiri'
2
+
3
+ class Hash
4
+ class << self
5
+ def from_xml(xml_io)
6
+ result = Nokogiri::XML(xml_io)
7
+ return { result.root.name.to_sym => xml_node_to_hash(result.root) }
8
+ end
9
+
10
+ def xml_node_to_hash(node)
11
+ # If we are at the root of the document, start the hash
12
+ if node.element?
13
+ result_hash = {}
14
+ if node.attributes != {}
15
+ node.attributes.keys.each do |key|
16
+ result_hash[node.attributes[key].name.to_sym] = prepare(node.attributes[key].value)
17
+ end
18
+ end
19
+ if node.children.size > 0
20
+ node.children.each do |child|
21
+ result = xml_node_to_hash(child)
22
+
23
+ if child.name == "text"
24
+ unless child.next_sibling || child.previous_sibling
25
+ result = prepare(result)
26
+ return result if result_hash.empty?
27
+ result_hash[:content] = result
28
+ return result_hash
29
+ end
30
+ elsif result_hash[child.name.to_sym]
31
+ if result_hash[child.name.to_sym].is_a?(Object::Array)
32
+ result_hash[child.name.to_sym] << prepare(result)
33
+ else
34
+ result_hash[child.name.to_sym] = [result_hash[child.name.to_sym]] << prepare(result)
35
+ end
36
+ else
37
+ result_hash[child.name.to_sym] = prepare(result)
38
+ end
39
+ end
40
+ return result_hash
41
+ else
42
+ return nil
43
+ end
44
+ else
45
+ return prepare(node.content.to_s)
46
+ end
47
+ end
48
+
49
+ def prepare(data)
50
+ (data.class == String && data.to_i.to_s == data) ? data.to_i : data
51
+ end
52
+ end
53
+
54
+ def to_struct(struct_name)
55
+ Struct.new(struct_name,*keys).new(*values)
56
+ end
57
+ end
@@ -0,0 +1,6 @@
1
+ class Object
2
+ # From activesupport/lib/active_support/core_ext/object/blank.rb, line 12
3
+ def blank?
4
+ respond_to?(:empty?) ? empty? : !self
5
+ end
6
+ end
data/lib/oas/error.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Oas
2
+ # Custom error class for rescuing from all Oas errors
3
+ class Error < StandardError
4
+ attr_reader :error_code
5
+
6
+ def initialize(message, error_code)
7
+ @error_code = error_code
8
+ super message
9
+ end
10
+ end
11
+
12
+ # Raised when Oas returns the error code 550
13
+ class InvalidSite < Error; end
14
+
15
+ # Raised when Oas returns the error code 551
16
+ class InvalidUrl < Error; end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Oas
2
+ VERSION = "0.1.0"
3
+ end
data/lib/oas.rb ADDED
@@ -0,0 +1,31 @@
1
+ Dir[File.join(File.dirname(__FILE__),'oas/core_ext/**/*.rb')].each {|f| require f}
2
+
3
+ require 'oas/version'
4
+ require 'oas/error'
5
+ require 'oas/configuration'
6
+ require 'oas/api'
7
+ require 'oas/client'
8
+
9
+ module Oas
10
+ extend Configuration
11
+
12
+ # Alias for Oas::Client.new
13
+ #
14
+ # @return [Oas::Client]
15
+ def self.client(options={})
16
+ Oas::Client.new(options)
17
+ end
18
+
19
+ # Delegate to Oas::Client
20
+ def self.method_missing(method, *args, &block)
21
+ return super unless client.respond_to?(method)
22
+ client.send(method, *args, &block)
23
+ end
24
+
25
+ def self.respond_to?(method, include_private = false)
26
+ client.respond_to?(method, include_private) || super(method, include_private)
27
+ end
28
+
29
+ HTTPI.log = false
30
+ Savon.configure { |c| c.log = false }
31
+ end
data/oas.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "oas/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "oas"
7
+ s.version = Oas::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Damian Caruso"]
10
+ s.email = ["damian.caruso@gmail.com"]
11
+ s.homepage = "http://github.com/realmedia/ruby-oas"
12
+ s.summary = %q{Ruby wrapper for the OAS 7.4 API}
13
+ s.description = %q{Ruby wrapper for the OAS 7.4 API}
14
+
15
+ s.rubyforge_project = "oas"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency "httpclient", "~> 2.2.0.2"
23
+ s.add_dependency "nokogiri", "~> 1.4.4"
24
+ s.add_dependency "savon", "~> 0.9.2"
25
+
26
+ s.add_development_dependency "rspec", "~> 2.5.0"
27
+ s.add_development_dependency "webmock", "~> 1.6.2"
28
+ end
@@ -0,0 +1,49 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5
+ <soapenv:Body>
6
+ <ns1:OasXmlRequestResponse xmlns:ns1="http://api.oas.tfsm.com/">
7
+ <result>
8
+ <![CDATA[
9
+ <?xml version="1.0"?>
10
+ <AdXML>
11
+ <Response>
12
+ <Advertiser>
13
+ <Id>advertiser_id</Id>
14
+ <Organization>A Company Name</Organization>
15
+ <Notes></Notes>
16
+ <ContactFirstName></ContactFirstName>
17
+ <ContactLastName></ContactLastName>
18
+ <ContactTitle></ContactTitle>
19
+ <Email></Email>
20
+ <Phone></Phone>
21
+ <Fax></Fax>
22
+ <ExternalUsers/>
23
+ <BillingInformation>
24
+ <Method>
25
+ <Code>O</Code>
26
+ </Method>
27
+ <Address>test address2</Address>
28
+ <City>Philadelphia</City>
29
+ <State>
30
+ <Code>US:PA</Code>
31
+ </State>
32
+ <Country>
33
+ <Code>US</Code>
34
+ </Country>
35
+ <Zip>20007</Zip>
36
+ <Email>testmail@247realmeida.com</Email>
37
+ </BillingInformation>
38
+ <WhoCreated>realmedia</WhoCreated>
39
+ <WhenCreated>01/20/2008 20:59:29</WhenCreated>
40
+ <WhoModified>realmedia</WhoModified>
41
+ <WhenModified>01/20/2008 21:22:33</WhenModified>
42
+ </Advertiser>
43
+ </Response>
44
+ </AdXML>
45
+ ]]>
46
+ </result>
47
+ </ns1:OasXmlRequestResponse>
48
+ </soapenv:Body>
49
+ </soapenv:Envelope>
@@ -0,0 +1,49 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5
+ <soapenv:Body>
6
+ <ns1:OasXmlRequestResponse xmlns:ns1="http://api.oas.tfsm.com/">
7
+ <result>
8
+ <![CDATA[
9
+ <?xml version="1.0"?>
10
+ <AdXML>
11
+ <Response>
12
+ <Agency>
13
+ <Id>agency_id</Id>
14
+ <Organization>A Company Name</Organization>
15
+ <Notes>This Agency was added through the API.(With Billing Info)</Notes>
16
+ <ContactFirstName>Nobody</ContactFirstName>
17
+ <ContactLastName>Kim</ContactLastName>
18
+ <ContactTitle>Senior Engineer</ContactTitle>
19
+ <Email>nobody@247realmedia.com</Email>
20
+ <Phone>123-123-1234</Phone>
21
+ <Fax>123-123-1235</Fax>
22
+ <ExternalUsers>
23
+ <UserId>ExtUser1</UserId>
24
+ <UserId>ExtUser2</UserId>
25
+ </ExternalUsers>
26
+ <BillingInformation>
27
+ <Method>
28
+ <Code>M</Code>
29
+ </Method>
30
+ <Address>51-12 BANPO 4-DONG SEOCHO-GU, SEOUL, SOUTH KOREA</Address>
31
+ <City>SEOUL</City>
32
+ <State>
33
+ <Code>KR:SOULTUKPYOLS</Code>
34
+ </State>
35
+ <Country>
36
+ <Code>KR</Code>
37
+ </Country>
38
+ <Zip>137-802</Zip>
39
+ </BillingInformation>
40
+ <InternalQuickReport>short</InternalQuickReport>
41
+ <ExternalQuickReport>to-date</ExternalQuickReport>
42
+ </Agency>
43
+ </Response>
44
+ </AdXML>
45
+ ]]>
46
+ </result>
47
+ </ns1:OasXmlRequestResponse>
48
+ </soapenv:Body>
49
+ </soapenv:Envelope>