pocketmath-advertise 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c9ff5e64083c8fbfebd787eeea561cec50bdf79
4
- data.tar.gz: 7f670f3d445182aa9a86728fc212bc0599ef85d9
3
+ metadata.gz: 1fa5aa04e223ff53658c46d7b519315fb79e8546
4
+ data.tar.gz: 0d3b61f58a15c21b323ccba55c2244fa82ab1d0e
5
5
  SHA512:
6
- metadata.gz: 56289da6d8e1acc54fc44a68a5c29e50da6efbcee24aa5ab4b70bb0277684cf4542990b51a6b901d60915602381fe852cffe21735ac5ef3b10d85ec92df3bc5e
7
- data.tar.gz: 277c043dfbee2c67a2989d7ee01f0ba85421deb8ede18226460d2c534d4924ff3bcc9497d906d161f5f37edebce4993095b5fa5cd1c5dee00e1dc8640e17ce9c
6
+ metadata.gz: ceade68a085ea00f3c7bdc1c5bb0b9516a90682135a13cd0ecac309fd74dbb4fe5a30f466a47eee6692a916ca337fc4545da638c3a3c33e2bfa181b8b5275e1b
7
+ data.tar.gz: e93f468332b6b9fb624148b0778a1631c2090007a113853213c456690bab303d64fa0e08029cc679ee1253ed5cc00fd28e43c5fc1c90ed3b8d040c5c46d724ea
@@ -0,0 +1,42 @@
1
+ module PocketMath::Advertiser::V1
2
+
3
+ class InsertionOrderStats
4
+
5
+ # Cost per thousand Impressions
6
+ attr_reader :cpm
7
+
8
+ # Cost per Click
9
+ attr_reader :cpc
10
+
11
+ # Cost per Action (Cost per Conversion)
12
+ attr_reader :cpa
13
+
14
+ # Click-through Rate (Clicks per impression)
15
+ attr_reader :ctr
16
+
17
+ attr_reader :impressions, :clicks, :conversions
18
+
19
+ # Ad spend in currency
20
+ attr_reader :spend
21
+
22
+ private
23
+
24
+ attr_writer :cpm, :cpc, :cpa, :ctr
25
+ attr_writer :impressions, :clicks, :conversions
26
+ attr_writer :spend
27
+
28
+ public
29
+
30
+ # Create a new instance.
31
+ # * Specify attributes in a hash as { :cpm => 1.25, :cpc => 2.33, ... }
32
+ def self.create(opts = {})
33
+ iostats = InsertionOrderStats.new
34
+ opts.each_pair do |k,v|
35
+ raise "#{k.to_s}=#{v} was not a number" if !v.is_a?(Numeric)
36
+ iostats.send(k.to_s + "=", v)
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -1,2 +1,3 @@
1
1
  require 'pocketmath-geocode'
2
2
  require 'pocketmath-advertiser'
3
+ require 'model/insertion_order_stats'
@@ -1,5 +1,4 @@
1
1
  require 'json'
2
- require 'open-uri'
3
2
  require 'net/http'
4
3
  require 'net/https'
5
4
  require 'uri'
@@ -10,152 +9,213 @@ require 'curb'
10
9
  module PocketMath
11
10
  module PocketMath::Advertiser
12
11
  module PocketMath::Advertiser::V1
13
-
14
- API_BASE_URL = "https://api.pocketmath.com"
12
+
13
+ DEFAULT_API_BASE_URL = "https://api.pocketmath.com"
14
+
15
+ def self.open(pocketmath_api_key, pocketmath_api_base_url = DEFAULT_API_BASE_URL)
16
+ return Client.new(pocketmath_api_key, pocketmath_api_base_url)
17
+ end
18
+
19
+ class PocketMath::Advertiser::V1::Client
20
+
21
+ def initialize(pocketmath_api_key, pocketmath_api_base_url)
22
+ @pocketmath_api_key = pocketmath_api_key
23
+ @pocketmath_api_base_url = pocketmath_api_base_url
24
+ end
25
+
26
+ def close
27
+ end
15
28
 
