bloom-ad_gear_client 0.3.5

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.
Files changed (48) hide show
  1. data/.gitignore +6 -0
  2. data/LICENSE +21 -0
  3. data/README.rdoc +55 -0
  4. data/Rakefile +131 -0
  5. data/VERSION +1 -0
  6. data/ad_gear_client.gemspec +105 -0
  7. data/examples/.gitignore +1 -0
  8. data/examples/ad_gear.yml.sample +8 -0
  9. data/examples/create_placement.rb +57 -0
  10. data/examples/prelude.rb +27 -0
  11. data/examples/read_write_site.rb +36 -0
  12. data/examples/upload_file_to_ad_unit.rb +49 -0
  13. data/lib/ad_gear/ad_spot.rb +7 -0
  14. data/lib/ad_gear/ad_spot_membership.rb +5 -0
  15. data/lib/ad_gear/ad_unit.rb +14 -0
  16. data/lib/ad_gear/ad_unit_click.rb +5 -0
  17. data/lib/ad_gear/ad_unit_file.rb +6 -0
  18. data/lib/ad_gear/ad_unit_interaction.rb +5 -0
  19. data/lib/ad_gear/ad_unit_variable.rb +5 -0
  20. data/lib/ad_gear/advertiser.rb +4 -0
  21. data/lib/ad_gear/base.rb +168 -0
  22. data/lib/ad_gear/click.rb +4 -0
  23. data/lib/ad_gear/config.rb +143 -0
  24. data/lib/ad_gear/core_ext.rb +18 -0
  25. data/lib/ad_gear/file.rb +4 -0
  26. data/lib/ad_gear/format.rb +4 -0
  27. data/lib/ad_gear/has_many_array.rb +58 -0
  28. data/lib/ad_gear/interaction.rb +4 -0
  29. data/lib/ad_gear/placement_membership.rb +5 -0
  30. data/lib/ad_gear/placement_rule.rb +5 -0
  31. data/lib/ad_gear/publisher.rb +7 -0
  32. data/lib/ad_gear/site.rb +6 -0
  33. data/lib/ad_gear/template.rb +4 -0
  34. data/lib/ad_gear/upload.rb +46 -0
  35. data/lib/ad_gear/variable.rb +4 -0
  36. data/lib/ad_gear/web_campaign.rb +4 -0
  37. data/lib/ad_gear/web_placement.rb +26 -0
  38. data/lib/ad_gear/xml_format.rb +35 -0
  39. data/lib/ad_gear.rb +105 -0
  40. data/test/ad_gear/ad_spot_test.rb +43 -0
  41. data/test/ad_gear/config_test.rb +114 -0
  42. data/test/ad_gear/placement_rule_test.rb +22 -0
  43. data/test/ad_gear/site_test.rb +69 -0
  44. data/test/ad_gear/upload_test.rb +58 -0
  45. data/test/ad_gear_test.rb +23 -0
  46. data/test/fixtures/access-denied-no-auth.txt +13 -0
  47. data/test/test_helper.rb +33 -0
  48. metadata +150 -0
