bsm-openx 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,125 @@
1
+ module OpenX
2
+ module Services
3
+
4
+ class TargetingRule < Hash
5
+ TYPES = {
6
+ 'Client' => %w(Browser Domain Ip Language Os Useragent),
7
+ 'Geo' => %w(Areacode City Continent Country Dma Latlong Netspeed Organisation Postalcode Region),
8
+ 'Site' => %w(Channel Pageurl Referingpage Source Variable),
9
+ 'Time' => %w(Date Day Hour)
10
+ }.freeze
11
+
12
+ DATA_KEYS = ['comparison', 'data', 'logical'].freeze
13
+ ALL_KEYS = (DATA_KEYS + ['type']).freeze
14
+
15
+ attr_reader :type
16
+
17
+ def self.instantiate(hash)
18
+ rule = new(hash['type'])
19
+ DATA_KEYS.each {|k| rule.update k => hash[k] }
20
+ rule
21
+ end
22
+
23
+ def initialize(type)
24
+ super().update('type' => verify_type(type), 'logical' => 'and')
25
+ end
26
+
27
+ def equal?(value)
28
+ update 'comparison' => '==', 'data' => convert(value)
29
+ end
30
+ alias_method :eq?, :equal?
31
+ alias_method :is?, :equal?
32
+ alias_method :==, :equal?
33
+
34
+ def not_equal?(value)
35
+ update 'comparison' => '!=', 'data' => convert(value)
36
+ end
37
+ alias_method :ne?, :not_equal?
38
+ alias_method :not?, :not_equal?
39
+
40
+ def lt?(value)
41
+ update 'comparison' => '<', 'data' => convert(value)
42
+ end
43
+ alias_method :<, :lt?
44
+
45
+ def gt?(value)
46
+ update 'comparison' => '>', 'data' => convert(value)
47
+ end
48
+ alias_method :>, :gt?
49
+
50
+ def lte?(value)
51
+ update 'comparison' => '<=', 'data' => convert(value)
52
+ end
53
+ alias_method :<=, :lte?
54
+
55
+ def gte?(value)
56
+ update 'comparison' => '>=', 'data' => convert(value)
57
+ end
58
+ alias_method :>=, :gte?
59
+
60
+ def match?(value)
61
+ update 'comparison' => '=x', 'data' => convert(value)
62
+ end
63
+ alias_method :=~, :match?
64
+
65
+ def &(other)
66
+ other.logical('and')
67
+ end
68
+
69
+ def |(other)
70
+ other.logical('or')
71
+ end
72
+
73
+ def no_match?(value)
74
+ update 'comparison' => '!x', 'data' => convert(value)
75
+ end
76
+
77
+ def include?(*value)
78
+ update 'comparison' => '=~', 'data' => convert(value)
79
+ end
80
+ alias_method :contains?, :include?
81
+
82
+ def exclude?(*value)
83
+ update 'comparison' => '!~', 'data' => convert(value)
84
+ end
85
+ alias_method :does_not_contain?, :exclude?
86
+
87
+ def with(value)
88
+ update 'data' => convert(value)
89
+ end
90
+
91
+ def compare(value)
92
+ update 'comparison' => value
93
+ end
94
+
95
+ def logical(value)
96
+ value = value.to_s
97
+ update 'logical' => (value == 'or' ? value : 'and')
98
+ end
99
+
100
+ def complete?
101
+ values_at(*ALL_KEYS).all? {|v| !v.nil? }
102
+ end
103
+
104
+ private
105
+
106
+ def verify_type(type)
107
+ group, component = type.to_s.split(':').last(2)
108
+ raise "Invalid type '#{self['type']}'" unless TYPES.key?(group) && TYPES[group].include?(component)
109
+ "#{group}:#{component}"
110
+ end
111
+
112
+ def convert(value)
113
+ case value
114
+ when Array
115
+ value.map {|v| convert(v) }.join(',')
116
+ when Regexp
117
+ value.source
118
+ else
119
+ value.to_s
120
+ end
121
+ end
122
+
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,26 @@
1
+ module OpenX
2
+ module Services
3
+
4
+ # Create targeting rule sets. Example:
5
+ #
6
+ # rules = OpenX::Services::TargetingRules.new do |t|
7
+ # t['Site:Pageurl'].include?('test') &
8
+ # t['Client:Ip'].match?(/^127\./) |
9
+ # t['Geo:Country'].include?('GB', 'US')
10
+ # end
11
+ class TargetingRules < Array
12
+
13
+ def initialize(&block)
14
+ super([])
15
+ block.call(self)
16
+ end
17
+
18
+ def [](key)
19
+ rule = TargetingRule.new(key)
20
+ push(rule)
21
+ rule
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,82 @@
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, options = {})
35
+ options = { 'ip_address' => '192.168.1.1', 'cookies' => [] }.update(options)
36
+ server = XmlrpcClient.new("#{connection.host}/delivery/axmlrpc.php")
37
+ server.call('openads.view', options, "zone:#{zone_id}", 0, '', '', true, [])
38
+ end
39
+
40
+ end
41
+
42
+ def initialize(params = {})
43
+ raise "need publisher" unless params[:publisher_id] || params[:publisher]
44
+ params[:publisher_id] ||= params[:publisher].id
45
+ super(params)
46
+ end
47
+
48
+ # Link this zone to +campaign+
49
+ def link_campaign(campaign)
50
+ raise "Zone must be saved" if new_record?
51
+ raise ArgumentError.new("Campaign must be saved")if campaign.new_record?
52
+ remote.call("ox.linkCampaign", self.id, campaign.id)
53
+ end
54
+
55
+ # Unlink this zone from +campaign+
56
+ def unlink_campaign(campaign)
57
+ raise "Zone must be saved" if new_record?
58
+ raise ArgumentError.new("Campaign must be saved")if campaign.new_record?
59
+ remote.call("ox.unlinkCampaign", self.id, campaign.id)
60
+ end
61
+
62
+ # Link this zone to +banner+
63
+ def link_banner(banner)
64
+ raise "Zone must be saved" if new_record?
65
+ raise ArgumentError.new("Banner must be saved")if banner.new_record?
66
+ remote.call("ox.linkBanner", self.id, banner.id)
67
+ end
68
+
69
+ # Unlink this zone from +banner+
70
+ def unlink_banner(banner)
71
+ raise "Zone must be saved" if new_record?
72
+ raise ArgumentError.new("Banner must be saved")if banner.new_record?
73
+ remote.call("ox.unlinkBanner", self.id, banner.id)
74
+ end
75
+
76
+ # Generate tags for displaying this zone using +tag_type+
77
+ def generate_tags(tag_type = IFRAME)
78
+ remote.call("ox.generateTags", self.id, tag_type, [])
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,72 @@
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,
11
+ Errno::ECONNRESET, EOFError, Net::HTTPBadResponse,
12
+ Net::HTTPHeaderSyntaxError, Net::ProtocolError
13
+ ].each {|m| m.send(:include, HTTPBroken) }
14
+ end
15
+
16
+ class XmlrpcClient
17
+ attr_reader :client, :url
18
+
19
+ def initialize(url)
20
+ @url = url
21
+ init_client!
22
+ end
23
+
24
+ def call(method, *args)
25
+ @client.call(method, *convert(args))
26
+ rescue HTTPBroken
27
+ raise unless OpenX.configuration['retry']
28
+ init_client!
29
+ retry
30
+ end
31
+
32
+ protected
33
+
34
+ def convert(args)
35
+ args
36
+ end
37
+
38
+ private
39
+
40
+ def init_client!
41
+ @client = XMLRPC::Client.new2(url)
42
+ @client.timeout = OpenX.configuration['timeout']
43
+ end
44
+
45
+ end
46
+
47
+
48
+ class XmlrpcSessionClient < XmlrpcClient
49
+
50
+ attr_reader :session
51
+
52
+ def initialize(session)
53
+ @session = session
54
+ super(session.url)
55
+ end
56
+
57
+ def call(method, *args)
58
+ super
59
+ rescue XMLRPC::FaultException => error
60
+ raise unless error.message =~ /Session ID.*invalid/i
61
+ session.recreate!
62
+ retry
63
+ end
64
+
65
+ protected
66
+
67
+ def convert(args)
68
+ [session.id] + args
69
+ end
70
+
71
+ end
72
+ end
Binary file
Binary file
data/test/helper.rb ADDED
@@ -0,0 +1,131 @@
1
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '../lib')))
2
+
3
+ ENV['OPENX_ENV'] = 'test'
4
+
5
+ require 'rubygems'
6
+ require 'bundler'
7
+
8
+ Bundler.setup
9
+ Bundler.require :test
10
+
11
+ require 'test/unit'
12
+ require 'openx'
13
+
14
+ module OpenX
15
+ class TestCase < ActiveSupport::TestCase
16
+ TEST_SWF = File.expand_path(File.join(File.dirname(__FILE__), 'assets', 'cat.swf'))
17
+ TEST_JPG = File.expand_path(File.join(File.dirname(__FILE__), 'assets', '300x250.jpg'))
18
+
19
+ Base = OpenX::Services::Base
20
+ Banner = OpenX::Services::Banner
21
+ Zone = OpenX::Services::Zone
22
+ Publisher = OpenX::Services::Publisher
23
+ Campaign = OpenX::Services::Campaign
24
+ Agency = OpenX::Services::Agency
25
+ Advertiser = OpenX::Services::Advertiser
26
+ Session = OpenX::Services::Session
27
+ Channel = OpenX::Services::Channel
28
+ TargetingRule = OpenX::Services::TargetingRule
29
+ TargetingRules = OpenX::Services::TargetingRules
30
+
31
+ undef :default_test
32
+
33
+ def setup
34
+ raise 'Please create the credentials file' unless File.exists?(OpenX.config_file)
35
+ end
36
+
37
+ def agency
38
+ @agency ||= Agency.create!({
39
+ :name => "Testing! - #{Time.now}",
40
+ :contact_name => 'Contact Name!',
41
+ :email => 'foo@bar.com'
42
+ })
43
+ end
44
+
45
+ def advertiser
46
+ @advertiser ||= Advertiser.create!(
47
+ {
48
+ :name => "adv-#{Time.now}",
49
+ :contact_name => 'Contact Name!',
50
+ :email => 'foo@bar.com'
51
+ }.merge(:agency => agency)
52
+ )
53
+ end
54
+
55
+ def campaign
56
+ @campaign ||= Campaign.create!(
57
+ {
58
+ :advertiser => advertiser,
59
+ :name => "Campaign-#{Time.now}",
60
+ :impressions => 2000
61
+ }
62
+ )
63
+ end
64
+
65
+ def publisher
66
+ @publisher ||= Publisher.create!(
67
+ {
68
+ :agency => agency,
69
+ :name => "Publisher! - #{Time.now}",
70
+ :contact_name => 'Aaron Patterson',
71
+ :email => 'aaron@tenderlovemaking.com',
72
+ :username => 'one',
73
+ :password => 'two',
74
+ }
75
+ )
76
+ end
77
+
78
+ def zone
79
+ @zone ||= Zone.create!(
80
+ {
81
+ :publisher => publisher,
82
+ :name => "Zone - #{Time.now}",
83
+ :type => Zone::BANNER,
84
+ :width => 300,
85
+ :height => 250,
86
+ }
87
+ )
88
+ end
89
+
90
+ def channel
91
+ @channel ||= Channel.create!(
92
+ {
93
+ :publisher => publisher,
94
+ :name => "Channel - #{Time.now}",
95
+ :comments => 'Random Comments',
96
+ :description => 'Random Description'
97
+ }
98
+ )
99
+ end
100
+
101
+ def banner
102
+ @banner ||= Banner.create!({
103
+ :name => "Banner-#{Time.now}",
104
+ :storage_type => Banner::LOCAL_SQL,
105
+ :campaign => campaign,
106
+ :url => 'http://tenderlovemaking.com/',
107
+ :file_name => 'oogabooga',
108
+ :image => OpenX::Image.new(File.open(TEST_SWF, 'rb'))
109
+ })
110
+ end
111
+
112
+ def targeting_rules
113
+ @targeting_rules ||= OpenX::Services::TargetingRules.new do |t|
114
+ t['Site:Pageurl'].include?('test') &
115
+ t['Client:Ip'].match?(/^127\./) |
116
+ t['Geo:Country'].include?('GB', 'US')
117
+ end
118
+ end
119
+
120
+ def destroy
121
+ @banner.destroy if defined? @banner
122
+ @zone.destroy if defined? @zone
123
+ @publisher.destroy if defined? @publisher
124
+ @campaign.destroy if defined? @campaign
125
+ @advertiser.destroy if defined? @advertiser
126
+ @agency.destroy if defined? @agency
127
+ @channel.destroy if defined? @channel
128
+ end
129
+
130
+ end
131
+ end
@@ -0,0 +1,82 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class AdvertiserTest < OpenX::TestCase
4
+ def test_create_advertiser
5
+ advertiser = nil
6
+ assert_nothing_raised {
7
+ advertiser = Advertiser.create!(init_params.merge({
8
+ :agency => agency,
9
+ }))
10
+ }
11
+ assert_not_nil advertiser
12
+ init_params.each do |k,v|
13
+ assert_equal(v, advertiser.send(:"#{k}"))
14
+ end
15
+ end
16
+
17
+ def test_destroy
18
+ a = nil
19
+ assert_nothing_raised {
20
+ a = Advertiser.create!(init_params.merge({:agency => agency}))
21
+ }
22
+ id = a.id
23
+ assert_nothing_raised {
24
+ a.destroy
25
+ }
26
+ assert_raises(XMLRPC::FaultException) {
27
+ Advertiser.find(id)
28
+ }
29
+ end
30
+
31
+ def test_create_advertiser_with_agency
32
+ advertiser = nil
33
+ assert_nothing_raised {
34
+ advertiser = agency.create_advertiser!(init_params)
35
+ }
36
+ assert_not_nil advertiser
37
+ init_params.each do |k,v|
38
+ assert_equal(v, advertiser.send(:"#{k}"))
39
+ end
40
+ end
41
+
42
+ def test_find_advertiser
43
+ advertiser = nil
44
+ assert_nothing_raised {
45
+ advertiser = agency.create_advertiser!(init_params)
46
+ }
47
+ assert_not_nil advertiser
48
+
49
+ original = advertiser
50
+ advertiser = Advertiser.find(advertiser.id)
51
+ assert_equal(original, advertiser)
52
+ assert_not_nil advertiser
53
+ assert_not_nil advertiser.agency
54
+ init_params.each do |k,v|
55
+ assert_equal(v, advertiser.send(:"#{k}"))
56
+ end
57
+ end
58
+
59
+ def test_find_all_advertisers
60
+ advertiser = nil
61
+ assert_nothing_raised {
62
+ advertiser = agency.create_advertiser!(init_params)
63
+ }
64
+ assert_not_nil advertiser
65
+
66
+ advertisers = Advertiser.find(:all, agency.id)
67
+
68
+ advertiser = advertisers.find { |a| a.id == advertiser.id }
69
+ assert_not_nil advertiser
70
+ init_params.each do |k,v|
71
+ assert_equal(v, advertiser.send(:"#{k}"))
72
+ end
73
+ end
74
+
75
+ def init_params
76
+ {
77
+ :name => 'Test advertiser',
78
+ :contact_name => 'Contact name',
79
+ :email => 'email@example.com',
80
+ }
81
+ end
82
+ end