16
- def self.find_gps_list_id_by_name(name)
17
- p "get_gps_list_id"
18
- url = "#{API_BASE_URL}/v1/lists/gps/list.json?token=#{POCKETMATH_API_KEY}&limit=10000"
19
- response = Net::HTTP.get_response(URI.parse(url))
20
- data = response.body
21
- obj = JSON.parse(data)
22
- obj.each do |result|
23
- return result["id"] if result["name"] == name
29
+ def find_gps_list_id_by_name(name)
30
+ p "get_gps_list_id"
31
+ url = "#{@pocketmath_api_base_url}/v1/lists/gps/list.json?token=#{@pocketmath_api_key}&limit=10000"
32
+ response = Net::HTTP.get_response(URI.parse(url))
33
+ data = response.body
34
+ obj = JSON.parse(data)
35
+ obj.each do |result|
36
+ return result["id"] if result["name"] == name
37
+ end
24
38
  end
25
- end
26
39
 
27
- def self.create_gps_list(name)
28
- raise "name was nil" if name.nil?
29
- raise "name was blank" if name.empty?
40
+ def create_gps_list(name)
41
+ raise "name was nil" if name.nil?
42
+ raise "name was blank" if name.empty?
30
43
 
31
- add_list_json = JSON::generate(
32
- {
33
- "token" => "#{POCKETMATH_API_KEY}",
34
- "list" =>
35
- {
36
- "name" => "#{name}"
37
- }
38
- })
44
+ add_list_json = JSON::generate(
45
+ {
46
+ "token" => "#{@pocketmath_api_key}",
47
+ "list" =>
48
+ {
49
+ "name" => "#{name}"
50
+ }
51
+ })
39
52
 
40
- uri = URI.parse(API_BASE_URL)
41
- response = nil
42
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
43
- request = Net::HTTP::Post.new("/v1/lists/gps/add_list.json")
44
- request.body = add_list_json
45
- request.content_type = "application/json"
46
- response = http.request(request)
47
- end
48
- if !response.nil?
49
- data = response.body
50
- obj = JSON::parse(data)
51
- list_id = obj["id"]
52
- return list_id
53
- else
54
- return nil
53
+ uri = URI.parse(@pocketmath_api_base_url)
54
+ response = nil
55
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
56
+ request = Net::HTTP::Post.new("/v1/lists/gps/add_list.json")
57
+ request.body = add_list_json
58
+ request.content_type = "application/json"
59
+ response = http.request(request)
60
+ end
61
+ if !response.nil?
62
+ data = response.body
63
+ obj = JSON::parse(data)
64
+ list_id = obj["id"]
65
+ return list_id
66
+ else
67
+ return nil
68
+ end
55
69
  end
56
- end
57
70
 
58
- def self.upload_gps_list(id, coordinates = [])
59
- raise "id was nil" if id.nil?
60
- raise "coordinates was nil" if coordinates.nil?
61
- raise "coordiantes was empty" if coordinates.empty?
71
+ def upload_gps_list(id, coordinates = [])
72
+ raise "id was nil" if id.nil?
73
+ raise "coordinates was nil" if coordinates.nil?
74
+ raise "coordiantes was empty" if coordinates.empty?
62
75
 
63
- c = Curl::Easy.new("#{API_BASE_URL}/v1/lists/gps/upload.json")
64
- c.multipart_form_post = true
76
+ c = Curl::Easy.new("#{@pocketmath_api_base_url}/v1/lists/gps/upload.json")
77
+ c.multipart_form_post = true
65
78
 
66
- coordinates_string = ''
67
- coordinates.each do |coord|
68
- coordinates_string << "#{coord[:latitude]},#{coord[:longitude]}\r\n"
69
- end
79
+ coordinates_string = ''
80
+ coordinates.each do |coord|
81
+ coordinates_string << "#{coord[:latitude]},#{coord[:longitude]}\r\n"
82
+ end
70
83
 