@@ -0,0 +1,168 @@
1
+ module AdGear
2
+ class Base < ActiveResource::Base
3
+ def initialize(params={})
4
+ super({})
5
+ params.each do |key, value|
6
+ send("#{key}=", value)
7
+ end
8
+ end
9
+
10
+ # Declares a relationship where we store the ID, but accept and/or return the full object.
11
+ #
12
+ # @example
13
+ # class AdGear::AdSpot < AdGear::Base
14
+ # belongs_to :format
15
+ # belongs_to :bookable, :polymorphic => true
16
+ # end
17
+ #
18
+ # include AdGear
19
+ # AdSpot.new(:format => Format.find(1), :bookable => Publisher.find(2)).attributes
20
+ # #=> {"format_id" => 1, "bookable_id" => 2, "bookable_type" => "Publisher"}
21
+ def self.belongs_to(*attributes)
22
+ options = attributes.extract_options!
23
+ attributes.each do |attribute|
24
+ attribute_name = attribute.to_s
25
+ belongs_to_associations[attribute_name] = options
26
+
27
+ if options[:polymorphic] then
28
+ polymorphic_belongs_to_attribute_writer_for(attribute_name)
29
+ polymorphic_belongs_to_attribute_reader_for(attribute_name)
30
+ else
31
+ belongs_to_attribute_writer_for(attribute_name)
32
+ belongs_to_attribute_reader_for(attribute_name)
33
+ end
34
+ end
35
+ end
36
+
37
+ def self.belongs_to_associations #:nodoc:
38
+ @belongs_to_associations ||= {}
39
+ end
40
+
41
+ # Defines a managed sub-collection. Elements managed through a #has_many are
42
+ # ready for use by AttributeFu or ActiveRecord's 2.3 nested_attributes.
43
+ #
44
+ # @example
45
+ # class AdGear::AdUnit < AdGear::Base
46
+ # has_many :ad_unit_files, :ad_unit_clicks
47
+ # has_many :ad_unit_interactions, :ad_unit_variables
48
+ # end
49
+ #
50
+ # AdGear::AdUnit.new(:ad_unit_files => [AdUnitFile.new(...)]).to_xml
51
+ # <ad-unit>
52
+ # <ad-unit-file-attributes>
53
+ # <new>
54
+ # <n0>
55
+ # ...
56
+ # </n0>
57
+ # </new>
58
+ # <!-- If there were "old" records, they'd be here
59
+ # </ad-unit-file-attributes>
60
+ # </ad-unit>
61
+ def self.has_many(*collections)
62
+ collections.flatten.compact.each do |collection|
63
+ collection_name = collection.to_s
64
+
65
+ # Remember what collections we are managing, for use in #to_xml
66
+ has_many_collections << collection_name
67
+
68
+ # Define a getter for the collection that transforms a plain Array into
69
+ # a HasManyArray which knows about new and old records
70
+ define_method(collection_name) do
71
+ arr = @attributes[collection_name]
72
+ return arr if arr.kind_of?(AdGear::HasManyArray)
73
+ @attributes[collection_name] = AdGear::HasManyArray.new(collection_name.to_sym, AdGear.const_get(collection_name.classify), arr)
74
+ end
75
+
76
+ define_method("#{collection_name}=") do |arr|
77
+ @attributes[collection_name] = if arr.kind_of?(AdGear::HasManyArray) then
78
+ arr
79
+ else
80
+ AdGear::HasManyArray.new(collection_name.to_sym, AdGear.const_get(collection_name.classify), arr)
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ def self.has_many_collections #:nodoc:
87
+ @has_many_collections ||= []
88
+ end
89
+
90
+ # Defines a list of attributes that should be ignored and not sent back to the server.
91
+ #
92
+ # @example
93
+ # class AdGear::Site < AdGear::Base
94
+ # ignorable_attributes :embed_code
95
+ # end
96
+ #
97
+ # AdGear::Site.find(13).to_xml
98
+ # <site>
99
+ # ...
100
+ # <!-- no embed-code element -->
101
+ # </site>
102
+ def self.ignorable_attributes(*attributes)
103
+ @ignorable_attributes ||= []
104
+ @ignorable_attributes += attributes.flatten.compact.map {|name| name.to_s}
105
+ @ignorable_attributes
106
+ end
107
+
108
+ def to_xml(options={})
109
+ self.class.has_many_collections.each do |name|
110
+ send(name) # convert the @attributes value into a HasManyArray
111
+ end
112
+
113
+ hash = if self.class.ignorable_attributes.empty?
114
+ @attributes
115
+ else
116
+ returning(@attributes.dup) do |hash|
117
+ self.class.ignorable_attributes.each do |attr_name|
118
+ hash.delete(attr_name)
119
+ end
120
+ end
121
+ end
122
+ hash.to_xml({:root => self.class.element_name}.merge(options))
123
+ end
124
+
125
+ # Delegates to #to_xml, as this is the simplest thing that could possibly work
126
+ def encode(options={}) #:nodoc:
127
+ self.to_xml
128
+ end
129
+
130
+ private
131
+
132
+ def self.polymorphic_belongs_to_attribute_writer_for(attribute_name) #:nodoc:
133
+ define_method("#{attribute_name}=") do |value|
134
+ @attributes[self.class.belongs_to_attribute_name_for_id(attribute_name)] = value ? value.id : nil
135
+ @attributes[self.class.belongs_to_attribute_name_for_class(attribute_name)] = value ? value.class.name.demodulize : nil
136
+ end
137
+ end
138
+
139
+ def self.polymorphic_belongs_to_attribute_reader_for(attribute_name) #:nodoc:
140
+ define_method(attribute_name) do
141
+ klass = @attributes[belongs_to_attribute_name_for_class(attribute_name)]
142
+ id = @attributes[belongs_to_attribute_name_for_id(attribute_name)]
143
+ id.blank? ? nil : AdGear.const_get(AdGear.const_get(klass)).find(id)
144
+ end
145
+ end
146
+
147
+ def self.belongs_to_attribute_writer_for(attribute_name) #:nodoc:
148
+ define_method("#{attribute_name}=") do |value|
149
+ @attributes[self.class.belongs_to_attribute_name_for_id(attribute_name)] = value ? value.id : nil
150
+ end
151
+ end
152
+
153
+ def self.belongs_to_attribute_reader_for(attribute_name) #:nodoc:
154
+ define_method(attribute_name) do
155
+ id = @attributes[belongs_to_attribute_name_for_id(attribute_name)]
156
+ id.blank? ? nil : AdGear.const_get(attribute_name.classify).find(id)
157
+ end
158
+ end
159
+
160
+ def self.belongs_to_attribute_name_for_class(association_name)
161
+ "#{association_name}_type"
162
+ end
163
+
164
+ def self.belongs_to_attribute_name_for_id(association_name)
165
+ "#{association_name}_id"
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Click < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,143 @@
1
+ require "erb"
2
+ require "pathname"
3
+
4
+ module AdGear
5
+ class Config
6
+ # Raised when the specified environment could not be found in the YAML configuration file.
7
+ class MissingEnvironmentSpecification < RuntimeError; end
8
+
9
+ # Reads in a YAML file containing configuration parameters for the AdGear::Client. The file
10
+ # can contain sections relating to the environment the client is running within.
11
+ #
12
+ # The YAML configuration file *must* use strings as keys.
13
+ #
14
+ # @example A sample YAML configuration file:
15
+ # development:
16
+ # site: http://localhost:3000/api
17
+ # user: dummy
18
+ # password: whatever
19
+ # logger: <%= Rails.root %>/path/to/log/file.log
20
+ # production:
21
+ # site: http://admin.adgear.com/api
22
+ # user: your_real_login
23
+ # password: your_real_digest_password
24
+ # logger: /var/log/ad_gear.log
25
+ #
26
+ # @example Reading this sample file:
27
+ # AdGear.config = AdGear::Config.new("path/to/config/file", "development")
28
+ #
29
+ # @example Reading from +config/initializers/ad_gear.rb+ in a Rails environment
30
+ # AdGear.config = AdGear::Config.new(Rails.root + "config/ad_gear.yml", Rails.env)
31
+ #
32
+ # @param obj [#read, Hash, String] When the object responds to #read, reads in the IO-like
33
+ # object and parses it as a YAML stream. If the object is a
34
+ # Hash, use it as-is. Else, treat the object as the path to a
35
+ # YAML file containing the configuration.
36
+ # @param environment [String, Symbol, nil] If this is +nil+, then do no environment unpacking, else
37
+ # find the environment that matches this string. If none
38
+ # matches, a MissingEnvironmentSpecification exception will
39
+ # be raised.
40
+ #
41
+ # @raise MissingEnvironmentSpecification When the +environment+ parameter specifies a missing environment declaration.
42
+ def initialize(obj={}, environment=nil)
43
+ @config = Hash.new
44
+ @logger = nil
45
+
46
+ config = if obj.kind_of?(Hash) then
47
+ obj
48
+ elsif obj.respond_to?(:read) then
49
+ YAML.load(ERB.new(obj.read).result)
50
+ else
51
+ YAML.load(ERB.new(IO.read(obj)).result)
52
+ end
53
+ if environment then
54
+ raise MissingEnvironmentSpecification, "Could not find #{environment.to_s.inspect} in #{config.inspect} read from #{obj.inspect}. Add the missing environment declaration, or change the parameter to this method." unless config.respond_to?(:has_key?) && config.has_key?(environment.to_s)
55
+ config = config[environment.to_s]
56
+ end
57
+
58
+ config.each_pair do |key, value|
59
+ send("#{key}=", value)
60
+ end
61
+ end
62
+
63
+ # Returns a Hash of the currect configuration.
64
+ def to_hash
65
+ @config.dup
66
+ end
67
+
68
+ def site=(value)
69
+ @config["site"] = value
70
+ end
71
+
72
+ # Returns the configured site, which is the root of the API.
73
+ def site
74
+ @config["site"]
75
+ end
76
+
77
+ def user=(value)
78
+ @config["user"] = value
79
+ end
80
+
81
+ # Returns the configured username / login.
82
+ def user
83
+ @config["user"]
84
+ end
85
+
86
+ def password=(value)
87
+ @config["password"] = value
88
+ end
89
+
90
+ # Returns the configured password.
91
+ def password
92
+ @config["password"]
93
+ end
94
+
95
+ # Denies or allows using Basic authentication method. This will have an effect only if you are using http://github.com/francois/rails/ar_basic/activeresource
96
+ def use_basic_authentication
97
+ @config["use_basic_authentication"]
98
+ end
99
+
100
+ def use_basic_authentication=(value)
101
+ @config["use_basic_authentication"] = value
102
+ end
103
+
104
+ # Denies or allows using Digest authentication method. This will have an effect only if you are using http://github.com/francois/rails/ar_digest/activeresource
105
+ def use_digest_authentication
106
+ @config["use_digest_authentication"]
107
+ end
108
+
109
+ def use_digest_authentication=(value)
110
+ @config["use_digest_authentication"] = value
111
+ end
112
+
113
+ # Returns a format object suitable for use by ActiveResource.
114
+ def format
115
+ AdGear::XmlFormat
116
+ end
117
+
118
+ # Returns the Logger instance that was configured in #logger=.
119
+ def logger
120
+ @logger
121
+ end
122
+
123
+ # Register a Logger for use by AdGear's client.
124
+ # @param value [nil, String] When nil, no Logger is assigned.
125
+ # When the values STDERR or STDOUT are used, logs to the specified stream.
126
+ # Else, it is taken as the path to a log file.
127
+ def logger=(value)
128
+ @config["logger"] = value
129
+ @logger = case value
130
+ when nil, ""
131
+ # No logger
132
+ nil
133
+ when /^std(err|out)$/i
134
+ # Existing stream
135
+ Logger.new(Object.const_get(value.upcase))
136
+ else
137
+ warn("WARNING: path to logger in AdGear::Client configuration is relative: CWD is #{Dir.pwd.inspect}") unless Pathname.new(value).absolute?
138
+ # Path to a file
139
+ Logger.new(value)
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,18 @@
1
+ #
2
+ # ActiveSupport's Array#to_xml will build an XML with root set to the full class name including
3
+ # module(s) it may be nested in - we don't want that, we want it to be *just* the class name,
4
+ # make it so with this monkey patch...
5
+ #
6
+ # Note this is loaded last from AdGear.config= after ActiveSupport has already been loaded. We
7
+ # cannot simply override because ActiveSupport does lazy loading.
8
+ #
9
+ class Array
10
+ def to_xml_with_module_prefixing(options = {})
11
+ raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
12
+ root = all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ?
13
+ ActiveSupport::Inflector.pluralize(ActiveSupport::Inflector.underscore(first.class.to_s.split("::").last)) : "records"
14
+ to_xml_without_module_prefixing({ :root => root }.merge(options))
15
+ end
16
+
17
+ alias_method_chain :to_xml, :module_prefixing
18
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class File < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Format < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,58 @@
1
+ module AdGear
2
+ class HasManyArray
3
+ include Enumerable
4
+
5
+ def initialize(name, klass, saved=nil)
6
+ @name = name.to_s.singularize.dasherize + "-attributes"
7
+ @klass = klass
8
+ @new = []
9
+ @saved = []
10
+ saved.each do |obj|
11
+ self << obj
12
+ end if saved
13
+ end
14
+
15
+ def <<(object)
16
+ root = if object.kind_of?(Hash) then
17
+ # Instantiate an object from the Hash, which will obviously be a new object
18
+ object = @klass.new(object)
19
+ @new
20
+ elsif object.respond_to?(:new_record?) && object.new_record?
21
+ @new
22
+ else
23
+ @saved
24
+ end
25
+ root << object
26
+ end
27
+
28
+ def each(&block)
29
+ @saved.each(&block)
30
+ @new.each(&block)
31
+ end
32
+
33
+ def length
34
+ @saved.length + @new.length
35
+ end
36
+
37
+ alias_method :size, :length
38
+
39
+ def to_xml(options={})
40
+ xml = options[:builder] || Builder::XmlMarkup.new
41
+ xml.__send__(@name) do
42
+ unless @new.empty?
43
+ xml.tag!(:new) do
44
+ @new.each_with_index do |obj, index|
45
+ obj.to_xml(options.merge(:root => "n" << index.to_s))
46
+ end
47
+ end
48
+ end
49
+
50
+ unless @saved.empty?
51
+ @saved.each do |obj|
52
+ obj.to_xml(options.merge(:root => "n" << obj.id.to_s))
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Interaction < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module AdGear
2
+ class PlacementMembership < AdGear::Base
3
+ belongs_to :ad_unit
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module AdGear
2
+ class PlacementRule < AdGear::Base
3
+ belongs_to :bookable, :polymorphic => true
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module AdGear
2
+ class Publisher < AdGear::Base
3
+ def active?
4
+ state == "active"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module AdGear
2
+ class Site < AdGear::Base
3
+ has_many :ad_spots
4
+ ignorable_attributes :embed_code
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Template < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,46 @@
1
+ begin
2
+ gem "francois-rest-client", ">= 1.1.5"
3
+ rescue
4
+ # Ignored. We hope we got what we wanted
5
+ warn "Could not ensure francois-rest-client 1.1.5 is loaded. If you have problems uploading files, make sure you have that gem installed and that the AdGear::Client uses that version."
6
+ end
7
+ require "restclient"
8
+
9
+ module AdGear
10
+ class Upload < AdGear::Base
11
+ def save
12
+ retried = false
13
+ headers = Hash.new
14
+ begin
15
+ uri = self.class.site.merge(URI.parse(self.class.collection_path))
16
+ params = {"upload[uploaded_data]" => ::File.new(attributes["filename"]), "upload[filename]" => ::File.basename(attributes["filename"])}
17
+ out = RestClient.post(uri.to_s, params, headers)
18
+ logger.debug out if logger
19
+ load(connection.format.decode(out))
20
+ rescue RestClient::Unauthorized => e
21
+ # Retry once only
22
+ raise if retried
23
+
24
+ www_authenticate = e.response["www-authenticate"]
25
+ header = ActiveResource::Digest.authenticate(uri, self.class.user, self.class.password, www_authenticate, :post)
26
+ headers["Authorization"] = header
27
+
28
+ retried = true
29
+ retry
30
+ end
31
+ end
32
+
33
+ def update_attribute(*args)
34
+ raise_unsupported_operation
35
+ end
36
+
37
+ def update_attributes(*args)
38
+ raise_unsupported_operation
39
+ end
40
+
41
+ protected
42
+ def raise_unsupported_operation
43
+ raise UnsupportedOperation, "Unsupported operation: uploads are write-once only"
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Variable < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class WebCampaign < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,26 @@
1
+ module AdGear
2
+ class WebPlacement < AdGear::Base
3
+ belongs_to :campaign, :format
4
+ has_many :placement_rules, :placement_memberships
5
+
6
+ def selection_mechanism
7
+ case value = attributes["selection_mechanism"]
8
+ when "R" ; "rotated"
9
+ when "W" ; "weighted"
10
+ else ; value
11
+ end
12
+ end
13
+
14
+ def selection_mechanism=(value)
15
+ case value
16
+ when /^r/i
17
+ attributes["selection_mechanism"] = "R"
18
+ when /^w/i
19
+ attributes["selection_mechanism"] = "W"
20
+ else
21
+ # Assign whatever we received, and hope for the best
22
+ attributes["selection_mechanism"] = value
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ require 'active_support/core_ext/hash/conversions'
2
+
3
+ module AdGear
4
+ # Copied from ActiveResource's +active_resource/formats/xml_format.rb+. Changed +mime_type+ to return AdGear's expected mime type.
5
+ module XmlFormat
6
+ extend self
7
+
8
+ def extension
9
+ "agml"
10
+ end
11
+
12
+ def mime_type
13
+ "application/vnd.bloom.adgear.v1+xml"
14
+ end
15
+
16
+ def encode(hash, options={})
17
+ hash.to_xml(options)
18
+ end
19
+
20
+ def decode(xml)
21
+ from_xml_data(Hash.from_xml(xml))
22
+ end
23
+
24
+ private
25
+ # Manipulate from_xml Hash, because xml_simple is not exactly what we
26
+ # want for Active Resource.
27
+ def from_xml_data(data)
28
+ if data.is_a?(Hash) && data.keys.size == 1
29
+ data.values.first
30
+ else
31
+ data
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/ad_gear.rb ADDED
@@ -0,0 +1,105 @@
1
+ #--
2
+ # Copyright (c) 2009 François Beausoleil
3
+ # Copyright (c) 2009 Bloom Digital Platforms
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ require "active_support"
26
+ require "active_resource"
27
+ require "logger"
28
+
29
+ warn "You are using the plain jane version of ActiveResource. You could use Digest authentication if you used http://github.com/francois/rails/tree/ar_digest" unless ActiveResource::Base.respond_to?(:use_basic_authentication)
30
+
31
+ module AdGear
32
+ # AdGear's models superclass
33
+ autoload :Base, "ad_gear/base"
34
+
35
+ # AdGear models themselves
36
+ autoload :Site, "ad_gear/site"
37
+ autoload :AdSpot, "ad_gear/ad_spot"
38
+ autoload :AdSpotMembership, "ad_gear/ad_spot_membership"
39
+ autoload :WebCampaign, "ad_gear/web_campaign"
40
+ autoload :Format, "ad_gear/format"
41
+ autoload :Upload, "ad_gear/upload"
42
+ autoload :Publisher, "ad_gear/publisher"
43
+
44
+ # Placements and it's dependencies
45
+ autoload :WebPlacement, "ad_gear/web_placement"
46
+ autoload :PlacementRule, "ad_gear/placement_rule"
47
+ autoload :PlacementMembership, "ad_gear/placement_membership"
48
+
49
+ # AdUnits and it's child models
50
+ autoload :AdUnit, "ad_gear/ad_unit"
51
+ autoload :AdUnitFile, "ad_gear/ad_unit_file"
52
+ autoload :AdUnitInteraction, "ad_gear/ad_unit_interaction"
53
+ autoload :AdUnitClick, "ad_gear/ad_unit_click"
54
+ autoload :AdUnitVariable, "ad_gear/ad_unit_variable"
55
+
56
+ # Templates and their dependencies, to know what child models are required
57
+ autoload :Template, "ad_gear/template"
58
+ autoload :File, "ad_gear/file"
59
+ autoload :Variable, "ad_gear/variable"
60
+ autoload :Click, "ad_gear/click"
61
+ autoload :Interaction, "ad_gear/interaction"
62
+
63
+ # Miscellaneous stuff
64
+ autoload :Config, "ad_gear/config"
65
+ autoload :XmlFormat, "ad_gear/xml_format"
66
+ autoload :HasManyArray, "ad_gear/has_many_array"
67
+
68
+ class UnsupportedOperation < RuntimeError; end
69
+
70
+ # Configures AdGear's ActiveResource models.
71
+ #
72
+ # NOTE: AdGear's client expects and uses Nokogiri instead of REXML.
73
+ # See http://rubyglasses.blogspot.com/2009/07/40-speedup-using-nokogiri.html#instructions
74
+ def self.config=(config)
75
+ @config = config
76
+
77
+ AdGear::Base.logger = config.logger
78
+
79
+ AdGear::Base.site = config.site
80
+ AdGear::Base.user = config.user
81
+ AdGear::Base.password = config.password
82
+ AdGear::Base.format = config.format
83
+
84
+ if AdGear::Base.respond_to?(:use_basic_authentication=)
85
+ AdGear::Base.use_basic_authentication = config.use_basic_authentication
86
+ end
87
+
88
+ if AdGear::Base.respond_to?(:use_digest_authentication=)
89
+ AdGear::Base.use_digest_authentication = config.use_digest_authentication
90
+ end
91
+
92
+ ActiveSupport::XmlMini.backend = "Nokogiri"
93
+
94
+ # Can't require before now, because our own method is overwritten
95
+ require "ad_gear/core_ext"
96
+ end
97
+
98
+ def self.config
99
+ @config
100
+ end
101
+
102
+ def self.logger
103
+ config.logger
104
+ end
105
+ end