touchlocal-openx 1.1.0

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.
@@ -0,0 +1,124 @@
1
+ require 'yaml'
2
+
3
+ module OpenX
4
+ module Services
5
+ class Base
6
+ include Comparable
7
+
8
+ CONFIGURATION_YAML = File.join(ENV['HOME'], '.openx', 'credentials.yml')
9
+
10
+ @@connection = nil
11
+ @@configuration = nil
12
+
13
+ class << self
14
+ attr_accessor :translations
15
+ attr_accessor :create, :update, :delete, :find_one, :find_all
16
+
17
+ def configuration
18
+ @@configuration ||=
19
+ YAML.load_file(CONFIGURATION_YAML)[ENV['OPENX_ENV'] || 'production']
20
+ end
21
+
22
+ def configuration=(c); @@configuration = c; end
23
+
24
+ def connection= c
25
+ @@connection = c
26
+ end
27
+
28
+ def connection
29
+ unless @@connection
30
+ @@connection = Session.new(configuration['url'])
31
+ @@connection.create( configuration['username'],
32
+ configuration['password']
33
+ )
34
+ end
35
+ @@connection
36
+ end
37
+
38
+ def create!(params = {})
39
+ new(params).save!
40
+ end
41
+
42
+ def openx_accessor(accessor_map)
43
+ @translations ||= {}
44
+ @translations = accessor_map.merge(@translations)
45
+ accessor_map.each do |ruby,openx|
46
+ attr_accessor :"#{ruby}"
47
+ end
48
+ end
49
+
50
+ def has_one(*things)
51
+ things.each do |thing|
52
+ attr_writer :"#{thing}"
53
+ define_method(:"#{thing}") do
54
+ klass = thing.to_s.capitalize.gsub(/_[a-z]/) { |m| m[1].chr.upcase }
55
+ klass = OpenX::Services.const_get(:"#{klass}")
56
+ klass.find(send("#{thing}_id"))
57
+ end
58
+ end
59
+ end
60
+
61
+ def find(id, *args)
62
+ session = self.connection
63
+ server = XmlrpcClient.new2("#{session.url}")
64
+ if id == :all
65
+ responses = server.call(find_all(), session, *args)
66
+ responses.map { |response|
67
+ new(translate(response))
68
+ }
69
+ else
70
+ response = server.call(find_one(), session, id)
71
+ new(translate(response))
72
+ end
73
+ end
74
+
75
+ def destroy(id)
76
+ new(:id => id).destroy
77
+ end
78
+
79
+ private
80
+ def translate(response)
81
+ params = {}
82
+ self.translations.each { |k,v|
83
+ params[k] = response[v.to_s] if response[v.to_s]
84
+ }
85
+ params
86
+ end
87
+ end
88
+
89
+ def initialize(params = {})
90
+ @id = nil
91
+ params.each { |k,v| send(:"#{k}=", v) }
92
+ @server = XmlrpcClient.new2("#{self.class.connection.url}")
93
+ end
94
+
95
+ def new_record?; @id.nil?; end
96
+
97
+ def save!
98
+ params = {}
99
+ session = self.class.connection
100
+ self.class.translations.keys.each { |k|
101
+ value = send(:"#{k}")
102
+ params[self.class.translations[k].to_s] = value if value
103
+ }
104
+
105
+ if new_record?
106
+ @id = @server.call(self.class.create, session, params)
107
+ else
108
+ @server.call(self.class.update, session, params)
109
+ end
110
+ self
111
+ end
112
+
113
+ def destroy
114
+ session = self.class.connection
115
+ @server.call(self.class.delete, session, id)
116
+ @id = nil
117
+ end
118
+
119
+ def <=>(other)
120
+ self.id <=> other.id
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,51 @@
1
+ module OpenX
2
+ module Services
3
+ class Campaign < Base
4
+ # Translate our property names to OpenX property names
5
+ openx_accessor :name => :campaignName,
6
+ :advertiser_id => :advertiserId,
7
+ :id => :campaignId,
8
+ :start_date => :startDate,
9
+ :end_date => :endDate,
10
+ :impressions => :impressions,
11
+ :target_impressions => :targetImpressions,
12
+ :target_clicks => :targetClicks,
13
+ :revenue => :revenue,
14
+ :revenue_type => :revenueType,
15
+ :impressions => :impressions,
16
+ :clicks => :clicks,
17
+ :priority => :priority,
18
+ :weight => :weight,
19
+ :campaign_type => :campaignType
20
+
21
+ has_one :advertiser
22
+
23
+ self.create = 'ox.addCampaign'
24
+ self.update = 'ox.modifyCampaign'
25
+ self.delete = 'ox.deleteCampaign'
26
+ self.find_one = 'ox.getCampaign'
27
+ self.find_all = 'ox.getCampaignListByAdvertiserId'
28
+
29
+ # Revenue types
30
+ CPM = 1
31
+ CPC = 2
32
+ CPA = 3
33
+ MONTHLY_TENANCY = 4
34
+
35
+ # Campaign types
36
+ REMNANT = 1
37
+ HIGH = 2
38
+ EXCLUSIVE = 3
39
+
40
+ def initialize(params = {})
41
+ raise ArgumentError.new("Missing advertiser_id") unless params[:advertiser_id] || params[:advertiser]
42
+ params[:advertiser_id] ||= params[:advertiser].id
43
+ super(params)
44
+ end
45
+
46
+ def banners
47
+ Banner.find(:all, self.id)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,31 @@
1
+ module OpenX
2
+ module Services
3
+ class Publisher < Base
4
+ openx_accessor :name => :publisherName,
5
+ :contact_name => :contactName,
6
+ :email => :emailAddress,
7
+ :username => :username,
8
+ :password => :password,
9
+ :id => :publisherId,
10
+ :agency_id => :agencyId
11
+
12
+ has_one :agency
13
+
14
+ self.create = 'ox.addPublisher'
15
+ self.update = 'ox.modifyPublisher'
16
+ self.delete = 'ox.deletePublisher'
17
+ self.find_one = 'ox.getPublisher'
18
+ self.find_all = 'ox.getPublisherListByAgencyId'
19
+
20
+ def initialize(params = {})
21
+ raise "need agency" unless params[:agency_id] || params[:agency]
22
+ params[:agency_id] ||= params[:agency].id
23
+ super(params)
24
+ end
25
+
26
+ def zones
27
+ Zone.find(:all, self.id)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ module OpenX
2
+ module Services
3
+ class Session
4
+ attr_accessor :url, :id
5
+ attr_accessor :user, :password
6
+
7
+ def initialize(url)
8
+ @url = url
9
+ @server = XmlrpcClient.new2("#{@url}")
10
+ @id = nil
11
+ end
12
+
13
+ def create(user, password)
14
+ @user = user
15
+ @password = password
16
+ @id = @server.call('ox.logon', @user, @password)
17
+ self
18
+ end
19
+
20
+ def recreate!
21
+ raise "Unable to refresh Session" unless @user && @password
22
+ @id = @server.call('ox.logon', @user, @password)
23
+ self
24
+ end
25
+
26
+ def destroy
27
+ @server.call('ox.logoff', @id)
28
+ @id = nil
29
+ self
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,98 @@
1
+ module OpenX
2
+ module Services
3
+ class Zone < Base
4
+ # Delivery types
5
+ BANNER = 'delivery-b'
6
+ INTERSTITIAL = 'delivery-i'
7
+ TEXT = 'delivery-t'
8
+ EMAIL = 'delivery-e'
9
+
10
+ # Tag Types
11
+ JAVASCRIPT = 'adjs'
12
+ LOCAL = 'local'
13
+ IFRAME = 'adframe'
14
+ XMLRPC_TAG = 'xmlrpc'
15
+
16
+ openx_accessor :name => :zoneName,
17
+ :id => :zoneId,
18
+ :width => :width,
19
+ :height => :height,
20
+ :type => :type,
21
+ :publisher_id => :publisherId
22
+
23
+ has_one :publisher
24
+
25
+ self.create = 'ox.addZone'
26
+ self.update = 'ox.modifyZone'
27
+ self.delete = 'ox.deleteZone'
28
+ self.find_one = 'ox.getZone'
29
+ self.find_all = 'ox.getZoneListByPublisherId'
30
+
31
+ class << self
32
+ ###
33
+ # Deliver +zone_id+ to +ip_address+ with +cookies+,
34
+ def deliver zone_id, ip_address = '192.168.1.1', cookies = []
35
+ url = "#{self.configuration['root']}/delivery/axmlrpc.php"
36
+ server = XmlrpcClient.new2(url)
37
+ server.call('openads.view', {
38
+ 'cookies' => cookies,
39
+ 'remote_addr' => ip_address,
40
+ }, "zone:#{zone_id}", 0, '', '', true, [])
41
+ end
42
+ end
43
+
44
+ def initialize(params = {})
45
+ raise "need publisher" unless params[:publisher_id] || params[:publisher]
46
+ params[:publisher_id] ||= params[:publisher].id
47
+ super(params)
48
+ end
49
+
50
+ # Link this zone to +campaign+
51
+ def link_campaign(campaign)
52
+ raise "Zone must be saved" if new_record?
53
+ raise ArgumentError.new("Campaign must be saved")if campaign.new_record?
54
+
55
+ session = self.class.connection
56
+ server = XmlrpcClient.new2("#{session.url}")
57
+ server.call("ox.linkCampaign", session, self.id, campaign.id)
58
+ end
59
+
60
+ # Unlink this zone from +campaign+
61
+ def unlink_campaign(campaign)
62
+ raise "Zone must be saved" if new_record?
63
+ raise ArgumentError.new("Campaign must be saved")if campaign.new_record?
64
+
65
+ session = self.class.connection
66
+ server = XmlrpcClient.new2("#{session.url}")
67
+ server.call("ox.unlinkCampaign", session, self.id, campaign.id)
68
+ end
69
+
70
+ # Link this zone to +banner+
71
+ def link_banner(banner)
72
+ raise "Zone must be saved" if new_record?
73
+ raise ArgumentError.new("Banner must be saved")if banner.new_record?
74
+
75
+ session = self.class.connection
76
+ server = XmlrpcClient.new2("#{session.url}")
77
+ server.call("ox.linkBanner", session, self.id, banner.id)
78
+ end
79
+
80
+ # Unlink this zone from +banner+
81
+ def unlink_banner(banner)
82
+ raise "Zone must be saved" if new_record?
83
+ raise ArgumentError.new("Banner must be saved")if banner.new_record?
84
+
85
+ session = self.class.connection
86
+ server = XmlrpcClient.new2("#{session.url}")
87
+ server.call("ox.unlinkBanner", session, self.id, banner.id)
88
+ end
89
+
90
+ # Generate tags for displaying this zone using +tag_type+
91
+ def generate_tags(tag_type = IFRAME)
92
+ session = self.class.connection
93
+ server = XmlrpcClient.new2("#{session.url}")
94
+ server.call("ox.generateTags", session, self.id, tag_type, [])
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,78 @@
1
+ require 'xmlrpc/client'
2
+
3
+ module OpenX
4
+
5
+ unless defined? HTTPBroken
6
+ # A module that captures all the possible Net::HTTP exceptions
7
+ # from http://pastie.org/pastes/145154
8
+ module HTTPBroken; end
9
+
10
+ [Timeout::Error, Errno::EINVAL, Errno::EPIPE, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse,
11
+ Net::HTTPHeaderSyntaxError, Net::ProtocolError].each {|m| m.send(:include, HTTPBroken)}
12
+ end
13
+
14
+ class XmlrpcClient
15
+ @uri = nil
16
+ @server = nil
17
+
18
+ @retry_on_http_error = true
19
+ @timeout = 10 # seconds
20
+
21
+ class << self
22
+ attr_accessor :retry_on_http_error, :timeout
23
+
24
+ def init_server(uri)
25
+ server = XMLRPC::Client.new2(uri)
26
+ server.timeout = self.timeout
27
+ #server.instance_variable_get(:@http).set_debug_output($stderr)
28
+ server
29
+ end
30
+
31
+ def new2(uri)
32
+ server = init_server(uri)
33
+ new(server, uri)
34
+ end
35
+ end
36
+
37
+ def initialize(server, uri)
38
+ @server = server
39
+ @uri = uri
40
+ end
41
+
42
+ def call(method, *args)
43
+ if args.first.is_a?(OpenX::Services::Session)
44
+ session = args.shift()
45
+ args.unshift(session.id)
46
+ begin
47
+ do_call(method, *args)
48
+ rescue XMLRPC::FaultException => sess_id_err
49
+ if sess_id_err.message.strip == 'Session ID is invalid'
50
+ session.recreate!
51
+ args.shift()
52
+ args.unshift(session.id)
53
+ do_call(method, *args)
54
+ else
55
+ raise sess_id_err
56
+ end
57
+ end
58
+ else
59
+ do_call(method, *args)
60
+ end
61
+ end
62
+
63
+ def do_call(method, *args)
64
+ begin
65
+ @server.call(method, *args)
66
+ rescue HTTPBroken => httpbe
67
+ if self.class.retry_on_http_error
68
+ @server = self.class.init_server(@uri)
69
+ @server.call(method, *args)
70
+ else
71
+ raise httpbe
72
+ end
73
+ end
74
+ end
75
+ private :do_call
76
+
77
+ end
78
+ end
Binary file
Binary file
data/test/helper.rb ADDED
@@ -0,0 +1,99 @@
1
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '../lib')))
2
+
3
+ require 'test/unit'
4
+ require 'openx'
5
+
6
+ ENV['OPENX_ENV'] = 'test'
7
+
8
+ module OpenX
9
+ class TestCase < Test::Unit::TestCase
10
+ TEST_SWF = File.expand_path(File.join(File.dirname(__FILE__), 'assets', 'cat.swf'))
11
+ TEST_JPG = File.expand_path(File.join(File.dirname(__FILE__), 'assets', '300x250.jpg'))
12
+
13
+ include OpenX::Services
14
+
15
+ undef :default_test
16
+
17
+ def setup
18
+ assert(
19
+ File.exists?(Base::CONFIGURATION_YAML),
20
+ 'Please create the credentials file'
21
+ )
22
+ end
23
+
24
+ def agency
25
+ @agency ||= Agency.create!(
26
+ {
27
+ :name => "Testing! - #{Time.now}",
28
+ :contact_name => 'Contact Name!',
29
+ :email => 'foo@bar.com'
30
+ }
31
+ )
32
+ end
33
+
34
+ def advertiser
35
+ @advertiser ||= Advertiser.create!(
36
+ {
37
+ :name => "adv-#{Time.now}",
38
+ :contact_name => 'Contact Name!',
39
+ :email => 'foo@bar.com'
40
+ }.merge(:agency => agency)
41
+ )
42
+ end
43
+
44
+ def campaign
45
+ @campaign ||= Campaign.create!(
46
+ {
47
+ :advertiser => advertiser,
48
+ :name => "Campaign-#{Time.now}",
49
+ :impressions => 2000
50
+ }
51
+ )
52
+ end
53
+
54
+ def publisher
55
+ @publisher ||= Publisher.create!(
56
+ {
57
+ :agency => agency,
58
+ :name => "Publisher! - #{Time.now}",
59
+ :contact_name => 'Aaron Patterson',
60
+ :email => 'aaron@tenderlovemaking.com',
61
+ :username => 'one',
62
+ :password => 'two',
63
+ }
64
+ )
65
+ end
66
+
67
+ def zone
68
+ @zone ||= Zone.create!(
69
+ {
70
+ :publisher => publisher,
71
+ :name => "Zone - #{Time.now}",
72
+ :type => Zone::BANNER,
73
+ :width => 300,
74
+ :height => 250,
75
+ }
76
+ )
77
+ end
78
+
79
+ def banner
80
+ @banner ||= Banner.create!({
81
+ :name => "Banner-#{Time.now}",
82
+ :storage_type => Banner::LOCAL_SQL,
83
+ :campaign => campaign,
84
+ :url => 'http://tenderlovemaking.com/',
85
+ :file_name => 'oogabooga',
86
+ :image => OpenX::Image.new(File.open(TEST_SWF, 'rb'))
87
+ })
88
+ end
89
+
90
+ def destroy
91
+ @banner.destroy if defined? @banner
92
+ @zone.destroy if defined? @zone
93
+ @publisher.destroy if defined? @publisher
94
+ @campaign.destroy if defined? @campaign
95
+ @advertiser.destroy if defined? @advertiser
96
+ @agency.destroy if defined? @agency
97
+ end
98
+ end
99
+ end