71
- r = Random.new
72
- remote_file_name = "pm-advert-client-gps-list-#{r.rand(2*1000*1000*1000)}-#{r.rand(2*1000*1000*1000)}.txt"
73
- content_field = Curl::PostField.file('file', remote_file_name) do |field|
74
- field.content = coordinates_string
75
- end
84
+ r = Random.new
85
+ remote_file_name = "pm-advert-client-gps-list-#{r.rand(2*1000*1000*1000)}-#{r.rand(2*1000*1000*1000)}.txt"
86
+ content_field = Curl::PostField.file('file', remote_file_name) do |field|
87
+ field.content = coordinates_string
88
+ end
76
89
 
77
- success = nil
90
+ success = nil
78
91
 
79
- success = c.http_post(
80
- content_field,
81
- Curl::PostField.content('token', POCKETMATH_API_KEY),
82
- Curl::PostField.content('mode', 'append'),
83
- Curl::PostField.content('list_id', id.to_s )
84
- )
92
+ success = c.http_post(
93
+ content_field,
94
+ Curl::PostField.content('token', @pocketmath_api_key),
95
+ Curl::PostField.content('mode', 'append'),
96
+ Curl::PostField.content('list_id', id.to_s )
97
+ )
85
98
 
86
- return success
87
- end
88
-
89
- private
90
-
91
- def self.deep_copy(o)
92
- Marshal.load(Marshal.dump(o))
93
- end
94
-
95
- public
96
-
97
- def self.create_insertion_order( opts =
98
- {
99
- "name" => nil,
100
- "start_datetime" => Date.now,
101
- "end_datetime" => Date.now + 7.days,
102
- "creative_type_ids" => [],
103
- "budget" => "1.00",
104
- "iab_catgories" => [],
105
- "bid_per_impression" => "2.00",
106
- "top_level_domain" => "pocketmath.com",
107
- "country" => "223",
108
- "image_url" => "https://s3.amazonaws.com/pocketmath/pocketmath_320x50.jpg",
109
- "landing_page_url" => "www.pocketmath.com",
110
- "size_id" => "11"
111
- })
112
-
113
- o = deep_copy(opts)
114
-
115
- if o["name"].nil?
116
- raise "name was nil"
99
+ return success
117
100
  end
118
101
 
119
- if o["iab_category_codes"].empty?
120
- raise "no iab_category_codes specified"
102
+ def get_insertion_order_stats(id, start_date = nil, end_date = nil)
103
+ url = "#{@pocketmath_api_base_url}/v1/stats/id.json?token=#{@pocketmath_api_key}&id=#{URI.encode(id)}"
104
+ start_date_string = to_date_string(start_date)
105
+ end_date_string = to_date_string(end_date)
106
+ url << "&start_date=#{URI.encode(start_date_string)}" if !start_date_string.nil?
107
+ url << "&end_date=#{URI.encode(end_date_string)}" if !end_date_string.nil?
108
+ uri = URI.parse(url)
109
+
110
+ response = Net::HTTP.get(uri)
111
+ p response
112
+
113
+ if !response.nil?
114
+ data = response
115
+ obj = JSON::parse(data)
116
+ stats = obj["stats"]
117
+ return nil if stats.nil?
118
+ io_totals = stats["io_totals"]
119
+ return nil if io_totals.nil?
120
+ p io_totals
121
+ iostats = InsertionOrderStats.create({
122
+ :impressions => io_totals["imp"].to_i,
123
+ :clicks => io_totals["clk"].to_i,
124
+ :conversions => io_totals["conv"].to_i,
125
+ :spend => io_totals["spend"].gsub(/[^\d\.]/, '').to_f,
126
+ :cpm => io_totals["cpm"].gsub(/[^\d\.]/, '').to_f,
127
+ :cpc => io_totals["cpc"].gsub(/[^\d\.]/, '').to_f,
128
+ :cpa => io_totals["cpa"].gsub(/[^\d\.]/, '').to_f,
129
+ :ctr => io_totals["ctr"].to_f
130
+ })
131
+ return iostats
132
+ else
133
+ return nil
134
+ end
121
135
  end
