touchlocal-openx 1.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,3 @@
1
+ *.swp
2
+ .svn/
3
+ pkg/
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2008-04-07
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,26 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/openx.rb
6
+ lib/openx/image.rb
7
+ lib/openx/services.rb
8
+ lib/openx/services/advertiser.rb
9
+ lib/openx/services/agency.rb
10
+ lib/openx/services/banner.rb
11
+ lib/openx/services/base.rb
12
+ lib/openx/services/campaign.rb
13
+ lib/openx/services/publisher.rb
14
+ lib/openx/services/session.rb
15
+ lib/openx/services/zone.rb
16
+ test/assets/300x250.jpg
17
+ test/assets/cat.swf
18
+ test/helper.rb
19
+ test/test_advertiser.rb
20
+ test/test_agency.rb
21
+ test/test_banner.rb
22
+ test/test_base.rb
23
+ test/test_campaign.rb
24
+ test/test_publisher.rb
25
+ test/test_session.rb
26
+ test/test_zone.rb
data/README.txt ADDED
@@ -0,0 +1,109 @@
1
+ = openx
2
+
3
+ * http://openx.rubyforge.org
4
+
5
+ == DESCRIPTION:
6
+
7
+ A Ruby interface to the OpenX XML-RPC API.
8
+
9
+ == SYNOPSIS:
10
+
11
+ OpenX::Services::Base.configuration = {
12
+ 'username' => 'admin',
13
+ 'password' => 'password',
14
+ 'url' => 'http://localhost/www/api/v2/xmlrpc/',
15
+ }
16
+
17
+ OpenX::Services::Agency.find(:all).each do |agency|
18
+ puts agency.name
19
+
20
+ # Look up publishers
21
+ agency.publishers.each do |publisher|
22
+ puts "-- #{publisher.name}"
23
+ end
24
+
25
+ # Create a publisher
26
+ Publisher.create!(
27
+ :agency => agency,
28
+ :name => 'My Test Publisher',
29
+ :contact_name => 'Aaron Patterson',
30
+ :email => 'aaron@tenderlovemaking.com',
31
+ :username => 'user',
32
+ :password => 'password'
33
+ )
34
+ end
35
+
36
+ == REQUIREMENTS:
37
+
38
+ * ruby
39
+
40
+ == INSTALL:
41
+
42
+ * sudo gem install openx
43
+ * Update your $HOME/.openx/credentials.yml file. Here is a sample:
44
+
45
+ ---
46
+ production:
47
+ username: admin
48
+ password: admin
49
+ url: http://www.example.com/www/api/v2/xmlrpc/
50
+ invocation_url: http://www.example.com/www/delivery/axmlrpc.php
51
+
52
+ The YAML file lists configuration for each environment. The gem uses the
53
+ 'production' environment by default. Trailing slash is required on the 'url'.
54
+ 'invocation_url' is only used by the OpenX::Invocation methods to serve
55
+ advertisements over XML-RPC
56
+
57
+ == RUBY ON RAILS INTEGRATION
58
+
59
+ As common deployment scenarios for RoR projects dictates that you manage all
60
+ of your dependent files from within your project, storing your credentials.yml
61
+ file in the default location (as above) will not work. However, this is easily
62
+ fixed.
63
+
64
+ Create your credentials.yml file in your ./config folder, and populate it with
65
+ the necessary environment settings. It may in fact be more useful to name your
66
+ file something like openx_credentials.yml to be explicit about the content.
67
+
68
+ Then, add your gem require line to the initialize block of the environment.rb:
69
+
70
+ config.gem "touchlocal-openx",
71
+ :lib => "openx", :source => "http://gemcutter.org"
72
+
73
+ You will of course need to install the gem, either manually or via
74
+ rake gems:install
75
+
76
+ Finally, create a config/initializers/openx.rb and include the following line:
77
+
78
+ OpenX::Services::Base.configuration =
79
+ YAML.load_file(File.join(Rails.root, 'config', 'credentials.yml'))[Rails.env]
80
+
81
+
82
+ == LICENSE:
83
+
84
+ (The MIT License)
85
+
86
+ Copyright (c) 2008:
87
+
88
+ * {Aaron Patterson}[http://tenderlovemaking.com]
89
+ * Andy Smith
90
+ * {TouchLocal Plc}[http://www.touchlocal.com]
91
+
92
+ Permission is hereby granted, free of charge, to any person obtaining
93
+ a copy of this software and associated documentation files (the
94
+ 'Software'), to deal in the Software without restriction, including
95
+ without limitation the rights to use, copy, modify, merge, publish,
96
+ distribute, sublicense, and/or sell copies of the Software, and to
97
+ permit persons to whom the Software is furnished to do so, subject to
98
+ the following conditions:
99
+
100
+ The above copyright notice and this permission notice shall be
101
+ included in all copies or substantial portions of the Software.
102
+
103
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
104
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
105
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
106
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
107
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
108
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
109
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gemspec|
9
+ gemspec.name = "touchlocal-openx"
10
+ gemspec.summary = "A Ruby interface to the OpenX XML-RPC API"
11
+ gemspec.description = "A Ruby interface to the OpenX XML-RPC API"
12
+ gemspec.email = "info@touchlocal.com"
13
+ gemspec.homepage = "http://github.com/touchlocal/openx"
14
+ gemspec.authors = ["Aaron Patterson", "Andy Smith", "TouchLocal Plc"]
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
19
+ end
20
+
21
+ $: << "lib/"
22
+ require 'openx'
23
+
24
+ namespace :openx do
25
+ task :clean do
26
+ include OpenX::Services
27
+ ENV['OPENX_ENV'] = 'test'
28
+ Agency.find(:all) do |agency|
29
+ Advertiser.find(:all, agency.id).each do |advertiser|
30
+ Campaign.find(:all, advertiser.id).each do |campaign|
31
+ Banner.find(:all, campaign.id).each do |banner|
32
+ banner.destroy
33
+ end
34
+ campaign.destroy
35
+ end
36
+ advertiser.destroy
37
+ end
38
+ end
39
+ end
40
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.0
data/lib/openx.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'xmlrpc/client'
2
+ require 'openx/xmlrpc_client'
3
+ require 'openx/services'
4
+ require 'openx/invocation'
5
+ require 'openx/image'
6
+
7
+ module OpenX
8
+ VERSION = '1.1.0'
9
+ end
@@ -0,0 +1,22 @@
1
+ module OpenX
2
+ class Image
3
+ include XMLRPC::Marshallable
4
+ attr_accessor :filename, :content, :editswf
5
+
6
+ def initialize(hash_or_file)
7
+ @editswf = 0
8
+ if hash_or_file.is_a?(File)
9
+ @filename = File.basename(hash_or_file.path)
10
+ @editswf = File.basename(@filename, '.swf') == @filename ? 0 : 1
11
+ @content = XMLRPC::Base64.new(hash_or_file.read)
12
+ else
13
+ raise ArgumentError unless hash_or_file.key?(:filename)
14
+ raise ArgumentError unless hash_or_file.key?(:content)
15
+ hash_or_file.each { |k,v| send(:"#{k}=", v) }
16
+ unless self.content.is_a?(XMLRPC::Base64)
17
+ self.content = XMLRPC::Base64.new(self.content)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,63 @@
1
+ module OpenX
2
+ class Invocation
3
+ class << self
4
+ #
5
+ # banner = OpenX::Invocation.view("Plumber")
6
+ #
7
+ # banners = OpenX::Invocation.view("Plumber", :count => 2, :exclude_by_campaignid => true) ;nil
8
+ # banners.each do |banner|
9
+ # puts "Banner #{banner['bannerid']}"
10
+ # end; nil
11
+ #
12
+ def view(what, params = {})
13
+ defaults = {
14
+ :count => 1,
15
+ :campaignid => 0,
16
+ :target => '',
17
+ :source => '',
18
+ :with_text => false,
19
+ :exclusions => [],
20
+ :inclusions => [],
21
+ :exclude_by_campaignid => false,
22
+ :exclude_by_bannerid => false
23
+ }
24
+ params = defaults.merge(params)
25
+
26
+ url = OpenX::Services::Base.configuration['invocation_url']
27
+
28
+ settings = {:cookies => [], :remote_addr => 'localhost'}
29
+
30
+ context = [] # used by reference after initial use
31
+ params[:exclusions].each { |item| context << convert_to_context(false, item) }
32
+ params[:inclusions].each { |item| context << convert_to_context(true, item) }
33
+ count = params[:count].to_i
34
+
35
+ remote_params = [ what, params[:campaignid], params[:target], params[:source], params[:with_text], context]
36
+ server = XmlrpcClient.new2(url)
37
+
38
+ out = []
39
+ if count > 0
40
+ (0...count).each do
41
+ out << banner = server.call('openads.view', settings, *remote_params)
42
+ if count > 1
43
+ if params[:exclude_by_campaignid]
44
+ campaign_id = banner['campaignid']
45
+ context << convert_to_context(false, "campaignid:#{campaign_id}")
46
+ elsif params[:exclude_by_bannerid]
47
+ banner_id = banner['bannerid']
48
+ context << convert_to_context(false, "bannerid:#{banner_id}")
49
+ end
50
+ end
51
+ end
52
+ end
53
+ count > 1 ? out : out.first
54
+ end
55
+
56
+ def convert_to_context(is_inclusion, item)
57
+ key = is_inclusion ? '==' : '!='
58
+ { key => item }
59
+ end
60
+ protected :convert_to_context
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,8 @@
1
+ require 'openx/services/base'
2
+ require 'openx/services/session'
3
+ require 'openx/services/advertiser'
4
+ require 'openx/services/agency'
5
+ require 'openx/services/campaign'
6
+ require 'openx/services/banner'
7
+ require 'openx/services/publisher'
8
+ require 'openx/services/zone'
@@ -0,0 +1,31 @@
1
+ module OpenX
2
+ module Services
3
+ class Advertiser < Base
4
+ openx_accessor :name => :advertiserName,
5
+ :contact_name => :contactName,
6
+ :email => :emailAddress,
7
+ :username => :username,
8
+ :password => :password,
9
+ :agency_id => :agencyId,
10
+ :id => :advertiserId
11
+
12
+ has_one :agency
13
+
14
+ self.create = 'ox.addAdvertiser'
15
+ self.update = 'ox.modifyAdvertiser'
16
+ self.delete = 'ox.deleteAdvertiser'
17
+ self.find_one = 'ox.getAdvertiser'
18
+ self.find_all = 'ox.getAdvertiserListByAgencyId'
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 campaigns
27
+ Campaign.find(:all, self.id)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ module OpenX
2
+ module Services
3
+ class Agency < Base
4
+ # Translate our property names to OpenX property names
5
+ openx_accessor :name => :agencyName,
6
+ :contact_name => :contactName,
7
+ :email => :emailAddress,
8
+ :username => :username,
9
+ :password => :password,
10
+ :id => :agencyId,
11
+ :account_id => :accountId
12
+
13
+ self.create = 'ox.addAgency'
14
+ self.update = 'ox.modifyAgency'
15
+ self.delete = 'ox.deleteAgency'
16
+ self.find_one = 'ox.getAgency'
17
+ self.find_all = 'ox.getAgencyList'
18
+
19
+ def create_advertiser!(params = {})
20
+ Advertiser.create!(params.merge({
21
+ :agency => self,
22
+ }))
23
+ end
24
+
25
+ def advertisers
26
+ Advertiser.find(:all, self.id)
27
+ end
28
+
29
+ def publishers
30
+ Publisher.find(:all, self.id)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,96 @@
1
+ require 'date'
2
+
3
+ module OpenX
4
+ module Services
5
+ class Banner < Base
6
+ LOCAL_SQL = 'sql'
7
+ LOCAL_WEB = 'web'
8
+ EXTERNAL = 'url'
9
+ HTML = 'html'
10
+ TEXT = 'txt'
11
+
12
+ RUNNING = 0
13
+ PAUSED = 1
14
+
15
+ class << self
16
+ def find(id, *args)
17
+ session = self.connection
18
+ server = XmlrpcClient.new2("#{session.url}")
19
+ if id == :all
20
+ responses = server.call(find_all(), session, *args)
21
+ response = responses.first
22
+ return [] unless response
23
+ responses = [response]
24
+
25
+ ### Annoying.. For some reason OpenX returns a linked list.
26
+ ### Probably a bug....
27
+ while response.key?('aImage')
28
+ response = response.delete('aImage')
29
+ break unless response
30
+ responses << response
31
+ end
32
+
33
+ responses.map { |response|
34
+ new(translate(response))
35
+ }
36
+ else
37
+ response = server.call(find_one(), session, id)
38
+ new(translate(response))
39
+ end
40
+ end
41
+ end
42
+
43
+ # Translate our property names to OpenX property names
44
+ openx_accessor :name => :bannerName,
45
+ :campaign_id => :campaignId,
46
+ :id => :bannerId,
47
+ :storage_type => :storageType,
48
+ :file_name => :fileName,
49
+ :image_url => :imageURL,
50
+ :html_template => :htmlTemplate,
51
+ :width => :width,
52
+ :height => :height,
53
+ :weight => :weight,
54
+ :target => :target,
55
+ :url => :url,
56
+ :status => :status,
57
+ :adserver => :adserver,
58
+ :transparent => :transparent,
59
+ :image => :aImage,
60
+ :backup_image => :aBackupImage,
61
+ # 'keyword' only supported by patched server
62
+ # as per https://developer.openx.org/jira/browse/OX-4779
63
+ # No averse effect when unsupported by server (returns nil)
64
+ :keyword => :keyword
65
+
66
+ has_one :campaign
67
+
68
+ self.create = 'ox.addBanner'
69
+ self.update = 'ox.modifyBanner'
70
+ self.delete = 'ox.deleteBanner'
71
+ self.find_one = 'ox.getBanner'
72
+ self.find_all = 'ox.getBannerListByCampaignId'
73
+
74
+ def initialize(params = {})
75
+ raise ArgumentError.new("Missing campaign_id") unless params[:campaign_id] || params[:campaign]
76
+ params[:campaign_id] ||= params[:campaign].id
77
+ super(params)
78
+ end
79
+
80
+ def statistics start_on = Date.today, end_on = Date.today
81
+ session = self.class.connection
82
+ @server.call('ox.bannerDailyStatistics', session, self.id, start_on, end_on)
83
+ end
84
+
85
+ def targeting
86
+ session = self.class.connection
87
+ @server.call('ox.getBannerTargeting', session, self.id)
88
+ end
89
+
90
+ def targeting= targeting
91
+ session = self.class.connection
92
+ @server.call('ox.setBannerTargeting', session, self.id, targeting)
93
+ end
94
+ end
95
+ end
96
+ end