francois-ad_gear_client 0.1.1

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.
data/.document ADDED
@@ -0,0 +1 @@
1
+ lib/**/*.rb
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ pkg
5
+ doc
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2009 François Beausoleil
2
+ Copyright (c) 2009 Bloom Digital Platforms
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = ad_gear_client
2
+
3
+ This gem is Ruby 1.8.6, Ruby 1.8.7, Ruby 1.9 and JRuby 1.3 compatible.
4
+
5
+ AdGear::Client is a client for accessing AdGear's RESTian web service.
6
+
7
+ AdGear is a product of Bloom Digital Platforms, a Montreal-based company founded in 2008. Through the AdGear family of products Bloom provides advertising management solutions to publishers, ad networks and platform developers looking to monetize their audiences.
8
+
9
+ == Dependencies
10
+
11
+ AdGear::Client works best with the ActiveResource branch made by François Beausoleil, at http://github.com/francois/rails. This branch of ActiveResource supports Digest authentication. AdGear::Client will work wihout that branch, but without Digest authentication.
12
+
13
+ == Copyright
14
+
15
+ Copyright (c) 2009 François Beausoleil.
16
+ Copyright (c) 2009 Bloom Digital Platforms
17
+ See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,117 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = "ad_gear_client"
10
+ gem.summary = %Q{A Ruby client for accessing AdGear http://bloomdigital.com/}
11
+ gem.email = "francois@teksol.info"
12
+ gem.homepage = "http://github.com/francois/ad_gear_client"
13
+ gem.authors = ["François Beausoleil"]
14
+ gem.rubyforge_project = "ad_gear_client"
15
+
16
+ gem.add_development_dependency "lsegal-yard", ">= 0.2.3"
17
+ gem.add_development_dependency "mocha", ">= 0.9.5"
18
+
19
+ gem.add_dependency "activeresource", "> 2.0"
20
+ gem.add_dependency "francois-rest-client", "~> 1"
21
+ end
22
+
23
+ Jeweler::RubyforgeTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
+ end
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.libs << "vendor/activesupport/lib" if File.directory?("vendor/activesupport/lib")
32
+ test.libs << "vendor/activemodel/lib" if File.directory?("vendor/activemodel/lib")
33
+ test.libs << "vendor/activeresource/lib" if File.directory?("vendor/activeresource/lib")
34
+
35
+ test.pattern = 'test/**/*_test.rb'
36
+ test.verbose = true
37
+ end
38
+
39
+ begin
40
+ require 'rcov/rcovtask'
41
+ Rcov::RcovTask.new do |test|
42
+ test.libs << 'test'
43
+ test.pattern = 'test/**/*_test.rb'
44
+ test.verbose = true
45
+ end
46
+ rescue LoadError
47
+ task :rcov do
48
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
49
+ end
50
+ end
51
+
52
+
53
+ task :default => :test
54
+
55
+ module AdGear
56
+ if File.exist?("VERSION")
57
+ Version = File.read("VERSION")
58
+ else
59
+ Version = ""
60
+ end
61
+ end
62
+
63
+ begin
64
+ require "yard"
65
+ YARD::Rake::YardocTask.new(:doc) do |t|
66
+ t.options = ["--title", "AdGear::Client #{AdGear::Version}", "--readme", "README.rdoc"]
67
+ end
68
+
69
+ namespace :doc do
70
+ desc "Blow away all generated documentation"
71
+ task :clean do
72
+ rm_rf "doc"
73
+ end
74
+ end
75
+
76
+ task :doc => "doc:clean"
77
+ rescue LoadError
78
+ STDERR.puts "YARD is not available. In order to generate the best possible documentation, install YARD: sudo gem install yard"
79
+
80
+ require 'rake/rdoctask'
81
+ Rake::RDocTask.new(:doc) do |rdoc|
82
+ rdoc.rdoc_dir = "doc"
83
+ rdoc.title = "AdGear::Client #{AdGear::Version}"
84
+
85
+ rdoc.rdoc_files.include('README*')
86
+ rdoc.rdoc_files.include('lib/**/*.rb')
87
+ end
88
+ end
89
+
90
+ desc "Runs tests under all supported multiruby versions"
91
+ task :multi do
92
+ tests = FileList["test/**/*_test.rb"].map do |file|
93
+ 'require "%s"' % file
94
+ end.join("; ")
95
+ sh %{ multiruby -w -Ilib:test -e 'require "rubygems"; require "test/unit"; #{tests}' }
96
+ end
97
+
98
+ namespace :test do
99
+ desc "Do a live test against http://adgear.local/"
100
+ task :live do
101
+ base_url = ENV["BASE_URL"] || "http://adgear.local/api/services"
102
+ $:.unshift "lib"
103
+ require "ad_gear"
104
+
105
+ begin
106
+ client = AdGear::Client.new("francois", "94457f97dd3aa153c05257104e59a90f41a8110184cdefc8e52e4e295e48a782", :base_url => base_url, :logger => Logger.new(STDOUT))
107
+ p client.sites
108
+ rescue
109
+ puts $!
110
+ puts $!.backtrace
111
+ end
112
+ end
113
+ end
114
+
115
+ task :shell do
116
+ sh "irb -Ilib:vendor/activeresource/lib:vendor/activemodel/lib:vendor/activesupport/lib -rad_gear"
117
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,96 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{ad_gear_client}
5
+ s.version = "0.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Fran\303\247ois Beausoleil"]
9
+ s.date = %q{2009-08-12}
10
+ s.email = %q{francois@teksol.info}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "ad_gear_client.gemspec",
23
+ "examples/.gitignore",
24
+ "examples/ad_gear.yml.sample",
25
+ "examples/prelude.rb",
26
+ "examples/read_write_site.rb",
27
+ "examples/upload_file_to_ad_unit.rb",
28
+ "lib/ad_gear.rb",
29
+ "lib/ad_gear/ad_spot.rb",
30
+ "lib/ad_gear/ad_unit.rb",
31
+ "lib/ad_gear/ad_unit_click.rb",
32
+ "lib/ad_gear/ad_unit_file.rb",
33
+ "lib/ad_gear/ad_unit_interaction.rb",
34
+ "lib/ad_gear/ad_unit_variable.rb",
35
+ "lib/ad_gear/base.rb",
36
+ "lib/ad_gear/campaign.rb",
37
+ "lib/ad_gear/click.rb",
38
+ "lib/ad_gear/config.rb",
39
+ "lib/ad_gear/file.rb",
40
+ "lib/ad_gear/format.rb",
41
+ "lib/ad_gear/has_many_array.rb",
42
+ "lib/ad_gear/interaction.rb",
43
+ "lib/ad_gear/site.rb",
44
+ "lib/ad_gear/template.rb",
45
+ "lib/ad_gear/upload.rb",
46
+ "lib/ad_gear/variable.rb",
47
+ "lib/ad_gear/xml_format.rb",
48
+ "lib/core_ext.rb",
49
+ "test/ad_gear/ad_spot_test.rb",
50
+ "test/ad_gear/config_test.rb",
51
+ "test/ad_gear/site_test.rb",
52
+ "test/ad_gear/upload_test.rb",
53
+ "test/ad_gear_test.rb",
54
+ "test/fixtures/access-denied-no-auth.txt",
55
+ "test/test_helper.rb"
56
+ ]
57
+ s.homepage = %q{http://github.com/francois/ad_gear_client}
58
+ s.rdoc_options = ["--charset=UTF-8"]
59
+ s.require_paths = ["lib"]
60
+ s.rubyforge_project = %q{ad_gear_client}
61
+ s.rubygems_version = %q{1.3.5}
62
+ s.summary = %q{A Ruby client for accessing AdGear http://bloomdigital.com/}
63
+ s.test_files = [
64
+ "test/ad_gear/ad_spot_test.rb",
65
+ "test/ad_gear/config_test.rb",
66
+ "test/ad_gear/site_test.rb",
67
+ "test/ad_gear/upload_test.rb",
68
+ "test/ad_gear_test.rb",
69
+ "test/test_helper.rb",
70
+ "examples/prelude.rb",
71
+ "examples/read_write_site.rb",
72
+ "examples/upload_file_to_ad_unit.rb"
73
+ ]
74
+
75
+ if s.respond_to? :specification_version then
76
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
77
+ s.specification_version = 3
78
+
79
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
80
+ s.add_development_dependency(%q<lsegal-yard>, [">= 0.2.3"])
81
+ s.add_development_dependency(%q<mocha>, [">= 0.9.5"])
82
+ s.add_runtime_dependency(%q<activeresource>, ["> 2.0"])
83
+ s.add_runtime_dependency(%q<francois-rest-client>, ["~> 1"])
84
+ else
85
+ s.add_dependency(%q<lsegal-yard>, [">= 0.2.3"])
86
+ s.add_dependency(%q<mocha>, [">= 0.9.5"])
87
+ s.add_dependency(%q<activeresource>, ["> 2.0"])
88
+ s.add_dependency(%q<francois-rest-client>, ["~> 1"])
89
+ end
90
+ else
91
+ s.add_dependency(%q<lsegal-yard>, [">= 0.2.3"])
92
+ s.add_dependency(%q<mocha>, [">= 0.9.5"])
93
+ s.add_dependency(%q<activeresource>, ["> 2.0"])
94
+ s.add_dependency(%q<francois-rest-client>, ["~> 1"])
95
+ end
96
+ end
@@ -0,0 +1 @@
1
+ ad_gear.yml
@@ -0,0 +1,8 @@
1
+ ---
2
+ development:
3
+ site: http://adgear.local/api
4
+ user: francois
5
+ password: 94457f97dd3aa153c05257104e59a90f41a8110184cdefc8e52e4e295e48a782
6
+ use_basic_authentication: false
7
+ use_digest_authentication: true
8
+ logger: STDERR
@@ -0,0 +1,18 @@
1
+ $:.unshift "../lib"
2
+ %w(activesupport activemodel activeresource rest-client).each do |lib|
3
+ $:.unshift "../vendor/#{lib}/lib" if File.directory?("../vendor/#{lib}/lib")
4
+ end
5
+
6
+ require "ad_gear"
7
+ require "pp"
8
+
9
+ begin
10
+ require "ruby-debug"
11
+ rescue LoadError
12
+ # Ignored under 1.9, JRuby
13
+ end
14
+
15
+ require "test/unit/assertions"
16
+ include Test::Unit::Assertions
17
+
18
+ AdGear.config = AdGear::Config.new("ad_gear.yml", "development")
@@ -0,0 +1,32 @@
1
+ require "prelude"
2
+
3
+ p AdGear::Site.find(:all)
4
+
5
+ formats = AdGear::Format.find(:all)
6
+ site = AdGear::Site.new(:name => "XLsuite", :url => "http://xlsuite.com/", :ad_spots => [{:format_id => formats.first.id, :name => "sidebar top"}])
7
+ site.ad_spots << AdGear::AdSpot.new(:format_id => formats.first.id, :name => "homepage banner")
8
+
9
+ begin
10
+ p site.new?
11
+ p site.save
12
+ p site.new?
13
+ p "Saved"
14
+
15
+ p site.embed_code
16
+ p site.ad_spots
17
+
18
+ p site.ad_spots.class
19
+
20
+ site.ad_spots << AdGear::AdSpot.new(:format_id => formats.first.id, :name => "homepage vertical")
21
+ site.ad_spots.detect {|as| as.name == "homepage banner"}.name = "home page banner"
22
+ assert_equal 3, site.ad_spots.length, site.to_xml
23
+
24
+ puts site.to_xml
25
+ site.save
26
+
27
+ p "After PUT"
28
+ assert_equal 3, site.ad_spots.length, site.to_xml
29
+ rescue ActiveResource::BadRequest => e
30
+ p ActiveResource::Formats[:xml].decode(e.response.body)
31
+ p "Could not save"
32
+ end
@@ -0,0 +1,40 @@
1
+ require "prelude"
2
+
3
+ begin
4
+ gem "francois-rest-client", ">= 1.1.5"
5
+ rescue RuntimeError => e
6
+ p e
7
+ end
8
+
9
+ require "restclient"
10
+ p RestClient.version
11
+ RestClient.log = "stdout"
12
+
13
+ upload = AdGear::Upload.new(:filename => File.dirname(__FILE__) + "/ad_gear.yml")
14
+ if upload.save then
15
+ p "uploaded successfully"
16
+ p upload.id
17
+ else
18
+ p upload.errors
19
+ exit 1
20
+ end
21
+
22
+ templates = AdGear::Template.find(:all)
23
+ template = templates.detect {|template| template.name == "Javascript"}
24
+ formats = AdGear::Format.find(:all)
25
+ campaigns = AdGear::Campaign.find(:all)
26
+
27
+ # Use Javascript, but forget to put the payload
28
+ ad_unit = AdGear::AdUnit.new(:campaign => campaigns.first, :name => "BMW M5", :format => formats.first, :template => template.name)
29
+ ad_unit.ad_unit_files << AdGear::AdUnitFile.new(:name => "image", :upload => upload)
30
+ ad_unit.ad_unit_interactions << AdGear::AdUnitInteraction.new(:name => "something")
31
+ ad_unit.ad_unit_clicks << AdGear::AdUnitClick.new(:name => "clickTAG", :url => "http://somewhere.com/")
32
+ puts "================="*8
33
+ puts ad_unit.to_xml
34
+ puts "================="*8
35
+ assert_raise ActiveResource::BadRequest do
36
+ ad_unit.save
37
+ end
38
+
39
+ ad_unit.ad_unit_variables << AdGear::AdUnitVariable.new(:name => "payload", :value => "// whatever")
40
+ assert ad_unit.save, "What? Now I'm providing the system-required variable, why am I still erroring out?\n" + ad_unit.errors.to_yaml
@@ -0,0 +1,6 @@
1
+ module AdGear
2
+ class AdSpot < AdGear::Base
3
+ ignorable_attributes :embed_code
4
+ belongs_to :format
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module AdGear
2
+ class AdUnit < AdGear::Base
3
+ has_many :ad_unit_files, :ad_unit_clicks, :ad_unit_interactions, :ad_unit_variables
4
+ belongs_to :campaign, :format
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class AdUnitClick < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module AdGear
2
+ class AdUnitFile < AdGear::Base
3
+ belongs_to :upload
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class AdUnitInteraction < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class AdUnitVariable < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,144 @@
1
+ module AdGear
2
+ class Base < ActiveResource::Base
3
+ def initialize(params={})
4
+ params = params.inject(Hash.new) do |memo, (name, value)|
5
+ name = name.to_s
6
+ if self.class.belongs_to_associations.include?(name) then
7
+ name = self.class.belongs_to_attribute_name_for(name)
8
+ value = self.class.unpack_belongs_to_association(value)
9
+ end
10
+
11
+ memo[name] = value
12
+ memo
13
+ end
14
+ super(params)
15
+ end
16
+
17
+ # Declares a relationship where we store the ID, but accept and/or return the full object.
18
+ #
19
+ # @example
20
+ # class AdGear::AdSpot < AdGear::Base
21
+ # belongs_to :format
22
+ # end
23
+ #
24
+ # AdGear::AdSpot.new(:format => Format.find(1)).attributes
25
+ # #=> {"format_id" => 1}
26
+ def self.belongs_to(*attributes)
27
+ attributes.flatten.compact.each do |attribute|
28
+ attribute_name = attribute.to_s
29
+ belongs_to_associations << attribute_name
30
+
31
+ belongs_to_attribute_writer_for(attribute_name)
32
+ belongs_to_attribute_reader_for(attribute_name)
33
+ end
34
+ end
35
+
36
+ def self.belongs_to_associations #:nodoc:
37
+ @belongs_to_associations ||= []
38
+ end
39
+
40
+ # Defines a managed sub-collection. Elements managed through a #has_many are
41
+ # ready for use by AttributeFu or ActiveRecord's 2.3 nested_attributes.
42
+ #
43
+ # @example
44
+ # class AdGear::AdUnit < AdGear::Base
45
+ # has_many :ad_unit_files, :ad_unit_clicks
46
+ # has_many :ad_unit_interactions, :ad_unit_variables
47
+ # end
48
+ #
49
+ # AdGear::AdUnit.new(:ad_unit_files => [AdUnitFile.new(...)]).to_xml
50
+ # <ad-unit>
51
+ # <ad-unit-file-attributes>
52
+ # <new>
53
+ # <n0>
54
+ # ...
55
+ # </n0>
56
+ # </new>
57
+ # <!-- If there were "old" records, they'd be here
58
+ # </ad-unit-file-attributes>
59
+ # </ad-unit>
60
+ def self.has_many(*collections)
61
+ collections.flatten.compact.each do |collection|
62
+ collection_name = collection.to_s
63
+
64
+ # Remember what collections we are managing, for use in #to_xml
65
+ has_many_collections << collection_name
66
+
67
+ # Define a getter for the collection that transforms a plain Array into
68
+ # a HasManyArray which knows about new and old records
69
+ define_method(collection_name) do
70
+ arr = @attributes[collection_name]
71
+ return arr if arr.kind_of?(AdGear::HasManyArray)
72
+ @attributes[collection_name] = AdGear::HasManyArray.new(collection_name.to_sym, arr)
73
+ end
74
+ end
75
+ end
76
+
77
+ def self.has_many_collections #:nodoc:
78
+ @has_many_collections ||= []
79
+ end
80
+
81
+ # Defines a list of attributes that should be ignored and not sent back to the server.
82
+ #
83
+ # @example
84
+ # class AdGear::Site < AdGear::Base
85
+ # ignorable_attributes :embed_code
86
+ # end
87
+ #
88
+ # AdGear::Site.find(13).to_xml
89
+ # <site>
90
+ # ...
91
+ # <!-- no embed-code element -->
92
+ # </site>
93
+ def self.ignorable_attributes(*attributes)
94
+ @ignorable_attributes ||= []
95
+ @ignorable_attributes += attributes.flatten.compact.map {|name| name.to_s}
96
+ @ignorable_attributes
97
+ end
98
+
99
+ def to_xml(options={})
100
+ self.class.has_many_collections.each do |name|
101
+ send(name) # convert the @attributes value into a HasManyArray
102
+ end
103
+
104
+ hash = if self.class.ignorable_attributes.empty?
105
+ @attributes
106
+ else
107
+ returning(@attributes.dup) do |hash|
108
+ self.class.ignorable_attributes.each do |attr_name|
109
+ hash.delete(attr_name)
110
+ end
111
+ end
112
+ end
113
+ hash.to_xml({:root => self.class.element_name}.merge(options))
114
+ end
115
+
116
+ # Delegates to #to_xml, as this is the simplest thing that could possibly work
117
+ def encode(options={}) #:nodoc:
118
+ self.to_xml
119
+ end
120
+
121
+ private
122
+
123
+ def self.belongs_to_attribute_writer_for(attribute_name) #:nodoc:
124
+ define_method("#{attribute_name}=") do |value|
125
+ @attributes[self.class.belongs_to_attribute_name_for(attribute_name)] = self.class.unpack_belongs_to_association(value)
126
+ end
127
+ end
128
+
129
+ def self.belongs_to_attribute_reader_for(attribute_name) #:nodoc:
130
+ define_method(attribute_name) do
131
+ id = @attributes[belongs_to_attribute_name_for(attribute_name)]
132
+ id.blank? ? nil : AdGear.const_get(attribute_name.classify).find(id)
133
+ end
134
+ end
135
+
136
+ def self.belongs_to_attribute_name_for(association_name)
137
+ "#{association_name}_id"
138
+ end
139
+
140
+ def self.unpack_belongs_to_association(value)
141
+ value ? value.id : nil
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Campaign < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Click < AdGear::Base
3
+ end
4
+ end