122
136
 
123
- if o["start_datetime"].is_a?(Date)
124
- o["start_datetime"] = o["start_datetime"].strftime("%d %b %Y")
125
- elsif ! o["start_datetime"].is_a?(String)
126
- raise "unsupported type"
137
+ private
138
+
139
+ def deep_copy(o)
140
+ Marshal.load(Marshal.dump(o))
127
141
  end
128
142
 
129
- if o["end_datetime"].is_a?(Date)
130
- o["end_datetime"] = o["end_datetime"].strftime("%d %b %Y")
131
- elsif ! o["end_datetime"].is_a?(String)
132
- raise "unsupported type"
143
+ def to_date_string(o)
144
+ if o.nil?
145
+ return nil
146
+ elsif o.is_a?(Date)
147
+ return o.strftime("%d %b %Y")
148
+ elsif o.is_a?(String)
149
+ raise "case not handled"
150
+ end
133
151
  end
152
+
153
+ public
154
+
155
+ def create_insertion_order( opts =
156
+ {
157
+ "name" => nil,
158
+ "start_datetime" => Date.now,
159
+ "end_datetime" => Date.now + 7.days,
160
+ "creative_type_ids" => [],
161
+ "budget" => "1.00",
162
+ "iab_catgories" => [],
163
+ "bid_per_impression" => "2.00",
164
+ "top_level_domain" => "pocketmath.com",
165
+ "country" => "223",
166
+ "image_url" => "https://s3.amazonaws.com/pocketmath/pocketmath_320x50.jpg",
167
+ "landing_page_url" => "www.pocketmath.com",
168
+ "size_id" => "11"
169
+ })
134
170
 
135
- obj = { "token" => POCKETMATH_API_KEY, "io" => o }
171
+ o = deep_copy(opts)
136
172
 
137
- create_io_json = JSON.generate(obj)
173
+ if o["name"].nil?
174
+ raise "name was nil"
175
+ end
138
176
 
139
- uri = URI.parse(API_BASE_URL)
140
- response = nil
141
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
142
- request = Net::HTTP::Post.new("/v1/io/create.json")
143
- request.body = create_io_json
144
- request.content_type = "application/json"
145
- response = http.request(request)
146
- end
147
- if !response.nil?
148
- data = response.body
149
- p response
150
- p data
151
- obj = JSON::parse(data)
152
- io_id = obj["id"]
153
- return io_id
154
- else
155
- return nil
156
- end
177
+ if o["iab_category_codes"].empty?
178
+ raise "no iab_category_codes specified"
179
+ end
157
180
 
158
- end
181
+ if o["start_datetime"].is_a?(Date)
182
+ o["start_datetime"] = o["start_datetime"].strftime("%d %b %Y")
183
+ elsif ! o["start_datetime"].is_a?(String)
184
+ raise "unsupported type"
185
+ end
186
+
187
+ if o["end_datetime"].is_a?(Date)
188
+ o["end_datetime"] = o["end_datetime"].strftime("%d %b %Y")
189
+ elsif ! o["end_datetime"].is_a?(String)
190
+ raise "unsupported type"
191
+ end
192
+
193
+ obj = { "token" => @pocketmath_api_key, "io" => o }
194
+
195
+ create_io_json = JSON.generate(obj)
196
+
197
+ uri = URI.parse(@pocketmath_api_base_url)
198
+ response = nil
199
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
200
+ request = Net::HTTP::Post.new("/v1/io/create.json")
201
+ request.body = create_io_json
202
+ request.content_type = "application/json"
203
+ response = http.request(request)
204
+ end
205
+ if !response.nil?
206
+ data = response.body
207
+ p response
208
+ p data
209
+ obj = JSON::parse(data)
210
+ io_id = obj["id"]
211
+ return io_id
212
+ else
213
+ return nil
214
+ end
215
+
216
+ end
217
+
218
+ end # end Client
159
219
 
160
220
  end # module PocketMath::Advertiser::V1
161
221
  end # module PocketMath::Advertiser
@@ -1,73 +1,113 @@
1
1
  require 'json'
2
- require 'open-uri'
3
2
  require 'net/http'
4
3
  require 'uri'
5
4
 
6
- GEOCODING_PROVIDER = :open # May also use :google (see Google Map API Terms of Service to determine licensing requirements)
7
-
8
5
  module PocketMath
9
6
  module PocketMath::Geocode
10
7
 
11
- private
8
+ DEFAULT_GEOCODING_PROVIDER = :open # May also use :google (see Google Map API Terms of Service to determine licensing requirements)
12
9
 
13
- def self.get_gps_coordinates_open(location, max_results = 1)
14
- url = "http://open.mapquestapi.com/geocoding/v1/address?key=#{MAPQUEST_API_KEY}&location=#{URI.encode(location)}&maxResults=#{max_results.to_s}&inFormat=kvp&outFormat=json&json=true"
15
- response = Net::HTTP.get_response(URI.parse(url))
16
- data = response.body
17
- obj = JSON.parse(data)
18
- p url
19
- p obj
20
- gps_coordinates = []
21
- obj["results"].each do |result|
22
- result["locations"].each do |location|
23
- lat_lng = location["latLng"]
24
- gps_coordinates << { :latitude => lat_lng["lat"], :longitude => lat_lng["lng"] }
10
+ def self.open( opts = { :mapquest_api_key => nil, :provider => DEFAULT_GEOCODING_PROVIDER } )
11
+ return Geocode::Client.new(opts)
12
+ end
13
+
14
+ class PocketMath::Geocode::Client
15
+
16
+ private
17
+
18
+ def initialize( opts = { :mapquest_api_key => nil, :provider => DEFAULT_GEOCODING_PROVIDER } )
19
+ if !opts[:provider].nil?
20
+ @provider = opts[:provider]
21
+ else
22
+ @provider = DEFAULT_GEOCODING_PROVIDER
23
+ end
24
+
25
+ if !opts[:mapquest_api_key].nil?
26
+ @mapquest_api_key = opts[:mapquest_api_key]
27
+ else
28
+ @mapquest_api_key = nil
29
+ end
30
+
31
+ if @provider == :open && @mapquest_api_key.nil?
32
+ raise "Geocoding provider OPEN requires MapQuest API key. No key was specified. Please specify like this: Geocode.open{ :mapquest_api_key => \"...\" }"
25
33
  end
26
34
  end
27
- return nil if gps_coordinates.empty?
28
- return gps_coordinates
29
- end
30
35
 
31
- private
36
+ private
32
37
 
33
- #
34
- # Use of the Google Map API requires licensing from Google.
35
- #
36
- def self.get_gps_coordinates_google(location, max_results = 1)
37
- url = "http://maps.googleapis.com/maps/api/geocode/json?address=#{URI.encode(location)}&sensor=true"
38
- response = Net::HTTP.get_response(URI.parse(url))
39
- data = response.body
40
- obj = JSON.parse(data)
41
- p url
42
- p obj
43
- gps_coordinates = []
44
- n = 0
45
- obj["results"].each do |result|
46
- break if n >= max_results
47
- geometry = result["geometry"]
48
- raise "geometry was unavailable" if geometry.nil?
49
- location = geometry["location"]
50
- raise "location was unavailable" if location.nil?
51
- lat = location["lat"]
52
- lng = location["lng"]
53
- gps_coordinates << { :latitude => lat, :longitude => lng }
54
- n += 1
38
+ def get_gps_coordinates_open(location, max_results = 1)
39
+ url = "http://open.mapquestapi.com/geocoding/v1/address?key=#{@mapquest_api_key}&location=#{URI.encode(location)}&maxResults=#{max_results.to_s}&inFormat=kvp&outFormat=json&json=true"
40
+ response = Net::HTTP.get_response(URI.parse(url))
41
+ data = response.body
42
+ obj = JSON.parse(data)
43
+ p url
44
+ p obj
45
+ gps_coordinates = []
46
+ obj["results"].each do |result|
47
+ result["locations"].each do |location|
48
+ lat_lng = location["latLng"]
49
+ gps_coordinates << { :latitude => lat_lng["lat"], :longitude => lat_lng["lng"] }
50
+ end
51
+ end
52
+ return nil if gps_coordinates.empty?
53
+ return gps_coordinates
55
54
  end
56
- return nil if gps_coordinates.empty?
57
- return gps_coordinates
58
- end
59
55
 
60
- public
56
+ private
61
57
 
62
- def self.get_gps_coordinates(location, max_results = 1)
63
- if GEOCODING_PROVIDER == :google
64
- return get_gps_coordinates_google(location, max_results)
65
- elsif GEOCODING_PROVIDER == :open
66
- return get_gps_coordinates_open(location, max_results)
67
- else
68
- raise "map provider was not specified"
58
+ #
59
+ # Use of the Google Map API requires licensing from Google.
60
+ #
61
+ def get_gps_coordinates_google(location, max_results = 1)
62
+ url = "http://maps.googleapis.com/maps/api/geocode/json?address=#{URI.encode(location)}&sensor=true"
63
+ response = Net::HTTP.get_response(URI.parse(url))
64
+ data = response.body
65
+ obj = JSON.parse(data)
66
+ p url
67
+ p obj
68
+ gps_coordinates = []
69
+ n = 0
70
+ obj["results"].each do |result|
71
+ break if n >= max_results
72
+ geometry = result["geometry"]
73
+ raise "geometry was unavailable" if geometry.nil?
74
+ location = geometry["location"]
75
+ raise "location was unavailable" if location.nil?
76
+ lat = location["lat"]
77
+ lng = location["lng"]
78
+ gps_coordinates << { :latitude => lat, :longitude => lng }
79
+ n += 1
80
+ end
81
+ return nil if gps_coordinates.empty?
82
+ return gps_coordinates
69
83
  end
70
- end
71
84
 
85
+ public
86
+
87
+ def get_gps_coordinates(locations, max_results = 1)
88
+ _locations = nil
89
+ if (!locations.is_a?(Array))
90
+ _locations = [ locations ]
91
+ else
92
+ _locations = locations
93
+ end
94
+ gps_coordinates = []
95
+ _locations.each do |location|
96
+ if @provider == :google
97
+ gps_coordinates = gps_coordinates + get_gps_coordinates_google(location, max_results)
98
+ elsif @provider == :open
99
+ gps_coordinates = gps_coordinates + get_gps_coordinates_open(location, max_results)
100
+ else
101
+ raise "map provider was not specified"
102
+ end
103
+ end
104
+ gps_coodinates = gps_coordinates.zip
105
+ return gps_coordinates
106
+ end
107
+
108
+ def close
109
+ end
110
+
111
+ end
72
112
  end
73
113
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pocketmath-advertise
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Tucker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-05 00:00:00.000000000 Z
11
+ date: 2014-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curb
@@ -16,20 +16,27 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '0.8'
20
+ - - '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 0.8.5
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ~>
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: '0.8'
30
+ - - '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 0.8.5
27
33
  description: A client to connect to the PocketMath advertising API.
28
34
  email: eric@pocketmath.com
29
35
  executables: []
30
36
  extensions: []
31
37
  extra_rdoc_files: []
32
38
  files:
39
+ - lib/model/insertion_order_stats.rb
33
40
  - lib/pocketmath-advertise.rb
34
41
  - lib/pocketmath-advertiser.rb
35
42
  - lib/pocketmath-geocode.rb